aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorKitty Draper2011-03-05 21:39:25 -0500
committerKitty Draper2011-03-05 21:39:25 -0500
commitd40ae99422e118188a7f48055dc340c6aca022aa (patch)
tree83ab93f49fd9e66e43bcd824091ae1dbcaa0c173 /source
downloadsnes9x2005-d40ae99422e118188a7f48055dc340c6aca022aa.tar.gz
snes9x2005-d40ae99422e118188a7f48055dc340c6aca022aa.tar.bz2
snes9x2005-d40ae99422e118188a7f48055dc340c6aca022aa.zip
first commit
Diffstat (limited to 'source')
-rw-r--r--source/.cvsignore19
-rw-r--r--source/3d.h150
-rw-r--r--source/65c816.h172
-rw-r--r--source/Makefile342
-rw-r--r--source/Makefile.in339
-rw-r--r--source/apu.cpp959
-rw-r--r--source/apu.h214
-rw-r--r--source/apudebug.cpp439
-rw-r--r--source/apumem.h248
-rw-r--r--source/autom4te.cache/output.00
-rw-r--r--source/autom4te.cache/requests67
-rw-r--r--source/autom4te.cache/traces.00
-rw-r--r--source/c4.cpp237
-rw-r--r--source/c4.h124
-rw-r--r--source/c4emu.cpp1020
-rw-r--r--source/changes.txt2155
-rw-r--r--source/cheats.cpp440
-rw-r--r--source/cheats.h185
-rw-r--r--source/cheats2.cpp281
-rw-r--r--source/clip.cpp763
-rw-r--r--source/copyright.h159
-rw-r--r--source/cpu.cpp240
-rw-r--r--source/cpuaddr.h420
-rw-r--r--source/cpuexec.cpp476
-rw-r--r--source/cpuexec.h226
-rw-r--r--source/cpumacro.h892
-rw-r--r--source/cpuops.cpp4443
-rw-r--r--source/cpuops.h100
-rw-r--r--source/data.cpp539
-rw-r--r--source/debug.cpp2220
-rw-r--r--source/debug.h113
-rw-r--r--source/dependencies167
-rw-r--r--source/display.h133
-rw-r--r--source/dma.cpp1170
-rw-r--r--source/dma.h101
-rw-r--r--source/doc/porting.txt725
-rw-r--r--source/dsp1.cpp1455
-rw-r--r--source/dsp1.h131
-rw-r--r--source/dsp1emu.c1397
-rw-r--r--source/dsp2emu.c342
-rw-r--r--source/dsp4.h174
-rw-r--r--source/dsp4emu.cpp1488
-rw-r--r--source/font.h148
-rw-r--r--source/fxdbg.cpp409
-rw-r--r--source/fxemu.cpp726
-rw-r--r--source/fxemu.h177
-rw-r--r--source/fxinst.cpp1916
-rw-r--r--source/fxinst.h475
-rw-r--r--source/getset.h785
-rw-r--r--source/gfx.cpp4026
-rw-r--r--source/gfx.h318
-rw-r--r--source/globals.cpp405
-rw-r--r--source/hardware.txt502
-rw-r--r--source/language.h328
-rw-r--r--source/loadzip.cpp267
-rw-r--r--source/memmap.cpp4397
-rw-r--r--source/memmap.h300
-rw-r--r--source/messages.h137
-rw-r--r--source/missing.h164
-rw-r--r--source/movie.cpp779
-rw-r--r--source/movie.h146
-rw-r--r--source/nds/bdf_font.c1112
-rw-r--r--source/nds/bdf_font.h64
-rw-r--r--source/nds/bitmap.c204
-rw-r--r--source/nds/bitmap.h111
-rw-r--r--source/nds/charsets.c12345
-rw-r--r--source/nds/charsets.h13
-rw-r--r--source/nds/cheats3.cpp206
-rw-r--r--source/nds/displaymodes.cpp53
-rw-r--r--source/nds/draw.c1376
-rw-r--r--source/nds/draw.h207
-rw-r--r--source/nds/ds2_main.c65
-rw-r--r--source/nds/entry.cpp1234
-rw-r--r--source/nds/font_dot.h93
-rw-r--r--source/nds/gcheat.c527
-rw-r--r--source/nds/gcheat.h65
-rw-r--r--source/nds/gui.c4587
-rw-r--r--source/nds/gui.h125
-rw-r--r--source/nds/message.h175
-rw-r--r--source/netplay.cpp1048
-rw-r--r--source/netplay.h285
-rw-r--r--source/obc1.cpp204
-rw-r--r--source/obc1.h102
-rw-r--r--source/offsets.cpp421
-rw-r--r--source/pixform.h322
-rw-r--r--source/port.h299
-rw-r--r--source/ppu.cpp3299
-rw-r--r--source/ppu.h633
-rw-r--r--source/problems.txt459
-rw-r--r--source/sa1.cpp943
-rw-r--r--source/sa1.h223
-rw-r--r--source/sa1cpu.cpp196
-rw-r--r--source/sar.h138
-rw-r--r--source/screenshot.cpp235
-rw-r--r--source/screenshot.h96
-rw-r--r--source/sdd1.cpp181
-rw-r--r--source/sdd1.h98
-rw-r--r--source/sdd1emu.cpp414
-rw-r--r--source/sdd1emu.h104
-rw-r--r--source/server.cpp1303
-rw-r--r--source/seta.cpp105
-rw-r--r--source/seta.h156
-rw-r--r--source/seta010.cpp750
-rw-r--r--source/seta011.cpp232
-rw-r--r--source/seta018.cpp256
-rw-r--r--source/sfc.mk83
-rw-r--r--source/snaporig.cpp465
-rw-r--r--source/snaporig.h379
-rw-r--r--source/snapshot.cpp1824
-rw-r--r--source/snapshot.h116
-rw-r--r--source/snes9x.cpp808
-rw-r--r--source/snes9x.h431
-rw-r--r--source/sound.cpp279
-rw-r--r--source/soundux.cpp2030
-rw-r--r--source/soundux.h247
-rw-r--r--source/spc.cpp133
-rw-r--r--source/spc700.cpp2565
-rw-r--r--source/spc700.h204
-rw-r--r--source/spc7110.cpp2312
-rw-r--r--source/spc7110.h195
-rw-r--r--source/spccycles.cpp110
-rw-r--r--source/spctool.cpp201
-rw-r--r--source/srtc.cpp577
-rw-r--r--source/srtc.h157
-rw-r--r--source/tile.cpp1175
-rw-r--r--source/tile.h317
-rw-r--r--source/unicode.c1854
-rw-r--r--source/unicode.h44
-rw-r--r--source/unzip/explode.c1120
-rw-r--r--source/unzip/unreduce.c217
-rw-r--r--source/unzip/unshrink.c177
-rw-r--r--source/unzip/unz.h994
-rw-r--r--source/unzip/unzip.c1224
-rw-r--r--source/unzip/unzip.h285
-rw-r--r--source/unzip/unzipP.h125
135 files changed, 97382 insertions, 0 deletions
diff --git a/source/.cvsignore b/source/.cvsignore
new file mode 100644
index 0000000..018f254
--- /dev/null
+++ b/source/.cvsignore
@@ -0,0 +1,19 @@
+no_glide
+no_opengl
+c_fx
+offsets
+zsnes_fx
+*.O
+snes9x
+dependencies
+Makefile
+config.cache
+config.log
+config.status
+config.info
+autom4te.cache
+configure
+build
+vc60.pdb
+*.Obj
+conftezt.out.2
diff --git a/source/3d.h b/source/3d.h
new file mode 100644
index 0000000..da82860
--- /dev/null
+++ b/source/3d.h
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _3D_H_
+#define _3D_H_
+
+#if defined(USE_OPENGL)
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#ifdef __linux__
+#include <GL/glx.h>
+#endif
+
+typedef struct
+{
+ bool8 packed_pixels_extension_present;
+ bool8 draw_cube;
+ uint32 version;
+ // Texture format
+ GLint internal_format;
+ GLint format;
+ GLint type;
+
+ GLint max_texture_size;// 256 or 512
+ GLint texture_size;
+ uint32 num_textures; // 1 if max_texture_size == 256, 2 otherwise
+ GLuint textures [2];
+} OpenGLData;
+
+extern OpenGLData OpenGL;
+
+bool8 S9xOpenGLInit ();
+bool8 S9xOpenGLInit2 ();
+void S9xOpenGLPutImage (int width, int height);
+void S9xOpenGLDeinit ();
+
+#endif
+
+#ifdef USE_GLIDE
+#include <glide.h>
+
+typedef struct
+{
+ bool8 voodoo_present;
+ GrVertex sq[4];
+ GrTexInfo texture;
+ int32 texture_mem_size;
+ int32 texture_mem_start;
+ float x_offset, y_offset;
+ float x_scale, y_scale;
+ float voodoo_width;
+ float voodoo_height;
+} GlideData;
+
+extern GlideData Glide;
+bool8 S9xGlideEnable (bool8 enable);
+void S9xGlideDeinit ();
+bool8 S9xGlideInit ();
+bool8 S9xVoodooInitialise ();
+#endif
+
+#endif
+
diff --git a/source/65c816.h b/source/65c816.h
new file mode 100644
index 0000000..a82de8d
--- /dev/null
+++ b/source/65c816.h
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _65c816_h_
+#define _65c816_h_
+
+#define AL A.B.l
+#define AH A.B.h
+#define XL X.B.l
+#define XH X.B.h
+#define YL Y.B.l
+#define YH Y.B.h
+#define SL S.B.l
+#define SH S.B.h
+#define DL D.B.l
+#define DH D.B.h
+#define PL P.B.l
+#define PH P.B.h
+
+#define Carry 1
+#define Zero 2
+#define IRQ 4
+#define Decimal 8
+#define IndexFlag 16
+#define MemoryFlag 32
+#define Overflow 64
+#define Negative 128
+#define Emulation 256
+
+#define ClearCarry() (ICPU._Carry = 0)
+#define SetCarry() (ICPU._Carry = 1)
+#define SetZero() (ICPU._Zero = 0)
+#define ClearZero() (ICPU._Zero = 1)
+#define SetIRQ() (Registers.PL |= IRQ)
+#define ClearIRQ() (Registers.PL &= ~IRQ)
+#define SetDecimal() (Registers.PL |= Decimal)
+#define ClearDecimal() (Registers.PL &= ~Decimal)
+#define SetIndex() (Registers.PL |= IndexFlag)
+#define ClearIndex() (Registers.PL &= ~IndexFlag)
+#define SetMemory() (Registers.PL |= MemoryFlag)
+#define ClearMemory() (Registers.PL &= ~MemoryFlag)
+#define SetOverflow() (ICPU._Overflow = 1)
+#define ClearOverflow() (ICPU._Overflow = 0)
+#define SetNegative() (ICPU._Negative = 0x80)
+#define ClearNegative() (ICPU._Negative = 0)
+
+#define CheckZero() (ICPU._Zero == 0)
+#define CheckCarry() (ICPU._Carry)
+#define CheckIRQ() (Registers.PL & IRQ)
+#define CheckDecimal() (Registers.PL & Decimal)
+#define CheckIndex() (Registers.PL & IndexFlag)
+#define CheckMemory() (Registers.PL & MemoryFlag)
+#define CheckOverflow() (ICPU._Overflow)
+#define CheckNegative() (ICPU._Negative & 0x80)
+#define CheckEmulation() (Registers.P.W & Emulation)
+
+#define ClearFlags(f) (Registers.P.W &= ~(f))
+#define SetFlags(f) (Registers.P.W |= (f))
+#define CheckFlag(f) (Registers.PL & (f))
+
+typedef union
+{
+#ifdef LSB_FIRST
+ struct { uint8 l,h; } B;
+#else
+ struct { uint8 h,l; } B;
+#endif
+ uint16 W;
+} pair;
+
+struct SRegisters{
+ uint8 PB;
+ uint8 DB;
+ pair P;
+ pair A;
+ pair D;
+ pair S;
+ pair X;
+ pair Y;
+ uint16 PC;
+};
+
+EXTERN_C struct SRegisters Registers;
+
+#endif
+
diff --git a/source/Makefile b/source/Makefile
new file mode 100644
index 0000000..9bc8f97
--- /dev/null
+++ b/source/Makefile
@@ -0,0 +1,342 @@
+# Generated automatically from Makefile.in by configure.
+#ZSNESFX=1
+#ZSNESC4=1
+#ASMCPU=1
+#SPC700ASM=1
+#NETPLAY=1
+#UNZIP=1
+#GLIDE=1
+#OPENGL=1
+#AIDO=1
+#GUI=0
+#THREAD_SOUND=1
+#ASMKREED=1
+SDD1_DECOMP=1
+#SDD1_VERIFY=0
+
+#Fairly good and special-char-safe descriptor of the os being built on.
+OS=`uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"`
+BUILDDIR=.
+#BUILDDIR=build/$(OS)
+
+
+ifdef ZSNESFX
+FXOBJ=i386/fxemu2b.o i386/fxemu2.o i386/fxemu2c.o i386/fxtable.o i386/sfxproc.o i386/ZSNES.O
+FXDEFINES=-DZSNES_FX -DEXECUTE_SUPERFX_PER_LINE
+FXDEPENDS=zsnes_fx
+FXNO_DEPENDS=c_fx
+else
+FXOBJ=fxinst.o fxemu.o fxdbg.o
+FXDEFINES=-DEXECUTE_SUPERFX_PER_LINE
+FXDEPENDS=c_fx
+FXNO_DEPENDS=zsnes_fx
+endif
+
+ifdef ZSNESC4
+C4OBJ=i386/C4.O i386/zsnesc4.o c4.o
+C4DEFINES=-DZSNES_C4
+C4DEPENDS=zsnes_c4
+C4NO_DEPENDS=c_c4
+else
+C4OBJ=c4.o c4emu.o
+C4DEFINES=
+C4DEPENDS=c_c4
+C4NO_DEPENDS=zsnes_c4
+endif
+
+ifdef SPC700ASM
+SOUNDOBJ=spctool/spc700.o spctool/dsp.o spctool.o spctool/soundmod.o SPC.O
+SOUNDDEFINES=-DSPCTOOL
+else
+SOUNDOBJ=spc700.o soundux.o apu.o
+SOUNDDEFINES=-DSPC700_C
+endif
+
+ifdef ASMCPU
+CPUOBJ=i386/cpuops.o i386/cpuexec.o i386/sa1ops.o
+else
+CPUOBJ=cpuops.o cpuexec.o sa1cpu.o
+endif
+
+ifdef ASMKREED
+KREEDOBJ=i386/2XSAIMMX.O i386/bilinear.o 2xsai.o
+KREEDDEFINES=-DMMX
+else
+KREEDDEFINES=
+# KREEDOBJ=2xsai.o
+endif
+
+ifdef SDD1_DECOMP
+SDD1OBJ=sdd1emu.o
+ifdef SDD1_VERIFY
+SDD1DEFINES=-DSDD1_DECOMP -DSDD1_VERIFY
+else
+SDD1DEFINES=-DSDD1_DECOMP
+endif
+else
+SDD1DEFINES=
+SDD1OBJ=
+endif
+
+SPC7110OBJ=spc7110.o
+OBC1OBJ=obc1.o
+SETAOBJ=seta.o seta010.o seta011.o seta018.o
+
+OBJECTS=$(CPUOBJ) $(SOUNDOBJ) apudebug.o $(FXOBJ) $(C4OBJ) \
+ cpu.o sa1.o debug.o sdd1.o tile.o srtc.o \
+ gfx.o memmap.o snaporig.o clip.o dsp1.o \
+ movie.o \
+ ppu.o dma.o snes9x.o snapshot.o screenshot.o \
+ cheats.o cheats2.o data.o unix/unix.o unix/config.o globals.o \
+ $(SPC7110OBJ) $(OBC1OBJ) $(SETAOBJ) $(KREEDOBJ) $(SDD1OBJ)
+
+#OBJECTS += ../zlib/libz.a
+
+#FIXME: The gui is bitrotted if it ever worked at all. Remove?
+ifdef GUI
+GUIOBJS = unix/snes9x_gui.o unix/moc_snes9x_gui.o
+GUILIBS = -L$(QTDIR)/lib -lqt
+GUIDEFINES = -I$(QTDIR)/include
+endif
+
+ifdef NETPLAY
+OBJECTS += netplay.o server.o
+NETPLAYDEFINES=-DNETPLAY_SUPPORT
+SERVER_OBJECTS=server.o
+endif
+
+ifdef UNZIP
+OBJECTS += loadzip.o unzip/unzip.o unzip/explode.o unzip/unreduce.o unzip/unshrink.o
+UNZIPDEFINES=-DUNZIP_SUPPORT
+endif
+
+ifdef THREAD_SOUND
+CPUDEFINES += -DUSE_THREADS
+EXTRALIBS += -lpthread
+endif
+
+ifdef GLIDE
+GLIDEOBJS = unix/glide.o
+GLIDEDEFINES = -DUSE_GLIDE -I/usr/include/glide
+GLIDELIBS = -lglide2x
+endif
+
+ifdef OPENGL
+OPENGLOBJS = unix/opengl.o
+OPENGLDEFINES = -DUSE_OPENGL
+OPENGLLIBS = -lGL -lGLU -ldl
+endif
+
+ifdef AIDO
+AIDOOBJS = unix/aido.o
+AIDODEFINES = -DUSE_AIDO
+endif
+
+JOYDEFINES =
+
+MOC = $(QTDIR)/bin/moc
+CCC = c++ -fno-rtti
+GASM = c++
+CC = gcc
+NASM = /usr/bin/nasm
+
+#INCLUDES = -I../zlib -INONE
+INCLUDES = -INONE
+
+#OPTIMISE = -mcpu=pentiumpro -O6 -fomit-frame-pointer -fno-exceptions -Wall -W -pedantic -Wno-unused-parameter -pipe
+OPTIMISE = -O6 -fomit-frame-pointer -fno-exceptions -Wall -W -pedantic -Wno-unused-parameter -pipe
+
+#OPTIMISE=-g -fno-exceptions
+
+CCFLAGS = $(OPTIMISE) -DMITSHM \
+ -I. \
+-Iunzip \
+-DVAR_CYCLES \
+-DCPU_SHUTDOWN \
+-DSPC700_SHUTDOWN \
+$(FXDEFINES) \
+$(C4DEFINES) \
+$(CPUDEFINES) \
+$(SOUNDDEFINES) \
+$(NETPLAYDEFINES) \
+$(UNZIPDEFINES) \
+$(GLIDEDEFINES) \
+$(OPENGLDEFINES) \
+$(AIDODEFINES) \
+$(GUIDEFINES) \
+$(KREEDDEFINES) \
+$(SDD1DEFINES) \
+$(JOYDEFINES) \
+-DNO_INLINE_SET_GET -DNOASM -DHAVE_MKSTEMP '-DACCEPT_SIZE_T=size_t'
+
+#-DOLD_COLOUR_BLENDING
+#-DSOUND
+#-DDEBUGGER
+#-DNO_INLINE_SET_GET
+#-DVAR_CYCLES
+#-DCPU_SHUTDOWN
+#-DSPC700_SHUTDOWN
+
+CFLAGS=$(CCFLAGS)
+
+.SUFFIXES: .o .cpp .c .cc .h .m .i .S .asm .obj .O .CPP .C .ASM
+#FIXME: Why is this set statically?
+#LDLIBS = -L/usr/X11R6/lib
+# -L../zlib
+
+ifdef GLIDE
+all: Makefile configure offsets gsnes9x
+else
+ifdef OPENGL
+all: Makefile configure offsets osnes9x
+else
+# all: Makefile configure offsets snes9x
+all: Makefile configure snes9x
+endif
+endif
+
+Makefile: configure Makefile.in
+ @echo "Makefile is older than configure or in-file. Run configure or touch Makefile."
+ exit 1
+
+configure: configure.in
+ @echo "configure is older than in-file. Run autoconf or touch configure."
+ exit 1
+
+#ssnes9x
+#ggisnes9x
+#xf86snes9x
+
+# offsets: offsets.o
+# $(CCC) $(INCLUDES) -o $@ offsets.o
+# ./offsets >i386/offsets.h
+
+#../zlib/libz.a:
+# cd ../zlib && sh ./configure && make
+
+snes9x: $(OBJECTS) $(AIDOOBJS) $(GUIOBJS)
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(AIDOOBJS) $(GLIDEOBJS) $(OPENGLOBJS) $(GUIOBJS) $(LDLIBS) $(GLIDELIBS) $(OPENGLLIBS) $(GUILIBS) -lnsl -lXext -lX11 $(EXTRALIBS) -lm
+
+ssnes9x: $(OBJECTS) unix/svga.o
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) unix/svga.o $(LDLIBS) $(GLIDELIBS) -lvga -lvgagl $(EXTRALIBS) -lm
+
+gsnes9x: $(OBJECTS) $(GLIDEOBJS)
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) $(LDLIBS) -lglide $(EXTRALIBS) -lm
+
+ggisnes9x: $(OBJECTS) unix/ggi.o
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) unix/ggi.o $(LDLIBS) -lggi $(EXTRALIBS) -lm
+
+osnes9x: $(OBJECTS) $(OPENGLOBJS)
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(OPENGLOBJS) $(LDLIBS) $(OPENGLLIBS) -lnsl -lXext -lX11 $(EXTRALIBS) -lm
+
+s9xserver: $(SERVER_OBJECTS)
+ $(CCC) $(INCLUDES) -o $@ $(SERVER_OBJECTS)
+
+.cpp.o:
+ $(CCC) $(INCLUDES) -c $(CCFLAGS) $*.cpp -o $@
+
+.c.o:
+ $(CC) $(INCLUDES) -c $(CCFLAGS) $*.c -o $@
+
+.cpp.S:
+ $(GASM) $(INCLUDES) -S $(CCFLAGS) $*.cpp -o $@
+
+.cpp.i:
+ $(GASM) $(INCLUDES) -E $(CCFLAGS) $*.cpp -o $@
+
+.S.o:
+ $(GASM) $(INCLUDES) -c $(CCFLAGS) $*.S -o $@
+
+.S.i:
+ $(GASM) $(INCLUDES) -c -E $(CCFLAGS) $*.S -o $@
+
+.asm.o:
+ $(NASM) -f elf $(FXDEFINES) -i. -ii386 -o $@ $*.asm
+
+.obj.o:
+ cp $*.obj $*.o
+
+.CPP.O:
+ $(CCC) $(INCLUDES) -c $(CCFLAGS) -x c++ $*.CPP -o $@
+
+.C.O:
+ $(CC) $(INCLUDES) -c $(CCFLAGS) $*.C -o $@
+
+.ASM.O:
+ $(NASM) -f elf $(FXDEFINES) -i . -i i386 $*.ASM -o $@
+
+unix/moc_snes9x_gui.cpp: unix/snes9x_gui.h
+ $(MOC) unix/snes9x_gui.h -o $@
+
+clean:
+ rm -f $(OBJECTS) offsets.o unix/svga.o unix/aido.o unix/ggi.o unix/xf86.o unix/glide.o
+
+#release: CCFLAGS += -DNO_DEBUGGER
+
+_bin-package:
+ RELNR=`grep "#define VERSION" snes9x.h | sed -e 's/"//g' | awk '{ print $$3 }'` && \
+ echo $$RELNR && \
+ RELNAME=snes9x-$${RELNR} && export RELNAME && \
+ test \! -f $${RELNAME}.tar.gz && \
+ DISTDIR=disttmp/$${RELNAME}/ && \
+ rm -rf disttmp && \
+ mkdir disttmp && \
+ mkdir $${DISTDIR} && \
+ cp snes9x $${DISTDIR} && \
+ cp config.info hardware.txt problems.txt changes.txt ../faqs.txt ../readme.txt ../readme.unix $${DISTDIR} && \
+ (cd disttmp && tar cvf - $${RELNAME}) | gzip -c > $${RELNAME}.tar.gz &&\
+ rm -rf disttmp
+
+#FIXME: Should possibly have clean, but not in xenofarm build
+bin-release: snes9x _bin-package
+
+#FIXME: Intelligent messages when bailing out.
+#FIXME: See those ls:s? Don't look to closely at the statements...
+_src-package:
+ RELNR=`grep "#define VERSION" snes9x.h | sed -e 's/"//g' | awk '{ print $$3 }'` && \
+ echo $$RELNR && \
+ RELNAME=snes9x-$${RELNR}-src && \
+ test \! -f $${RELNAME}.tar.gz && \
+ test \! `ls *~` && \
+ test \! `ls *.o` && \
+ test \! -f snes9x && \
+ export RELNR && export RELNAME && \
+ (cd .. && PWD=`pwd` && SNESDIR=`basename $$PWD` && cd .. && \
+ DISTDIR=disttmp/$${RELNAME} && \
+ rm -rf disttmp && \
+ mkdir disttmp && \
+ cp -r $${SNESDIR} $${DISTDIR} && \
+ rm -f $${DISTDIR}/snes9x/config.* 2>/dev/null && \
+ rm -f $${DISTDIR}/snes9x/conftezt.out.* 2>/dev/null && \
+ rm -rf $${DISTDIR}/snes9x/autom4te.cache 2>/dev/null && \
+ rm $${DISTDIR}/snes9x/Makefile && \
+ find disttmp -name CVS -type f -exec rm "{}" \; && \
+ find disttmp -name CVS -type d -exec rm "{}" \; && \
+ (cd disttmp && tar cvf - $${RELNAME}) | gzip -c > $${RELNAME}.tar.gz && \
+ mv $${RELNAME}.tar.gz $${SNESDIR}/snes9x/ ) && \
+ rm -rf disttmp
+
+#Requires:
+# 1. Prestine checkout
+# 2. `autoconf`
+# 3. `./configure`
+src-release: depend _src-package
+
+xenofarm:
+ ./xenofarm.sh
+ cd build/xenofarm && tar cf - . > ../../../xenofarm_result.tar
+ gzip -f9 ../xenofarm_result.tar
+
+# And now for the impressive testsuite:
+verify: snes9x
+ ./snes9x --selftest
+
+#FIXME: Make a auto-self-reference.
+depend:
+ $(CC) $(CFLAGS) -MM -MG \
+ `find . '(' -name '*.c' -o -name '*.cpp' -o -name '*.S' ')' -print -o -name msdos -prune` \
+ | sed -e 's@^[^ :]*: *\([^ ]*/\)[^ /]*@\1&@' \
+ >dependencies
+
+include dependencies
+
diff --git a/source/Makefile.in b/source/Makefile.in
new file mode 100644
index 0000000..82f5b86
--- /dev/null
+++ b/source/Makefile.in
@@ -0,0 +1,339 @@
+@ZSNESFX@
+@ZSNESC4@
+@ASMCPU@
+@SPC700ASM@
+NETPLAY=1
+UNZIP=1
+@GLIDE@
+@OPENGL@
+@AIDO@
+#GUI=0
+@THREAD_SOUND@
+@ASMKREED@
+@SDD1_DECOMP@
+#SDD1_VERIFY=0
+
+#Fairly good and special-char-safe descriptor of the os being built on.
+OS=`uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"`
+BUILDDIR=.
+#BUILDDIR=build/$(OS)
+
+
+ifdef ZSNESFX
+FXOBJ=i386/fxemu2b.o i386/fxemu2.o i386/fxemu2c.o i386/fxtable.o i386/sfxproc.o i386/ZSNES.O
+FXDEFINES=-DZSNES_FX -DEXECUTE_SUPERFX_PER_LINE
+FXDEPENDS=zsnes_fx
+FXNO_DEPENDS=c_fx
+else
+FXOBJ=fxinst.o fxemu.o fxdbg.o
+FXDEFINES=-DEXECUTE_SUPERFX_PER_LINE
+FXDEPENDS=c_fx
+FXNO_DEPENDS=zsnes_fx
+endif
+
+ifdef ZSNESC4
+C4OBJ=i386/C4.O i386/zsnesc4.o c4.o
+C4DEFINES=-DZSNES_C4
+C4DEPENDS=zsnes_c4
+C4NO_DEPENDS=c_c4
+else
+C4OBJ=c4.o c4emu.o
+C4DEFINES=
+C4DEPENDS=c_c4
+C4NO_DEPENDS=zsnes_c4
+endif
+
+ifdef SPC700ASM
+SOUNDOBJ=spctool/spc700.o spctool/dsp.o spctool.o spctool/soundmod.o SPC.O
+SOUNDDEFINES=-DSPCTOOL
+else
+SOUNDOBJ=spc700.o soundux.o apu.o @I386SPC@
+SOUNDDEFINES=-DSPC700_C
+endif
+
+ifdef ASMCPU
+CPUOBJ=i386/cpuops.o i386/cpuexec.o i386/sa1ops.o
+else
+CPUOBJ=cpuops.o cpuexec.o sa1cpu.o
+endif
+
+ifdef ASMKREED
+KREEDOBJ=i386/2XSAIMMX.O i386/bilinear.o 2xsai.o
+KREEDDEFINES=-DMMX
+else
+KREEDDEFINES=
+KREEDOBJ=2xsai.o
+endif
+
+ifdef SDD1_DECOMP
+SDD1OBJ=sdd1emu.o
+ifdef SDD1_VERIFY
+SDD1DEFINES=-DSDD1_DECOMP -DSDD1_VERIFY
+else
+SDD1DEFINES=-DSDD1_DECOMP
+endif
+else
+SDD1DEFINES=
+SDD1OBJ=
+endif
+
+SPC7110OBJ=spc7110.o
+OBC1OBJ=obc1.o
+SETAOBJ=seta.o seta010.o seta011.o seta018.o
+
+OBJECTS=$(CPUOBJ) $(SOUNDOBJ) apudebug.o $(FXOBJ) $(C4OBJ) \
+ cpu.o sa1.o debug.o sdd1.o tile.o srtc.o \
+ gfx.o memmap.o snaporig.o clip.o dsp1.o \
+ movie.o \
+ ppu.o dma.o snes9x.o snapshot.o screenshot.o \
+ cheats.o cheats2.o data.o unix/unix.o unix/config.o globals.o \
+ $(SPC7110OBJ) $(OBC1OBJ) $(SETAOBJ) $(KREEDOBJ) $(SDD1OBJ)
+
+#OBJECTS += ../zlib/libz.a
+
+#FIXME: The gui is bitrotted if it ever worked at all. Remove?
+ifdef GUI
+GUIOBJS = unix/snes9x_gui.o unix/moc_snes9x_gui.o
+GUILIBS = -L$(QTDIR)/lib -lqt
+GUIDEFINES = -I$(QTDIR)/include
+endif
+
+ifdef NETPLAY
+OBJECTS += netplay.o server.o
+NETPLAYDEFINES=-DNETPLAY_SUPPORT
+SERVER_OBJECTS=server.o
+endif
+
+ifdef UNZIP
+OBJECTS += loadzip.o unzip/unzip.o unzip/explode.o unzip/unreduce.o unzip/unshrink.o
+UNZIPDEFINES=-DUNZIP_SUPPORT
+endif
+
+ifdef THREAD_SOUND
+CPUDEFINES += -DUSE_THREADS
+EXTRALIBS += -lpthread
+endif
+
+ifdef GLIDE
+GLIDEOBJS = unix/glide.o
+GLIDEDEFINES = -DUSE_GLIDE -I/usr/include/glide
+GLIDELIBS = -lglide2x
+endif
+
+ifdef OPENGL
+OPENGLOBJS = unix/opengl.o
+OPENGLDEFINES = -DUSE_OPENGL
+OPENGLLIBS = -lGL -lGLU -ldl
+endif
+
+ifdef AIDO
+AIDOOBJS = unix/aido.o
+AIDODEFINES = -DUSE_AIDO
+endif
+
+JOYDEFINES = @JOYDEFINES@
+
+MOC = $(QTDIR)/bin/moc
+CCC = @CXX@ @RTTIFLAG@
+GASM = @CXX@
+CC = @CC@
+NASM = @NASM@
+
+#INCLUDES = -I../zlib @XINCLUDES@
+INCLUDES = @XINCLUDES@
+
+OPTIMISE = @OPTIMIZE@
+
+#OPTIMISE=-g -fno-exceptions
+
+CCFLAGS = $(OPTIMISE) -DMITSHM \
+@CPUINC@ -I. \
+-Iunzip \
+-DVAR_CYCLES \
+-DCPU_SHUTDOWN \
+-DSPC700_SHUTDOWN \
+$(FXDEFINES) \
+$(C4DEFINES) \
+$(CPUDEFINES) \
+$(SOUNDDEFINES) \
+$(NETPLAYDEFINES) \
+$(UNZIPDEFINES) \
+$(GLIDEDEFINES) \
+$(OPENGLDEFINES) \
+$(AIDODEFINES) \
+$(GUIDEFINES) \
+$(KREEDDEFINES) \
+$(SDD1DEFINES) \
+$(JOYDEFINES) \
+-DNO_INLINE_SET_GET @SYSDEFINES@
+
+#-DOLD_COLOUR_BLENDING
+#-DSOUND
+#-DDEBUGGER
+#-DNO_INLINE_SET_GET
+#-DVAR_CYCLES
+#-DCPU_SHUTDOWN
+#-DSPC700_SHUTDOWN
+
+CFLAGS=$(CCFLAGS)
+
+.SUFFIXES: .o .cpp .c .cc .h .m .i .S .asm .obj .O .CPP .C .ASM
+#FIXME: Why is this set statically?
+#LDLIBS = -L/usr/X11R6/lib
+# -L../zlib
+
+ifdef GLIDE
+all: Makefile configure offsets gsnes9x
+else
+ifdef OPENGL
+all: Makefile configure offsets osnes9x
+else
+all: Makefile configure offsets snes9x
+endif
+endif
+
+Makefile: configure Makefile.in
+ @echo "Makefile is older than configure or in-file. Run configure or touch Makefile."
+ exit 1
+
+configure: configure.in
+ @echo "configure is older than in-file. Run autoconf or touch configure."
+ exit 1
+
+#ssnes9x
+#ggisnes9x
+#xf86snes9x
+
+offsets: offsets.o
+ $(CCC) $(INCLUDES) -o $@ offsets.o
+ ./offsets >i386/offsets.h
+
+#../zlib/libz.a:
+# cd ../zlib && sh ./configure && make
+
+snes9x: $(OBJECTS) unix/x11.o $(AIDOOBJS) $(GUIOBJS)
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(AIDOOBJS) $(GLIDEOBJS) $(OPENGLOBJS) unix/x11.o $(GUIOBJS) $(LDLIBS) $(GLIDELIBS) $(OPENGLLIBS) $(GUILIBS) @SYSLIBS@ -lXext -lX11 $(EXTRALIBS) -lm
+
+ssnes9x: $(OBJECTS) unix/svga.o
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) unix/svga.o $(LDLIBS) $(GLIDELIBS) -lvga -lvgagl $(EXTRALIBS) -lm
+
+gsnes9x: $(OBJECTS) $(GLIDEOBJS)
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) $(LDLIBS) -lglide $(EXTRALIBS) -lm
+
+ggisnes9x: $(OBJECTS) unix/ggi.o
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) unix/ggi.o $(LDLIBS) -lggi $(EXTRALIBS) -lm
+
+osnes9x: $(OBJECTS) unix/x11.o $(OPENGLOBJS)
+ $(CCC) $(INCLUDES) -o $@ $(OBJECTS) unix/x11.o $(OPENGLOBJS) $(LDLIBS) $(OPENGLLIBS) @SYSLIBS@ -lXext -lX11 $(EXTRALIBS) -lm
+
+s9xserver: $(SERVER_OBJECTS)
+ $(CCC) $(INCLUDES) -o $@ $(SERVER_OBJECTS)
+
+.cpp.o:
+ $(CCC) $(INCLUDES) -c $(CCFLAGS) $*.cpp -o $@
+
+.c.o:
+ $(CC) $(INCLUDES) -c $(CCFLAGS) $*.c -o $@
+
+.cpp.S:
+ $(GASM) $(INCLUDES) -S $(CCFLAGS) $*.cpp -o $@
+
+.cpp.i:
+ $(GASM) $(INCLUDES) -E $(CCFLAGS) $*.cpp -o $@
+
+.S.o:
+ $(GASM) $(INCLUDES) -c $(CCFLAGS) $*.S -o $@
+
+.S.i:
+ $(GASM) $(INCLUDES) -c -E $(CCFLAGS) $*.S -o $@
+
+.asm.o:
+ $(NASM) -f elf $(FXDEFINES) -i. -ii386 -o $@ $*.asm
+
+.obj.o:
+ cp $*.obj $*.o
+
+.CPP.O:
+ $(CCC) $(INCLUDES) -c $(CCFLAGS) -x c++ $*.CPP -o $@
+
+.C.O:
+ $(CC) $(INCLUDES) -c $(CCFLAGS) $*.C -o $@
+
+.ASM.O:
+ $(NASM) -f elf $(FXDEFINES) -i . -i i386 $*.ASM -o $@
+
+unix/moc_snes9x_gui.cpp: unix/snes9x_gui.h
+ $(MOC) unix/snes9x_gui.h -o $@
+
+clean:
+ rm -f $(OBJECTS) offsets.o unix/svga.o unix/aido.o unix/x11.o unix/ggi.o unix/xf86.o unix/glide.o
+
+#release: CCFLAGS += -DNO_DEBUGGER
+
+_bin-package:
+ RELNR=`grep "#define VERSION" snes9x.h | sed -e 's/"//g' | awk '{ print $$3 }'` && \
+ echo $$RELNR && \
+ RELNAME=snes9x-$${RELNR} && export RELNAME && \
+ test \! -f $${RELNAME}.tar.gz && \
+ DISTDIR=disttmp/$${RELNAME}/ && \
+ rm -rf disttmp && \
+ mkdir disttmp && \
+ mkdir $${DISTDIR} && \
+ cp snes9x $${DISTDIR} && \
+ cp config.info hardware.txt problems.txt changes.txt ../faqs.txt ../readme.txt ../readme.unix $${DISTDIR} && \
+ (cd disttmp && tar cvf - $${RELNAME}) | gzip -c > $${RELNAME}.tar.gz &&\
+ rm -rf disttmp
+
+#FIXME: Should possibly have clean, but not in xenofarm build
+bin-release: snes9x _bin-package
+
+#FIXME: Intelligent messages when bailing out.
+#FIXME: See those ls:s? Don't look to closely at the statements...
+_src-package:
+ RELNR=`grep "#define VERSION" snes9x.h | sed -e 's/"//g' | awk '{ print $$3 }'` && \
+ echo $$RELNR && \
+ RELNAME=snes9x-$${RELNR}-src && \
+ test \! -f $${RELNAME}.tar.gz && \
+ test \! `ls *~` && \
+ test \! `ls *.o` && \
+ test \! -f snes9x && \
+ export RELNR && export RELNAME && \
+ (cd .. && PWD=`pwd` && SNESDIR=`basename $$PWD` && cd .. && \
+ DISTDIR=disttmp/$${RELNAME} && \
+ rm -rf disttmp && \
+ mkdir disttmp && \
+ cp -r $${SNESDIR} $${DISTDIR} && \
+ rm -f $${DISTDIR}/snes9x/config.* 2>/dev/null && \
+ rm -f $${DISTDIR}/snes9x/conftezt.out.* 2>/dev/null && \
+ rm -rf $${DISTDIR}/snes9x/autom4te.cache 2>/dev/null && \
+ rm $${DISTDIR}/snes9x/Makefile && \
+ find disttmp -name CVS -type f -exec rm "{}" \; && \
+ find disttmp -name CVS -type d -exec rm "{}" \; && \
+ (cd disttmp && tar cvf - $${RELNAME}) | gzip -c > $${RELNAME}.tar.gz && \
+ mv $${RELNAME}.tar.gz $${SNESDIR}/snes9x/ ) && \
+ rm -rf disttmp
+
+#Requires:
+# 1. Prestine checkout
+# 2. `autoconf`
+# 3. `./configure`
+src-release: depend _src-package
+
+xenofarm:
+ ./xenofarm.sh
+ cd build/xenofarm && tar cf - . > ../../../xenofarm_result.tar
+ gzip -f9 ../xenofarm_result.tar
+
+# And now for the impressive testsuite:
+verify: snes9x
+ ./snes9x --selftest
+
+#FIXME: Make a auto-self-reference.
+depend:
+ $(CC) $(CFLAGS) -MM -MG \
+ `find . '(' -name '*.c' -o -name '*.cpp' -o -name '*.S' ')' -print -o -name msdos -prune` \
+ | sed -e 's@^[^ :]*: *\([^ ]*/\)[^ /]*@\1&@' \
+ >dependencies
+
+include dependencies
+
diff --git a/source/apu.cpp b/source/apu.cpp
new file mode 100644
index 0000000..3abb669
--- /dev/null
+++ b/source/apu.cpp
@@ -0,0 +1,959 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifdef __DJGPP
+#include <allegro.h>
+#undef TRUE
+#endif
+
+#include "snes9x.h"
+#include "spc700.h"
+#include "apu.h"
+#include "soundux.h"
+#include "cpuexec.h"
+
+/* For note-triggered SPC dump support */
+#include "snapshot.h"
+
+extern "C" {const char *S9xGetFilenameInc (const char *);}
+
+int spc_is_dumping=0;
+int spc_is_dumping_temp;
+uint8 spc_dump_dsp[0x100];
+
+extern int NoiseFreq [32];
+#ifdef DEBUGGER
+void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
+ int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0);
+#endif
+
+bool8 S9xInitAPU ()
+{
+ IAPU.RAM = (uint8 *) malloc (0x10000);
+ IAPU.ShadowRAM = (uint8 *) malloc (0x10000);
+ IAPU.CachedSamples = (uint8 *) malloc (0x40000);
+
+ if (!IAPU.RAM || !IAPU.ShadowRAM || !IAPU.CachedSamples)
+ {
+ S9xDeinitAPU ();
+ return (FALSE);
+ }
+
+ memset(IAPU.RAM, 0, 0x10000);
+ memset(IAPU.ShadowRAM, 0, 0x10000);
+ memset(IAPU.CachedSamples, 0, 0x40000);
+
+ return (TRUE);
+}
+
+void S9xDeinitAPU ()
+{
+ if (IAPU.RAM)
+ {
+ free ((char *) IAPU.RAM);
+ IAPU.RAM = NULL;
+ }
+ if (IAPU.ShadowRAM)
+ {
+ free ((char *) IAPU.ShadowRAM);
+ IAPU.ShadowRAM = NULL;
+ }
+ if (IAPU.CachedSamples)
+ {
+ free ((char *) IAPU.CachedSamples);
+ IAPU.CachedSamples = NULL;
+ }
+}
+
+EXTERN_C uint8 APUROM [64];
+
+void S9xResetAPU ()
+{
+
+ int i;
+
+ Settings.APUEnabled = Settings.NextAPUEnabled;
+
+ ZeroMemory(spc_dump_dsp, 0x100);
+ ZeroMemory(IAPU.RAM, 0x100);
+ memset(IAPU.RAM+0x20, 0xFF, 0x20);
+ memset(IAPU.RAM+0x60, 0xFF, 0x20);
+ memset(IAPU.RAM+0xA0, 0xFF, 0x20);
+ memset(IAPU.RAM+0xE0, 0xFF, 0x20);
+
+ for(i=1;i<256;i++)
+ {
+ memcpy(IAPU.RAM+(i<<8), IAPU.RAM, 0x100);
+ }
+
+ memcpy (IAPU.ShadowRAM, IAPU.RAM, 0x10000);
+
+ ZeroMemory (IAPU.CachedSamples, 0x40000);
+ ZeroMemory (APU.OutPorts, 4);
+ IAPU.DirectPage = IAPU.RAM;
+ memmove (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM));
+ memmove (APU.ExtraRAM, APUROM, sizeof (APUROM));
+ IAPU.PC = IAPU.RAM + IAPU.RAM [0xfffe] + (IAPU.RAM [0xffff] << 8);
+ APU.Cycles = 0;
+ APURegisters.YA.W = 0;
+ APURegisters.X = 0;
+ APURegisters.S = 0xff;
+ APURegisters.P = 0;
+ S9xAPUUnpackStatus ();
+ APURegisters.PC = 0;
+ IAPU.APUExecuting = Settings.APUEnabled;
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitAddress1 = NULL;
+ IAPU.WaitAddress2 = NULL;
+ IAPU.WaitCounter = 0;
+#endif
+ APU.ShowROM = TRUE;
+ IAPU.RAM [0xf1] = 0x80;
+
+ for (i = 0; i < 3; i++)
+ {
+ APU.TimerEnabled [i] = FALSE;
+ APU.TimerValueWritten [i] = 0;
+ APU.TimerTarget [i] = 0;
+ APU.Timer [i] = 0;
+ }
+ for (int j = 0; j < 0x80; j++)
+ APU.DSP [j] = 0;
+
+ IAPU.TwoCycles = IAPU.OneCycle * 2;
+
+ for (i = 0; i < 256; i++)
+ S9xAPUCycles [i] = S9xAPUCycleLengths [i] * IAPU.OneCycle;
+
+ APU.DSP [APU_ENDX] = 0;
+ APU.DSP [APU_KOFF] = 0;
+ APU.DSP [APU_KON] = 0;
+ APU.DSP [APU_FLG] = APU_MUTE | APU_ECHO_DISABLED;
+ APU.KeyedChannels = 0;
+
+ S9xResetSound (TRUE);
+ S9xSetEchoEnable (0);
+}
+
+void S9xSetAPUDSP (uint8 byte)
+{
+ uint8 reg = IAPU.RAM [0xf2];
+ static uint8 KeyOn;
+ static uint8 KeyOnPrev;
+ int i;
+
+ spc_dump_dsp[reg] = byte;
+
+ switch (reg)
+ {
+ case APU_FLG:
+ if (byte & APU_SOFT_RESET)
+ {
+ APU.DSP [reg] = APU_MUTE | APU_ECHO_DISABLED | (byte & 0x1f);
+ APU.DSP [APU_ENDX] = 0;
+ APU.DSP [APU_KOFF] = 0;
+ APU.DSP [APU_KON] = 0;
+ S9xSetEchoWriteEnable (FALSE);
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] DSP reset\n", ICPU.Scanline);
+#endif
+ // Kill sound
+ S9xResetSound (FALSE);
+ }
+ else
+ {
+ S9xSetEchoWriteEnable (!(byte & APU_ECHO_DISABLED));
+ if (byte & APU_MUTE)
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Mute sound\n", ICPU.Scanline);
+#endif
+ S9xSetSoundMute (TRUE);
+ }
+ else
+ S9xSetSoundMute (FALSE);
+
+ SoundData.noise_hertz = NoiseFreq [byte & 0x1f];
+ for (i = 0; i < 8; i++)
+ {
+ if (SoundData.channels [i].type == SOUND_NOISE)
+ S9xSetSoundFrequency (i, SoundData.noise_hertz);
+ }
+ }
+ break;
+ case APU_NON:
+ if (byte != APU.DSP [APU_NON])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Noise:", ICPU.Scanline);
+#endif
+ uint8 mask = 1;
+ for (int c = 0; c < 8; c++, mask <<= 1)
+ {
+ int type;
+ if (byte & mask)
+ {
+ type = SOUND_NOISE;
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ {
+ if (APU.DSP [reg] & mask)
+ S9xTraceSoundDSP ("%d,", c);
+ else
+ S9xTraceSoundDSP ("%d(on),", c);
+ }
+#endif
+ }
+ else
+ {
+ type = SOUND_SAMPLE;
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ {
+ if (APU.DSP [reg] & mask)
+ S9xTraceSoundDSP ("%d(off),", c);
+ }
+#endif
+ }
+ S9xSetSoundType (c, type);
+ }
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("\n");
+#endif
+ }
+ break;
+ case APU_MVOL_LEFT:
+ if (byte != APU.DSP [APU_MVOL_LEFT])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Master volume left:%d\n",
+ ICPU.Scanline, (signed char) byte);
+#endif
+ S9xSetMasterVolume ((signed char) byte,
+ (signed char) APU.DSP [APU_MVOL_RIGHT]);
+ }
+ break;
+ case APU_MVOL_RIGHT:
+ if (byte != APU.DSP [APU_MVOL_RIGHT])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Master volume right:%d\n",
+ ICPU.Scanline, (signed char) byte);
+#endif
+ S9xSetMasterVolume ((signed char) APU.DSP [APU_MVOL_LEFT],
+ (signed char) byte);
+ }
+ break;
+ case APU_EVOL_LEFT:
+ if (byte != APU.DSP [APU_EVOL_LEFT])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Echo volume left:%d\n",
+ ICPU.Scanline, (signed char) byte);
+#endif
+ S9xSetEchoVolume ((signed char) byte,
+ (signed char) APU.DSP [APU_EVOL_RIGHT]);
+ }
+ break;
+ case APU_EVOL_RIGHT:
+ if (byte != APU.DSP [APU_EVOL_RIGHT])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Echo volume right:%d\n",
+ ICPU.Scanline, (signed char) byte);
+#endif
+ S9xSetEchoVolume ((signed char) APU.DSP [APU_EVOL_LEFT],
+ (signed char) byte);
+ }
+ break;
+ case APU_ENDX:
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Reset ENDX\n", ICPU.Scanline);
+#endif
+ byte = 0;
+ break;
+
+ case APU_KOFF:
+ // if (byte)
+ {
+ uint8 mask = 1;
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Key off:", ICPU.Scanline);
+#endif
+ for (int c = 0; c < 8; c++, mask <<= 1)
+ {
+ if ((byte & mask) != 0)
+ {
+#ifdef DEBUGGER
+
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("%d,", c);
+#endif
+ if (APU.KeyedChannels & mask)
+ {
+ {
+ KeyOnPrev&=~mask;
+ APU.KeyedChannels &= ~mask;
+ APU.DSP [APU_KON] &= ~mask;
+ //APU.DSP [APU_KOFF] |= mask;
+ S9xSetSoundKeyOff (c);
+ }
+ }
+ }
+ else if((KeyOnPrev&mask)!=0)
+ {
+ KeyOnPrev&=~mask;
+ APU.KeyedChannels |= mask;
+ //APU.DSP [APU_KON] |= mask;
+ APU.DSP [APU_KOFF] &= ~mask;
+ APU.DSP [APU_ENDX] &= ~mask;
+ S9xPlaySample (c);
+ }
+ }
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("\n");
+#endif
+ }
+ //KeyOnPrev=0;
+ APU.DSP [APU_KOFF] = byte;
+ return;
+ case APU_KON:
+ if (spc_is_dumping)
+ {
+ if (byte & ~spc_is_dumping_temp)
+ {
+ APURegisters.PC = IAPU.PC - IAPU.RAM;
+ S9xAPUPackStatus();
+ S9xSPCDump (S9xGetFilenameInc (".spc"));
+ spc_is_dumping = 0;
+ }
+ }
+ if (byte)
+ {
+ uint8 mask = 1;
+#ifdef DEBUGGER
+
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Key on:", ICPU.Scanline);
+#endif
+ for (int c = 0; c < 8; c++, mask <<= 1)
+ {
+ if ((byte & mask) != 0)
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("%d,", c);
+#endif
+ // Pac-In-Time requires that channels can be key-on
+ // regardeless of their current state.
+ if((APU.DSP [APU_KOFF] & mask) ==0)
+ {
+ KeyOnPrev&=~mask;
+ APU.KeyedChannels |= mask;
+ //APU.DSP [APU_KON] |= mask;
+ //APU.DSP [APU_KOFF] &= ~mask;
+ APU.DSP [APU_ENDX] &= ~mask;
+ S9xPlaySample (c);
+ }
+ else KeyOn|=mask;
+ }
+ }
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("\n");
+#endif
+ }
+ spc_is_dumping_temp = byte;
+ return;
+
+ case APU_VOL_LEFT + 0x00:
+ case APU_VOL_LEFT + 0x10:
+ case APU_VOL_LEFT + 0x20:
+ case APU_VOL_LEFT + 0x30:
+ case APU_VOL_LEFT + 0x40:
+ case APU_VOL_LEFT + 0x50:
+ case APU_VOL_LEFT + 0x60:
+ case APU_VOL_LEFT + 0x70:
+ // At Shin Megami Tensei suggestion 6/11/00
+ // if (byte != APU.DSP [reg])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d volume left: %d\n",
+ ICPU.Scanline, reg>>4, (signed char) byte);
+#endif
+ S9xSetSoundVolume (reg >> 4, (signed char) byte,
+ (signed char) APU.DSP [reg + 1]);
+ }
+ break;
+ case APU_VOL_RIGHT + 0x00:
+ case APU_VOL_RIGHT + 0x10:
+ case APU_VOL_RIGHT + 0x20:
+ case APU_VOL_RIGHT + 0x30:
+ case APU_VOL_RIGHT + 0x40:
+ case APU_VOL_RIGHT + 0x50:
+ case APU_VOL_RIGHT + 0x60:
+ case APU_VOL_RIGHT + 0x70:
+ // At Shin Megami Tensei suggestion 6/11/00
+ // if (byte != APU.DSP [reg])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d volume right: %d\n",
+ ICPU.Scanline, reg >>4, (signed char) byte);
+#endif
+ S9xSetSoundVolume (reg >> 4, (signed char) APU.DSP [reg - 1],
+ (signed char) byte);
+ }
+ break;
+
+ case APU_P_LOW + 0x00:
+ case APU_P_LOW + 0x10:
+ case APU_P_LOW + 0x20:
+ case APU_P_LOW + 0x30:
+ case APU_P_LOW + 0x40:
+ case APU_P_LOW + 0x50:
+ case APU_P_LOW + 0x60:
+ case APU_P_LOW + 0x70:
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d freq low: %d\n",
+ ICPU.Scanline, reg>>4, byte);
+#endif
+ S9xSetSoundHertz (reg >> 4, ((byte + (APU.DSP [reg + 1] << 8)) & FREQUENCY_MASK) * 8);
+ break;
+
+ case APU_P_HIGH + 0x00:
+ case APU_P_HIGH + 0x10:
+ case APU_P_HIGH + 0x20:
+ case APU_P_HIGH + 0x30:
+ case APU_P_HIGH + 0x40:
+ case APU_P_HIGH + 0x50:
+ case APU_P_HIGH + 0x60:
+ case APU_P_HIGH + 0x70:
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d freq high: %d\n",
+ ICPU.Scanline, reg>>4, byte);
+#endif
+ S9xSetSoundHertz (reg >> 4,
+ (((byte << 8) + APU.DSP [reg - 1]) & FREQUENCY_MASK) * 8);
+ break;
+
+ case APU_SRCN + 0x00:
+ case APU_SRCN + 0x10:
+ case APU_SRCN + 0x20:
+ case APU_SRCN + 0x30:
+ case APU_SRCN + 0x40:
+ case APU_SRCN + 0x50:
+ case APU_SRCN + 0x60:
+ case APU_SRCN + 0x70:
+ if (byte != APU.DSP [reg])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d sample number: %d\n",
+ ICPU.Scanline, reg>>4, byte);
+#endif
+ S9xSetSoundSample (reg >> 4, byte);
+ }
+ break;
+
+ case APU_ADSR1 + 0x00:
+ case APU_ADSR1 + 0x10:
+ case APU_ADSR1 + 0x20:
+ case APU_ADSR1 + 0x30:
+ case APU_ADSR1 + 0x40:
+ case APU_ADSR1 + 0x50:
+ case APU_ADSR1 + 0x60:
+ case APU_ADSR1 + 0x70:
+ if (byte != APU.DSP [reg])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d adsr1: %02x\n",
+ ICPU.Scanline, reg>>4, byte);
+#endif
+ {
+ S9xFixEnvelope (reg >> 4, APU.DSP [reg + 2], byte,
+ APU.DSP [reg + 1]);
+ }
+ }
+ break;
+
+ case APU_ADSR2 + 0x00:
+ case APU_ADSR2 + 0x10:
+ case APU_ADSR2 + 0x20:
+ case APU_ADSR2 + 0x30:
+ case APU_ADSR2 + 0x40:
+ case APU_ADSR2 + 0x50:
+ case APU_ADSR2 + 0x60:
+ case APU_ADSR2 + 0x70:
+ if (byte != APU.DSP [reg])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d adsr2: %02x\n",
+ ICPU.Scanline, reg>>4, byte);
+#endif
+ {
+ S9xFixEnvelope (reg >> 4, APU.DSP [reg + 1], APU.DSP [reg - 1],
+ byte);
+ }
+ }
+ break;
+
+ case APU_GAIN + 0x00:
+ case APU_GAIN + 0x10:
+ case APU_GAIN + 0x20:
+ case APU_GAIN + 0x30:
+ case APU_GAIN + 0x40:
+ case APU_GAIN + 0x50:
+ case APU_GAIN + 0x60:
+ case APU_GAIN + 0x70:
+ if (byte != APU.DSP [reg])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] %d gain: %02x\n",
+ ICPU.Scanline, reg>>4, byte);
+#endif
+ {
+ S9xFixEnvelope (reg >> 4, byte, APU.DSP [reg - 2],
+ APU.DSP [reg - 1]);
+ }
+ }
+ break;
+
+ case APU_ENVX + 0x00:
+ case APU_ENVX + 0x10:
+ case APU_ENVX + 0x20:
+ case APU_ENVX + 0x30:
+ case APU_ENVX + 0x40:
+ case APU_ENVX + 0x50:
+ case APU_ENVX + 0x60:
+ case APU_ENVX + 0x70:
+ break;
+
+ case APU_OUTX + 0x00:
+ case APU_OUTX + 0x10:
+ case APU_OUTX + 0x20:
+ case APU_OUTX + 0x30:
+ case APU_OUTX + 0x40:
+ case APU_OUTX + 0x50:
+ case APU_OUTX + 0x60:
+ case APU_OUTX + 0x70:
+ break;
+
+ case APU_DIR:
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ S9xTraceSoundDSP ("[%d] Sample directory to: %02x\n",
+ ICPU.Scanline, byte);
+#endif
+ break;
+
+ case APU_PMON:
+ if (byte != APU.DSP [APU_PMON])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ {
+ S9xTraceSoundDSP ("[%d] FreqMod:", ICPU.Scanline);
+ uint8 mask = 1;
+ for (int c = 0; c < 8; c++, mask <<= 1)
+ {
+ if (byte & mask)
+ {
+ if (APU.DSP [reg] & mask)
+ S9xTraceSoundDSP ("%d", c);
+ else
+ S9xTraceSoundDSP ("%d(on),", c);
+ }
+ else
+ {
+ if (APU.DSP [reg] & mask)
+ S9xTraceSoundDSP ("%d(off),", c);
+ }
+ }
+ S9xTraceSoundDSP ("\n");
+ }
+#endif
+ S9xSetFrequencyModulationEnable (byte);
+ }
+ break;
+
+ case APU_EON:
+ if (byte != APU.DSP [APU_EON])
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP)
+ {
+ S9xTraceSoundDSP ("[%d] Echo:", ICPU.Scanline);
+ uint8 mask = 1;
+ for (int c = 0; c < 8; c++, mask <<= 1)
+ {
+ if (byte & mask)
+ {
+ if (APU.DSP [reg] & mask)
+ S9xTraceSoundDSP ("%d", c);
+ else
+ S9xTraceSoundDSP ("%d(on),", c);
+ }
+ else
+ {
+ if (APU.DSP [reg] & mask)
+ S9xTraceSoundDSP ("%d(off),", c);
+ }
+ }
+ S9xTraceSoundDSP ("\n");
+ }
+#endif
+ S9xSetEchoEnable (byte);
+ }
+ break;
+
+ case APU_EFB:
+ S9xSetEchoFeedback ((signed char) byte);
+ break;
+
+ case APU_ESA:
+ break;
+
+ case APU_EDL:
+ S9xSetEchoDelay (byte & 0xf);
+ break;
+
+ case APU_C0:
+ case APU_C1:
+ case APU_C2:
+ case APU_C3:
+ case APU_C4:
+ case APU_C5:
+ case APU_C6:
+ case APU_C7:
+ S9xSetFilterCoefficient (reg >> 4, (signed char) byte);
+ break;
+ default:
+ // XXX
+ //printf ("Write %02x to unknown APU register %02x\n", byte, reg);
+ break;
+ }
+
+ KeyOnPrev|=KeyOn;
+ KeyOn=0;
+
+ if (reg < 0x80)
+ APU.DSP [reg] = byte;
+}
+
+void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2)
+{
+ if (adsr1 & 0x80)
+ {
+ // ADSR mode
+ static unsigned long AttackRate [16] = {
+ 4100, 2600, 1500, 1000, 640, 380, 260, 160,
+ 96, 64, 40, 24, 16, 10, 6, 1
+ };
+ static unsigned long DecayRate [8] = {
+ 1200, 740, 440, 290, 180, 110, 74, 37
+ };
+ static unsigned long SustainRate [32] = {
+ ~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400,
+ 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500,
+ 1200, 880, 740, 590, 440, 370, 290, 220,
+ 180, 150, 110, 92, 74, 55, 37, 18
+ };
+ // XXX: can DSP be switched to ADSR mode directly from GAIN/INCREASE/
+ // DECREASE mode? And if so, what stage of the sequence does it start
+ // at?
+ if (S9xSetSoundMode (channel, MODE_ADSR))
+ {
+ // Hack for ROMs that use a very short attack rate, key on a
+ // channel, then switch to decay mode. e.g. Final Fantasy II.
+
+ int attack = AttackRate [adsr1 & 0xf];
+
+ if (attack == 1 && (!Settings.SoundSync
+#ifdef __WIN32__
+ || Settings.SoundDriver != WIN_SNES9X_DIRECT_SOUND_DRIVER
+#endif
+ ))
+ attack = 0;
+
+ S9xSetSoundADSR (channel, attack,
+ DecayRate [(adsr1 >> 4) & 7],
+ SustainRate [adsr2 & 0x1f],
+ (adsr2 >> 5) & 7, 8);
+ }
+ }
+ else
+ {
+ // Gain mode
+ if ((gain & 0x80) == 0)
+ {
+ if (S9xSetSoundMode (channel, MODE_GAIN))
+ {
+ S9xSetEnvelopeRate (channel, 0, 0, gain & 0x7f);
+ S9xSetEnvelopeHeight (channel, gain & 0x7f);
+ }
+ }
+ else
+ {
+ static unsigned long IncreaseRate [32] = {
+ ~0, 4100, 3100, 2600, 2000, 1500, 1300, 1000,
+ 770, 640, 510, 380, 320, 260, 190, 160,
+ 130, 96, 80, 64, 48, 40, 32, 24,
+ 20, 16, 12, 10, 8, 6, 4, 2
+ };
+ static unsigned long DecreaseRateExp [32] = {
+ ~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400,
+ 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500,
+ 1200, 880, 740, 590, 440, 370, 290, 220,
+ 180, 150, 110, 92, 74, 55, 37, 18
+ };
+ if (gain & 0x40)
+ {
+ // Increase mode
+ if (S9xSetSoundMode (channel, (gain & 0x20) ?
+MODE_INCREASE_BENT_LINE :
+ MODE_INCREASE_LINEAR))
+ {
+ S9xSetEnvelopeRate (channel, IncreaseRate [gain & 0x1f],
+ 1, 127);
+ }
+ }
+ else
+ {
+ uint32 rate = (gain & 0x20) ? DecreaseRateExp [gain & 0x1f] / 2 :
+ IncreaseRate [gain & 0x1f];
+ int mode = (gain & 0x20) ? MODE_DECREASE_EXPONENTIAL
+ : MODE_DECREASE_LINEAR;
+
+ if (S9xSetSoundMode (channel, mode))
+ S9xSetEnvelopeRate (channel, rate, -1, 0);
+ }
+ }
+ }
+}
+
+void S9xSetAPUControl (uint8 byte)
+{
+ //if (byte & 0x40)
+ //printf ("*** Special SPC700 timing enabled\n");
+ if ((byte & 1) != 0 && !APU.TimerEnabled [0])
+ {
+ APU.Timer [0] = 0;
+ IAPU.RAM [0xfd] = 0;
+ if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0)
+ APU.TimerTarget [0] = 0x100;
+ }
+ if ((byte & 2) != 0 && !APU.TimerEnabled [1])
+ {
+ APU.Timer [1] = 0;
+ IAPU.RAM [0xfe] = 0;
+ if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0)
+ APU.TimerTarget [1] = 0x100;
+ }
+ if ((byte & 4) != 0 && !APU.TimerEnabled [2])
+ {
+ APU.Timer [2] = 0;
+ IAPU.RAM [0xff] = 0;
+ if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0)
+ APU.TimerTarget [2] = 0x100;
+ }
+ APU.TimerEnabled [0] = byte & 1;
+ APU.TimerEnabled [1] = (byte & 2) >> 1;
+ APU.TimerEnabled [2] = (byte & 4) >> 2;
+
+ if (byte & 0x10)
+ IAPU.RAM [0xF4] = IAPU.RAM [0xF5] = 0;
+
+ if (byte & 0x20)
+ IAPU.RAM [0xF6] = IAPU.RAM [0xF7] = 0;
+
+ if (byte & 0x80)
+ {
+ if (!APU.ShowROM)
+ {
+ memmove (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM));
+ APU.ShowROM = TRUE;
+ }
+ }
+ else
+ {
+ if (APU.ShowROM)
+ {
+ APU.ShowROM = FALSE;
+ memmove (&IAPU.RAM [0xffc0], APU.ExtraRAM, sizeof (APUROM));
+ }
+ }
+ IAPU.RAM [0xf1] = byte;
+}
+
+void S9xSetAPUTimer (uint16 Address, uint8 byte)
+{
+ IAPU.RAM [Address] = byte;
+
+ switch (Address)
+ {
+ case 0xfa:
+ if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0)
+ APU.TimerTarget [0] = 0x100;
+ APU.TimerValueWritten [0] = TRUE;
+ break;
+ case 0xfb:
+ if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0)
+ APU.TimerTarget [1] = 0x100;
+ APU.TimerValueWritten [1] = TRUE;
+ break;
+ case 0xfc:
+ if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0)
+ APU.TimerTarget [2] = 0x100;
+ APU.TimerValueWritten [2] = TRUE;
+ break;
+ }
+}
+
+uint8 S9xGetAPUDSP ()
+{
+ uint8 reg = IAPU.RAM [0xf2] & 0x7f;
+ uint8 byte = APU.DSP [reg];
+
+ switch (reg)
+ {
+ case APU_KON:
+ break;
+ case APU_KOFF:
+ break;
+ case APU_OUTX + 0x00:
+ case APU_OUTX + 0x10:
+ case APU_OUTX + 0x20:
+ case APU_OUTX + 0x30:
+ case APU_OUTX + 0x40:
+ case APU_OUTX + 0x50:
+ case APU_OUTX + 0x60:
+ case APU_OUTX + 0x70:
+ if (SoundData.channels [reg >> 4].state == SOUND_SILENT)
+ return (0);
+ return ((SoundData.channels [reg >> 4].sample >> 8) |
+ (SoundData.channels [reg >> 4].sample & 0xff));
+
+ case APU_ENVX + 0x00:
+ case APU_ENVX + 0x10:
+ case APU_ENVX + 0x20:
+ case APU_ENVX + 0x30:
+ case APU_ENVX + 0x40:
+ case APU_ENVX + 0x50:
+ case APU_ENVX + 0x60:
+ case APU_ENVX + 0x70:
+ return ((uint8) S9xGetEnvelopeHeight (reg >> 4));
+
+ case APU_ENDX:
+ // To fix speech in Magical Drop 2 6/11/00
+ // APU.DSP [APU_ENDX] = 0;
+ break;
+ default:
+ break;
+ }
+ return (byte);
+}
+
diff --git a/source/apu.h b/source/apu.h
new file mode 100644
index 0000000..0a64e34
--- /dev/null
+++ b/source/apu.h
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _apu_h_
+#define _apu_h_
+
+#include "spc700.h"
+
+struct SIAPU
+{
+ uint8 *PC;
+ uint8 *RAM;
+ uint8 *DirectPage;
+ bool8 APUExecuting;
+ uint8 Bit;
+ uint32 Address;
+ uint8 *WaitAddress1;
+ uint8 *WaitAddress2;
+ uint32 WaitCounter;
+ uint8 *ShadowRAM;
+ uint8 *CachedSamples;
+ uint8 _Carry;
+ uint8 _Zero;
+ uint8 _Overflow;
+ uint32 TimerErrorCounter;
+ uint32 Scanline;
+ int32 OneCycle;
+ int32 TwoCycles;
+};
+
+struct SAPU
+{
+ int32 Cycles;
+ bool8 ShowROM;
+ uint8 Flags;
+ uint8 KeyedChannels;
+ uint8 OutPorts [4];
+ uint8 DSP [0x80];
+ uint8 ExtraRAM [64];
+ uint16 Timer [3];
+ uint16 TimerTarget [3];
+ bool8 TimerEnabled [3];
+ bool8 TimerValueWritten [3];
+};
+
+EXTERN_C struct SAPU APU;
+EXTERN_C struct SIAPU IAPU;
+extern int spc_is_dumping;
+extern int spc_is_dumping_temp;
+extern uint8 spc_dump_dsp[0x100];
+STATIC inline void S9xAPUUnpackStatus()
+{
+ IAPU._Zero = ((APURegisters.P & Zero) == 0) | (APURegisters.P & Negative);
+ IAPU._Carry = (APURegisters.P & Carry);
+ IAPU._Overflow = (APURegisters.P & Overflow) >> 6;
+}
+
+STATIC inline void S9xAPUPackStatus()
+{
+ APURegisters.P &= ~(Zero | Negative | Carry | Overflow);
+ APURegisters.P |= IAPU._Carry | ((IAPU._Zero == 0) << 1) |
+ (IAPU._Zero & 0x80) | (IAPU._Overflow << 6);
+}
+
+START_EXTERN_C
+void S9xResetAPU (void);
+bool8 S9xInitAPU ();
+void S9xDeinitAPU ();
+void S9xDecacheSamples ();
+int S9xTraceAPU ();
+int S9xAPUOPrint (char *buffer, uint16 Address);
+void S9xSetAPUControl (uint8 byte);
+void S9xSetAPUDSP (uint8 byte);
+uint8 S9xGetAPUDSP ();
+void S9xSetAPUTimer (uint16 Address, uint8 byte);
+bool8 S9xInitSound (int quality, bool8 stereo, int buffer_size);
+void S9xOpenCloseSoundTracingFile (bool8);
+void S9xPrintAPUState ();
+extern int32 S9xAPUCycles [256]; // Scaled cycle lengths
+extern int32 S9xAPUCycleLengths [256]; // Raw data.
+extern void (*S9xApuOpcodes [256]) (void);
+END_EXTERN_C
+
+
+#define APU_VOL_LEFT 0x00
+#define APU_VOL_RIGHT 0x01
+#define APU_P_LOW 0x02
+#define APU_P_HIGH 0x03
+#define APU_SRCN 0x04
+#define APU_ADSR1 0x05
+#define APU_ADSR2 0x06
+#define APU_GAIN 0x07
+#define APU_ENVX 0x08
+#define APU_OUTX 0x09
+
+#define APU_MVOL_LEFT 0x0c
+#define APU_MVOL_RIGHT 0x1c
+#define APU_EVOL_LEFT 0x2c
+#define APU_EVOL_RIGHT 0x3c
+#define APU_KON 0x4c
+#define APU_KOFF 0x5c
+#define APU_FLG 0x6c
+#define APU_ENDX 0x7c
+
+#define APU_EFB 0x0d
+#define APU_PMON 0x2d
+#define APU_NON 0x3d
+#define APU_EON 0x4d
+#define APU_DIR 0x5d
+#define APU_ESA 0x6d
+#define APU_EDL 0x7d
+
+#define APU_C0 0x0f
+#define APU_C1 0x1f
+#define APU_C2 0x2f
+#define APU_C3 0x3f
+#define APU_C4 0x4f
+#define APU_C5 0x5f
+#define APU_C6 0x6f
+#define APU_C7 0x7f
+
+#define APU_SOFT_RESET 0x80
+#define APU_MUTE 0x40
+#define APU_ECHO_DISABLED 0x20
+
+#define FREQUENCY_MASK 0x3fff
+#endif
+
diff --git a/source/apudebug.cpp b/source/apudebug.cpp
new file mode 100644
index 0000000..a016977
--- /dev/null
+++ b/source/apudebug.cpp
@@ -0,0 +1,439 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "spc700.h"
+#include "apu.h"
+#include "soundux.h"
+#include "cpuexec.h"
+
+#ifdef SPCTOOL
+#include "spctool/spc700.h"
+#endif
+
+#ifdef DEBUGGER
+extern int NoiseFreq [32];
+
+FILE *apu_trace = NULL;
+
+static char *S9xMnemonics [256] = {
+"NOP", "TCALL0", "SET0 $%02X", "BBS0 $%02X,$%04X",
+"OR A,$%02X", "OR A,$%04X", "OR A,(X)", "OR A,($%02X+X)",
+"OR A,#$%02X", "OR $%02X,$%02X", "OR1 C,$%04X,%d", "ASL $%02X",
+"ASL $%04X", "PUSH PSW", "TSET1 $%04X", "BRK",
+"BPL $%04X", "TCALL1", "CLR0 $%02X", "BBC0 $%02X,$%04X",
+"OR A,$%02X+X", "OR A,$%04X+X", "OR A,$%04X+Y", "OR A,($%02X)+Y",
+"OR $%02X,#$%02X", "OR (X),(Y)", "DECW $%02X", "ASL $%02X+X",
+"ASL A", "DEC X", "CMP X,$%04X", "JMP ($%04X+X)",
+"CLRP", "TCALL2", "SET1 $%02X", "BBS1 $%02X,$%04X",
+"AND A,$%02X", "AND A,$%04X", "AND A,(X)", "AND A,($%02X+X)",
+"AND A,$%02X", "AND $%02X,$%02X", "OR1 C,$%04X, not %d", "ROL $%02X",
+"ROL $%04X", "PUSH A", "CBNE $%02X,$%04X", "BRA $%04X",
+"BMI $%04X", "TCALL3", "CLR1 $%02X", "BBC1 $%02X,$%04X",
+"AND A,$%02X+X", "AND A,$%04X+X", "AND A,$%04X+Y", "AND A,($%02X)+Y",
+"AND $%02X,#$%02X", "AND (X),(Y)", "INCW $%02X", "ROL $%02X+X",
+"ROL A", "INC X", "CMP X,$%02X", "CALL $%04X",
+"SETP", "TCALL4", "SET2 $%02X", "BBS2 $%02X,$%04X",
+"EOR A,$%02X", "EOR A,$%04X", "EOR A,(X)", "EOR A,($%02X+X)",
+"EOR A,#$%02X", "EOR $%02X,$%02X", "AND1 C,$%04X,%d", "LSR $%02X",
+"LSR $%04X", "PUSH X", "TCLR1 $%04X", "PCALL $%02X",
+"BVC $%04X", "TCALL5", "CLR2 $%02X", "BBC2 $%02X,$%04X",
+"EOR A,$%02X+X", "EOR A,$%04X+X", "EOR A,$%04X+Y", "EOR A,($%02X)+Y",
+"EOR $%02X,#$%02X", "EOR (X),(Y)", "CMPW YA,$%02X", "LSR $%02X+X",
+"LSR A", "MOV X,A", "CMP Y,$%04X", "JMP $%04X",
+"CLRC", "TCALL6", "SET3 $%02X", "BBS3 $%02X,$%04X",
+"CMP A,$%02X", "CMP A,$%04X", "CMP A,(X)", "CMP A,($%02X+X)",
+"CMP A,#$%02X", "CMP $%02X,$%02X", "AND1 C, $%04X, not %d", "ROR $%02X",
+"ROR $%04X", "PUSH Y", "DBNZ $%02X,$%04X", "RET",
+"BVS $%04X", "TCALL7", "CLR3 $%02X", "BBC3 $%02X,$%04X",
+"CMP A,$%02X+X", "CMP A,$%04X+X", "CMP A,$%04X+Y", "CMP A,($%02X)+Y",
+"CMP $%02X,#$%02X", "CMP (X),(Y)", "ADDW YA,$%02X", "ROR $%02X+X",
+"ROR A", "MOV A,X", "CMP Y,$%02X", "RETI",
+"SETC", "TCALL8", "SET4 $%02X", "BBS4 $%02X,$%04X",
+"ADC A,$%02X", "ADC A,$%04X", "ADC A,(X)", "ADC A,($%02X+X)",
+"ADC A,#$%02X", "ADC $%02X,$%02X", "EOR1 C,%04,%d", "DEC $%02X",
+"DEC $%04X", "MOV Y,#$%02X", "POP PSW", "MOV $%02X,#$%02X",
+"BCC $%04X", "TCALL9", "CLR4 $%02X", "BBC4 $%02X,$%04X",
+"ADC A,$%02X+X", "ADC A,$%04X+X", "ADC A,$%04X+Y", "ADC A,($%02X)+Y",
+"ADC $%02X,#$%02X", "ADC (X),(Y)", "SUBW YA,$%02X", "DEC $%02X+X",
+"DEC A", "MOV X,SP", "DIV YA,X", "XCN A",
+"EI", "TCALL10", "SET5 $%02X", "BBS5 $%02X,$%04X",
+"SBC A,$%02X", "SBC A,$%04X", "SBC A,(X)", "SBC A,($%02X+X)",
+"SBC A,#$%02X", "SBC $%02X,$%02X", "MOV1 C,$%04X,%d", "INC $%02X",
+"INC $%04X", "CMP Y,#$%02X", "POP A", "MOV (X)+,A",
+"BCS $%04X", "TCALL11", "CLR5 $%02X", "BBC5 $%02X,$%04X",
+"SBC A,$%02X+X", "SBC A,$%04X+X", "SBC A,$%04X+Y", "SBC A,($%02X)+Y",
+"SBC $%02X,#$%02X", "SBC (X),(Y)", "MOVW YA,$%02X", "INC $%02X+X",
+"INC A", "MOV SP,X", "DAS", "MOV A,(X)+",
+"DI", "TCALL12", "SET6 $%02X", "BBS6 $%02X,$%04X",
+"MOV $%02X,A", "MOV $%04X,A", "MOV (X),A", "MOV ($%02X+X),A",
+"CMP X,#$%02X", "MOV $%04X,X", "MOV1 $%04X,%d,C", "MOV $%02X,Y",
+"MOV $%04X,Y", "MOV X,#$%02X", "POP X", "MUL YA",
+"BNE $%04X", "TCALL13", "CLR6 $%02X", "BBC6 $%02X,$%04X",
+"MOV $%02X+X,A", "MOV $%04X+X,A", "MOV $%04X+Y,A", "MOV ($%02X)+Y,A",
+"MOV $%02X,X", "MOV $%02X+Y,X", "MOVW $%02X,YA", "MOV $%02X+X,Y",
+"DEC Y", "MOV A,Y", "CBNE $%02X+X,$%04X", "DAA",
+"CLRV", "TCALL14", "SET7 $%02X", "BBS7 $%02X,$%04X",
+"MOV A,$%02X", "MOV A,$%04X", "MOV A,(X)", "MOV A,($%02X+X)",
+"MOV A,#$%02X", "MOV X,$%04X", "NOT1 $%04X,%d", "MOV Y,$%02X",
+"MOV Y,$%04X", "NOTC", "POP Y", "SLEEP",
+"BEQ $%04X", "TCALL15", "CLR7 $%02X", "BBC7 $%02X,$%04X",
+"MOV A,$%02X+X", "MOV A,$%04X+X", "MOV A,$%04X+Y", "MOV A,($%02X)+Y",
+"MOV X,$%02X", "MOV X,$%02X+Y", "MOV $%02X,$%02X", "MOV Y,$%02X+X",
+"INC Y", "MOV Y,A", "DBNZ Y,$%04X", "STOP"
+};
+
+#undef ABS
+
+#define DP 0
+#define ABS 1
+#define IM 2
+#define DP2DP 3
+#define DPIM 4
+#define DPREL 5
+#define ABSBIT 6
+#define REL 7
+
+static uint8 Modes [256] = {
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, DP2DP, ABSBIT, DP,
+ ABS, IM, ABS, IM,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DPIM, IM, DP, DP,
+ IM, IM, ABS, ABS,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, DP2DP, ABSBIT, DP,
+ ABS, IM, DPREL, REL,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DPIM, IM, DP, DP,
+ IM, IM, DP, ABS,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, DP2DP, ABSBIT, DP,
+ ABS, IM, ABS, DP,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DPIM, IM, DP, DP,
+ IM, IM, ABS, ABS,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, DP2DP, ABSBIT, DP,
+ ABS, IM, DPREL, IM,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DPIM, IM, DP, DP,
+ IM, IM, DP, IM,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, DP2DP, ABSBIT, DP,
+ ABS, DP, IM, DPIM,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DPIM, IM, DP, DP,
+ IM, IM, IM, IM,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, DP2DP, ABSBIT, DP,
+ ABS, DP, IM, IM,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DPIM, IM, DP, DP,
+ IM, IM, IM, IM,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, ABS, ABSBIT, DP,
+ ABS, DP, IM, IM,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DP, DP, DP, DP,
+ IM, IM, DPREL, IM,
+ IM, IM, DP, DPREL,
+ DP, ABS, IM, DP,
+ DP, ABS, ABSBIT, DP,
+ ABS, IM, IM, IM,
+ REL, IM, DP, DPREL,
+ DP, ABS, ABS, DP,
+ DP, DP, DP2DP, DP,
+ IM, IM, REL, IM
+};
+
+static uint8 ModesToBytes [] = {
+ 2, 3, 1, 3, 3, 3, 3, 2
+};
+
+static FILE *SoundTracing = NULL;
+
+void S9xOpenCloseSoundTracingFile (bool8 open)
+{
+ if (open && !SoundTracing)
+ {
+ SoundTracing = fopen ("sound_trace.log", "w");
+ }
+ else
+ if (!open && SoundTracing)
+ {
+ fclose (SoundTracing);
+ SoundTracing = NULL;
+ }
+}
+
+void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
+ int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0)
+{
+ fprintf (SoundTracing, s, i1, i2, i3, i4, i5, i6, i7);
+}
+
+int S9xTraceAPU ()
+{
+ char buffer [200];
+
+ uint8 b = S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
+ if (apu_trace == NULL)
+ apu_trace = fopen ("apu_trace.log", "wb");
+
+ fprintf (apu_trace, "%s\n", buffer);
+ return (b);
+}
+
+int S9xAPUOPrint (char *buffer, uint16 Address)
+{
+ char mnem [100];
+ uint8 *p = IAPU.RAM + Address;
+ int mode = Modes [*p];
+ int bytes = ModesToBytes [mode];
+
+ switch (bytes)
+ {
+ case 1:
+ sprintf (buffer, "%04X %02X ", p - IAPU.RAM, *p);
+ break;
+ case 2:
+ sprintf (buffer, "%04X %02X %02X ", p - IAPU.RAM, *p,
+ *(p + 1));
+ break;
+ case 3:
+ sprintf (buffer, "%04X %02X %02X %02X ", p - IAPU.RAM, *p,
+ *(p + 1), *(p + 2));
+ break;
+ }
+
+ switch (mode)
+ {
+ case DP:
+ sprintf (mnem, S9xMnemonics [*p], *(p + 1));
+ break;
+ case ABS:
+ sprintf (mnem, S9xMnemonics [*p], *(p + 1) + (*(p + 2) << 8));
+ break;
+ case IM:
+ sprintf (mnem, S9xMnemonics [*p]);
+ break;
+ case DP2DP:
+ sprintf (mnem, S9xMnemonics [*p], *(p + 2), *(p + 1));;
+ break;
+ case DPIM:
+ sprintf (mnem, S9xMnemonics [*p], *(p + 2), *(p + 1));;
+ break;
+ case DPREL:
+ sprintf (mnem, S9xMnemonics [*p], *(p + 1),
+ (int) (p + 3 - IAPU.RAM) + (signed char) *(p + 2));
+ break;
+ case ABSBIT:
+ sprintf (mnem, S9xMnemonics [*p], (*(p + 1) + (*(p + 2) << 8)) & 0x1fff,
+ *(p + 2) >> 5);
+ break;
+ case REL:
+ sprintf (mnem, S9xMnemonics [*p],
+ (int) (p + 2 - IAPU.RAM) + (signed char) *(p + 1));
+ break;
+ }
+
+ sprintf (buffer, "%s %-20s A:%02X X:%02X Y:%02X S:%02X P:%c%c%c%c%c%c%c%c %03dl %04dl %04dl",
+ buffer, mnem,
+ APURegisters.YA.B.A, APURegisters.X, APURegisters.YA.B.Y,
+ APURegisters.S,
+ APUCheckNegative () ? 'N' : 'n',
+ APUCheckOverflow () ? 'V' : 'v',
+ APUCheckDirectPage () ? 'P' : 'p',
+ APUCheckBreak () ? 'B' : 'b',
+ APUCheckHalfCarry () ? 'H' : 'h',
+ APUCheckInterrupt () ? 'I' : 'i',
+ APUCheckZero () ? 'Z' : 'z',
+ APUCheckCarry () ? 'C' : 'c',
+ CPU.V_Counter,
+ CPU.Cycles,
+ APU.Cycles);
+
+ return (bytes);
+}
+
+const char *as_binary (uint8 data)
+{
+ static char buf [9];
+
+ for (int i = 7; i >= 0; i--)
+ buf [7 - i] = ((data & (1 << i)) != 0) + '0';
+
+ buf [8] = 0;
+ return (buf);
+}
+
+void S9xPrintAPUState ()
+{
+ printf ("Master volume left: %d, right: %d\n",
+ SoundData.master_volume_left, SoundData.master_volume_right);
+ printf ("Echo: %s %s, Delay: %d Feedback: %d Left: %d Right: %d\n",
+ SoundData.echo_write_enabled ? "on" : "off",
+ as_binary (SoundData.echo_enable),
+ SoundData.echo_buffer_size >> 9,
+ SoundData.echo_feedback, SoundData.echo_volume_left,
+ SoundData.echo_volume_right);
+
+ printf ("Noise: %s, Frequency: %d, Pitch mod: %s\n", as_binary (APU.DSP [APU_NON]),
+ NoiseFreq [APU.DSP [APU_FLG] & 0x1f],
+ as_binary (SoundData.pitch_mod));
+ extern int FilterTaps [8];
+
+ printf ("Filter: ");
+ for (int i = 0; i < 8; i++)
+ printf ("%03d, ", FilterTaps [i]);
+ printf ("\n");
+ for (int J = 0; J < 8; J++)
+ {
+ register Channel *ch = &SoundData.channels[J];
+
+ printf ("%d: ", J);
+ if (ch->state == SOUND_SILENT)
+ {
+ printf ("off\n");
+ }
+ else
+ if (!(so.sound_switch & (1 << J)))
+ printf ("muted by user using channel on/off toggle\n");
+ else
+ {
+ int freq = ch->hertz;
+ if (APU.DSP [APU_NON] & (1 << J)) //ch->type == SOUND_NOISE)
+ {
+ freq = NoiseFreq [APU.DSP [APU_FLG] & 0x1f];
+ printf ("noise, ");
+ }
+ else
+ printf ("sample %d, ", APU.DSP [APU_SRCN + J * 0x10]);
+
+ printf ("freq: %d", freq);
+ if (J > 0 && (SoundData.pitch_mod & (1 << J)) &&
+ ch->type != SOUND_NOISE)
+ {
+ printf ("(mod), ");
+ }
+ else
+ printf (", ");
+
+ printf ("left: %d, right: %d, ",
+ ch->volume_left, ch->volume_right);
+
+ static char* envelope [] =
+ {
+ "silent", "attack", "decay", "sustain", "release", "gain",
+ "inc_lin", "inc_bent", "dec_lin", "dec_exp"
+ };
+ printf ("%s envx: %d, target: %d, %ld", ch->state > 9 ? "???" : envelope [ch->state],
+ ch->envx, ch->envx_target, ch->erate);
+ printf ("\n");
+ }
+ }
+}
+#endif
+
+
diff --git a/source/apumem.h b/source/apumem.h
new file mode 100644
index 0000000..8f6dfa4
--- /dev/null
+++ b/source/apumem.h
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _apumemory_h_
+#define _apumemory_h_
+
+START_EXTERN_C
+extern uint8 W4;
+extern uint8 APUROM[64];
+END_EXTERN_C
+
+INLINE uint8 S9xAPUGetByteZ (uint8 Address)
+{
+ if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
+ {
+ if (Address >= 0xf4 && Address <= 0xf7)
+ {
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitAddress2 = IAPU.WaitAddress1;
+ IAPU.WaitAddress1 = IAPU.PC;
+#endif
+ return (IAPU.RAM [Address]);
+ }
+ if (Address >= 0xfd)
+ {
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitAddress2 = IAPU.WaitAddress1;
+ IAPU.WaitAddress1 = IAPU.PC;
+#endif
+ uint8 t = IAPU.RAM [Address];
+ IAPU.RAM [Address] = 0;
+ return (t);
+ }
+ else
+ if (Address == 0xf3)
+ return (S9xGetAPUDSP ());
+
+ return (IAPU.RAM [Address]);
+ }
+ else
+ return (IAPU.DirectPage [Address]);
+}
+
+INLINE void S9xAPUSetByteZ (uint8 byte, uint8 Address)
+{
+ if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
+ {
+ if (Address == 0xf3)
+ S9xSetAPUDSP (byte);
+ else
+ if (Address >= 0xf4 && Address <= 0xf7)
+ APU.OutPorts [Address - 0xf4] = byte;
+ else
+ if (Address == 0xf1)
+ S9xSetAPUControl (byte);
+ else
+ if (Address < 0xfd)
+ {
+ IAPU.RAM [Address] = byte;
+ if (Address >= 0xfa)
+ {
+ if (byte == 0)
+ APU.TimerTarget [Address - 0xfa] = 0x100;
+ else
+ APU.TimerTarget [Address - 0xfa] = byte;
+ }
+ }
+ }
+ else
+ IAPU.DirectPage [Address] = byte;
+}
+
+INLINE uint8 S9xAPUGetByte (uint32 Address)
+{
+ Address &= 0xffff;
+
+ if (Address <= 0xff && Address >= 0xf0)
+ {
+ if (Address >= 0xf4 && Address <= 0xf7)
+ {
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitAddress2 = IAPU.WaitAddress1;
+ IAPU.WaitAddress1 = IAPU.PC;
+#endif
+ return (IAPU.RAM [Address]);
+ }
+ else
+ if (Address == 0xf3)
+ return (S9xGetAPUDSP ());
+ if (Address >= 0xfd)
+ {
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitAddress2 = IAPU.WaitAddress1;
+ IAPU.WaitAddress1 = IAPU.PC;
+#endif
+ uint8 t = IAPU.RAM [Address];
+ IAPU.RAM [Address] = 0;
+ return (t);
+ }
+ return (IAPU.RAM [Address]);
+ }
+ else
+ return (IAPU.RAM [Address]);
+}
+
+INLINE void S9xAPUSetByte (uint8 byte, uint32 Address)
+{
+ Address &= 0xffff;
+
+ if (Address <= 0xff && Address >= 0xf0)
+ {
+ if (Address == 0xf3)
+ S9xSetAPUDSP (byte);
+ else
+ if (Address >= 0xf4 && Address <= 0xf7)
+ APU.OutPorts [Address - 0xf4] = byte;
+ else
+ if (Address == 0xf1)
+ S9xSetAPUControl (byte);
+ else
+ if (Address < 0xfd)
+ {
+ IAPU.RAM [Address] = byte;
+ if (Address >= 0xfa)
+ {
+ if (byte == 0)
+ APU.TimerTarget [Address - 0xfa] = 0x100;
+ else
+ APU.TimerTarget [Address - 0xfa] = byte;
+ }
+ }
+ }
+ else
+ {
+#if 0
+if (Address >= 0x2500 && Address <= 0x2504)
+printf ("%06d %04x <- %02x\n", ICPU.Scanline, Address, byte);
+if (Address == 0x26c6)
+{
+ extern FILE *apu_trace;
+ extern FILE *trace;
+ APU.Flags |= TRACE_FLAG;
+ CPU.Flags |= TRACE_FLAG;
+ if (apu_trace == NULL)
+ apu_trace = fopen ("aputrace.log", "wb");
+ if (trace == NULL)
+ trace = fopen ("trace.log", "wb");
+ printf ("TRACING SWITCHED ON\n");
+}
+#endif
+ if (Address < 0xffc0)
+ IAPU.RAM [Address] = byte;
+ else
+ {
+ APU.ExtraRAM [Address - 0xffc0] = byte;
+ if (!APU.ShowROM)
+ IAPU.RAM [Address] = byte;
+ }
+ }
+}
+#endif
+
diff --git a/source/autom4te.cache/output.0 b/source/autom4te.cache/output.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/autom4te.cache/output.0
diff --git a/source/autom4te.cache/requests b/source/autom4te.cache/requests
new file mode 100644
index 0000000..bec4e12
--- /dev/null
+++ b/source/autom4te.cache/requests
@@ -0,0 +1,67 @@
+# This file was generated by Autom4te Tue Dec 22 07:01:21 UTC 2009.
+# It contains the lists of macros which have been traced.
+# It can be safely removed.
+
+@request = (
+ bless( [
+ '0',
+ 1,
+ [
+ '/usr/share/autoconf'
+ ],
+ [
+ '/usr/share/autoconf/autoconf/autoconf.m4f',
+ 'Makefile.in'
+ ],
+ {
+ '_LT_AC_TAGCONFIG' => 1,
+ 'AM_PROG_F77_C_O' => 1,
+ 'AC_INIT' => 1,
+ 'm4_pattern_forbid' => 1,
+ '_AM_COND_IF' => 1,
+ 'AC_CANONICAL_TARGET' => 1,
+ 'AC_SUBST' => 1,
+ 'AC_CONFIG_LIBOBJ_DIR' => 1,
+ 'AC_FC_SRCEXT' => 1,
+ 'AC_CANONICAL_HOST' => 1,
+ 'AC_PROG_LIBTOOL' => 1,
+ 'AM_INIT_AUTOMAKE' => 1,
+ 'AC_CONFIG_SUBDIRS' => 1,
+ 'AM_AUTOMAKE_VERSION' => 1,
+ 'LT_CONFIG_LTDL_DIR' => 1,
+ 'AC_REQUIRE_AUX_FILE' => 1,
+ 'AC_CONFIG_LINKS' => 1,
+ 'm4_sinclude' => 1,
+ 'LT_SUPPORTED_TAG' => 1,
+ 'AM_MAINTAINER_MODE' => 1,
+ 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
+ '_m4_warn' => 1,
+ 'AM_PROG_CXX_C_O' => 1,
+ '_AM_COND_ENDIF' => 1,
+ 'AM_ENABLE_MULTILIB' => 1,
+ 'AM_SILENT_RULES' => 1,
+ 'AC_CONFIG_FILES' => 1,
+ 'include' => 1,
+ 'LT_INIT' => 1,
+ 'AM_GNU_GETTEXT' => 1,
+ 'AC_LIBSOURCE' => 1,
+ 'AM_PROG_FC_C_O' => 1,
+ 'AC_CANONICAL_BUILD' => 1,
+ 'AC_FC_FREEFORM' => 1,
+ 'AH_OUTPUT' => 1,
+ '_AM_SUBST_NOTMAKE' => 1,
+ 'AC_CONFIG_AUX_DIR' => 1,
+ 'sinclude' => 1,
+ 'm4_pattern_allow' => 1,
+ 'AM_PROG_CC_C_O' => 1,
+ 'AC_CANONICAL_SYSTEM' => 1,
+ 'AM_CONDITIONAL' => 1,
+ 'AC_CONFIG_HEADERS' => 1,
+ 'AC_DEFINE_TRACE_LITERAL' => 1,
+ 'm4_include' => 1,
+ '_AM_COND_ELSE' => 1,
+ 'AC_SUBST_TRACE' => 1
+ }
+ ], 'Autom4te::Request' )
+ );
+
diff --git a/source/autom4te.cache/traces.0 b/source/autom4te.cache/traces.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/autom4te.cache/traces.0
diff --git a/source/c4.cpp b/source/c4.cpp
new file mode 100644
index 0000000..8774f46
--- /dev/null
+++ b/source/c4.cpp
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <math.h>
+#include <stdlib.h>
+#include "c4.h"
+#include "memmap.h"
+extern "C" {
+
+short C4WFXVal;
+short C4WFYVal;
+short C4WFZVal;
+short C4WFX2Val;
+short C4WFY2Val;
+short C4WFDist;
+short C4WFScale;
+
+static double tanval;
+static double c4x, c4y, c4z;
+static double c4x2, c4y2, c4z2;
+
+void C4TransfWireFrame ()
+{
+ c4x = (double) C4WFXVal;
+ c4y = (double) C4WFYVal;
+ c4z = (double) C4WFZVal - 0x95;
+
+ // Rotate X
+ tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128;
+ c4y2 = c4y * cos (tanval) - c4z * sin (tanval);
+ c4z2 = c4y * sin (tanval) + c4z * cos (tanval);
+
+ // Rotate Y
+ tanval = -(double)C4WFY2Val*3.14159265*2/128;
+ c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval);
+ c4z = c4x * - sin (tanval) + c4z2 * cos (tanval);
+
+ // Rotate Z
+ tanval = -(double) C4WFDist * 3.14159265*2 / 128;
+ c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval);
+ c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval);
+
+ // Scale
+ C4WFXVal = (short) (c4x*(double)C4WFScale/(0x90*(c4z+0x95))*0x95);
+ C4WFYVal = (short) (c4y*(double)C4WFScale/(0x90*(c4z+0x95))*0x95);
+}
+
+void C4TransfWireFrame2 ()
+{
+ c4x = (double)C4WFXVal;
+ c4y = (double)C4WFYVal;
+ c4z = (double)C4WFZVal;
+
+ // Rotate X
+ tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128;
+ c4y2 = c4y * cos (tanval) - c4z * sin (tanval);
+ c4z2 = c4y * sin (tanval) + c4z * cos (tanval);
+
+ // Rotate Y
+ tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128;
+ c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval);
+ c4z = c4x * -sin (tanval) + c4z2 * cos (tanval);
+
+ // Rotate Z
+ tanval = -(double)C4WFDist * 3.14159265 * 2 / 128;
+ c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval);
+ c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval);
+
+ // Scale
+ C4WFXVal =(short)(c4x * (double)C4WFScale / 0x100);
+ C4WFYVal =(short)(c4y * (double)C4WFScale / 0x100);
+}
+
+void C4CalcWireFrame ()
+{
+ C4WFXVal = C4WFX2Val - C4WFXVal;
+ C4WFYVal = C4WFY2Val - C4WFYVal;
+ if (abs (C4WFXVal) > abs (C4WFYVal))
+ {
+ C4WFDist = abs (C4WFXVal) + 1;
+ C4WFYVal = (short) (256 * (double) C4WFYVal / abs (C4WFXVal));
+ if (C4WFXVal < 0)
+ C4WFXVal = -256;
+ else
+ C4WFXVal = 256;
+ }
+ else
+ {
+ if (C4WFYVal != 0)
+ {
+ C4WFDist = abs(C4WFYVal)+1;
+ C4WFXVal = (short) (256 * (double)C4WFXVal / abs (C4WFYVal));
+ if (C4WFYVal < 0)
+ C4WFYVal = -256;
+ else
+ C4WFYVal = 256;
+ }
+ else
+ C4WFDist = 0;
+ }
+}
+
+short C41FXVal;
+short C41FYVal;
+short C41FAngleRes;
+short C41FDist;
+short C41FDistVal;
+
+void C4Op1F ()
+{
+ if (C41FXVal == 0)
+ {
+ if (C41FYVal > 0)
+ C41FAngleRes = 0x80;
+ else
+ C41FAngleRes = 0x180;
+ }
+ else
+ {
+ tanval = (double) C41FYVal / C41FXVal;
+ C41FAngleRes = (short) (atan (tanval) / (3.141592675 * 2) * 512);
+ C41FAngleRes = C41FAngleRes;
+ if (C41FXVal< 0)
+ C41FAngleRes += 0x100;
+ C41FAngleRes &= 0x1FF;
+ }
+}
+
+void C4Op15()
+{
+ tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
+ C41FDist = (short) tanval;
+}
+
+void C4Op0D()
+{
+ tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
+ tanval = C41FDistVal / tanval;
+ C41FYVal = (short) (C41FYVal * tanval * 0.99);
+ C41FXVal = (short) (C41FXVal * tanval * 0.98);
+}
+
+#ifdef ZSNES_C4
+void C4LoaDMem(char *C4RAM)
+{
+ memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff),
+ S9xGetMemPointer(READ_3WORD(C4RAM+0x1f40)),
+ READ_WORD(C4RAM+0x1f43));
+}
+#endif
+}//end extern C
+
diff --git a/source/c4.h b/source/c4.h
new file mode 100644
index 0000000..f7957d4
--- /dev/null
+++ b/source/c4.h
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _C4_H_
+#define _C4_H_
+
+#include "port.h"
+
+extern "C" {
+
+extern int16 C4WFXVal;
+extern int16 C4WFYVal;
+extern int16 C4WFZVal;
+extern int16 C4WFX2Val;
+extern int16 C4WFY2Val;
+extern int16 C4WFDist;
+extern int16 C4WFScale;
+
+void C4TransfWireFrame();
+void C4TransfWireFrame2();
+void C4CalcWireFrame();
+
+extern int16 C41FXVal;
+extern int16 C41FYVal;
+extern int16 C41FAngleRes;
+extern int16 C41FDist;
+extern int16 C41FDistVal;
+
+void C4Op1F();
+void C4Op15();
+void C4Op0D();
+
+extern int16 C4CosTable[];
+extern int16 C4SinTable[];
+
+}
+
+#endif
+
diff --git a/source/c4emu.cpp b/source/c4emu.cpp
new file mode 100644
index 0000000..a8fcce9
--- /dev/null
+++ b/source/c4emu.cpp
@@ -0,0 +1,1020 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+#include <math.h>
+#include "snes9x.h"
+#include "sar.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "c4.h"
+
+void S9xInitC4 ()
+{
+ // Stupid zsnes code, we can't do the logical thing without breaking
+ // savestates
+// Memory.C4RAM = &Memory.FillRAM [0x6000];
+ memset(Memory.C4RAM, 0, 0x2000);
+}
+
+uint8 S9xGetC4 (uint16 Address)
+{
+#ifdef DEBUGGER
+ if(Settings.BGLayering) printf("%02x from %04x\n", Memory.C4RAM[Address-0x6000], Address);
+#endif
+ return (Memory.C4RAM [Address-0x6000]);
+}
+
+static uint8 C4TestPattern [12 * 4] =
+{
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x00,
+ 0x80, 0xff, 0xff, 0x7f,
+ 0x00, 0x80, 0x00, 0xff,
+ 0x7f, 0x00, 0xff, 0x7f,
+ 0xff, 0x7f, 0xff, 0xff,
+ 0x00, 0x00, 0x01, 0xff,
+ 0xff, 0xfe, 0x00, 0x01,
+ 0x00, 0xff, 0xfe, 0x00
+};
+
+
+static void C4ConvOAM(void){
+ uint8 *OAMptr=Memory.C4RAM+(Memory.C4RAM[0x626]<<2);
+ for(uint8 *i=Memory.C4RAM+0x1fd; i>OAMptr; i-=4){
+ // Clear OAM-to-be
+ *i=0xe0;
+ }
+
+ uint16 globalX, globalY;
+ uint8 *OAMptr2;
+ int16 SprX, SprY;
+ uint8 SprName, SprAttr;
+ uint8 SprCount;
+
+ globalX=READ_WORD(Memory.C4RAM+0x0621);
+ globalY=READ_WORD(Memory.C4RAM+0x0623);
+ OAMptr2=Memory.C4RAM+0x200+(Memory.C4RAM[0x626]>>2);
+
+#ifdef DEBUGGER
+ if(Memory.C4RAM[0x625]!=0) printf("$6625=%02x, expected 00\n", Memory.C4RAM[0x625]);
+ if((Memory.C4RAM[0x626]>>2)!=Memory.C4RAM[0x629]) printf("$6629=%02x, expected %02x\n", Memory.C4RAM[0x629], (Memory.C4RAM[0x626]>>2));
+ if(((uint16)Memory.C4RAM[0x626]<<2)!=READ_WORD(Memory.C4RAM+0x627)) printf("$6627=%04x, expected %04x\n", READ_WORD(Memory.C4RAM+0x627), ((uint16)Memory.C4RAM[0x626]<<2));
+#endif
+
+ if(Memory.C4RAM[0x0620]!=0){
+ SprCount=128-Memory.C4RAM[0x626];
+ uint8 offset=(Memory.C4RAM[0x626]&3)*2;
+ for(int prio=0x30; prio>=0; prio-=0x10){
+ uint8 *srcptr=Memory.C4RAM+0x220;
+ for(int i=Memory.C4RAM[0x0620]; i>0 && SprCount>0; i--, srcptr+=16){
+ if((srcptr[4]&0x30)!=prio) continue;
+ SprX=READ_WORD(srcptr)-globalX;
+ SprY=READ_WORD(srcptr+2)-globalY;
+ SprName=srcptr[5];
+ SprAttr=srcptr[4] | srcptr[0x06]; // XXX: mask bits?
+
+ uint8 *sprptr=S9xGetMemPointer(READ_3WORD(srcptr+7));
+ if(*sprptr!=0){
+ int16 X, Y;
+ for(int SprCnt=*sprptr++; SprCnt>0 && SprCount>0; SprCnt--, sprptr+=4){
+ X=(int8)sprptr[1];
+ if(SprAttr&0x40){ // flip X
+ X=-X-((sprptr[0]&0x20)?16:8);
+ }
+ X+=SprX;
+ if(X>=-16 && X<=272){
+ Y=(int8)sprptr[2];
+ if(SprAttr&0x80){
+ Y=-Y-((sprptr[0]&0x20)?16:8);
+ }
+ Y+=SprY;
+ if(Y>=-16 && Y<=224){
+ OAMptr[0]=X&0xff;
+ OAMptr[1]=(uint8)Y;
+ OAMptr[2]=SprName+sprptr[3];
+ OAMptr[3]=SprAttr^(sprptr[0]&0xc0); // XXX: Carry from SprName addition?
+ *OAMptr2 &= ~(3<<offset);
+ if(X&0x100) *OAMptr2 |= 1<<offset;
+ if(sprptr[0]&0x20) *OAMptr2 |= 2<<offset;
+ OAMptr+=4;
+ SprCount--;
+ offset=(offset+2)&6;
+ if(offset==0) OAMptr2++;
+ }
+ }
+ }
+ } else if(SprCount>0){
+ OAMptr[0]=(uint8)SprX;
+ OAMptr[1]=(uint8)SprY;
+ OAMptr[2]=SprName;
+ OAMptr[3]=SprAttr;
+ *OAMptr2 &= ~(3<<offset);
+ if(SprX&0x100) *OAMptr2 |= 3<<offset;
+ else *OAMptr2 |= 2<<offset;
+ OAMptr+=4;
+ SprCount--;
+ offset=(offset+2)&6;
+ if(offset==0) OAMptr2++;
+ }
+ }
+ }
+ }
+ // XXX: Copy to OAM? I doubt it.
+}
+
+static void C4DoScaleRotate(int row_padding){
+ int16 A, B, C, D;
+
+ // Calculate matrix
+ int32 XScale=READ_WORD(Memory.C4RAM+0x1f8f);
+ if(XScale&0x8000) XScale=0x7fff;
+ int32 YScale=READ_WORD(Memory.C4RAM+0x1f92);
+ if(YScale&0x8000) YScale=0x7fff;
+
+ if(READ_WORD(Memory.C4RAM+0x1f80)==0)
+ { // no rotation
+ // XXX: only do this for C and D?
+ // XXX: and then only when YScale is 0x1000?
+ A=(int16)XScale;
+ B=0;
+ C=0;
+ D=(int16)YScale;
+ }
+ else if(READ_WORD(Memory.C4RAM+0x1f80)==128){ // 90 degree rotation
+ // XXX: Really do this?
+ A=0;
+ B=(int16)(-YScale);
+ C=(int16)XScale;
+ D=0;
+ } else if(READ_WORD(Memory.C4RAM+0x1f80)==256){ // 180 degree rotation
+ // XXX: Really do this?
+ A=(int16)(-XScale);
+ B=0;
+ C=0;
+ D=(int16)(-YScale);
+ } else if(READ_WORD(Memory.C4RAM+0x1f80)==384){ // 270 degree rotation
+ // XXX: Really do this?
+ A=0;
+ B=(int16)YScale;
+ C=(int16)(-XScale);
+ D=0;
+ } else {
+ A=(int16)SAR(C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*XScale, 15);
+ B=(int16)(-SAR(C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*YScale, 15));
+ C=(int16)SAR(C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*XScale, 15);
+ D=(int16)SAR(C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*YScale, 15);
+ }
+
+ // Calculate Pixel Resolution
+ uint8 w=Memory.C4RAM[0x1f89]&~7;
+ uint8 h=Memory.C4RAM[0x1f8c]&~7;
+
+// printf("%dx%d XScale=%04x YScale=%04x angle=%03x\n", w, h, XScale, YScale, READ_WORD(Memory.C4RAM+0x1f80)&0x1ff);
+// printf("Matrix: [%10g %10g] [%04x %04x]\n", A/4096.0, B/4096.0, A&0xffff, B&0xffff);
+// printf(" [%10g %10g] [%04x %04x]\n", C/4096.0, D/4096.0, C&0xffff, D&0xffff);
+
+ // Clear the output RAM
+ memset(Memory.C4RAM, 0, (w+row_padding/4)*h/2);
+
+ int32 Cx=(int16)READ_WORD(Memory.C4RAM+0x1f83);
+ int32 Cy=(int16)READ_WORD(Memory.C4RAM+0x1f86);
+
+#ifdef DEBUGGER
+ if(Memory.C4RAM[0x1f97]!=0) printf("$7f97=%02x, expected 00\n", Memory.C4RAM[0x1f97]);
+ if((Cx&~1)!=w/2 || (Cy&~1)!=h/2) printf("Center is not middle of image! (%d, %d) != (%d, %d)\n", Cx, Cy, w/2, h/2);
+#endif
+
+ // Calculate start position (i.e. (Ox, Oy) = (0, 0))
+ // The low 12 bits are fractional, so (Cx<<12) gives us the Cx we want in
+ // the function. We do Cx*A etc normally because the matrix parameters
+ // already have the fractional parts.
+ int32 LineX=(Cx<<12) - Cx*A - Cx*B;
+ int32 LineY=(Cy<<12) - Cy*C - Cy*D;
+
+ // Start loop
+ uint32 X, Y;
+ uint8 byte;
+ int outidx=0;
+ uint8 bit=0x80;
+ for(int y=0; y<h; y++){
+ X=LineX;
+ Y=LineY;
+ for(int x=0; x<w; x++){
+ if((X>>12)>=w || (Y>>12)>=h){
+ byte=0;
+ } else {
+ uint32 addr=(Y>>12)*w+(X>>12);
+ byte=Memory.C4RAM[0x600+(addr>>1)];
+ if(addr&1) byte>>=4;
+ }
+
+ // De-bitplanify
+ if(byte&1) Memory.C4RAM[outidx]|=bit;
+ if(byte&2) Memory.C4RAM[outidx+1]|=bit;
+ if(byte&4) Memory.C4RAM[outidx+16]|=bit;
+ if(byte&8) Memory.C4RAM[outidx+17]|=bit;
+
+ bit>>=1;
+ if(bit==0){
+ bit=0x80;
+ outidx+=32;
+ }
+
+ X+=A; // Add 1 to output x => add an A and a C
+ Y+=C;
+ }
+ outidx+=2+row_padding;
+ if(outidx&0x10){
+ outidx&=~0x10;
+ } else {
+ outidx-=w*4+row_padding;
+ }
+ LineX+=B; // Add 1 to output y => add a B and a D
+ LineY+=D;
+ }
+}
+
+static void C4DrawLine(int32 X1, int32 Y1, int16 Z1,
+ int32 X2, int32 Y2, int16 Z2, uint8 Color){
+ // Transform coordinates
+ C4WFXVal=(short)X1;
+ C4WFYVal=(short)Y1;
+ C4WFZVal=Z1;
+ C4WFScale=Memory.C4RAM[0x1f90];
+ C4WFX2Val=Memory.C4RAM[0x1f86];
+ C4WFY2Val=Memory.C4RAM[0x1f87];
+ C4WFDist=Memory.C4RAM[0x1f88];
+ C4TransfWireFrame2();
+ X1=(C4WFXVal+48)<<8;
+ Y1=(C4WFYVal+48)<<8;
+
+ C4WFXVal=(short)X2;
+ C4WFYVal=(short)Y2;
+ C4WFZVal=Z2;
+ C4TransfWireFrame2();
+ X2=(C4WFXVal+48)<<8;
+ Y2=(C4WFYVal+48)<<8;
+
+ // get line info
+ C4WFXVal=(short)(X1>>8);
+ C4WFYVal=(short)(Y1>>8);
+ C4WFX2Val=(short)(X2>>8);
+ C4WFY2Val=(short)(Y2>>8);
+ C4CalcWireFrame();
+ X2=(int16)C4WFXVal;
+ Y2=(int16)C4WFYVal;
+
+ // render line
+ for(int i=C4WFDist?C4WFDist:1; i>0; i--)
+ { //.loop
+ if(X1>0xff && Y1>0xff && X1<0x6000 && Y1<0x6000)
+ {
+ uint16 addr=((X1&~0x7ff) + (Y1&~0x7ff)*12 + (Y1&0x700))>>7;
+ addr=(((Y1>>8)>>3)<<8)-(((Y1>>8)>>3)<<6)+(((X1>>8)>>3)<<4)+((Y1>>8)&7)*2;
+ uint8 bit=0x80>>((X1>>8)&7);
+ Memory.C4RAM[addr+0x300]&=~bit;
+ Memory.C4RAM[addr+0x301]&=~bit;
+ if(Color&1) Memory.C4RAM[addr+0x300]|=bit;
+ if(Color&2) Memory.C4RAM[addr+0x301]|=bit;
+ }
+ X1+=X2;
+ Y1+=Y2;
+ }
+}
+
+static void C4DrawWireFrame(void)
+{
+ uint8 *line=S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f80));
+ uint8 *point1, *point2;
+ int16 X1, Y1, Z1;
+ int16 X2, Y2, Z2;
+ uint8 Color;
+
+#ifdef DEBUGGER
+ if(READ_3WORD(Memory.C4RAM+0x1f8f)&0xff00ff) printf("wireframe: Unexpected value in $7f8f: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8f));
+ if(READ_3WORD(Memory.C4RAM+0x1fa4)!=0x001000) printf("wireframe: Unexpected value in $7fa4: %06x\n", READ_3WORD(Memory.C4RAM+0x1fa4));
+#endif
+
+ for(int i=Memory.C4RAM[0x0295]; i>0; i--, line+=5){
+ if(line[0]==0xff && line[1]==0xff){
+ uint8 *tmp=line-5;
+ while(line[2]==0xff && line[3]==0xff) tmp-=5;
+ point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (tmp[2]<<8) | tmp[3]);
+ } else {
+ point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[0]<<8) | line[1]);
+ }
+ point2=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[2]<<8) | line[3]);
+
+ X1=(point1[0]<<8) | point1[1];
+ Y1=(point1[2]<<8) | point1[3];
+ Z1=(point1[4]<<8) | point1[5];
+ X2=(point2[0]<<8) | point2[1];
+ Y2=(point2[2]<<8) | point2[3];
+ Z2=(point2[4]<<8) | point2[5];
+ Color=line[4];
+ C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color);
+ }
+}
+
+static void C4TransformLines(void){
+ C4WFX2Val=Memory.C4RAM[0x1f83];
+ C4WFY2Val=Memory.C4RAM[0x1f86];
+ C4WFDist=Memory.C4RAM[0x1f89];
+ C4WFScale=Memory.C4RAM[0x1f8c];
+
+#ifdef DEBUGGER
+ if(Memory.C4RAM[0x1f8a]!=0x90) printf("lines: $7f8a = %02x, expected 90\n", READ_WORD(Memory.C4RAM+0x1f8a));
+#endif
+
+ // transform vertices
+ uint8 *ptr=Memory.C4RAM;
+ {
+ for(int i=READ_WORD(Memory.C4RAM+0x1f80); i>0; i--, ptr+=0x10)
+ {
+ C4WFXVal=READ_WORD(ptr+1);
+ C4WFYVal=READ_WORD(ptr+5);
+ C4WFZVal=READ_WORD(ptr+9);
+ C4TransfWireFrame();
+
+ // displace
+ WRITE_WORD(ptr+1, C4WFXVal+0x80);
+ WRITE_WORD(ptr+5, C4WFYVal+0x50);
+ }
+ }
+ WRITE_WORD(Memory.C4RAM+0x600, 23);
+ WRITE_WORD(Memory.C4RAM+0x602, 0x60);
+ WRITE_WORD(Memory.C4RAM+0x605, 0x40);
+ WRITE_WORD(Memory.C4RAM+0x600+8, 23);
+ WRITE_WORD(Memory.C4RAM+0x602+8, 0x60);
+ WRITE_WORD(Memory.C4RAM+0x605+8, 0x40);
+
+ ptr=Memory.C4RAM+0xb02;
+ uint8 *ptr2=Memory.C4RAM;
+ {
+ for(int i=READ_WORD(Memory.C4RAM+0xb00); i>0; i--, ptr+=2, ptr2+=8)
+ {
+ C4WFXVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+1);
+ C4WFYVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+5);
+ C4WFX2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+1);
+ C4WFY2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+5);
+ C4CalcWireFrame();
+ WRITE_WORD(ptr2+0x600, C4WFDist?C4WFDist:1);
+ WRITE_WORD(ptr2+0x602, C4WFXVal);
+ WRITE_WORD(ptr2+0x605, C4WFYVal);
+ }
+ }
+}
+static void C4BitPlaneWave(){
+ static uint16 bmpdata[]={
+ 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E,
+ 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020A, 0x020C, 0x020E,
+ 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040A, 0x040C, 0x040E,
+ 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060A, 0x060C, 0x060E,
+ 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080A, 0x080C, 0x080E
+ };
+
+ uint8 *dst=Memory.C4RAM;
+ uint32 waveptr=Memory.C4RAM[0x1f83];
+ uint16 mask1=0xc0c0;
+ uint16 mask2=0x3f3f;
+
+#ifdef DEBUGGER
+ if(READ_3WORD(Memory.C4RAM+0x1f80) != Memory.C4RAM[waveptr+0xb00]) printf("$7f80=%06x, expected %02x\n", READ_3WORD(Memory.C4RAM+0x1f80), Memory.C4RAM[waveptr+0xb00]);
+#endif
+
+ for(int j=0; j<0x10; j++){
+ do {
+ int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16;
+ for(int i=0; i<40; i++){
+ uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2;
+ if(height>=0){
+ if(height<8){
+ tmp|=mask1&READ_WORD(Memory.C4RAM+0xa00+height*2);
+ } else {
+ tmp|=mask1&0xff00;
+ }
+ }
+ WRITE_WORD(dst+bmpdata[i], tmp);
+ height++;
+ }
+ waveptr=(waveptr+1)&0x7f;
+ mask1=(mask1>>2)|(mask1<<6);
+ mask2=(mask2>>2)|(mask2<<6);
+ } while(mask1!=0xc0c0);
+ dst+=16;
+
+ do {
+ int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16;
+ for(int i=0; i<40; i++){
+ uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2;
+ if(height>=0){
+ if(height<8){
+ tmp|=mask1&READ_WORD(Memory.C4RAM+0xa10+height*2);
+ } else {
+ tmp|=mask1&0xff00;
+ }
+ }
+ WRITE_WORD(dst+bmpdata[i], tmp);
+ height++;
+ }
+ waveptr=(waveptr+1)&0x7f;
+ mask1=(mask1>>2)|(mask1<<6);
+ mask2=(mask2>>2)|(mask2<<6);
+ } while(mask1!=0xc0c0);
+ dst+=16;
+ }
+}
+
+static void C4SprDisintegrate()
+{
+ uint8 width, height;
+ uint32 StartX, StartY;
+ uint8 *src;
+ int32 scaleX, scaleY;
+ int32 Cx, Cy;
+
+ width=Memory.C4RAM[0x1f89];
+ height=Memory.C4RAM[0x1f8c];
+ Cx=(int16)READ_WORD(Memory.C4RAM+0x1f80);
+ Cy=(int16)READ_WORD(Memory.C4RAM+0x1f83);
+
+#ifdef DEBUGGER
+ if((Cx&~1)!=width/2 || (Cy&~1)!=height/2) printf("Center is not middle of image for disintegrate! (%d, %d) != (%d, %d)\n", Cx, Cy, width/2, height/2);
+#endif
+
+ scaleX=(int16)READ_WORD(Memory.C4RAM+0x1f86);
+ scaleY=(int16)READ_WORD(Memory.C4RAM+0x1f8f);
+ StartX=-Cx*scaleX+(Cx<<8);
+ StartY=-Cy*scaleY+(Cy<<8);
+ src=Memory.C4RAM+0x600;
+
+ memset(Memory.C4RAM, 0, width*height/2);
+
+ for(uint32 y=StartY, i=0; i<height; i++, y+=scaleY)
+ {
+ for(uint32 x=StartX, j=0; j<width; j++, x+=scaleX)
+ {
+ if((x>>8)<width && (y>>8)<height && (y>>8)*width+(x>>8)<0x2000)
+ {
+ uint8 pixel=(j&1)?(*src>>4):*src;
+ int idx=(y>>11)*width*4+(x>>11)*32+((y>>8)&7)*2;
+ uint8 mask=0x80>>((x>>8)&7);
+ if(pixel&1) Memory.C4RAM[idx]|=mask;
+ if(pixel&2) Memory.C4RAM[idx+1]|=mask;
+ if(pixel&4) Memory.C4RAM[idx+16]|=mask;
+ if(pixel&8) Memory.C4RAM[idx+17]|=mask;
+ }
+ if(j&1) src++;
+ }
+ }
+}
+
+static void S9xC4ProcessSprites()
+{
+ switch(Memory.C4RAM[0x1f4d])
+ {
+ case 0x00: // Build OAM
+#ifdef DEBUGGER
+// printf("00 00 Build OAM!\n");
+#endif
+ C4ConvOAM();
+ break;
+
+ case 0x03: // Scale/Rotate
+#ifdef DEBUGGER
+// printf("00 03 Scale/Rotate!\n");
+#endif
+ C4DoScaleRotate(0);
+ break;
+
+ case 0x05: // Transform Lines
+#ifdef DEBUGGER
+// printf("00 05 Transform Lines!\n");
+#endif
+ C4TransformLines();
+ break;
+
+ case 0x07: // Scale/Rotate
+#ifdef DEBUGGER
+// printf("00 07 Scale/Rotate!\n");
+#endif
+ C4DoScaleRotate(64);
+ break;
+
+ case 0x08: // Draw wireframe
+#ifdef DEBUGGER
+// printf("00 08 Draw wireframe!\n");
+#endif
+ C4DrawWireFrame();
+ break;
+
+ case 0x0b: // Disintegrate
+#ifdef DEBUGGER
+ printf("00 0b Disintegrate!\n");
+#endif
+ C4SprDisintegrate();
+ break;
+
+ case 0x0c: // Wave
+#ifdef DEBUGGER
+// printf("00 0b Wave!\n");
+#endif
+ C4BitPlaneWave();
+ break;
+
+ default:
+#ifdef DEBUGGER
+ printf ("Unknown C4 sprite command (%02x)\n", Memory.C4RAM [0x1f4d]);
+#endif
+ break;
+ }
+}
+
+void S9xSetC4 (uint8 byte, uint16 Address)
+{
+ int i;
+
+#ifdef DEBUGGER
+ if(Settings.BGLayering) printf("%02x to %04x\n", byte, Address);
+#endif
+ Memory.C4RAM [Address-0x6000] = byte;
+ if (Address == 0x7f4f)
+ {
+ if(Memory.C4RAM[0x1f4d]==0x0e && byte<0x40 && (byte&3)==0)
+ {
+#ifdef DEBUGGER
+ printf("Test command %02x 0e used!\n", byte);
+#endif
+ Memory.C4RAM[0x1f80]=byte>>2;
+ }
+ else
+ {
+ switch (byte)
+ {
+ case 0x00: // Sprite
+ S9xC4ProcessSprites();
+ break;
+
+ case 0x01: // Draw wireframe
+#ifdef DEBUGGER
+ //printf("01 Draw wireframe used!\n");
+ if(Memory.C4RAM[0x1f4d]!=8) printf("$7f4d=%02x, expected 08 for command 01 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ memset(Memory.C4RAM+0x300, 0, 16*12*3*4);
+ C4DrawWireFrame();
+ break;
+
+ case 0x05: // Propulsion (?)
+#ifdef DEBUGGER
+ printf("05 Propulsion (?)!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 05 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ {
+ int32 tmp=0x10000;
+ if(READ_WORD(Memory.C4RAM+0x1f83)){
+ tmp=SAR((tmp/READ_WORD(Memory.C4RAM+0x1f83))*READ_WORD(Memory.C4RAM+0x1f81), 8);
+ }
+ WRITE_WORD(Memory.C4RAM+0x1f80, (uint16)tmp);
+ }
+ break;
+
+ case 0x0d: // Set vector length
+#ifdef DEBUGGER
+ printf("0d Set vector length!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 0d %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ C41FXVal=READ_WORD(Memory.C4RAM+0x1f80);
+ C41FYVal=READ_WORD(Memory.C4RAM+0x1f83);
+ C41FDistVal=READ_WORD(Memory.C4RAM+0x1f86);
+ C4Op0D();
+ WRITE_WORD(Memory.C4RAM+0x1f89, C41FXVal);
+ WRITE_WORD(Memory.C4RAM+0x1f8c, C41FYVal);
+ break;
+
+ case 0x10: // Polar to rectangluar
+#ifdef DEBUGGER
+// printf("10 Polar->Rect!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 10 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ {
+ int32 tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 16);
+ WRITE_3WORD(Memory.C4RAM+0x1f86, tmp);
+ tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 16);
+ WRITE_3WORD(Memory.C4RAM+0x1f89, (tmp-SAR(tmp, 6)));
+ }
+ break;
+
+ case 0x13: // Polar to rectangluar
+#ifdef DEBUGGER
+// printf("13 Polar->Rect!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 13 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ {
+ int32 tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 8);
+ WRITE_3WORD(Memory.C4RAM+0x1f86, tmp);
+ tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 8);
+ WRITE_3WORD(Memory.C4RAM+0x1f89, tmp);
+ }
+ break;
+
+ case 0x15: // Pythagorean
+#ifdef DEBUGGER
+ printf("15 Pythagorean!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 15 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ C41FXVal=READ_WORD(Memory.C4RAM+0x1f80);
+ C41FYVal=READ_WORD(Memory.C4RAM+0x1f83);
+ C41FDist=(int16)sqrt((double)C41FXVal*C41FXVal + (double)C41FYVal*C41FYVal);
+ WRITE_WORD(Memory.C4RAM+0x1f80, C41FDist);
+ break;
+
+ case 0x1f: // atan
+#ifdef DEBUGGER
+// printf("1f atan!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 1f %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ C41FXVal=READ_WORD(Memory.C4RAM+0x1f80);
+ C41FYVal=READ_WORD(Memory.C4RAM+0x1f83);
+ C4Op1F();
+ WRITE_WORD(Memory.C4RAM+0x1f86, C41FAngleRes);
+ break;
+
+ case 0x22: // Trapezoid
+ {
+#ifdef DEBUGGER
+// printf("22 Trapezoid!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 22 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ int16 angle1=READ_WORD(Memory.C4RAM+0x1f8c)&0x1ff;
+ int16 angle2=READ_WORD(Memory.C4RAM+0x1f8f)&0x1ff;
+#ifdef DEBUGGER
+ if(C4CosTable[angle1]==0) fprintf(stderr, "22 Trapezoid: Invalid tangent! angle1=%d\n", angle1);
+ if(C4CosTable[angle2]==0) fprintf(stderr, "22 Trapezoid: Invalid tangent! angle2=%d\n", angle2);
+#endif
+ int32 tan1=(C4CosTable[angle1]!=0)?((((int32)C4SinTable[angle1])<<16)/C4CosTable[angle1]):0x80000000;
+ int32 tan2=(C4CosTable[angle2]!=0)?((((int32)C4SinTable[angle2])<<16)/C4CosTable[angle2]):0x80000000;
+ int16 y = READ_WORD(Memory.C4RAM+0x1f83) - READ_WORD(Memory.C4RAM+0x1f89);
+ int16 left, right;
+ for(int j=0; j<225; j++)
+ {
+ if(y>=0)
+ {
+ left = SAR((int32)tan1*y, 16) -
+ READ_WORD(Memory.C4RAM+0x1f80) +
+ READ_WORD(Memory.C4RAM+0x1f86);
+ right = SAR((int32)tan2*y, 16) -
+ READ_WORD(Memory.C4RAM+0x1f80) +
+ READ_WORD(Memory.C4RAM+0x1f86) +
+ READ_WORD(Memory.C4RAM+0x1f93);
+
+ if(left<0 && right<0){
+ left=1;
+ right=0;
+ } else if(left<0){
+ left=0;
+ } else if(right<0){
+ right=0;
+ }
+ if(left>255 && right>255){
+ left=255;
+ right=254;
+ } else if(left>255){
+ left=255;
+ } else if(right>255){
+ right=255;
+ }
+ }
+ else
+ {
+ left=1;
+ right=0;
+ }
+ Memory.C4RAM[j+0x800] = (uint8)left;
+ Memory.C4RAM[j+0x900] = (uint8)right;
+ y++;
+ }
+ }
+ break;
+
+ case 0x25: // Multiply
+#ifdef DEBUGGER
+ printf("25 Multiply!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 25 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ {
+ int32 foo=READ_3WORD(Memory.C4RAM+0x1f80);
+ int32 bar=READ_3WORD(Memory.C4RAM+0x1f83);
+ foo*=bar;
+ WRITE_3WORD(Memory.C4RAM+0x1f80, foo);
+ }
+ break;
+
+ case 0x2d: // Transform Coords
+#ifdef DEBUGGER
+// printf("2d Transform Coords!\n");
+ if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 2d %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+ if(READ_3WORD(Memory.C4RAM+0x1f8f)&0xff00ff) printf("2d transform coords: Unexpected value in $7f8f: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8f));
+ if(READ_3WORD(Memory.C4RAM+0x1f8c)!=0x001000) printf("0d transform coords: Unexpected value in $7f8c: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8c));
+#endif
+ C4WFXVal=READ_WORD(Memory.C4RAM+0x1f81);
+ C4WFYVal=READ_WORD(Memory.C4RAM+0x1f84);
+ C4WFZVal=READ_WORD(Memory.C4RAM+0x1f87);
+ C4WFX2Val=Memory.C4RAM[0x1f89];
+ C4WFY2Val=Memory.C4RAM[0x1f8a];
+ C4WFDist=Memory.C4RAM[0x1f8b];
+ C4WFScale=READ_WORD(Memory.C4RAM+0x1f90);
+ C4TransfWireFrame2();
+ WRITE_WORD(Memory.C4RAM+0x1f80, C4WFXVal);
+ WRITE_WORD(Memory.C4RAM+0x1f83, C4WFYVal);
+ break;
+
+ case 0x40: // Sum
+#ifdef DEBUGGER
+ printf("40 Sum!\n");
+ if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 40 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ {
+ uint16 sum=0;
+ for(int i=0; i<0x800; sum+=Memory.C4RAM[i++]);
+ WRITE_WORD(Memory.C4RAM+0x1f80, sum);
+ }
+ break;
+
+ case 0x54: // Square
+#ifdef DEBUGGER
+ printf("54 Square!\n");
+ if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 54 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ {
+ int64 a=SAR((int64)READ_3WORD(Memory.C4RAM+0x1f80)<<40, 40);
+ // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF));
+ a*=a;
+ // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF));
+ WRITE_3WORD(Memory.C4RAM+0x1f83, a);
+ WRITE_3WORD(Memory.C4RAM+0x1f86, (a>>24));
+ }
+ break;
+
+ case 0x5c: // Immediate Reg
+#ifdef DEBUGGER
+ printf("5c Immediate Reg!\n");
+ if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 5c %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ for (i = 0; i < 12 * 4; i++)
+ Memory.C4RAM [i] = C4TestPattern [i];
+ break;
+
+ case 0x89: // Immediate ROM
+#ifdef DEBUGGER
+ printf("89 Immediate ROM!\n");
+ if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 89 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
+#endif
+ Memory.C4RAM [0x1f80] = 0x36;
+ Memory.C4RAM [0x1f81] = 0x43;
+ Memory.C4RAM [0x1f82] = 0x05;
+ break;
+
+ default:
+#ifdef DEBUGGER
+ printf ("Unknown C4 command (%02x)\n", byte);
+#endif
+ break;
+ }
+ }
+ } else if (Address == 0x7f47) {
+#ifdef DEBUGGER
+// printf("C4 load memory %06x => %04x, %04x bytes\n", READ_3WORD(Memory.C4RAM+0x1f40), READ_WORD(Memory.C4RAM+0x1f45), READ_WORD(Memory.C4RAM+0x1f43));
+ if(byte != 0) printf("C4 load: non-0 written to $7f47! Wrote %02x\n", byte);
+ if(READ_WORD(Memory.C4RAM+0x1f45) < 0x6000 || (READ_WORD(Memory.C4RAM+0x1f45) + READ_WORD(Memory.C4RAM+0x1f43)) > 0x6c00) printf("C4 load: Dest unusual! It's %04x\n", READ_WORD(Memory.C4RAM+0x1f45));
+#endif
+ memmove(Memory.C4RAM+(READ_WORD(Memory.C4RAM+0x1f45)&0x1fff),
+ S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f40)),
+ READ_WORD(Memory.C4RAM+0x1f43));
+ }
+}
+
+int16 C4SinTable[512] = {
+ 0, 402, 804, 1206, 1607, 2009, 2410, 2811,
+ 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
+ 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
+ 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
+ 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
+ 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
+ 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
+ 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
+ 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
+ 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
+ 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
+ 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
+ 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
+ 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
+ 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
+ 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765,
+ 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
+ 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
+ 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
+ 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
+ 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
+ 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
+ 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
+ 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
+ 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
+ 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
+ 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
+ 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
+ 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
+ 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
+ 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
+ 3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
+ 0, -402, -804, -1206, -1607, -2009, -2410, -2811,
+ -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
+ -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
+ -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
+ -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
+ -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
+ -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
+ -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
+ -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
+ -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
+ -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
+ -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
+ -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
+ -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
+ -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
+ -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
+ -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
+ -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
+ -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
+ -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
+ -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
+ -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
+ -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
+ -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
+ -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
+ -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
+ -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
+ -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
+ -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
+ -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
+ -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
+ -3211, -2811, -2410, -2009, -1607, -1206, -804, -402
+};
+
+int16 C4CosTable[512] = {
+ 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
+ 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
+ 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
+ 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
+ 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
+ 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
+ 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
+ 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
+ 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
+ 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
+ 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
+ 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
+ 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
+ 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
+ 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
+ 3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
+ 0, -402, -804, -1206, -1607, -2009, -2410, -2811,
+ -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
+ -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
+ -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
+ -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
+ -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
+ -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
+ -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
+ -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
+ -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
+ -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
+ -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
+ -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
+ -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
+ -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
+ -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
+ -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
+ -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
+ -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
+ -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
+ -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
+ -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
+ -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
+ -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
+ -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
+ -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
+ -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
+ -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
+ -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
+ -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
+ -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
+ -3211, -2811, -2410, -2009, -1607, -1206, -804, -402,
+ 0, 402, 804, 1206, 1607, 2009, 2410, 2811,
+ 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
+ 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
+ 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
+ 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
+ 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
+ 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
+ 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
+ 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
+ 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
+ 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
+ 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
+ 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
+ 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
+ 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
+ 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765
+};
+
diff --git a/source/changes.txt b/source/changes.txt
new file mode 100644
index 0000000..3aabb22
--- /dev/null
+++ b/source/changes.txt
@@ -0,0 +1,2155 @@
+Snes9x 1.43 (WIP1)
+- Win32: added .avi output feature (blip)
+- Win32: fixed frame timings >100ms, added frame advance (blip)
+- Rewrote Unfreeze, renamed it S9xUnfreezeFromStream,
+ failing to load a freeze file no longer resets emulation (blip)
+- Fixed Unfreeze to restore IPPU.HDMA properly (blip)
+- Rewrote OBC1 code to match the real chip (Overload)
+- More updates the to DSP-1 code, fixes to projection (Overload, Andreas Naive)
+- Unix/X11: Rewrote keyboard setup code (Bisqwit)
+- Added movie recording+rerecording support (blip, Bisqwit)
+- Added -hidemenu CLI switch (funkyass)
+- fixed broken Win32 filters (lantus)
+- Added internal support for emulating the new-style SNES (MKendora)
+- Cleaned up many quirks of the cheat search engine (MKendora, Don Vincenzo)
+- Fix mosaic in hires SNES modes (Tokimeki Memorial) (MKendora, zones)
+- Rewrote Legend's hack, added another game to it (MKendora)
+- Optimized the Open ROM dialog (MKendora)
+- Rewrote the Seta DSP map (The Dumper, MKendora)
+- Began string isolation for the UI, eases translation (funkyass)
+- added -nopatch -nocheat, and -cheat CLI items (MKendora)
+- fixed a UI typo (funkyass)
+- fixed several C core stack ops in emulation mode (MKendora)
+- split emulation mode ops from native mode ops (MKendora)
+- Seta special chip emulation enhancements (Feather, The Dumper, Overload, MKendora)
+- code tweaks to the ST010 (Nach, pagefault)
+- fix some C/asm quirks and HDMA quirks (all my fault) (MKendora)
+- several timing hacks to fix games (lantus)
+- improved checksumming for odd mirrorings (MKendora)
+- Snes9x uses a standard zlib instead of a packaged one (PBortas)
+- Exhaust Heat 2 and regional ports are playable (Feather, The Dumper, Overload, MKendora)
+- Game Doctor dumps that are 24 Mbit are now supported by
+ a force option (MKendora, Nach)
+- SuperFx interleave format is now considered deprecated.
+ Support will be removed in future versions (Team decision)
+- made SuperFx interleave detection a compile option (MKendora)
+- added memory maps for slotted games (MKendora)
+- fixed a typo in the usage messages (MKendora)
+- fixed the bug that had nuked optimizations (The Dumper)
+- restored full speed optimizations in release builds (funkyass)
+- Added non-speed-hack version of color subtraction. (zones)
+- Fixed mouse offset in resized X11 window. (PhaethonH)
+- Fixed a (presumably) long-standing bug: Mode 6's BG is
+ depth 4, not depth 8! (anomie)
+- Unix: unmap all joystick buttons before applying -joymapX (anomie)
+- Win32: added a define to disable pausing when focus is lost, NOPAUSE (funkyass)
+- Win32: Changed the default for Auto-save SRAM to 15 sec (funkyass)
+- Dreamcast: Added SH4 assembler (PBortas, Marcus Comstedt, Per Hedbor)
+
+
+Snes9x 1.42
+- Added 8-bit rendering filters (funkyass)
+- Added Sanity Checks for the Display Dialog (funkyass)
+- New Layout for the Joypad Dialog, (funkyass)
+- Fixed that anoying Joypad dialog bug. Now check to see
+ if the axis exists before asking for the info form it (funkyass)
+- Added full POV support. (funkyass)
+- Fixed sram sizes for SuperFx games (Nach, MKendora)
+- Stopped saving sram for games with no battery (Nach, Mkendora)
+- Killed the gray line and slightly optimized Win32 GL (MKendora)
+- stack wrapping fix in C core (MKendora)
+- removed some dead hacks (Oda Nobunaga and Dezaemon) (MKendora)
+- fixed some DMA and HDMA modes (anomie, MKendora)
+- improved HDMA timing (anomie)
+- cleaned up load and deinterleave code (MKendora)
+- removed old UI DLL (MKendora)
+- new cheat dialogs (MKendora)
+- started Unicode preparation in Win32 UI (MKendora)
+- Implement odd sprite sizes, sprite priority rotation. (anomie)
+- RTO code that hopefully works. MK's #define is
+ "MK_DEBUG_RTO" to try to debug the RTO code. (anomie)
+- SDD1 decompression support for Linux. Also added a new
+ command line option -sdd1-pack. (anomie)
+- Added correct VRAM read logic. #define CORRECT_VRAM_READS
+ if you want it. (anomie)
+- removed the non-VAR_CYCLES path (MKendora)
+- changed access timing map to be address-based. (MKendora, anomie)
+- DSP-1 updates (Overload, Andreas Naive)
+- S-DD1 decompression support (Andreas Naive)
+- optimized S-DD1 code (anomie)
+- S-DD1 can use packs or decompression (MKendora)
+- More work on Exhaust Heat 2 (MKendora, Overload, The Dumper)
+- separated ROM detection from file reading (lantus)
+- fixed a mirroring bug in LoROMs (MKendora)
+- cleaned up some mapping issues (MKendora)
+- ST018 games now boot before locking up (Mkendora, Overload)
+- SA-1 state was not completely reset, crashed Marvelous (zones)
+- Removed sample caching. It caused problems, and was not
+ noticably faster. (MKendora)
+- Fixed interlace without breaking the displays for MK (anomie)
+- Fixed a PPU OpenBus hack (anomie)
+- Moved SPC7110 and S-DD1 regs to speed up the general case
+ of reading the $4xxx registers (MKendora)
+- altered Hi/Lo ROM detection to fix a few misdetects. (MKendora)
+- Implemented RTO flags. With MK's implementation of $213F's
+ interlace bit, we now pass the SNES Test Cart's
+ Electronics Test (anomie)
+- Fix sprite windowing bug (anomie)
+- Way back in 1.40 MK changed the Windows port to default
+ to a plain old joypad instead of the MP5. And then we
+ removed the hacks for games that dislike the MP5. So
+ we need to change the defaults elsewhere too... (anomie)
+- cleaned up the hacks section somewhat (MKendora)
+- removed some interleave hacks (MKendora)
+- fixed a bug in KartContents (MKendora)
+- transparency fix for Jurassic Park (lantus)
+- A hidden Win32 feature (MKendora)
+- Kludged Mark Davis until I get stable APU timing (MKendora)
+- Win32 renders overscan always, fixes some jumpy games (MKendora, lantus)
+- Fixed an FMOD bug (MKendora)
+- cosmetic tweaks (Everyone)
+- Fixed 2 special chip bugs in the C core (zones)
+- Added some sanity fixes to the C core, fixes MLBPA
+ Baseball for C core users (zones)
+- updated zlib source (includes 1.1.4-1 patch) (MKendora)
+- compiler warning fixes (PBortas)
+- Updated the SuperFx asm core (pagefault)
+- Kludged Unix compilation to produce working SuperFx (PBortas)
+ with the asm core.
+- Kludged VC to deal with optimization weirdness (MKendora)
+- Hacked Robocop vs. Terminator using Daffy Duck hack. Stops
+ flashing. (MKendora)
+- Added some defines to the asm core (MKendora)
+- Added possibility to take screenshots on Unix (PBortas)
+- Initialize the C SuperFx core better (PBortas)
+- Kludge a Japanese golf game until the APU timing is fixed (MKendora)
+
+
+Snes9x 1.41-1
+
+- Oops, in the asm CPU core i was stomping on %eax too
+ early, so register $4210 wasn't getting set properly. (anomie)
+
+
+Snes9x 1.41
+
+- Win32 controllers now stay the same between games (MKendora)
+- Win 32 Open ROM dialog fixes (MKendora)
+- Win32 Display dialog fixes (funkyass)
+- Win32 OpenGL ratio tweaking. (Reduces the gray line) (kode54)
+- Fixed Win32 superscope for those having issues (MKendora)
+- Generic accuracy fix in main SUperscope emulation (MKendora)
+- sprite bug fixed (gah! How'd we miss that) (anomie)
+- SPC saving compatibility fix (Caz and zones)
+- Window clipping update (anomie)
+- Mode 7 clipping fix (TRAC)
+- latching fix (anomie)
+- BS BIOS checksum and mapping fix (MKendora)
+- Working Uniracers hack (dma.cpp) (anomie)
+- HDMA Indirect Address fix for Romancing Saga 2 (anomie)
+- Better savestate hack, does it break anything? (anomie)
+- C4 C core fixes. Mostly Trapezoid (thanks Nach),
+ some s/short/int16/, some indentation. (anomie)
+- Damn, but the indentation in ppu.cpp was screwed up.
+ Killed some dead code too (twas commented forevermore). (anomie)
+- fixed a potential crash in S-DD1 logging (MKendora)
+- Improved accuracy of Hi/LoROM detection (~500 ROM test) (MKendora)
+- Hack for Moryou Senki Madara 2, don't call
+ SelectTileRenderer from DrawOBJS if BGMode is 5 or 6. A
+ real fix requires at least rewriting SelectTileRenderer,
+ or inlining a special version in DrawOBJS. (anomie)
+- DMA traces: add additional address info to reads too. (anomie)
+- Killed the old Borland Joypad dialog (funkyass)
+- Fixed issues with Dezaemon and CT, maybe others (anomie, MKendora)
+- Changed the internal snapshot key from \ to VK_F12 (funkyass)
+ Fixes issues with non-US keyboard layouts.
+- Fixed OAM reset to not occur during forced blank. (anomie)
+- Killed some dead OAM reset code that doesn't need saving. (anomie)
+- Unix/X11: Fixed screen jumping. CT enables overscan mid-
+ frame for only one frame, and we now update the rendered
+ screen height accordingly. Other ports are still broken. (anomie)
+- Unix/X11: Fixed possible TV mode crash. (anomie)
+- Fixed OAM reset timing (beginning of V-Blank rather than
+ end) for R-TYPE 3 (J). (anomie)
+- Unix/X11: Fixed OpenGL target (PBortas)
+- Unix/OSS: Fixed big endian sound (PBortas/ernstp)
+- Tweaked the About Dialog so its read-only and no scroll (funkyass)
+
+
+Snes9x 1.40
+
+- cleaned up a sound skipping code issue. Same as the
+ RTC issue (lantus)
+- re-fixed the invalid BRR header behavior twice (Lord Nightmare, FatlXception, Mkendora)
+- More BS mapping fixes. (The Dumper, MKendora)
+- Fixed Ranma Bun no 1 - Chonai Gekitou Hen (J) and
+ Street Combat (U). Interlace is not supported in the
+ non-Hi-res modes, as far as I can tell. (MKendora)
+- Also fixes Maka Maka (J). Frank Yang's report, and
+ anomie's code both provided clues to this one.
+- Removed special casing on setting 5c77 version to one.
+ This seems to be true for U and J units always. I need
+ it checked out on PAL... (neviksti)
+- Using SNEeSe's values for 5c78 and 5A22. Note we know
+ that the 5c78 version can also be 1 or 2, instead of 3. (TRAC, neviksti)
+- Added turbo buttons. Credit/blame for the design goes
+ to slack, Nave, Gogo, and myself. (MKendora)
+- fixed a bug in turbo (slack, MKendora)
+- Tried merging the behavior of Old $4200 with new $4200 (MKendora)
+- Made $4200's return value match what VSMC Explorer
+ showed on Fancia's SNES (MKendora)
+- Fixed a matrix multiplcation bug in ZSNES state loads (MKendora)
+- Fixed Dezaemon and Ys3 mode 7 (lantus)
+- Fixed H-DMA modes 5-7. Thanks to The Dumper for the
+ extra motivation needed. GunForce and Genocide 2 work. (The Dumper, MKendora)
+- Fixed BG3 Priority. I'm stupid. anomie had fixed it,
+ but lantus fixed it again, because I didn't use it. (anomie, lantus)
+- Added a Star Fox 2 hack, and an interleave skip (The Dumper, lantus, MKendora)
+- Cleared BS setting on load (lantus)
+- Fix for Mode 7 priorities. fixes F-1 Grand Prix (all 3) (anomie)
+- JANJYU GAKUEN 2 needs Multi-tap 5 off. (Frank Yang, MKendora)
+- HONKAKUHA IGO GOSEI: No multi-tap 5, allow mouse (lantus, MKendora)
+- Added a few missed conditional compiles (Nach)
+- disabled multitap 5 by default, added menu to enable (MKendora)
+- special thanks to anomie and lantus. One of them is
+ responsible for a bug fix I forgot already. (anomie, lantus)
+- Removed several Multitap5 disable hacks. (MKendora)
+- Added an SPC dumping upgrade from kode54 (kode54)
+- cleaned up some resource leaks (MKendora)
+- I forgot this since 1.39mk, but SPC700 flag fixes (anomie)
+- Mode 7 interpolation screen flip fix (anomie)
+- Updated SPC7110 code a bit, for compatibility (Daniel, anomie)
+- Changed RTC saving. (Byte exact to old format on Win32)
+ The submitted patch for "safety" doubled the file size,
+ so I had to write it in explicitly little-endian. (MKendora)
+- Removed the old hidden cursor (MKendora)
+- Applied a WAI correction from anomie. (anomie)
+- Added a patch for Pseudo hi-res (anomie)
+- Hacked around Word writes to $7F:FFFF. Thanks to lantus
+ and The Dumper for verification. (MKendora)
+- PPC compile fix? and debugger reversion (anomie)
+- Set defaults differently to improve sound quality. (MKendora)
+- Clear Force load settings after Init (lantus)
+- Made menu reset a soft reset. Fixed BL Sound Test & more (CaitSith2)
+- Fixed word writes to block bounds in asm core. (MKendora)
+- redone version of my bounds fix, only this one WORKS! (TRAC)
+- Thanks to TRAC for the AT&T syntax refresher! (TRAC)
+- Fixed screen saver disable (kode54)
+- Fixed OAM and sprite priority in the asm core (anomie)
+- Proper Interlace fix for mid-frame changes (anomie)
+- Fixed OpenGL to accomodate previous patch (MKendora)
+- Ported the "Settings" dialog to VC (MKendora)
+- Fixed ROM Info bugs (_pentium_five, MKendora)
+- Fixed non-stretched interlacing, but it's s.l.o.w. (anomie)
+- Superscope and Mouse need to be enabled by the menu. (MKendora)
+- Fixed HiROM sram reads in asm and C cores (anomie, MKendora)
+- Added Company 48 to the list. Thanks to _pentium_five_ (StatMat)
+- Set Super Drift Out's S-ram correctly. (Snes9xppSE Team)
+- Fixed NTSC timing. Helps ToP Intro greatly (kode54)
+- Added several entries to the company list, from uCON64 (Nach)
+- Lots more companies (StatMat, Nach)
+- Fixed Win32 Superscope support (NT kernel only?) (MKendora)
+- Added ZSNES OBC1 code ported from asm to C (sanmaiwashi)
+- Implemented Justifier emulation (neviksti, MKendora)
+- Fixed Rudora no Hihou's clip window bug (anomie)
+- Fixed Flintstones sprite issue (lantus)
+- Fixed sram mappings for Big Sky Troopers and
+ Taikyoku - IGO Goliath. Both map in bank F0 (MKendora)
+- Fixed a possible crash when switching audio settings (MKendora)
+- Added per-pack gfx pack configuration (MKendora)
+- Fixed glitches in DSP-1 games (Flintstones fix) (lantus)
+- Added delay to Superscope latching. Fixes X-Zone. (neviksti, MKendora, zones)
+- Added DSP-2 support (Overload, The Dumper, Lord Nightmare,
+ MKendora, neviksti)
+- Fixed Super Bases Loaded 2 (and J/K ports) DSP-1 seems
+ to ignore the A15 line in LoROM maps (MKendora)
+- Corrected $4200 again (The Dumper)
+- Corrected $2100, $2102, and $2102 read behavior (anomie)
+- Fixed Cancel on the Sound Options dialog. (MKendora)
+- Fixed the sound options dialog (Thanks, Quattro) (MKendora)
+- updated DSP-1 support to match chip better (Overload, neviksti, The Dumper)
+- added a few Ops to the DSP-4 routine (Nothing plays yet) (neviksti, The Dumper, Overload, MKendora)
+- added screenshot support (anomie, sanmaiwashi)
+- stubbed the ST010 chip in Exhaust Heat 2 (Overload, MKendora)
+- hacked around War 2410's lockup (pagefault, _Demo_, MKendora)
+- updated tests for type 1 ROMs (based on reset vector) (MKendora)
+- Emulation mode CPU fix (The Dumper)
+- Open Bus fixes (anomie)
+- Better Expansion port emulation (anomie)
+- More Open Bus fixes (Overload, anomie)
+- HDMA fixes (fix colors only in Full Throttle Racing) (anomie)
+- Migrated DKJM2 onto the Tales map (MKendora)
+- Tried to remove Dragon Knight 4 hack (LoROM sram fix) (MKendora)
+- Fixed ROM Mirroring for LoROMs (<= 32 Mbit) (MKendora, TRAC)
+- blocked wram to wram DMAs (neviksti)
+- fixed HiROM mirroring, too. Thanks TRAC! (MKendora, TRAC)
+- fixed C core RMW and Push ops to write in the correct
+ order, fixes Michael Jordan gfx. (anomie, Overload, MKendora)
+- set RDIO to start as 0xFF, fixes SuperFx games. (anomie, Overload)
+- New connect dialog (funkyass)
+- better conditional compile of FMOD (funkyass)
+- fixed screenshot code when libpng is not used (funkyass)
+- added portability fixes (zones)
+- fixed asm Pushes (anomie)
+- fixed asm LoROM s-ram decode (MKendora)
+- migrated DEZAEMON to standard LoROM map (MKendora)
+- fixed the Madara 2 OpenGL bug (key found in Rudra) (MKendora)
+- fixed asm RMW instructions (MKendora)
+- fixed ADC opcode (The Dumper)
+- added DSP-2 Op09 (The Dumper)
+- updated C4 C code (anomie)
+- updated C4 asm code (Nach)
+- Keep OpenGL in ratio (kode54)
+- Replaced many more Borland dialogs (funkyass, MKendora, Nach)
+- Added CRC32 to displayed ROM Info (Nach, MKendora)
+- Fix cheat support (The Dumper)
+- improved DMA timing (MKendora, Overload, The Dumper)
+- Fixed Mode 7 math, removed Dezaemon, Gaia, Ys 3 hacks (TRAC, MKendora)
+- Mode 7 flip fix (TRAC)
+- Multiple safety and initialization fixes (zones)
+- Platform safety fixes (PBortas)
+- Memmap cleanups (MKendora)
+- More preliminary work on special chips (The Dumper, Overload, MKendora)
+- Added color coding (MKendora)
+- Another HDMA fix (anomie)
+- added another known hack to the hacked games list (Nach)
+- ToP memmap changes (MKendora)
+- Checksum calculation changes (MKendora)
+- Special cased a few games for OAM issues (MKendora)
+- Reverted OAM reset to 1.39 timing (MKendora)
+- Reworked vram wrapping (zones, Mkendora)
+- Fixed $4210 and Super Professional Baseball 2 (Overload, MKendora)
+- Fixed APU RAM init (Overload, MKendora)
+- More support for Exhaust Heat 2 (not playable) (The Dumper, Overload, neviksti)
+- removed some debris from save states (MKendora)
+- fixed? Doom's save state bug (MKendora)
+- simple overdump detection warning (MKendora)
+
+
+1.39mk3b
+
+- Fixed the RTC detection. FINALLY done correctly (lantus, MKendora)
+
+
+1.39mk3a
+
+- neatened up the company table. (MKendora)
+- fixed a mistake in the ROM Info box (MKendora)
+- Added a Calulcated Size field to ROM INfo. (MKendora)
+- Added 3 more companies to the ROM Info table (MKendora)
+- Fixed BS detection (The Dumper)
+- Added a Legend-specific hack to get sound. I remembered
+ it being mentioned in the changelog. (Gary Henderson)
+- Unbroke the Star Ocean special cases (Trigger of Time, MKendora)
+- Company 255 is not Hudson-ZFE detects all Hudson games
+ without it, except a corrupt dump (StatMat, MKendora)
+- fixed a bug in the redone detection for the SPC7110 (CaitSith2)
+- 44Khz sound should be 44.1Kz. Changed, though you'll
+ need to re-set 44.1Khz to make it take effect. Not sure
+ if this affects non-Windows ports. (MKendora)
+- Added 32Khz playback (MKendora)
+- Inproved BS ROM mapping (_Demo_, The Dumper, MKendora)
+
+
+1.39mk3
+
+- Honkaku Syogi Fuunji Ryuou (J) fixed (force no multitap) (Frank Yang)
+ Also Fixed Super Castles (j).
+ Also fixed a bunch more. This dude e-mailed like 100 bugs
+ to my hosts, some already fixed in Snes9x1.39mk2, but
+ about 7 were clearly multi-tap5.
+- also fixed Dekitate High School. Error was in Japanese (Frank Yang, Tomato)
+- fixed 2 memory leaks (Aaron)
+- Dai Kaiju Monogotari 2 works as a 40 Mbit ROM. (MKendora, The Dumper)
+- Fixed the Flashback bug. Lots of info led to this. (neviksti, MKendora)
+ Thanks neviksti, The Dumper, TRAC, and FatlXception
+ for clarifying the behavior.
+- Fixed Sailor Moon Fuwa Fuwa Panic 2 to work with (neviksti, MKendora)
+ previous fix. It's a total hack, but it should sound
+ just like the old Snes9x did. neviksti strikes again!
+- Dirty hack to make 3 games deinterleave properly: (MKendora)
+ Wizardry 4, Mark Davis, and Honkakuha Igo Gosei(FX)
+ all work as well as the deinterleaved counterparts.
+ (The last is a hacked game, and you should get the
+ non-FX version)
+- Fixed Seima Jyuden Beasts and Blades. Another Multitap, (Frank Yang)
+ but for some reason, the hack requires the C cpu core.
+ Thanks to Tomato for taking a stab at the error message,
+ as well. It was too vague to be of use, he said. I
+ just tried it because it worked on other games.
+- Res Arcana fixed. Another Frank Yang report, another J (Frank Yang, MKendora)
+ error, but I can read kana well enough with a table!
+- Removed a Terranigma specific hack. Not sure, but the (anomie)
+ new behavior might have fixed Tin-Tin in Tibet's colors.
+- Dirty hack to work around a dirty hack. Both Yoshi's (MKendora)
+ Island (E) dumps should work now
+- Added the JumboLoROM memory map, Extends LoROM support (The Dumper, neviksti, MKendora)
+ to 48+ Megabits.
+- added an EXTBG fix, since iirc, TRAC is using it as well (anomie)
+ Does it actually fix anything?
+- Fixed crash in DSP Op06 (The Dumper)
+- Fixed a GUI error on my part (Trigger of Time)
+- Cleaned up some of the SPC7110 detection/size code. (MKendora)
+- Merged in XBox port changes to SPC7110 code (lantus)
+- Added a call to Memory.Deinit when exiting. (lantus, MKendora)
+- Many memory leaks fixed while chatting with lantus (lantus, MKendora)
+- Fixed that stubborn open/close leak (lantus)
+
+
+1.39mk2
+
+- hacked in Shien's Revenge (anomie)
+- fixed Orge Battle's green lines. (CPU source for DMA) (anomie)
+ - Looks interesting, and might apply to other DMA cases?
+- maybe "fixed" DKC's barrels? by treating $2001
+ as unmapped. The game worked before with a hack. (MKendora)
+- optimized SPC7110 slightly by removing extra setup work (MKendora)
+- Fixed DBZ 3 (Korean). S. Korea is, in fact, NTSC. (MKendora)
+- Fixed a hard-coded value in the SPC7110 (MKendora)
+- Added a Win port ROM Info dialog (MKendora)
+ - some companies aren't in the table I used.
+ If you encounter an Unimplemented company,
+ report it the the Snes9x development forum, with
+ the correct company and the number.
+
+
+1.39mk
+- SPC7110 support based on Dark Force's docs. (Dark Force, zsKnight,
+ The Dumper, MKendora)
+ Trust me when I say those guys deserve the credit more
+ than me. From what I'm told, Dark Force is the man
+ behind most of the reverse engineering, but they all
+ did a much harder bunch of work than I did following
+ their specs. It's plain and simple that these three
+ are the masterminds behind all SPC7110 support.
+
+ Dark Force for reverse engineering the chip (Extremely tough work!)
+ zsKnight for the original core, and probably other things
+ The Dumper for dumping the packs and doing hardware tests.
+
+ Also thanks to CaitSith2 for numerous bug reports
+ and a lot of bug fixes.
+
+- Theme Park hack removed, fixed via PPU latching (anomie, MKendora, TRAC)
+- WWF Wrestlemania hack removed (anomie, TRAC)
+- Strike Gunner hack fixed (anomie, MKendora, TRAC)
+- FF:MQ text fixed. May help other sprite issues. (TRAC)
+- Umi Hara Kawa Se timing corrected. (anomie)
+- S-DD1 packs load by the same rules as ZSNES (MKendora)
+- SPC7110 code builds in linux (Lord Nightmare, zinx)
+- Added The Dumper's DSP-1 updates (The Dumper)
+- SPC7110 is correctly displayed on load, RTC also noted. (MKendora)
+- Fixed a potential graphics problem (TRAC)
+ no known games fixed, but who knows?
+- Fixed Ballz3D (pagefault)
+- Re-fixed Ballz3D, via DSP op 0F (The Dumper)
+- included some of anomie's fixes. Many caused me grief,
+ so only Marko's Magic Football is intentionally fixed. (anomie)
+- finished zsnes save support, though I don't know how
+ well it will work with SPC7110 games (MKendora)
+- Added a new soundux.cpp again to fix some noise.
+ (Fixes the GW "fart track") (Lord Nightmare, info from Anti-Res)
+- Added 3 cache modes for SPC7110 games (MKendora)
+- Added new BRR decoder. Requires sample caching
+ and the Anti-Res decoder be disabled. (FatlXception, port by Lord Nightmare)
+- Added CaitSith2's RTC debugger. define RTC_DEBUGGER in
+ project settings to enable it. (CaitSith2)
+- SPC7110 per-game cumulative logging (MKendora)
+- other fixes that I've forgotten (sanma iwashi, TRAC, anomie, ????)
+
+- "I'm not worthy" thanks to the original SPC7110 crew (DF, zsKnight, and the Dumper)
+- Thanks again to the same people, because they deserve it!
+- thanks to The Dumper, Dejap, TRAC, and all the ZSNES crew for technical assistance
+- Thanks to most of the Snes9x mods for testing (no thanks to you, Raptor ;)
+- and thanks to TRAC and #mkendora for letting me vent at you.
+
+1.39
+- Added SDD-1 unknown graphics data logging at the dumper's request. A bit late
+ but might help with Street Fighter 2 Alpha's data dumping. Creates a
+ romname.dat file in the freeze file folder.
+- Implemented 16-bit texture support for OpenGL modes in Windows and Linux.
+ Had to support a new pixel format type to do it - RGB5551 (one bit of alpha)
+ which caused me some major problems - black was no longer always pixel value
+ zero!
+- Removed the Bump map OpenGL mode from the Windows port (didn't look so good
+ anyway and was slow).
+- Added a hidden novelty OpenGL mode (clue: a keyboard shortcut activates it)
+- Reverted back to FMod version 3.20 after reports that version 3.33 broke
+ AD3 support.
+- Implemented a better work-around for the broken select system call in the
+ Linux kernel - the original work-around was long-winded and stopped working
+ when I implemented OpenGL support under Linux.
+- Added the same speed-up hack to the OpenGL code that the Glide code already
+ supported. Basically, if your OpenGL implementation supports 16-bit textures
+ then OpenGL mode should be as fast, or faster than the 3dfx Glide mode.
+- Hopefully fixed Glide support.
+- Reverted back to the original colour blending code. The newer code, although
+ more accurate in most cases, had too many glitches and was slower.
+- Included multiple Japanese games fixes from Iswashi San.
+- Fixed a timing problem caused by a speed up hack that was affecting Top Gear
+ 300. No the game still isn't playable yet, but I noticed the problem while
+ investigating the DSP-4 chip used by the game.
+1.38
+- Added support for Star Ocean and Street Fighter 2 Alpha decompressed graphics
+ packs from dejap. Used a binary chop search rather than a linear search to
+ locate correct decompressed graphics more quickly - should help emulation
+ speed during later stages of the game.
+- Included OpenGL support into the Linux port and speeded up the Windows OpenGL
+ implementation slightly. The real speed up would occur if I could figure out
+ how/if 16-bit textures are supported in OpenGL because at the moment the
+ 16-bit software rendered SNES image must be converted to 24-bit before being
+ uploaded as a texture...
+- Included the latest ZSNES DSP-1 code. Now Pilotwings, SD Racer and Suzuka 8
+ Hours are playable. Aim For The Ace, Super Air Diver 1 & 2 and Syutoko Battle 94
+ are also playable, but with bugs. Thanks to zsKnight, _demo_, et al for all
+ their hard work.
+- Another Daffy Duck: Marvin Missions screen flicker problem worked around -
+ writing to the IRQ enable register shouldn't clear any pending IRQs, but
+ Sieken 3 seems to require this or else the game hangs. Special-cased Daffy
+ Duck for now.
+- An NMI emulation bug was triggering a Panic Bomberman World game bug,
+ crashing it. Basically, if a game enables NMIs after the normal trigger
+ point, the NMI should not trigger if the game has already read the NMI clear
+ register.
+- Panic Bomberman World requires SPC700 memory to be initialised to zero on
+ reset otherwise the game hangs when a tune finishes and another one should
+ start.
+- Added mouse pointer auto-hide to the Windows port. Much better than the turn
+ the mouse pointer into a black dot method I was using before.
+- Included the latest ZSNES Super FX code. Not sure if it fixes actually fixes
+ any games.
+- Added an offset hack for Strike Gunner to get the scrolling ground layer
+ to line up correctly - another offset-per-tile bug hacked around for now.
+- Arrr! Left in some debugging code in the last release that prevented all
+ games that need the slower SPC700 timing from working. Removed it.
+- Hmm. The broken cut-scenes in Deep Space 9 seem to indicate that I haven't
+ got the emulated clock speed of the 65c816 CPU correct yet. And not by a
+ little bit - a 9% too slow error. Hacked special timing for the game for now.
+- Added triple-buffering to Windows port - enabling double-buffering actually
+ enables triple-buffering if you have enough free video RAM, defaulting to
+ double-buffering if you don't.
+- Fixed another crash bug in the interpolated mode 7 code - if no scaling
+ was being used (either up or down) and screen repeat was enabled and the
+ screen was flipped horizontally, the routine would crash Snes9x. Was causing
+ Snes9x to crash during rock monster boss stage of Castlevania 4.
+- Oops. Got the initialisation of the default SNES screen width and height
+ round the wrong way - could cause a X Windows System error message on the
+ UNIX port after loading a ZSNES freeze file.
+- Included the unofficial Windows port emulation fixes for several games including
+ Kentouou World championship and TKO Super Championship.
+- Included Iwashi San's improved Anti Res. sound sample decoding routine and
+ updated the C version to match.
+- Included Anti Res. improved sample decompression code he sent me ages ago,
+ but for some reason I didn't include. Sorry. This version seems good enough
+ to leave enabled all the time.
+1.37
+- Added fix for Captain America's corrupt graphics - a ROM bug causes it to
+ read from what I thought should be an unmapped memory area, but it expects
+ the value returned to be zero.
+- Added code to support games that switch to the hi-res. SNES screen mode part
+ way down the screen while using the 3dfx bi-linear filter mode. The code
+ basically has to back out of the speed up hack it was using when the game
+ switches resolutions.
+- Fixed support for games that have mixed lo-res. (256x224), medium res.
+ (512x224) and hi-res. (512x448) all on the same screen - corrects the display
+ of Majin Tensei 2.
+- Added support for games that use sub-screen addition to the back-drop layer
+ while displaying hi-res. graphics - something I thought the SNES couldn't do
+ but the game Marvelous uses this.
+- Reworked the UNIX/Linux output image handling code: the image doesn't always
+ have to be scaled when hi-res. support is enabled, the PutImage operation
+ only updates the area of the screen it has to, the SNES image is now always
+ centred in the window/full-screen area and if the SNES image changes size
+ between frames, the old screen areas are now correctly cleared.
+- Fixed the corrupt graphics problem during the battle scene of Last Bible 3 -
+ it requires that previously unknown DMA mode 5 should just act the same as
+ DMA mode 1.
+- Fixed a nasty bug when H-IRQs were being reused on the same scanline - a logic
+ bug could cause H-DMA processing for that line to be skipped. Was causing
+ the bridge and the start banners to be the wrong colours in Top Gear 2.
+- Added Kreed's display processing modes to the Linux port, including his new
+ asm version of the Super2xSaI mode and the new software bi-linear filtering
+ mode.
+- Think I might have figured out the odd Mode 7 glitch problems the games
+ Illusion and Gaia and Chase HQ were having. My original fix was to mod the
+ centre X & Y values with 1024, but looks like the true fix is to mod
+ X + horizontal offset and Y + vertical offset with 1024 when screen wrapping
+ is enabled.
+- Disabled H-DMA'ing into V-RAM via registers 2118/2119. The game Hook
+ deliberately does this causing graphic corruption while dialog boxes are
+ displayed. Maybe the real SNES disallowed this and it was left in the game by
+ mistake? Not sure what effect the game was trying to produce because
+ disabling the emulation of this feature doesn't seem to affect the game at
+ all, other than stopping the corruption.
+ + Also fixes graphics junk problem on first screen of Bugs Bunny.
+- Added a 'region-free' timing hack for Power Rangers Fight - without it the
+ NTSC version was displaying badly glitching graphics; I'd already fixed the
+ PAL version.
+- Added true priority-per-pixel mode 7 support (the previous support was just
+ a hack to get the colours correct) - level 2 of Contra 3 used this feature.
+- The Japanese, German, French and Spanish version of Illusion of Gaia needs the
+ slow SPC700 timing.
+- Deleted the Breath of Fire 2 S-RAM hack for the hacker intro version -
+ according to reports it was causing problems for the non-hacked version.
+- Legend, the PAL version, never sets the sound master volume control - Snes9x
+ was defaulting this to off, I guess the real SNES must default it to full
+ volume; changed Snes9x. The NTSC version of Legend does set the master
+ volume level, but sets it to off just after the title screen. Hmm. The -nmv
+ command-line switch allows you to hear sound in this version.
+- Panic Bomber World was tripping an SA-1 emulation bug - the WAI instruction
+ emulation code was setting the 'waiting for interrupt' flag on the wrong CPU
+ causing the main SNES to skip an instruction when the next interrupt occurred.
+- Panic Bomber World, Bomberman 4 and UFO Kamen Yakisoban all need the slower
+ SPC700 timing.
+- Oops! The Super Formation Soccer 95 fix was causing Aero 2 to lock up. This
+ means I have no no idea what value the DMA in progress register should
+ represent. I've hacked it and made it toggle between 0 and $ff on each read
+ which gets both games working, for now...
+- The ROM de-interleaving code always assumed the blocks were rearranged based
+ on a power of two, but Francois found a copy of Soldiers of Fortune where
+ this was not the case. Corrected the code.
+1.36
+- Finally worked out why the menu items weren't being highlighted in several
+ ROMs, including Battletoads, U.N. Squadron and All Japan Pro Wrestling.
+ Two problems: its seems the SNES does halve the colour value result when
+ blending colours when only the fixed colour addition/subtraction is enabled,
+ but doesn't halve the result when sub-screen is being blended and its a clear
+ part of the sub-screen. The second problem was that I had an optimisation
+ that prevented the time consuming colour blending code from being called if
+ the colour being added/subtracted was black - adding zero to a number doesn't
+ affect the result, but not performing the side-effect of halving the result
+ does affect the final value...
+- Super Formation Soccer 95 requires that the DMA enabled register doesn't
+ always return zero, otherwise the game locks up.
+- Thanks to several people reporting a screen flickering problem in the
+ pseudo 3-d section of Jurassic Park 2 I've fixed a nasty problem in H-IRQ
+ handling code which could cause double-triggers or skip IRQs altogether.
+ With this fix I can now remove the special hacks for Ninja Warriors Again,
+ Chuck Rock and F-1 Grand Prix.
+- More games needing the slow SPC700 timing:
+ Zennihon Puroresu 2, Soulblazer and Robotrek.
+- The CPU idle time skipping code was skipping cycles during a software delay
+ loop in Itchy and Scratchy, causing screen flicker.
+- Looks like reading the value of register $2137 shouldn't clear a pending
+ IRQ - was causing screen flicker on Yoshi's Island.
+- Actraiser 1 & 2 both need the slow SPC700 timing.
+- Terranigma reads a sound channel's current sample output value and waits for
+ it to be zero before preceeding. I forgot to always return zero when a
+ channel was silent. This mistake was causing the game to lock up.
+ + Itchy and Scratchy and was causing the music to stop and samples to be cut
+ short in the Mario Early Years series.
+- Added a hack for Secret of the Evermore - at several points in the game, just
+ as the plane is about to land, it reads from unknown registers $4000 and
+ $4001 and, if it doesn't get the value its looking for, the game hangs or
+ displays corrupt graphics.
+- Silva Saga 2 was accidentally triggering a colour blending hack I put in
+ place Kirby Dreamland 3 and Kirby Superstar.
+- The ZSNES freeze-file loading code could leave a file open if the file wasn't
+ a valid ZSNES freeze file.
+- Super Punch-out requires certain DMA registers to be updated after the DMA
+ completes. Snes9x used to do that, but I must have accidentally left the code
+ commented out whilst investigating a different problem in another game.
+1.35
+- Added a recently played game list to the Windows port File menu so you can
+ quickly load up your favourite games.
+- Included IPS patching support based on code from Neill Corlett - just rename
+ the patch file to match your ROM image name but with a .ips extension and
+ copy it into your ROM or freeze-file folder.
+- Added John Weidman's and Darkforce's S-RTC, (Real Time Clock) emulation code.
+ The only game that seems to use it is Dai Kaijyu Monogatari II.
+- Included code from Nose000 for games with 128Kbytes of S-RAM. Now
+ Sound Novel-Tcool, Thoroughbred Breeder 3, RPG-Tcool 2 and Dezaemon are
+ supported.
+- The Windows port now has an option to make the 'turbo speed' button a toggle
+ button.
+- The optimised fixed colour addition/subtraction code was ignoring the colour
+ window. Thanks to John Weidman for pointing this out.
+- Added mode 7 and hi-res. hack for Dezaemon from Nose000 - the mode 7 hack
+ looks interesting (to me); I wonder if some other games would benefit?
+- Both Tales of Phantasia and Star Ocean need custom sound CPU timing. Hmm.
+ That's 4 ROMs now, there will be more... That means I still haven't
+ discovered all the major SNES timing quirks. :-(
+- Windows port now has an option to save the S-RAM data at any time.
+- Windows port saving SPC dumps now auto-increments the filename.
+- Added work-around for a Super Robot Wars Ex ROM bug - the game was checking
+ the wrong PPU register for end of h-blank. The game must have only worked by
+ chance rather than by design on a real SNES.
+1.34
+- Corrected the colour addition/subtraction and halve the result code not to
+ halve the result when only the fixed colour is used, i.e. the sub-screen is
+ clear. Discovered and fixed this awhile ago, but I accidentally reintroduced
+ the bug when adding some optimisations a few versions back.
+- Finally cleared the last of the offset per tile background mode bugs. There
+ was something odd about the tile at the left-hand edge of the screen that I
+ couldn't figure out - well now I have. Yoshi's Island level 6 boss screen,
+ Mario RPG mine cart screen and Jim Power title screen now all display
+ correctly.
+- Made reading blank areas of the SNES memory map return the middle byte of
+ the address - fixes Home Alone which tries to execute code in an empty part
+ of its memory map but only works because the real SNES seems to return the
+ middle byte of the address - $60 in this case, which corresponds to the
+ ReTurn from Subroutine instruction.
+- Added auto-cycle skipping disable for Earth Worm Jim 2 and several other
+ games that spool sample data using H-DMA as the sample is being played.
+ Improves some sound effects in these games.
+- Fixed joy-pad routines to only report up or left if down or right are also
+ pressed respectively. Works around a game bug in Empire Strikes Back in the
+ asteroid stage where the game crashes if both left and right are pressed -
+ something impossible to do on the original SNES game-pad.
+- Added custom SPC700 timing for Rendering Ranger R2 - the game now works with
+ full sound. No idea why it needs custom SPC700 timing.
+- The ROM type detection was broken for Treasure Hunter G and Test Drive 2 -
+ fixed the code so type 2 ROMs can be LoROM.
+- Adjusted the main CPU cycles per scan-line from 341 to 342 to give an exact
+ match for the timing required for Earth Worm Jim 2. All EWJ2 needs now
+ for perfect sound emulation is a method of synchronising the emulation
+ speed to the host hardware's sound card playback rate, oh, and a fast CPU!
+ The Linux port already has this but seems to be broken because games
+ play at double-speed when this option is enabled.
+- Some SPC700 code in Earth Worm Jim 2 seemed to prove that I had guessed the
+ clock speed of the SPC700 sound CPU incorrectly - out by almost a factor of
+ two, in fact. Changed the relative emulated clock speed of SPC700. Now
+ Chrono Trigger doesn't lock up at certain points anymore, the special SPC700
+ timing for games written by the Human Software company isn't required and
+ you can hear some more of the sound samples in Earth Worm Jim 2, etc.
+- H-IRQ triggering code was broken - if a ROM turned on H-IRQ but later turned
+ it off, Snes9x could continued to generate H-IRQs, crashing some games.
+- Added a generic test for Human Entertainment games - they need special
+ sound CPU timing to work. Gets Taekwon-Do working.
+- Disabled offset-per-tile mode for Theme Park; the world map screen is corrupt
+ with it enabled.
+- Yet more changes to the offset-per-tile backgrounds modes 2 and 4. Added
+ 64 tile wide screen support for Mario RPG's mine cart ride and fixed multiple
+ bugs with the handling of horizontal offset-per-tile used in Chrono Trigger's
+ fade in of the space ship.
+- New feature: Snes9x can now load ZSNES freeze state files! Just copy them
+ into the freeze file folder and Snes9x will load them when you load a freeze
+ file, but only if the corresponding native format Snes9x freeze file doesn't
+ exist.
+- Added memory map hack for Batman - Revenge of the Joker: its ROM header block
+ is in the wrong location and Snes9x incorrectly detected its ROM type.
+- Fixed an off-by-one-pixel clip window 2 bug when the window was set to clip
+ outside the window area; clip window 1 was already correct. Removed the bright
+ line bug at the left edge when the combat screen is appearing in Starfox and
+ the clip problem when text boxes zoom-out in Yoshi's Island.
+- Jim Power's title screen seems to prove that the per-tile offset data on
+ mode 2 isn't ignored for the left most tile as I originally thought.
+ Modified the code.
+- The recent timing changes highlighted another problem with Daffy Duck -
+ changed IRQ enable register to only clear pending IRQs if one has been pending
+ for several microseconds.
+- Speeded up the sprite data register handling slightly.
+- Finally got Aero the AcroBat 2 working, after many hours of investigation,
+ spread over several years - literally! Two problems. The SNES doesn't seem
+ to consider scan-line line zero to be part of the v-blank period even though
+ the line is never drawn and V-IRQs at the start of the scan-line have to be
+ delayed until a few microseconds into the line - Traverse: Starlight & Prairie
+ required this as well, so I removed the original, Traverse specific hack.
+ There's a problem with the in-game music that I'll investigate at a later
+ date.
+ - The in-game music problem just required ENVX emulation to be switched on,
+ off by default on the Linux port, on by default on the Windows port.
+- Fixed the mode 7 corruption problem on the title screen of Chase HQ using the
+ same trick as Illusion of Gaia - i.e. mod the mode 7 centre X & Y values with
+ 1024.
+- Fixed another crash bug in the interpolated mode 7 code - a portion of
+ the code was ignoring the screen flip value and the fact that X render
+ direction reversed if the screen was flipped horizontally. Was causing a
+ crash on the whale boss screen of Kirby Superstar.
+- Mortal Kombat 3 now auto-adjusts emulated cycles per scan-line work-around
+ a speech sample being cut short.
+- Added sample data register reading support to the sound DSP - somehow I
+ seem to have missed implementing this. Not sure if any ROM actually reads
+ the value.
+- Followed Sumire Kinoshita's suggestion and stopped clearing the ENDX flags
+ when the value is read, against my better judgement, and it does actually
+ improve speech samples in several games. Ooops! The Mortal Kombat series,
+ Magical Drop 2 and Metal Combat are the ones I've discovered so far.
+- WWF Arcade now auto-adjusts the cycles per scan-line value to work-around
+ a sound sample repeat problem.
+- Hmm. There's something about offset-per-tile mode I don't understand - WWF
+ Wrestlemania Arcade is getting corrupt graphics; not sure what effect the
+ ROM is trying to produce. Disabled offset-per-tile mode for the game for now.
+- Fixed Street Racer player 1 wobble problem during the soccer game by auto-
+ adjusting the cycles per scan-line value slightly.
+- Made Power Rangers Fight auto-adjust emulated cycles per scan-line to work
+ around a slight timing problem that causes an NMI to corrupt register
+ values that an IRQ handler is trying to update. Without it the scrolling
+ back-drop and fighter graphics are corrupt.
+- Illusion of Gaia seems to need the mode 7 centre X & Y values to be mod 1024
+ if the screen repeat flag is set. Fixes the island fly-over bug right at
+ the end of the intro but breaks a few other games. Hmm. Made it auto-switch
+ on for this game only.
+- Added memory map support for Radical Dreamers. Thanks to satellite hut master
+ for the information.
+- Made updates to the top bit of the sprite write address register be ignored
+ unless the low byte had been written to first. A ROM coding bug in
+ James Pond II requires this, otherwise it writes a junk byte value into the
+ main character's X position and Robocod wobbles around all over the place.
+- Reverted back to pre 1.31 way of initialising unknown register values -
+ Rock and Roll Racing was reading a junk register value and using the value
+ to set up DMA, which in turn was causing corruption on the player select
+ screen.
+- Added Star Ocean memory map - thanks zsKnight! The original ROM I was testing
+ was corrupt, no wonder I couldn't figure out the memory map myself! The game
+ still isn't playable, though, due to missing S-DD1 graphics decompression
+ (+ encryption?) emulation.
+- Started to dump some compressed data values from Street Fighter 2 Alpha in
+ the hope that one day someone will be able to crack the S-DD1's compression
+ algorithm.
+1.33a
+- C4 emulation wasn't being automatically enabled for Rockman X2 / X3 - the
+ Japanese versions of Megaman X2 / X3.
+- Fixed the Super FX plot table pointer that I accidentally broke while saving
+ 1Mb of workspace RAM - it was stopping all Super FX games from working.
+1.33
+- Noticed another problem with the CPU_SHUTDOWN code - Chrono Trigger locked
+ up during the intro but only when using the asm code CPU core. Found the
+ algorithm difference between the code and made the CPU match what the C
+ version was doing. Still not sure why it caused a problem in the first place.
+- Changed colour subtraction code to use Lindsey Dubb's newer version he sent
+ me some time ago but I 'forgot' to include. I say forgot, but I really put
+ off including it because, although it improves most games that use the
+ effect, it does result in one or two slight visual glitches.
+- Hacked in zsKnight's C4 emulation asm code - now both Megaman X2 and X3 are
+ playable. Still got to complete the reverse engineering of the i386 asm code
+ to C so other, non-Intel ports can have C4 emulation.
+- Shuffled the keyboard mapping a bit on the Linux port so now Tab key acts as
+ an emulation speed turbo button, `, # and ~ act as superscope turbo and
+ / acts as the superscope pause button.
+- Fixed asm CPU_SHUTDOWN code that I accidentally broke while trying to
+ optimise it! Thanks to all the people who noticed Snes9x's frame skipping
+ had changed between releases. Frames rates should be improved again for more
+ than 50% of games.
+- Re-enabled in-lining of the C SNES memory access routines, improves frame
+ rate by one or two on slower machines.
+- Optimised the asm 65c816 addressing mode emulation code a little.
+- Included some code changes making life easier for the Mac porter, John Stiles.
+- Added memory map support for Sufami Turbo using information supplied by
+ Nose0000. No idea if it works because I don't have the ROM.
+- Spent a few minutes trying to figure out the Star Ocean memory map so at
+ least the sound effects could be heard. But gave up after a couple of hours
+ due to laziness. If anyone knows the memory map details, let me know please!
+1.32a
+- The delay loading of the OpenGL DLLs on the Windows port was causing the
+ OpenGL initialisation code to fail. Reverted back to normal DDL loading but
+ with the side effect that Windows 95 users must visit the Microsoft web site
+ and download the OpenGL add-on before Snes9x will work for them.
+- Corrected the OpenGL bump-map display option - my attempt to get the
+ bi-linear OpenGL display option to work with Voodoo card's limited texture
+ size had broken the bump-map mode.
+1.32
+- Changed the Windows port to delay load the two OpenGL DLLs, so now they're
+ only loaded if you switch to OpenGL mode. The original version of Windows 95
+ didn't include the OpenGL DDLs, so Snes9x wouldn't even start on that
+ platform; now it should.
+- Added yet another sound buffer option to the Windows port - this time the
+ block size of sound data to mix. Some DirectSound sound card drivers only
+ report the play position moving in steps rather than continuous amounts and
+ Snes9x's default mix block size turned out to be smaller than this step
+ value on several cards.
+ Snes9x couldn't work out out where the true play position was accurately
+ enough resulting in broken, noisy sound output.
+- Modified the Windows frame timer code to use semaphores rather than events -
+ they should make Snes9x more reliable at not missing frame sync pulses when
+ Windows is busy doing background tasks.
+- Added SA-1 shutdown code - basically, Snes9x now stops emulating SA-1 CPU
+ instructions when the SA-1 enters an idle loop waiting for the main SNES
+ CPU to give it something to do. All SA-1 run much faster and smoother now.
+- Added multi-axis joystick/game controller support to the Windows port and
+ tweaked the dead-zone threshold position a little.
+- It looks like the SNES PPU was designed to support 128K of V-RAM but only
+ 64K was fitted; Snes9x wasn't wrapping all V-RAM address to stay within the
+ 64K limit causing a corrupt title screen on ReX Ronan - there will be others.
+- Added amend functionality to the Windows Cheat Entry dialog and added extra
+ text boxes for direct address and cheat value input rather than only being
+ able to type in a Game Genie or Pro-Action Reply code.
+- BS Suttehakkun2 was crashing just before start of play - the ROM was
+ performing a junk DMA that was corrupting RAM, crashing the game when it
+ went searching for a particular value.
+- F-1 Grand Prix requires IRQ triggering when IRQ scan-line register set to
+ current scan line, but Chuck Rock objects. Hmm. Chuck Rock seems to indicate
+ the CPU emulation is running too fast, but I can't see where the mistake is.
+ Special-cased Chuck Rock for now.
+- Optimised SNES DMA handling slightly - copying data to SNES V-RAM is now
+ significantly faster.
+- Windows Cheat search dialog was ignoring data type parameter in various
+ places which was causing problems when larger numbers were being searched
+ for.
+- Forced unknown PPU register reads to always return 0 - a coding bug in
+ Equinox shows that this is required. An earlier fix didn't work.
+- Puya Puya 2 & remix were objecting to an NMI being triggered when enabling
+ NMIs after scan-line 226, but Ys 5 seems to require this. Hmm. Added a hack
+ to support both games.
+1.31
+- Snes9x DirectSound code modified - the mixing block size is now always 10ms
+ for Windows 95/98/2000 and 20ms for NT 4.x, now there should be no need to
+ enable Sync Sound when a large sound buffer is required (helps emulation
+ speed). The maximum sound buffer length values have been updated to reflect
+ the smaller mixing block size.
+- Changed the DirectSound code back to use an offset from the play position
+ as the place to write new sample data into the sound buffer - on NT 4.x the
+ write position seems to vary randomly rather than being a fixed distance
+ in front of the play position as documented. Now I know why I used the play
+ position originally!
+- Changed the DirectSound code to fill the sound buffer at the write position
+ supplied by DirectSound, rather than just before the current play position -
+ should help reduce latency.
+- Added an auto-detect method for interleaved mode 2 Super FX ROM images -
+ well, not really auto-detect: if the game crashes and its a Super FX game,
+ Snes9x assumes its in interleaved mode 2, de-mangles the ROM image and tries
+ to run the game again.
+- Had to update the Snes9x Windows registry version number as the additional
+ diagonal settings make old registry settings incompatible.
+- Added diagonal keyboard controls to the Windows port, as requested by
+ several users.
+- Changed PPU code to return zero when reading non-existent registers - the
+ game Equinox relies on this due to an original game coding bug.
+- Included FMOD sound driver support to Windows port - people experiencing
+ broken sound or delayed sound, etc, might want to give it a try.
+- Tales of Phantasia - un-interleaved format ROM memory map changes to match
+ odd ZSNES format, now the hacked ROM works.
+- Changed NMI again. Made reading or writing to PPU register 0x4210
+ clear NMI pending flag again, without this Super Tennis does not work.
+- Changed NMI timing back to be the same as several versions ago and just
+ special cased Cacoma Knight instead - although kept the code to prevent
+ the re-triggering of an NNI more than once in the same frame.
+1.30
+- Forgot to force GUI surface to be displayed when some dialogs where popped
+ up - problem only happened on full-screen mode with triple or double
+ buffering enabled, or when using 3dfx mode. It appeared as if Snes9x had
+ locked up, but pressing Esc would pop down the hidden dialog.
+- Added a couple of options to the Settings dialog. Now its possible to
+ disable S-RAM auto-save which was causing Snes9x to write to the hard disk
+ every 30 seconds on some games, causing the occasional skipped frame.
+- Fixed Reset option which was accidentally broken when Netplay support was
+ added.
+- Added support for Dirt Racer - it leaves the Super FX chip running all the
+ time, so the default CPU emulation method never allocated any time to other
+ CPUs and the emulation seemed to lock up.
+- NMI timing changed again. Now an NMI can only be triggered once per
+ frame and enabling an NMI after the normal trigger scan line triggers
+ an NMI immediately. This fixes display glitches in Ys 5, Stargate and
+ Daffy Duck.
+- Fixed the WAI instruction to only 'wake up' once an actual NMI has
+ triggered, rather than just waking up when it should have triggered.
+ This fixes Battletoads, broken since version 1.29(ish).
+- Changed NMI again. Made reading or writing to PPU register 0x4210 not
+ clear NMI pending flag. Seems to allow all the NMI timing sensitive ROMs
+ I had on my list to now work without any special hacks. Illusion of
+ Gaia now works again.
+- Another NMI fix - cleared the CPU pending NMI flag at start of frame;
+ Battletoads intro was crashing without this. A long DMA was stopping the
+ SNES CPU so it couldn't and shouldn't respond to the NMI signal from the PPU.
+- Fixed Netplay problem when game didn't have any S-RAM and Sync Using Reset
+ was being used. An error dialog was displayed and the client would disconnect
+ from the server.
+1.30b#1
+- The Windows auto-frame skip code was broken - badly. It didn't re-sync a
+ timer value with timer events being generated, causing Snes9x to deliberately
+ stop and wait for an event when it didn't need to, slowing down the overall
+ emulation speed and increasing the number of frames skipped.
+- Improved the Windows cheat search dialog - its now possible to compare
+ against a value and more comparison functions are available.
+- Finally worked out why Voodoo 3 support was so buggy in Snes9x - the Voodoo 3
+ card generates a WM_DISPLAYCHANGE message when switching to Voodoo mode (the
+ Voodoo 1 and 2 cards don't); Snes9x thought that some other application had
+ changed the screen depth or resolution and tried to adjust its window to
+ match - triggering another WM_DISPLAYCHANGE message. No idea how the code
+ worked at all; it must have been only by chance and very dependant on the
+ driver version you were using!
+- Implemented Netplay on the Windows port - but its buggy as hell. I seem to
+ be having major Windows multi-threading problems. Comments I've seen seem to
+ suggest that Windows 95/98 don't implement true multi-threading; hmm...
+- Not happy with the current Netplay, so I scrapped it and tried again;
+ the protocol is much improved and not using select to control game timing
+ seems to have removed lots of the threading-type problems I was having.
+- Attempted to switch to just using Borland's C++ Builder to build the Windows
+ port - and failed, again. Although C++ Builder can build Snes9x from sources,
+ it can't then link in the asm CPU cores. I had hoped Borland might have
+ fixed this with their latest release - they haven't.
+- Several attempts to get Anti Resonance's super-fast sound CPU and sound DSP
+ code working in Snes9x, but all failed. Part of the problem was his code was
+ written using TASM and the object files it generated would only work under
+ Windows - but all my SNES debugging code was in the Linux port. Anti' fixed
+ that, and I then had some success getting his code working, but its just too
+ unstable at the moment for a main-stream release.
+- Included an option to use Anti Resonance's alternate sample decoding routine;
+ it can approximate the wind and noise sound effects heard in several Square
+ Soft games.
+- Thanks to Lindsey Dubb for the mode 7 bi-linear filtering code - it
+ generates a nice smooth image when a game scales the screen using the SNES'
+ mode 7, but you'll a fast machine if you don't want the frame rate to drop.
+- Thanks again to Lindsey Dubb, he improved the colour addition/subtraction
+ subtraction routines - they are just a little slower but now mostly perform
+ full 15-bit precision addition and subtraction rather than the previous
+ 13-bits of precision. Many more colour shades can be seen - look at the
+ improved shading on the Mario Kart or F-Zero track for example.
+- Added a reverse stereo option, for people with sound cards that swap the two
+ channels.
+- Added a sound config dialog to the Windows port - now you can access extra
+ sound options that have always been there, but just no GUI interface to
+ access them.
+- Fixed the 32-bit windowed support on the Windows port.
+- Adjusted the NMI timing by a few microseconds to get Metal Warriors working
+ again.
+- Added a few more sound playback rate choices. Most modern sound cards allow
+ any value to be used from a large range, rather than just a select few, may
+ be I ought to add text field so you could just type a value in?
+- Used Factory Setup 4 to build a new installer package for the Windows port -
+ just shipping a zip file was confusing novice users and many (mostly AOL
+ users) seemed to have an odd program mapped to .zip files, further confusing
+ the issue.
+1.29
+- Disabled the SPC700 noise feature simulation used by Chrono Trigger and
+ Final Fantasy 3 until I work out why its being triggered by sound effects
+ that don't use it.
+- Rewrote/reorganised the DirectX and 3D/fx handling code, now both are never
+ enabled at the same time in Snes9X. It might fix the crashing problems some
+ Window port users are seeing. Changing between DirectX and Voodoo 3D/fx
+ modes now requires Snes9X to be restarted.
+- Tracked down and fixed the Chrono Trigger black screen problem on the Windows
+ port: a rogue asm instruction was left in by mistake after some code edits -
+ it was only by chance that the code worked on the Linux port.
+- Added some SNES debug options to the Windows port, but disabled by default,
+ on the shipped version.
+- Clicking on the column headings in the OpenROM dialog in the Windows port
+ now sorts by that column; plus added some slight screen update optimisations.
+- Added an optimisation to graphics rendering: don't add or subtract
+ sub-screen from background layers, or clear the sub-screen, if SNES fixed
+ colour is black and no background layers are enabled on sub-screen, even if
+ ROM tries to enable translucency effects for every background layer.
+ Discovered Sonic was doing this, there will be others.
+- Forgot to enable auto S-RAM save on Windows port, oops!
+1.28
+- Warning dialog added to the Windows port - if a ROM is loaded from a
+ read-only directory, e.g. a CD, and the freeze file folder is set to be the
+ same as the ROM image folder, then a warning is displayed when the game first
+ starts.
+- The Windows port now supports 5 joy-pads - Snes9x always did support 5 but
+ the Windows port lacked the GUI option to enable and configure it.
+- Added an about dialog to the Windows port.
+- The Windows port now has a simple settings dialog, only one option so far -
+ changing the freeze file and S-RAM save directory; much better than having to
+ use regedit at least.
+- Added a new cheat search dialog, you can use it to find where games are
+ storing life counters, health levels, etc. and then add cheats that stop the
+ values from changing.
+- Added a cheat code entry dialog to the Windows port; now Game Genie,
+ Pro-Action Replay and Gold Finger codes can be graphically entered and
+ edited.
+- Added a master cheat codes on/off toggle, available from the Cheats menu
+ on the Windows port.
+- Extended the number of cheats per game from 10 to 75.
+- Changed cheat code to reapply cheat every emulated frame so if RAM is being
+ patched the cheat value is continuously applied.
+- Wrote some new cheat search code, the code won't be useful until I get around
+ to writing a cheat search dialog.
+- Added automatic cheat code loading and saving using the same file format as
+ ZSNES.
+- Rewrote large parts of the Snes9x cheat handling code ready for adding
+ cheat dialogs to the Windows port.
+1.27
+- Added a flag to only enable SPC700 noise 'feature' when Chrono Trigger or
+ Final Fantasy 3 are loaded - the conditions that I thought were necessary to
+ trigger the feature where sometimes being met by other games.
+- Added a simulation of the SPC700 noise 'feature' where some games, notably
+ Chrono Trigger and Final Fantasy 3, play samples that deliberately overrun
+ outside a 16-bit value, the SPC700 sound DSP then for some reason starts to
+ generate a type of noise sound which the games use to generate wind and
+ swish type sound effects. Thanks to ZSNES for some of the information.
+- Fixed another sound interpolation problem, thanks to Mikael Bouillot -
+ the initial value of the sample byte being played was not being set correctly
+ when processing fractional offsets.
+- Added auto S-RAM save option; S-RAM is automatically written to a .srm file
+ a few seconds (30 by default) after a ROM writes to it - useful for people
+ who were playing games long into to night, only to lose their progress
+ after a power cut or machine crash.
+- NMI delay code changed again - the fix for Cacoma Knight was breaking
+ Tuff E Nuff; it would seem delaying NMI until the start of h-blank to too
+ long, added a cycle counter instead.
+- Fixed yet another clip window bug - clip window was being incorrectly set
+ at no range if colour window was enabled but background layer clip window
+ was disabled (meaning layer should not be clipped).
+ Fixes the sunken ship level on FF5.
+- Worked out (by example) how to add keyboard accelerators to the Windows port,
+ now toggling full screen using ALT+Return works.
+- Added mouse-warp to the Windows port so the the cursor doesn't wonder off the
+ Window while SNES mouse emulation is enabled.
+- Improved 3dfx support on Windows port - load dialog doesn't drop out of
+ bi-linear mode and underlying window zooms to full-screen so its easy to find
+ and click on the menu bar with the mouse.
+- Added Mouse and Superscope SNES emulation support to the Windows port, use
+ '7' on the keyboard to select.
+- Windows cursor now hidden unless super scope emulation is enabled.
+- Windows port now has command line parsing - cheapo way of adding Game Genie,
+ Pro Action Replay cheat codes, disabling sound CPU emulation for the
+ corrupt copy of Star Fox 2, etc. Also allows ROM images to be dropped onto
+ the Snes9x icon.
+- Cacoma Knight seems to provide proof that Snes9x triggers the SNES
+ non-maskable interrupt (NMI) too early. Changed interrupt to trigger at the
+ start of the next horizontal blank period. Will have to watch for it
+ causing problems for other ROMs.
+- Added a translucency hack - when a ROM tries to create a stipple background
+ pattern by enabling pseudo hi-res. and not enabling a background layer on
+ one of the screens, Snes9x changes the effect to use transparency effects
+ instead (the real SNES can't do transparency effects with pseudo hi-res.
+ enabled). Now the water in Kirby 3 is translucent.
+- SA-1 CPU reset bug fixed, now Jumpin' Derby boots and plays but with major
+ graphics problems.
+- Fixed nasty asm SA-1 custom hardware read/write bug that was causing the
+ course map not to be displayed on Augusta Masters and Pebble Beach.
+- Added SA-1 character conversion DMA support for all SNES depths, now
+ Augusta Masters and Pebble Beach work.
+- Merged in minor code changes for Linux running on the Alpha processor. Thanks
+ to Sadruddin Rejeb for the changes.
+- Added four more auto-multi-player-adaptor-emulation-off presets based on
+ code from Mystagogus.
+- Added DirectX3D output image processing support to the Windows port... and
+ removed it again because it causes my desktop machine to lock up. Back to
+ the drawing board...
+1.26
+- Fixed memory leak that crept in when SA-1 support was added when loading a
+ game freeze file.
+- Added SPC dumping option based on code from Cyber Warrior X that he sent me
+ ages ago but I've just found again while looking for something else!
+- Merged in most of the Amiga PPC port source code changes into the main
+ source code tree.
+- Keying on a sound channel seems to clear its last-sound-sample-block-just-
+ played flag. Chaos Engine/Soldiers of Fortune needs this.
+- Add multi-thread support to the UNIX ports for sound playing - required in
+ the Linux port to work around a Sound Blaster Live driver bug and useful if
+ you have multiple CPUs in your machine to help spread the emulation workload.
+1.25
+- Added BS 24Mbit ROM memory map, for Derby Stallion 96 and Sound Novel-TCool.
+ No idea if it works. Thanks to Nose0000 for the info and code.
+- Corrected unzip code not to loop forever if an encrypted zip file is loaded -
+ an error is generated instead.
+- Changed relative SPC700 cycle length for Mortal Kombat 3 to fix sample
+ repeat problems - I wish I knew exactly how fast the SPC700 is clocked.
+ Maybe I should write a test ROM and run it on a real SNES?
+1.24
+- 3dfx speed hack back again, only disabled when Seiken 3 is loaded.
+- Some minor SA-1 speed ups added - the SA-1 instruction skipping code will
+ have to wait until I have more time.
+1.23
+- Corrected a SA-1 reset bug that reset the SA-1 RAM bank pointer back to block
+ zero but didn't clear the RAM bank register. Was causing Kirby 3 to crash.
+- Fixed a wave clipping problem with interpolated sound that was causing noise
+ on sound output when certain sound samples were played.
+- Fixed a bug in the sync-sound code that could overrun the sound buffer by a
+ few bytes causing clicks on the sound output.
+- The sound sample repeat bug that has plagued Snes9x ever since is was called
+ Snes96 finally bit the dust - Snes9x continued to play sample loops
+ even if the game dynamically updated the sample not to loop. Fixes the
+ stutter in the Mortal Kombat series and improves the sound from several games
+ that download sound samples in real-time as they are played.
+- Rewrote the code the handled the SPC700's 64 byte shadow RAM area to fix a
+ possible sample corruption problem with ROMs that stored samples that
+ cross the 64 byte start area.
+- Added code to allow ROMs to change the sample being played the next time the
+ channel loops or is keyed on - not sure if it fixes anything but seems more
+ correct.
+- Added a zero-frequency fix to the stereo sound mixing code that I'd already
+ added to the mono code some time ago.
+- Changed the code to set the end-of-sample flag just before the last block is
+ played, rather than just after. Seems to help improve the sound on some
+ games.
+- Sound sample start code now doesn't reset the channel's envelope volume level
+ to zero before starting the sample - helps reduce the clicks being heard when
+ a channel envelope volume level hadn't reached zero before being keyed on
+ again.
+- Changed initialisation of sample-end-register to 0 rather than 255 - seems
+ more logical now I've thought about it. Not sure if it helps anything.
+1.22
+- Finally fixed the corrupt copy of Donkey Kong Country not working problem -
+ Snes9x thought the ROM used the same memory map as Street Fighter Alpha 2.
+- Added explode, un-shrink and un-reduce decompression modes support to the
+ unzip code.
+- Fixed offset per tile bug that crept in after me trying to fix the Starfox
+ on-tilt bug.
+- Made some fixes to the C Super FX emulation code, enough to get most 'FX
+ games playable on the Mac port.
+1.21
+- Finally worked out how character DMA worked on the SA-1 and implemented a
+ hacky, slow version, but its enough to get the level up screens displaying
+ correctly on Mario RPG.
+- Incorporated ZSNES' new optimised Super FX asm code - had to track down and
+ fix a nasty memory overwrite bug in the code first to get it to work.
+- Changed sample mixing code to not automatically wrap offsets to
+ keep inside the sound buffer, external port code is now expected to do that.
+ Helped me fix a problem in the Windows port that prevented very large sound
+ buffers from working, which are required for some badly written sound card
+ drivers.
+- Corrected a bug in the SA-1 C code where incorrect processor emulation
+ functions where called if the code was compiled with in-lining turned off.
+- Fixed crash bug in Super Mario RPG on the level up screen - forgot to mask
+ the enable bit from the RAM bank register. Thanks to Christian Wolf for
+ sending me a freeze file which made it easy to find the problem.
+- Fixed a lockup bug in the window clipping code, if the ROM ever turned off
+ the sub-screen completely the clipping code would enter an infinite loop.
+ Fixes The Cartoon Addams.
+- Made the Daffy Duck NMI fix only enable when Daffy Duck is loaded - fix was
+ causing problems for Breath Of Fire 1 and 2.
+1.20
+- Windows port no longer sets DirectSound to exclusive mode, so its now
+ possible to hear sound output from Windows apps while Snes9x has focus.
+- Fixed the freeze file loading and saving on the Windows port.
+- More GUI settings are saved in the registry on the Windows port now.
+- Added 3D/FX image scaling/filtering support to the Windows port.
+- Added the TV mode from the Mac/Linux ports to the Windows port.
+- Incorporated Kreed's new output image routines into the Windows port that
+ fixes RGB555 display colour problems. Many thanks to Kreed.
+- New auto-frame rate timing code on the Windows port, stops the silly speed
+ up problems when the old code tried to 'catch up' after the emulator had
+ been paused.
+- Increased the DirectSound secondary buffer length on the Windows port to
+ hopefully fix all the static/broken sound output problems some people were
+ experiencing.
+- Altered the ZSNES Super FX asm code so the Windows port could use it - all
+ previous versions of the Windows port were shipped using the C Super FX
+ emulation code which is a lot slower.
+- Implemented interpolated and sync-sound options on the Windows port.
+- Added an image stretch option to the Windows port - stretches the SNES image
+ to fill the whole screen or the Window. Looks really good on my TNT card
+ since that chips seems to filter the image as it scales it.
+- Implemented Windowed mode on the Windows port.
+- Added special SPC700 cycle timing for Empire Strikes Back.
+- Fixed the missing polygon problem for Super FX games - thanks to zsknight
+ for the information.
+- Implemented SA-1 support required for Mario RPG, Kirby Superstar,
+ Paradius 3, etc. but since only a good image of Mario RPG exists, I could
+ only test that game.
+- Fixed a graphics clip window bug: inverting the area of a clip area that
+ only consisted of empty bands should become the full width of the screen;
+ Mario Kart's rear-view mirror display needs it.
+- Fixed mode 7 render code to use correct z-buffer when rendering onto the
+ sub-screen. Fixes Final Fantasy V title screen.
+- Added horizontal offset per tile support in the offset per tile modes 2
+ and 6, and switchable horizontal/vertical offset in mode 4. Fixes Chrono
+ Trigger in several places and Mario All Stars title screens.
+- Changed SPC700 relative cycle length to 14, needed for Stunt Car Racer.
+- Enabled immediate triggering of NMI if NMI enable flag set while scan-line
+ was on first line of v-blank. Needed to fix a background jitter bug in
+ Daffy Duck: The Marvin Missions.
+- Altered ROM load code to ignore corrupt ROM map type byte in ROM header,
+ preventing the code erroneously detecting what it thinks are interleaved
+ ROMs. Fixes EEK! The cat, Formation Soccer, the corrupt copy of Donkey
+ Kong Country, ...
+- Disabled IRQ re-triggering if V-IRQ registers set to the current line. Fixes
+ Chuck Rock.
+- Fixed missing sprites in Andre Agassi Tennis - writing to low byte only of
+ the sprite write address register seems to also clear the hi-byte.
+1.19
+- Games written by the Japanese software company Human seem to need special
+ SPC700 sound CPU timing, so the ROM load and reset routines now check the
+ software author company and adjust the CPU cycle length accordingly.
+ It gets Clock Tower, Super Fire Pro-wrestling Premium, etc working.
+- Added ROM check sum calculation and testing code - Snes9x can now detect
+ pure, corrupt or hacked ROMs.
+- Noticed a fast way to implement the SNES 4096 colour mode, so I implemented
+ it. Now the colours in ActRaiser 2 look correct.
+- Corrected a noise frequency error thanks to information from Takehiro.
+- Added a 'start in full screen mode' flag to the Linux port.
+- While debugging the new graphics code I thought of a fast way to implement
+ the SNES direct colour mode, tried it out and now the colours in Actraiser 2
+ are correct.
+- Blast, forgot about the colour window and fixed colour effects. The separate
+ sub-screen is back again, but all the other graphics speed ups are there.
+- Now I've got a z-buffer I keep finding other ways to optimise the SNES
+ graphics rendering - no need for a separate sub-screen, no need to clear
+ the sub-screen to the fixed colour, no need to waste CPU time on translucency
+ effects on hidden pixels, no need to completely clear the main-screen to the
+ back drop colour, etc., etc.
+- Implemented a software z-buffer and changed the SNES graphics rendering to
+ use it (required change for future 3D card support). Finally fixes the
+ sprite-to-sprite priority bug that some games suffer from. Also a big speed
+ increasing for some games (10 fps+), others are slight losers.
+- Added code to skip the rendering of completely transparent graphic tiles
+ rather than comparing each pixel to see if it is transparent; helps the
+ frame rate a bit on some games.
+- Added a fixed for Tetris & Dr. Mario - the game didn't like a multi-player 5
+ adaptor plugged in to the real SNES when being played, so turned off the
+ adaptor emulation for this game.
+- Added hack for Final Fantasy II - if sync sound isn't on, make attack rate of
+ 1ms actually 0ms (old v1.16 behaviour). Causes a slight click but its better
+ than samples being cut short.
+- Fixed a clip window area invert bug if the colour window was enabled on
+ on one window and the other window was being used to clip a background layer.
+ Fixes the finial (I hope) display problem with Gun Hazard.
+- Added code to intersect the clip window areas if both a colour window and
+ a background layer clip window were enabled at the same time. Required by
+ Gun Hazard.
+- Forgot to mark graphic clip windows as needing recomputing when the master
+ colour window inside/outside/on/off/main-screen/sub-screen PPU register was
+ updated. Was causing display problems for Gun Hazard.
+- Internal H-DMA execution accelerator pointer variables where not always
+ being recomputed when started H-DMA part way into a frame. Was causing
+ display problems for Gun Hazard.
+- Made H-DMA continue for one extra scan-line to fix a disappearing monster
+ problem in Dragon Quest 5. Thanks to Alex Jackson for the bug report.
+- Zoop seems to require volume envelope height reading by the sound CPU to
+ always return 0 when the channel is in gain mode.
+- The sound code was ignoring updates to the ADSR volume envelope rates while
+ one was in progress. Fixed that and now the bird song at the start of
+ Chrono Trigger sounds correct.
+- Had to disable the CPU shutdown code for loops reading the horizontal beam
+ position, it was causing problems for Star Fox. Still no polygons though.
+- Oops, sound DSP noise output was broken - accidentally deleted an important
+ line while removing debug code ready for the last release.
+- Added initial 3Dfx support to the Linux port - basically using the Voodoo
+ card as a bi-linear filtering, scaling blitter. Actually slightly slower than
+ TV mode, for non-scrolling images due to poor texture upload speeds to the
+ card, but the full-screen feature is nice and the speed doesn't drop as more
+ of the screen changes.
+1.18
+- Implemented a sync-sound mode where sound data gets generated in sync with
+ SPC700 instructions being executed. Finally the sound Williams Arcade
+ classics can be heard. Also helps slight sound timing problems in many other
+ games but doesn't fix Mortal Kombat 2 like I thought it would - its
+ sound routine programmers must have been on drugs or something!
+- Added interpolated sound - gives low frequency sounds much more bass similar
+ to a real SNES especially with the playback rate ramped up to 44KHz.
+- Added on-screen messages as various emulation options are toggled on and off
+ using the in-game keys.
+- Fixed a PPU register read bug with the sprite register write position. Thanks
+ to Takehiro TOMINAGA for the bug report.
+- Altered the auto-frame skip timing code to only wait and re-sync to the end
+ of frame when frames haven't been skipped. Again thanks to Takehiro.
+- Speeded up the colour addition and subtraction code using ideas from
+ Takehiro.
+1.17
+- Linux and UNIX sound code now driven directly from signal timer handler
+ rather than the timer handler just setting a flag which had to be polled in
+ the main emulation code. Slightly faster execution.
+- Fixed the crash bug in the ZSNES Super FX asm code with Vortex - the game's
+ polygons still aren't visible though.
+- Implemented bent-line increase and exponential decay and sustain volume
+ envelopes - they should match, or at least be very similar to the real SNES
+ sound DSP chip now.
+- It would seem ROMs can key on sound channels even if the channel hasn't
+ been keyed-off, Pac-In-Time requires it. Changed code to allow it.
+- Quick mod to ZSNES Super FX code to get Winter Gold working - it was already
+ working with the C Super FX code.
+- Added emulation of the extra 1/2 scan-line per frame on PAL and NTSC -
+ should help improve music speed emulation.
+- Worked around the click sound heard when ROMs use 0 volume envelope attack
+ rate.
+- Removed the 'check for IRQ already happened' H-IRQ position register setting
+ code - it was causing problems for Ninja Warriors and was not required by
+ F1 Grand Prix.
+- Fixed a bug in the new sound code - the sustain part of the
+ attack-decay-sustain-release volume envelope was being skipped if the
+ sustain level wasn't at 100%. The fix has helped some music notes from
+ being cut off early in a few games.
+- Added fix to Pro Action Reply support (again). Thanks to Paul Shoener III for
+ the original fix and Gil Pedersen for reminding me to apply it!
+- Finally fixed the Tales of Phantasia 'bum note' problem! The ROM set its
+ sample directory to the upper-most page and I forget to code for the hidden
+ 64 bytes of RAM, that appear when the boot ROM is switched off, when fetching
+ sample addresses.
+- Adjusted the relative cycle length between the 65c816 and the SPC700 slightly
+ to get Terranigma working again.
+- Oops, the emulated joypads 3 and 4 via the emulated Multi-player 5 interface
+ weren't working. Thanks to Steffen Schwenke for the bug report.
+- Optimised the echo sound code - by-passed the the FIR filter code if only
+ a pass-through FIR filter was defined by the ROM.
+- Modified V and H-IRQ register changing code to trigger an IRQ immediately if
+ V-IRQ is enabled and the scan-lines match and either H-IRQ is not enabled or
+ the electron beam position has already gone past the trigger point. Fixes
+ the screen flicker in F1 Grand Prix.
+- Modified the priority-per-pixel mode 7 code to use BG#1's clipping data if
+ the top bit of the mode 7 pixel is set. Fixes initial track drive-through
+ display in F1 Grand Prix.
+- Modified the sprite priority levels for the priority-per-pixel mode 7
+ display. Now the car can be seen in F1 Grand Prix.
+- Wrote a sound DSP register recording scheme which 'plays back' the register
+ changes in sync with the sound generation code. I'm bit disappointed, it
+ only improves the sound in a very few games... Scrapped the code, it actually
+ causes more problems than it fixes. Oh, well, another 3 weeks work wasted...
+- Fixed a SPC700 wake up problem for Lufia I - made the SPC700 also wake up
+ when the 65c816 read from one of the four comm ports.
+- Included lots of sound code speed ups and sound quality improvements
+ from Takehiro TOMINAGA - many thanks go to him.
+1.16
+- Fixed a case where the -forcelorom option didn't work - the case was
+ required for Formation Soccer which claims in its ROM header to use the
+ same memory map as Super FX ROM, it doesn't.
+- Pulled apart a real SNES using a crowbar (great fun), just to look at what
+ speed the SPC700 is actually clocked at for more accurate relative emulation
+ speed.
+- Implemented SPC700 cycle counting in the hope the improved timing would fix
+ Tales'; no such luck but at least the -ratio option is obsolete now.
+- Implemented executing SPC700 instructions during DMA, fixes BSZelda and
+ Goal lock up at start and music pausing briefly when ROMs do lots of DMA,
+ usually between game screens.
+- Scrapped the i386 asm SPC700 code - it was the cause of the music not
+ restarting after a battle in Chrono Trigger and FF3 and I didn't realise
+ because the bug had already occurred in the test freeze-file I had.
+ Thanks to John Stiles for pointing out that the Mac port didn't have the
+ missing music problem.
+- Fixed RGB subtraction bug on displays with only 5 bits for green, e.g. RGB555
+ displays. The GREEN_HI_BIT variable was always set to a value for 6 bit
+ green displays.
+- Added the SA-1 memory map, still a long way to go before any SA-1 game will
+ run.
+1.15
+- Jumped versions to keep in sync with the DOS port release.
+1.14
+- Improved 8-bit sound generation slightly, but it still sounds very poor
+ compared to 16-bit sound.
+1.13
+- Implemented the Tales of Phantasia memory map using the information supplied
+ by zsKnight. Had to also implement a de-interleave routine to work around
+ a ROM feature and Snes9x CPU instruction fetching implementation detail.
+- Added a frames-per-second on-screen display option.
+- Fixed the final glitch bug with the Mario Kart track display - the byte code
+ for the termination of the DSP1 raster command wasn't been recognised.
+- Disabled a NMI/DMA hack for Rise of the Robots, was causing problems for
+ Mario Kart and 'Robots wasn't working correctly anyway.
+- Optimised the mode 7 rendering a little.
+- Changed tile rendering code to use offsets into screen buffer rather than
+ direct pointers ready for z-buffer implementation.
+1.12
+- Changed V-blank NMI to occur immediately after a WAI instruction, Toy Story
+ required this.
+- Fixed reading of H-DMA line counter register, Top Gear 3000 needed this.
+- Ripped off large parts of ZSNES's DSP1 code (with _Demo_'s and zsKnight's
+ approval). Now Mario Kart works almost 100%.
+- Added a check to see if a vertical scan-line IRQ register change will cause
+ a H-IRQ later on the current scan-line. Pilot Wings needed this.
+- Fixed possible crash bug in clip window code when both windows had two
+ spans. Could actually cause Chrono Trigger to crash the emulator.
+- Fixed a lock-up problem with the C Super FX code, Star Fox and executing
+ a few 'FX instructions per scan-line (required for Winter Gold).
+1.11
+- Partially fixed the DOS netplay server - the server timer is running too
+ slowly and it doesn't deal with disconnects correctly yet.
+- Corrected the sound echo delay - it was varying with the sound playback
+ rate chosen by the user - it shouldn't have been.
+- Implemented DOS netplay code - DOS server code still not working though.
+- Removed all floating point calculations from the sound generation code.
+- Fiddled with the pitch modulation code - my guess is the output of a
+ channel that is used to modulate the frequency of another channel is
+ automatically muted by the SPC700 chip. Just a guess, but the wind from
+ FF3 sounds 'better' but far from perfect.
+- Optimised the tile palette index calculation.
+- Optimised the planar to chunky tile conversion code.
+- Fixed X11 port to always scale SNES image if hi-res. only (no interpolation)
+ support is enabled.
+- Added zipped ROM image support using Gilles Vollant unzip code and
+ some code that Ivar (Lestat) sent me a long time ago.
+- 65c816 asm RTI instruction was destroying the program bank in emulation mode,
+ the C code was already correct. Caused C64E to break.
+1.10
+- Finished NetPlay v1 - allows up to five networked machines to play
+ multi-player SNES games, one player on each machine.
+- Switchable full-screen mode added to Linux X11 port, some code and ideas
+ nicked from Maciej Babinski's original Snes9x XFree86 DGA Linux port, the
+ UAE Amiga emulator, plus lots of my own code.
+1.08
+- Bug fixes to C Super FX emulation - now Winter Gold works correctly again.
+1.07
+- More DSP1 work. Mario Kart is now playable! The character projection code
+ is still broken so the opponents and obstacles aren't always positioned
+ correctly on screen and you keep bumping into them, but I can still keep
+ coming first!
+- Started work on NetPlay support.
+- Decreased sound card DMA buffer size on DOS port to improve sound generation
+ and sound CPU synchronisation in some games.
+- Included Linux joystick driver patches from Vojtech Pavlik so the port can
+ use the new v1.x joystick drivers, again written by Vojtech Pavlik. Allows
+ use of Micro$oft Sidewinder pads, NES and SNES pads, PlayStation pads,
+ Gamepad Pros, etc.
+- Added halve-the-result colour subtraction.
+1.06
+- Extended code to allow support for multiple 16-bit screen formats,
+ switchable at run-time, rather just supporting one, selectable at compile
+ time.
+- Added XFree86 DGA Linux port - code from Maciej Babinski.
+- More fixes to the X11 image format conversion and setup code.
+- The asm SetByte routine wasn't wrapping writes to S-RAM correctly, allowing
+ some ROMs to think they were running on a copier and put up an error
+ screen. Thanks to Nu of #rom for the report.
+- Added 'TV-Mode' support (interpolation and scan-lines) to the DOS and
+ UNIX ports from code based on John Stiles work.
+- Added v-sync option to the DOS port.
+- Added fix to Pro Action Reply support, thanks to Paul Shoener III.
+- Added ggi support (untested) to Linux port using patches from
+ Alexander Larsson (alla@lysator.liu.se).
+- Added 16 to 24/32 bit image conversion routines to the UNIX X11 code.
+- The SPC700 OR1 instruction was broken. Thanks to Pyrgopolinices for the
+ report.
+- DOS port was having trouble splitting and joining path names - caused
+ problems when specifying the full path name of a ROM when the ROM image
+ was on another drive.
+- If a ROM reset the sound DSP and then turned on echo effects but kept
+ the same echo delay setting, then the echo effects could not be heard.
+ Thanks to madec@mclink.it for the bug report and freeze file that made it
+ easy to find the problem.
+- DOS port was always using stereo sound setting, if sound card
+ supported it, regardless of the user preference.
+- Linux port X11 port could crash if window was resized while transparency
+ effects were enabled.
+- The colour subtraction accelerator look-up table was slightly wrong, causing
+ one bit of red, green blue values to 'spill' into the next field.
+- Allowed colour window to cut a hole in the main-screen and show the sub-
+ screen underneath. The effect is used by Illusion of Gaia.
+- Added support for colour subtraction, with the halve-the-result flag
+ set.
+- Included DSP1 code from _Demo_. Now you can see the track in Mario Kart and
+ the ground in Pilot Wings - still can't play the games though due to other
+ missing commands.
+- Added an NMI hack to work around a code bug in Battle Toads: BATTLEMANIACS,
+ its only by chance that the game works on a real SNES - And disabled it
+ again because it causes problems for Chrono Trigger.
+- A frame skip of zero was actually still skipping one frame. Thanks to
+ Marius Fodor for the info.
+- And yet more X-OR window bug fixes - now the effects during some of the more
+ 'posh' spells look correct in Chrono Trigger.
+- Yet another window area inversion bug - off by one pixel on right-hand edge.
+- Forgot to put dummy start and end points for XOR window combination modes -
+ now Uniracers looks correct and Sailor Moon looks like it does on a real
+ SNES.
+- Window clip code was using wrong index into a 2-dimensional array when
+ the whole of the main or sub-screens were clipped.
+1.05
+- The master volume disable code was looking that the wrong variable!
+- Fixed crash bug in newer sound code if a ROM tried to start a sample
+ playing who's data went past the end of SPC700 memory. (Cannon Fodder)
+1.04
+- Fixed DSP1 ROM header detection bug.
+- More DSP1 work; still nothing works, although I know the multiply command
+ is correct because I've compared the results against a real DSP1.
+1.03
+- Oops, the multi-player 5 disable code change broke the multi-player 5 being
+ the default controller.
+- Implemented the colour window on the main screen - now Zelda's oval zoom
+ window displays correctly and Krusty's Super Fun House clips the left-most
+ 8 pixels as it does on the real SNES.
+- TERRANIGMA didn't like me returning a random value when it attempted to
+ read a channel's the current sample byte.
+- Hacked in initial support for mode 7 priority-per-pixel - the priority bit
+ doesn't actually change the priority of the pixel but the two games that I
+ know of that use the feature look OK. (Winter Extreme Skiing and the
+ intro of Tiny Toons Adventures).
+- Colour addition/subtraction code now uses RGB565 rather than RGB555
+ calculations - helps a little with the loss of the bottom bit of SNES
+ colour data.
+- DSP1 emulation started - nothing works yet.
+1.02
+- Switched to adding back drop colour rather than fixed colour when
+ sub-screen addition is enabled but there's nothing on the sub-screen.
+ Uniracers seems to need it. - DISABLED it again. Causes problems for
+ other ROMs and Uniracers itself on later screens.
+- Fixed XOR window logic combination mode and area inversion code, now
+ Uniracers works correctly.
+- Oops, if colour window and half colour addition/subtraction were both
+ switched on, area outside colour window was still being halved, it shouldn't.
+ Hacky fix at the moment until I implement the correct fix.
+- Fixed several bugs with the mosaic effect and 16x16 tiles and a few
+ possible background scroll offset bugs and the mosaic effect.
+- Optimised the sound sample generation code for cases when the SNES
+ sample playback frequency was higher than the sound card playback rate.
+- Fixed possible click sound when a sample was first started to be played.
+1.01
+- Corrected scan-line count for PAL games - should be 312 lines verses 262 for
+ NTSC. Was causing slow music on PAL games.
+- Added error correction code to the SPC700 timer update code - the
+ SPC700 timers are updated using the emulated h-blank handler which is
+ called every emulated 63.6 microseconds (15.720KHz) but the SPC700 timers
+ need to be updated at multiples of 8KHz, hence the error. Was causing
+ music to be played slightly too fast.
+- Switched back to using C SPC700 code - the old SPC700 asm code was lacking
+ several optimisations that the C version had. It also had multiple
+ speed hack cycle skipping bugs. Plus I hadn't even finished optimising
+ all the code from the last time I converted the C compiler output.
+- Optimised SPC700 memory access routines a little.
+- Disabled code that prevented ROMs updating SPC700 timer values while the
+ timer was running - it seems like it is allowed, even though docs on the
+ 'net I've seen say its not.
+1.0
+- Fixed SuperScope support.
+- Added hi-res. option to my DOS port.
+- Fixed 4, 6, and 8 button standard PC joystick support.
+- Changed some types the source code was using BYTE -> uint8, WORD -> uint16,
+ DWORD -> uint32 and BOOL -> bool8, types were clashing Windows typedefs
+ but sizes didn't always match.
+0.99
+- 8-bit double height and/or width tile rendering was missing every other
+ group of 4 pixels - screen pointer advance count was wrong.
+- Asm SPC700 emulation was ignoring the Shutdown flag - the result is its
+ not possible to turn off cycle skipping for the SPC700 emulation.
+0.98
+- CPU to ROM address decoding code rewritten - used by Game Genie cheat codes,
+ orginal code might have been the cause of some Game Genie codes not working.
+- Started to remove printf calls and replace them with calls to S9xMessage,
+ port code can then dicide what to do with message.
+0.97
+- Re-enabled decompressed sample caching, still has a possible click problem
+ but the sound code is a lot faster with it enabled. Added command line option
+ to disable it if required.
+- Added '7' key support to rotate through available controller options, in
+ the order multi-player5, mouse on #1, mouse on #2, superscope,
+ standard controller and then back to multi-player5.
+- Hi-res. (512x448) support fixed.
+- Mouse support completed - Lemmings 2 and Mario Paint working a treat.
+- More colour window fixes.
+- Fixed freeze game problem when ZSNES SuperFX code is being used -
+ ZSNES 'FX state was not being saved and restored.
+- ZSNES SuperFX asm emulation code plugged in to Snes9x.
+0.96
+- Looks like if the colour window is not enabled at all and the colour
+ window selector is defined to only allow colour effects inside the colour
+ window, then no effects should be visible.
+- Offset-per-tile rendering code didn't support width 64 screen size, which
+ Chrono Trigger used on its title screen.
+- Contra 3 seems to prove that defining the clip window area to be 'outside'
+ a window that covers the whole screen is not an area with no range.
+ - No it doesn't. It proves that I shouldn't have initialised the right
+ window edges to 255! Contra 3 enables clipping windows without first
+ defining their range.
+- Debug frame advance feature was being prevented from forcing the next
+ frame to be rendered by SyncSpeed which was being called after the
+ debugger returned to the main loop.
+- H-DMA code was allowing ROMs to manually start H-DMA during the v-blank
+ period, ROMs shouldn't be allowed to do this.
+- Asm code would not push the correct CPU status onto the emulated stack if
+ returning from an NMI immediately triggered an IRQ - fixes Mortal Kombat 1
+ and War of the Gems.
+- 'd' dump memory debug command was not preserving the CYCLES count.
+- C versions of SNES memory access code had same problem as asm code on the DOS
+ port except it didn't cause a crash just ROMs failed to work correctly.
+- Asm i386 code was using signed compares to check for special case memory
+ areas - it was causing crash problems on the DOS port which was sometimes
+ returning valid address values with the top bit set - i.e. they seemed
+ like negative values!
+- Changed event reschedule code to always allow h-blank start events, used to
+ disable them during v-blank period.
+- Added code to HDMA when end of visible lines reached.
+- Changed register 4212 code not to always return h-blank when in v-blank.
+- Clipping fixed colour addition to background area was off by one pixel on
+ the right-hand edge.
+- HDMA: Finally worked out how the real SNES operates when ROMs manual
+ start H-DMA during the frame - ROMs must set up the H-DMA line count
+ and address values before H-DMA is started.
+- Fixed the asm code to remove all hard-wired structure offsets - one offset
+ into the IPPU structure was wrong in the code because the structure had
+ changed size.
+- Added colour window support and allowed graphic window settings to be
+ different on the main screen and sub screen, just like a real SNES.
+- SuperFX LJMP instruction had bank and address values swapped.
+- Fixed possible memory overwrite problem because OBJList array was one
+ element too short.
+- Added AND multi-graphic window combo support.
+- ROM image memory allocation allocates an extra 32K of RAM, then moves the
+ pointer forward by that amount - stops the SuperFX emulation from accessing
+ unallocated memory, possibly causing a crash.
+- SuperFX emulation now stores sign and zero flags in separate variables so
+ the MERGE instruction can set flags correctly.
+- Added 65c816 instruction skipping to i386 asm code when 65c816 waiting in
+ a simple loop for some 'event' to happen e.g. end of frame NMI.
+- Finally fixed the APU instruction skipping problem with the i386 asm
+ code when the WAI instruction is used - caused slow music on some ROMs.
+- Offset-per-tile modes don't seem to support screen size - Mario All Stars
+ Super Mario 2 requires this on title screen. Doesn't seem to effect
+ Tetris Attack or Puzzle Bobble.
+- Changed SNES select and start keys from shift and control to space and
+ enter - allows shift-fn key to save game positions without the SNES ROM
+ also getting a select joypad button press.
+- Multiplayer5 support for controllers 3+ was broken for ROMs that used
+ automatic hardware joypad reading rather than reading joypads serially.
+- ResetPPU was not clearing tile caches and marking OBJ as need recomputing.
+- Cached OBJ positions and sizes were not being recomputed if ROM changed
+ global OBJ sizes during frame.
+- Fixed brightness multiplication problem on 16-bit code for green.
+- SPC700 emulation now uses one variable to store ZERO and NEGATIVE flags.
+- SPC700 emulation now only increments PC once at end of instruction.
+- New ROM type and interleaved detection code.
+- Reading sound DSP register ENDX also clears the value. The docs on the
+ 'net said that only writing to the register cleared its value. Fixes
+ sound in Zoop.
+- Fixed mode 4 colour palette problem on background #2 in tile-based graphics
+ code.
+- Fixed graphics mode 4, offset-per-tile support. Only one set of offset data
+ that is switchable between horizontal and vertical, unlike modes 2 and 6
+ which allow separate horizontal and vertical offsets per tile.
+- Modified the APU timer code again, if the timer is enabled, a write to the
+ timer target register is only allowed if a value hasn't been written yet.
+ Fixed Donkey Kong Country 1 and Earth Worm Jim 1 & 2.
+- Attack rate of 0ms changed from 1ms back to 0ms because of a group of ROMs
+ that change from attack mode to decay mode in real-time. Will change back
+ when I've added better SPC700 CPU and sound generation sync code.
+- Added support for ROMs set a new sound timer value while the timer is
+ enabled (EWJ 1 & 2).
+- Added support for ROMs that read the sound envelope height (MK1, MK2, etc).
+- ROMs writing to the H-DMA enable register during visible scan-lines were
+ restarting H-DMA for that frame causing random screen effect corruption.
+- Echo feedback seems to be after the FIR filter, not before as a diagram I've
+ seen suggests.
+- Sound pitch modulation added.
+- Memory access routines changed to pass a single 24-bit address rather than
+ the previous separate 8-bit bank and 16-bit address parameters.
+0.3
+- Updates to A-Bus address during a frame must not update H-DMA address.
+ Fixes Actraiser 2 and Pacman 2.
+- Removed sound volume mangling - with echo support enabled it doesn't seem to
+ be required.
+- Attack rate of 0ms changed to 1ms to help prevent click sound with sudden
+ start of a sample playing.
+- Sample caching of samples that looped using part of the original sample
+ created a click on the sound output. Caching disabled for the moment. Would
+ require 512K of cache RAM to fix sample caching.
+- Colour addition/subtraction support added - but still a little buggy in
+ places and very slow.
+- 16-bit colour support added.
+- Sustain sound volume was not being set if a sample using ADSR was started
+ with both the attack rate and decay rate set to zero - resulted in missing
+ sound samples on with some games.
+- Sound echo support added.
+- Sound channel mixing code was not completely clearing a channel's sound
+ buffer when a channel finished playing a sample.
+- Sound mixing code rewritten to use one buffer, rather than writing each
+ channel into a separate buffer then combining them into one buffer.
+- Memory access routines rewritten to use an 8K block lookup table rather than
+ dedicated code for each ROM memory map - it was getting difficult to support
+ the new types of SNES ROM memory maps becoming apparent.
+- Sound sample decoding wasn't decoding sound samples correctly if a
+ previously cached sample was only partially overwritten by the ROM as
+ opposed to being completely replaced.
+- Sound sample decoding wasn't clipping generated sample values correctly.
+- Changed H-DMA to start in the current frame only if enable register is
+ written to during v-blank, h-blank or while the screen is blanked.
+- The SPC700 seems to start executing instructions before the 65c816 -
+ shorter reset pulse? (NO - forgot the SPC700 executes instructions while DMA
+ is taking place).
+- ROMs that reset the H-IRQ position so another IRQ would be triggered on the
+ same scan-line where not supported - Super Off-Road: The Baj needs it.
+- $4212 bit 7 needs to go high at the end of h-blank at line 224 not at the
+ start of h-blank - Bubsy needs it.
+- Sample decoding routine could write to memory outside sample cache area if
+ address of block to decode was greater than $0x10000 - 9.
+- Walking mario can be seen on map screen of MarioWorld - needed sprite
+ priority rotation working. ROM sets bit 7 of $2103 then sets rotation in
+ $2102. Reset rotation at start of v-blank not at end.
+0.24
+- Fixed reading of DMA register values - now Ms Pacman works.
+- Saved sprite memory address being restored on the wrong scan-line - caused
+ corrupt sprites on at least one game (GANBARE GOEMON 2).
+- Screen colour palette not being updated if ROM only wrote to low byte of
+ palette register.
+- Possible memory corruption fixed if a ROM tried to write to an invalid
+ sprite address via PPU registers.
+- X11 port support quick load and save by pressing function keys to load or
+ shift + function keys to save.
+0.23
+- Added option to disable graphic window effects - T2: The Arcade Game doesn't
+ seem to like them.
+- Mode 7 "outside screen area" register interpretation fixed - now the
+ Actraiser map screen looks a lot better.
+- Old DMA code hack for Battle Toads: Double Dragon removed as it was no
+ longer required and it was causing problems for Ys III.
+- Lowered max volume level of 16-bit sound mixing code to help with sound
+ clipping problems is lots of SNES sound channels are playing.
+0.22
+- Crash bug fixed in mode 7 graphics windows code
+0.21
+- Fixed a noise channel volume bug - noise waveform was getting clipped.
+- Fixed 24bit X Window System server support on the Solaris port.
+- Sprites in priority level 1 on mode 7 were being drawn incorrectly behind
+ graphics screen.
+- BG 3 priority 1 tiles sometimes not drawn dependent on the $2105 bit 3
+ setting.
+- Added graphic window support the tile redraw code.
+- Added mosaic support to tile redraw code.
+- Tile redraw code was drawing one line too many on screen-splits.
+- Tile-based redraw code made more intelligent about when a background should
+ be displayed or not.
+- Added wrap within bank support to large DMAs just to support Rock 'n' Roll
+ racing.
+0.20
+- DMA routines added lots of special cases and removed most calls to GetByte,
+ using a pointer instead.
+- Multiple using PPU registers is now only computed when first byte of result
+ is actually read.
+- Sound enabled by default if compiled without DEBUGGER defined.
+- Tile redraw method made the default.
+- Fixed CPU_SHUTDOWN so SPC700 continues to execute even if main CPU is
+ "skipping" cycles waiting for an event to happen.
+- More command line options added.
+- Default cycles-per-scan-line to execute lowered to 90% from 100%.
+- +/- keys now work even if auto-frame rate adjust was enabled.
+- SPC700 emulation partially rewritten in assembler.
+- Asm 65c816 code change to use same speed up techniques as the C++ code.
+- Minor speed tweaks to the sound decoding and mixing code.
+- C++ SPC700 emulation changed to use same method as 65c816 emulation for
+ computing and storing emulated CPU flags.
+- Mode 7 code rewritten and several scrolling offset bugs fixed.
+- Lo-ROM S-RAM memory map bug fixed - now Uniracers works.
+- Multiple speed ups and changes to the tile and line-based redraw code.
+- Tile and line redraw code changed to cache converted tiles between frames.
+- Variable cycle length timing made compile-tile switchable.
+- C++ 65c816 emulation changed to use several opcode jump tables to avoid
+ a register size comparison test on most emulated instructions.
+- C++ 65c816 emulation changed how is computes and stores emulated CPU flags.
+- Fixed high frequency sound playback bug - the sample rate calculation was
+ blowing the range of an unsigned long.
+- Fixed V-RAM reading so DKC3, Addams Family, Aladdin and Pacman all work.
+- Fixed sound code so ROMs can change from ADSR mode to decrease mode - fixes
+ lots of ROMs.
+0.12 released
+- Added dynamic speed regulation.
+- TCALL vector calculation change from n to 15 - n.
+- Fixed crash bug if ROM writes to sound DSP register numbers greater than
+ 127.
+- Fixed DOS memory locked for interrupt code.
+- Added long name versions of command line switches.
+- Added command line switch for SPC700_SHUTDOWN code and WAI cycle skipping
+ code.
+0.1 released
+- All DOS memory is now locked from being swapped.
+- Fixed DOS port keyboard polling code - could get confused if a keyboard
+ interrupt happened while keys were being checked.
+- SPC700 ADC instruction never cleared Overflow or Carry flags!
+- Changed selection of playback speeds for Solaris port.
+- Sample caching code was broken - cached samples were never used.
+- Added code speed ups for ROMs that use a lot of DMA to VRAM.
+- More cpu code asm speed up.
+- Fixed 16x16 size tiles on tile-based redraw code.
+- Fixed sound gain-mode increase and decrease volume envelopes.
+- Added code to support ROMs that reuse sprites in the same frame.
+- Fixed processing of negative volume levels.
+- Fixed SPC700 EOR1 instruction.
+- Added SPC700 shutdown code to stop executing SPC700 instructions if in
+ a tight loop waiting for a timer or for the 65C816 to respond.
+- DOS playback rate was being forced to 16KHz by Allegro - fixed.
+- Fixed bug in SPC700 MOV1 C,bit, address.
+- Fixed a off-by-one loop sample pointer bug in MixSamples.
+- Added command line flags for cached-tile based drawing and sub-screen
+ background layers priority swapping.
+- NOPE, got encoding of the OR1/EOR1,AND1 range of correct originally -
+ got duff information from an "SPC700" programmer.
+- More SPC700 fixes: got the encoding of the OR1/EOR1,AND1 range of
+ instructions wrong - I guessed wrong originally.
+- Sample looping bug fix on mono sound mixing code.
+- Sound pitch value no-longer clipped to 14 bits - apparently FF3 needs this.
+- Followed Paradox's suggestion and changed graphics code to place sub-screen
+ background layers below main-screen background layers. Helps lots of games
+ that use sub-screen addition/subtraction - now you don't have to toggle
+ background layers on and off so often just to see hidden text, characters,
+ or maps, etc. Made it switchable.
+ Acts as a good intermediate solution until sub-screen addition/subtraction
+ is actually implemented.
+- Modified sound skipper code to return random values when ROM is stuck
+ waiting for the SPC700 CPU to respond - helps several ROMs that previously
+ don't work with the currently selection of APU skippers.
+- Improved sound mixing code so volume is not attenuated so much, giving
+ better results on 8bit sound cards.
+- Changed the frequency at which the joystick polling routine is called - now
+ called every-other frame rather than every 3rd frame.
+- Recompiled Linux and DOS ports with the Pentium optimising version of gcc -
+ gives a few percent speed increase.
+- Changed V-RAM increment count from 64 to 128 - apparently Final Fantasy 3
+ needs this as well.
+- Fixed sprite priority bug with Mode 7 - apparently Final Fantasy 3 needs
+ this.
+- Fixed a screen clipping problem with the S-VGA mode.
+- Fixed bug that had crept in with -m 2 S-VGA mode (Linux version).
+- Fixed S-VGA Linux version with sound enabled.
+- The SPC700 ADC (X),(Y) instruction was broken - with all these SPC700 fixes
+ now many more ROMs work with sound enabled.
+- The SPC700 Pop PSW instruction was not resetting the direct page location.
+- The SPC700 instruction MOV A,[DP+X] was incorrectly doing a MOV A,DP+X.
+- Got the SPC700 SETx and CLRx instruction encoding swapped around.
+- Fixed #define problem that was stopping DOS snapshot saving from working.
+0.72 released
+- Fixed the DOS filename handling - old Unix code was screwing up with ROM
+ filenames that contained backslashes (\) - the ROM would load but S-RAM
+ loading and saving would fail and the default filename for snapshots
+ wouldn't work.
+- This time really fixed Allegro library keyboard handling (DOS port); it
+ was missing key some presses/releases (was stopping Chrono Trigger
+ Left + Right + A button combo from working).
+- Added code to automatically remove headers off S-RAM save files with
+ 512 byte headers.
+- 32Mbit ROMs in interleaved format are now automatically detected and
+ converted.
+- Added -ss 3 sound skip method support to the asm version - now NBA Live '96
+ works again.
+- Added support for multi-part ROM images.
+0.71 released
+- Made libgz.so statically linked (again) on Linux port - sorry.
+- Made writing to $4200 also clear any pending IRQs. This finally allows
+ Battle Toads: Double Dragon, Spawn and Sieken 3 all the work with the same
+ IRQ logic (but Sieken 3 still gets stuck in sound download code).
+- Fixed a H-DMA wobble bug - some frames could randomly miss a line of
+ H-DMA causing the F-Zero screen to wobble, and slight text character
+ corruption on games like DKC3.
+- Interleaved format ROM images are now swapped in-place, without the need
+ for a temp 4Mb buffer (saves lots of disk swapping on a 16Mb Windows 95
+ machine).
+0.7 released
+- Fixed Allegro library keyboard handling (DOS port); it was missing key
+ some presses/releases.
+- DOS port had a different MAX_PATH value which moved the location of the
+ SRAM size variable when using the asm CPU emulation core. This, in turn,
+ caused the SRAM emulation to fail on the DOS port. Donkey Kong County 2 & 3
+ were reporting a ROM copier was connected to the SNES and refused to run.
+- Fixed assembler version of XCE - it was always leaving the carry flag
+ clear - caused Killer Instinct and Super Punchout to think a ROM
+ copier was fitted to the SNES and they all refused to run.
+- Fixed assembler versions of MVN/MVP - they weren't setting the data bank
+ register to the destination bank of the instruction.
+- Fixed joystick detection on MS-DOS port - a single 2 or 4 button joystick in
+ port 1 was being ignored if a second joystick was not present in port 2.
+- Fixed an uninitialised variable in graphics code - was causing random
+ missing scan lines on Mode 7 screens.
+- Joysticks now scanned every 3rd frame (joystick scanning is slow in the PC).
+- Double-whoops, Metriod 3 had stopped working in v0.6 - fixed it
+ (memory map bug).
+- Made bit 6 of $4211 set if v-counter == v-timer-position.
+- Made reading of $4200 read $4212 instead.
+- Adjusted DMA timing to always access ROM memory at slow speed - this seems
+ to fix Battle Toads.
+- Added code to automatically clear pending IRQs when the horizontal line
+ is no longer equal to the horizontal timer line - this fixes Seiken 3, it
+ now just gets stuck in the sound CPU wait code - oh well.
+- Moved NMI back to its original pre-0.65 behaviour, now Puzzle Bobble works.
+- More graphics speed ups - the code to render background tiles with their
+ priority bits set is only called if there are actual priority-bit tiles.
+- Changed default frame skip rate from 1 to 2 - its seems most people don't
+ bother to read the docs, so I thought I'll help them out a bit!
+- Speeded up Mode 7 graphics on games like F-Zero that rewrite the matrix
+ registers on each scan line using H-DMA.
+- Reorganised the graphics code and did a slight speed up - graphics code
+ will be the next thing to rewrite in assembler.
+- Rewrote CPU core in assembler for Intel platforms - gives a very noticeable
+ speed increase.
+- Fixed several problems with the APU sound CPU emulation - its now getting
+ stable enough to try and implement sound.
+- Fixed bug that caused 1 byte of S-RAM to be emulated when ROM didn't
+ expect any - it was enough to stop Street Fighter 2 and others from
+ working - thanks Lord ESNES.
+- The TXS and TCS instructions shouldn't set the Z and N flags.
+- Looks like MVP/MVN instructions should ignore accumulator size - change
+ code to always use all 16 bits and exit with accumulator set to 0xffff.
+- Whoops, accidently left some test code in which was causing the V-BLANK
+ flag, bit 8 in register $4212, to be miss-calculated.
+- Fixed palette in mode 0.
+- Speeded up graphics drawing a little by skipping groups of 4 pixels that
+ were all transparent.
+0.65 released
+- S-VGA and MS-DOS ports now have a VGA mode command line flag.
+- Improved the fading code - should be much more smooth now.
+- Fixed second joy-pad support and re-mapped keys and joysticks to actually
+ make a match between what my docs said and a real SNES (SNES docs I'd
+ seen were wrong!).
+- Fixed a bug in Relative Long CPU addressing mode.
+- Ported Snes96 to MS-DOS.
+- Snapshot loading and saving no longer uses external gzip binary.
+- Added support for registers at $21c2 and $21c3.
+- Made reading the software latch for the horizontal and vertical counters also
+ clear any pending IRQ.
+- Added sprite priority rotation.
+- Rewrote parts of the graphics routines to fix a sprite-to-sprite priority
+ bug.
+- NMI flag changed again - now back to being reset by reading $4210 but
+ actual NMI is delayed.
+- Made mode 7 background colour 0 transparent - this fixed several sprite
+ priority problems a few games where having.
+- Finally worked out how sprite "Object Name Select" works and emulated it -
+ this fixes many (if not all) of the corrupted sprites some games
+ experienced.
+- Delayed NMI activation for one instruction to give time for loops that
+ wait for bit 7 of $4210 to go high.
+- Special-cased line count of 128 on H-DMA to mean repeat previous data with
+ a line count of 128 and not just terminate H-DMA on that channel.
+- APU sound CPU emulation added - just need to debug the thing.
+- Fixed Overflow flag setting in ADC and SBC instructions - it was never
+ being set.
+- Rewrote how CPU instructions are fetched and how values are pushed and pulled
+ from the stack - it gave a very large increase in emulation speed.
+- H-DMA was being started one scan-line too late.
+- Added CG-RAM reading support.
+- Added "Full Graphic" V-RAM reading.
+- Speeded up C version of CPU emulation quite a bit - could speed it up a
+ little more before rewriting in assembler.
+- Fixed bugs in 16x16 tile drawing on 2bit and 8bit deep screens.
+0.6 released
+- Speeded up 16x16 tile background rendering by removing a temp tile buffer
+ it was using. The speed up also fixed a vertical scroll bug.
+- Fixed slight window clipping on 16x16 tile backgrounds.
+- Added automatic PAL/NTSC mode switching.
+- Fixed background and sprites so only visible if on main-screen or
+ on sub-screen under correct circumstance.
+- Fixed lockup bug in DMA.
+- Stopped NMI flag from being reset by reading $4210 - was causing a couple
+ of games to get stuck.
+- Whoops, got horizontal and vertical Mode 7 flip bits around the wrong way!
+- Fixed MIT shared memory pixmap support for X11 version (it was always turned
+ off).
+- Fixed minor bug - first sprite in priority group was drawn twice. Didn't
+ cause any visual bugs, it just slowed down redrawing a little.
+- Fixed DMA bug - transfer byte count should be 0 after DMA has finished.
+- Fixed a scaling bug if width < height.
+- Interleaved ROM image support added.
+- 16bit and 24bit X11 server support added - with scaling.
+- Added window scaling on X11 version.
+- Partial clip windows added - the only window overlap option implemented at
+ the moment is OR, it seems it good enough for all the ROMs I've tested
+ it with.
+- Partial Mosaic effect added (pixels only growing vertically).
+- Missing Mode 7 "outside screen area" option added.
+- Fixed mode 7 screen wrap "outside screen area" option.
+- Used new event processing to finally fix H-IRQ so it triggers at the
+ correct position on the scan line.
+- New event processing added.
+- Linux version now statically links libgz.so (sorry).
+0.5 released
+- Linux S-VGA version changed from using a 320x240 ModeX screen (slow) to a
+ 256x256 chunky screen (faster) - thanks to Phillip Ezolt (pe28+@andrew.cmu.edu)
+ for information on how to do this.
+- Mode 7 screen flipping added.
+- Included Snes97's CPU emulation code into Snes96. Didn't fix any bugs but
+ slowed down the emulation some what and I couldn't compile it optimised
+ because it was so large - so I removed it again.
+- Added a few extra features available via the keyboard.
+- Fixed a H-DMA transfer mode - bad documentation.
+- Fixed H-DMA indirect addressing (it was using the wrong CPU memory bank).
+- The Linux slow down bug is my crappy laptop enabling battery saving features !
+- Changed graphics code to perform true line-by-line screen updates.
+- Fixed sprite drawing bugs.
+- Ported Snes97's graphics code to Snes96.
+- Fixed memory map for HiROM save RAM area.
+- Fixed HiROM memory map - now Killer Instinct and Donkey Kong County work !
+- OK the slow down bug is just actually my laptop trying to save battery
+ power by slowing the CPU clock!
+- The Linux slow down bug shows itself on DOS emulators running under DOSEMU
+ so it must be a kernel problem (or feature).
+- Fixed H-DMA (again) to be complete emulation - all I need now is line-by-line
+ screen update...
+- Fixed DMA to not copy too many bytes if byte count was not a multiple of
+ the transfer mode quantity (caused corruption on Super Mario World map screen).
+- Changed mapping of keyboard to joy-pad buttons and added additional
+ direction keys for joy-pad one so player one's right hand doesn't have to
+ obscure player two's keyboard joy-pad buttons.
+- Changed joystick button layout to match SNES if using a 6 button joy-pad.
+- Changed snapshot format so I can easily use libgz on Linux.
+- Added few speed up tweaks that will be lost again when I add line-by-line
+ screen update.
+- First visible scan-line changed from 8 to 1 to match with new docs.
+- New SNES information source found; fixed partial H-DMA emulation to include
+ indirect addressing support.
+- Snapshot files are now compressed.
+- Compressed ROM images now supported on Linux.
+- Snapshot loading and saving added.
+- Joystick support for Linux added. One 2, 4 or 6 button joystick, or two 2
+ button joysticks supported (PC hardware limitation).
+- SVGA full screen support added for Linux. Still has the X11 slow down bug so
+ can't blame the X11 server any more! Must be a kernel bug or a very odd
+ emulator bug.
+- Added emulation of two joy-pads on the PC/Sun keyboard.
+- Removed -i command line flag as it is no longer used. -h value range has also
+ changed: now 1 - 100 (percentage).
+- Actuate cycle counting rather than instruction counting now added including
+ fast and slow ROM timing - should give much better timing information when
+ line-by-line screen update added.
+- Bug fixed old-style joy-pad access used by some ROMs - Mario All Stars still
+ gives problems if enabled and I don't know why; but at least Super Bomberman
+ now works !
+- Looks like if both horizontal and vertical IRQ are enabled then IRQ should
+ only be triggered once per frame and not once per scan line - looking at the
+ IRQ handler of a couple of ROMs seems to confirm this.
+- Added initial cycle counting - not accurate enough for some ROMs though.
+- Finally worked out how the odd VRAM address increments should work but only
+ found one ROM, so far, that actually uses it.
+- Debugged the odd slow down problem with the Linux port - it seems to be a
+ bug in the X Window System server - starve the X server of keyboard presses
+ or mouse clicks or movement and the X server slows down, slowing down the
+ emulator with it !
+0.4 released
+- Fixed sprite vertical clipping at top of screen.
+- No need to invert the Mode 7 transformation matrix before use - the
+ ROM coder already had to!
+- Fixed Mode 7 scrolling offset when using special effects.
+- Added Mode 7 rotation, enlargement and reduction emulation.
+- DMA shouldn't zero the byte count value after a DMA has completed.
+- Added DMA reading (Addams Family was using it)
+- Fixed V-RAM read function - returned data should lag behind the V-RAM
+ address by one byte/word.
+- Added mode 7 graphics only.
+0.3 released
+- Speeded up the main CPU loop a bit.
+- Add more command line options:
+ -f <frame skip> (default 1)
+ -i <no instructions between polling X> (default 32768)
+ -h <number instructions per scan line> (default 45, some games allow a lower
+ setting resulting in a increased
+ emulated frame rate)
+ -t enable CPU tracing
+ -ss <sound CPU skip wait method> (default 0, more methods to be added)
+ -H disable H-DMA emulation
+ -F Force Hi-ROM memory map
+- Modified planar to chunky conversion to use look up tables.
+- But now Mario All Stars won't start. Made emulation of $4016 optional with
+ -o command line switch.
+- Thanks to Carlos (calb) of ESNES fame, I've added correct $4016 & $4017
+ joy-pad register processing - now several more ROMs will start once a
+ button is pressed and can be controlled.
+- DMA wasn't updating DMA registers with the final CPU address used after the
+ DMA had completed (caused sprite and background corruption with some ROMs).
+ Still suspect another DMA side effect isn't being emulated correctly though.
+- Fixed setting of CPU overflow flag in ADC and SBC instructions in decimal
+ mode.
+- Fixed MVP/MVN CPU instructions to leave X and Y values correct at end of
+ loop - several more ROMs now work. Still don't know if MVP/MVN instructions
+ should ignore the accumulator size flag or not.
+- Rewrote background drawing code - gives a large increase in speed.
+- Flag to only update X Windows colour palette when necessary was missing a
+ case - caused some ROMs to start with a black screen.
+- Code to only update background tiles when changed wasn't working so I
+ disabled it.
+- CPU WAI instruction needed to trigger on hardware IRQ even when interrupt
+ enable flag was false.
+- DMA was not transferring 65536 bytes when byte count was 0.
+- Fixed matrix 16bit x 8bit multiplication (old debug code was causing junk
+ value to be returned).
+- Fixed Makefile so version.h header file change recompiles file that shows
+ version number in window title.
+- Added more reporting of used but unimplemented missing hardware features to
+ debug command.
+- New ROM loading code from Jerremy included, can now cope with ROM images
+ with no 512 byte header.
+- Speeded up emulated memory access a little bit.
+0.2 released
+- Added matrix 16bit x 8bit multiplication for Super Off-Road Racer.
+- Added initial H-DMA emulation - visual effects using it will not be seen
+ correctly until screen is updated line-by-line rather than the whole screen
+ at end-of-frame.
+- Fixed horizontal sprite clipping (vertical clipping still has a problem).
+- Integrated large sprite bug fixes and new background drawing code from
+ Jerremy.
+- Fixed large size per-sprite flag; always stayed true after sprite size was
+ changed to large.
+- Rewrote the planar to chunky pixel conversion routines (still need more
+ work).
+- Made registers $4016 & $4017 always return $ff - lots of ROMs that previously
+ wouldn't go beyond the title screen thought old-style joy-pads were
+ connected and were waiting for the user to press a button on them.
+- Frame skip rate now set to 1 instead of 5 on my P166 laptop!
+- Fixed NMI v-blank flag being incorrect set, caused some ROMs to lock.
+- X keyboard autorepeat now switched off when emulator has keyboard focus.
+- Added number key options to toggle backgrounds 1 to 4 and objs (sprites) on
+ and off.
+- Fixed sprite clipping problems at edge of left hand side of screen.
+- Corrected Hi-ROM memory map (I think) (no I didn't)
+- Fixed most of the sprite-to-sprite priority problems.
+- Added sprite debug command, 'S'.
+- Added a debug command to show what missing hardware features a ROM was using.
+- Added horizontal and vertical beam position IRQ - horizontal always triggers
+ at start of line at the moment.
+- Fixed SBC instruction to set carry flag the correct way around.
+Initial release 0.1
+- Ported Windows 95 version of Snes96 to Linux on a PC and Solaris on a
+ SparcStation.
+- Corrected work RAM memory map.
diff --git a/source/cheats.cpp b/source/cheats.cpp
new file mode 100644
index 0000000..922e08d
--- /dev/null
+++ b/source/cheats.cpp
@@ -0,0 +1,440 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "snes9x.h"
+#include "cheats.h"
+#include "memmap.h"
+
+static bool8 S9xAllHex (const char *code, int len)
+{
+ for (int i = 0; i < len; i++)
+ if ((code [i] < '0' || code [i] > '9') &&
+ (code [i] < 'a' || code [i] > 'f') &&
+ (code [i] < 'A' || code [i] > 'F'))
+ return (FALSE);
+
+ return (TRUE);
+}
+
+const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte)
+{
+ uint32 data = 0;
+ if (strlen (code) != 8 || !S9xAllHex (code, 8) ||
+ sscanf (code, "%x", &data) != 1)
+ return ("Invalid Pro Action Replay code - should be 8 hex digits in length.");
+
+ address = data >> 8;
+ byte = (uint8) data;
+ return (NULL);
+}
+
+const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
+ uint8 &num_bytes, uint8 bytes[3])
+{
+ char tmp [15];
+ if (strlen (code) != 14)
+ return ("Invalid Gold Finger code should be 14 hex digits in length.");
+
+ strncpy (tmp, code, 5);
+ tmp [5] = 0;
+ if (sscanf (tmp, "%x", &address) != 1)
+ return ("Invalid Gold Finger code.");
+
+ int i;
+ for (i = 0; i < 3; i++)
+ {
+ strncpy (tmp, code + 5 + i * 2, 2);
+ tmp [2] = 0;
+ int byte;
+ if (sscanf (tmp, "%x", &byte) != 1)
+ break;
+ bytes [i] = (uint8) byte;
+ }
+ num_bytes = i;
+ sram = code [13] == '1';
+ return (NULL);
+}
+
+const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte)
+{
+ char new_code [12];
+
+ if (strlen (code) != 9 || *(code + 4) != '-' || !S9xAllHex (code, 4) ||
+ !S9xAllHex (code + 5, 4))
+ return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'.");
+
+ strcpy (new_code, "0x");
+ strncpy (new_code + 2, code, 4);
+ strcpy (new_code + 6, code + 5);
+
+ static char *real_hex = "0123456789ABCDEF";
+ static char *genie_hex = "DF4709156BC8A23E";
+
+ for (int i = 2; i < 10; i++)
+ {
+ if (islower (new_code [i]))
+ new_code [i] = toupper (new_code [i]);
+ int j;
+ for (j = 0; j < 16; j++)
+ {
+ if (new_code [i] == genie_hex [j])
+ {
+ new_code [i] = real_hex [j];
+ break;
+ }
+ }
+ if (j == 16)
+ return ("Invalid hex-character in Game Genie(tm) code");
+ }
+ uint32 data = 0;
+ sscanf (new_code, "%x", &data);
+ byte = (uint8)(data >> 24);
+ address = data & 0xffffff;
+ address = ((address & 0x003c00) << 10) +
+ ((address & 0x00003c) << 14) +
+ ((address & 0xf00000) >> 8) +
+ ((address & 0x000003) << 10) +
+ ((address & 0x00c000) >> 6) +
+ ((address & 0x0f0000) >> 12) +
+ ((address & 0x0003c0) >> 6);
+
+ return (NULL);
+}
+
+void S9xStartCheatSearch (SCheatData *d)
+{
+ memmove (d->CWRAM, d->RAM, 0x20000);
+ memmove (d->CSRAM, d->SRAM, 0x10000);
+ memmove (d->CIRAM, &d->FillRAM [0x3000], 0x2000);
+ memset ((char *) d->WRAM_BITS, 0xff, 0x20000 >> 3);
+ memset ((char *) d->SRAM_BITS, 0xff, 0x10000 >> 3);
+ memset ((char *) d->IRAM_BITS, 0xff, 0x2000 >> 3);
+}
+
+#define BIT_CLEAR(a,v) \
+(a)[(v) >> 5] &= ~(1 << ((v) & 31))
+
+#define BIT_SET(a,v) \
+(a)[(v) >> 5] |= 1 << ((v) & 31)
+
+#define TEST_BIT(a,v) \
+((a)[(v) >> 5] & (1 << ((v) & 31)))
+
+#define _C(c,a,b) \
+((c) == S9X_LESS_THAN ? (a) < (b) : \
+ (c) == S9X_GREATER_THAN ? (a) > (b) : \
+ (c) == S9X_LESS_THAN_OR_EQUAL ? (a) <= (b) : \
+ (c) == S9X_GREATER_THAN_OR_EQUAL ? (a) >= (b) : \
+ (c) == S9X_EQUAL ? (a) == (b) : \
+ (a) != (b))
+
+#define _D(s,m,o) \
+((s) == S9X_8_BITS ? (uint8) (*((m) + (o))) : \
+ (s) == S9X_16_BITS ? ((uint16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
+ (s) == S9X_24_BITS ? ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16))) : \
+((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
+
+#define _DS(s,m,o) \
+((s) == S9X_8_BITS ? ((int8) *((m) + (o))) : \
+ (s) == S9X_16_BITS ? ((int16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
+ (s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \
+ ((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
+
+void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp,
+ S9xCheatDataSize size, bool8 is_signed, bool8 update)
+{
+ int l;
+
+ switch (size)
+ {
+ case S9X_8_BITS: l = 0; break;
+ case S9X_16_BITS: l = 1; break;
+ case S9X_24_BITS: l = 2; break;
+ default:
+ case S9X_32_BITS: l = 3; break;
+ }
+
+ int i;
+ if (is_signed)
+ {
+ for (i = 0; i < 0x20000 - l; i++)
+ {
+ if (TEST_BIT (d->WRAM_BITS, i) &&
+ _C(cmp, _DS(size, d->RAM, i), _DS(size, d->CWRAM, i)))
+ {
+ if (update)
+ d->CWRAM [i] = d->RAM [i];
+ }
+ else
+ BIT_CLEAR (d->WRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x10000 - l; i++)
+ {
+ if (TEST_BIT (d->SRAM_BITS, i) &&
+ _C(cmp, _DS(size, d->SRAM, i), _DS(size, d->CSRAM, i)))
+ {
+ if (update)
+ d->CSRAM [i] = d->SRAM [i];
+ }
+ else
+ BIT_CLEAR (d->SRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x2000 - l; i++)
+ {
+ if (TEST_BIT (d->IRAM_BITS, i) &&
+ _C(cmp, _DS(size, d->FillRAM + 0x3000, i), _DS(size, d->CIRAM, i)))
+ {
+ if (update)
+ d->CIRAM [i] = d->FillRAM [i + 0x3000];
+ }
+ else
+ BIT_CLEAR (d->IRAM_BITS, i);
+ }
+ }
+ else
+ {
+ for (i = 0; i < 0x20000 - l; i++)
+ {
+ if (TEST_BIT (d->WRAM_BITS, i) &&
+ _C(cmp, _D(size, d->RAM, i), _D(size, d->CWRAM, i)))
+ {
+ if (update)
+ d->CWRAM [i] = d->RAM [i];
+ }
+ else
+ BIT_CLEAR (d->WRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x10000 - l; i++)
+ {
+ if (TEST_BIT (d->SRAM_BITS, i) &&
+ _C(cmp, _D(size, d->SRAM, i), _D(size, d->CSRAM, i)))
+ {
+ if (update)
+ d->CSRAM [i] = d->SRAM [i];
+ }
+ else
+ BIT_CLEAR (d->SRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x2000 - l; i++)
+ {
+ if (TEST_BIT (d->IRAM_BITS, i) &&
+ _C(cmp, _D(size, d->FillRAM + 0x3000, i), _D(size, d->CIRAM, i)))
+ {
+ if (update)
+ d->CIRAM [i] = d->FillRAM [i + 0x3000];
+ }
+ else
+ BIT_CLEAR (d->IRAM_BITS, i);
+ }
+ }
+}
+
+void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp,
+ S9xCheatDataSize size, uint32 value,
+ bool8 is_signed, bool8 update)
+{
+ int l;
+
+ switch (size)
+ {
+ case S9X_8_BITS: l = 0; break;
+ case S9X_16_BITS: l = 1; break;
+ case S9X_24_BITS: l = 2; break;
+ default:
+ case S9X_32_BITS: l = 3; break;
+ }
+
+ int i;
+
+ if (is_signed)
+ {
+ for (i = 0; i < 0x20000 - l; i++)
+ {
+ if (TEST_BIT (d->WRAM_BITS, i) &&
+ _C(cmp, _DS(size, d->RAM, i), (int32) value))
+ {
+ if (update)
+ d->CWRAM [i] = d->RAM [i];
+ }
+ else
+ BIT_CLEAR (d->WRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x10000 - l; i++)
+ {
+ if (TEST_BIT (d->SRAM_BITS, i) &&
+ _C(cmp, _DS(size, d->SRAM, i), (int32) value))
+ {
+ if (update)
+ d->CSRAM [i] = d->SRAM [i];
+ }
+ else
+ BIT_CLEAR (d->SRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x2000 - l; i++)
+ {
+ if (TEST_BIT (d->IRAM_BITS, i) &&
+ _C(cmp, _DS(size, d->FillRAM + 0x3000, i), (int32) value))
+ {
+ if (update)
+ d->CIRAM [i] = d->FillRAM [i + 0x3000];
+ }
+ else
+ BIT_CLEAR (d->IRAM_BITS, i);
+ }
+ }
+ else
+ {
+ for (i = 0; i < 0x20000 - l; i++)
+ {
+ if (TEST_BIT (d->WRAM_BITS, i) &&
+ _C(cmp, _D(size, d->RAM, i), value))
+ {
+ if (update)
+ d->CWRAM [i] = d->RAM [i];
+ }
+ else
+ BIT_CLEAR (d->WRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x10000 - l; i++)
+ {
+ if (TEST_BIT (d->SRAM_BITS, i) &&
+ _C(cmp, _D(size, d->SRAM, i), value))
+ {
+ if (update)
+ d->CSRAM [i] = d->SRAM [i];
+ }
+ else
+ BIT_CLEAR (d->SRAM_BITS, i);
+ }
+
+ for (i = 0; i < 0x2000 - l; i++)
+ {
+ if (TEST_BIT (d->IRAM_BITS, i) &&
+ _C(cmp, _D(size, d->FillRAM + 0x3000, i), value))
+ {
+ if (update)
+ d->CIRAM [i] = d->FillRAM [i + 0x3000];
+ }
+ else
+ BIT_CLEAR (d->IRAM_BITS, i);
+ }
+ }
+}
+
+void S9xOutputCheatSearchResults (SCheatData *d)
+{
+ int i;
+ for (i = 0; i < 0x20000; i++)
+ {
+ if (TEST_BIT (d->WRAM_BITS, i))
+ printf ("WRAM: %05x: %02x\n", i, d->RAM [i]);
+ }
+
+ for (i = 0; i < 0x10000; i++)
+ {
+ if (TEST_BIT (d->SRAM_BITS, i))
+ printf ("SRAM: %04x: %02x\n", i, d->SRAM [i]);
+ }
+
+ for (i = 0; i < 0x2000; i++)
+ {
+ if (TEST_BIT (d->IRAM_BITS, i))
+ printf ("IRAM: %05x: %02x\n", i, d->FillRAM [i + 0x3000]);
+ }
+}
+
diff --git a/source/cheats.h b/source/cheats.h
new file mode 100644
index 0000000..c8bd716
--- /dev/null
+++ b/source/cheats.h
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _CHEATS_H_
+#define _CHEATS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_SFCCHEAT_NAME 24
+#define MAX_CHEATS_T 200
+
+struct SCheat
+{
+ uint32 address;
+ uint8 byte;
+ uint8 saved_byte;
+ bool8 enabled;
+ bool8 saved;
+ uint8 total_part;
+ uint8 part_id;
+ uint8 part_len;
+ uint8 cheat_type;
+ uint32 name_id;
+ char name[MAX_SFCCHEAT_NAME];
+};
+
+
+struct SCheatData
+{
+ struct SCheat c [MAX_CHEATS_T];
+ uint32 num_cheats;
+ uint8 CWRAM [0x20000];
+ uint8 CSRAM [0x10000];
+ uint8 CIRAM [0x2000];
+ uint8 *RAM;
+ uint8 *FillRAM;
+ uint8 *SRAM;
+ uint32 WRAM_BITS [0x20000 >> 3];
+ uint32 SRAM_BITS [0x10000 >> 3];
+ uint32 IRAM_BITS [0x2000 >> 3];
+};
+
+typedef enum
+{
+ S9X_LESS_THAN, S9X_GREATER_THAN, S9X_LESS_THAN_OR_EQUAL,
+ S9X_GREATER_THAN_OR_EQUAL, S9X_EQUAL, S9X_NOT_EQUAL
+} S9xCheatComparisonType;
+
+typedef enum
+{
+ S9X_8_BITS, S9X_16_BITS, S9X_24_BITS, S9X_32_BITS
+} S9xCheatDataSize;
+
+void S9xInitCheatData ();
+
+const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte);
+const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte);
+const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
+ uint8 &num_bytes, uint8 bytes[3]);
+void S9xApplyCheats ();
+void S9xApplyCheat (uint32 which1);
+void S9xRemoveCheats ();
+void S9xRemoveCheat (uint32 which1);
+void S9xEnableCheat (uint32 which1);
+void S9xDisableCheat (uint32 which1);
+void S9xDisableAllCheat(void);
+void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address,
+ uint8 byte);
+void S9xDeleteCheats ();
+void S9xDeleteCheat (uint32 which1);
+bool8 S9xLoadCheatFile (const char *filename);
+bool8 S9xSaveCheatFile (const char *filename);
+
+void S9xStartCheatSearch (SCheatData *);
+void S9xSearchForChange (SCheatData *, S9xCheatComparisonType cmp,
+ S9xCheatDataSize size, bool8 is_signed, bool8 update);
+void S9xSearchForValue (SCheatData *, S9xCheatComparisonType cmp,
+ S9xCheatDataSize size, uint32 value,
+ bool8 is_signed, bool8 update);
+void S9xOutputCheatSearchResults (SCheatData *);
+
+
+int S9xAddCheat_ex (unsigned int address, unsigned char* cheat_dat, unsigned int cheat_dat_len,
+ unsigned int cheat_cell_num, unsigned int part_id, unsigned int str_num);
+void S9xAddCheat_ov(unsigned int cheat_cell_num, unsigned int total_part);
+unsigned int S9xGetCheat_nameid(unsigned int start, unsigned int part);
+void S9xCheat_switch(unsigned int start, unsigned int sub_part, unsigned int enable);
+void S9xApplyCheats_ex(void);
+void S9xCheat_Disable(void);
+void S9xCheat_Enable(void);
+
+void S9x_dumpcheat(unsigned int id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/source/cheats2.cpp b/source/cheats2.cpp
new file mode 100644
index 0000000..346a9b1
--- /dev/null
+++ b/source/cheats2.cpp
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "snes9x.h"
+#include "cheats.h"
+#include "memmap.h"
+
+extern SCheatData Cheat;
+
+void S9xInitCheatData ()
+{
+ Cheat.RAM = Memory.RAM;
+ Cheat.SRAM = ::SRAM;
+ Cheat.FillRAM = Memory.FillRAM;
+}
+
+void S9xAddCheat (bool8 enable, bool8 save_current_value,
+ uint32 address, uint8 byte)
+{
+ if (Cheat.num_cheats < sizeof (Cheat.c) / sizeof (Cheat. c [0]))
+ {
+ Cheat.c [Cheat.num_cheats].address = address;
+ Cheat.c [Cheat.num_cheats].byte = byte;
+ Cheat.c [Cheat.num_cheats].enabled = TRUE;
+ if (save_current_value)
+ {
+ Cheat.c [Cheat.num_cheats].saved_byte = S9xGetByte (address);
+ Cheat.c [Cheat.num_cheats].saved = TRUE;
+ }
+ Cheat.num_cheats++;
+ }
+}
+
+void S9xDeleteCheat (uint32 which1)
+{
+ if (which1 < Cheat.num_cheats)
+ {
+ if (Cheat.c [which1].enabled)
+ S9xRemoveCheat (which1);
+
+ memmove (&Cheat.c [which1], &Cheat.c [which1 + 1],
+ sizeof (Cheat.c [0]) * (Cheat.num_cheats - which1 - 1));
+ Cheat.num_cheats--; //MK: This used to set it to 0??
+ }
+}
+
+void S9xDeleteCheats ()
+{
+ S9xRemoveCheats ();
+ Cheat.num_cheats = 0;
+}
+
+void S9xEnableCheat (uint32 which1)
+{
+ if (which1 < Cheat.num_cheats && !Cheat.c [which1].enabled)
+ {
+ Cheat.c [which1].enabled = TRUE;
+ S9xApplyCheat (which1);
+ }
+}
+
+void S9xDisableCheat (uint32 which1)
+{
+ if (which1 < Cheat.num_cheats && Cheat.c [which1].enabled)
+ {
+ S9xRemoveCheat (which1);
+ Cheat.c [which1].enabled = FALSE;
+ }
+}
+
+void S9xRemoveCheat (uint32 which1)
+{
+ if (Cheat.c [which1].saved)
+ {
+ uint32 address = Cheat.c [which1].address;
+
+ int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK;
+ uint8 *ptr = Memory.Map [block];
+
+ if (ptr >= (uint8 *) CMemory::MAP_LAST)
+ *(ptr + (address & 0xffff)) = Cheat.c [which1].saved_byte;
+ else
+ S9xSetByte (Cheat.c [which1].saved_byte, address);
+ }
+}
+
+void S9xApplyCheat (uint32 which1)
+{
+ uint32 address = Cheat.c [which1].address;
+
+ if (!Cheat.c [which1].saved)
+ Cheat.c [which1].saved_byte = S9xGetByte (address);
+
+ int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK;
+ uint8 *ptr = Memory.Map [block];
+
+ if (ptr >= (uint8 *) CMemory::MAP_LAST)
+ *(ptr + (address & 0xffff)) = Cheat.c [which1].byte;
+ else
+ S9xSetByte (Cheat.c [which1].byte, address);
+ Cheat.c [which1].saved = TRUE;
+}
+
+void S9xApplyCheats ()
+{
+ if (Settings.ApplyCheats)
+ {
+ for (uint32 i = 0; i < Cheat.num_cheats; i++)
+ if (Cheat.c [i].enabled)
+ S9xApplyCheat (i);
+ }
+}
+
+void S9xRemoveCheats ()
+{
+ for (uint32 i = 0; i < Cheat.num_cheats; i++)
+ if (Cheat.c [i].enabled)
+ S9xRemoveCheat (i);
+}
+
+bool8 S9xLoadCheatFile (const char *filename)
+{
+ Cheat.num_cheats = 0;
+
+ FILE *fs = fopen (filename, "rb");
+ uint8 data [28];
+
+ if (!fs)
+ return (FALSE);
+
+ while (fread ((void *) data, 1, 28, fs) == 28)
+ {
+ Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0;
+ Cheat.c [Cheat.num_cheats].byte = data [1];
+ Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | (data [4] << 16);
+ Cheat.c [Cheat.num_cheats].saved_byte = data [5];
+ Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0;
+ memmove (Cheat.c [Cheat.num_cheats].name, &data [8], 20);
+ Cheat.c [Cheat.num_cheats++].name [20] = 0;
+ }
+ fclose (fs);
+
+ return (TRUE);
+}
+
+bool8 S9xSaveCheatFile (const char *filename)
+{
+ if (Cheat.num_cheats == 0)
+ {
+ (void) remove (filename);
+ return (TRUE);
+ }
+
+ FILE *fs = fopen (filename, "wb");
+ uint8 data [28];
+
+ if (!fs)
+ return (FALSE);
+
+ uint32 i;
+ for (i = 0; i < Cheat.num_cheats; i++)
+ {
+ memset (data, 0, 28);
+ if (i == 0)
+ {
+ data [6] = 254;
+ data [7] = 252;
+ }
+ if (!Cheat.c [i].enabled)
+ data [0] |= 4;
+
+ if (Cheat.c [i].saved)
+ data [0] |= 8;
+
+ data [1] = Cheat.c [i].byte;
+ data [2] = (uint8) Cheat.c [i].address;
+ data [3] = (uint8) (Cheat.c [i].address >> 8);
+ data [4] = (uint8) (Cheat.c [i].address >> 16);
+ data [5] = Cheat.c [i].saved_byte;
+
+ memmove (&data [8], Cheat.c [i].name, 19);
+ if (fwrite (data, 28, 1, fs) != 1)
+ {
+ fclose (fs);
+ return (FALSE);
+ }
+ }
+
+ fclose (fs);
+ return (TRUE);
+}
+
+
diff --git a/source/clip.cpp b/source/clip.cpp
new file mode 100644
index 0000000..57204ac
--- /dev/null
+++ b/source/clip.cpp
@@ -0,0 +1,763 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <stdlib.h>
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "ppu.h"
+
+struct Band
+{
+ uint32 Left;
+ uint32 Right;
+};
+
+#undef MIN
+#undef MAX
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#define MAX(A,B) ((A) > (B) ? (A) : (B))
+#define BAND_EMPTY(B) (B.Left >= B.Right)
+#define BANDS_INTERSECT(A,B) ((A.Left >= B.Left && A.Left < B.Right) || \
+ (B.Left >= A.Left && B.Left < A.Right))
+#define OR_BANDS(R,A,B) {\
+ R.Left = MIN(A.Left, B.Left); \
+ R.Right = MAX(A.Right, B.Right);}
+
+#define AND_BANDS(R,A,B) {\
+ R.Left = MAX(A.Left, B.Left); \
+ R.Right = MIN(A.Right, B.Right);}
+
+static int IntCompare (const void *d1, const void *d2)
+{
+ if (*(uint32 *) d1 > *(uint32 *) d2)
+ return (1);
+ else
+ if (*(uint32 *) d1 < *(uint32 *) d2)
+ return (-1);
+ return (0);
+}
+
+static int BandCompare (const void *d1, const void *d2)
+{
+ if (((struct Band *) d1)->Left > ((struct Band *) d2)->Left)
+ return (1);
+ else
+ if (((struct Band *) d1)->Left < ((struct Band *) d2)->Left)
+ return (-1);
+ return (0);
+}
+
+void ComputeClipWindows ()
+{
+ struct ClipData *pClip = &IPPU.Clip [0];
+
+ // Loop around the main screen then the sub-screen.
+ for (int c = 0; c < 2; c++, pClip++)
+ {
+ // Loop around the colour window then a clip window for each of the
+ // background layers.
+ for (int w = 5; w >= 0; w--)
+ {
+ pClip->Count[w] = 0;
+
+ if (w == 5) // The colour window...
+ {
+ if (c == 0) // ... on the main screen
+ {
+ if ((Memory.FillRAM [0x2130] & 0xc0) == 0xc0)
+ {
+ // The whole of the main screen is switched off,
+ // completely clip everything.
+ for (int i = 0; i < 6; i++)
+ {
+ IPPU.Clip [c].Count [i] = 1;
+ IPPU.Clip [c].Left [0][i] = 1;
+ IPPU.Clip [c].Right [0][i] = 0;
+ }
+ continue;
+ }
+ else if ((Memory.FillRAM [0x2130] & 0xc0) == 0x00)
+ continue;
+ }
+ else
+ {
+ // .. colour window on the sub-screen.
+ if ((Memory.FillRAM [0x2130] & 0x30) == 0x30)
+ {
+ // The sub-screen is switched off, completely
+ // clip everything.
+ for (int i = 0; i < 6; i++)
+ {
+ IPPU.Clip [1].Count [i] = 1;
+ IPPU.Clip [1].Left [0][i] = 1;
+ IPPU.Clip [1].Right [0][i] = 0;
+ }
+ return;
+ }
+ else if ((Memory.FillRAM [0x2130] & 0x30) == 0x00)
+ continue;
+ }
+ }
+
+// if (!Settings.DisableGraphicWindows)
+ {
+ if (w == 5 || pClip->Count [5] ||
+ (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w)))
+ {
+ struct Band Win1[3];
+ struct Band Win2[3];
+ uint32 Window1Enabled = 0;
+ uint32 Window2Enabled = 0;
+ bool8 invert = (w == 5 &&
+ ((c == 1 && (Memory.FillRAM [0x2130] & 0x30) == 0x10) ||
+ (c == 0 && (Memory.FillRAM [0x2130] & 0xc0) == 0x40)));
+
+ if (w == 5 ||
+ (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w)))
+ {
+ if (PPU.ClipWindow1Enable [w])
+ {
+ if (!PPU.ClipWindow1Inside [w])
+ {
+ Win1[Window1Enabled].Left = PPU.Window1Left;
+ Win1[Window1Enabled++].Right = PPU.Window1Right + 1;
+ }
+ else
+ {
+ if (PPU.Window1Left <= PPU.Window1Right)
+ {
+ if (PPU.Window1Left > 0)
+ {
+ Win1[Window1Enabled].Left = 0;
+ Win1[Window1Enabled++].Right = PPU.Window1Left;
+ }
+ if (PPU.Window1Right < 255)
+ {
+ Win1[Window1Enabled].Left = PPU.Window1Right + 1;
+ Win1[Window1Enabled++].Right = 256;
+ }
+ if (Window1Enabled == 0)
+ {
+ Win1[Window1Enabled].Left = 1;
+ Win1[Window1Enabled++].Right = 0;
+ }
+ }
+ else
+ {
+ // 'outside' a window with no range -
+ // appears to be the whole screen.
+ Win1[Window1Enabled].Left = 0;
+ Win1[Window1Enabled++].Right = 256;
+ }
+ }
+ }
+ if (PPU.ClipWindow2Enable [w])
+ {
+ if (!PPU.ClipWindow2Inside [w])
+ {
+ Win2[Window2Enabled].Left = PPU.Window2Left;
+ Win2[Window2Enabled++].Right = PPU.Window2Right + 1;
+ }
+ else
+ {
+ if (PPU.Window2Left <= PPU.Window2Right)
+ {
+ if (PPU.Window2Left > 0)
+ {
+ Win2[Window2Enabled].Left = 0;
+ Win2[Window2Enabled++].Right = PPU.Window2Left;
+ }
+ if (PPU.Window2Right < 255)
+ {
+ Win2[Window2Enabled].Left = PPU.Window2Right + 1;
+ Win2[Window2Enabled++].Right = 256;
+ }
+ if (Window2Enabled == 0)
+ {
+ Win2[Window2Enabled].Left = 1;
+ Win2[Window2Enabled++].Right = 0;
+ }
+ }
+ else
+ {
+ Win2[Window2Enabled].Left = 0;
+ Win2[Window2Enabled++].Right = 256;
+ }
+ }
+ }
+ }
+ if (Window1Enabled && Window2Enabled)
+ {
+ // Overlap logic
+ //
+ // Each window will be in one of three states:
+ // 1. <no range> (Left > Right. One band)
+ // 2. | ---------------- | (Left >= 0, Right <= 255, Left <= Right. One band)
+ // 3. |------------ ----------| (Left1 == 0, Right1 < Left2; Left2 > Right1, Right2 == 255. Two bands)
+
+ struct Band Bands [6];
+ int B = 0;
+ switch (PPU.ClipWindowOverlapLogic [w] ^ 1)
+ {
+ case CLIP_OR:
+ if (Window1Enabled == 1)
+ {
+ if (BAND_EMPTY(Win1[0]))
+ {
+ B = Window2Enabled;
+ memmove (Bands, Win2,
+ sizeof(Win2[0]) * Window2Enabled);
+ }
+ else
+ {
+ if (Window2Enabled == 1)
+ {
+ if (BAND_EMPTY (Win2[0]))
+ Bands[B++] = Win1[0];
+ else
+ {
+ if (BANDS_INTERSECT (Win1[0], Win2[0]))
+ {
+ OR_BANDS(Bands[0],Win1[0], Win2[0])
+ B = 1;
+ }
+ else
+ {
+ Bands[B++] = Win1[0];
+ Bands[B++] = Win2[0];
+ }
+ }
+ }
+ else
+ {
+ if (BANDS_INTERSECT(Win1[0], Win2[0]))
+ {
+ OR_BANDS(Bands[0], Win1[0], Win2[0])
+ if (BANDS_INTERSECT(Win1[0], Win2[1]))
+ OR_BANDS(Bands[1], Win1[0], Win2[1])
+ else
+ Bands[1] = Win2[1];
+ B = 1;
+ if (BANDS_INTERSECT(Bands[0], Bands[1]))
+ OR_BANDS(Bands[0], Bands[0], Bands[1])
+ else
+ B = 2;
+ }
+ else
+ if (BANDS_INTERSECT(Win1[0], Win2[1]))
+ {
+ Bands[B++] = Win2[0];
+ OR_BANDS(Bands[B], Win1[0], Win2[1]);
+ B++;
+ }
+ else
+ {
+ Bands[0] = Win2[0];
+ Bands[1] = Win1[0];
+ Bands[2] = Win2[1];
+ B = 3;
+ }
+ }
+ }
+ }
+ else
+ if (Window2Enabled == 1)
+ {
+ if (BAND_EMPTY(Win2[0]))
+ {
+ // Window 2 defines an empty range - just
+ // use window 1 as the clipping (which
+ // could also be empty).
+ B = Window1Enabled;
+ memmove (Bands, Win1,
+ sizeof(Win1[0]) * Window1Enabled);
+ }
+ else
+ {
+ // Window 1 has two bands and Window 2 has one.
+ // Neither is an empty region.
+ if (BANDS_INTERSECT(Win2[0], Win1[0]))
+ {
+ OR_BANDS(Bands[0], Win2[0], Win1[0])
+ if (BANDS_INTERSECT(Win2[0], Win1[1]))
+ OR_BANDS(Bands[1], Win2[0], Win1[1])
+ else
+ Bands[1] = Win1[1];
+ B = 1;
+ if (BANDS_INTERSECT(Bands[0], Bands[1]))
+ OR_BANDS(Bands[0], Bands[0], Bands[1])
+ else
+ B = 2;
+ }
+ else
+ if (BANDS_INTERSECT(Win2[0], Win1[1]))
+ {
+ Bands[B++] = Win1[0];
+ OR_BANDS(Bands[B], Win2[0], Win1[1]);
+ B++;
+ }
+ else
+ {
+ Bands[0] = Win1[0];
+ Bands[1] = Win2[0];
+ Bands[2] = Win1[1];
+ B = 3;
+ }
+ }
+ }
+ else
+ {
+ // Both windows have two bands
+ OR_BANDS(Bands[0], Win1[0], Win2[0]);
+ OR_BANDS(Bands[1], Win1[1], Win2[1]);
+ B = 1;
+ if (BANDS_INTERSECT(Bands[0], Bands[1]))
+ OR_BANDS(Bands[0], Bands[0], Bands[1])
+ else
+ B = 2;
+ }
+ break;
+
+ case CLIP_AND:
+ if (Window1Enabled == 1)
+ {
+ // Window 1 has one band
+ if (BAND_EMPTY(Win1[0]))
+ Bands [B++] = Win1[0];
+ else
+ if (Window2Enabled == 1)
+ {
+ if (BAND_EMPTY (Win2[0]))
+ Bands [B++] = Win2[0];
+ else
+ {
+ AND_BANDS(Bands[0], Win1[0], Win2[0]);
+ B = 1;
+ }
+ }
+ else
+ {
+ AND_BANDS(Bands[0], Win1[0], Win2[0]);
+ AND_BANDS(Bands[1], Win1[0], Win2[1]);
+ B = 2;
+ }
+ }
+ else
+ if (Window2Enabled == 1)
+ {
+ if (BAND_EMPTY(Win2[0]))
+ Bands[B++] = Win2[0];
+ else
+ {
+ // Window 1 has two bands.
+ AND_BANDS(Bands[0], Win1[0], Win2[0]);
+ AND_BANDS(Bands[1], Win1[1], Win2[0]);
+ B = 2;
+ }
+ }
+ else
+ {
+ // Both windows have two bands.
+ AND_BANDS(Bands[0], Win1[0], Win2[0]);
+ AND_BANDS(Bands[1], Win1[1], Win2[1]);
+ B = 2;
+ if (BANDS_INTERSECT(Win1[0], Win2[1]))
+ {
+ AND_BANDS(Bands[2], Win1[0], Win2[1]);
+ B = 3;
+ }
+ else
+ if (BANDS_INTERSECT(Win1[1], Win2[0]))
+ {
+ AND_BANDS(Bands[2], Win1[1], Win2[0]);
+ B = 3;
+ }
+ }
+ break;
+ case CLIP_XNOR:
+ invert = !invert;
+ // Fall...
+
+ case CLIP_XOR:
+ if (Window1Enabled == 1 && BAND_EMPTY(Win1[0]))
+ {
+ B = Window2Enabled;
+ memmove (Bands, Win2,
+ sizeof(Win2[0]) * Window2Enabled);
+ }
+ else
+ if (Window2Enabled == 1 && BAND_EMPTY(Win2[0]))
+ {
+ B = Window1Enabled;
+ memmove (Bands, Win1,
+ sizeof(Win1[0]) * Window1Enabled);
+ }
+ else
+ {
+ uint32 p = 0;
+ uint32 points [10];
+ uint32 i;
+
+ invert = !invert;
+ // Build an array of points (window edges)
+ points [p++] = 0;
+ for (i = 0; i < Window1Enabled; i++)
+ {
+ points [p++] = Win1[i].Left;
+ points [p++] = Win1[i].Right;
+ }
+ for (i = 0; i < Window2Enabled; i++)
+ {
+ points [p++] = Win2[i].Left;
+ points [p++] = Win2[i].Right;
+ }
+ points [p++] = 256;
+ // Sort them
+ qsort ((void *) points, p, sizeof (points [0]),
+ IntCompare);
+ for (i = 0; i < p; i += 2)
+ {
+ if (points [i] == points [i + 1])
+ continue;
+ Bands [B].Left = points [i];
+ while (i + 2 < p &&
+ points [i + 1] == points [i + 2])
+ {
+ i += 2;
+ }
+ Bands [B++].Right = points [i + 1];
+ }
+ }
+ break;
+ }
+ if (invert)
+ {
+ int b;
+ int j = 0;
+ int empty_band_count = 0;
+
+ // First remove all empty bands from the list.
+ for (b = 0; b < B; b++)
+ {
+ if (!BAND_EMPTY(Bands[b]))
+ {
+ if (b != j)
+ Bands[j] = Bands[b];
+ j++;
+ }
+ else
+ empty_band_count++;
+ }
+
+ if (j > 0)
+ {
+ if (j == 1)
+ {
+ j = 0;
+ // Easy case to deal with, so special case it.
+
+ if (Bands[0].Left > 0)
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j++][w] = Bands[0].Left + 1;
+ }
+ if (Bands[0].Right < 256)
+ {
+ pClip->Left[j][w] = Bands[0].Right;
+ pClip->Right[j++][w] = 256;
+ }
+ if (j == 0)
+ {
+ pClip->Left[j][w] = 1;
+ pClip->Right[j++][w] = 0;
+ }
+ }
+ else
+ {
+ // Now sort the bands into order
+ B = j;
+ qsort ((void *) Bands, B,
+ sizeof (Bands [0]), BandCompare);
+
+ // Now invert the area the bands cover
+ j = 0;
+ for (b = 0; b < B; b++)
+ {
+ if (b == 0 && Bands[b].Left > 0)
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j++][w] = Bands[b].Left + 1;
+ }
+ else
+ if (b == B - 1 && Bands[b].Right < 256)
+ {
+ pClip->Left[j][w] = Bands[b].Right;
+ pClip->Right[j++][w] = 256;
+ }
+ if (b < B - 1)
+ {
+ pClip->Left[j][w] = Bands[b].Right;
+ pClip->Right[j++][w] = Bands[b + 1].Left + 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Inverting a window that consisted of only
+ // empty bands is the whole width of the screen.
+ // Needed for Mario Kart's rear-view mirror display.
+ if (empty_band_count)
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j][w] = 256;
+ j++;
+ }
+ }
+ pClip->Count[w] = j;
+ }
+ else
+ {
+ for (int j = 0; j < B; j++)
+ {
+ pClip->Left[j][w] = Bands[j].Left;
+ pClip->Right[j][w] = Bands[j].Right;
+ }
+ pClip->Count [w] = B;
+ }
+ }
+ else
+ {
+ // Only one window enabled so no need to perform
+ // complex overlap logic...
+
+ if (Window1Enabled)
+ {
+ if (invert)
+ {
+ int j = 0;
+
+ if (Window1Enabled == 1)
+ {
+ if (Win1[0].Left <= Win1[0].Right)
+ {
+ if (Win1[0].Left > 0)
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j++][w] = Win1[0].Left;
+ }
+ if (Win1[0].Right < 256)
+ {
+ pClip->Left[j][w] = Win1[0].Right;
+ pClip->Right[j++][w] = 256;
+ }
+ if (j == 0)
+ {
+ pClip->Left[j][w] = 1;
+ pClip->Right[j++][w] = 0;
+ }
+ }
+ else
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j++][w] = 256;
+ }
+ }
+ else
+ {
+ pClip->Left [j][w] = Win1[0].Right;
+ pClip->Right[j++][w] = Win1[1].Left;
+ }
+ pClip->Count [w] = j;
+ }
+ else
+ {
+ for (uint32 j = 0; j < Window1Enabled; j++)
+ {
+ pClip->Left [j][w] = Win1[j].Left;
+ pClip->Right [j][w] = Win1[j].Right;
+ }
+ pClip->Count [w] = Window1Enabled;
+ }
+ }
+ else
+ if (Window2Enabled)
+ {
+ if (invert)
+ {
+ int j = 0;
+ if (Window2Enabled == 1)
+ {
+ if (Win2[0].Left <= Win2[0].Right)
+ {
+ if (Win2[0].Left > 0)
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j++][w] = Win2[0].Left;
+ }
+ if (Win2[0].Right < 256)
+ {
+ pClip->Left[j][w] = Win2[0].Right;
+ pClip->Right[j++][w] = 256;
+ }
+ if (j == 0)
+ {
+ pClip->Left[j][w] = 1;
+ pClip->Right[j++][w] = 0;
+ }
+ }
+ else
+ {
+ pClip->Left[j][w] = 0;
+ pClip->Right[j++][w] = 256;
+ }
+ }
+ else
+ {
+ pClip->Left [j][w] = Win2[0].Right;
+ pClip->Right[j++][w] = Win2[1].Left + 1;
+ }
+ pClip->Count [w] = j;
+ }
+ else
+ {
+ for (uint32 j = 0; j < Window2Enabled; j++)
+ {
+ pClip->Left [j][w] = Win2[j].Left;
+ pClip->Right [j][w] = Win2[j].Right;
+ }
+ pClip->Count [w] = Window2Enabled;
+ }
+ }
+ }
+
+ if (w != 5 && pClip->Count [5])
+ {
+ // Colour window enabled. Set the
+ // clip windows for all remaining backgrounds to be
+ // the same as the colour window.
+ if (pClip->Count [w] == 0)
+ {
+ pClip->Count [w] = pClip->Count [5];
+ for (uint32 i = 0; i < pClip->Count [w]; i++)
+ {
+ pClip->Left [i][w] = pClip->Left [i][5];
+ pClip->Right [i][w] = pClip->Right [i][5];
+ }
+ }
+ else
+ {
+ // Intersect the colour window with the bg's
+ // own clip window.
+ for (uint32 i = 0; i < pClip->Count [w]; i++)
+ {
+ uint32 j;
+ for (j = 0; j < pClip->Count [5]; j++)
+ {
+ if((pClip->Left[i][w] >= pClip->Left[j][5] && pClip->Left[i][w] < pClip->Right[j][5]) || (pClip->Left[j][5] >= pClip->Left[i][w] && pClip->Left[j][5] < pClip->Right[i][w])){
+ // Found an intersection!
+ pClip->Left[i][w]=MAX(pClip->Left[i][w], pClip->Left[j][5]);
+ pClip->Right[i][w]=MIN(pClip->Right[i][w], pClip->Right[j][5]);
+ goto Clip_ok;
+ }
+ }
+ // no intersection, nullify it
+ pClip->Left[i][w]=1;
+ pClip->Right[i][w]=0;
+Clip_ok:
+ j=0; // dummy statement
+ }
+ }
+ }
+ } // if (w == 5 | ...
+ } // if (!Settings.DisableGraphicWindows)
+ } // for (int w...
+ } // for (int c...
+}
+
diff --git a/source/copyright.h b/source/copyright.h
new file mode 100644
index 0000000..f53dd80
--- /dev/null
+++ b/source/copyright.h
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+/*
+ * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+ *
+ * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
+ * Jerremy Koot (jkoot@snes9x.com)
+ *
+ * Super FX C emulator code
+ * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
+ * Gary Henderson.
+ * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
+ *
+ * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
+ * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
+ * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
+ *
+ * DOS port code contains the works of other authors. See headers in
+ * individual files.
+ *
+ * Snes9x homepage: http://www.snes9x.com
+ *
+ * Permission to use, copy, modify and distribute Snes9x in both binary and
+ * source form, for non-commercial purposes, is hereby granted without fee,
+ * providing that this license information and copyright notice appear with
+ * all copies and any derived work.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event shall the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Snes9x is freeware for PERSONAL USE only. Commercial users should
+ * seek permission of the copyright holders first. Commercial use includes
+ * charging money for Snes9x or software derived from Snes9x.
+ *
+ * The copyright holders request that bug fixes and improvements to the code
+ * should be forwarded to them so everyone can benefit from the modifications
+ * in future versions.
+ *
+ * Super NES and Super Nintendo Entertainment System are trademarks of
+ * Nintendo Co., Limited and its subsidiary companies.
+ */
+/*
+ * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+ *
+ * (c) Copyright 1996, 1997, 1998, 1999 Gary Henderson (gary@daniver.demon.co.uk) and
+ * Jerremy Koot (jkoot@snes9x.com)
+ *
+ * Super FX C emulator code (c) Copyright 1997, 1998 Ivar and
+ * Gary Henderson.
+ * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
+ *
+ * Permission to use, copy, modify and distribute Snes9x in both binary and
+ * source form, for non-commercial purposes, is hereby granted without fee,
+ * providing that this license information and copyright notice appear with
+ * all copies and any derived work.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event shall the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Snes9x is freeware for PERSONAL USE only. Commercial users should
+ * seek permission of the copyright holders first. Commercial use includes
+ * charging money for Snes9x or software derived from Snes9x.
+ *
+ * The copyright holders request that bug fixes and improvements to the code
+ * should be forwarded to them so everyone can benefit from the modifications
+ * in future versions.
+ *
+ * Super NES and Super Nintendo Entertainment System are trademarks of
+ * Nintendo Co., Limited and its subsidiary companies.
+ */
+
diff --git a/source/cpu.cpp b/source/cpu.cpp
new file mode 100644
index 0000000..80e387f
--- /dev/null
+++ b/source/cpu.cpp
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "dsp1.h"
+#include "cpuexec.h"
+#include "debug.h"
+#include "apu.h"
+#include "dma.h"
+#include "sa1.h"
+#include "cheats.h"
+#include "srtc.h"
+#include "sdd1.h"
+#include "spc7110.h"
+#include "obc1.h"
+
+
+#ifndef ZSNES_FX
+#include "fxemu.h"
+
+extern struct FxInit_s SuperFX;
+
+void S9xResetSuperFX ()
+{
+ SuperFX.vFlags = 0; //FX_FLAG_ROM_BUFFER;// | FX_FLAG_ADDRESS_CHECKING;
+ FxReset (&SuperFX);
+}
+#endif
+
+void S9xResetCPU ()
+{
+ Registers.PB = 0;
+ Registers.PC = S9xGetWord (0xFFFC);
+ Registers.D.W = 0;
+ Registers.DB = 0;
+ Registers.SH = 1;
+ Registers.SL = 0xFF;
+ Registers.XH = 0;
+ Registers.YH = 0;
+ Registers.P.W = 0;
+
+ ICPU.ShiftedPB = 0;
+ ICPU.ShiftedDB = 0;
+ SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation);
+ ClearFlags (Decimal);
+
+ CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
+ CPU.BranchSkip = FALSE;
+ CPU.NMIActive = FALSE;
+ CPU.IRQActive = FALSE;
+ CPU.WaitingForInterrupt = FALSE;
+ CPU.InDMA = FALSE;
+ CPU.WhichEvent = HBLANK_START_EVENT;
+ CPU.PC = NULL;
+ CPU.PCBase = NULL;
+ CPU.PCAtOpcodeStart = NULL;
+ CPU.WaitAddress = NULL;
+ CPU.WaitCounter = 0;
+ CPU.Cycles = 0;
+ CPU.NextEvent = Settings.HBlankStart;
+ CPU.V_Counter = 0;
+ CPU.MemSpeed = SLOW_ONE_CYCLE;
+ CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
+ CPU.FastROMSpeed = SLOW_ONE_CYCLE;
+ CPU.AutoSaveTimer = 0;
+ CPU.SRAMModified = FALSE;
+ // CPU.NMITriggerPoint = 4; // Set when ROM image loaded
+ CPU.BRKTriggered = FALSE;
+ //CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded
+ CPU.NMICycleCount = 0;
+ CPU.IRQCycleCount = 0;
+ S9xSetPCBase (Registers.PC);
+
+ ICPU.S9xOpcodes = S9xOpcodesE1;
+ ICPU.CPUExecuting = TRUE;
+
+ S9xUnpackStatus();
+}
+
+#ifdef ZSNES_FX
+START_EXTERN_C
+void S9xResetSuperFX ();
+bool8 WinterGold = 0;
+extern uint8 *C4Ram;
+END_EXTERN_C
+#endif
+
+void S9xReset (void)
+{
+ if (Settings.SuperFX)
+ S9xResetSuperFX ();
+
+#ifdef ZSNES_FX
+ WinterGold = Settings.WinterGold;
+#endif
+ ZeroMemory (Memory.FillRAM, 0x8000);
+ memset (Memory.VRAM, 0x00, 0x10000);
+ memset (Memory.RAM, 0x55, 0x20000);
+
+ if(Settings.SPC7110)
+ S9xSpc7110Reset();
+ S9xResetCPU ();
+ S9xResetPPU ();
+ S9xResetSRTC ();
+ if (Settings.SDD1)
+ S9xResetSDD1 ();
+
+ S9xResetDMA ();
+ S9xResetAPU ();
+ S9xResetDSP1 ();
+ S9xSA1Init ();
+ if (Settings.C4)
+ S9xInitC4 ();
+ S9xInitCheatData ();
+ if(Settings.OBC1)
+ ResetOBC1();
+
+// Settings.Paused = FALSE;
+}
+void S9xSoftReset (void)
+{
+ if (Settings.SuperFX)
+ S9xResetSuperFX ();
+
+#ifdef ZSNES_FX
+ WinterGold = Settings.WinterGold;
+#endif
+ ZeroMemory (Memory.FillRAM, 0x8000);
+ memset (Memory.VRAM, 0x00, 0x10000);
+ // memset (Memory.RAM, 0x55, 0x20000);
+
+ if(Settings.SPC7110)
+ S9xSpc7110Reset();
+ S9xResetCPU ();
+ S9xSoftResetPPU ();
+ S9xResetSRTC ();
+ if (Settings.SDD1)
+ S9xResetSDD1 ();
+
+ S9xResetDMA ();
+ S9xResetAPU ();
+ S9xResetDSP1 ();
+ if(Settings.OBC1)
+ ResetOBC1();
+ S9xSA1Init ();
+ if (Settings.C4)
+ S9xInitC4 ();
+ S9xInitCheatData ();
+
+// Settings.Paused = FALSE;
+}
+
diff --git a/source/cpuaddr.h b/source/cpuaddr.h
new file mode 100644
index 0000000..a4c0ff4
--- /dev/null
+++ b/source/cpuaddr.h
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _CPUADDR_H_
+#define _CPUADDR_H_
+
+EXTERN_C long OpAddress;
+
+typedef enum {
+ NONE = 0,
+ READ = 1,
+ WRITE = 2,
+ MODIFY = 3,
+ JUMP = 4
+} AccessMode;
+
+STATIC inline void Immediate8 (AccessMode a)
+{
+ OpAddress = ICPU.ShiftedPB + CPU.PC - CPU.PCBase;
+ CPU.PC++;
+}
+
+STATIC inline void Immediate16 (AccessMode a)
+{
+ OpAddress = ICPU.ShiftedPB + CPU.PC - CPU.PCBase;
+ CPU.PC += 2;
+}
+
+STATIC inline void Relative (AccessMode a)
+{
+ Int8 = *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ OpAddress = ((int) (CPU.PC - CPU.PCBase) + Int8) & 0xffff;
+}
+
+STATIC inline void RelativeLong (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = *(uint16 *) CPU.PC;
+#else
+ OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE;
+#endif
+ CPU.PC += 2;
+ OpAddress += (CPU.PC - CPU.PCBase);
+ OpAddress &= 0xffff;
+}
+
+STATIC inline void AbsoluteIndexedIndirect (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = (Registers.X.W + *(uint16 *) CPU.PC) & 0xffff;
+#else
+ OpAddress = (Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff;
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ OpenBus = *(CPU.PC + 1);
+ CPU.PC += 2;
+ OpAddress = S9xGetWord (ICPU.ShiftedPB + OpAddress);
+ if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+}
+
+STATIC inline void AbsoluteIndirectLong (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = *(uint16 *) CPU.PC;
+#else
+ OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ OpenBus = *(CPU.PC + 1);
+ CPU.PC += 2;
+ if(a&READ) {
+ OpAddress = S9xGetWord (OpAddress) | ((OpenBus=S9xGetByte (OpAddress + 2)) << 16);
+ } else {
+ OpAddress = S9xGetWord (OpAddress) | (S9xGetByte (OpAddress + 2) << 16);
+ }
+}
+
+STATIC inline void AbsoluteIndirect (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = *(uint16 *) CPU.PC;
+#else
+ OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ OpenBus = *(CPU.PC + 1);
+ CPU.PC += 2;
+ OpAddress = S9xGetWord (OpAddress);
+ if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ OpAddress += ICPU.ShiftedPB;
+}
+
+STATIC inline void Absolute (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = *(uint16 *) CPU.PC + ICPU.ShiftedDB;
+#else
+ OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB;
+#endif
+ if(a&READ) OpenBus = *(CPU.PC+1);
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+}
+
+STATIC inline void AbsoluteLong (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = (*(uint32 *) CPU.PC) & 0xffffff;
+#else
+ OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16);
+#endif
+ if(a&READ) OpenBus = *(CPU.PC+2);
+ CPU.PC += 3;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed;
+#endif
+}
+
+STATIC inline void Direct(AccessMode a)
+{
+ if(a&READ) OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+}
+
+STATIC inline void DirectIndirectIndexed (AccessMode a)
+{
+ OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+
+ OpAddress = S9xGetWord (OpAddress);
+ if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ OpAddress += ICPU.ShiftedDB + Registers.Y.W;
+
+// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+ // XXX: always add one if STA
+ // XXX: else Add one cycle if crosses page boundary
+}
+
+STATIC inline void DirectIndirectIndexedLong (AccessMode a)
+{
+ OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+
+ if(a&READ){
+ OpAddress = S9xGetWord (OpAddress) + ((OpenBus = S9xGetByte (OpAddress + 2)) << 16) + Registers.Y.W;
+ } else {
+ OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16) + Registers.Y.W;
+ }
+// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+}
+
+STATIC inline void DirectIndexedIndirect(AccessMode a)
+{
+ OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+
+ OpAddress = S9xGetWord (OpAddress);
+ if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ OpAddress += ICPU.ShiftedDB;
+
+#ifndef SA1_OPCODES
+// if (Registers.DL != 0)
+// CPU.Cycles += TWO_CYCLES;
+// else
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+STATIC inline void DirectIndexedX (AccessMode a)
+{
+ if(a&READ) OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W);
+ OpAddress &= CheckEmulation() ? 0xff : 0xffff;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+
+#ifndef SA1_OPCODES
+// if (Registers.DL != 0)
+// CPU.Cycles += TWO_CYCLES;
+// else
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+STATIC inline void DirectIndexedY (AccessMode a)
+{
+ if(a&READ) OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W + Registers.Y.W);
+ OpAddress &= CheckEmulation() ? 0xff : 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+
+#ifndef SA1_OPCODES
+// if (Registers.DL != 0)
+// CPU.Cycles += TWO_CYCLES;
+// else
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+STATIC inline void AbsoluteIndexedX (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W;
+#else
+ OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) +
+ Registers.X.W;
+#endif
+ if(a&READ) OpenBus = *(CPU.PC+1);
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ // XXX: always add one cycle for ROL, LSR, etc
+ // XXX: else is cross page boundary add one cycle
+}
+
+STATIC inline void AbsoluteIndexedY (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W;
+#else
+ OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) +
+ Registers.Y.W;
+#endif
+ if(a&READ) OpenBus = *(CPU.PC+1);
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ // XXX: always add cycle for STA
+ // XXX: else is cross page boundary add one cycle
+}
+
+STATIC inline void AbsoluteLongIndexedX (AccessMode a)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ OpAddress = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff;
+#else
+ OpAddress = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff;
+#endif
+ if(a&READ) OpenBus = *(CPU.PC+2);
+ CPU.PC += 3;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed;
+#endif
+}
+
+STATIC inline void DirectIndirect (AccessMode a)
+{
+ OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ OpAddress = S9xGetWord (OpAddress);
+ if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ OpAddress += ICPU.ShiftedDB;
+
+// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+}
+
+STATIC inline void DirectIndirectLong (AccessMode a)
+{
+ OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ if(a&READ){
+ OpAddress = S9xGetWord (OpAddress) + ((OpenBus=S9xGetByte (OpAddress + 2)) << 16);
+ } else {
+ OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16);
+ }
+// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+}
+
+STATIC inline void StackRelative (AccessMode a)
+{
+ if(a&READ) OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+STATIC inline void StackRelativeIndirectIndexed (AccessMode a)
+{
+ OpenBus = *CPU.PC;
+ OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ OpAddress = S9xGetWord (OpAddress);
+ if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ OpAddress = (OpAddress + ICPU.ShiftedDB +
+ Registers.Y.W) & 0xffffff;
+}
+#endif
+
diff --git a/source/cpuexec.cpp b/source/cpuexec.cpp
new file mode 100644
index 0000000..21b1574
--- /dev/null
+++ b/source/cpuexec.cpp
@@ -0,0 +1,476 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "ds2_timer.h"
+#include "ds2_cpu.h"
+#include "ds2io.h"
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "cpuops.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "debug.h"
+#include "snapshot.h"
+#include "gfx.h"
+#include "missing.h"
+#include "apu.h"
+#include "dma.h"
+#include "fxemu.h"
+#include "sa1.h"
+#include "spc7110.h"
+
+extern void S9xProcessSound (unsigned int);
+
+void S9xMainLoop (void)
+{
+ for (;;)
+ {
+ APU_EXECUTE ();
+
+ if (CPU.Flags)
+ {
+ if (CPU.Flags & NMI_FLAG)
+ {
+ if (--CPU.NMICycleCount == 0) {
+ CPU.Flags &= ~NMI_FLAG;
+ if (CPU.WaitingForInterrupt) {
+ CPU.WaitingForInterrupt = FALSE;
+ CPU.PC++;
+ }
+ S9xOpcode_NMI ();
+ }
+ }
+
+ CHECK_SOUND ();
+
+ if (CPU.Flags & IRQ_PENDING_FLAG)
+ {
+ if (CPU.IRQCycleCount == 0)
+ {
+ if (CPU.WaitingForInterrupt) {
+ CPU.WaitingForInterrupt = FALSE;
+ CPU.PC++;
+ }
+ if (CPU.IRQActive && !Settings.DisableIRQ) {
+ if (!CheckFlag (IRQ))
+ S9xOpcode_IRQ ();
+ }
+ else
+ CPU.Flags &= ~IRQ_PENDING_FLAG;
+ }
+ else
+ {
+ if(--CPU.IRQCycleCount==0 && CheckFlag (IRQ))
+ CPU.IRQCycleCount=1;
+ }
+ }
+
+ if (CPU.Flags & SCAN_KEYS_FLAG)
+ break;
+ }
+
+#ifdef CPU_SHUTDOWN
+ CPU.PCAtOpcodeStart = CPU.PC;
+#endif
+ CPU.Cycles += CPU.MemSpeed;
+
+ (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) ();
+
+ if (SA1.Executing)
+ S9xSA1MainLoop ();
+ DO_HBLANK_CHECK();
+ }
+
+ Registers.PC = CPU.PC - CPU.PCBase;
+ S9xPackStatus ();
+ APURegisters.PC = IAPU.PC - IAPU.RAM;
+ S9xAPUPackStatus ();
+ if (CPU.Flags & SCAN_KEYS_FLAG)
+ {
+ S9xSyncSpeed ();
+ CPU.Flags &= ~SCAN_KEYS_FLAG;
+ }
+
+#ifdef DETECT_NASTY_FX_INTERLEAVE
+ if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2)
+ {
+ CPU.TriedInterleavedMode2 = TRUE;
+ CPU.BRKTriggered = FALSE;
+ S9xDeinterleaveMode2 ();
+ }
+#endif
+}
+
+void S9xSetIRQ (uint32 source)
+{
+ CPU.IRQActive |= source;
+ CPU.Flags |= IRQ_PENDING_FLAG;
+ CPU.IRQCycleCount = 3;
+ if (CPU.WaitingForInterrupt)
+ {
+ // Force IRQ to trigger immediately after WAI -
+ // Final Fantasy Mystic Quest crashes without this.
+ CPU.IRQCycleCount = 0;
+ CPU.WaitingForInterrupt = FALSE;
+ CPU.PC++;
+ }
+}
+
+void S9xClearIRQ (uint32 source)
+{
+ CLEAR_IRQ_SOURCE (source);
+}
+
+static unsigned int sync_last= 0;
+static unsigned int sync_next = 0;
+static unsigned int framenum = 0;
+static unsigned int realframe = 0;
+
+extern "C" unsigned int game_fast_forward;
+static unsigned int skip_rate= 0;
+
+void S9xDoHBlankProcessing ()
+{
+ unsigned int syncnow;
+ unsigned int syncdif;
+
+#ifdef CPU_SHUTDOWN
+ CPU.WaitCounter++;
+#endif
+ switch (CPU.WhichEvent)
+ {
+ case HBLANK_START_EVENT:
+ if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
+ IPPU.HDMA = S9xDoHDMA (IPPU.HDMA);
+
+ break;
+
+ case HBLANK_END_EVENT:
+ S9xSuperFXExec ();
+
+#ifndef STORM
+ if (Settings.SoundSync)
+ S9xGenerateSound ();
+#endif
+
+ CPU.Cycles -= Settings.H_Max;
+ if (IAPU.APUExecuting)
+ {
+ APU.Cycles -= Settings.H_Max;
+#ifdef MK_APU
+ S9xCatchupCount();
+#endif
+ }
+ else
+ APU.Cycles = 0;
+
+ CPU.NextEvent = -1;
+ ICPU.Scanline++;
+
+ if (++CPU.V_Counter >= (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER))
+ {
+ CPU.V_Counter = 0;
+ Memory.FillRAM[0x213F]^=0x80;
+ PPU.RangeTimeOver = 0;
+ CPU.NMIActive = FALSE;
+ ICPU.Frame++;
+ PPU.HVBeamCounterLatched = 0;
+ CPU.Flags |= SCAN_KEYS_FLAG;
+ S9xStartHDMA ();
+ }
+
+ S9xProcessSound (0);
+
+ if (PPU.VTimerEnabled && !PPU.HTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos)
+ {
+ S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
+ }
+
+ if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)
+ {
+ // Start of V-blank
+ S9xEndScreenRefresh ();
+ IPPU.HDMA = 0;
+ // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
+ missing.dma_this_frame = 0;
+ IPPU.MaxBrightness = PPU.Brightness;
+ PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1;
+
+ if(!PPU.ForcedBlanking)
+ {
+ PPU.OAMAddr = PPU.SavedOAMAddr;
+
+ uint8 tmp = 0;
+ if(PPU.OAMPriorityRotation)
+ tmp = (PPU.OAMAddr&0xFE)>>1;
+ if((PPU.OAMFlip&1) || PPU.FirstSprite!=tmp)
+ {
+ PPU.FirstSprite=tmp;
+ IPPU.OBJChanged=TRUE;
+ }
+
+ PPU.OAMFlip = 0;
+ }
+
+ Memory.FillRAM[0x4210] = 0x80 |Model->_5A22;
+ if (Memory.FillRAM[0x4200] & 0x80)
+ {
+ CPU.NMIActive = TRUE;
+ CPU.Flags |= NMI_FLAG;
+ CPU.NMICycleCount = CPU.NMITriggerPoint;
+ }
+
+#ifdef OLD_SNAPSHOT_CODE
+ if (CPU.Flags & SAVE_SNAPSHOT_FLAG)
+ {
+ CPU.Flags &= ~SAVE_SNAPSHOT_FLAG;
+ Registers.PC = CPU.PC - CPU.PCBase;
+ S9xPackStatus ();
+ S9xAPUPackStatus ();
+ Snapshot (NULL);
+ }
+#endif
+ if(!game_fast_forward)
+ {
+ syncnow = getSysTime();
+ if(syncnow > sync_next)
+ {
+ /*
+ * Little bit of a hack here:
+ * If we get behind and stay behind for a certain number
+ * of frames, we automatically enable fast forward.
+ * That really helps with certain games, such as
+ * Super Mario RPG and Yoshi's Island.
+ */
+ if(skip_rate++ < 10)
+ {
+ syncdif = syncnow - sync_next;
+ if(syncdif < 11718)
+ {
+ IPPU.RenderThisFrame = false;
+ sync_next += 391;
+ }
+ else
+ { //lag more than 0.5s, maybe paused
+ IPPU.RenderThisFrame = true;
+ sync_next = syncnow;
+ framenum = 0;
+ sync_last = syncnow;
+ realframe = 1;
+ }
+ }
+ else
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = true;
+ sync_last= syncnow;
+ sync_next = syncnow+391;
+ }
+ }
+ else
+ {
+ skip_rate = 0;
+ syncdif = sync_next - syncnow;
+ if(syncdif > 391)
+ {
+ udelay(syncdif*22);
+ S9xProcessSound (0);
+ }
+
+ IPPU.RenderThisFrame = true;
+ sync_next += 391; //16.7ms
+ realframe += 1;
+ }
+#if 0
+ if(++framenum >= 60)
+ {
+ syncdif = syncnow - sync_last;
+ sync_last = syncnow;
+ framenum = 0;
+ //printf("T %d %d\n", syncdif*42667/1000, realframe);
+ realframe = 0;
+ }
+#endif
+ }
+ else
+ {
+ sync_last= 0;
+ sync_next = 0;
+
+ if(skip_rate++ < 10)
+ IPPU.RenderThisFrame = false;
+ else
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = true;
+ }
+ }
+ }
+
+ if (CPU.V_Counter == PPU.ScreenHeight + 3)
+ S9xUpdateJoypads ();
+
+ if (CPU.V_Counter == FIRST_VISIBLE_LINE)
+ {
+ Memory.FillRAM[0x4210] = Model->_5A22;
+ CPU.Flags &= ~NMI_FLAG;
+ S9xStartScreenRefresh ();
+ }
+ if (CPU.V_Counter >= FIRST_VISIBLE_LINE &&
+ CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE)
+ {
+ RenderLine (CPU.V_Counter - FIRST_VISIBLE_LINE);
+ }
+ // Use TimerErrorCounter to skip update of SPC700 timers once
+ // every 128 updates. Needed because this section of code is called
+ // once every emulated 63.5 microseconds, which coresponds to
+ // 15.750KHz, but the SPC700 timers need to be updated at multiples
+ // of 8KHz, hence the error correction.
+// IAPU.TimerErrorCounter++;
+// if (IAPU.TimerErrorCounter >= )
+// IAPU.TimerErrorCounter = 0;
+// else
+ {
+ if (APU.TimerEnabled [2])
+ {
+ APU.Timer [2] += 4;
+ while (APU.Timer [2] >= APU.TimerTarget [2])
+ {
+ IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf;
+ APU.Timer [2] -= APU.TimerTarget [2];
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+ IAPU.APUExecuting = TRUE;
+#endif
+ }
+ }
+ if (CPU.V_Counter & 1)
+ {
+ if (APU.TimerEnabled [0])
+ {
+ APU.Timer [0]++;
+ if (APU.Timer [0] >= APU.TimerTarget [0])
+ {
+ IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf;
+ APU.Timer [0] = 0;
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+ IAPU.APUExecuting = TRUE;
+#endif
+ }
+ }
+ if (APU.TimerEnabled [1])
+ {
+ APU.Timer [1]++;
+ if (APU.Timer [1] >= APU.TimerTarget [1])
+ {
+ IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf;
+ APU.Timer [1] = 0;
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+ IAPU.APUExecuting = TRUE;
+#endif
+ }
+ }
+ }
+ }
+ break;
+
+ case HTIMER_BEFORE_EVENT:
+ case HTIMER_AFTER_EVENT:
+ if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos))
+ {
+ S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE);
+ }
+ break;
+ }
+
+ S9xReschedule ();
+}
+
diff --git a/source/cpuexec.h b/source/cpuexec.h
new file mode 100644
index 0000000..9a26081
--- /dev/null
+++ b/source/cpuexec.h
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _CPUEXEC_H_
+#define _CPUEXEC_H_
+#include "ppu.h"
+#include "memmap.h"
+#include "65c816.h"
+
+#define DO_HBLANK_CHECK() \
+ if (CPU.Cycles >= CPU.NextEvent) \
+ S9xDoHBlankProcessing ();
+
+struct SOpcodes {
+#ifdef __WIN32__
+ void (__cdecl *S9xOpcode)( void);
+#else
+ void (*S9xOpcode)( void);
+#endif
+};
+
+struct SICPU
+{
+ uint8 *Speed;
+ struct SOpcodes *S9xOpcodes;
+ uint8 _Carry;
+ uint8 _Zero;
+ uint8 _Negative;
+ uint8 _Overflow;
+ bool8 CPUExecuting;
+ uint32 ShiftedPB;
+ uint32 ShiftedDB;
+ uint32 Frame;
+ uint32 Scanline;
+ uint32 FrameAdvanceCount;
+};
+
+START_EXTERN_C
+void S9xMainLoop (void);
+void S9xReset (void);
+void S9xSoftReset (void);
+void S9xDoHBlankProcessing ();
+void S9xClearIRQ (uint32);
+void S9xSetIRQ (uint32);
+
+extern struct SOpcodes S9xOpcodesE1 [256];
+extern struct SOpcodes S9xOpcodesM1X1 [256];
+extern struct SOpcodes S9xOpcodesM1X0 [256];
+extern struct SOpcodes S9xOpcodesM0X1 [256];
+extern struct SOpcodes S9xOpcodesM0X0 [256];
+
+extern struct SICPU ICPU;
+END_EXTERN_C
+
+STATIC inline void S9xUnpackStatus()
+{
+ ICPU._Zero = (Registers.PL & Zero) == 0;
+ ICPU._Negative = (Registers.PL & Negative);
+ ICPU._Carry = (Registers.PL & Carry);
+ ICPU._Overflow = (Registers.PL & Overflow) >> 6;
+}
+
+STATIC inline void S9xPackStatus()
+{
+ Registers.PL &= ~(Zero | Negative | Carry | Overflow);
+ Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) |
+ (ICPU._Negative & 0x80) | (ICPU._Overflow << 6);
+}
+
+STATIC inline void CLEAR_IRQ_SOURCE (uint32 M)
+{
+ CPU.IRQActive &= ~M;
+ if (!CPU.IRQActive)
+ CPU.Flags &= ~IRQ_PENDING_FLAG;
+}
+
+STATIC inline void S9xFixCycles ()
+{
+ if (CheckEmulation ())
+ {
+ ICPU.S9xOpcodes = S9xOpcodesE1;
+ }
+ else
+ if (CheckMemory ())
+ {
+ if (CheckIndex ())
+ {
+ ICPU.S9xOpcodes = S9xOpcodesM1X1;
+ }
+ else
+ {
+ ICPU.S9xOpcodes = S9xOpcodesM1X0;
+ }
+ }
+ else
+ {
+ if (CheckIndex ())
+ {
+ ICPU.S9xOpcodes = S9xOpcodesM0X1;
+ }
+ else
+ {
+ ICPU.S9xOpcodes = S9xOpcodesM0X0;
+ }
+ }
+}
+
+STATIC inline void S9xReschedule ()
+{
+ uint8 which;
+ long max;
+
+ if (CPU.WhichEvent == HBLANK_START_EVENT ||
+ CPU.WhichEvent == HTIMER_AFTER_EVENT)
+ {
+ which = HBLANK_END_EVENT;
+ max = Settings.H_Max;
+ }
+ else
+ {
+ which = HBLANK_START_EVENT;
+ max = Settings.HBlankStart;
+ }
+
+ if (PPU.HTimerEnabled &&
+ (long) PPU.HTimerPosition < max &&
+ (long) PPU.HTimerPosition > CPU.NextEvent &&
+ (!PPU.VTimerEnabled ||
+ (PPU.VTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos)))
+ {
+ which = (long) PPU.HTimerPosition < Settings.HBlankStart ?
+ HTIMER_BEFORE_EVENT : HTIMER_AFTER_EVENT;
+ max = PPU.HTimerPosition;
+ }
+ CPU.NextEvent = max;
+ CPU.WhichEvent = which;
+}
+
+#endif
+
diff --git a/source/cpumacro.h b/source/cpumacro.h
new file mode 100644
index 0000000..d97aa53
--- /dev/null
+++ b/source/cpumacro.h
@@ -0,0 +1,892 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _CPUMACRO_H_
+#define _CPUMACRO_H_
+
+STATIC inline void SetZN16 (uint16 Work)
+{
+ ICPU._Zero = Work != 0;
+ ICPU._Negative = (uint8) (Work >> 8);
+}
+
+STATIC inline void SetZN8 (uint8 Work)
+{
+ ICPU._Zero = Work;
+ ICPU._Negative = Work;
+}
+
+STATIC inline void ADC8 ()
+{
+ Work8 = S9xGetByte (OpAddress);
+
+ if (CheckDecimal ())
+ {
+ A1 = (Registers.A.W) & 0xF;
+ A2 = (Registers.A.W >> 4) & 0xF;
+ W1 = Work8 & 0xF;
+ W2 = (Work8 >> 4) & 0xF;
+
+ A1 += W1 + CheckCarry();
+ if (A1 > 9)
+ {
+ A1 -= 10;
+ A1 &= 0xF;
+ A2++;
+ }
+
+ A2 += W2;
+ if (A2 > 9)
+ {
+ A2 -= 10;
+ A2 &= 0xF;
+ SetCarry ();
+ }
+ else
+ {
+ ClearCarry ();
+ }
+
+ Ans8 = (A2 << 4) | A1;
+ if (~(Registers.AL ^ Work8) &
+ (Work8 ^ Ans8) & 0x80)
+ SetOverflow();
+ else
+ ClearOverflow();
+ Registers.AL = Ans8;
+ SetZN8 (Registers.AL);
+ }
+ else
+ {
+ Ans16 = Registers.AL + Work8 + CheckCarry();
+
+ ICPU._Carry = Ans16 >= 0x100;
+
+ if (~(Registers.AL ^ Work8) &
+ (Work8 ^ (uint8) Ans16) & 0x80)
+ SetOverflow();
+ else
+ ClearOverflow();
+ Registers.AL = (uint8) Ans16;
+ SetZN8 (Registers.AL);
+
+ }
+}
+
+STATIC inline void ADC16 ()
+{
+ Work16 = S9xGetWord (OpAddress);
+
+ if (CheckDecimal ())
+ {
+ A1 = (Registers.A.W) & 0xF;
+ A2 = (Registers.A.W >> 4) & 0xF;
+ A3 = (Registers.A.W >> 8) & 0xF;
+ A4 = (Registers.A.W >> 12) & 0xF;
+ W1 = Work16 & 0xF;
+ W2 = (Work16 >> 4) & 0xF;
+ W3 = (Work16 >> 8) & 0xF;
+ W4 = (Work16 >> 12) & 0xF;
+
+ A1 += W1 + CheckCarry ();
+ if (A1 > 9)
+ {
+ A1 -= 10;
+ A1 &= 0xF;
+ A2++;
+ }
+
+ A2 += W2;
+ if (A2 > 9)
+ {
+ A2 -= 10;
+ A2 &= 0xF;
+ A3++;
+ }
+
+ A3 += W3;
+ if (A3 > 9)
+ {
+ A3 -= 10;
+ A3 &= 0xF;
+ A4++;
+ }
+
+ A4 += W4;
+ if (A4 > 9)
+ {
+ A4 -= 10;
+ A4 &= 0xF;
+ SetCarry ();
+ }
+ else
+ {
+ ClearCarry ();
+ }
+
+ Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1);
+ if (~(Registers.A.W ^ Work16) &
+ (Work16 ^ Ans16) & 0x8000)
+ SetOverflow();
+ else
+ ClearOverflow();
+ Registers.A.W = Ans16;
+ SetZN16 (Registers.A.W);
+ }
+ else
+ {
+ Ans32 = Registers.A.W + Work16 + CheckCarry();
+
+ ICPU._Carry = Ans32 >= 0x10000;
+
+ if (~(Registers.A.W ^ Work16) &
+ (Work16 ^ (uint16) Ans32) & 0x8000)
+ SetOverflow();
+ else
+ ClearOverflow();
+ Registers.A.W = (uint16) Ans32;
+ SetZN16 (Registers.A.W);
+ }
+}
+
+STATIC inline void AND16 ()
+{
+ Registers.A.W &= S9xGetWord (OpAddress);
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void AND8 ()
+{
+ Registers.AL &= S9xGetByte (OpAddress);
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void A_ASL16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ ICPU._Carry = (Registers.AH & 0x80) != 0;
+ Registers.A.W <<= 1;
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void A_ASL8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ ICPU._Carry = (Registers.AL & 0x80) != 0;
+ Registers.AL <<= 1;
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void ASL16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = S9xGetWord (OpAddress);
+ ICPU._Carry = (Work16 & 0x8000) != 0;
+ Work16 <<= 1;
+ //S9xSetWord (Work16, OpAddress);
+ S9xSetByte(Work16>>8, OpAddress+1);
+ S9xSetByte(Work16&0xFF, OpAddress);
+ SetZN16 (Work16);
+}
+
+STATIC inline void ASL8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work8 = S9xGetByte (OpAddress);
+ ICPU._Carry = (Work8 & 0x80) != 0;
+ Work8 <<= 1;
+ S9xSetByte (Work8, OpAddress);
+ SetZN8 (Work8);
+}
+
+STATIC inline void BIT16 ()
+{
+ Work16 = S9xGetWord (OpAddress);
+ ICPU._Overflow = (Work16 & 0x4000) != 0;
+ ICPU._Negative = (uint8) (Work16 >> 8);
+ ICPU._Zero = (Work16 & Registers.A.W) != 0;
+}
+
+STATIC inline void BIT8 ()
+{
+ Work8 = S9xGetByte (OpAddress);
+ ICPU._Overflow = (Work8 & 0x40) != 0;
+ ICPU._Negative = Work8;
+ ICPU._Zero = Work8 & Registers.AL;
+}
+
+STATIC inline void CMP16 ()
+{
+ Int32 = (long) Registers.A.W -
+ (long) S9xGetWord (OpAddress);
+ ICPU._Carry = Int32 >= 0;
+ SetZN16 ((uint16) Int32);
+}
+
+STATIC inline void CMP8 ()
+{
+ Int16 = (short) Registers.AL -
+ (short) S9xGetByte (OpAddress);
+ ICPU._Carry = Int16 >= 0;
+ SetZN8 ((uint8) Int16);
+}
+
+STATIC inline void CMX16 ()
+{
+ Int32 = (long) Registers.X.W -
+ (long) S9xGetWord (OpAddress);
+ ICPU._Carry = Int32 >= 0;
+ SetZN16 ((uint16) Int32);
+}
+
+STATIC inline void CMX8 ()
+{
+ Int16 = (short) Registers.XL -
+ (short) S9xGetByte (OpAddress);
+ ICPU._Carry = Int16 >= 0;
+ SetZN8 ((uint8) Int16);
+}
+
+STATIC inline void CMY16 ()
+{
+ Int32 = (long) Registers.Y.W -
+ (long) S9xGetWord (OpAddress);
+ ICPU._Carry = Int32 >= 0;
+ SetZN16 ((uint16) Int32);
+}
+
+STATIC inline void CMY8 ()
+{
+ Int16 = (short) Registers.YL -
+ (short) S9xGetByte (OpAddress);
+ ICPU._Carry = Int16 >= 0;
+ SetZN8 ((uint8) Int16);
+}
+
+STATIC inline void A_DEC16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.A.W--;
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void A_DEC8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.AL--;
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void DEC16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Work16 = S9xGetWord (OpAddress) - 1;
+ //S9xSetWord (Work16, OpAddress);
+ S9xSetByte (Work16>>8, OpAddress+1);
+ S9xSetByte (Work16&0xFF, OpAddress);
+ SetZN16 (Work16);
+}
+
+STATIC inline void DEC8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Work8 = S9xGetByte (OpAddress) - 1;
+ S9xSetByte (Work8, OpAddress);
+ SetZN8 (Work8);
+}
+
+STATIC inline void EOR16 ()
+{
+ Registers.A.W ^= S9xGetWord (OpAddress);
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void EOR8 ()
+{
+ Registers.AL ^= S9xGetByte (OpAddress);
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void A_INC16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.A.W++;
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void A_INC8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.AL++;
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void INC16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Work16 = S9xGetWord (OpAddress) + 1;
+ //S9xSetWord (Work16, OpAddress);
+ S9xSetByte (Work16>>8, OpAddress+1);
+ S9xSetByte (Work16&0xFF, OpAddress);
+ SetZN16 (Work16);
+}
+
+STATIC inline void INC8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Work8 = S9xGetByte (OpAddress) + 1;
+ S9xSetByte (Work8, OpAddress);
+ SetZN8 (Work8);
+}
+
+STATIC inline void LDA16 ()
+{
+ Registers.A.W = S9xGetWord (OpAddress);
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void LDA8 ()
+{
+ Registers.AL = S9xGetByte (OpAddress);
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void LDX16 ()
+{
+ Registers.X.W = S9xGetWord (OpAddress);
+ SetZN16 (Registers.X.W);
+}
+
+STATIC inline void LDX8 ()
+{
+ Registers.XL = S9xGetByte (OpAddress);
+ SetZN8 (Registers.XL);
+}
+
+STATIC inline void LDY16 ()
+{
+ Registers.Y.W = S9xGetWord (OpAddress);
+ SetZN16 (Registers.Y.W);
+}
+
+STATIC inline void LDY8 ()
+{
+ Registers.YL = S9xGetByte (OpAddress);
+ SetZN8 (Registers.YL);
+}
+
+STATIC inline void A_LSR16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ ICPU._Carry = Registers.AL & 1;
+ Registers.A.W >>= 1;
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void A_LSR8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ ICPU._Carry = Registers.AL & 1;
+ Registers.AL >>= 1;
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void LSR16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = S9xGetWord (OpAddress);
+ ICPU._Carry = Work16 & 1;
+ Work16 >>= 1;
+ //S9xSetWord (Work16, OpAddress);
+ S9xSetByte (Work16>>8, OpAddress+1);
+ S9xSetByte (Work16&0xFF, OpAddress);
+ SetZN16 (Work16);
+}
+
+STATIC inline void LSR8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work8 = S9xGetByte (OpAddress);
+ ICPU._Carry = Work8 & 1;
+ Work8 >>= 1;
+ S9xSetByte (Work8, OpAddress);
+ SetZN8 (Work8);
+}
+
+STATIC inline void ORA16 ()
+{
+ Registers.A.W |= S9xGetWord (OpAddress);
+ SetZN16 (Registers.A.W);
+}
+
+STATIC inline void ORA8 ()
+{
+ Registers.AL |= S9xGetByte (OpAddress);
+ SetZN8 (Registers.AL);
+}
+
+STATIC inline void A_ROL16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work32 = (Registers.A.W << 1) | CheckCarry();
+ ICPU._Carry = Work32 >= 0x10000;
+ Registers.A.W = (uint16) Work32;
+ SetZN16 ((uint16) Work32);
+}
+
+STATIC inline void A_ROL8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = Registers.AL;
+ Work16 <<= 1;
+ Work16 |= CheckCarry();
+ ICPU._Carry = Work16 >= 0x100;
+ Registers.AL = (uint8) Work16;
+ SetZN8 ((uint8) Work16);
+}
+
+STATIC inline void ROL16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work32 = S9xGetWord (OpAddress);
+ Work32 <<= 1;
+ Work32 |= CheckCarry();
+ ICPU._Carry = Work32 >= 0x10000;
+ //S9xSetWord ((uint16) Work32, OpAddress);
+ S9xSetByte((Work32>>8)&0xFF, OpAddress+1);
+ S9xSetByte(Work32&0xFF, OpAddress);
+ SetZN16 ((uint16) Work32);
+}
+
+STATIC inline void ROL8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = S9xGetByte (OpAddress);
+ Work16 <<= 1;
+ Work16 |= CheckCarry ();
+ ICPU._Carry = Work16 >= 0x100;
+ S9xSetByte ((uint8) Work16, OpAddress);
+ SetZN8 ((uint8) Work16);
+}
+
+STATIC inline void A_ROR16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work32 = Registers.A.W;
+ Work32 |= (int) CheckCarry() << 16;
+ ICPU._Carry = (uint8) (Work32 & 1);
+ Work32 >>= 1;
+ Registers.A.W = (uint16) Work32;
+ SetZN16 ((uint16) Work32);
+}
+
+STATIC inline void A_ROR8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = Registers.AL | ((uint16) CheckCarry() << 8);
+ ICPU._Carry = (uint8) Work16 & 1;
+ Work16 >>= 1;
+ Registers.AL = (uint8) Work16;
+ SetZN8 ((uint8) Work16);
+}
+
+STATIC inline void ROR16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work32 = S9xGetWord (OpAddress);
+ Work32 |= (int) CheckCarry() << 16;
+ ICPU._Carry = (uint8) (Work32 & 1);
+ Work32 >>= 1;
+ //S9xSetWord ((uint16) Work32, OpAddress);
+ S9xSetByte ( (Work32>>8)&0x00FF, OpAddress+1);
+ S9xSetByte (Work32&0x00FF, OpAddress);
+ SetZN16 ((uint16) Work32);
+}
+
+STATIC inline void ROR8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = S9xGetByte (OpAddress);
+ Work16 |= (int) CheckCarry () << 8;
+ ICPU._Carry = (uint8) (Work16 & 1);
+ Work16 >>= 1;
+ S9xSetByte ((uint8) Work16, OpAddress);
+ SetZN8 ((uint8) Work16);
+}
+
+STATIC inline void SBC16 ()
+{
+ Work16 = S9xGetWord (OpAddress);
+
+ if (CheckDecimal ())
+ {
+ A1 = (Registers.A.W) & 0xF;
+ A2 = (Registers.A.W >> 4) & 0xF;
+ A3 = (Registers.A.W >> 8) & 0xF;
+ A4 = (Registers.A.W >> 12) & 0xF;
+ W1 = Work16 & 0xF;
+ W2 = (Work16 >> 4) & 0xF;
+ W3 = (Work16 >> 8) & 0xF;
+ W4 = (Work16 >> 12) & 0xF;
+
+ A1 -= W1 + !CheckCarry ();
+ A2 -= W2;
+ A3 -= W3;
+ A4 -= W4;
+ if (A1 > 9)
+ {
+ A1 += 10;
+ A2--;
+ }
+ if (A2 > 9)
+ {
+ A2 += 10;
+ A3--;
+ }
+ if (A3 > 9)
+ {
+ A3 += 10;
+ A4--;
+ }
+ if (A4 > 9)
+ {
+ A4 += 10;
+ ClearCarry ();
+ }
+ else
+ {
+ SetCarry ();
+ }
+
+ Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1);
+ if ((Registers.A.W ^ Work16) &
+ (Registers.A.W ^ Ans16) & 0x8000)
+ SetOverflow();
+ else
+ ClearOverflow();
+ Registers.A.W = Ans16;
+ SetZN16 (Registers.A.W);
+ }
+ else
+ {
+
+ Int32 = (long) Registers.A.W - (long) Work16 + (long) CheckCarry() - 1;
+
+ ICPU._Carry = Int32 >= 0;
+
+ if ((Registers.A.W ^ Work16) &
+ (Registers.A.W ^ (uint16) Int32) & 0x8000)
+ SetOverflow();
+ else
+ ClearOverflow ();
+ Registers.A.W = (uint16) Int32;
+ SetZN16 (Registers.A.W);
+ }
+}
+
+STATIC inline void SBC8 ()
+{
+ Work8 = S9xGetByte (OpAddress);
+ if (CheckDecimal ())
+ {
+ A1 = (Registers.A.W) & 0xF;
+ A2 = (Registers.A.W >> 4) & 0xF;
+ W1 = Work8 & 0xF;
+ W2 = (Work8 >> 4) & 0xF;
+
+ A1 -= W1 + !CheckCarry ();
+ A2 -= W2;
+ if (A1 > 9)
+ {
+ A1 += 10;
+ A2--;
+ }
+ if (A2 > 9)
+ {
+ A2 += 10;
+ ClearCarry ();
+ }
+ else
+ {
+ SetCarry ();
+ }
+
+ Ans8 = (A2 << 4) | A1;
+ if ((Registers.AL ^ Work8) &
+ (Registers.AL ^ Ans8) & 0x80)
+ SetOverflow ();
+ else
+ ClearOverflow ();
+ Registers.AL = Ans8;
+ SetZN8 (Registers.AL);
+ }
+ else
+ {
+ Int16 = (short) Registers.AL - (short) Work8 + (short) CheckCarry() - 1;
+
+ ICPU._Carry = Int16 >= 0;
+ if ((Registers.AL ^ Work8) &
+ (Registers.AL ^ (uint8) Int16) & 0x80)
+ SetOverflow ();
+ else
+ ClearOverflow ();
+ Registers.AL = (uint8) Int16;
+ SetZN8 (Registers.AL);
+ }
+}
+
+STATIC inline void STA16 ()
+{
+ S9xSetWord (Registers.A.W, OpAddress);
+}
+
+STATIC inline void STA8 ()
+{
+ S9xSetByte (Registers.AL, OpAddress);
+}
+
+STATIC inline void STX16 ()
+{
+ S9xSetWord (Registers.X.W, OpAddress);
+}
+
+STATIC inline void STX8 ()
+{
+ S9xSetByte (Registers.XL, OpAddress);
+}
+
+STATIC inline void STY16 ()
+{
+ S9xSetWord (Registers.Y.W, OpAddress);
+}
+
+STATIC inline void STY8 ()
+{
+ S9xSetByte (Registers.YL, OpAddress);
+}
+
+STATIC inline void STZ16 ()
+{
+ S9xSetWord (0, OpAddress);
+}
+
+STATIC inline void STZ8 ()
+{
+ S9xSetByte (0, OpAddress);
+}
+
+STATIC inline void TSB16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = S9xGetWord (OpAddress);
+ ICPU._Zero = (Work16 & Registers.A.W) != 0;
+ Work16 |= Registers.A.W;
+ //S9xSetWord (Work16, OpAddress);
+ S9xSetByte (Work16>>8, OpAddress+1);
+ S9xSetByte (Work16&0xFF, OpAddress);
+}
+
+STATIC inline void TSB8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work8 = S9xGetByte (OpAddress);
+ ICPU._Zero = Work8 & Registers.AL;
+ Work8 |= Registers.AL;
+ S9xSetByte (Work8, OpAddress);
+}
+
+STATIC inline void TRB16 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work16 = S9xGetWord (OpAddress);
+ ICPU._Zero = (Work16 & Registers.A.W) != 0;
+ Work16 &= ~Registers.A.W;
+ //S9xSetWord (Work16, OpAddress);
+ S9xSetByte (Work16>>8, OpAddress+1);
+ S9xSetByte (Work16&0xFF, OpAddress);
+}
+
+STATIC inline void TRB8 ()
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Work8 = S9xGetByte (OpAddress);
+ ICPU._Zero = Work8 & Registers.AL;
+ Work8 &= ~Registers.AL;
+ S9xSetByte (Work8, OpAddress);
+}
+#endif
+
diff --git a/source/cpuops.cpp b/source/cpuops.cpp
new file mode 100644
index 0000000..c5adc67
--- /dev/null
+++ b/source/cpuops.cpp
@@ -0,0 +1,4443 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+/*****************************************************************************/
+/* CPU-S9xOpcodes.CPP */
+/* This file contains all the opcodes */
+/*****************************************************************************/
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "debug.h"
+#include "missing.h"
+#include "apu.h"
+#include "sa1.h"
+#include "spc7110.h"
+
+START_EXTERN_C
+extern uint8 A1, A2, A3, A4, W1, W2, W3, W4;
+extern uint8 Ans8;
+extern uint16 Ans16;
+extern uint32 Ans32;
+extern uint8 Work8;
+extern uint16 Work16;
+extern uint32 Work32;
+extern signed char Int8;
+extern short Int16;
+extern long Int32;
+END_EXTERN_C
+
+#include "cpuexec.h"
+#include "cpuaddr.h"
+#include "cpuops.h"
+#include "cpumacro.h"
+#include "apu.h"
+
+/* ADC *************************************************************************************** */
+static void Op69M1 (void)
+{
+ Immediate8 (READ);
+ ADC8 ();
+}
+
+static void Op69M0 (void)
+{
+ Immediate16 (READ);
+ ADC16 ();
+}
+
+static void Op65M1 (void)
+{
+ Direct (READ);
+ ADC8 ();
+}
+
+static void Op65M0 (void)
+{
+ Direct (READ);
+ ADC16 ();
+}
+
+static void Op75M1 (void)
+{
+ DirectIndexedX (READ);
+ ADC8 ();
+}
+
+static void Op75M0 (void)
+{
+ DirectIndexedX (READ);
+ ADC16 ();
+}
+
+static void Op72M1 (void)
+{
+ DirectIndirect (READ);
+ ADC8 ();
+}
+
+static void Op72M0 (void)
+{
+ DirectIndirect (READ);
+ ADC16 ();
+}
+
+static void Op61M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ ADC8 ();
+}
+
+static void Op61M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ ADC16 ();
+}
+
+static void Op71M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ ADC8 ();
+}
+
+static void Op71M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ ADC16 ();
+}
+
+static void Op67M1 (void)
+{
+ DirectIndirectLong (READ);
+ ADC8 ();
+}
+
+static void Op67M0 (void)
+{
+ DirectIndirectLong (READ);
+ ADC16 ();
+}
+
+static void Op77M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ ADC8 ();
+}
+
+static void Op77M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ ADC16 ();
+}
+
+static void Op6DM1 (void)
+{
+ Absolute (READ);
+ ADC8 ();
+}
+
+static void Op6DM0 (void)
+{
+ Absolute (READ);
+ ADC16 ();
+}
+
+static void Op7DM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ ADC8 ();
+}
+
+static void Op7DM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ ADC16 ();
+}
+
+static void Op79M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ ADC8 ();
+}
+
+static void Op79M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ ADC16 ();
+}
+
+static void Op6FM1 (void)
+{
+ AbsoluteLong (READ);
+ ADC8 ();
+}
+
+static void Op6FM0 (void)
+{
+ AbsoluteLong (READ);
+ ADC16 ();
+}
+
+static void Op7FM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ ADC8 ();
+}
+
+static void Op7FM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ ADC16 ();
+}
+
+static void Op63M1 (void)
+{
+ StackRelative (READ);
+ ADC8 ();
+}
+
+static void Op63M0 (void)
+{
+ StackRelative (READ);
+ ADC16 ();
+}
+
+static void Op73M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ ADC8 ();
+}
+
+static void Op73M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ ADC16 ();
+}
+
+/**********************************************************************************************/
+
+/* AND *************************************************************************************** */
+static void Op29M1 (void)
+{
+ Registers.AL &= *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ SetZN8 (Registers.AL);
+}
+
+static void Op29M0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Registers.A.W &= *(uint16 *) CPU.PC;
+#else
+ Registers.A.W &= *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ SetZN16 (Registers.A.W);
+}
+
+static void Op25M1 (void)
+{
+ Direct (READ);
+ AND8 ();
+}
+
+static void Op25M0 (void)
+{
+ Direct (READ);
+ AND16 ();
+}
+
+static void Op35M1 (void)
+{
+ DirectIndexedX (READ);
+ AND8 ();
+}
+
+static void Op35M0 (void)
+{
+ DirectIndexedX (READ);
+ AND16 ();
+}
+
+static void Op32M1 (void)
+{
+ DirectIndirect (READ);
+ AND8 ();
+}
+
+static void Op32M0 (void)
+{
+ DirectIndirect (READ);
+ AND16 ();
+}
+
+static void Op21M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ AND8 ();
+}
+
+static void Op21M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ AND16 ();
+}
+
+static void Op31M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ AND8 ();
+}
+
+static void Op31M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ AND16 ();
+}
+
+static void Op27M1 (void)
+{
+ DirectIndirectLong (READ);
+ AND8 ();
+}
+
+static void Op27M0 (void)
+{
+ DirectIndirectLong (READ);
+ AND16 ();
+}
+
+static void Op37M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ AND8 ();
+}
+
+static void Op37M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ AND16 ();
+}
+
+static void Op2DM1 (void)
+{
+ Absolute (READ);
+ AND8 ();
+}
+
+static void Op2DM0 (void)
+{
+ Absolute (READ);
+ AND16 ();
+}
+
+static void Op3DM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ AND8 ();
+}
+
+static void Op3DM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ AND16 ();
+}
+
+static void Op39M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ AND8 ();
+}
+
+static void Op39M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ AND16 ();
+}
+
+static void Op2FM1 (void)
+{
+ AbsoluteLong (READ);
+ AND8 ();
+}
+
+static void Op2FM0 (void)
+{
+ AbsoluteLong (READ);
+ AND16 ();
+}
+
+static void Op3FM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ AND8 ();
+}
+
+static void Op3FM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ AND16 ();
+}
+
+static void Op23M1 (void)
+{
+ StackRelative (READ);
+ AND8 ();
+}
+
+static void Op23M0 (void)
+{
+ StackRelative (READ);
+ AND16 ();
+}
+
+static void Op33M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ AND8 ();
+}
+
+static void Op33M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ AND16 ();
+}
+/**********************************************************************************************/
+
+/* ASL *************************************************************************************** */
+static void Op0AM1 (void)
+{
+ A_ASL8 ();
+}
+
+static void Op0AM0 (void)
+{
+ A_ASL16 ();
+}
+
+static void Op06M1 (void)
+{
+ Direct (MODIFY);
+ ASL8 ();
+}
+
+static void Op06M0 (void)
+{
+ Direct (MODIFY);
+ ASL16 ();
+}
+
+static void Op16M1 (void)
+{
+ DirectIndexedX (MODIFY);
+ ASL8 ();
+}
+
+static void Op16M0 (void)
+{
+ DirectIndexedX (MODIFY);
+ ASL16 ();
+}
+
+static void Op0EM1 (void)
+{
+ Absolute (MODIFY);
+ ASL8 ();
+}
+
+static void Op0EM0 (void)
+{
+ Absolute (MODIFY);
+ ASL16 ();
+}
+
+static void Op1EM1 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ ASL8 ();
+}
+
+static void Op1EM0 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ ASL16 ();
+}
+/**********************************************************************************************/
+
+/* BIT *************************************************************************************** */
+static void Op89M1 (void)
+{
+ ICPU._Zero = Registers.AL & *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+}
+
+static void Op89M0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ ICPU._Zero = (Registers.A.W & *(uint16 *) CPU.PC) != 0;
+#else
+ ICPU._Zero = (Registers.A.W & (*CPU.PC + (*(CPU.PC + 1) << 8))) != 0;
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ CPU.PC += 2;
+}
+
+static void Op24M1 (void)
+{
+ Direct (READ);
+ BIT8 ();
+}
+
+static void Op24M0 (void)
+{
+ Direct (READ);
+ BIT16 ();
+}
+
+static void Op34M1 (void)
+{
+ DirectIndexedX (READ);
+ BIT8 ();
+}
+
+static void Op34M0 (void)
+{
+ DirectIndexedX (READ);
+ BIT16 ();
+}
+
+static void Op2CM1 (void)
+{
+ Absolute (READ);
+ BIT8 ();
+}
+
+static void Op2CM0 (void)
+{
+ Absolute (READ);
+ BIT16 ();
+}
+
+static void Op3CM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ BIT8 ();
+}
+
+static void Op3CM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ BIT16 ();
+}
+/**********************************************************************************************/
+
+/* CMP *************************************************************************************** */
+static void OpC9M1 (void)
+{
+ Int32 = (int) Registers.AL - (int) *CPU.PC++;
+ ICPU._Carry = Int32 >= 0;
+ SetZN8 ((uint8) Int32);
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+}
+
+static void OpC9M0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Int32 = (long) Registers.A.W - (long) *(uint16 *) CPU.PC;
+#else
+ Int32 = (long) Registers.A.W -
+ (long) (*CPU.PC + (*(CPU.PC + 1) << 8));
+#endif
+ ICPU._Carry = Int32 >= 0;
+ SetZN16 ((uint16) Int32);
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+}
+
+static void OpC5M1 (void)
+{
+ Direct (READ);
+ CMP8 ();
+}
+
+static void OpC5M0 (void)
+{
+ Direct (READ);
+ CMP16 ();
+}
+
+static void OpD5M1 (void)
+{
+ DirectIndexedX (READ);
+ CMP8 ();
+}
+
+static void OpD5M0 (void)
+{
+ DirectIndexedX (READ);
+ CMP16 ();
+}
+
+static void OpD2M1 (void)
+{
+ DirectIndirect (READ);
+ CMP8 ();
+}
+
+static void OpD2M0 (void)
+{
+ DirectIndirect (READ);
+ CMP16 ();
+}
+
+static void OpC1M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ CMP8 ();
+}
+
+static void OpC1M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ CMP16 ();
+}
+
+static void OpD1M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ CMP8 ();
+}
+
+static void OpD1M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ CMP16 ();
+}
+
+static void OpC7M1 (void)
+{
+ DirectIndirectLong (READ);
+ CMP8 ();
+}
+
+static void OpC7M0 (void)
+{
+ DirectIndirectLong (READ);
+ CMP16 ();
+}
+
+static void OpD7M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ CMP8 ();
+}
+
+static void OpD7M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ CMP16 ();
+}
+
+static void OpCDM1 (void)
+{
+ Absolute (READ);
+ CMP8 ();
+}
+
+static void OpCDM0 (void)
+{
+ Absolute (READ);
+ CMP16 ();
+}
+
+static void OpDDM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ CMP8 ();
+}
+
+static void OpDDM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ CMP16 ();
+}
+
+static void OpD9M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ CMP8 ();
+}
+
+static void OpD9M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ CMP16 ();
+}
+
+static void OpCFM1 (void)
+{
+ AbsoluteLong (READ);
+ CMP8 ();
+}
+
+static void OpCFM0 (void)
+{
+ AbsoluteLong (READ);
+ CMP16 ();
+}
+
+static void OpDFM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ CMP8 ();
+}
+
+static void OpDFM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ CMP16 ();
+}
+
+static void OpC3M1 (void)
+{
+ StackRelative (READ);
+ CMP8 ();
+}
+
+static void OpC3M0 (void)
+{
+ StackRelative (READ);
+ CMP16 ();
+}
+
+static void OpD3M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ CMP8 ();
+}
+
+static void OpD3M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ CMP16 ();
+}
+
+/**********************************************************************************************/
+
+/* CMX *************************************************************************************** */
+static void OpE0X1 (void)
+{
+ Int32 = (int) Registers.XL - (int) *CPU.PC++;
+ ICPU._Carry = Int32 >= 0;
+ SetZN8 ((uint8) Int32);
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+}
+
+static void OpE0X0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Int32 = (long) Registers.X.W - (long) *(uint16 *) CPU.PC;
+#else
+ Int32 = (long) Registers.X.W -
+ (long) (*CPU.PC + (*(CPU.PC + 1) << 8));
+#endif
+ ICPU._Carry = Int32 >= 0;
+ SetZN16 ((uint16) Int32);
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+}
+
+static void OpE4X1 (void)
+{
+ Direct (READ);
+ CMX8 ();
+}
+
+static void OpE4X0 (void)
+{
+ Direct (READ);
+ CMX16 ();
+}
+
+static void OpECX1 (void)
+{
+ Absolute (READ);
+ CMX8 ();
+}
+
+static void OpECX0 (void)
+{
+ Absolute (READ);
+ CMX16 ();
+}
+
+/**********************************************************************************************/
+
+/* CMY *************************************************************************************** */
+static void OpC0X1 (void)
+{
+ Int32 = (int) Registers.YL - (int) *CPU.PC++;
+ ICPU._Carry = Int32 >= 0;
+ SetZN8 ((uint8) Int32);
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+}
+
+static void OpC0X0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Int32 = (long) Registers.Y.W - (long) *(uint16 *) CPU.PC;
+#else
+ Int32 = (long) Registers.Y.W -
+ (long) (*CPU.PC + (*(CPU.PC + 1) << 8));
+#endif
+ ICPU._Carry = Int32 >= 0;
+ SetZN16 ((uint16) Int32);
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+}
+
+static void OpC4X1 (void)
+{
+ Direct (READ);
+ CMY8 ();
+}
+
+static void OpC4X0 (void)
+{
+ Direct (READ);
+ CMY16 ();
+}
+
+static void OpCCX1 (void)
+{
+ Absolute (READ);
+ CMY8 ();
+}
+
+static void OpCCX0 (void)
+{
+ Absolute (READ);
+ CMY16 ();
+}
+
+/**********************************************************************************************/
+
+/* DEC *************************************************************************************** */
+static void Op3AM1 (void)
+{
+ A_DEC8 ();
+}
+
+static void Op3AM0 (void)
+{
+ A_DEC16 ();
+}
+
+static void OpC6M1 (void)
+{
+ Direct (MODIFY);
+ DEC8 ();
+}
+
+static void OpC6M0 (void)
+{
+ Direct (MODIFY);
+ DEC16 ();
+}
+
+static void OpD6M1 (void)
+{
+ DirectIndexedX (MODIFY);
+ DEC8 ();
+}
+
+static void OpD6M0 (void)
+{
+ DirectIndexedX (MODIFY);
+ DEC16 ();
+}
+
+static void OpCEM1 (void)
+{
+ Absolute (MODIFY);
+ DEC8 ();
+}
+
+static void OpCEM0 (void)
+{
+ Absolute (MODIFY);
+ DEC16 ();
+}
+
+static void OpDEM1 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ DEC8 ();
+}
+
+static void OpDEM0 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ DEC16 ();
+}
+
+/**********************************************************************************************/
+
+/* EOR *************************************************************************************** */
+static void Op49M1 (void)
+{
+ Registers.AL ^= *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ SetZN8 (Registers.AL);
+}
+
+static void Op49M0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Registers.A.W ^= *(uint16 *) CPU.PC;
+#else
+ Registers.A.W ^= *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ SetZN16 (Registers.A.W);
+}
+
+static void Op45M1 (void)
+{
+ Direct (READ);
+ EOR8 ();
+}
+
+static void Op45M0 (void)
+{
+ Direct (READ);
+ EOR16 ();
+}
+
+static void Op55M1 (void)
+{
+ DirectIndexedX (READ);
+ EOR8 ();
+}
+
+static void Op55M0 (void)
+{
+ DirectIndexedX (READ);
+ EOR16 ();
+}
+
+static void Op52M1 (void)
+{
+ DirectIndirect (READ);
+ EOR8 ();
+}
+
+static void Op52M0 (void)
+{
+ DirectIndirect (READ);
+ EOR16 ();
+}
+
+static void Op41M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ EOR8 ();
+}
+
+static void Op41M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ EOR16 ();
+}
+
+static void Op51M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ EOR8 ();
+}
+
+static void Op51M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ EOR16 ();
+}
+
+static void Op47M1 (void)
+{
+ DirectIndirectLong (READ);
+ EOR8 ();
+}
+
+static void Op47M0 (void)
+{
+ DirectIndirectLong (READ);
+ EOR16 ();
+}
+
+static void Op57M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ EOR8 ();
+}
+
+static void Op57M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ EOR16 ();
+}
+
+static void Op4DM1 (void)
+{
+ Absolute (READ);
+ EOR8 ();
+}
+
+static void Op4DM0 (void)
+{
+ Absolute (READ);
+ EOR16 ();
+}
+
+static void Op5DM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ EOR8 ();
+}
+
+static void Op5DM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ EOR16 ();
+}
+
+static void Op59M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ EOR8 ();
+}
+
+static void Op59M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ EOR16 ();
+}
+
+static void Op4FM1 (void)
+{
+ AbsoluteLong (READ);
+ EOR8 ();
+}
+
+static void Op4FM0 (void)
+{
+ AbsoluteLong (READ);
+ EOR16 ();
+}
+
+static void Op5FM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ EOR8 ();
+}
+
+static void Op5FM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ EOR16 ();
+}
+
+static void Op43M1 (void)
+{
+ StackRelative (READ);
+ EOR8 ();
+}
+
+static void Op43M0 (void)
+{
+ StackRelative (READ);
+ EOR16 ();
+}
+
+static void Op53M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ EOR8 ();
+}
+
+static void Op53M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ EOR16 ();
+}
+
+/**********************************************************************************************/
+
+/* INC *************************************************************************************** */
+static void Op1AM1 (void)
+{
+ A_INC8 ();
+}
+
+static void Op1AM0 (void)
+{
+ A_INC16 ();
+}
+
+static void OpE6M1 (void)
+{
+ Direct (MODIFY);
+ INC8 ();
+}
+
+static void OpE6M0 (void)
+{
+ Direct (MODIFY);
+ INC16 ();
+}
+
+static void OpF6M1 (void)
+{
+ DirectIndexedX (MODIFY);
+ INC8 ();
+}
+
+static void OpF6M0 (void)
+{
+ DirectIndexedX (MODIFY);
+ INC16 ();
+}
+
+static void OpEEM1 (void)
+{
+ Absolute (MODIFY);
+ INC8 ();
+}
+
+static void OpEEM0 (void)
+{
+ Absolute (MODIFY);
+ INC16 ();
+}
+
+static void OpFEM1 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ INC8 ();
+}
+
+static void OpFEM0 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ INC16 ();
+}
+
+/**********************************************************************************************/
+/* LDA *************************************************************************************** */
+static void OpA9M1 (void)
+{
+ Registers.AL = *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ SetZN8 (Registers.AL);
+}
+
+static void OpA9M0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Registers.A.W = *(uint16 *) CPU.PC;
+#else
+ Registers.A.W = *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ SetZN16 (Registers.A.W);
+}
+
+static void OpA5M1 (void)
+{
+ Direct (READ);
+ LDA8 ();
+}
+
+static void OpA5M0 (void)
+{
+ Direct (READ);
+ LDA16 ();
+}
+
+static void OpB5M1 (void)
+{
+ DirectIndexedX (READ);
+ LDA8 ();
+}
+
+static void OpB5M0 (void)
+{
+ DirectIndexedX (READ);
+ LDA16 ();
+}
+
+static void OpB2M1 (void)
+{
+ DirectIndirect (READ);
+ LDA8 ();
+}
+
+static void OpB2M0 (void)
+{
+ DirectIndirect (READ);
+ LDA16 ();
+}
+
+static void OpA1M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ LDA8 ();
+}
+
+static void OpA1M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ LDA16 ();
+}
+
+static void OpB1M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ LDA8 ();
+}
+
+static void OpB1M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ LDA16 ();
+}
+
+static void OpA7M1 (void)
+{
+ DirectIndirectLong (READ);
+ LDA8 ();
+}
+
+static void OpA7M0 (void)
+{
+ DirectIndirectLong (READ);
+ LDA16 ();
+}
+
+static void OpB7M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ LDA8 ();
+}
+
+static void OpB7M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ LDA16 ();
+}
+
+static void OpADM1 (void)
+{
+ Absolute (READ);
+ LDA8 ();
+}
+
+static void OpADM0 (void)
+{
+ Absolute (READ);
+ LDA16 ();
+}
+
+static void OpBDM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ LDA8 ();
+}
+
+static void OpBDM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ LDA16 ();
+}
+
+static void OpB9M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ LDA8 ();
+}
+
+static void OpB9M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ LDA16 ();
+}
+
+static void OpAFM1 (void)
+{
+ AbsoluteLong (READ);
+ LDA8 ();
+}
+
+static void OpAFM0 (void)
+{
+ AbsoluteLong (READ);
+ LDA16 ();
+}
+
+static void OpBFM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ LDA8 ();
+}
+
+static void OpBFM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ LDA16 ();
+}
+
+static void OpA3M1 (void)
+{
+ StackRelative (READ);
+ LDA8 ();
+}
+
+static void OpA3M0 (void)
+{
+ StackRelative (READ);
+ LDA16 ();
+}
+
+static void OpB3M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ LDA8 ();
+}
+
+static void OpB3M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ LDA16 ();
+}
+
+/**********************************************************************************************/
+
+/* LDX *************************************************************************************** */
+static void OpA2X1 (void)
+{
+ Registers.XL = *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ SetZN8 (Registers.XL);
+}
+
+static void OpA2X0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Registers.X.W = *(uint16 *) CPU.PC;
+#else
+ Registers.X.W = *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ SetZN16 (Registers.X.W);
+}
+
+static void OpA6X1 (void)
+{
+ Direct (READ);
+ LDX8 ();
+}
+
+static void OpA6X0 (void)
+{
+ Direct (READ);
+ LDX16 ();
+}
+
+static void OpB6X1 (void)
+{
+ DirectIndexedY (READ);
+ LDX8 ();
+}
+
+static void OpB6X0 (void)
+{
+ DirectIndexedY (READ);
+ LDX16 ();
+}
+
+static void OpAEX1 (void)
+{
+ Absolute (READ);
+ LDX8 ();
+}
+
+static void OpAEX0 (void)
+{
+ Absolute (READ);
+ LDX16 ();
+}
+
+static void OpBEX1 (void)
+{
+ AbsoluteIndexedY (READ);
+ LDX8 ();
+}
+
+static void OpBEX0 (void)
+{
+ AbsoluteIndexedY (READ);
+ LDX16 ();
+}
+/**********************************************************************************************/
+
+/* LDY *************************************************************************************** */
+static void OpA0X1 (void)
+{
+ Registers.YL = *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ SetZN8 (Registers.YL);
+}
+
+static void OpA0X0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Registers.Y.W = *(uint16 *) CPU.PC;
+#else
+ Registers.Y.W = *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ SetZN16 (Registers.Y.W);
+}
+
+static void OpA4X1 (void)
+{
+ Direct (READ);
+ LDY8 ();
+}
+
+static void OpA4X0 (void)
+{
+ Direct (READ);
+ LDY16 ();
+}
+
+static void OpB4X1 (void)
+{
+ DirectIndexedX (READ);
+ LDY8 ();
+}
+
+static void OpB4X0 (void)
+{
+ DirectIndexedX (READ);
+ LDY16 ();
+}
+
+static void OpACX1 (void)
+{
+ Absolute (READ);
+ LDY8 ();
+}
+
+static void OpACX0 (void)
+{
+ Absolute (READ);
+ LDY16 ();
+}
+
+static void OpBCX1 (void)
+{
+ AbsoluteIndexedX (READ);
+ LDY8 ();
+}
+
+static void OpBCX0 (void)
+{
+ AbsoluteIndexedX (READ);
+ LDY16 ();
+}
+/**********************************************************************************************/
+
+/* LSR *************************************************************************************** */
+static void Op4AM1 (void)
+{
+ A_LSR8 ();
+}
+
+static void Op4AM0 (void)
+{
+ A_LSR16 ();
+}
+
+static void Op46M1 (void)
+{
+ Direct (MODIFY);
+ LSR8 ();
+}
+
+static void Op46M0 (void)
+{
+ Direct (MODIFY);
+ LSR16 ();
+}
+
+static void Op56M1 (void)
+{
+ DirectIndexedX (MODIFY);
+ LSR8 ();
+}
+
+static void Op56M0 (void)
+{
+ DirectIndexedX (MODIFY);
+ LSR16 ();
+}
+
+static void Op4EM1 (void)
+{
+ Absolute (MODIFY);
+ LSR8 ();
+}
+
+static void Op4EM0 (void)
+{
+ Absolute (MODIFY);
+ LSR16 ();
+}
+
+static void Op5EM1 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ LSR8 ();
+}
+
+static void Op5EM0 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ LSR16 ();
+}
+
+/**********************************************************************************************/
+
+/* ORA *************************************************************************************** */
+static void Op09M1 (void)
+{
+ Registers.AL |= *CPU.PC++;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed;
+#endif
+ SetZN8 (Registers.AL);
+}
+
+static void Op09M0 (void)
+{
+#ifdef FAST_LSB_WORD_ACCESS
+ Registers.A.W |= *(uint16 *) CPU.PC;
+#else
+ Registers.A.W |= *CPU.PC + (*(CPU.PC + 1) << 8);
+#endif
+ CPU.PC += 2;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2;
+#endif
+ SetZN16 (Registers.A.W);
+}
+
+static void Op05M1 (void)
+{
+ Direct (READ);
+ ORA8 ();
+}
+
+static void Op05M0 (void)
+{
+ Direct (READ);
+ ORA16 ();
+}
+
+static void Op15M1 (void)
+{
+ DirectIndexedX (READ);
+ ORA8 ();
+}
+
+static void Op15M0 (void)
+{
+ DirectIndexedX (READ);
+ ORA16 ();
+}
+
+static void Op12M1 (void)
+{
+ DirectIndirect (READ);
+ ORA8 ();
+}
+
+static void Op12M0 (void)
+{
+ DirectIndirect (READ);
+ ORA16 ();
+}
+
+static void Op01M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ ORA8 ();
+}
+
+static void Op01M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ ORA16 ();
+}
+
+static void Op11M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ ORA8 ();
+}
+
+static void Op11M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ ORA16 ();
+}
+
+static void Op07M1 (void)
+{
+ DirectIndirectLong (READ);
+ ORA8 ();
+}
+
+static void Op07M0 (void)
+{
+ DirectIndirectLong (READ);
+ ORA16 ();
+}
+
+static void Op17M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ ORA8 ();
+}
+
+static void Op17M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ ORA16 ();
+}
+
+static void Op0DM1 (void)
+{
+ Absolute (READ);
+ ORA8 ();
+}
+
+static void Op0DM0 (void)
+{
+ Absolute (READ);
+ ORA16 ();
+}
+
+static void Op1DM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ ORA8 ();
+}
+
+static void Op1DM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ ORA16 ();
+}
+
+static void Op19M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ ORA8 ();
+}
+
+static void Op19M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ ORA16 ();
+}
+
+static void Op0FM1 (void)
+{
+ AbsoluteLong (READ);
+ ORA8 ();
+}
+
+static void Op0FM0 (void)
+{
+ AbsoluteLong (READ);
+ ORA16 ();
+}
+
+static void Op1FM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ ORA8 ();
+}
+
+static void Op1FM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ ORA16 ();
+}
+
+static void Op03M1 (void)
+{
+ StackRelative (READ);
+ ORA8 ();
+}
+
+static void Op03M0 (void)
+{
+ StackRelative (READ);
+ ORA16 ();
+}
+
+static void Op13M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ ORA8 ();
+}
+
+static void Op13M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ ORA16 ();
+}
+
+/**********************************************************************************************/
+
+/* ROL *************************************************************************************** */
+static void Op2AM1 (void)
+{
+ A_ROL8 ();
+}
+
+static void Op2AM0 (void)
+{
+ A_ROL16 ();
+}
+
+static void Op26M1 (void)
+{
+ Direct (MODIFY);
+ ROL8 ();
+}
+
+static void Op26M0 (void)
+{
+ Direct (MODIFY);
+ ROL16 ();
+}
+
+static void Op36M1 (void)
+{
+ DirectIndexedX (MODIFY);
+ ROL8 ();
+}
+
+static void Op36M0 (void)
+{
+ DirectIndexedX (MODIFY);
+ ROL16 ();
+}
+
+static void Op2EM1 (void)
+{
+ Absolute (MODIFY);
+ ROL8 ();
+}
+
+static void Op2EM0 (void)
+{
+ Absolute (MODIFY);
+ ROL16 ();
+}
+
+static void Op3EM1 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ ROL8 ();
+}
+
+static void Op3EM0 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ ROL16 ();
+}
+/**********************************************************************************************/
+
+/* ROR *************************************************************************************** */
+static void Op6AM1 (void)
+{
+ A_ROR8 ();
+}
+
+static void Op6AM0 (void)
+{
+ A_ROR16 ();
+}
+
+static void Op66M1 (void)
+{
+ Direct (MODIFY);
+ ROR8 ();
+}
+
+static void Op66M0 (void)
+{
+ Direct (MODIFY);
+ ROR16 ();
+}
+
+static void Op76M1 (void)
+{
+ DirectIndexedX (MODIFY);
+ ROR8 ();
+}
+
+static void Op76M0 (void)
+{
+ DirectIndexedX (MODIFY);
+ ROR16 ();
+}
+
+static void Op6EM1 (void)
+{
+ Absolute (MODIFY);
+ ROR8 ();
+}
+
+static void Op6EM0 (void)
+{
+ Absolute (MODIFY);
+ ROR16 ();
+}
+
+static void Op7EM1 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ ROR8 ();
+}
+
+static void Op7EM0 (void)
+{
+ AbsoluteIndexedX (MODIFY);
+ ROR16 ();
+}
+/**********************************************************************************************/
+
+/* SBC *************************************************************************************** */
+static void OpE9M1 (void)
+{
+ Immediate8 (READ);
+ SBC8 ();
+}
+
+static void OpE9M0 (void)
+{
+ Immediate16 (READ);
+ SBC16 ();
+}
+
+static void OpE5M1 (void)
+{
+ Direct (READ);
+ SBC8 ();
+}
+
+static void OpE5M0 (void)
+{
+ Direct (READ);
+ SBC16 ();
+}
+
+static void OpF5M1 (void)
+{
+ DirectIndexedX (READ);
+ SBC8 ();
+}
+
+static void OpF5M0 (void)
+{
+ DirectIndexedX (READ);
+ SBC16 ();
+}
+
+static void OpF2M1 (void)
+{
+ DirectIndirect (READ);
+ SBC8 ();
+}
+
+static void OpF2M0 (void)
+{
+ DirectIndirect (READ);
+ SBC16 ();
+}
+
+static void OpE1M1 (void)
+{
+ DirectIndexedIndirect (READ);
+ SBC8 ();
+}
+
+static void OpE1M0 (void)
+{
+ DirectIndexedIndirect (READ);
+ SBC16 ();
+}
+
+static void OpF1M1 (void)
+{
+ DirectIndirectIndexed (READ);
+ SBC8 ();
+}
+
+static void OpF1M0 (void)
+{
+ DirectIndirectIndexed (READ);
+ SBC16 ();
+}
+
+static void OpE7M1 (void)
+{
+ DirectIndirectLong (READ);
+ SBC8 ();
+}
+
+static void OpE7M0 (void)
+{
+ DirectIndirectLong (READ);
+ SBC16 ();
+}
+
+static void OpF7M1 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ SBC8 ();
+}
+
+static void OpF7M0 (void)
+{
+ DirectIndirectIndexedLong (READ);
+ SBC16 ();
+}
+
+static void OpEDM1 (void)
+{
+ Absolute (READ);
+ SBC8 ();
+}
+
+static void OpEDM0 (void)
+{
+ Absolute (READ);
+ SBC16 ();
+}
+
+static void OpFDM1 (void)
+{
+ AbsoluteIndexedX (READ);
+ SBC8 ();
+}
+
+static void OpFDM0 (void)
+{
+ AbsoluteIndexedX (READ);
+ SBC16 ();
+}
+
+static void OpF9M1 (void)
+{
+ AbsoluteIndexedY (READ);
+ SBC8 ();
+}
+
+static void OpF9M0 (void)
+{
+ AbsoluteIndexedY (READ);
+ SBC16 ();
+}
+
+static void OpEFM1 (void)
+{
+ AbsoluteLong (READ);
+ SBC8 ();
+}
+
+static void OpEFM0 (void)
+{
+ AbsoluteLong (READ);
+ SBC16 ();
+}
+
+static void OpFFM1 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ SBC8 ();
+}
+
+static void OpFFM0 (void)
+{
+ AbsoluteLongIndexedX (READ);
+ SBC16 ();
+}
+
+static void OpE3M1 (void)
+{
+ StackRelative (READ);
+ SBC8 ();
+}
+
+static void OpE3M0 (void)
+{
+ StackRelative (READ);
+ SBC16 ();
+}
+
+static void OpF3M1 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ SBC8 ();
+}
+
+static void OpF3M0 (void)
+{
+ StackRelativeIndirectIndexed (READ);
+ SBC16 ();
+}
+/**********************************************************************************************/
+
+/* STA *************************************************************************************** */
+static void Op85M1 (void)
+{
+ Direct (WRITE);
+ STA8 ();
+}
+
+static void Op85M0 (void)
+{
+ Direct (WRITE);
+ STA16 ();
+}
+
+static void Op95M1 (void)
+{
+ DirectIndexedX (WRITE);
+ STA8 ();
+}
+
+static void Op95M0 (void)
+{
+ DirectIndexedX (WRITE);
+ STA16 ();
+}
+
+static void Op92M1 (void)
+{
+ DirectIndirect (WRITE);
+ STA8 ();
+}
+
+static void Op92M0 (void)
+{
+ DirectIndirect (WRITE);
+ STA16 ();
+}
+
+static void Op81M1 (void)
+{
+ DirectIndexedIndirect (WRITE);
+ STA8 ();
+#ifdef noVAR_CYCLES
+ if (CheckIndex ())
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op81M0 (void)
+{
+ DirectIndexedIndirect (WRITE);
+ STA16 ();
+#ifdef noVAR_CYCLES
+ if (CheckIndex ())
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op91M1 (void)
+{
+ DirectIndirectIndexed (WRITE);
+ STA8 ();
+}
+
+static void Op91M0 (void)
+{
+ DirectIndirectIndexed (WRITE);
+ STA16 ();
+}
+
+static void Op87M1 (void)
+{
+ DirectIndirectLong (WRITE);
+ STA8 ();
+}
+
+static void Op87M0 (void)
+{
+ DirectIndirectLong (WRITE);
+ STA16 ();
+}
+
+static void Op97M1 (void)
+{
+ DirectIndirectIndexedLong (WRITE);
+ STA8 ();
+}
+
+static void Op97M0 (void)
+{
+ DirectIndirectIndexedLong (WRITE);
+ STA16 ();
+}
+
+static void Op8DM1 (void)
+{
+ Absolute (WRITE);
+ STA8 ();
+}
+
+static void Op8DM0 (void)
+{
+ Absolute (WRITE);
+ STA16 ();
+}
+
+static void Op9DM1 (void)
+{
+ AbsoluteIndexedX (WRITE);
+ STA8 ();
+}
+
+static void Op9DM0 (void)
+{
+ AbsoluteIndexedX (WRITE);
+ STA16 ();
+}
+
+static void Op99M1 (void)
+{
+ AbsoluteIndexedY (WRITE);
+ STA8 ();
+}
+
+static void Op99M0 (void)
+{
+ AbsoluteIndexedY (WRITE);
+ STA16 ();
+}
+
+static void Op8FM1 (void)
+{
+ AbsoluteLong (WRITE);
+ STA8 ();
+}
+
+static void Op8FM0 (void)
+{
+ AbsoluteLong (WRITE);
+ STA16 ();
+}
+
+static void Op9FM1 (void)
+{
+ AbsoluteLongIndexedX (WRITE);
+ STA8 ();
+}
+
+static void Op9FM0 (void)
+{
+ AbsoluteLongIndexedX (WRITE);
+ STA16 ();
+}
+
+static void Op83M1 (void)
+{
+ StackRelative (WRITE);
+ STA8 ();
+}
+
+static void Op83M0 (void)
+{
+ StackRelative (WRITE);
+ STA16 ();
+}
+
+static void Op93M1 (void)
+{
+ StackRelativeIndirectIndexed (WRITE);
+ STA8 ();
+}
+
+static void Op93M0 (void)
+{
+ StackRelativeIndirectIndexed (WRITE);
+ STA16 ();
+}
+/**********************************************************************************************/
+
+/* STX *************************************************************************************** */
+static void Op86X1 (void)
+{
+ Direct (WRITE);
+ STX8 ();
+}
+
+static void Op86X0 (void)
+{
+ Direct (WRITE);
+ STX16 ();
+}
+
+static void Op96X1 (void)
+{
+ DirectIndexedY (WRITE);
+ STX8 ();
+}
+
+static void Op96X0 (void)
+{
+ DirectIndexedY (WRITE);
+ STX16 ();
+}
+
+static void Op8EX1 (void)
+{
+ Absolute (WRITE);
+ STX8 ();
+}
+
+static void Op8EX0 (void)
+{
+ Absolute (WRITE);
+ STX16 ();
+}
+/**********************************************************************************************/
+
+/* STY *************************************************************************************** */
+static void Op84X1 (void)
+{
+ Direct (WRITE);
+ STY8 ();
+}
+
+static void Op84X0 (void)
+{
+ Direct (WRITE);
+ STY16 ();
+}
+
+static void Op94X1 (void)
+{
+ DirectIndexedX (WRITE);
+ STY8 ();
+}
+
+static void Op94X0 (void)
+{
+ DirectIndexedX (WRITE);
+ STY16 ();
+}
+
+static void Op8CX1 (void)
+{
+ Absolute (WRITE);
+ STY8 ();
+}
+
+static void Op8CX0 (void)
+{
+ Absolute (WRITE);
+ STY16 ();
+}
+/**********************************************************************************************/
+
+/* STZ *************************************************************************************** */
+static void Op64M1 (void)
+{
+ Direct (WRITE);
+ STZ8 ();
+}
+
+static void Op64M0 (void)
+{
+ Direct (WRITE);
+ STZ16 ();
+}
+
+static void Op74M1 (void)
+{
+ DirectIndexedX (WRITE);
+ STZ8 ();
+}
+
+static void Op74M0 (void)
+{
+ DirectIndexedX (WRITE);
+ STZ16 ();
+}
+
+static void Op9CM1 (void)
+{
+ Absolute (WRITE);
+ STZ8 ();
+}
+
+static void Op9CM0 (void)
+{
+ Absolute (WRITE);
+ STZ16 ();
+}
+
+static void Op9EM1 (void)
+{
+ AbsoluteIndexedX (WRITE);
+ STZ8 ();
+}
+
+static void Op9EM0 (void)
+{
+ AbsoluteIndexedX (WRITE);
+ STZ16 ();
+}
+
+/**********************************************************************************************/
+
+/* TRB *************************************************************************************** */
+static void Op14M1 (void)
+{
+ Direct (MODIFY);
+ TRB8 ();
+}
+
+static void Op14M0 (void)
+{
+ Direct (MODIFY);
+ TRB16 ();
+}
+
+static void Op1CM1 (void)
+{
+ Absolute (MODIFY);
+ TRB8 ();
+}
+
+static void Op1CM0 (void)
+{
+ Absolute (MODIFY);
+ TRB16 ();
+}
+/**********************************************************************************************/
+
+/* TSB *************************************************************************************** */
+static void Op04M1 (void)
+{
+ Direct (MODIFY);
+ TSB8 ();
+}
+
+static void Op04M0 (void)
+{
+ Direct (MODIFY);
+ TSB16 ();
+}
+
+static void Op0CM1 (void)
+{
+ Absolute (MODIFY);
+ TSB8 ();
+}
+
+static void Op0CM0 (void)
+{
+ Absolute (MODIFY);
+ TSB16 ();
+}
+
+/**********************************************************************************************/
+
+/* Branch Instructions *********************************************************************** */
+#ifndef SA1_OPCODES
+#define BranchCheck0()\
+ if( CPU.BranchSkip)\
+ {\
+ CPU.BranchSkip = FALSE;\
+ if (!Settings.SoundSkipMethod)\
+ if( CPU.PC - CPU.PCBase > OpAddress)\
+ return;\
+ }
+
+#define BranchCheck1()\
+ if( CPU.BranchSkip)\
+ {\
+ CPU.BranchSkip = FALSE;\
+ if (!Settings.SoundSkipMethod) {\
+ if( CPU.PC - CPU.PCBase > OpAddress)\
+ return;\
+ } else \
+ if (Settings.SoundSkipMethod == 1)\
+ return;\
+ if (Settings.SoundSkipMethod == 3)\
+ if( CPU.PC - CPU.PCBase > OpAddress)\
+ return;\
+ else\
+ CPU.PC = CPU.PCBase + OpAddress;\
+ }
+
+#define BranchCheck2()\
+ if( CPU.BranchSkip)\
+ {\
+ CPU.BranchSkip = FALSE;\
+ if (!Settings.SoundSkipMethod) {\
+ if( CPU.PC - CPU.PCBase > OpAddress)\
+ return;\
+ } else \
+ if (Settings.SoundSkipMethod == 1)\
+ CPU.PC = CPU.PCBase + OpAddress;\
+ if (Settings.SoundSkipMethod == 3)\
+ if (CPU.PC - CPU.PCBase > OpAddress)\
+ return;\
+ else\
+ CPU.PC = CPU.PCBase + OpAddress;\
+ }
+#else
+#define BranchCheck0()
+#define BranchCheck1()
+#define BranchCheck2()
+#endif
+
+#ifdef CPU_SHUTDOWN
+#ifndef SA1_OPCODES
+inline void CPUShutdown()
+{
+ if (Settings.Shutdown && CPU.PC == CPU.WaitAddress)
+ {
+ // Don't skip cycles with a pending NMI or IRQ - could cause delayed
+ // interrupt. Interrupts are delayed for a few cycles already, but
+ // the delay could allow the shutdown code to cycle skip again.
+ // Was causing screen flashing on Top Gear 3000.
+
+ if (CPU.WaitCounter == 0 &&
+ !(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG)))
+ {
+ CPU.WaitAddress = NULL;
+ if (Settings.SA1)
+ S9xSA1ExecuteDuringSleep ();
+ CPU.Cycles = CPU.NextEvent;
+ if (IAPU.APUExecuting)
+ {
+ ICPU.CPUExecuting = FALSE;
+ do
+ {
+ APU_EXECUTE1();
+ } while (APU.Cycles < CPU.NextEvent);
+ ICPU.CPUExecuting = TRUE;
+ }
+ }
+ else
+ if (CPU.WaitCounter >= 2)
+ CPU.WaitCounter = 1;
+ else
+ CPU.WaitCounter--;
+ }
+}
+#else
+inline void CPUShutdown()
+{
+ if (Settings.Shutdown && CPU.PC == CPU.WaitAddress)
+ {
+ if (CPU.WaitCounter >= 1)
+ {
+ SA1.Executing = FALSE;
+ SA1.CPUExecuting = FALSE;
+ }
+ else
+ CPU.WaitCounter++;
+ }
+}
+#endif
+#else
+#define CPUShutdown()
+#endif
+
+/* BCC */
+static void Op90 (void)
+{
+ Relative (JUMP);
+ BranchCheck0 ();
+ if (!CheckCarry ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BCS */
+static void OpB0 (void)
+{
+ Relative (JUMP);
+ BranchCheck0 ();
+ if (CheckCarry ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BEQ */
+static void OpF0 (void)
+{
+ Relative (JUMP);
+ BranchCheck2 ();
+ if (CheckZero ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BMI */
+static void Op30 (void)
+{
+ Relative (JUMP);
+ BranchCheck1 ();
+ if (CheckNegative ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BNE */
+static void OpD0 (void)
+{
+ Relative (JUMP);
+ BranchCheck1 ();
+ if (!CheckZero ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BPL */
+static void Op10 (void)
+{
+ Relative (JUMP);
+ BranchCheck1 ();
+ if (!CheckNegative ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BRA */
+static void Op80 (void)
+{
+ Relative (JUMP);
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+}
+
+/* BVC */
+static void Op50 (void)
+{
+ Relative (JUMP);
+ BranchCheck0 ();
+ if (!CheckOverflow ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+
+/* BVS */
+static void Op70 (void)
+{
+ Relative (JUMP);
+ BranchCheck0 ();
+ if (CheckOverflow ())
+ {
+ CPU.PC = CPU.PCBase + OpAddress;
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ CPUShutdown ();
+ }
+}
+/**********************************************************************************************/
+
+/* ClearFlag Instructions ******************************************************************** */
+/* CLC */
+static void Op18 (void)
+{
+ ClearCarry ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+/* CLD */
+static void OpD8 (void)
+{
+ ClearDecimal ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+/* CLI */
+static void Op58 (void)
+{
+ ClearIRQ ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+/* CHECK_FOR_IRQ(); */
+}
+
+/* CLV */
+static void OpB8 (void)
+{
+ ClearOverflow ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+/**********************************************************************************************/
+
+/* DEX/DEY *********************************************************************************** */
+static void OpCAX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.XL--;
+ SetZN8 (Registers.XL);
+}
+
+static void OpCAX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.X.W--;
+ SetZN16 (Registers.X.W);
+}
+
+static void Op88X1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.YL--;
+ SetZN8 (Registers.YL);
+}
+
+static void Op88X0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.Y.W--;
+ SetZN16 (Registers.Y.W);
+}
+/**********************************************************************************************/
+
+/* INX/INY *********************************************************************************** */
+static void OpE8X1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.XL++;
+ SetZN8 (Registers.XL);
+}
+
+static void OpE8X0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.X.W++;
+ SetZN16 (Registers.X.W);
+}
+
+static void OpC8X1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.YL++;
+ SetZN8 (Registers.YL);
+}
+
+static void OpC8X0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = NULL;
+#endif
+
+ Registers.Y.W++;
+ SetZN16 (Registers.Y.W);
+}
+
+/**********************************************************************************************/
+
+/* NOP *************************************************************************************** */
+static void OpEA (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+
+}
+/**********************************************************************************************/
+
+/* PUSH Instructions ************************************************************************* */
+/* #define PushW(w) \
+ * S9xSetWord (w, Registers.S.W - 1);\
+ * Registers.S.W -= 2;
+ */
+#define PushB(b)\
+ S9xSetByte (b, Registers.S.W--);
+
+#define PushBE(b)\
+ S9xSetByte (b, Registers.S.W--);\
+ Registers.SH=0x01;
+
+
+#define PushW(w) \
+ S9xSetByte ((w)>>8, Registers.S.W);\
+ S9xSetByte ((w)&0xff, (Registers.S.W - 1)&0xFFFF);\
+ Registers.S.W -= 2;
+
+#define PushWE(w) \
+ S9xSetByte ((w)>>8, Registers.S.W--);\
+ Registers.SH=0x01;\
+ S9xSetByte ((w)&0xff, (Registers.S.W--)&0xFFFF);\
+ Registers.SH = 0x01;
+
+#define PushWENew(w) \
+ S9xSetByte ((w)>>8, Registers.S.W--);\
+ S9xSetByte ((w)&0xff, (Registers.S.W--)&0xFFFF);\
+ Registers.SH = 0x01;
+
+//PEA NL
+static void OpF4E1 (void)
+{
+ Absolute (NONE);
+ PushWENew ((unsigned short)OpAddress);
+}
+
+static void OpF4 (void)
+{
+ Absolute (NONE);
+ PushW ((unsigned short)OpAddress);
+}
+
+//PEI NL
+static void OpD4E1 (void)
+{
+ DirectIndirect (NONE);
+ PushWENew ((unsigned short)OpAddress);
+}
+
+static void OpD4 (void)
+{
+ DirectIndirect (NONE);
+ PushW ((unsigned short)OpAddress);
+}
+
+//PER NL
+static void Op62E1 (void)
+{
+ RelativeLong (NONE);
+ PushWENew ((unsigned short)OpAddress);
+}
+
+static void Op62 (void)
+{
+ RelativeLong (NONE);
+ PushW ((unsigned short)OpAddress);
+}
+
+
+//PHA
+static void Op48E1 (void)
+{
+ PushBE (Registers.AL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op48M1 (void)
+{
+ PushB (Registers.AL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op48M0 (void)
+{
+ PushW (Registers.A.W);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//PHB
+static void Op8BE1 (void)
+{
+ PushBE (Registers.DB);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+static void Op8B (void)
+{
+ PushB (Registers.DB);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//PHD NL
+static void Op0BE1 (void)
+{
+ PushWENew (Registers.D.W);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op0B (void)
+{
+ PushW (Registers.D.W);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//PHK
+static void Op4BE1 (void)
+{
+ PushBE (Registers.PB);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op4B (void)
+{
+ PushB (Registers.PB);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//PHP
+static void Op08E1 (void)
+{
+ S9xPackStatus ();
+ PushBE (Registers.PL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op08 (void)
+{
+ S9xPackStatus ();
+ PushB (Registers.PL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//PHX
+static void OpDAE1 (void)
+{
+ PushBE (Registers.XL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void OpDAX1 (void)
+{
+ PushB (Registers.XL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void OpDAX0 (void)
+{
+ PushW (Registers.X.W);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//PHY
+static void Op5AE1 (void)
+{
+ PushBE (Registers.YL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op5AX1 (void)
+{
+ PushB (Registers.YL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op5AX0 (void)
+{
+ PushW (Registers.Y.W);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+/**********************************************************************************************/
+
+/* PULL Instructions ************************************************************************* */
+#define PullW(w) \
+ w = S9xGetByte (++Registers.S.W); \
+ w |= (S9xGetByte (++Registers.S.W)<<8);
+
+/* w = S9xGetWord (Registers.S.W + 1); \
+ Registers.S.W += 2;
+*/
+
+#define PullB(b)\
+ b = S9xGetByte (++Registers.S.W);
+
+#define PullBE(b)\
+ Registers.S.W++;\
+ Registers.SH=0x01;\
+ b = S9xGetByte (Registers.S.W);
+
+#define PullWE(w) \
+ Registers.S.W++;\
+ Registers.SH=0x01;\
+ w = S9xGetByte (Registers.S.W); \
+ Registers.S.W++; \
+ Registers.SH=0x01;\
+ w |= (S9xGetByte (Registers.S.W)<<8);
+
+#define PullWENew(w) \
+ PullW(w);\
+ Registers.SH=0x01;
+
+//PLA
+static void Op68E1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullBE (Registers.AL);
+ SetZN8 (Registers.AL);
+}
+
+static void Op68M1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullB (Registers.AL);
+ SetZN8 (Registers.AL);
+}
+
+static void Op68M0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullW (Registers.A.W);
+ SetZN16 (Registers.A.W);
+}
+
+//PLB
+static void OpABE1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullBE (Registers.DB);
+ SetZN8 (Registers.DB);
+ ICPU.ShiftedDB = Registers.DB << 16;
+}
+
+static void OpAB (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullB (Registers.DB);
+ SetZN8 (Registers.DB);
+ ICPU.ShiftedDB = Registers.DB << 16;
+}
+
+/* PHP */
+//PLD NL
+static void Op2BE1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullWENew (Registers.D.W);
+ SetZN16 (Registers.D.W);
+}
+
+static void Op2B (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullW (Registers.D.W);
+ SetZN16 (Registers.D.W);
+}
+
+/* PLP */
+static void Op28E1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullBE (Registers.PL);
+ S9xUnpackStatus ();
+
+ if (CheckIndex ())
+ {
+ Registers.XH = 0;
+ Registers.YH = 0;
+ }
+ S9xFixCycles();
+/* CHECK_FOR_IRQ();*/
+}
+
+static void Op28 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullB (Registers.PL);
+ S9xUnpackStatus ();
+
+ if (CheckIndex ())
+ {
+ Registers.XH = 0;
+ Registers.YH = 0;
+ }
+ S9xFixCycles();
+/* CHECK_FOR_IRQ();*/
+}
+
+//PLX
+static void OpFAE1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullBE (Registers.XL);
+ SetZN8 (Registers.XL);
+}
+
+static void OpFAX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullB (Registers.XL);
+ SetZN8 (Registers.XL);
+}
+
+static void OpFAX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullW (Registers.X.W);
+ SetZN16 (Registers.X.W);
+}
+
+//PLY
+static void Op7AE1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullBE (Registers.YL);
+ SetZN8 (Registers.YL);
+}
+
+static void Op7AX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullB (Registers.YL);
+ SetZN8 (Registers.YL);
+}
+
+static void Op7AX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ PullW (Registers.Y.W);
+ SetZN16 (Registers.Y.W);
+}
+
+/**********************************************************************************************/
+
+/* SetFlag Instructions ********************************************************************** */
+/* SEC */
+static void Op38 (void)
+{
+ SetCarry ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+/* SED */
+static void OpF8 (void)
+{
+ SetDecimal ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ missing.decimal_mode = 1;
+}
+
+/* SEI */
+static void Op78 (void)
+{
+ SetIRQ ();
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+/**********************************************************************************************/
+
+/* Transfer Instructions ********************************************************************* */
+/* TAX8 */
+static void OpAAX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.XL = Registers.AL;
+ SetZN8 (Registers.XL);
+}
+
+/* TAX16 */
+static void OpAAX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.X.W = Registers.A.W;
+ SetZN16 (Registers.X.W);
+}
+
+/* TAY8 */
+static void OpA8X1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.YL = Registers.AL;
+ SetZN8 (Registers.YL);
+}
+
+/* TAY16 */
+static void OpA8X0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.Y.W = Registers.A.W;
+ SetZN16 (Registers.Y.W);
+}
+
+static void Op5B (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.D.W = Registers.A.W;
+ SetZN16 (Registers.D.W);
+}
+
+static void Op1B (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.S.W = Registers.A.W;
+ if (CheckEmulation())
+ Registers.SH = 1;
+}
+
+static void Op7B (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.A.W = Registers.D.W;
+ SetZN16 (Registers.A.W);
+}
+
+static void Op3B (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.A.W = Registers.S.W;
+ SetZN16 (Registers.A.W);
+}
+
+static void OpBAX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.XL = Registers.SL;
+ SetZN8 (Registers.XL);
+}
+
+static void OpBAX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.X.W = Registers.S.W;
+ SetZN16 (Registers.X.W);
+}
+
+static void Op8AM1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.AL = Registers.XL;
+ SetZN8 (Registers.AL);
+}
+
+static void Op8AM0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.A.W = Registers.X.W;
+ SetZN16 (Registers.A.W);
+}
+
+static void Op9A (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.S.W = Registers.X.W;
+ if (CheckEmulation())
+ Registers.SH = 1;
+}
+
+static void Op9BX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.YL = Registers.XL;
+ SetZN8 (Registers.YL);
+}
+
+static void Op9BX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.Y.W = Registers.X.W;
+ SetZN16 (Registers.Y.W);
+}
+
+static void Op98M1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.AL = Registers.YL;
+ SetZN8 (Registers.AL);
+}
+
+static void Op98M0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.A.W = Registers.Y.W;
+ SetZN16 (Registers.A.W);
+}
+
+static void OpBBX1 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.XL = Registers.YL;
+ SetZN8 (Registers.XL);
+}
+
+static void OpBBX0 (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ Registers.X.W = Registers.Y.W;
+ SetZN16 (Registers.X.W);
+}
+
+/**********************************************************************************************/
+
+/* XCE *************************************************************************************** */
+static void OpFB (void)
+{
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+
+ A1 = ICPU._Carry;
+ A2 = Registers.PH;
+ ICPU._Carry = A2 & 1;
+ Registers.PH = A1;
+
+ if (CheckEmulation())
+ {
+ SetFlags (MemoryFlag | IndexFlag);
+ Registers.SH = 1;
+ missing.emulate6502 = 1;
+ }
+ if (CheckIndex ())
+ {
+ Registers.XH = 0;
+ Registers.YH = 0;
+ }
+ S9xFixCycles();
+}
+/**********************************************************************************************/
+
+/* BRK *************************************************************************************** */
+static void Op00 (void)
+{
+#ifdef DEBUGGER
+ if (CPU.Flags & TRACE_FLAG)
+ S9xTraceMessage ("*** BRK");
+#endif
+
+#ifndef SA1_OPCODES
+ CPU.BRKTriggered = TRUE;
+#endif
+
+ if (!CheckEmulation())
+ {
+ PushB (Registers.PB);
+ PushW (CPU.PC - CPU.PCBase + 1);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+ S9xSetPCBase (S9xGetWord (0xFFE6));
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ }
+ else
+ {
+ PushW (CPU.PC - CPU.PCBase);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+ S9xSetPCBase (S9xGetWord (0xFFFE));
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ }
+}
+/**********************************************************************************************/
+
+/* BRL ************************************************************************************** */
+static void Op82 (void)
+{
+ RelativeLong (JUMP);
+ S9xSetPCBase (ICPU.ShiftedPB + OpAddress);
+}
+/**********************************************************************************************/
+
+/* IRQ *************************************************************************************** */
+void S9xOpcode_IRQ (void)
+{
+#ifdef DEBUGGER
+ if (CPU.Flags & TRACE_FLAG)
+ S9xTraceMessage ("*** IRQ");
+#endif
+ if (!CheckEmulation())
+ {
+ PushB (Registers.PB);
+ PushW (CPU.PC - CPU.PCBase);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+#ifdef SA1_OPCODES
+ S9xSA1SetPCBase (Memory.FillRAM [0x2207] |
+ (Memory.FillRAM [0x2208] << 8));
+#else
+ if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40))
+ S9xSetPCBase (Memory.FillRAM [0x220e] |
+ (Memory.FillRAM [0x220f] << 8));
+ else
+ S9xSetPCBase (S9xGetWord (0xFFEE));
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ }
+ else
+ {
+ PushW (CPU.PC - CPU.PCBase);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+#ifdef SA1_OPCODES
+ S9xSA1SetPCBase (Memory.FillRAM [0x2207] |
+ (Memory.FillRAM [0x2208] << 8));
+#else
+ if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40))
+ S9xSetPCBase (Memory.FillRAM [0x220e] |
+ (Memory.FillRAM [0x220f] << 8));
+ else
+ S9xSetPCBase (S9xGetWord (0xFFFE));
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ }
+}
+
+/**********************************************************************************************/
+
+/* NMI *************************************************************************************** */
+void S9xOpcode_NMI (void)
+{
+#ifdef DEBUGGER
+ if (CPU.Flags & TRACE_FLAG)
+ S9xTraceMessage ("*** NMI");
+#endif
+ if (!CheckEmulation())
+ {
+ PushB (Registers.PB);
+ PushW (CPU.PC - CPU.PCBase);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+#ifdef SA1_OPCODES
+ S9xSA1SetPCBase (Memory.FillRAM [0x2205] |
+ (Memory.FillRAM [0x2206] << 8));
+#else
+ if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20))
+ S9xSetPCBase (Memory.FillRAM [0x220c] |
+ (Memory.FillRAM [0x220d] << 8));
+ else
+ S9xSetPCBase (S9xGetWord (0xFFEA));
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ }
+ else
+ {
+ PushW (CPU.PC - CPU.PCBase);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+#ifdef SA1_OPCODES
+ S9xSA1SetPCBase (Memory.FillRAM [0x2205] |
+ (Memory.FillRAM [0x2206] << 8));
+#else
+ if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20))
+ S9xSetPCBase (Memory.FillRAM [0x220c] |
+ (Memory.FillRAM [0x220d] << 8));
+ else
+ S9xSetPCBase (S9xGetWord (0xFFFA));
+#endif
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ }
+}
+/**********************************************************************************************/
+
+/* COP *************************************************************************************** */
+static void Op02 (void)
+{
+#ifdef DEBUGGER
+ if (CPU.Flags & TRACE_FLAG)
+ S9xTraceMessage ("*** COP");
+#endif
+ if (!CheckEmulation())
+ {
+ PushB (Registers.PB);
+ PushW (CPU.PC - CPU.PCBase + 1);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+ S9xSetPCBase (S9xGetWord (0xFFE4));
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ }
+ else
+ {
+ PushW (CPU.PC - CPU.PCBase);
+ S9xPackStatus ();
+ PushB (Registers.PL);
+ OpenBus = Registers.PL;
+ ClearDecimal ();
+ SetIRQ ();
+
+ Registers.PB = 0;
+ ICPU.ShiftedPB = 0;
+ S9xSetPCBase (S9xGetWord (0xFFF4));
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+ }
+}
+/**********************************************************************************************/
+
+/* JML *************************************************************************************** */
+static void OpDC (void)
+{
+ AbsoluteIndirectLong (JUMP);
+ Registers.PB = (uint8) (OpAddress >> 16);
+ ICPU.ShiftedPB = OpAddress & 0xff0000;
+ S9xSetPCBase (OpAddress);
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+}
+
+static void Op5C (void)
+{
+ AbsoluteLong (JUMP);
+ Registers.PB = (uint8) (OpAddress >> 16);
+ ICPU.ShiftedPB = OpAddress & 0xff0000;
+ S9xSetPCBase (OpAddress);
+}
+/**********************************************************************************************/
+
+/* JMP *************************************************************************************** */
+static void Op4C (void)
+{
+ Absolute (JUMP);
+ S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff));
+#if defined(CPU_SHUTDOWN) && defined(SA1_OPCODES)
+ CPUShutdown ();
+#endif
+}
+
+static void Op6C (void)
+{
+ AbsoluteIndirect (JUMP);
+ S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff));
+}
+
+static void Op7C (void)
+{
+ AbsoluteIndexedIndirect (JUMP);
+ S9xSetPCBase (ICPU.ShiftedPB + OpAddress);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+/**********************************************************************************************/
+
+/* JSL/RTL *********************************************************************************** */
+static void Op22E1 (void)
+{
+ AbsoluteLong (JUMP);
+ PushB (Registers.PB);
+ PushWENew (CPU.PC - CPU.PCBase - 1);
+ Registers.PB = (uint8) (OpAddress >> 16);
+ ICPU.ShiftedPB = OpAddress & 0xff0000;
+ S9xSetPCBase (OpAddress);
+}
+
+static void Op22 (void)
+{
+ AbsoluteLong (JUMP);
+ PushB (Registers.PB);
+ PushW (CPU.PC - CPU.PCBase - 1);
+ Registers.PB = (uint8) (OpAddress >> 16);
+ ICPU.ShiftedPB = OpAddress & 0xff0000;
+ S9xSetPCBase (OpAddress);
+}
+
+static void Op6BE1 (void)
+{
+ PullWENew (Registers.PC);
+ PullB (Registers.PB);
+ ICPU.ShiftedPB = Registers.PB << 16;
+ S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff));
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+}
+
+static void Op6B (void)
+{
+ PullW (Registers.PC);
+ PullB (Registers.PB);
+ ICPU.ShiftedPB = Registers.PB << 16;
+ S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff));
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+}
+/**********************************************************************************************/
+
+/* JSR/RTS *********************************************************************************** */
+static void Op20 (void)
+{
+ Absolute (JUMP);
+ PushW (CPU.PC - CPU.PCBase - 1);
+ S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff));
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+//JSR a,x
+static void OpFCE1 (void)
+{
+ AbsoluteIndexedIndirect (JUMP);
+ PushWENew (CPU.PC - CPU.PCBase - 1);
+ S9xSetPCBase (ICPU.ShiftedPB + OpAddress);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void OpFC (void)
+{
+ AbsoluteIndexedIndirect (JUMP);
+ PushW (CPU.PC - CPU.PCBase - 1);
+ S9xSetPCBase (ICPU.ShiftedPB + OpAddress);
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE;
+#endif
+}
+
+static void Op60 (void)
+{
+ PullW (Registers.PC);
+ S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff));
+#ifndef SA1_OPCODES
+ CPU.Cycles += ONE_CYCLE * 3;
+#endif
+}
+
+/**********************************************************************************************/
+
+/* MVN/MVP *********************************************************************************** */
+static void Op54X1 (void)
+{
+ uint32 SrcBank;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES;
+#endif
+
+ Registers.DB = *CPU.PC++;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ OpenBus = SrcBank = *CPU.PC++;
+
+ S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W),
+ ICPU.ShiftedDB + Registers.Y.W);
+
+ Registers.XL++;
+ Registers.YL++;
+ Registers.A.W--;
+ if (Registers.A.W != 0xffff)
+ CPU.PC -= 3;
+}
+
+static void Op54X0 (void)
+{
+ uint32 SrcBank;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES;
+#endif
+
+ Registers.DB = *CPU.PC++;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ OpenBus = SrcBank = *CPU.PC++;
+
+ S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W),
+ ICPU.ShiftedDB + Registers.Y.W);
+
+ Registers.X.W++;
+ Registers.Y.W++;
+ Registers.A.W--;
+ if (Registers.A.W != 0xffff)
+ CPU.PC -= 3;
+}
+
+static void Op44X1 (void)
+{
+ uint32 SrcBank;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES;
+#endif
+ Registers.DB = *CPU.PC++;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ OpenBus = SrcBank = *CPU.PC++;
+ S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W),
+ ICPU.ShiftedDB + Registers.Y.W);
+
+ Registers.XL--;
+ Registers.YL--;
+ Registers.A.W--;
+ if (Registers.A.W != 0xffff)
+ CPU.PC -= 3;
+}
+
+static void Op44X0 (void)
+{
+ uint32 SrcBank;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES;
+#endif
+ Registers.DB = *CPU.PC++;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ OpenBus = SrcBank = *CPU.PC++;
+ S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W),
+ ICPU.ShiftedDB + Registers.Y.W);
+
+ Registers.X.W--;
+ Registers.Y.W--;
+ Registers.A.W--;
+ if (Registers.A.W != 0xffff)
+ CPU.PC -= 3;
+}
+
+/**********************************************************************************************/
+
+/* REP/SEP *********************************************************************************** */
+static void OpC2 (void)
+{
+ Work8 = ~*CPU.PC++;
+ Registers.PL &= Work8;
+ ICPU._Carry &= Work8;
+ ICPU._Overflow &= (Work8 >> 6);
+ ICPU._Negative &= Work8;
+ ICPU._Zero |= ~Work8 & Zero;
+
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed + ONE_CYCLE;
+#endif
+ if (CheckEmulation())
+ {
+ SetFlags (MemoryFlag | IndexFlag);
+ missing.emulate6502 = 1;
+ }
+ if (CheckIndex ())
+ {
+ Registers.XH = 0;
+ Registers.YH = 0;
+ }
+ S9xFixCycles();
+/* CHECK_FOR_IRQ(); */
+}
+
+static void OpE2 (void)
+{
+ Work8 = *CPU.PC++;
+ Registers.PL |= Work8;
+ ICPU._Carry |= Work8 & 1;
+ ICPU._Overflow |= (Work8 >> 6) & 1;
+ ICPU._Negative |= Work8;
+ if (Work8 & Zero)
+ ICPU._Zero = 0;
+#ifndef SA1_OPCODES
+ CPU.Cycles += CPU.MemSpeed + ONE_CYCLE;
+#endif
+ if (CheckEmulation())
+ {
+ SetFlags (MemoryFlag | IndexFlag);
+ missing.emulate6502 = 1;
+ }
+ if (CheckIndex ())
+ {
+ Registers.XH = 0;
+ Registers.YH = 0;
+ }
+ S9xFixCycles();
+}
+/**********************************************************************************************/
+
+/* XBA *************************************************************************************** */
+static void OpEB (void)
+{
+ Work8 = Registers.AL;
+ Registers.AL = Registers.AH;
+ Registers.AH = Work8;
+
+ SetZN8 (Registers.AL);
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+}
+/**********************************************************************************************/
+
+/* RTI *************************************************************************************** */
+static void Op40 (void)
+{
+ PullB (Registers.PL);
+ S9xUnpackStatus ();
+ PullW (Registers.PC);
+ if (!CheckEmulation())
+ {
+ PullB (Registers.PB);
+ ICPU.ShiftedPB = Registers.PB << 16;
+ }
+ else
+ {
+ SetFlags (MemoryFlag | IndexFlag);
+ missing.emulate6502 = 1;
+ }
+ S9xSetPCBase (ICPU.ShiftedPB + Registers.PC);
+
+ if (CheckIndex ())
+ {
+ Registers.XH = 0;
+ Registers.YH = 0;
+ }
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ S9xFixCycles();
+/* CHECK_FOR_IRQ(); */
+}
+
+/**********************************************************************************************/
+
+/* STP/WAI/DB ******************************************************************************** */
+// WAI
+static void OpCB (void)
+{
+
+// Ok, let's just C-ify the ASM versions separately.
+#ifdef SA1_OPCODES
+ SA1.WaitingForInterrupt = TRUE;
+ SA1.PC--;
+#if 0
+// XXX: FIXME
+ if(Settings.Shutdown){
+ SA1.Cycles = SA1.NextEvent;
+ if (IAPU.APUExecuting)
+ {
+ SA1.Executing = FALSE;
+ do
+ {
+ APU_EXECUTE1 ();
+ } while (APU.Cycles < SA1.NextEvent);
+ SA1.Executing = TRUE;
+ }
+ }
+#endif
+#else // SA1_OPCODES
+#if 0
+
+
+ if (CPU.IRQActive)
+ {
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+ }
+ else
+#endif
+ {
+ CPU.WaitingForInterrupt = TRUE;
+ CPU.PC--;
+#ifdef CPU_SHUTDOWN
+ if (Settings.Shutdown)
+ {
+ CPU.Cycles = CPU.NextEvent;
+ if (IAPU.APUExecuting)
+ {
+ ICPU.CPUExecuting = FALSE;
+ do
+ {
+ APU_EXECUTE1 ();
+ } while (APU.Cycles < CPU.NextEvent);
+ ICPU.CPUExecuting = TRUE;
+ }
+ }
+ else
+ {
+#ifndef SA1_OPCODES
+ CPU.Cycles += TWO_CYCLES;
+#endif
+#endif
+ }
+ }
+#endif // SA1_OPCODES
+}
+
+// STP
+static void OpDB (void)
+{
+ CPU.PC--;
+ CPU.Flags |= DEBUG_MODE_FLAG;
+}
+
+// Reserved S9xOpcode
+static void Op42 (void)
+{
+}
+
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* CPU-S9xOpcodes Definitions */
+/*****************************************************************************/
+struct SOpcodes S9xOpcodesM1X1[256] =
+{
+ {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1},
+ {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1},
+ {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1},
+ {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1},
+ {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18},
+ {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1},
+ {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22},
+ {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1},
+ {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1},
+ {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1},
+ {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1},
+ {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B},
+ {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40},
+ {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1},
+ {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1},
+ {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1},
+ {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1},
+ {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1},
+ {Op5AX1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1},
+ {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1},
+ {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1},
+ {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1},
+ {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1},
+ {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1},
+ {Op78}, {Op79M1}, {Op7AX1}, {Op7B}, {Op7C},
+ {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1},
+ {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1},
+ {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8B},
+ {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90},
+ {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1},
+ {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A},
+ {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1},
+ {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1},
+ {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1},
+ {OpAAX1}, {OpAB}, {OpACX1}, {OpADM1}, {OpAEX1},
+ {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1},
+ {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8},
+ {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1},
+ {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2},
+ {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1},
+ {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1},
+ {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1},
+ {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1},
+ {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX1}, {OpDB},
+ {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1},
+ {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1},
+ {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA},
+ {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1},
+ {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4},
+ {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1},
+ {OpFAX1}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1},
+ {OpFFM1}
+};
+
+struct SOpcodes S9xOpcodesE1[256] =
+{
+ {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1},
+ {Op05M1}, {Op06M1}, {Op07M1}, {Op08E1}, {Op09M1},
+ {Op0AM1}, {Op0BE1}, {Op0CM1}, {Op0DM1}, {Op0EM1},
+ {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1},
+ {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18},
+ {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1},
+ {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22E1},
+ {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1},
+ {Op28}, {Op29M1}, {Op2AM1}, {Op2BE1}, {Op2CM1},
+ {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1},
+ {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1},
+ {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B},
+ {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40},
+ {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1},
+ {Op46M1}, {Op47M1}, {Op48E1}, {Op49M1}, {Op4AM1},
+ {Op4BE1}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1},
+ {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1},
+ {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1},
+ {Op5AE1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1},
+ {Op5FM1}, {Op60}, {Op61M1}, {Op62E1}, {Op63M1},
+ {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68E1},
+ {Op69M1}, {Op6AM1}, {Op6BE1}, {Op6C}, {Op6DM1},
+ {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1},
+ {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1},
+ {Op78}, {Op79M1}, {Op7AE1}, {Op7B}, {Op7C},
+ {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1},
+ {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1},
+ {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8BE1},
+ {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90},
+ {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1},
+ {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A},
+ {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1},
+ {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1},
+ {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1},
+ {OpAAX1}, {OpABE1}, {OpACX1}, {OpADM1}, {OpAEX1},
+ {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1},
+ {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8},
+ {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1},
+ {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2},
+ {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1},
+ {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1},
+ {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1},
+ {OpD2M1}, {OpD3M1}, {OpD4E1}, {OpD5M1}, {OpD6M1},
+ {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAE1}, {OpDB},
+ {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1},
+ {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1},
+ {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA},
+ {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1},
+ {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4E1},
+ {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1},
+ {OpFAE1}, {OpFB}, {OpFCE1}, {OpFDM1}, {OpFEM1},
+ {OpFFM1}
+};
+
+struct SOpcodes S9xOpcodesM1X0[256] =
+{
+ {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1},
+ {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1},
+ {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1},
+ {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1},
+ {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18},
+ {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1},
+ {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22},
+ {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1},
+ {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1},
+ {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1},
+ {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1},
+ {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B},
+ {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40},
+ {Op41M1}, {Op42}, {Op43M1}, {Op44X0}, {Op45M1},
+ {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1},
+ {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1},
+ {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X0},
+ {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1},
+ {Op5AX0}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1},
+ {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1},
+ {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1},
+ {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1},
+ {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1},
+ {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1},
+ {Op78}, {Op79M1}, {Op7AX0}, {Op7B}, {Op7C},
+ {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1},
+ {Op82}, {Op83M1}, {Op84X0}, {Op85M1}, {Op86X0},
+ {Op87M1}, {Op88X0}, {Op89M1}, {Op8AM1}, {Op8B},
+ {Op8CX0}, {Op8DM1}, {Op8EX0}, {Op8FM1}, {Op90},
+ {Op91M1}, {Op92M1}, {Op93M1}, {Op94X0}, {Op95M1},
+ {Op96X0}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A},
+ {Op9BX0}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1},
+ {OpA0X0}, {OpA1M1}, {OpA2X0}, {OpA3M1}, {OpA4X0},
+ {OpA5M1}, {OpA6X0}, {OpA7M1}, {OpA8X0}, {OpA9M1},
+ {OpAAX0}, {OpAB}, {OpACX0}, {OpADM1}, {OpAEX0},
+ {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1},
+ {OpB4X0}, {OpB5M1}, {OpB6X0}, {OpB7M1}, {OpB8},
+ {OpB9M1}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM1},
+ {OpBEX0}, {OpBFM1}, {OpC0X0}, {OpC1M1}, {OpC2},
+ {OpC3M1}, {OpC4X0}, {OpC5M1}, {OpC6M1}, {OpC7M1},
+ {OpC8X0}, {OpC9M1}, {OpCAX0}, {OpCB}, {OpCCX0},
+ {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1},
+ {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1},
+ {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX0}, {OpDB},
+ {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X0},
+ {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X0}, {OpE5M1},
+ {OpE6M1}, {OpE7M1}, {OpE8X0}, {OpE9M1}, {OpEA},
+ {OpEB}, {OpECX0}, {OpEDM1}, {OpEEM1}, {OpEFM1},
+ {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4},
+ {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1},
+ {OpFAX0}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1},
+ {OpFFM1}
+};
+
+struct SOpcodes S9xOpcodesM0X0[256] =
+{
+ {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0},
+ {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0},
+ {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0},
+ {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0},
+ {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18},
+ {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0},
+ {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22},
+ {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0},
+ {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0},
+ {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0},
+ {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0},
+ {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B},
+ {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40},
+ {Op41M0}, {Op42}, {Op43M0}, {Op44X0}, {Op45M0},
+ {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0},
+ {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0},
+ {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X0},
+ {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0},
+ {Op5AX0}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0},
+ {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0},
+ {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0},
+ {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0},
+ {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0},
+ {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0},
+ {Op78}, {Op79M0}, {Op7AX0}, {Op7B}, {Op7C},
+ {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0},
+ {Op82}, {Op83M0}, {Op84X0}, {Op85M0}, {Op86X0},
+ {Op87M0}, {Op88X0}, {Op89M0}, {Op8AM0}, {Op8B},
+ {Op8CX0}, {Op8DM0}, {Op8EX0}, {Op8FM0}, {Op90},
+ {Op91M0}, {Op92M0}, {Op93M0}, {Op94X0}, {Op95M0},
+ {Op96X0}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A},
+ {Op9BX0}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0},
+ {OpA0X0}, {OpA1M0}, {OpA2X0}, {OpA3M0}, {OpA4X0},
+ {OpA5M0}, {OpA6X0}, {OpA7M0}, {OpA8X0}, {OpA9M0},
+ {OpAAX0}, {OpAB}, {OpACX0}, {OpADM0}, {OpAEX0},
+ {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0},
+ {OpB4X0}, {OpB5M0}, {OpB6X0}, {OpB7M0}, {OpB8},
+ {OpB9M0}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM0},
+ {OpBEX0}, {OpBFM0}, {OpC0X0}, {OpC1M0}, {OpC2},
+ {OpC3M0}, {OpC4X0}, {OpC5M0}, {OpC6M0}, {OpC7M0},
+ {OpC8X0}, {OpC9M0}, {OpCAX0}, {OpCB}, {OpCCX0},
+ {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0},
+ {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0},
+ {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX0}, {OpDB},
+ {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X0},
+ {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X0}, {OpE5M0},
+ {OpE6M0}, {OpE7M0}, {OpE8X0}, {OpE9M0}, {OpEA},
+ {OpEB}, {OpECX0}, {OpEDM0}, {OpEEM0}, {OpEFM0},
+ {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4},
+ {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0},
+ {OpFAX0}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0},
+ {OpFFM0}
+};
+
+struct SOpcodes S9xOpcodesM0X1[256] =
+{
+ {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0},
+ {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0},
+ {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0},
+ {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0},
+ {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18},
+ {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0},
+ {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22},
+ {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0},
+ {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0},
+ {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0},
+ {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0},
+ {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B},
+ {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40},
+ {Op41M0}, {Op42}, {Op43M0}, {Op44X1}, {Op45M0},
+ {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0},
+ {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0},
+ {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X1},
+ {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0},
+ {Op5AX1}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0},
+ {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0},
+ {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0},
+ {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0},
+ {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0},
+ {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0},
+ {Op78}, {Op79M0}, {Op7AX1}, {Op7B}, {Op7C},
+ {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0},
+ {Op82}, {Op83M0}, {Op84X1}, {Op85M0}, {Op86X1},
+ {Op87M0}, {Op88X1}, {Op89M0}, {Op8AM0}, {Op8B},
+ {Op8CX1}, {Op8DM0}, {Op8EX1}, {Op8FM0}, {Op90},
+ {Op91M0}, {Op92M0}, {Op93M0}, {Op94X1}, {Op95M0},
+ {Op96X1}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A},
+ {Op9BX1}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0},
+ {OpA0X1}, {OpA1M0}, {OpA2X1}, {OpA3M0}, {OpA4X1},
+ {OpA5M0}, {OpA6X1}, {OpA7M0}, {OpA8X1}, {OpA9M0},
+ {OpAAX1}, {OpAB}, {OpACX1}, {OpADM0}, {OpAEX1},
+ {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0},
+ {OpB4X1}, {OpB5M0}, {OpB6X1}, {OpB7M0}, {OpB8},
+ {OpB9M0}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM0},
+ {OpBEX1}, {OpBFM0}, {OpC0X1}, {OpC1M0}, {OpC2},
+ {OpC3M0}, {OpC4X1}, {OpC5M0}, {OpC6M0}, {OpC7M0},
+ {OpC8X1}, {OpC9M0}, {OpCAX1}, {OpCB}, {OpCCX1},
+ {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0},
+ {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0},
+ {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX1}, {OpDB},
+ {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X1},
+ {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X1}, {OpE5M0},
+ {OpE6M0}, {OpE7M0}, {OpE8X1}, {OpE9M0}, {OpEA},
+ {OpEB}, {OpECX1}, {OpEDM0}, {OpEEM0}, {OpEFM0},
+ {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4},
+ {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0},
+ {OpFAX1}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0},
+ {OpFFM0}
+};
+
diff --git a/source/cpuops.h b/source/cpuops.h
new file mode 100644
index 0000000..8b59dbb
--- /dev/null
+++ b/source/cpuops.h
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _CPUOPS_H_
+#define _CPUOPS_H_
+void S9xOpcode_NMI ();
+void S9xOpcode_IRQ ();
+
+#define CHECK_FOR_IRQ() \
+if (CPU.IRQActive && !CheckFlag (IRQ) && !Settings.DisableIRQ) \
+ S9xOpcode_IRQ()
+
+#endif
+
diff --git a/source/data.cpp b/source/data.cpp
new file mode 100644
index 0000000..0854ed4
--- /dev/null
+++ b/source/data.cpp
@@ -0,0 +1,539 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+
+uint8 add32_32 [32][32] = {
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
+ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
+ 0x1e,0x1f},
+{ 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,
+ 0x1f,0x1f},
+{ 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
+ 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x1f,0x1f},
+{ 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,
+ 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
+ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,
+ 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
+ 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
+ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
+ 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
+ 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
+ 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,
+ 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
+ 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,
+ 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
+ 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f},
+{ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
+ 0x1f,0x1f}
+};
+
+uint8 add32_32_half [32][32] = {
+{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
+ 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,
+ 0x0f,0x0f},
+{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,
+ 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,
+ 0x0f,0x10},
+{ 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,
+ 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,
+ 0x10,0x10},
+{ 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,
+ 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,
+ 0x10,0x11},
+{ 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,
+ 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,
+ 0x11,0x11},
+{ 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,
+ 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,
+ 0x11,0x12},
+{ 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,
+ 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,
+ 0x12,0x12},
+{ 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,
+ 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,
+ 0x12,0x13},
+{ 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,
+ 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,
+ 0x13,0x13},
+{ 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,
+ 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,
+ 0x13,0x14},
+{ 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,
+ 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,
+ 0x14,0x14},
+{ 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,
+ 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,
+ 0x14,0x15},
+{ 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,
+ 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,
+ 0x15,0x15},
+{ 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
+ 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,
+ 0x15,0x16},
+{ 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,
+ 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,
+ 0x16,0x16},
+{ 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,
+ 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,
+ 0x16,0x17},
+{ 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,
+ 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,
+ 0x17,0x17},
+{ 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,
+ 0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,
+ 0x17,0x18},
+{ 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,
+ 0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,
+ 0x18,0x18},
+{ 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,
+ 0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,
+ 0x18,0x19},
+{ 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,
+ 0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,
+ 0x19,0x19},
+{ 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,
+ 0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,
+ 0x19,0x1a},
+{ 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,
+ 0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,
+ 0x1a,0x1a},
+{ 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,
+ 0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,
+ 0x1a,0x1b},
+{ 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,
+ 0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,
+ 0x1b,0x1b},
+{ 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,
+ 0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,
+ 0x1b,0x1c},
+{ 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,
+ 0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,
+ 0x1c,0x1c},
+{ 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,
+ 0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,
+ 0x1c,0x1d},
+{ 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,
+ 0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,
+ 0x1d,0x1d},
+{ 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,
+ 0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,
+ 0x1d,0x1e},
+{ 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,
+ 0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,
+ 0x1e,0x1e},
+{ 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,
+ 0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1e,
+ 0x1e,0x1f}
+};
+uint8 sub32_32 [32][32] = {
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
+ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
+ 0x1e,0x1f},
+{ 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
+ 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,
+ 0x1d,0x1e},
+{ 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
+ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
+ 0x1c,0x1d},
+{ 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
+ 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,
+ 0x1b,0x1c},
+{ 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
+ 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
+ 0x1a,0x1b},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+ 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
+ 0x19,0x1a},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
+ 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
+ 0x17,0x18},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
+ 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
+ 0x16,0x17},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,
+ 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
+ 0x15,0x16},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
+ 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,
+ 0x14,0x15},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
+ 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
+ 0x13,0x14},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
+ 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,
+ 0x12,0x13},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
+ 0x11,0x12},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
+ 0x0f,0x10},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
+ 0x0e,0x0f},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
+ 0x0d,0x0e},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
+ 0x0c,0x0d},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
+ 0x0b,0x0c},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+ 0x0a,0x0b},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
+ 0x09,0x0a},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09},
+{ 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,0x02,0x03,0x04,0x05,0x06,
+ 0x07,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,0x01,0x02,0x03,0x04,0x05,
+ 0x06,0x07},
+{ 0x00,0x00,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,0x02,0x03,0x04,
+ 0x05,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,0x01,0x02,0x03,
+ 0x04,0x05},
+{ 0x00,0x00,0x00,0x00,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,0x02,
+ 0x03,0x04},
+{ 0x00,0x00,0x00,0x00,0x00,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,
+ 0x02,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,
+ 0x01,0x02},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,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}
+};
+
+uint8 sub32_32_half [32][32] = {
+{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
+ 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,
+ 0x0f,0x0f},
+{ 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,
+ 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,
+ 0x0e,0x0f},
+{ 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,
+ 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
+ 0x0e,0x0e},
+{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,
+ 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,
+ 0x0d,0x0e},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,
+ 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,
+ 0x0d,0x0d},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
+ 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,
+ 0x0c,0x0d},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,
+ 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,
+ 0x0c,0x0c},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,
+ 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,
+ 0x0b,0x0c},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,
+ 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,
+ 0x0b,0x0b},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,
+ 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,
+ 0x0a,0x0b},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,
+ 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,
+ 0x0a,0x0a},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
+ 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,
+ 0x09,0x0a},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,
+ 0x09,0x09},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,
+ 0x08,0x09},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,
+ 0x08,0x08},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
+ 0x07,0x08},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,
+ 0x07,0x07},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,
+ 0x06,0x07},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,
+ 0x06,0x06},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,
+ 0x05,0x06},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
+ 0x05,0x05},
+{ 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,0x02,0x02,0x03,0x03,0x04,
+ 0x04,0x05},
+{ 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,0x02,0x02,0x03,0x03,
+ 0x04,0x04},
+{ 0x00,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,0x02,0x02,0x03,
+ 0x03,0x04},
+{ 0x00,0x00,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,0x02,0x02,
+ 0x03,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,0x01,0x01,0x02,
+ 0x02,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,0x01,0x01,
+ 0x02,0x02},
+{ 0x00,0x00,0x00,0x00,0x00,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,0x02},
+{ 0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00}
+};
+
+
+uint8 mul_brightness [16][32] = {
+{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,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,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+ 0x02,0x02},
+{ 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,
+ 0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,
+ 0x04,0x04},
+{ 0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x03,0x03,
+ 0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x06,0x06,
+ 0x06,0x06},
+{ 0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x04,
+ 0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x08,
+ 0x08,0x08},
+{ 0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,
+ 0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,
+ 0x0a,0x0a},
+{ 0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06,
+ 0x06,0x06,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0c,
+ 0x0c,0x0c},
+{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
+ 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,
+ 0x0e,0x0e},
+{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,
+ 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,
+ 0x10,0x11},
+{ 0x00,0x01,0x01,0x02,0x02,0x03,0x04,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x08,
+ 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x10,0x10,0x11,0x11,
+ 0x12,0x13},
+{ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x09,0x09,
+ 0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x11,0x12,0x13,0x13,
+ 0x14,0x15},
+{ 0x00,0x01,0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0a,
+ 0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x15,
+ 0x16,0x17},
+{ 0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b,
+ 0x0c,0x0d,0x0e,0x0e,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x16,0x16,0x17,
+ 0x18,0x19},
+{ 0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b,0x0c,
+ 0x0d,0x0e,0x0f,0x10,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x19,
+ 0x1a,0x1b},
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
+ 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
+ 0x1c,0x1d},
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
+ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
+ 0x1e,0x1f}
+};
+
+
diff --git a/source/debug.cpp b/source/debug.cpp
new file mode 100644
index 0000000..6ea02e9
--- /dev/null
+++ b/source/debug.cpp
@@ -0,0 +1,2220 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "cpuops.h"
+#include "cheats.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "debug.h"
+#include "missing.h"
+#include "display.h"
+#include "apu.h"
+#include "sa1.h"
+#include "spc7110.h"
+
+#ifdef DEBUGGER
+static void WhatsMissing ();
+static void WhatsUsed ();
+EXTERN_C SDMA DMA[8];
+extern struct SCheatData Cheat;
+
+#ifdef SPCTOOL
+#include "spctool/spc700.h"
+extern "C" void TraceSPC (unsigned char *PC, unsigned short YA, unsigned char X,
+ SPCFlags PS, unsigned char *SP);
+#endif
+
+FILE *trace = NULL;
+FILE *trace2 = NULL;
+struct SBreakPoint S9xBreakpoint[6];
+struct SDebug
+{
+ struct
+ {
+ uint8 Bank;
+ uint16 Address;
+ } Dump;
+ struct
+ {
+ uint8 Bank;
+ uint16 Address;
+ } Unassemble;
+} Debug =
+{
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ }
+};
+char *HelpMessage[] = {
+ "Command Help:",
+ "? - Shows this Command Help",
+ "r - Shows the Registers",
+ "i - Shows the interrupt vectors",
+ "t - Trace current instruction [Step-into]",
+ "T - Toggle CPU instruction tracing to trace.log",
+ "D - Toggle DMA tracing to stdout",
+ "H - Toggle H-DMA tracing to stdout",
+ "P - Toggle DSP tracing to stdout",
+ "U - Toggle unknown register read/write tracing",
+ "V - Toggle non-DMA V-RAM read/write tracing",
+ "R - Reset ROM.",
+ "p - Proceed to next instruction [Step-over]",
+ "s - Skip to next instruction [Skip]",
+ "S - dump sprite (OBJ) status",
+ "g [Address] - Go or Go to [Address]",
+ "u [Address] - Disassemble from PC or [Address]",
+ "d [Address] - Dump from PC or [Address]",
+ "bv [Number] - View Breakpoints or View Breakpoint [Number]",
+ "bs [Number] [Address] - Enable/Disable Breakpoint",
+ " [Enable example: BS #2 $02:8002]",
+ " [Disable example: BS #2]",
+ "c - Dump SNES colour palette",
+ "W - Show what SNES hardware features a ROM is using",
+ " which might not be implemented yet.",
+ "w - Show some SNES hardware features used so far in this frame",
+ "q - Quit emulator",
+ "",
+ "[Address] - $Bank:Address or $Address",
+ " [For example: $01:8123]",
+ "[Number] - #Number",
+ " [For example: #1]",
+ "a - Show Sound CPU status",
+ "A - Toggle sound CPU instruction tracing to aputrace.log",
+ "B - Toggle sound DSP register tracing",
+ "C - Dump sound sample addresses",
+ "ad [Address] - Dump sound CPU RAM from PC or [Address]",
+ "", NULL};
+
+char *S9xMnemonics[256] = {
+ "BRK", "ORA", "COP", "ORA", "TSB", "ORA", "ASL", "ORA",
+ "PHP", "ORA", "ASL", "PHD", "TSB", "ORA", "ASL", "ORA",
+ "BPL", "ORA", "ORA", "ORA", "TRB", "ORA", "ASL", "ORA",
+ "CLC", "ORA", "INC", "TCS", "TRB", "ORA", "ASL", "ORA",
+ "JSR", "AND", "JSL", "AND", "BIT", "AND", "ROL", "AND",
+ "PLP", "AND", "ROL", "PLD", "BIT", "AND", "ROL", "AND",
+ "BMI", "AND", "AND", "AND", "BIT", "AND", "ROL", "AND",
+ "SEC", "AND", "DEC", "TSC", "BIT", "AND", "ROL", "AND",
+ "RTI", "EOR", "DB ", "EOR", "MVP", "EOR", "LSR", "EOR",
+ "PHA", "EOR", "LSR", "PHK", "JMP", "EOR", "LSR", "EOR",
+ "BVC", "EOR", "EOR", "EOR", "MVN", "EOR", "LSR", "EOR",
+ "CLI", "EOR", "PHY", "TCD", "JMP", "EOR", "LSR", "EOR",
+ "RTS", "ADC", "PER", "ADC", "STZ", "ADC", "ROR", "ADC",
+ "PLA", "ADC", "ROR", "RTL", "JMP", "ADC", "ROR", "ADC",
+ "BVS", "ADC", "ADC", "ADC", "STZ", "ADC", "ROR", "ADC",
+ "SEI", "ADC", "PLY", "TDC", "JMP", "ADC", "ROR", "ADC",
+ "BRA", "STA", "BRL", "STA", "STY", "STA", "STX", "STA",
+ "DEY", "BIT", "TXA", "PHB", "STY", "STA", "STX", "STA",
+ "BCC", "STA", "STA", "STA", "STY", "STA", "STX", "STA",
+ "TYA", "STA", "TXS", "TXY", "STZ", "STA", "STZ", "STA",
+ "LDY", "LDA", "LDX", "LDA", "LDY", "LDA", "LDX", "LDA",
+ "TAY", "LDA", "TAX", "PLB", "LDY", "LDA", "LDX", "LDA",
+ "BCS", "LDA", "LDA", "LDA", "LDY", "LDA", "LDX", "LDA",
+ "CLV", "LDA", "TSX", "TYX", "LDY", "LDA", "LDX", "LDA",
+ "CPY", "CMP", "REP", "CMP", "CPY", "CMP", "DEC", "CMP",
+ "INY", "CMP", "DEX", "WAI", "CPY", "CMP", "DEC", "CMP",
+ "BNE", "CMP", "CMP", "CMP", "PEI", "CMP", "DEC", "CMP",
+ "CLD", "CMP", "PHX", "STP", "JML", "CMP", "DEC", "CMP",
+ "CPX", "SBC", "SEP", "SBC", "CPX", "SBC", "INC", "SBC",
+ "INX", "SBC", "NOP", "XBA", "CPX", "SBC", "INC", "SBC",
+ "BEQ", "SBC", "SBC", "SBC", "PEA", "SBC", "INC", "SBC",
+ "SED", "SBC", "PLX", "XCE", "JSR", "SBC", "INC", "SBC"
+};
+int AddrModes[256] = {
+ //0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 3, 10, 3, 19, 6, 6, 6, 12, 0, 1,24, 0, 14, 14, 14, 17, //0
+ 4, 11, 9, 20, 6, 7, 7, 13, 0, 16,24, 0, 14, 15, 15, 18, //1
+ 14, 10,17, 19, 6, 6, 6, 12, 0, 1,24, 0, 14, 14, 14, 17, //2
+ 4, 11, 9, 20, 7, 7, 7, 13, 0, 16,24, 0, 15, 15, 15, 18, //3
+ 0, 10, 3, 19, 25,6, 6, 12, 0, 1,24, 0, 14, 14, 14, 17, //4
+ 4, 11, 9, 20, 25,7, 7, 13, 0, 16, 0, 0, 17, 15, 15, 18, //5
+ 0, 10, 5, 19, 6, 6, 6, 12, 0, 1,24, 0, 21, 14, 14, 17, //6
+ 4, 11, 9, 20, 7, 7, 7, 13, 0, 16, 0, 0, 23, 15, 15, 18, //7
+ 4, 10, 5, 19, 6, 6, 6, 12, 0, 1, 0, 0, 14, 14, 14, 17, //8
+ 4, 11, 9, 20, 7, 7, 8, 13, 0, 16, 0, 0, 14, 15, 15, 18, //9
+ 2, 10, 2, 19, 6, 6, 6, 12, 0, 1, 0, 0, 14, 14, 14, 17, //A
+ 4, 11, 9, 20, 7, 7, 8, 13, 0, 16, 0, 0, 15, 15, 16, 18, //B
+ 2, 10, 3, 19, 6, 6, 6, 12, 0, 1, 0, 0, 14, 14, 14, 17, //C
+ 4, 11, 9, 9, 0, 7, 7, 13, 0, 16, 0, 0, 22, 15, 15, 18, //D
+ 2, 10, 3, 19, 6, 6, 6, 12, 0, 1, 0, 0, 14, 14, 14, 17, //E
+ 4, 11, 9, 20,14, 7, 7, 13, 0, 16, 0, 0, 23, 15, 15, 18 //F
+};
+
+uint8 S9xOPrint (char *Line, uint8 Bank, uint16 Address)
+{
+ uint8 S9xOpcode;
+ uint8 Operant[3];
+ uint16 Word;
+ uint8 Byte;
+ uint8 Size = 0;
+ char SByte;
+ short SWord;
+
+#if 0
+ sprintf (Line, "%04X%04X%04X%04X%02X%04X%c%c%c%c%c%c%c%c%c%03d%03d",
+ Registers.A.W, Registers.X.W, Registers.Y.W,
+ Registers.D.W, Registers.DB, Registers.S.W,
+ CheckEmulation () ? 'E' : 'e',
+ CheckNegative () ? 'N' : 'n',
+ CheckOverflow () ? 'V' : 'v',
+ CheckMemory () ? 'M' : 'm',
+ CheckIndex () ? 'X' : 'x',
+ CheckDecimal () ? 'D' : 'd',
+ CheckIRQ () ? 'I' : 'i',
+ CheckZero () ? 'Z' : 'z',
+ CheckCarry () ? 'C' : 'c',
+ CPU.Cycles,
+ CPU.V_Counter);
+ return (0);
+
+#else
+ uint32 Cycles = CPU.Cycles;
+ uint8 *WaitAddress = CPU.WaitAddress;
+
+ S9xOpcode = S9xGetByte ((Bank << 16) + Address);
+ sprintf (Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
+ Operant[0] = S9xGetByte ((Bank << 16) + Address + 1);
+ Operant[1] = S9xGetByte ((Bank << 16) + Address + 2);
+ Operant[2] = S9xGetByte ((Bank << 16) + Address + 3);
+
+ switch (AddrModes[S9xOpcode])
+ {
+ case 0:
+ //Implied
+ sprintf (Line, "%s %s", Line, S9xMnemonics[S9xOpcode]);
+ Size = 1;
+ break;
+ case 1:
+ //Immediate[MemoryFlag]
+ if (!CheckFlag (MemoryFlag))
+ {
+ //Accumulator 16 - Bit
+ sprintf (Line, "%s%02X %02X %s #$%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Size = 3;
+ }
+ else
+ {
+ //Accumulator 8 - Bit
+ sprintf (Line, "%s%02X %s #$%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Size = 2;
+ }
+ break;
+ case 2:
+ //Immediate[IndexFlag]
+ if (!CheckFlag (IndexFlag))
+ {
+ //X / Y 16 - Bit
+ sprintf (Line, "%s%02X %02X %s #$%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Size = 3;
+ }
+ else
+ {
+ //X / Y 8 - Bit
+ sprintf (Line, "%s%02X %s #$%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Size = 2;
+ }
+ break;
+ case 3:
+ //Immediate[Always 8 - Bit]
+ if (1)
+ {
+ //Always 8 - Bit
+ sprintf (Line, "%s%02X %s #$%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Size = 2;
+ }
+ break;
+ case 4:
+ //Relative
+ sprintf (Line, "%s%02X %s $%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ SByte = Operant[0];
+ Word = Address;
+ Word += SByte;
+ Word += 2;
+ sprintf (Line, "%-32s[$%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 5:
+ //Relative Long
+ sprintf (Line, "%s%02X %02X %s $%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ SWord = (Operant[1] << 8) | Operant[0];
+ Word = Address;
+ Word += SWord;
+ Word += 3;
+ sprintf (Line, "%-32s[$%04X]", Line, Word);
+ Size = 3;
+ break;
+ case 6:
+ //Direct
+ sprintf (Line, "%s%02X %s $%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 7:
+ //Direct indexed (with x)
+ sprintf (Line, "%s%02X %s $%02X,x",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Word += Registers.X.W;
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 8:
+ //Direct indexed (with y)
+ sprintf (Line, "%s%02X %s $%02X,y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Word += Registers.Y.W;
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 9:
+ //Direct Indirect
+ sprintf (Line, "%s%02X %s ($%02X)",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Word = S9xGetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 2;
+ break;
+ case 10:
+ //Direct Indexed Indirect
+ sprintf (Line, "%s%02X %s ($%02X,x)",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Word += Registers.X.W;
+ Word = S9xGetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 2;
+ break;
+ case 11:
+ //Direct Indirect Indexed
+ sprintf (Line, "%s%02X %s ($%02X),y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Word = S9xGetWord (Word);
+ Word += Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 2;
+ break;
+ case 12:
+ //Direct Indirect Long
+ sprintf (Line, "%s%02X %s [$%02X]",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Byte = S9xGetByte (Word + 2);
+ Word = S9xGetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
+ Size = 2;
+ break;
+ case 13:
+ //Direct Indirect Indexed Long
+ sprintf (Line, "%s%02X %s [$%02X],y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += Registers.D.W;
+ Byte = S9xGetByte (Word + 2);
+ Word = S9xGetWord (Word);
+ Word += Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
+ Size = 2;
+ break;
+ case 14:
+ //Absolute
+ sprintf (Line, "%s%02X %02X %s $%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 3;
+ break;
+ case 15:
+ //Absolute Indexed (With X)
+ sprintf (Line, "%s%02X %02X %s $%02X%02X,x",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += Registers.X.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 3;
+ break;
+ case 16:
+ //Absolute Indexed (With Y)
+ sprintf (Line, "%s%02X %02X %s $%02X%02X,y",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 3;
+ break;
+ case 17:
+ //Absolute long
+ sprintf (Line, "%s%02X %02X %02X %s $%02X%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ Operant[2],
+ S9xMnemonics[S9xOpcode],
+ Operant[2],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
+ Size = 4;
+ break;
+ case 18:
+ //Absolute Indexed long
+ sprintf (Line, "%s%02X %02X %02X %s $%02X%02X%02X,x",
+ Line,
+ Operant[0],
+ Operant[1],
+ Operant[2],
+ S9xMnemonics[S9xOpcode],
+ Operant[2],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += Registers.X.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
+ Size = 4;
+ break;
+ case 19:
+ //StackRelative
+ sprintf (Line, "%s%02X %s $%02X,s",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Registers.S.W;
+ Word += Operant[0];
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 20:
+ //Stack Relative Indirect Indexed
+ sprintf (Line, "%s%02X %s ($%02X,s),y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Registers.S.W;
+ Word += Operant[0];
+ Word = S9xGetWord (Word);
+ Word += Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
+ Size = 2;
+ break;
+ case 21:
+ //Absolute Indirect
+ sprintf (Line, "%s%02X %02X %s ($%02X%02X)",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word = S9xGetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
+ Size = 3;
+ break;
+ case 22:
+ //Absolute Indirect Long
+ sprintf (Line, "%s%02X %02X %s [$%02X%02X]",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Byte = S9xGetByte (Word + 2);
+ Word = S9xGetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
+ Size = 3;
+ break;
+ case 23:
+ //Absolute Indexed Indirect
+ sprintf (Line, "%s%02X %02X %s ($%02X%02X,x)",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += Registers.X.W;
+ Word = S9xGetWord (ICPU.ShiftedPB + Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
+ Size = 3;
+ break;
+ case 24:
+ //Implied accumulator
+ sprintf (Line, "%s %s A", Line, S9xMnemonics[S9xOpcode]);
+ Size = 1;
+ break;
+ case 25:
+ // MVN/MVP SRC DST
+ sprintf (Line, "%s %s %02X %02X", Line, S9xMnemonics[S9xOpcode],
+ Operant[0], Operant[1]);
+ Size = 3;
+ break;
+ }
+// XXX:
+ sprintf (Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%03d VC:%03ld %02x",
+ Line, Registers.A.W, Registers.X.W, Registers.Y.W,
+ Registers.D.W, Registers.DB, Registers.S.W,
+ CheckEmulation () ? 'E' : 'e',
+ CheckNegative () ? 'N' : 'n',
+ CheckOverflow () ? 'V' : 'v',
+ CheckMemory () ? 'M' : 'm',
+ CheckIndex () ? 'X' : 'x',
+ CheckDecimal () ? 'D' : 'd',
+ CheckIRQ () ? 'I' : 'i',
+ CheckZero () ? 'Z' : 'z',
+ CheckCarry () ? 'C' : 'c',
+ Cycles,
+ CPU.V_Counter,
+ CPU.IRQActive);
+
+ CPU.Cycles = Cycles;
+ CPU.WaitAddress = WaitAddress;
+ return Size;
+#endif
+}
+
+uint8 S9xSA1OPrint (char *Line, uint8 Bank, uint16 Address)
+{
+ uint8 S9xOpcode;
+ uint8 Operant[3];
+ uint16 Word;
+ uint8 Byte;
+ uint8 Size = 0;
+ char SByte;
+ short SWord;
+
+#if 0
+ sprintf (Line, "%04X%04X%04X%04X%02X%04X%c%c%c%c%c%c%c%c%c%03d%03d",
+ SA1Registers.A.W, SA1Registers.X.W, SA1Registers.Y.W,
+ SA1Registers.D.W, SA1Registers.DB, SA1Registers.S.W,
+ SA1CheckEmulation () ? 'E' : 'e',
+ SA1CheckNegative () ? 'N' : 'n',
+ SA1CheckOverflow () ? 'V' : 'v',
+ SA1CheckMemory () ? 'M' : 'm',
+ SA1CheckIndex () ? 'X' : 'x',
+ SA1CheckDecimal () ? 'D' : 'd',
+ SA1CheckIRQ () ? 'I' : 'i',
+ SA1CheckZero () ? 'Z' : 'z',
+ SA1CheckCarry () ? 'C' : 'c',
+ CPU.Cycles,
+ CPU.V_Counter);
+ return (0);
+
+#else
+ S9xOpcode = S9xSA1GetByte ((Bank << 16) + Address);
+ sprintf (Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
+ Operant[0] = S9xSA1GetByte ((Bank << 16) + Address + 1);
+ Operant[1] = S9xSA1GetByte ((Bank << 16) + Address + 2);
+ Operant[2] = S9xSA1GetByte ((Bank << 16) + Address + 3);
+
+ switch (AddrModes[S9xOpcode])
+ {
+ case 0:
+ //Implied
+ sprintf (Line, "%s %s", Line, S9xMnemonics[S9xOpcode]);
+ Size = 1;
+ break;
+ case 1:
+ //Immediate[MemoryFlag]
+ if (!SA1CheckFlag (MemoryFlag))
+ {
+ //Accumulator 16 - Bit
+ sprintf (Line, "%s%02X %02X %s #$%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Size = 3;
+ }
+ else
+ {
+ //Accumulator 8 - Bit
+ sprintf (Line, "%s%02X %s #$%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Size = 2;
+ }
+ break;
+ case 2:
+ //Immediate[IndexFlag]
+ if (!SA1CheckFlag (IndexFlag))
+ {
+ //X / Y 16 - Bit
+ sprintf (Line, "%s%02X %02X %s #$%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Size = 3;
+ }
+ else
+ {
+ //X / Y 8 - Bit
+ sprintf (Line, "%s%02X %s #$%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Size = 2;
+ }
+ break;
+ case 3:
+ //Immediate[Always 8 - Bit]
+ if (1)
+ {
+ //Always 8 - Bit
+ sprintf (Line, "%s%02X %s #$%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Size = 2;
+ }
+ break;
+ case 4:
+ //Relative
+ sprintf (Line, "%s%02X %s $%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ SByte = Operant[0];
+ Word = Address;
+ Word += SByte;
+ Word += 2;
+ sprintf (Line, "%-32s[$%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 5:
+ //Relative Long
+ sprintf (Line, "%s%02X %02X %s $%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ SWord = (Operant[1] << 8) | Operant[0];
+ Word = Address;
+ Word += SWord;
+ Word += 3;
+ sprintf (Line, "%-32s[$%04X]", Line, Word);
+ Size = 3;
+ break;
+ case 6:
+ //Direct
+ sprintf (Line, "%s%02X %s $%02X",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 7:
+ //Direct indexed (with x)
+ sprintf (Line, "%s%02X %s $%02X,x",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Word += SA1Registers.X.W;
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 8:
+ //Direct indexed (with y)
+ sprintf (Line, "%s%02X %s $%02X,y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Word += SA1Registers.Y.W;
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 9:
+ //Direct Indirect
+ sprintf (Line, "%s%02X %s ($%02X)",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Word = S9xSA1GetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 2;
+ break;
+ case 10:
+ //Direct Indexed Indirect
+ sprintf (Line, "%s%02X %s ($%02X,x)",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Word += SA1Registers.X.W;
+ Word = S9xSA1GetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 2;
+ break;
+ case 11:
+ //Direct Indirect Indexed
+ sprintf (Line, "%s%02X %s ($%02X),y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Word = S9xSA1GetWord (Word);
+ Word += SA1Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 2;
+ break;
+ case 12:
+ //Direct Indirect Long
+ sprintf (Line, "%s%02X %s [$%02X]",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Byte = S9xSA1GetByte (Word + 2);
+ Word = S9xSA1GetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
+ Size = 2;
+ break;
+ case 13:
+ //Direct Indirect Indexed Long
+ sprintf (Line, "%s%02X %s [$%02X],y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = Operant[0];
+ Word += SA1Registers.D.W;
+ Byte = S9xSA1GetByte (Word + 2);
+ Word = S9xSA1GetWord (Word);
+ Word += SA1Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
+ Size = 2;
+ break;
+ case 14:
+ //Absolute
+ sprintf (Line, "%s%02X %02X %s $%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 3;
+ break;
+ case 15:
+ //Absolute Indexed (With X)
+ sprintf (Line, "%s%02X %02X %s $%02X%02X,x",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += SA1Registers.X.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 3;
+ break;
+ case 16:
+ //Absolute Indexed (With Y)
+ sprintf (Line, "%s%02X %02X %s $%02X%02X,y",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += SA1Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 3;
+ break;
+ case 17:
+ //Absolute long
+ sprintf (Line, "%s%02X %02X %02X %s $%02X%02X%02X",
+ Line,
+ Operant[0],
+ Operant[1],
+ Operant[2],
+ S9xMnemonics[S9xOpcode],
+ Operant[2],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
+ Size = 4;
+ break;
+ case 18:
+ //Absolute Indexed long
+ sprintf (Line, "%s%02X %02X %02X %s $%02X%02X%02X,x",
+ Line,
+ Operant[0],
+ Operant[1],
+ Operant[2],
+ S9xMnemonics[S9xOpcode],
+ Operant[2],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += SA1Registers.X.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
+ Size = 4;
+ break;
+ case 19:
+ //StackRelative
+ sprintf (Line, "%s%02X %s $%02X,s",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = SA1Registers.S.W;
+ Word += Operant[0];
+ sprintf (Line, "%-32s[$00:%04X]", Line, Word);
+ Size = 2;
+ break;
+ case 20:
+ //Stack Relative Indirect Indexed
+ sprintf (Line, "%s%02X %s ($%02X,s),y",
+ Line,
+ Operant[0],
+ S9xMnemonics[S9xOpcode],
+ Operant[0]);
+ Word = SA1Registers.S.W;
+ Word += Operant[0];
+ Word = S9xSA1GetWord (Word);
+ Word += SA1Registers.Y.W;
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
+ Size = 2;
+ break;
+ case 21:
+ //Absolute Indirect
+ sprintf (Line, "%s%02X %02X %s ($%02X%02X)",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word = S9xSA1GetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
+ Size = 3;
+ break;
+ case 22:
+ //Absolute Indirect Long
+ sprintf (Line, "%s%02X %02X %s [$%02X%02X]",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Byte = S9xSA1GetByte (Word + 2);
+ Word = S9xSA1GetWord (Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
+ Size = 3;
+ break;
+ case 23:
+ //Absolute Indexed Indirect
+ sprintf (Line, "%s%02X %02X %s ($%02X%02X,x)",
+ Line,
+ Operant[0],
+ Operant[1],
+ S9xMnemonics[S9xOpcode],
+ Operant[1],
+ Operant[0]);
+ Word = (Operant[1] << 8) | Operant[0];
+ Word += SA1Registers.X.W;
+ Word = S9xSA1GetWord (SA1.ShiftedPB + Word);
+ sprintf (Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
+ Size = 3;
+ break;
+ case 24:
+ //Implied accumulator
+ sprintf (Line, "%s %s A", Line, S9xMnemonics[S9xOpcode]);
+ Size = 1;
+ break;
+ case 25:
+ // MVN/MVP SRC DST
+ sprintf (Line, "%s %s %02X %02X", Line, S9xMnemonics[S9xOpcode],
+ Operant[0], Operant[1]);
+ Size = 3;
+ break;
+ }
+ sprintf (Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%03ld VC:%03ld",
+ Line, SA1Registers.A.W, SA1Registers.X.W, SA1Registers.Y.W,
+ SA1Registers.D.W, SA1Registers.DB, SA1Registers.S.W,
+ SA1CheckEmulation () ? 'E' : 'e',
+ SA1CheckNegative () ? 'N' : 'n',
+ SA1CheckOverflow () ? 'V' : 'v',
+ SA1CheckMemory () ? 'M' : 'm',
+ SA1CheckIndex () ? 'X' : 'x',
+ SA1CheckDecimal () ? 'D' : 'd',
+ SA1CheckIRQ () ? 'I' : 'i',
+ SA1CheckZero () ? 'Z' : 'z',
+ SA1CheckCarry () ? 'C' : 'c',
+ CPU.Cycles,
+ CPU.V_Counter);
+
+ return Size;
+#endif
+}
+
+/**********************************************************************************************/
+/* DPrint() */
+/* This function prints a line in the debug listbox and deletes upperlines if needed */
+/**********************************************************************************************/
+void DPrint (char *Line)
+{
+ printf ("%s\n", Line);
+}
+/**********************************************************************************************/
+/* GetNumber() */
+/* This function gets a number from a debug command */
+/**********************************************************************************************/
+int GetNumber (char *Line, uint16 * Number)
+{
+ int i;
+ if (sscanf (Line, " #%d", &i) == 1)
+ {
+ *Number = i;
+ return (1);
+ }
+ return (-1);
+}
+/**********************************************************************************************/
+/* GetStartAddress() */
+/* This function gets a starting address from a debug command */
+/**********************************************************************************************/
+short GetStartAddress (char *Line, uint8 *Bank, uint32 *Address)
+{
+ int a, b;
+ if (sscanf (Line + 1, " $%x:%x", &b, &a) != 2)
+ return (-1);
+ *Bank = b;
+ *Address = a;
+ return (1);
+}
+/**********************************************************************************************/
+/* ProcessDebugCommand() */
+/* This function processes a debug command */
+/**********************************************************************************************/
+void ProcessDebugCommand (char *Line)
+{
+ uint8 Bank = Registers.PB;
+ uint32 Address = CPU.PC - CPU.PCBase;
+ uint16 Hold;
+ uint16 Number;
+ char String [512];
+ short ErrorCode;
+
+ if (strcasecmp (Line, "cheat") == 0)
+ {
+ S9xStartCheatSearch (&Cheat);
+ printf ("Cheat Search Started\n");
+ return;
+ }
+ if (strcasecmp (Line, "less") == 0)
+ {
+ S9xSearchForChange (&Cheat, S9X_LESS_THAN, S9X_8_BITS, FALSE, TRUE);
+ printf ("Recorded all values that have decreased\n");
+ return;
+ }
+ if (strcasecmp (Line, "print") == 0)
+ {
+ printf ("Cheat search results:\n");
+ S9xOutputCheatSearchResults (&Cheat);
+ return;
+ }
+
+ if (strncasecmp (Line, "constant", 8) == 0)
+ {
+ uint32 Byte;
+ if (sscanf (&Line [8], "%x %x", &Address, &Byte) == 2)
+ S9xAddCheat (TRUE, TRUE, Address, Byte);
+ return;
+ }
+
+ if (strncasecmp (Line, "dump", 4) == 0)
+ {
+ int Count;
+ if (sscanf (&Line [4], "%x %d", &Address, &Count) == 2)
+ {
+ sprintf (String, "%06x%05d.sd2", Address, Count);
+ FILE *fs = fopen (String, "wb");
+ if (fs)
+ {
+ int i;
+ for (i = 0; i < Count; i++)
+ putc (S9xGetByte (Address + i), fs);
+
+ fclose (fs);
+ }
+ else
+ printf ("Can't open %s for writing\n", String);
+ }
+ else
+ printf ("Usage: dump start_address_in_hex count_in_decimal\n");
+ return;
+ }
+ if (Line[0] == 'i')
+ {
+ printf ("Vectors:\n");
+ sprintf (String, " 8 Bit 16 Bit ");
+ DPrint (String);
+ sprintf (String, "ABT $00:%04X|$00:%04X", S9xGetWord (0xFFF8), S9xGetWord (0xFFE8));
+ DPrint (String);
+ sprintf (String, "BRK $00:%04X|$00:%04X", S9xGetWord (0xFFFE), S9xGetWord (0xFFE6));
+ DPrint (String);
+ sprintf (String, "COP $00:%04X|$00:%04X", S9xGetWord (0xFFF4), S9xGetWord (0xFFE4));
+ DPrint (String);
+ sprintf (String, "IRQ $00:%04X|$00:%04X", S9xGetWord (0xFFFE), S9xGetWord (0xFFEE));
+ DPrint (String);
+ sprintf (String, "NMI $00:%04X|$00:%04X", S9xGetWord (0xFFFA), S9xGetWord (0xFFEA));
+ DPrint (String);
+ sprintf (String, "RES $00:%04X", S9xGetWord (0xFFFC));
+ DPrint (String);
+ }
+ if (strncmp (Line, "ai", 2) == 0)
+ {
+ printf ("APU vectors:");
+ for (int i = 0; i < 0x40; i += 2)
+ {
+ if (i % 16 == 0)
+ printf ("\n%04x ", 0xffc0 + i);
+ printf ("%04x ", APU.ExtraRAM [i]);
+ }
+ printf ("\n");
+ }
+ if (Line[0] == 's')
+ {
+ CPU.PC += S9xOPrint (String, Bank, Address);
+ Bank = Registers.PB;
+ Address = CPU.PC - CPU.PCBase;
+ Line[0] = 'r';
+ }
+ if (Line[0] == 'z')
+ {
+ uint16 *p = (uint16 *) &Memory.VRAM [PPU.BG[2].SCBase << 1];
+ for (int l = 0; l < 32; l++)
+ {
+ for (int c = 0; c < 32; c++, p++)
+ {
+ printf ("%04x,", *p++);
+ }
+ printf ("\n");
+ }
+ }
+ if (*Line == 'c')
+ {
+ printf ("Colours:\n");
+ for (int i = 0; i < 256; i++)
+ {
+ printf ("%02x%02x%02x ", PPU.CGDATA[i] & 0x1f,
+ (PPU.CGDATA[i] >> 5) & 0x1f,
+ (PPU.CGDATA[i] >> 10) & 0x1f);
+ }
+ printf ("\n");
+ }
+ if (*Line == 'S')
+ {
+ int SmallWidth, LargeWidth;
+ int SmallHeight, LargeHeight;
+ switch ((Memory.FillRAM[0x2101] >> 5) & 7)
+ {
+ case 0:
+ SmallWidth = SmallHeight = 8;
+ LargeWidth = LargeHeight = 16;
+ break;
+ case 1:
+ SmallWidth = SmallHeight = 8;
+ LargeWidth = LargeHeight = 32;
+ break;
+ case 2:
+ SmallWidth = SmallHeight = 8;
+ LargeWidth = LargeHeight = 64;
+ break;
+ case 3:
+ SmallWidth = SmallHeight = 16;
+ LargeWidth = LargeHeight = 32;
+ break;
+ case 4:
+ SmallWidth = SmallHeight = 16;
+ LargeWidth = LargeHeight = 64;
+ break;
+ default:
+ case 5:
+ SmallWidth = SmallHeight = 32;
+ LargeWidth = LargeHeight = 64;
+ break;
+ case 6:
+ SmallWidth = 16; SmallHeight = 32;
+ LargeWidth = 32; LargeHeight = 64;
+ break;
+ case 7:
+ SmallWidth = 16; SmallHeight = 32;
+ LargeWidth = LargeHeight = 32;
+ break;
+ }
+ printf ("Sprites: Small: %dx%d, Large: %dx%d, OAMAddr: 0x%04x, OBJNameBase: 0x%04x, OBJNameSelect: 0x%04x, First: %d\n",
+ SmallWidth,SmallHeight, LargeWidth,LargeHeight, PPU.OAMAddr,
+ PPU.OBJNameBase, PPU.OBJNameSelect, PPU.FirstSprite);
+// for (int p = 0; p < 4; p++)
+// {
+// int c = 0;
+// int i;
+// for (i = 0; GFX.OBJList [i] >= 0; i++)
+// {
+// if (PPU.OBJ[GFX.OBJList [i]].Priority == p)
+// c++;
+// }
+// printf ("Priority %d: %03d, ", p, c);
+// }
+// printf ("\n");
+ for (int i = 0; i < 128; i++)
+ {
+ printf ("X:%3d Y:%3d %c%c%d%c ",
+ PPU.OBJ[i].HPos,
+ PPU.OBJ[i].VPos,
+ PPU.OBJ[i].VFlip ? 'V' : 'v',
+ PPU.OBJ[i].HFlip ? 'H' : 'h',
+ PPU.OBJ[i].Priority,
+ PPU.OBJ[i].Size ? 'S' : 's');
+ if (i % 4 == 3)
+ printf ("\n");
+ }
+ }
+ if (*Line == 'T')
+ {
+ if (Line [1] == 'S')
+ {
+ SA1.Flags ^= TRACE_FLAG;
+ if (SA1.Flags & TRACE_FLAG)
+ {
+ printf ("SA1 CPU instruction tracing enabled.\n");
+ if (trace2 == NULL)
+ trace2 = fopen ("trace_sa1.log", "wb");
+ }
+ else
+ {
+ printf ("SA1 CPU instruction tracing disabled.\n");
+ fclose (trace2);
+ trace2 = NULL;
+ }
+ }
+ else
+ {
+ CPU.Flags ^= TRACE_FLAG;
+ if (CPU.Flags & TRACE_FLAG)
+ {
+ printf ("CPU instruction tracing enabled.\n");
+ if (trace == NULL)
+ trace = fopen ("trace.log", "wb");
+ }
+ else
+ {
+ printf ("CPU instruction tracing disabled.\n");
+ fclose (trace);
+ trace = NULL;
+ }
+ }
+ }
+ if (*Line == 'A')
+ {
+ APU.Flags ^= TRACE_FLAG;
+
+ extern FILE *apu_trace;
+ if (APU.Flags & TRACE_FLAG)
+ {
+#ifdef SPCTOOL
+ printf ("ENABLED\n");
+ _SetSPCDbg (TraceSPC); //Install debug handler
+#endif
+ if (apu_trace == NULL)
+ apu_trace = fopen ("aputrace.log", "wb");
+ }
+ else
+ {
+#ifdef SPCTOOL
+ _SetSPCDbg (NULL);
+#endif
+ if (apu_trace)
+ {
+ fclose (apu_trace);
+ apu_trace = NULL;
+ }
+ }
+
+ printf ("APU tracing %s\n", APU.Flags & TRACE_FLAG ? "enabled" :
+ "disabled");
+ }
+ if (*Line == 'B')
+ {
+ Settings.TraceSoundDSP ^= 1;
+ printf ("Sound DSP register tracing %s\n", Settings.TraceSoundDSP ?
+ "enabled" : "disabled");
+
+ S9xOpenCloseSoundTracingFile (Settings.TraceSoundDSP);
+ }
+
+ if (*Line == 'b')
+ S9xPrintAPUState ();
+
+ if (*Line == 'C')
+ {
+ printf ("SPC700 sample addresses at 0x%04x:\n", APU.DSP [APU_DIR] << 8);
+ for (int i = 0; i < 256; i++)
+ {
+ uint8 *dir = IAPU.RAM +
+ (((APU.DSP [APU_DIR] << 8) +
+ i * 4) & 0xffff);
+ int addr = *dir + (*(dir + 1) << 8);
+ int addr2 = *(dir + 2) + (*(dir + 3) << 8);
+ printf ("%04X %04X;", addr, addr2);
+ if (i % 8 == 7)
+ printf ("\n");
+ }
+ }
+ if (*Line == 'R')
+ {
+ S9xReset ();
+ printf ("SNES reset.\n");
+ CPU.Flags |= DEBUG_MODE_FLAG;
+ }
+ if (strncmp (Line, "ad", 2) == 0)
+ {
+ int Count = 16;
+ Address = 0;
+ if (sscanf (Line+2, "%x,%x", &Address, &Count) != 2)
+ {
+ if (sscanf (Line + 2, "%x", &Address) == 1)
+ Count = 16;
+ }
+ printf ("APU RAM dump:\n");
+ for (int l = 0; l < Count; l += 16)
+ {
+ printf ("%04X ", Address);
+ for (int i = 0; i < 16; i++)
+ printf ("%02X ", IAPU.RAM [Address++]);
+ printf ("\n");
+ }
+ *Line = 0;
+ }
+ if (*Line == 'a')
+ {
+ printf ("APU in-ports: %02X %02X %02X %02X\n",
+ IAPU.RAM [0xF4], IAPU.RAM [0xF5], IAPU.RAM [0xF6], IAPU.RAM [0xF7]);
+#ifdef SPCTOOL
+ printf ("APU out-ports: %02X %02X %02X %02X\n",
+ _SPCOutP [0], _SPCOutP [1], _SPCOutP [2], _SPCOutP [3]);
+#else
+ printf ("APU out-ports: %02X %02X %02X %02X\n",
+ APU.OutPorts [0], APU.OutPorts [1], APU.OutPorts [2], APU.OutPorts [3]);
+#endif
+ printf ("ROM/RAM switch: %s\n", (IAPU.RAM [0xf1] & 0x80) ? "ROM" : "RAM");
+ for (int i = 0; i < 3; i++)
+ if (APU.TimerEnabled [i])
+ printf ("Timer%d enabled, Value: 0x%03X, 4-bit: 0x%02X, Target: 0x%03X\n",
+ i, APU.Timer [i], IAPU.RAM [0xfd + i], APU.TimerTarget [i]);
+ }
+ if (*Line == 'P')
+ {
+ Settings.TraceDSP = !Settings.TraceDSP;
+ printf ("DSP tracing %s\n", Settings.TraceDSP ? "enabled" : "disabled");
+ }
+ if (Line[0] == 'p')
+ {
+ S9xBreakpoint[5].Enabled = FALSE;
+ Address += S9xOPrint (String, Bank, Address);
+ if (strncmp (&String[18], "JMP", 3) != 0 &&
+ strncmp (&String[18], "JML", 3) != 0 &&
+ strncmp (&String[18], "RT", 2) != 0 &&
+ strncmp (&String[18], "BRA", 3))
+ {
+ S9xBreakpoint[5].Enabled = TRUE;
+ S9xBreakpoint[5].Bank = Bank;
+ S9xBreakpoint[5].Address = Address;
+ }
+ else
+ {
+ CPU.Flags |= SINGLE_STEP_FLAG;
+ CPU.Flags &= ~DEBUG_MODE_FLAG;
+ }
+ }
+ if (Line[0] == 'b')
+ {
+ if (Line[1] == 's')
+ {
+ GetNumber (Line + 2, &Hold);
+ if (Hold > 4)
+ Hold = 0;
+ if (Hold < 5)
+ if (GetStartAddress (Line + 5, &Bank, &Address) == -1)
+ {
+ //Clear S9xBreakpoint
+ S9xBreakpoint[Hold].Enabled = FALSE;
+ }
+ else
+ {
+ //Set S9xBreakpoint
+ S9xBreakpoint[Hold].Enabled = TRUE;
+ S9xBreakpoint[Hold].Bank = Bank;
+ S9xBreakpoint[Hold].Address = Address;
+ CPU.Flags |= BREAK_FLAG;
+ }
+ Line = "bv";
+ }
+ if (Line[1] == 'v')
+ {
+ Number = 0;
+ if (GetNumber (Line + 2, &Number) == -1 &&
+ Number < 5)
+ {
+ //Show All Breakpoints
+ DPrint ("Breakpoints:");
+ for (Number = 0; Number != 5; Number++)
+ {
+ if (S9xBreakpoint[Number].Enabled)
+ sprintf (String, "%i @ $%02X:%04X", Number, S9xBreakpoint[Number].Bank, S9xBreakpoint[Number].Address);
+ else
+ sprintf (String, "%i @ Disabled", Number);
+ DPrint (String);
+ }
+ }
+ else
+ {
+ //Show selected S9xBreakpoint
+ DPrint ("Breakpoint:");
+ if (S9xBreakpoint[Number].Enabled)
+ sprintf (String, "%i @ $%02X:%04X", Number, S9xBreakpoint[Number].Bank, S9xBreakpoint[Number].Address);
+ else
+ sprintf (String, "%i @ Disabled", Number);
+ DPrint (String);
+ }
+ }
+ }
+ if (Line[0] == '?' || strcasecmp (Line, "help") == 0)
+ {
+ for (short Counter = 0; HelpMessage[Counter] != NULL; Counter++)
+ DPrint (HelpMessage[Counter]);
+ }
+ if (Line[0] == 't')
+ {
+ CPU.Flags |= SINGLE_STEP_FLAG;
+ CPU.Flags &= ~DEBUG_MODE_FLAG;
+ }
+ if (Line[0] == 'f')
+ {
+ CPU.Flags |= FRAME_ADVANCE_FLAG;
+ CPU.Flags &= ~DEBUG_MODE_FLAG;
+ // Render this frame
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.FrameSkip = 0;
+ if (sscanf (&Line [1], "%d", &ICPU.FrameAdvanceCount) != 1)
+ ICPU.Frame = 0;
+ }
+
+ if (Line[0] == 'g')
+ {
+ S9xBreakpoint[5].Enabled = FALSE;
+ int i;
+ bool8 found = FALSE;
+ for (i = 0; i < 5; i++)
+ {
+ if (S9xBreakpoint[i].Enabled)
+ {
+ found = TRUE;
+ if (S9xBreakpoint[i].Bank == Registers.PB &&
+ S9xBreakpoint[i].Address == CPU.PC - CPU.PCBase)
+ {
+ S9xBreakpoint[i].Enabled = 2;
+ break;
+ }
+ }
+ }
+ if (!found)
+ CPU.Flags &= ~BREAK_FLAG;
+ ErrorCode = GetStartAddress (Line, &Bank, &Address);
+ if (ErrorCode == 1)
+ {
+ S9xBreakpoint[5].Enabled = TRUE;
+ S9xBreakpoint[5].Bank = Bank;
+ S9xBreakpoint[5].Address = Address;
+ CPU.Flags |= BREAK_FLAG;
+ }
+ CPU.Flags &= ~DEBUG_MODE_FLAG;
+ }
+ if (*Line == 'D')
+ {
+ Settings.TraceDMA = !Settings.TraceDMA;
+ printf ("DMA tracing %s\n", Settings.TraceDMA ? "enabled" : "disabled");
+ }
+ if (*Line == 'V')
+ {
+ Settings.TraceVRAM = !Settings.TraceVRAM;
+ printf ("Non-DMA VRAM write tracing %s\n", Settings.TraceVRAM ? "enabled" : "disabled");
+ }
+ if (*Line == 'H')
+ {
+ Settings.TraceHDMA = !Settings.TraceHDMA;
+ printf ("H-DMA tracing %s\n", Settings.TraceHDMA ? "enabled" : "disabled");
+ }
+ if (*Line == 'U')
+ {
+ Settings.TraceUnknownRegisters = !Settings.TraceUnknownRegisters;
+ printf ("Unknown registers read/write tracing %s\n",
+ Settings.TraceUnknownRegisters ? "enabled" : "disabled");
+ }
+ if (Line[0] == 'd')
+ {
+ int CLine;
+ int CByte;
+ uint32 Cycles = CPU.Cycles;
+ uint8 MemoryByte;
+
+ if (Debug.Dump.Bank != 0 || Debug.Dump.Address != 0)
+ {
+ Bank = Debug.Dump.Bank;
+ Address = Debug.Dump.Address;
+ }
+ ErrorCode = GetStartAddress (Line, &Bank, &Address);
+ for (CLine = 0; CLine != 10; CLine++)
+ {
+ sprintf (String, "$%02X:%04X", Bank, Address);
+ for (CByte = 0; CByte != 16; CByte++)
+ {
+ if (Address + CByte == 0x2140 ||
+ Address + CByte == 0x2141 ||
+ Address + CByte == 0x2142 ||
+ Address + CByte == 0x2143 ||
+ Address + CByte == 0x4210)
+ {
+ MemoryByte = 0;
+ }
+ else
+ {
+ MemoryByte = S9xGetByte ((Bank << 16) + Address + CByte);
+ }
+ sprintf (String, "%s %02X", String, MemoryByte);
+ }
+ sprintf (String, "%s-", String);
+ for (CByte = 0; CByte != 16; CByte++)
+ {
+ if (Address + CByte == 0x2140 ||
+ Address + CByte == 0x2141 ||
+ Address + CByte == 0x2142 ||
+ Address + CByte == 0x2143 ||
+ Address + CByte == 0x4210)
+ {
+ MemoryByte = 0;
+ }
+ else
+ {
+ MemoryByte = S9xGetByte ((Bank << 16) + Address + CByte);
+ }
+ if (MemoryByte < 32 || MemoryByte >= 127)
+ MemoryByte = '?';
+ sprintf (String, "%s%c", String, MemoryByte);
+ }
+ Address += 16;
+ DPrint (String);
+ }
+ Debug.Dump.Bank = Bank;
+ Debug.Dump.Address = Address;
+ CPU.Cycles = Cycles;
+ }
+
+ if (*Line == 'q')
+ S9xExit ();
+ if (*Line == 'W')
+ WhatsMissing ();
+ if (*Line == 'w')
+ WhatsUsed ();
+ if (Line[0] == 'r')
+ {
+#if 0
+ sprintf (String,
+ "A[%04X] X[%04X] Y[%04X] S[%04X] D[%04X] DB[%02X] P[%02X] F[%s %s %s %s %s %s %s %s / %s]",
+ Registers.A.W,
+ Registers.X.W,
+ Registers.Y.W,
+ Registers.S.W,
+ Registers.D.W,
+ Registers.DB,
+ Registers.PL,
+ (Registers.P.W & 128) != 0 ? "N" : "n",
+ (Registers.P.W & 64) != 0 ? "V" : "v",
+ (Registers.P.W & 32) != 0 ? "M" : "m",
+ (Registers.P.W & 16) != 0 ? "X" : "x",
+ (Registers.P.W & 8) != 0 ? "D" : "d",
+ (Registers.P.W & 4) != 0 ? "I" : "i",
+ (Registers.P.W & 2) != 0 ? "Z" : "z",
+ (Registers.P.W & 1) != 0 ? "C" : "c",
+ (Registers.P.W & 256) != 0 ? "E" : "e");
+ DPrint (String);
+#endif
+ S9xOPrint (String, Bank, Address);
+ DPrint (String);
+ }
+ if (Line[0] == 'u')
+ {
+ if (Debug.Unassemble.Bank != 0 || Debug.Unassemble.Address != 0)
+ {
+ Bank = Debug.Unassemble.Bank;
+ Address = Debug.Unassemble.Address;
+ }
+ ErrorCode = GetStartAddress (Line, &Bank, &Address);
+ for (short Counter = 0; Counter != 10; Counter++)
+ {
+ Address += S9xOPrint (String, Bank, Address);
+ DPrint (String);
+ }
+ Debug.Unassemble.Bank = Bank;
+ Debug.Unassemble.Address = Address;
+ }
+ DPrint ("");
+ return;
+}
+static void PrintWindow (uint8 * a)
+{
+ for (int i = 0; i < 6; i++)
+ if (a[i])
+ switch (i)
+ {
+ case 0:
+ printf ("Background 0, ");
+ break;
+ case 1:
+ printf ("Background 1, ");
+ break;
+ case 2:
+ printf ("Background 2, ");
+ break;
+ case 3:
+ printf ("Background 3, ");
+ break;
+ case 4:
+ printf ("Objects, ");
+ break;
+ case 5:
+ printf ("Colour window, ");
+ break;
+ }
+}
+static char *ClipFn (int logic)
+{
+ switch (logic)
+ {
+ case CLIP_OR:
+ return ("OR");
+ case CLIP_AND:
+ return ("AND");
+ case CLIP_XOR:
+ return ("XOR");
+ case CLIP_XNOR:
+ return ("XNOR");
+ default:
+ return ("???");
+ }
+}
+
+static void WhatsUsed ()
+{
+ printf ("V-line: %ld, H-Pos: %ld\n", CPU.V_Counter, CPU.Cycles);
+ printf ("Screen mode: %d, ", PPU.BGMode);
+ if (PPU.BGMode <= 1 && (Memory.FillRAM [0x2105] & 8))
+ printf ("(BG#2 Priority)");
+
+ printf ("Brightness: %d", PPU.Brightness);
+ if (Memory.FillRAM[0x2100] & 0x80)
+ printf (" (screen blanked)");
+ printf ("\n");
+ if (Memory.FillRAM[0x2133] & 1)
+ printf ("Interlace, ");
+ if (Memory.FillRAM[0x2133] & 4)
+ printf ("240 line visible, ");
+ if (Memory.FillRAM[0x2133] & 8)
+ printf ("Pseudo 512 pixels horizontal resolution, ");
+ if (Memory.FillRAM[0x2133] & 0x40)
+ printf ("Mode 7 priority per pixel, ");
+ printf ("\n");
+ if (PPU.BGMode == 7 && (Memory.FillRAM[0x211a] & 3))
+ printf ("Mode 7 flipping, ");
+ if (PPU.BGMode == 7)
+ printf ("Mode 7 screen repeat: %d,", (Memory.FillRAM[0x211a] & 0xc0) >> 6);
+ if (Memory.FillRAM[0x2130] & 1)
+ printf ("32K colour mode, ");
+ if (PPU.BGMode == 7)
+ {
+ // Sign extend 13 bit values to 16 bit values...
+ if (PPU.CentreX & (1 << 12))
+ PPU.CentreX |= 0xe000;
+ if (PPU.CentreY & (1 << 12))
+ PPU.CentreY |= 0xe000;
+
+ printf ("\nMatrix A: %.3f, B: %.3f, C: %.3f, D: %.3f, Centre X: %d Y:%d\n",
+ (double) PPU.MatrixA / 256, (double) PPU.MatrixB / 256,
+ (double) PPU.MatrixC / 256, (double) PPU.MatrixD / 256,
+ PPU.CentreX, PPU.CentreY);
+ }
+ if ((Memory.FillRAM[0x2106] & 0xf0) && (Memory.FillRAM[0x2106] & 0x0f))
+ {
+ printf ("\nMosaic effect(%d) on ", PPU.Mosaic);
+ for (int i = 0; i < 4; i++)
+ if (Memory.FillRAM[0x2106] & (1 << i))
+ printf ("BG%d,", i);
+ printf (",");
+ }
+ if (PPU.HVBeamCounterLatched)
+ printf ("V and H beam pos latched, ");
+ if (Memory.FillRAM[0x4200] & 0x20)
+ printf ("V-IRQ enabled at %d\n", PPU.IRQVBeamPos);
+ if (Memory.FillRAM[0x4200] & 0x10)
+ printf ("H-IRQ enabled at %d\n", PPU.IRQHBeamPos);
+ if (Memory.FillRAM[0x4200] & 0x80)
+ printf ("V-blank NMI enabled\n");
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ if (missing.hdma_this_frame & (1 << i))
+ {
+ printf ("H-DMA %d [%d] 0x%02X%04X->0x21%02X %s %s 0x%02X%04X %s addressing\n",
+ i, DMA[i].TransferMode,
+ DMA[i].ABank, DMA[i].AAddress, DMA[i].BAddress,
+ DMA[i].AAddressDecrement ? "dec" : "inc",
+ DMA[i].Repeat ? "repeat" : "continue",
+ DMA[i].IndirectBank, DMA[i].IndirectAddress,
+ DMA[i].HDMAIndirectAddressing ? "indirect" : "absolute");
+ }
+ }
+ for (i = 0; i < 8; i++)
+ {
+ if (missing.dma_this_frame & (1 << i))
+ {
+ printf ("DMA %d %d 0x%02X%04X->0x21%02X Num: %d %s\n",
+ i, DMA[i].TransferMode, DMA[i].ABank, DMA[i].AAddress,
+ DMA[i].BAddress, DMA[i].TransferBytes,
+ DMA[i].AAddressFixed ? "fixed" :
+ (DMA[i].AAddressDecrement ? "dec" : "inc"));
+ }
+ }
+ printf ("VRAM write address: 0x%04x(%s), Full Graphic: %d, Address inc: %d\n",
+ PPU.VMA.Address,
+ PPU.VMA.High ? "Byte" : "Word",
+ PPU.VMA.FullGraphicCount, PPU.VMA.Increment);
+
+ for (i = 0; i < 4; i++)
+ {
+ printf ("BG%d: VOffset:%d, HOffset:%d, W:%d, H:%d, TS:%d, BA:0x%04x, TA:0x%04X\n",
+ i, PPU.BG[i].VOffset, PPU.BG[i].HOffset,
+ (PPU.BG[i].SCSize & 1) * 32 + 32,
+ (PPU.BG[i].SCSize & 2) * 16 + 32,
+ PPU.BG[i].BGSize * 8 + 8,
+ PPU.BG[i].SCBase,
+ PPU.BG[i].NameBase);
+ }
+ char *s = "";
+ switch ((Memory.FillRAM [0x2130] & 0xc0) >> 6)
+ {
+ case 0: s = "always on"; break;
+ case 1: s = "inside"; break;
+ case 2: s = "outside"; break;
+ case 3: s = "always off"; break;
+ }
+ printf ("Main screen (%s): ", s);
+ for (i = 0; i < 5; i++)
+ if (Memory.FillRAM[0x212c] & (1 << i))
+ switch (i)
+ {
+ case 0:
+ printf ("BG0,");
+ break;
+ case 1:
+ printf ("BG1,");
+ break;
+ case 2:
+ printf ("BG2,");
+ break;
+ case 3:
+ printf ("BG3,");
+ break;
+ case 4:
+ printf ("OBJ,");
+ break;
+ }
+
+ switch ((Memory.FillRAM [0x2130] & 0x30) >> 4)
+ {
+ case 0: s = "always on"; break;
+ case 1: s = "inside"; break;
+ case 2: s = "outside"; break;
+ case 3: s = "always off"; break;
+ }
+
+ printf ("\nSub-screen (%s): ", s);
+ for (i = 0; i < 5; i++)
+ if (Memory.FillRAM[0x212d] & (1 << i))
+ switch (i)
+ {
+ case 0:
+ printf ("BG0,");
+ break;
+ case 1:
+ printf ("BG1,");
+ break;
+ case 2:
+ printf ("BG2,");
+ break;
+ case 3:
+ printf ("BG3,");
+ break;
+ case 4:
+ printf ("OBJ,");
+ break;
+ }
+ printf ("\n");
+ if ((Memory.FillRAM[0x2131] & 0x3f))
+ {
+ if (Memory.FillRAM[0x2131] & 0x80)
+ {
+ if (Memory.FillRAM[0x2130] & 0x02)
+ printf ("Subscreen subtract");
+ else
+ printf ("Fixed colour subtract");
+ }
+ else
+ {
+ if (Memory.FillRAM[0x2130] & 0x02)
+ printf ("Subscreen addition");
+ else
+ printf ("Fixed colour addition");
+ }
+ if (Memory.FillRAM [0x2131] & 0x40)
+ printf ("(half):");
+ else
+ printf (":");
+
+ for (i = 0; i < 6; i++)
+ if (Memory.FillRAM[0x2131] & (1 << i))
+ {
+ switch (i)
+ {
+ case 0:
+ printf ("BG0,");
+ break;
+ case 1:
+ printf ("BG1,");
+ break;
+ case 2:
+ printf ("BG2,");
+ break;
+ case 3:
+ printf ("BG3,");
+ break;
+ case 4:
+ printf ("OBJ,");
+ break;
+ case 5:
+ printf ("BACK,");
+ break;
+ }
+ }
+ printf ("\n");
+ }
+ printf ("\nWindow 1 (%d, %d, %02x, %02x): ", PPU.Window1Left,
+ PPU.Window1Right, Memory.FillRAM [0x212e], Memory.FillRAM [0x212f]);
+ for (i = 0; i < 6; i++)
+ if (PPU.ClipWindow1Enable [i])
+ switch (i)
+ {
+ case 0:
+ printf ("BG0(%s-%s),", PPU.ClipWindow1Inside [i] ? "I" : "O",
+ ClipFn (PPU.ClipWindowOverlapLogic[0]));
+ break;
+ case 1:
+ printf ("BG1(%s-%s),", PPU.ClipWindow1Inside [i] ? "I" : "O",
+ ClipFn (PPU.ClipWindowOverlapLogic[1]));
+ break;
+ case 2:
+ printf ("BG2(%s-%s),", PPU.ClipWindow1Inside [i] ? "I" : "O",
+ ClipFn (PPU.ClipWindowOverlapLogic[2]));
+ break;
+ case 3:
+ printf ("BG3(%s-%s),", PPU.ClipWindow1Inside [i] ? "I" : "O",
+ ClipFn (PPU.ClipWindowOverlapLogic[3]));
+ break;
+ case 4:
+ printf ("OBJ(%s-%s),", PPU.ClipWindow1Inside [i] ? "I" : "O",
+ ClipFn (PPU.ClipWindowOverlapLogic[4]));
+ break;
+ case 5:
+ printf ("COL(%s-%s)", PPU.ClipWindow1Inside [i] ? "I" : "O",
+ ClipFn (PPU.ClipWindowOverlapLogic[5]));
+ break;
+ }
+
+ printf ("\nWindow 2 (%d, %d): ", PPU.Window2Left,
+ PPU.Window2Right);
+ for (i = 0; i < 6; i++)
+ if (PPU.ClipWindow2Enable [i])
+ switch (i)
+ {
+ case 0:
+ printf ("BG0(%s),", PPU.ClipWindow2Inside [i] ? "I" : "O");
+ break;
+ case 1:
+ printf ("BG1(%s),", PPU.ClipWindow2Inside [i] ? "I" : "O");
+ break;
+ case 2:
+ printf ("BG2(%s),", PPU.ClipWindow2Inside [i] ? "I" : "O");
+ break;
+ case 3:
+ printf ("BG3(%s),", PPU.ClipWindow2Inside [i] ? "I" : "O");
+ break;
+ case 4:
+ printf ("OBJ(%s),", PPU.ClipWindow2Inside [i] ? "I" : "O");
+ break;
+ case 5:
+ printf ("COL(%s)", PPU.ClipWindow2Inside [i] ? "I" : "O");
+ break;
+ }
+
+ printf ("\nFixed colour: %02x%02x%02x\n", PPU.FixedColourRed,
+ PPU.FixedColourGreen, PPU.FixedColourBlue);
+}
+
+static void WhatsMissing ()
+{
+ printf ("Processor: ");
+ if (missing.emulate6502)
+ printf ("emulation mode, ");
+ if (missing.decimal_mode)
+ printf ("decimal mode,");
+ if (missing.mv_8bit_index)
+ printf ("MVP/MVN with 8bit index registers and XH or YH > 0,");
+ if (missing.mv_8bit_acc)
+ printf ("MVP/MVN with 8bit accumulator > 255");
+ printf ("\nScreen modes used:");
+ int i;
+ for (i = 0; i < 8; i++)
+ if (missing.modes[i])
+ printf (" %d,", i);
+ printf ("\n");
+ if (missing.interlace)
+ printf ("Interlace, ");
+ if (missing.pseudo_512)
+ printf ("Pseudo 512 pixels horizontal resolution, ");
+ if (missing.lines_239)
+ printf ("240 lines visible,");
+ if (missing.sprite_double_height)
+ printf ("double-hight sprites,");
+ printf ("\n");
+ if (missing.mode7_fx)
+ printf ("Mode 7 rotation/scaling, ");
+ if (missing.matrix_read)
+ printf ("Mode 7 read matrix registers, ");
+ if (missing.mode7_flip)
+ printf ("Mode 7 flipping, ");
+ if (missing.mode7_bgmode)
+ printf ("Mode 7 priority per pixel, ");
+ if (missing.direct)
+ printf ("Direct 32000 colour mode");
+ printf ("\n");
+ if (missing.mosaic)
+ printf ("Mosaic effect, ");
+ if (missing.subscreen)
+ printf ("Subscreen enabled, ");
+ if (missing.subscreen_add)
+ printf ("Subscreen colour add, ");
+ if (missing.subscreen_sub)
+ printf ("Subscreen colour subtract, ");
+ if (missing.fixed_colour_add)
+ printf ("Fixed colour add, ");
+ if (missing.fixed_colour_sub)
+ printf ("Fixed colour subtract");
+ printf ("\n");
+ printf ("Window 1 enabled on:");
+ PrintWindow (missing.window1);
+ printf ("\nWindow 2 enabled on:");
+ PrintWindow (missing.window2);
+ printf ("\n");
+ if (missing.bg_offset_read)
+ printf ("BG offset read, ");
+ if (missing.oam_address_read)
+ printf ("OAM address read,");
+ if (missing.sprite_priority_rotation)
+ printf ("Sprite priority rotation, ");
+ if (missing.fast_rom)
+ printf ("Fast 3.58MHz ROM access enabled, ");
+ if (missing.matrix_multiply)
+ printf ("Matrix multiply 16bit by 8bit used");
+ printf ("\n");
+ if (missing.virq)
+ printf ("V-position IRQ used at line %d, ", missing.virq_pos);
+ if (missing.hirq)
+ printf ("H-position IRQ used at position %d, ", missing.hirq_pos);
+ printf ("\n");
+ if (missing.h_v_latch)
+ printf ("H and V-Pos latched, ");
+ if (missing.h_counter_read)
+ printf ("H-Pos read, ");
+ if (missing.v_counter_read)
+ printf ("V-Pos read");
+ printf ("\n");
+ if (missing.oam_read)
+ printf ("OAM read, ");
+ if (missing.vram_read)
+ printf ("VRAM read, ");
+ if (missing.cgram_read)
+ printf ("CG-RAM read, ");
+ if (missing.wram_read)
+ printf ("WRAM read, ");
+ if (missing.dma_read)
+ printf ("DMA read,");
+ if (missing.vram_inc)
+ printf ("VRAM inc: %d,", missing.vram_inc);
+ if (missing.vram_full_graphic_inc)
+ printf ("VRAM full graphic inc: %d,", missing.vram_full_graphic_inc);
+ printf ("\n");
+ for (i = 0; i < 8; i++)
+ {
+ if (missing.hdma[i].used)
+ {
+ printf ("HDMA %d, 0x%02X%04X->0x21%02X %s ", i,
+ missing.hdma[i].abus_bank, missing.hdma[i].abus_address,
+ missing.hdma[i].bbus_address,
+ missing.hdma[i].indirect_address ? "indirect" : "absolute");
+ if (missing.hdma[i].force_table_address_write)
+ printf ("Forced address write, ");
+ if (missing.hdma[i].force_table_address_read)
+ printf ("Current address read, ");
+ if (missing.hdma[i].line_count_write)
+ printf ("Line count write, ");
+ if (missing.hdma[i].line_count_read)
+ printf ("Line count read");
+ printf ("\n");
+ }
+ }
+ for (i = 0; i < 8; i++)
+ {
+ if (missing.dma_channels & (1 << i))
+ {
+ printf ("DMA %d %d 0x%02X%04X->0x21%02X Num: %d %s\n",
+ i, DMA[i].TransferMode, DMA[i].ABank, DMA[i].AAddress,
+ DMA[i].BAddress, DMA[i].TransferBytes,
+ DMA[i].AAddressFixed ? "fixed" :
+ (DMA[i].AAddressDecrement ? "dec" : "inc"));
+ }
+ }
+ if (missing.unknownppu_read)
+ printf ("Read from unknown PPU register: $%04X\n", missing.unknownppu_read);
+ if (missing.unknownppu_write)
+ printf ("Write to unknown PPU register: $%04X\n", missing.unknownppu_write);
+ if (missing.unknowncpu_read)
+ printf ("Read from unknown CPU register: $%04X\n", missing.unknowncpu_read);
+ if (missing.unknowncpu_write)
+ printf ("Write to unknown CPU register: $%04X\n", missing.unknowncpu_write);
+ if (missing.unknowndsp_read)
+ printf ("Read from unknown DSP register: $%04X\n", missing.unknowndsp_read);
+ if (missing.unknowndsp_write)
+ printf ("Write to unknown DSP register: $%04X\n", missing.unknowndsp_write);
+}
+
+void S9xDoDebug ()
+{
+ char Line[513];
+ Debug.Dump.Bank = 0;
+ Debug.Dump.Address = 0;
+ Debug.Unassemble.Bank = 0;
+ Debug.Unassemble.Address = 0;
+ S9xTextMode ();
+ ProcessDebugCommand ("r");
+ while (CPU.Flags & DEBUG_MODE_FLAG)
+ {
+ printf ("> ");
+ fflush (stdout);
+ fgets (Line, sizeof (Line) - 1, stdin);
+ Line [strlen (Line) - 1] = 0;
+ ProcessDebugCommand (Line);
+ }
+ if (!(CPU.Flags & SINGLE_STEP_FLAG))
+ S9xGraphicsMode ();
+}
+
+void S9xTrace ()
+{
+ if(!trace)
+ trace=fopen("trace.log", "a");
+ char String [512];
+ S9xOPrint (String, Registers.PB, CPU.PC - CPU.PCBase);
+ fprintf (trace, "%s\n", String);
+}
+
+void S9xSA1Trace ()
+{
+ char String [512];
+ S9xSA1OPrint (String, SA1Registers.PB, SA1.PC - SA1.PCBase);
+ fprintf (trace2, "%s\n", String);
+ fflush (trace2);
+}
+
+void S9xTraceMessage (const char *s)
+{
+ if(s)
+ {
+ if (trace)
+ fprintf (trace, "%s\n", s);
+ else
+ if (trace2)
+ fprintf (trace2, "%s\n", s);
+ }
+}
+
+extern "C" void TraceSA1 ()
+{
+ SA1.Flags ^= TRACE_FLAG;
+ if (SA1.Flags & TRACE_FLAG)
+ {
+ printf ("SA1 CPU instruction tracing enabled.\n");
+ if (trace2 == NULL)
+ trace2 = fopen ("trace_sa1.log", "wb");
+ }
+ else
+ {
+ printf ("SA1 CPU instruction tracing disabled.\n");
+ fclose (trace2);
+ trace2 = NULL;
+ }
+}
+
+extern "C" void Trace ()
+{
+ CPU.Flags ^= TRACE_FLAG;
+ if (CPU.Flags & TRACE_FLAG)
+ {
+ if (trace == NULL)
+ trace = fopen ("trace.log", "wb");
+ printf ("CPU instruction tracing enabled.\n");
+ }
+ else
+ {
+ printf ("CPU instruction tracing disabled.\n");
+ fclose (trace);
+ trace = NULL;
+ }
+}
+
+#endif
+
diff --git a/source/debug.h b/source/debug.h
new file mode 100644
index 0000000..cdc1541
--- /dev/null
+++ b/source/debug.h
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+START_EXTERN_C
+void S9xDoDebug ();
+void S9xTrace ();
+void S9xSA1Trace ();
+void S9xTraceMessage (const char *);
+
+// Structures
+struct SBreakPoint{
+ bool8 Enabled;
+ uint8 Bank;
+ uint16 Address;
+};
+
+uint8 S9xOPrint( char *Line, uint8 Bank, uint16 Address);
+uint8 S9xSA1OPrint( char *Line, uint8 Bank, uint16 Address);
+
+extern struct SBreakPoint S9xBreakpoint[ 6];
+extern char *S9xMnemonics[256];
+END_EXTERN_C
+#endif
+
diff --git a/source/dependencies b/source/dependencies
new file mode 100644
index 0000000..756e72f
--- /dev/null
+++ b/source/dependencies
@@ -0,0 +1,167 @@
+i386/cpuexec.o: i386/cpuexec.S i386/asmstruc.h i386/offsets.h i386/asmops.h \
+ i386/spcops.h
+i386/cpuops.o: i386/cpuops.S i386/asmstruc.h i386/offsets.h i386/asmaddr.h \
+ i386/asmops.h i386/getset.S
+i386/getset.o: i386/getset.S
+i386/sa1gs.o: i386/sa1gs.S
+i386/sa1ops.o: i386/sa1ops.S i386/sa1struc.h i386/offsets.h i386/sa1addr.h \
+ i386/sa1ops.h i386/sa1gs.S
+i386/spc700.o: i386/spc700.S i386/asmstruc.h i386/offsets.h i386/spcops.h
+2xsai.o: 2xsai.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h gfx.h
+2xsaiwin.o: 2xsaiwin.cpp snes9x/snes9x.h snes9x/port.h snes9x/gfx.h
+apu.o: apu.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h spc700.h apu.h soundux.h cpuexec.h ppu.h gfx.h memmap.h \
+ snapshot.h
+apudebug.o: apudebug.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h spc700.h apu.h soundux.h cpuexec.h ppu.h gfx.h memmap.h
+c4.o: c4.cpp c4.h port.h pixform.h memmap.h snes9x.h ../language.h \
+ 65c816.h messages.h
+c4emu.o: c4emu.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h sar.h memmap.h ppu.h gfx.h c4.h
+cheats.o: cheats.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h cheats.h memmap.h
+cheats2.o: cheats2.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h cheats.h memmap.h
+clip.o: clip.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h
+cpu.o: cpu.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h dsp1.h cpuexec.h debug.h apu.h spc700.h \
+ dma.h sa1.h cheats.h srtc.h sdd1.h spc7110.h obc1.h
+cpuexec.o: cpuexec.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h cpuops.h ppu.h gfx.h cpuexec.h debug.h snapshot.h \
+ missing.h apu.h spc700.h dma.h fxemu.h sa1.h spc7110.h
+cpuops.o: cpuops.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h debug.h missing.h apu.h spc700.h sa1.h spc7110.h \
+ cpuexec.h ppu.h gfx.h cpuaddr.h cpuops.h cpumacro.h
+data.o: data.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h
+debug.o: debug.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h cpuops.h cheats.h ppu.h gfx.h cpuexec.h debug.h \
+ missing.h display.h apu.h spc700.h sa1.h spc7110.h
+dma.o: dma.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h cpuexec.h missing.h dma.h apu.h \
+ spc700.h sa1.h spc7110.h sdd1emu.h
+dsp1.o: dsp1.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h dsp1.h missing.h memmap.h dsp1emu.c dsp2emu.c dsp4emu.cpp \
+ dsp4.h
+dsp1emu.o: dsp1emu.c
+dsp2emu.o: dsp2emu.c
+dsp4emu.o: dsp4emu.cpp dsp4.h
+fxdbg.o: fxdbg.cpp fxemu.h fxinst.h
+fxemu.o: fxemu.cpp fxemu.h fxinst.h
+fxinst.o: fxinst.cpp fxemu.h fxinst.h
+gfx.o: gfx.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h cpuexec.h display.h apu.h spc700.h \
+ cheats.h screenshot.h font.h
+globals.o: globals.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h dsp1.h missing.h cpuexec.h debug.h \
+ apu.h spc700.h dma.h fxemu.h soundux.h cheats.h sa1.h netplay.h \
+ spc7110.h
+loadzip.o: loadzip.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h unzip/unzip.h
+memmap.o: memmap.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h cpuexec.h ppu.h gfx.h display.h cheats.h apu.h \
+ spc700.h sa1.h dsp1.h srtc.h sdd1.h spc7110.h seta.h unzip/unzip.h \
+ getset.h obc1.h
+movie.o: movie.cpp movie.h snes9x.h ../language.h port.h pixform.h \
+ 65c816.h messages.h cpuexec.h ppu.h gfx.h memmap.h snapshot.h
+netplay.o: netplay.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h cpuexec.h ppu.h gfx.h memmap.h netplay.h snapshot.h \
+ display.h
+obc1.o: obc1.cpp memmap.h snes9x.h ../language.h port.h pixform.h \
+ 65c816.h messages.h obc1.h
+offsets.o: offsets.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h apu.h spc700.h cpuexec.h sa1.h
+ppu.o: ppu.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h cpuexec.h missing.h apu.h spc700.h \
+ dma.h display.h sa1.h netplay.h sdd1.h srtc.h spc7110.h movie.h
+sa1.o: sa1.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h ppu.h gfx.h memmap.h cpuexec.h sa1.h
+sa1cpu.o: sa1cpu.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h cpuexec.h sa1.h cpuops.cpp debug.h \
+ missing.h apu.h spc700.h spc7110.h cpuaddr.h cpuops.h cpumacro.h
+screenshot.o: screenshot.cpp snes9x.h ../language.h port.h pixform.h \
+ 65c816.h messages.h memmap.h display.h gfx.h ppu.h screenshot.h
+sdd1.o: sdd1.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h sdd1.h display.h
+sdd1emu.o: sdd1emu.cpp port.h pixform.h sdd1emu.h
+server.o: server.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h netplay.h memmap.h snapshot.h
+seta.o: seta.cpp seta.h port.h pixform.h
+seta010.o: seta010.cpp seta.h port.h pixform.h memmap.h snes9x.h \
+ ../language.h 65c816.h messages.h
+seta011.o: seta011.cpp seta.h port.h pixform.h memmap.h snes9x.h \
+ ../language.h 65c816.h messages.h
+seta018.o: seta018.cpp seta.h port.h pixform.h memmap.h snes9x.h \
+ ../language.h 65c816.h messages.h
+snaporig.o: snaporig.cpp snapshot.h snes9x.h ../language.h port.h \
+ pixform.h 65c816.h messages.h snaporig.h memmap.h ppu.h gfx.h cpuexec.h \
+ display.h apu.h spc700.h soundux.h
+snapshot.o: snapshot.cpp snapshot.h snes9x.h ../language.h port.h \
+ pixform.h 65c816.h messages.h snaporig.h memmap.h ppu.h gfx.h cpuexec.h \
+ display.h apu.h spc700.h soundux.h sa1.h srtc.h sdd1.h spc7110.h \
+ movie.h
+snes9x.o: snes9x.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h display.h cheats.h
+sound.o: sound.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h soundux.h
+soundux.o: soundux.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h soundux.h apu.h spc700.h memmap.h cpuexec.h ppu.h gfx.h
+spc.o: spc.cpp
+spc700.o: spc700.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h spc700.h memmap.h display.h cpuexec.h ppu.h gfx.h apu.h \
+ apumem.h
+spc7110.o: spc7110.cpp spc7110.h port.h pixform.h memmap.h snes9x.h \
+ ../language.h 65c816.h messages.h display.h
+spccycles.o: spccycles.cpp
+spctool.o: spctool.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h spctool/dsp.h spctool/spc700.h spctool/soundmod.h apu.h \
+ spc700.h
+srtc.o: srtc.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h srtc.h memmap.h
+tile.o: tile.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h ppu.h gfx.h display.h tile.h
+win32.o: win32.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h ..\directx.h ..\Render.h memmap.h debug.h cpuexec.h ppu.h \
+ gfx.h snapshot.h apu.h spc700.h display.h soundux.h netplay.h movie.h \
+ ..\AVIOutput.h
+sh/cpuexec.o: sh/cpuexec.S sh/asmstruc.h sh/offsets.h sh/asmops.h \
+ sh/spcops.h
+sh/cpuops.o: sh/cpuops.S sh/asmstruc.h sh/offsets.h sh/asmaddr.h sh/asmops.h \
+ sh/getset.S
+sh/getset.o: sh/getset.S
+sh/sa1gs.o: sh/sa1gs.S
+sh/sa1ops.o: sh/sa1ops.S sh/sa1struc.h sh/offsets.h sh/sa1addr.h sh/sa1ops.h \
+ sh/sa1gs.S
+unix/aido.o: unix/aido.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h gfx.h unix/aido.h
+unix/config.o: unix/config.c snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h
+unix/ggi.o: unix/ggi.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h debug.h ppu.h gfx.h snapshot.h display.h apu.h \
+ spc700.h
+unix/glide.o: unix/glide.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h gfx.h 3d.h
+unix/opengl.o: unix/opengl.cpp snes9x.h ../language.h port.h pixform.h \
+ 65c816.h messages.h gfx.h 3d.h
+unix/snes9x_gui.o: unix/snes9x_gui.cpp unix/snes9x_gui.h snes9x.h \
+ ../language.h port.h pixform.h 65c816.h messages.h memmap.h display.h \
+ soundux.h cpuexec.h ppu.h gfx.h filesave.xpm fileopen.xpm fileprint.xpm
+unix/svga.o: unix/svga.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h debug.h ppu.h gfx.h snapshot.h display.h apu.h \
+ spc700.h
+unix/tvmode.o: unix/tvmode.cpp
+unix/unix.o: unix/unix.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h debug.h cpuexec.h ppu.h gfx.h snapshot.h apu.h \
+ spc700.h display.h soundux.h spc7110.h cheats.h
+unix/x11.o: unix/x11.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h debug.h ppu.h gfx.h snapshot.h display.h apu.h \
+ spc700.h soundux.h spc7110.h movie.h
+unix/xf86.o: unix/xf86.cpp snes9x.h ../language.h port.h pixform.h 65c816.h \
+ messages.h memmap.h debug.h ppu.h gfx.h snapshot.h display.h apu.h \
+ spc700.h
+unzip/explode.o: unzip/explode.c unzip/unz.h unzip/unzipP.h unzip/unzip.h
+unzip/unreduce.o: unzip/unreduce.c unzip/unz.h unzip/unzipP.h unzip/unzip.h
+unzip/unshrink.o: unzip/unshrink.c unzip/unz.h
+unzip/unzip.o: unzip/unzip.c unzip/unzip.h unzip/unzipP.h
diff --git a/source/display.h b/source/display.h
new file mode 100644
index 0000000..8e65885
--- /dev/null
+++ b/source/display.h
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+START_EXTERN_C
+// Routines the port specific code has to implement
+void S9xTextMode ();
+void S9xGraphicsMode ();
+char *S9xParseArgs (char **argv, int argc);
+void S9xParseArg (char **argv, int &index, int argc);
+void S9xExtraUsage ();
+uint32 S9xReadJoypad (int which1_0_to_4);
+bool8 S9xReadMousePosition (int which1_0_to_1, int &x, int &y, uint32 &buttons);
+bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons);
+
+void S9xUsage ();
+void S9xInitDisplay (int argc, char **argv);
+void S9xDeinitDisplay ();
+void S9xInitInputDevices ();
+void S9xSetTitle (const char *title);
+void S9xPutImage (int width, int height);
+void S9xParseDisplayArg (char **argv, int &index, int argc);
+void S9xToggleSoundChannel (int channel);
+void S9xSetInfoString (const char *string);
+int S9xMinCommandLineArgs ();
+void S9xNextController ();
+bool8 S9xLoadROMImage (const char *string);
+const char *S9xSelectFilename (const char *def, const char *dir,
+ const char *ext, const char *title);
+
+const char *S9xChooseFilename (bool8 read_only);
+
+const char *S9xBasename (const char *filename);
+
+int S9xFStrcmp (FILE *, const char *);
+const char *S9xGetHomeDirectory ();
+const char *S9xGetSnapshotDirectory ();
+const char *S9xGetROMDirectory ();
+const char *S9xGetSRAMFilename ();
+const char *S9xGetFilename (const char *extension);
+const char *S9xGetFilenameInc (const char *);
+END_EXTERN_C
+
+#endif
+
diff --git a/source/dma.cpp b/source/dma.cpp
new file mode 100644
index 0000000..2addceb
--- /dev/null
+++ b/source/dma.cpp
@@ -0,0 +1,1170 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "snes9x.h"
+
+#include "memmap.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "missing.h"
+#include "dma.h"
+#include "apu.h"
+#include "gfx.h"
+#include "sa1.h"
+#include "spc7110.h"
+
+#ifdef SDD1_DECOMP
+#include "sdd1emu.h"
+#endif
+
+#ifdef SDD1_DECOMP
+uint8 buffer[0x10000];
+#endif
+
+extern int HDMA_ModeByteCounts [8];
+extern uint8 *HDMAMemPointers [8];
+extern uint8 *HDMABasePointers [8];
+
+// #define SETA010_HDMA_FROM_CART
+
+#ifdef SETA010_HDMA_FROM_CART
+uint32 HDMARawPointers[8]; // Cart address space pointer
+#endif
+
+#if defined(__linux__) || defined(__WIN32__)
+static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2)
+{
+ return (*(uint32 *) p1 - *(uint32 *) p2);
+}
+#endif
+
+/**********************************************************************************************/
+/* S9xDoDMA() */
+/* This function preforms the general dma transfer */
+/**********************************************************************************************/
+
+void S9xDoDMA (uint8 Channel)
+{
+ uint8 Work;
+
+ if (Channel > 7 || CPU.InDMA)
+ return;
+
+ CPU.InDMA = TRUE;
+ bool8 in_sa1_dma = FALSE;
+ uint8 *in_sdd1_dma = NULL;
+ uint8 *spc7110_dma=NULL;
+ bool s7_wrap=false;
+ SDMA *d = &DMA[Channel];
+
+
+ int count = d->TransferBytes;
+
+ if (count == 0)
+ count = 0x10000;
+
+ int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1);
+
+ if((d->ABank==0x7E||d->ABank==0x7F)&&d->BAddress==0x80)
+ {
+ d->AAddress+= d->TransferBytes;
+ //does an invalid DMA actually take time?
+ // I'd say yes, since 'invalid' is probably just the WRAM chip
+ // not being able to read and write itself at the same time
+ CPU.Cycles+=(d->TransferBytes+1)*SLOW_ONE_CYCLE;
+ goto update_address;
+ }
+ switch (d->BAddress)
+ {
+ case 0x18:
+ case 0x19:
+ if (IPPU.RenderThisFrame)
+ FLUSH_REDRAW ();
+ break;
+ }
+ if (Settings.SDD1)
+ {
+ if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0)
+ {
+ // Hacky support for pre-decompressed S-DD1 data
+ inc = !d->AAddressDecrement ? 1 : -1;
+ uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4;
+
+ address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)];
+
+#ifdef SDD1_DECOMP
+ if(Settings.SDD1Pack)
+ {
+ uint8* in_ptr=GetBasePointer(((d->ABank << 16) | d->AAddress));
+ in_ptr+=d->AAddress;
+
+ SDD1_decompress(buffer,in_ptr,d->TransferBytes);
+ in_sdd1_dma=buffer;
+#ifdef SDD1_VERIFY
+ void *ptr = bsearch (&address, Memory.SDD1Index,
+ Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries);
+ if(memcmp(buffer, ptr, d->TransferBytes))
+ {
+ uint8 *p = Memory.SDD1LoggedData;
+ bool8 found = FALSE;
+ uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0;
+
+ for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8)
+ {
+ if (*p == d->ABank ||
+ *(p + 1) == (d->AAddress >> 8) &&
+ *(p + 2) == (d->AAddress & 0xff) &&
+ *(p + 3) == (count >> 8) &&
+ *(p + 4) == (count & 0xff) &&
+ *(p + 7) == SDD1Bank)
+ {
+ found = TRUE;
+ }
+ }
+ if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES)
+ {
+ int j=0;
+ while(ptr[j]==buffer[j])
+ j++;
+
+ *p = d->ABank;
+ *(p + 1) = d->AAddress >> 8;
+ *(p + 2) = d->AAddress & 0xff;
+ *(p + 3) = j&0xFF;
+ *(p + 4) = (j>>8)&0xFF;
+ *(p + 7) = SDD1Bank;
+ Memory.SDD1LoggedDataCount += 1;
+ }
+ }
+#endif
+ }
+
+ else
+ {
+#endif
+#if defined(__linux__) || defined (__WIN32__)
+ void *ptr = bsearch (&address, Memory.SDD1Index,
+ Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries);
+ if (ptr)
+ in_sdd1_dma = *(uint32 *) ((uint8 *) ptr + 4) + Memory.SDD1Data;
+#else
+ uint8 *ptr = Memory.SDD1Index;
+
+ for (uint32 e = 0; e < Memory.SDD1Entries; e++, ptr += 12)
+ {
+ if (address == *(uint32 *) ptr)
+ {
+ in_sdd1_dma = *(uint32 *) (ptr + 4) + Memory.SDD1Data;
+ break;
+ }
+ }
+#endif
+
+ if (!in_sdd1_dma)
+ {
+ // No matching decompressed data found. Must be some new
+ // graphics not encountered before. Log it if it hasn't been
+ // already.
+ uint8 *p = Memory.SDD1LoggedData;
+ bool8 found = FALSE;
+ uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0;
+
+ for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8)
+ {
+ if (*p == d->ABank ||
+ *(p + 1) == (d->AAddress >> 8) &&
+ *(p + 2) == (d->AAddress & 0xff) &&
+ *(p + 3) == (count >> 8) &&
+ *(p + 4) == (count & 0xff) &&
+ *(p + 7) == SDD1Bank)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES)
+ {
+ *p = d->ABank;
+ *(p + 1) = d->AAddress >> 8;
+ *(p + 2) = d->AAddress & 0xff;
+ *(p + 3) = count >> 8;
+ *(p + 4) = count & 0xff;
+ *(p + 7) = SDD1Bank;
+ Memory.SDD1LoggedDataCount += 1;
+ }
+ }
+ }
+#ifdef SDD1_DECOMP
+ }
+#endif
+
+ Memory.FillRAM [0x4801] = 0;
+ }
+ if(Settings.SPC7110&&(d->AAddress==0x4800||d->ABank==0x50))
+ {
+ uint32 i,j;
+ i=(s7r.reg4805|(s7r.reg4806<<8));
+#ifdef SPC7110_DEBUG
+ printf("DMA Transfer of %04X bytes from %02X%02X%02X:%02X, offset of %04X, internal bank of %04X, multiplier %02X\n",d->TransferBytes,s7r.reg4803,s7r.reg4802,s7r.reg4801, s7r.reg4804,i, s7r.bank50Internal, s7r.AlignBy);
+#endif
+ i*=s7r.AlignBy;
+ i+=s7r.bank50Internal;
+ i%=DECOMP_BUFFER_SIZE;
+ j=0;
+ if((i+d->TransferBytes)<DECOMP_BUFFER_SIZE)
+ {
+ spc7110_dma=&s7r.bank50[i];
+ }
+ else
+ {
+ spc7110_dma=new uint8[d->TransferBytes];
+ j=DECOMP_BUFFER_SIZE-i;
+ memcpy(spc7110_dma, &s7r.bank50[i], j);
+ memcpy(&spc7110_dma[j],s7r.bank50,d->TransferBytes-j);
+ s7_wrap=true;
+ }
+ int icount=s7r.reg4809|(s7r.reg480A<<8);
+ icount-=d->TransferBytes;
+ s7r.reg4809=0x00ff&icount;
+ s7r.reg480A=(0xff00&icount)>>8;
+
+ s7r.bank50Internal+=d->TransferBytes;
+ s7r.bank50Internal%=DECOMP_BUFFER_SIZE;
+ inc=1;
+ d->AAddress-=count;
+ }
+ if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40)
+ {
+ // Perform packed bitmap to PPU character format conversion on the
+ // data before transmitting it to V-RAM via-DMA.
+ int num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7);
+ int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 :
+ (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2;
+
+ int bytes_per_char = 8 * depth;
+ int bytes_per_line = depth * num_chars;
+ int char_line_bytes = bytes_per_char * num_chars;
+ uint32 addr = (d->AAddress / char_line_bytes) * char_line_bytes;
+ uint8 *base = GetBasePointer ((d->ABank << 16) + addr) + addr;
+ uint8 *buffer = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000];
+ uint8 *p = buffer;
+ uint32 inc = char_line_bytes - (d->AAddress % char_line_bytes);
+ uint32 char_count = inc / bytes_per_char;
+
+ in_sa1_dma = TRUE;
+
+ //printf ("%08x,", base); fflush (stdout);
+ //printf ("depth = %d, count = %d, bytes_per_char = %d, bytes_per_line = %d, num_chars = %d, char_line_bytes = %d\n",
+ //depth, count, bytes_per_char, bytes_per_line, num_chars, char_line_bytes);
+ int i;
+
+ switch (depth)
+ {
+ case 2:
+ for (i = 0; i < count; i += inc, base += char_line_bytes,
+ inc = char_line_bytes, char_count = num_chars)
+ {
+ uint8 *line = base + (num_chars - char_count) * 2;
+ for (uint32 j = 0; j < char_count && p - buffer < count;
+ j++, line += 2)
+ {
+ uint8 *q = line;
+ for (int l = 0; l < 8; l++, q += bytes_per_line)
+ {
+ for (int b = 0; b < 2; b++)
+ {
+ uint8 r = *(q + b);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 2) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 3) & 1);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 6) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 7) & 1);
+ }
+ p += 2;
+ }
+ }
+ }
+ break;
+ case 4:
+ for (i = 0; i < count; i += inc, base += char_line_bytes,
+ inc = char_line_bytes, char_count = num_chars)
+ {
+ uint8 *line = base + (num_chars - char_count) * 4;
+ for (uint32 j = 0; j < char_count && p - buffer < count;
+ j++, line += 4)
+ {
+ uint8 *q = line;
+ for (int l = 0; l < 8; l++, q += bytes_per_line)
+ {
+ for (int b = 0; b < 4; b++)
+ {
+ uint8 r = *(q + b);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1);
+ *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1);
+ *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1);
+ *(p + 16) = (*(p + 16) << 1) | ((r >> 6) & 1);
+ *(p + 17) = (*(p + 17) << 1) | ((r >> 7) & 1);
+ }
+ p += 2;
+ }
+ p += 32 - 16;
+ }
+ }
+ break;
+ case 8:
+ for (i = 0; i < count; i += inc, base += char_line_bytes,
+ inc = char_line_bytes, char_count = num_chars)
+ {
+ uint8 *line = base + (num_chars - char_count) * 8;
+ for (uint32 j = 0; j < char_count && p - buffer < count;
+ j++, line += 8)
+ {
+ uint8 *q = line;
+ for (int l = 0; l < 8; l++, q += bytes_per_line)
+ {
+ for (int b = 0; b < 8; b++)
+ {
+ uint8 r = *(q + b);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1);
+ *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1);
+ *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1);
+ *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1);
+ *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1);
+ *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1);
+ *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1);
+ }
+ p += 2;
+ }
+ p += 64 - 16;
+ }
+ }
+ break;
+ }
+ }
+
+#ifdef DEBUGGER
+ if (Settings.TraceDMA)
+ {
+ sprintf (String, "DMA[%d]: %s Mode: %d 0x%02X%04X->0x21%02X Bytes: %d (%s) V-Line:%ld",
+ Channel, d->TransferDirection ? "read" : "write",
+ d->TransferMode, d->ABank, d->AAddress,
+ d->BAddress, d->TransferBytes,
+ d->AAddressFixed ? "fixed" :
+ (d->AAddressDecrement ? "dec" : "inc"),
+ CPU.V_Counter);
+ if (d->BAddress == 0x18 || d->BAddress == 0x19 || d->BAddress == 0x39 || d->BAddress == 0x3a)
+ sprintf (String, "%s VRAM: %04X (%d,%d) %s", String,
+ PPU.VMA.Address,
+ PPU.VMA.Increment, PPU.VMA.FullGraphicCount,
+ PPU.VMA.High ? "word" : "byte");
+
+ else
+ if (d->BAddress == 0x22 || d->BAddress == 0x3b)
+
+ sprintf (String, "%s CGRAM: %02X (%x)", String, PPU.CGADD,
+ PPU.CGFLIP);
+ else
+ if (d->BAddress == 0x04 || d->BAddress == 0x38)
+ sprintf (String, "%s OBJADDR: %04X", String, PPU.OAMAddr);
+ S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String);
+ }
+#endif
+
+ if (!d->TransferDirection)
+ {
+ /* XXX: DMA is potentially broken here for cases where we DMA across
+ * XXX: memmap boundries. A possible solution would be to re-call
+ * XXX: GetBasePointer whenever we cross a boundry, and when
+ * XXX: GetBasePointer returns (0) to take the 'slow path' and use
+ * XXX: S9xGetByte instead of *base. GetBasePointer() would want to
+ * XXX: return (0) for MAP_PPU and whatever else is a register range
+ * XXX: rather than a RAM/ROM block, and we'd want to detect MAP_PPU
+ * XXX: (or specifically, Address Bus B addresses $2100-$21FF in
+ * XXX: banks $00-$3F) specially and treat it as MAP_NONE (since
+ * XXX: PPU->PPU transfers don't work).
+ */
+
+ //reflects extra cycle used by DMA
+ CPU.Cycles += SLOW_ONE_CYCLE * (count+1);
+
+ uint8 *base = GetBasePointer ((d->ABank << 16) + d->AAddress);
+ uint16 p = d->AAddress;
+
+ if (!base)
+ base = Memory.ROM;
+
+ if (in_sa1_dma)
+ {
+ base = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000];
+ p = 0;
+ }
+
+ if (in_sdd1_dma)
+ {
+ base = in_sdd1_dma;
+ p = 0;
+ }
+ if(spc7110_dma)
+ {
+ base=spc7110_dma;
+ p = 0;
+ }
+ if (inc > 0)
+ d->AAddress += count;
+ else
+ if (inc < 0)
+ d->AAddress -= count;
+
+ if (d->TransferMode == 0 || d->TransferMode == 2 || d->TransferMode == 6)
+ {
+ switch (d->BAddress)
+ {
+ case 0x04:
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2104(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ break;
+ case 0x18:
+#ifndef CORRECT_VRAM_READS
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ if (!PPU.VMA.FullGraphicCount)
+ {
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2118_linear(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ }
+ else
+ {
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2118_tile(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ }
+ break;
+ case 0x19:
+#ifndef CORRECT_VRAM_READS
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ if (!PPU.VMA.FullGraphicCount)
+ {
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2119_linear(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ }
+ else
+ {
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2119_tile(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ }
+ break;
+ case 0x22:
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2122(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ break;
+ case 0x80:
+ do
+ {
+ Work = *(base + p);
+ REGISTER_2180(Work);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ break;
+ default:
+ do
+ {
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2100 + d->BAddress);
+ p += inc;
+ CHECK_SOUND();
+ } while (--count > 0);
+ break;
+ }
+ }
+ else
+ if (d->TransferMode == 1 || d->TransferMode == 5)
+ {
+ if (d->BAddress == 0x18)
+ {
+ // Write to V-RAM
+#ifndef CORRECT_VRAM_READS
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ if (!PPU.VMA.FullGraphicCount)
+ {
+ while (count > 1)
+ {
+ Work = *(base + p);
+ REGISTER_2118_linear(Work);
+ p += inc;
+
+ Work = *(base + p);
+ REGISTER_2119_linear(Work);
+ p += inc;
+ CHECK_SOUND();
+ count -= 2;
+ }
+ if (count == 1)
+ {
+ Work = *(base + p);
+ REGISTER_2118_linear(Work);
+ p += inc;
+ }
+ }
+ else
+ {
+ while (count > 1)
+ {
+ Work = *(base + p);
+ REGISTER_2118_tile(Work);
+ p += inc;
+
+ Work = *(base + p);
+ REGISTER_2119_tile(Work);
+ p += inc;
+ CHECK_SOUND();
+ count -= 2;
+ }
+ if (count == 1)
+ {
+ Work = *(base + p);
+ REGISTER_2118_tile(Work);
+ p += inc;
+ }
+ }
+ }
+ else
+ {
+ // DMA mode 1 general case
+ while (count > 1)
+ {
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2100 + d->BAddress);
+ p += inc;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2101 + d->BAddress);
+ p += inc;
+ CHECK_SOUND();
+ count -= 2;
+ }
+ if (count == 1)
+ {
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2100 + d->BAddress);
+ p += inc;
+ }
+ }
+ }
+ else
+ if (d->TransferMode == 3 || d->TransferMode == 7)
+ {
+ do
+ {
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2100 + d->BAddress);
+ p += inc;
+ if (count <= 1)
+ break;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2100 + d->BAddress);
+ p += inc;
+ if (count <= 2)
+ break;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2101 + d->BAddress);
+ p += inc;
+ if (count <= 3)
+ break;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2101 + d->BAddress);
+ p += inc;
+ CHECK_SOUND();
+ count -= 4;
+ } while (count > 0);
+ }
+ else
+ if (d->TransferMode == 4)
+ {
+ do
+ {
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2100 + d->BAddress);
+ p += inc;
+ if (count <= 1)
+ break;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2101 + d->BAddress);
+ p += inc;
+ if (count <= 2)
+ break;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2102 + d->BAddress);
+ p += inc;
+ if (count <= 3)
+ break;
+
+ Work = *(base + p);
+ S9xSetPPU (Work, 0x2103 + d->BAddress);
+ p += inc;
+ CHECK_SOUND();
+ count -= 4;
+ } while (count > 0);
+ }
+ else
+ {
+#ifdef DEBUGGER
+ // if (Settings.TraceDMA)
+ {
+ sprintf (String, "Unknown DMA transfer mode: %d on channel %d\n",
+ d->TransferMode, Channel);
+ S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String);
+ }
+#endif
+ }
+ }
+ else
+ {
+ /* XXX: DMA is potentially broken here for cases where the dest is
+ * XXX: in the Address Bus B range. Note that this bad dest may not
+ * XXX: cover the whole range of the DMA though, if we transfer
+ * XXX: 65536 bytes only 256 of them may be Address Bus B.
+ */
+ do
+ {
+ switch (d->TransferMode)
+ {
+ case 0:
+ case 2:
+ case 6:
+ Work = S9xGetPPU (0x2100 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ --count;
+ break;
+
+ case 1:
+ case 5:
+ Work = S9xGetPPU (0x2100 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2101 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ count--;
+ break;
+
+ case 3:
+ case 7:
+ Work = S9xGetPPU (0x2100 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2100 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2101 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2101 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ count--;
+ break;
+
+ case 4:
+ Work = S9xGetPPU (0x2100 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2101 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2102 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ if (!--count)
+ break;
+
+ Work = S9xGetPPU (0x2103 + d->BAddress);
+ S9xSetByte (Work, (d->ABank << 16) + d->AAddress);
+ d->AAddress += inc;
+ count--;
+ break;
+
+ default:
+#ifdef DEBUGGER
+ if (1) //Settings.TraceDMA)
+ {
+ sprintf (String, "Unknown DMA transfer mode: %d on channel %d\n",
+ d->TransferMode, Channel);
+ S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String);
+ }
+#endif
+ count = 0;
+ break;
+ }
+ CHECK_SOUND();
+ } while (count);
+ }
+
+#ifdef SPC700_C
+ IAPU.APUExecuting = Settings.APUEnabled;
+ APU_EXECUTE ();
+#endif
+ while (CPU.Cycles > CPU.NextEvent)
+ S9xDoHBlankProcessing ();
+
+ if(Settings.SPC7110&&spc7110_dma)
+ {
+ if(spc7110_dma&&s7_wrap)
+ delete [] spc7110_dma;
+ }
+
+update_address:
+ // Super Punch-Out requires that the A-BUS address be updated after the
+ // DMA transfer.
+ Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress;
+ Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8;
+
+ // Secret of the Mana requires that the DMA bytes transfer count be set to
+ // zero when DMA has completed.
+ Memory.FillRAM [0x4305 + (Channel << 4)] = 0;
+ Memory.FillRAM [0x4306 + (Channel << 4)] = 0;
+
+ DMA[Channel].IndirectAddress = 0;
+ d->TransferBytes = 0;
+
+ CPU.InDMA = FALSE;
+
+
+}
+
+void S9xStartHDMA ()
+{
+ if (Settings.DisableHDMA)
+ IPPU.HDMA = 0;
+ else
+ missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c];
+
+ //per anomie timing post
+ if(IPPU.HDMA!=0)
+ CPU.Cycles+=ONE_CYCLE*3;
+
+ IPPU.HDMAStarted = TRUE;
+
+ for (uint8 i = 0; i < 8; i++)
+ {
+ if (IPPU.HDMA & (1 << i))
+ {
+ CPU.Cycles+=SLOW_ONE_CYCLE ;
+ DMA [i].LineCount = 0;
+ DMA [i].FirstLine = TRUE;
+ DMA [i].Address = DMA [i].AAddress;
+ if(DMA[i].HDMAIndirectAddressing)
+ CPU.Cycles+=(SLOW_ONE_CYCLE <<2);
+ }
+ HDMAMemPointers [i] = NULL;
+#ifdef SETA010_HDMA_FROM_CART
+ HDMARawPointers [i] = 0;
+#endif
+ }
+}
+
+#ifdef DEBUGGER
+void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
+ int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0);
+#endif
+
+
+uint8 S9xDoHDMA (uint8 byte)
+{
+ struct SDMA *p = &DMA [0];
+
+ int d = 0;
+
+ CPU.InDMA = TRUE;
+ CPU.Cycles+=ONE_CYCLE*3;
+ for (uint8 mask = 1; mask; mask <<= 1, p++, d++)
+ {
+ if (byte & mask)
+ {
+ if (!p->LineCount)
+ {
+ //remember, InDMA is set.
+ //Get/Set incur no charges!
+ CPU.Cycles+=SLOW_ONE_CYCLE;
+ uint8 line = S9xGetByte ((p->ABank << 16) + p->Address);
+ if (line == 0x80)
+ {
+ p->Repeat = TRUE;
+ p->LineCount = 128;
+ }
+ else
+ {
+ p->Repeat = !(line & 0x80);
+ p->LineCount = line & 0x7f;
+ }
+
+ // Disable H-DMA'ing into V-RAM (register 2118) for Hook
+ /* XXX: instead of p->BAddress == 0x18, make S9xSetPPU fail
+ * XXX: writes to $2118/9 when appropriate
+ */
+#ifdef SETA010_HDMA_FROM_CART
+ if (!p->LineCount)
+#else
+ if (!p->LineCount || p->BAddress == 0x18)
+#endif
+ {
+ byte &= ~mask;
+ p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d];
+ Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress;
+ Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8;
+ continue;
+ }
+
+ p->Address++;
+ p->FirstLine = 1;
+ if (p->HDMAIndirectAddressing)
+ {
+ p->IndirectBank = Memory.FillRAM [0x4307 + (d << 4)];
+ //again, no cycle charges while InDMA is set!
+ CPU.Cycles+=SLOW_ONE_CYCLE<<2;
+ p->IndirectAddress = S9xGetWord ((p->ABank << 16) + p->Address);
+ p->Address += 2;
+ }
+ else
+ {
+ p->IndirectBank = p->ABank;
+ p->IndirectAddress = p->Address;
+ }
+ HDMABasePointers [d] = HDMAMemPointers [d] =
+ S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress);
+#ifdef SETA010_HDMA_FROM_CART
+ HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress;
+#endif
+ }
+ else
+ {
+ CPU.Cycles += SLOW_ONE_CYCLE;
+ }
+
+ if (!HDMAMemPointers [d])
+ {
+ if (!p->HDMAIndirectAddressing)
+ {
+ p->IndirectBank = p->ABank;
+ p->IndirectAddress = p->Address;
+ }
+#ifdef SETA010_HDMA_FROM_CART
+ HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress;
+#endif
+ if (!(HDMABasePointers [d] = HDMAMemPointers [d] =
+ S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress)))
+ {
+ /* XXX: Instead of this, goto a slow path that first
+ * XXX: verifies src!=Address Bus B, then uses
+ * XXX: S9xGetByte(). Or make S9xGetByte return OpenBus
+ * XXX: (probably?) for Address Bus B while inDMA.
+ */
+ byte &= ~mask;
+ continue;
+ }
+ // Uncommenting the following line breaks Punchout - it starts
+ // H-DMA during the frame.
+ //p->FirstLine = TRUE;
+ }
+ if (p->Repeat && !p->FirstLine)
+ {
+ p->LineCount--;
+ continue;
+ }
+
+ if (p->BAddress == 0x04){
+ if(SNESGameFixes.Uniracers){
+ PPU.OAMAddr = 0x10c;
+ PPU.OAMFlip=0;
+ }
+ }
+
+#ifdef DEBUGGER
+ if (Settings.TraceSoundDSP && p->FirstLine &&
+ p->BAddress >= 0x40 && p->BAddress <= 0x43)
+ S9xTraceSoundDSP ("Spooling data!!!\n");
+ if (Settings.TraceHDMA && p->FirstLine)
+ {
+ sprintf (String, "H-DMA[%d] (%d) 0x%02X%04X->0x21%02X %s, Count: %3d, Rep: %s, V-LINE: %3ld %02X%04X",
+ p-DMA, p->TransferMode, p->IndirectBank,
+ p->IndirectAddress,
+ p->BAddress,
+ p->HDMAIndirectAddressing ? "ind" : "abs",
+ p->LineCount,
+ p->Repeat ? "yes" : "no ", CPU.V_Counter,
+ p->ABank, p->Address);
+ S9xMessage (S9X_TRACE, S9X_HDMA_TRACE, String);
+ }
+#endif
+
+ switch (p->TransferMode)
+ {
+ case 0:
+ CPU.Cycles += SLOW_ONE_CYCLE;
+#ifdef SETA010_HDMA_FROM_CART
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d]++), 0x2100 + p->BAddress);
+ HDMAMemPointers [d]++;
+#else
+ S9xSetPPU (*HDMAMemPointers [d]++, 0x2100 + p->BAddress);
+#endif
+ break;
+ case 5:
+ CPU.Cycles += 2*SLOW_ONE_CYCLE;
+#ifdef SETA010_HDMA_FROM_CART
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress);
+ HDMARawPointers [d] += 2;
+#else
+ S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress);
+#endif
+ HDMAMemPointers [d] += 2;
+ /* fall through */
+ case 1:
+ CPU.Cycles += 2*SLOW_ONE_CYCLE;
+#ifdef SETA010_HDMA_FROM_CART
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress);
+ HDMARawPointers [d] += 2;
+#else
+ S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress);
+#endif
+ HDMAMemPointers [d] += 2;
+ break;
+ case 2:
+ case 6:
+ CPU.Cycles += 2*SLOW_ONE_CYCLE;
+#ifdef SETA010_HDMA_FROM_CART
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress);
+ HDMARawPointers [d] += 2;
+#else
+ S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress);
+#endif
+ HDMAMemPointers [d] += 2;
+ break;
+ case 3:
+ case 7:
+ CPU.Cycles += 4*SLOW_ONE_CYCLE;
+#ifdef SETA010_HDMA_FROM_CART
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2101 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2101 + p->BAddress);
+ HDMARawPointers [d] += 4;
+#else
+ S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress);
+#endif
+ HDMAMemPointers [d] += 4;
+ break;
+ case 4:
+ CPU.Cycles += 4*SLOW_ONE_CYCLE;
+#ifdef SETA010_HDMA_FROM_CART
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2102 + p->BAddress);
+ S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2103 + p->BAddress);
+ HDMARawPointers [d] += 4;
+#else
+ S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress);
+ S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress);
+#endif
+ HDMAMemPointers [d] += 4;
+ break;
+ }
+ if (!p->HDMAIndirectAddressing)
+ p->Address += HDMA_ModeByteCounts [p->TransferMode];
+ p->IndirectAddress += HDMA_ModeByteCounts [p->TransferMode];
+ /* XXX: Check for p->IndirectAddress crossing a mapping boundry,
+ * XXX: and invalidate HDMAMemPointers[d]
+ */
+ p->FirstLine = FALSE;
+ p->LineCount--;
+ }
+ }
+ CPU.InDMA=FALSE;
+ return (byte);
+}
+
+void S9xResetDMA ()
+{
+ int d;
+ for (d = 0; d < 8; d++)
+ {
+ DMA [d].TransferDirection = FALSE;
+ DMA [d].HDMAIndirectAddressing = FALSE;
+ DMA [d].AAddressFixed = TRUE;
+ DMA [d].AAddressDecrement = FALSE;
+ DMA [d].TransferMode = 0xff;
+ DMA [d].ABank = 0xff;
+ DMA [d].AAddress = 0xffff;
+ DMA [d].Address = 0xffff;
+ DMA [d].BAddress = 0xff;
+ DMA [d].TransferBytes = 0xffff;
+ }
+ for (int c = 0x4300; c < 0x4380; c += 0x10)
+ {
+ for (d = c; d < c + 12; d++)
+ Memory.FillRAM [d] = 0xff;
+
+ Memory.FillRAM [c + 0xf] = 0xff;
+ }
+}
diff --git a/source/dma.h b/source/dma.h
new file mode 100644
index 0000000..a95f20e
--- /dev/null
+++ b/source/dma.h
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _DMA_H_
+#define _DMA_H_
+
+START_EXTERN_C
+void S9xResetDMA (void);
+uint8 S9xDoHDMA (uint8);
+void S9xStartHDMA ();
+void S9xDoDMA (uint8);
+END_EXTERN_C
+
+#endif
+
diff --git a/source/doc/porting.txt b/source/doc/porting.txt
new file mode 100644
index 0000000..3d28eec
--- /dev/null
+++ b/source/doc/porting.txt
@@ -0,0 +1,725 @@
+ How to Port Snes9x to a New Platform
+ ====================================
+
+Version: 1.01
+Date: 23-December-1998
+
+(c) Copyright 1998 Gary Henderson (gary@daniver.demon.co.uk)
+
+Introduction
+============
+
+This is brief description of the steps involved in porting Snes9x, the Super
+Nintendo Entertainment System emulator, to new hardware which is at least
+similar to Workstation or PC. It describes what code you have to write and
+what functions exist that you can make use of. It also gives some insights as
+to how Snes9x actually works, although that will be subject of another
+document yet to be written.
+
+Host System Requirements
+========================
+
+A C++ compiler, so you can compile the emulator! Snes9x really isn't written
+in C++, it just uses the C++ compiler as a 'better C' compiler to get inline
+functions and so on. With some modification, it could be converted to be
+compiled with an ordinary C compiler. Snes9x isn't very C type safe and
+will probably not work on a system who's integers are less than 32-bits wide
+without lots of editing.
+
+If the host system uses a CPU that implements the i386 instruction set then
+you will also want to use the three assembler CPU cores, although I recently
+scrapped the SPC700 assembler code (too many bugs) and replaced it with
+compiler generated assembler code that I haven't got around to optimising
+yet. The 65c816 and SPC700 code needs to be assembled using the GNU
+assembler that comes with gcc and the Super FX code assembled with NASM
+v0.97 or higher. gcc is available from lots of sites. NASM is available from
+http://www.cryogen.com/Nasm
+
+A fast CPU. SNES emulation is very compute intensive: two, or sometimes three
+CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor
+with real-time sample decompression, filter and echo effects, two custom
+graphics processor chips that can produce transparency, scaling, rotation
+and window effects in 32768 colors, and finally hardware DMA all take their
+toll on the host CPU.
+
+Lots of RAM. The SNES itself has 128k work RAM, 64k V-RAM and 64k sound CPU
+RAM. If a Super FX game is being emulated, that usually comes with another
+64k inside the game pack. Snes9x itself needs 4Mb to load SNES ROM images
+into (or 6Mb if I ever figure out the SNES memory map of the 48Mbit ROM
+images out there), 256k to cache decompressed sound samples in, 512k to
+cache converted SNES tiles in, and another 64k for S-RAM emulation. And
+that's not counting a few large lookup tables that the graphics code needs
+for speeding up transparency effects plus few other tables used by the ZSNES
+Super FX code. It all adds up to 7Mb (ish). Add to that RAM needed to
+store the actual emulator code and RAM required by the host operating system
+and any other process that is running; that's lots of RAM. Well, it is if
+your host system only has a few mega-bytes of RAM available.
+
+An 8-bit, 256 color (one byte per pixel) or deeper display, at least 256x239
+pixels in resolution, or 512x478 if you're going to support the SNES'
+hi-res. background screen modes. Ideally, a 16-bit, 65536 color screen mode
+is required if you want to support transparency at speed, as that is what the
+code renders internally. Any other format screen, with transparency enabled,
+will require picture format conversion before you can place the rendered
+SNES image on to the screen.
+
+Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound
+data to the host computer's sound hardware. The DOS port uses interrupts
+from the sound card to know when more sound data is required, most other
+ports have to periodically poll the host sound hardware to see if more data
+is required; if it is then the SNES sound mixing code provided by Snes9x is
+called to fill an area of system memory with ready mixed SNES sound data,
+which then can be passed on to the host sound hardware. Sound data is
+generated as an array of bytes (uint8) for 8-bit sound or shorts (int16) for
+16-bit data. Stereo sound data generates twice as many samples, with each
+channel's samples interleaved, first left's then right's.
+
+For the user to be able to control and play SNES games, some form of input
+device is required, a joystick or keyboard, for example. The real SNES can
+have 2 eight-button digital joy-pads connected to it or 5 joy-pads when an
+optional multi-player adaptor was purchased, although most games only require
+a single joy-pad. Access to all eight buttons and the direction pad, of
+course, are usually required by most games. Snes9x does emulate the
+multi-player adaptor hardware, if you were wondering, but its still up to
+you to provide the emulation of the individual joy-pads.
+
+The SNES also had a mouse and light gun available as optional extras,
+Snes9x can emulate both of these using some form of pointing device,
+usually the host system's mouse.
+
+If an accurate, constant SNES play rate is required, then a real-time timer
+will be needed that can time intervals of 16.7ms (NTSC frame time) or 20ms
+(PAL frame time).
+
+Some SNES game packs contained a small amount of extra RAM and a battery so
+ROMs could save a player's progress through a game for games that takes many
+hours to play from start to finish. Snes9x simulates this S-RAM by saving
+the contents of the area of memory normally occupied by the S-RAM into file
+then automatically restoring it again the next time the user plays the same
+game. If the hardware you're porting to doesn't have a hard disk available
+then you could be in trouble.
+
+Snes9x also implements freeze-game files which can record the state of the
+SNES hardware and RAM at a particular point in time and can restore it to
+that exact state at a later date - the result is that users can save a game
+at any point, not just at save-game or password points provided by the
+original game coders. Each freeze file is over 400k in size. To help save
+disk space, Snes9x can be compiled with zlib, which is used to compress the
+freeze files, reducing the size to typically below 100k. Download zlib from
+its homepage at http://www.cdrom.com/pub/infozip/zlib/, compile Snes9x with
+ZLIB defined and link with zlib. zlib is also used to load any compressed
+ROM images Snes9x my encounter, compressed with gzip or compress.
+
+Porting
+=======
+
+In theory you will only need to edit port.h, then in a separate file write
+all the initialisation code and interface routines that Snes9x expects the
+you to implement. You, no doubt, will discover otherwise....
+
+There are several compile-time only options available:
+
+DEBUGGER
+--------
+
+Enables extra code to assist me in debugging SNES ROMs. The debugger has only
+ever been a quick-hack by me and user-interface to debugger facilities is
+virtually non-existent. Most of the debugger information is output via
+stdout and enabling the compile-time options slows the whole emulator down
+slightly. However, the debugger options available are very powerful; you
+could use it to help get your port working. You probably still want to ship
+the finished version with the debugger disabled, it will only confuse
+non-technical users.
+
+VAR_CYCLES
+----------
+
+I recommend you define this. The main CPU in the SNES actually varies in
+speed depending on what area of memory its accessing and the ROM access
+speed of the game pack; defining VAR_CYCLES causes Snes9x to emulate this,
+using a good approximation, rather than fixed cycle length as ZSNES does. The
+resultant code is slightly slower. Leaving it undefined results in many more
+emulation timing errors appearing while playing games.
+
+CPU_SHUTDOWN and SPC700_SHUTDOWN
+--------------------------------
+
+Again I recommend defining both of these. They are both speed up hacks.
+When defined, Snes9x starts watching for when either the main or sound CPUs
+are in simply loops waiting for a known event to happen - like the end of
+the current scan-line, and interrupt or a sound timer to reach a particular
+value. If Snes9x spots either CPU in such a loop it uses its insider
+knowledge to simply skip the emulation of that CPU's instructions until the
+event happens. It can be a big win with lots of SNES games.
+
+I'm constantly amazed at the ingenuity of some programmers who are able to
+produce complex code to do simple things: some ROM's wait loops are so
+complex Snes9x fails to spot the CPU is in such a loop and the shutdown
+speed up hacks don't work.
+
+You might be wondering why VAR_CYCLES, and the two SHUTDOWN options have to
+be enabled with defines, well, in the past they sometimes introduced
+problems with some ROMs, so I kept them as options. I think I've fixed all
+the problems now, but you never know...
+
+SPC700_C
+--------
+
+Define this if you are using the C/C++ version of the SPC700 CPU core. It
+enables a ROM compatibility feature that executes SPC700 instructions during
+SNES DMA, it allows several games to start that would otherwise lock up and
+fixes music pauses when ROMs do lots of DMA, usually when switching between
+game screens.
+
+ZLIB
+----
+
+Define this if you have the zlib library available and you want it to
+compress freeze-game files to save disk space. The library is also used to
+support compressed ROM images.
+
+NO_INLINE_SET_GET
+-----------------
+
+Define this to stop several of the memory access routines from being
+defined in-line. Whether the C++ compiler actually in-lines when this symbol
+is not defined is up to the compiler itself. In-lines functions can speed up
+the C++ CPU emulations on some architectures at the cost of increased code
+size. Try fiddling with this option once you've got port working to see if
+it helps the speed of your port.
+
+EXECUTE_SUPERFX_PER_LINE and ZSNES_FX
+-------------------------------------
+
+Define these if you're going to be using the ZSNES Super FX i386 assembler
+code, otherwise leave them both undefined. In theory,
+EXECUTE_SUPERFX_PER_LINE can also be defined when using the C++ Super FX
+emulation code, but the code is still buggy and enabling the option
+introduces more problems than it fixes. Any takers for fixing the C++ code?
+
+JOYSTICK_SUPPORT, SIDEWINDER_SUPPORT and GRIP_SUPPORT
+-----------------------------------------------------
+
+These options enable support for various input devices in the UNIX and MS-DOS
+port code. They're only of interest if you're able to use the existing UNIX
+or MS-DOS port specific code.
+
+port.h
+======
+
+If the byte ordering of the target system is least significant byte first,
+make sure LSB_FIRST is defined in this header, otherwise, make sure its not
+defined.
+
+If you're going to support 16-bit screen rendering (required if you want
+transparency effects) and your system doesn't use RGB 565 - 5 bits for red,
+6 bits for green and 5 bits for blue - then you'll need make sure RGB555,
+BGR565 or BGR555 is defined instead. You might want to take a look at the
+*_LOW_BIT_MASKs, *_HI_BIT_MASKs and BUILD_PIXEL macros to make sure they're
+correct, because I've only every tested the RGB565 version, though the Mac
+port uses the RGB555 option. If your system is 24 or 32-bit only, then
+don't define anything; instead write a conversion routine that will take a
+complete rendered 16-bit SNES screen in RGB565 format and convert to the
+format required to be displayed on your hardware.
+
+port.h also typedefs some types, uint8 for an unsigned, 8-bit quantity,
+uint16 for an unsigned, 16-bit quantity, uint32 for a 32-bit, unsigned
+quantity and bool8 for a true/false type. Signed versions are also
+typedef'ed.
+
+The CHECK_SOUND macro can be defined to invoke some code that polls the
+host system's sound hardware to see if it can accept any more sound data.
+Snes9x makes calls to this macro several times when it is rendering the SNES
+screen, during large SNES DMAs and after every emulated CPU instruction.
+
+Since this CHECK_SOUND macro is invoked often, the code should only take a
+very small amount of time to execute or it will slow down the emulator's
+performance. The Linux and UNIX ports use a system timer and set a variable
+when it has expired; the CHECK_SOUND only has to check to see if the
+variable is set. On the MS-DOS and Mac ports, the sound hardware is not
+polled at all, instead it is driven by interrupts or callbacks and the
+CHECK_SOUND macro is defined to be empty.
+
+Initialisation Code
+-------------------
+
+This is what the Linux, UNIX and MS-DOS ports do, I suspect your code
+might be similar:
+
+- The Settings structure is initialised to some sensible default values -
+ check the main function in unix.cpp for the values it uses.
+
+- The command line is parsed, options specified override default values in
+ the Settings structure and specify a ROM image filename that the user
+ wants loaded. Your port could load user preferences from a file or some
+ other source at this point. Most values, with a little care, can be changed
+ via a GUI once the emulator is running.
+
+- Some Settings structure value validation takes place, for example if
+ transparency effects are requested the code also makes sure 16-bit
+ screen rendering is turned on as well.
+
+- Memory.Init() and S9xInitAPU() are called, checking neither failed. The
+ only reason they would fail is if memory allocation failed.
+
+- Memory.LoadROM (filename) is called to load the specified ROM image into
+ memory. If that worked Memory.LoadSRAM (sram_filename) is called to load
+ the ROM's S-RAM file, if one exists. The all current ports base the
+ sram_filename on the filename of the ROM image, changing the file's
+ extension (the .smc or whatever bit) and changing the directory where its
+ located - you won't be able to save S-RAM files onto a CD if that's where
+ the ROM image is located!
+
+ If your port has a GUI, you can delay this step until the user picks an
+ image to load.
+
+ SNES roms images come in all shapes and sizes, some with headers, some
+ without, some have been mangled by the copier device in one of two ways, and
+ some split into several pieces; plus the SNES itself has several different
+ memory map models. The code tries to auto-detect all these various types,
+ but sometimes the SNES ROM header information has been manually edited by
+ someone at some stage and the code guesses wrong. To help it out it these
+ situations, the Settings structure contains several options to force a
+ particular ROM image format; these values must be initialised prior to each
+ call to Memory.LoadROM(filename).
+
+- The Linux and UNIX ports now do some more operating system initialisation
+ ready for a system timer to be started.
+
+- The host display hardware is now initialised. The actual screen depth and
+ resolution should be picked based on the user preferences if possible.
+ The X Window System port can't control the screen depth or resolution, if
+ the user requests transparency effects but the display hardware is only
+ set to 8-bit, it has to invoke an extra step of converting the 16-bit SNES
+ rendered screen to a fixed palette 8-bit display just before the SNES
+ screen is copied to the display hardware.
+
+ The GFX.Screen pointer needs to be initialised to point to an array of
+ uint8 for 8-bit screen rendering or uint16 for 16-bit rendering, cast to
+ an array of uint8. The array needs to be at least 256x239 bytes or shorts
+ in size for lo-res only support (Settings.SupportHiRes = FALSE) or
+ 512x478 for lo-res and hi-res support. If transparency effects are
+ required, the GFX.SubScreen array also needs to be initialised to another
+ identically sized array of the same type, otherwise it can be just
+ initialised to NULL.
+
+ The GFX.Pitch variable needs to be set to the number of bytes on each line
+ of the arrays, e.g. 256 for lo-res only support, up to 1024 for 16-bit
+ hi-res support. If GFX.Screen is pointing into an existing array, one
+ created by the library function rather than just calling malloc or new,
+ then set GFX.Pitch to the number of bytes per line of that array,
+ including any padding the library function may have added.
+
+ If the target hardware supports fast access to video RAM, the screen is in
+ 16-bit format supported by the SNES rendering code and you can double
+ buffer the display, you might want to point GFX.Screen directly at the
+ video buffer RAM. You will need to recompute the GFX.Delta value every
+ time you change the GFX.Screen value to double-buffer the rendering and
+ display.
+
+- A call to S9xGraphicsInit() is made; make sure all your graphics rendering
+ options are setup correctly by now. If later, you want to change some
+ settings, for example 16-bit to 8-bit rendering, call S9xGraphicsDeinit()
+ first, change your settings, GFX.Screen and GFX.SubScreen arrays, etc.,
+ then call S9xGraphicsInit() again.
+
+- S9xInitSound(int playbackrate, bool8 stereo, int sound_buffer_size)
+ is now called, which in turn will call your S9xOpenSoundDevice function -
+ see below.
+
+- The display is switched to graphics mode using a call to S9xGraphicsMode().
+
+- The system timer is started; its used for keeping the emulator speed
+ relatively constant on the MS-DOS port and noting when the sound hardware
+ sound should be able to accept more sound data on the Linux and UNIX ports.
+
+- A main loop is entered which is just a loop constantly calling
+ S9xMainLoop() then polling the operating system for any pending events
+ such as key presses and releases, joystick updates, mouse position
+ updates, GUI user interaction, etc.
+
+ Pause functionality can be implemented by skipping the call to S9xMainLoop
+ and muting the sound output by calling S9xSetSoundMute (TRUE).
+
+ Don't enter the main loop until a SNES ROM image has been loaded, or at
+ least skip calling S9xMainLoop inside the loop until one is and make sure
+ S9xReset is called instead before entering the main loop. The Mac port
+ implements this technique by starting in pause mode and refusing to unpause
+ until a ROM image is loaded.
+
+ S9xMainLoop processes SNES CPU emulation, SNES screen rendering, DMA and
+ H-DMA emulation, until emulated scan-line 0 is reached, then it returns.
+ Now is your chance to process any system events pending, scan the
+ keyboard, read joystick values, etc.
+
+ If DEBUGGER compile-time support is enabled and the CPU emulation has hit
+ a break point or single-stepping is switched on, or the DEBUG_MODE_FLAG is
+ set in the CPU.Flags variable, then the S9xMainLoop routine returns early,
+ allowing you to act on the event in some way. The Linux, DOS and UNIX ports
+ respond to the DEBUG_MODE_FLAG being set by calling S9xDoDebug(), which in
+ turn outputs the current instruction and loops reading commands from stdin
+ and outputting debug information, currently via stdout. The debugger
+ desperately needs rewriting to support a GUI interface, more descriptive
+ commands and better error handling; maybe one day...
+
+Existing Interface Routines
+---------------------------
+
+These are routines already written that you will either need to call or
+might find useful.
+
+-> bool8 Memory.Init ()
+
+Allocates and initialises several major lumps of memory, for example
+the SNES ROM and RAM arrays, tile cache arrays, etc. Returns FALSE if
+memory allocation fails.
+
+-> void Memory.Deinit ()
+
+Undoes the memory allocations made by Memory.Init.
+
+-> bool8 S9xGraphicsInit ()
+
+Allocated and initialises several lookup tables used to speed up SNES
+graphics rendering. Call after you have initialised the GFX.Screen,
+GFX.SubScreen and GFX.Pitch values. If Settings.Transparency is false it
+does not allocate tables used to speed up transparency effects. If you
+want to provide the user with option to turn the effects on and off during
+game play, make sure Settings.Transparency is true when this function is
+called, it can later be set to FALSE.
+
+Returns FALSE if memory allocation fails.
+
+-> void S9xGraphicsDeinit ()
+
+Undoes the memory allocations made by S9xGraphicsInit.
+
+-> bool8 S9xInitAPU ()
+
+Allocates and initialises several arrays used by the sound CPU and sound
+generation code.
+
+-> void S9xDeinitAPU ()
+
+Undoes the allocations made by S9xInitAPU.
+
+-> bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size)
+
+Does more sound code initialisation and opens the host system's sound hardware
+by calling the S9xOpenSoundDevice function provided by you.
+
+-> void S9xReset ()
+
+Resets the SNES emulated hardware back to the state it was in at 'switch-on'
+except the S-RAM area is presevered. The effect is it resets the current game
+back to the start. This function is automatically called by Memory.LoROM.
+
+-> bool8 Memory.LoadROM (const char *filename)
+
+Attempts to load the specified ROM image filename into the emulated ROM area.
+There are many different SNES ROM image formats and the code attempts to
+auto-detect as many different types as it can and in a vast majority of the
+cases gets it right. However, some ROM images have been edited by someone at
+some stage or have been mangled by the ROM copier that produced them and
+LoadROM needs help. Inparticular, it can't auto-detect the odd way in which
+some Super FX games have been mangled and needs to be told, via
+Settings.Interleaved2, that the ROM image is in that format, or that
+odd-sized ROM images have a 512 byte copier header.
+
+There are several other ROM image options in the Settings structure;
+allow the user to set them before calling LoadROM, or make sure they all
+reset to default values before each call to LoadROM.
+
+-> bool8 Memory.LoadSRAM (const char *filename)
+
+Call this routine to load the associated S-RAM save file (if any). The
+filename should be based on the ROM image name to allow easy linkage.
+The current ports change the directory and the filename extension of the ROM
+filename to derive the S-RAM filename.
+
+-> bool8 Memory.SaveSRAM (const char *filename)
+
+Call this routine to save the emulated S-RAM area into a file so it can
+be restored again the next time the user wants to play the game. Remember
+to call this when just before the emulator exits or when the user has been
+playing a game and is about to load another one.
+
+-> void S9xMainLoop()
+
+The emulator main loop. Call this from your own main loop that calls this
+function (if a ROM image is loaded and the game is not paused), processes
+any pending host system events, then goes back around the loop again until
+the emulator exits.
+
+S9xMainLoop normally returns control to your main loop once every emulated
+frame, when it reaches the start of scan-line zero. However, the routine
+can return more often if the DEBUGGER compile-time flag is defined and the
+CPU has hit a break point, or the DEBUG_MODE_FLAG bit is set in CPU.Flags
+or instruction single-stepping is enabled.
+
+-> void S9xMixSamples (uint8 *buffer, int sample_count)
+
+Call this routine from your host sound hardware handling code to fill the
+specified buffer with ready mixed SNES sound data. If 16-bit sound mode is
+choosen, then the buffer will be filled with an array of sample_count int16,
+otherwise an array of sample_count uint8. If stereo sound generation is
+selected the buffer is filled with the same number of samples, but in pairs,
+first a left channel sample followed by the right channel sample.
+
+There is a limit on how much data S9xMixSamples can deal with in one go and
+hence a limit on the sample_count value; the limit is the value of the
+MAX_BUFFER_SIZE symbol, normally 4096 bytes.
+
+-> bool8 S9xSetSoundMute (bool8 mute)
+
+Call with a TRUE parmeter to prevent S9xMixSamples from processing SNES
+sample data and instead just filling the return buffer with silent sound
+data. Useful if your sound system is interrupt or callback driven and the
+game has been paused either directly or indirectly because the user
+interacting with the emulator's user interface in some way.
+
+-> bool8 S9xFreezeGame (const char *filename)
+
+Call this routine to record the current SNES hardware state into a file,
+the file can be loaded back using S9xUnfreezeGame at a later date effectively
+restoring the current game to exact same spot. Call this routine while
+you're processing any pending system events when S9xMainLoop has returned
+control to you in your main loop.
+
+-> bool8 S9xUnfreezeGame (const char *filename)
+
+Restore the SNES hardware back to the exactly the state it was in when
+S9xFreezeGame was used to generate the file specified. You have to arrange
+the correct ROM is already loaded using Memory.LoadROM, an easy way to
+arrange this is to base freeze-game filenames on the ROM image name. The
+Linux, UNIX and DOS ports load freeze-game files when the user presses a
+function key, with the names romfilename.000 for F1, romfilename.001 for F2,
+etc. Games are frozen in the first place when the user presses Shift-function
+key. You could choose some other scheme.
+
+-> void S9xNextController ()
+
+The real SNES allows several different types of devices to be plugged into
+the game controller ports. The devices Snes9x emulates are a joy-pad,
+multi-player adaptor (allowing a further 4 joy-pads to be plugged in),
+a 2-button mouse and a light gun known as the SuperScope.
+
+Each call to S9xNextController will step the current emulated device on to
+the next device in the sequence multi-player, joy-pad, mouse on port 1,
+mouse on port 2, light gun then back to multi-player again. Defines
+allocating a number of each device type are in snes9x.h. The currently
+selected device is stored in IPPU.Controller if you want to give some
+feedback to the user. The initial value of IPPU.Controller (set when
+S9xReset is called) is obtained from Settings.ControllerOption based on
+currently enabled options.
+
+Some ROMs object to certain non-joy-pad devices being plugged into the real
+SNES while they are running, all Super FX games should only allow joy-pads to
+be plugged in because the Super FX chip and any other device would overload
+the SNES power supply. Tetris and Dr. Mario also objects for reasons best
+known to itself. For this reason there are switches in the Settings
+structure to enable and display the emulation of the various devices.
+
+const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte)
+
+const char *S9xProActionReplayToRaw (const char *code, uint32 &address,
+ uint8 &byte)
+
+const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
+ uint8 &num_bytes, uint8 bytes[3])
+
+void S9xApplyCheats (bool8 apply)
+
+void S9xRemoveCheats ()
+
+void S9xAddCheat (uint32 address, bool8 cpu_address, bool8 sram, uint8 num_bytes,
+ uint8 byte1, uint8 byte2, uint8 byte3)
+
+void S9xDeleteCheats ()
+
+void S9xDoDebug ()
+
+Interface Routines You Need to Implement
+----------------------------------------
+
+bool8 S9xOpenSnapshotFile (const char *base, bool8 read_only, STREAM *file)
+***************************************************************************
+void S9xCloseSnapshotFile (STREAM file)
+***************************************
+
+Routines to open and close freeze-game files. STREAM is defined as a
+gzFile if ZLIB is defined else its defined as FILE *. The read_only parameter
+is set to TRUE when reading a freeze-game file and FALSE when writing a
+freeze-game file.
+
+void S9xExit ()
+***************
+
+Called when some fatal error situation arises or when the 'q' debugger
+command is used. The Mac port just beeps and drops back to the GUI when
+S9xExit is called, the MS-DOS, Linux and Solaris ports all call exit () to
+terminate the emulator process.
+
+void S9xParseArg (char **argv, int &index, int argc)
+****************************************************
+
+void S9xExtraUsage ()
+*********************
+
+If you're going to be using the simple command line parser, when it
+encounters an unknown option it calls S9xUsage which is supposed to report
+all options the generic parse knows about (I haven't been keeping it up to
+date of late). S9xUsage then, in turn calls S9xExtraUsage which you
+implement to report any port-specific options available.
+
+void S9xGraphicsMode ()
+***********************
+void S9xTextMode ()
+*******************
+
+The SNES debugger calls these routines to switch from a graphics screen
+mode used to display the SNES game to a debugger screen used to display
+debugger output. If the SNES screen can be displayed at the same time as
+a text display, as would be the case when the host system implements a
+graphical window system, or you're not going to support the SNES debugger,
+then these routines should do nothing.
+
+On the X Window System UNIX/Linux port, these routines do nothing where as
+on the MS-DOS port they switch between a graphics screen mode and a text-only
+screen mode.
+
+bool8 S9xInitUpdate ()
+**********************
+
+Called just before Snes9x starts to render a SNES screen. The Windows port
+uses this call to lock Direct X screen area to allow exclusive access; on
+other existing ports its implemented as an empty function.
+
+bool8 S9xDeinitDisplay (int width, int height, bool8 sixteen_bit)
+*****************************************************************
+
+Called once a complete SNES screen has been rendered into the GFX.Screen
+memory buffer, now is your chance to copy the SNES rendered screen to the
+host computer's screen memory. The problem is that you have to cope with
+different sized SNES rendered screens. Width is always 256, unless you're
+supporting SNES hi-res. screen modes (Settings.SupportHiRes is TRUE), in
+which case it can be 256 or 512. The height parameter can be either 224 or
+239 if you're only supporting SNES lo-res. screen modes, or 224, 239, 448 or
+478 if hi-res. SNES screen modes are being supported.
+
+All current ports support scaling the SNES screen to fill the host system's
+screen, the many ports even supports interpolation - blending the colours of
+adjacent pixels to help hide the fact they've been scaled - and scan-line
+simulation - slightly darkening every other horizontal line.
+
+Don't forget that if you're just placing the SNES image centerally in the
+screen then you might need to clear areas of the screen if the SNES image
+changes size between calls to S9xDeinitDisplay. The MS-DOS and UNIX ports
+currently don't do this which results in junk being left on the screen if
+the ROM changes SNES screen modes.
+
+The sixteen_bit is just a copy of the Settings.SixteenBit setting and if
+TRUE indicates a 16-bit SNES screen image has been rendered, 8-bit otherwise.
+
+void S9xMessage (int type, int number, const char *message)
+***********************************************************
+
+I've started work on converting all the old printfs into calls to this
+routine. When Snes9x wants to display an error, information or warning
+message, it calls this routine. Check in messages.h for the types and
+individual message numbers that Snes9x currently passes as parameters.
+
+The idea is display the message string so the user can see it, but you
+choose not to display anything at all, or change the message based on the
+message number or message type.
+
+Eventually all debug output will also go via this function, trace information
+already does.
+
+bool8 S9xOpenSoundDevice(int mode, bool8 stereo, int buffer_size)
+*****************************************************************
+
+S9xInitSound calls this function to actually open the host operating system's
+sound device, or initialise the sound card in MS-DOS port.
+
+The mode parameter is the value passed in on the command line with the -r
+command line flag, assuming you're using the Snes9x parser. Its meant to
+indicate what playback the sound hardware should be set to, value 1 to 7.
+I think the real SNES sound chip playback rate is 30kHz, but such high
+playback rates take a lot of native CPU power to emulate. The default
+playback rate is 22kHz for the MS-DOS and UNIX ports.
+
+The stereo flag indicates if the user wants stereo sound. Again, stereo
+sound takes more CPU to power to emulate compared to mono sound.
+
+The buffer_size value indicates what sample buffer size the user wants,
+usually zero, meaning you should pick the value best suited to the current
+playback rate. Sound data is normally passed to the sound hardware in
+blocks, the smaller the block the less latency between the SNES game playing
+a sound and it being heard by the user. But if you pick a too smaller value,
+and you're having to periodically poll the operating system to see if it can
+accept more sound data, then the sound output will break up because other
+actions such as rendering the SNES screen can prevent you from polling the
+hardware often enough and the operating system runs out of sound data to
+play.
+
+The MS-DOS port uses a buffer size of 128 samples since the sound card
+sends an interrupt when more data is required which is acted upon promptly,
+where as the Linux and Solaris ports use a buffer size of 512 samples or
+more depending on the playback rate. Stereo and 16-bit sound both double the
+actual size of the buffer in bytes.
+
+uint32 S9xReadJoypad (int which1_0_to_4)
+****************************************
+
+This function is called to return a bit-wise mask of the state of one of the
+five emulated SNES controllers. Return 0 if you're not supporting controllers
+past a certain number or return the mask representing the current state of
+the controller number passed as a parameter or'ed with 0x80000000.
+
+Symbolic constants are defined in snes9x.h indicating the bit positions of
+the various SNES buttons and direction indicators; they're all in the form
+SNES_X_MASK where X is the SNES controller button name.
+
+The MS-DOS and X Window System ports record what keys are currently pressed
+and use that to build up a mask, the Windows port polls the operating system
+when S9xReadJoypad is called to find out what keys are pressed. All ports
+also implement host joysticks and joy-pads via this interface.
+
+bool8 S9xReadMousePosition (int which1_0_to_1, int &x, int &y, uint32 &buttons)
+*******************************************************************************
+
+Used by Snes9x to get the current position of the host pointing device,
+usually a mouse, used to emulated the SNES mouse. Snes9x converts the x and
+y values to delta values required by the SNES mouse, so the actual x and y
+values are unimportant, only the change in value since the last call to
+this function is used.
+
+Graphical windowing systems normally restrict the movement of the pointer on
+the screen, if you're porting to such an environment you might want to make
+a note of the change in position in the mouse since the last time you asked
+the operating system the mouse position, add this change in value to some
+saved x and y value, the reposition the pointer back to the centre of the
+SNES display window. The saved x and y values will be the values returned
+by this function.
+
+The buttons return value is a bit-wise mask of the two SNES mouse buttons,
+bit 0 for button 1 (left) and bit 1 for button 2 (right).
+
+bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons)
+*****************************************************************
+
+void S9xSetPalette ()
+*********************
+
+void S9xSyncSpeed ()
+S9xUnixProcessSound
+void _makepath(char *, char const *, char const *, char const *, char const *)
+void _splitpath(char const *, char *, char *, char *, char *)
+
+
+Sound Generation
+----------------
+
+Settings
+--------
diff --git a/source/dsp1.cpp b/source/dsp1.cpp
new file mode 100644
index 0000000..2628447
--- /dev/null
+++ b/source/dsp1.cpp
@@ -0,0 +1,1455 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "snes9x.h"
+#include "dsp1.h"
+#include "missing.h"
+#include "memmap.h"
+#include <math.h>
+
+#include "dsp1emu.c"
+#include "dsp2emu.c"
+
+void (*SetDSP)(uint8, uint16)=&DSP1SetByte;
+uint8 (*GetDSP)(uint16)=&DSP1GetByte;
+
+void S9xInitDSP1 ()
+{
+ static bool8 init = FALSE;
+
+ if (!init)
+ {
+ InitDSP ();
+ init = TRUE;
+ }
+}
+
+void S9xResetDSP1 ()
+{
+ S9xInitDSP1 ();
+
+ DSP1.waiting4command = TRUE;
+ DSP1.in_count = 0;
+ DSP1.out_count = 0;
+ DSP1.in_index = 0;
+ DSP1.out_index = 0;
+ DSP1.first_parameter = TRUE;
+}
+
+uint8 S9xGetDSP (uint16 address)
+{
+ uint8 t;
+
+#ifdef DEBUGGER
+ if (Settings.TraceDSP)
+ {
+ sprintf (String, "DSP read: 0x%04X", address);
+ S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
+ }
+#endif
+
+ t=(*GetDSP)(address);
+ //DSP1GetByte(address);
+ return (t);
+}
+
+void S9xSetDSP (uint8 byte, uint16 address)
+{
+#ifdef DEBUGGER
+ missing.unknowndsp_write = address;
+ if (Settings.TraceDSP)
+ {
+ sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte);
+ S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
+ }
+#endif
+ (*SetDSP)(byte, address);
+ //DSP1SetByte(byte, address);
+}
+
+void DSP1SetByte(uint8 byte, uint16 address)
+{
+ if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 )
+ {
+// if ((address & 1) == 0)
+// {
+ if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0)
+ {
+ DSP1.out_count--;
+ DSP1.out_index++;
+ return;
+ }
+ else if (DSP1.waiting4command)
+ {
+ DSP1.command = byte;
+ DSP1.in_index = 0;
+ DSP1.waiting4command = FALSE;
+ DSP1.first_parameter = TRUE;
+// printf("Op%02X\n",byte);
+ // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a
+ switch (byte)
+ {
+ case 0x00: DSP1.in_count = 2; break;
+ case 0x30:
+ case 0x10: DSP1.in_count = 2; break;
+ case 0x20: DSP1.in_count = 2; break;
+ case 0x24:
+ case 0x04: DSP1.in_count = 2; break;
+ case 0x08: DSP1.in_count = 3; break;
+ case 0x18: DSP1.in_count = 4; break;
+ case 0x28: DSP1.in_count = 3; break;
+ case 0x38: DSP1.in_count = 4; break;
+ case 0x2c:
+ case 0x0c: DSP1.in_count = 3; break;
+ case 0x3c:
+ case 0x1c: DSP1.in_count = 6; break;
+ case 0x32:
+ case 0x22:
+ case 0x12:
+ case 0x02: DSP1.in_count = 7; break;
+ case 0x0a: DSP1.in_count = 1; break;
+ case 0x3a:
+ case 0x2a:
+ case 0x1a:
+ DSP1. command =0x1a;
+ DSP1.in_count = 1; break;
+ case 0x16:
+ case 0x26:
+ case 0x36:
+ case 0x06: DSP1.in_count = 3; break;
+ case 0x1e:
+ case 0x2e:
+ case 0x3e:
+ case 0x0e: DSP1.in_count = 2; break;
+ case 0x05:
+ case 0x35:
+ case 0x31:
+ case 0x01: DSP1.in_count = 4; break;
+ case 0x15:
+ case 0x11: DSP1.in_count = 4; break;
+ case 0x25:
+ case 0x21: DSP1.in_count = 4; break;
+ case 0x09:
+ case 0x39:
+ case 0x3d:
+ case 0x0d: DSP1.in_count = 3; break;
+ case 0x19:
+ case 0x1d: DSP1.in_count = 3; break;
+ case 0x29:
+ case 0x2d: DSP1.in_count = 3; break;
+ case 0x33:
+ case 0x03: DSP1.in_count = 3; break;
+ case 0x13: DSP1.in_count = 3; break;
+ case 0x23: DSP1.in_count = 3; break;
+ case 0x3b:
+ case 0x0b: DSP1.in_count = 3; break;
+ case 0x1b: DSP1.in_count = 3; break;
+ case 0x2b: DSP1.in_count = 3; break;
+ case 0x34:
+ case 0x14: DSP1.in_count = 6; break;
+ case 0x07:
+ case 0x0f: DSP1.in_count = 1; break;
+ case 0x27:
+ case 0x2F: DSP1.in_count=1; break;
+ case 0x17:
+ case 0x37:
+ case 0x3F:
+ DSP1.command=0x1f;
+ case 0x1f: DSP1.in_count = 1; break;
+ // case 0x80: DSP1.in_count = 2; break;
+ default:
+ //printf("Op%02X\n",byte);
+ case 0x80:
+ DSP1.in_count = 0;
+ DSP1.waiting4command = TRUE;
+ DSP1.first_parameter = TRUE;
+ break;
+ }
+ DSP1.in_count<<=1;
+ }
+ else
+ {
+ DSP1.parameters [DSP1.in_index] = byte;
+ DSP1.first_parameter = FALSE;
+ DSP1.in_index++;
+ }
+
+ if (DSP1.waiting4command ||
+ (DSP1.first_parameter && byte == 0x80))
+ {
+ DSP1.waiting4command = TRUE;
+ DSP1.first_parameter = FALSE;
+ }
+ else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0)))
+ {
+ }
+// else if (DSP1.first_parameter)
+// {
+// }
+ else
+ {
+ if (DSP1.in_count)
+ {
+ //DSP1.parameters [DSP1.in_index] |= (byte << 8);
+ if (--DSP1.in_count == 0)
+ {
+ // Actually execute the command
+ DSP1.waiting4command = TRUE;
+ DSP1.out_index = 0;
+ switch (DSP1.command)
+ {
+ case 0x1f:
+ DSP1.out_count=2048;
+ break;
+ case 0x00: // Multiple
+ Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+
+ DSPOp00 ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = Op00Result&0xFF;
+ DSP1.output [1] = (Op00Result>>8)&0xFF;
+ break;
+
+ case 0x20: // Multiple
+ Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+
+ DSPOp20 ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = Op20Result&0xFF;
+ DSP1.output [1] = (Op20Result>>8)&0xFF;
+ break;
+
+ case 0x30:
+ case 0x10: // Inverse
+ Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+
+ DSPOp10 ();
+
+ DSP1.out_count = 4;
+ DSP1.output [0] = (uint8) (((int16) Op10CoefficientR)&0xFF);
+ DSP1.output [1] = (uint8) ((((int16) Op10CoefficientR)>>8)&0xFF);
+ DSP1.output [2] = (uint8) (((int16) Op10ExponentR)&0xff);
+ DSP1.output [3] = (uint8) ((((int16) Op10ExponentR)>>8)&0xff);
+ break;
+
+ case 0x24:
+ case 0x04: // Sin and Cos of angle
+ Op04Angle = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op04Radius = (uint16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+
+ DSPOp04 ();
+
+ DSP1.out_count = 4;
+ DSP1.output [0] = (uint8) (Op04Sin&0xFF);
+ DSP1.output [1] = (uint8) ((Op04Sin>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op04Cos&0xFF);
+ DSP1.output [3] = (uint8) ((Op04Cos>>8)&0xFF);
+ break;
+
+ case 0x08: // Radius
+ Op08X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op08Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op08Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp08 ();
+
+ DSP1.out_count = 4;
+ DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF);
+ DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF);
+ DSP1.output [2] = (uint8) (((int16) Op08Lh)&0xFF);
+ DSP1.output [3] = (uint8) ((((int16) Op08Lh)>>8)&0xFF);
+ break;
+
+ case 0x18: // Range
+
+ Op18X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op18Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op18Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op18R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+
+ DSPOp18 ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8) (Op18D&0xFF);
+ DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF);
+ break;
+
+ case 0x38: // Range
+
+ Op38X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op38Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op38Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op38R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+
+ DSPOp38 ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8) (Op38D&0xFF);
+ DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF);
+ break;
+
+ case 0x28: // Distance (vector length)
+ Op28X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op28Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op28Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp28 ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8) (Op28R&0xFF);
+ DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF);
+ break;
+
+ case 0x2c:
+ case 0x0c: // Rotate (2D rotate)
+ Op0CA = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op0CX1 = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op0CY1 = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp0C ();
+
+ DSP1.out_count = 4;
+ DSP1.output [0] = (uint8) (Op0CX2&0xFF);
+ DSP1.output [1] = (uint8) ((Op0CX2>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op0CY2&0xFF);
+ DSP1.output [3] = (uint8) ((Op0CY2>>8)&0xFF);
+ break;
+
+ case 0x3c:
+ case 0x1c: // Polar (3D rotate)
+ Op1CZ = (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ //MK: reversed X and Y on neviksti and John's advice.
+ Op1CY = (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op1CX = (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op1CXBR = (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+ Op1CYBR = (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
+ Op1CZBR = (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
+
+ DSPOp1C ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op1CXAR&0xFF);
+ DSP1.output [1] = (uint8) ((Op1CXAR>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op1CYAR&0xFF);
+ DSP1.output [3] = (uint8) ((Op1CYAR>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op1CZAR&0xFF);
+ DSP1.output [5] = (uint8) ((Op1CZAR>>8)&0xFF);
+ break;
+
+ case 0x32:
+ case 0x22:
+ case 0x12:
+ case 0x02: // Parameter (Projection)
+ Op02FX = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op02FY = (short)(DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op02FZ = (short)(DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op02LFE = (short)(DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+ Op02LES = (short)(DSP1.parameters [8]|(DSP1.parameters[9]<<8));
+ Op02AAS = (unsigned short)(DSP1.parameters [10]|(DSP1.parameters[11]<<8));
+ Op02AZS = (unsigned short)(DSP1.parameters [12]|(DSP1.parameters[13]<<8));
+
+ DSPOp02 ();
+
+ DSP1.out_count = 8;
+ DSP1.output [0] = (uint8) (Op02VOF&0xFF);
+ DSP1.output [1] = (uint8) ((Op02VOF>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op02VVA&0xFF);
+ DSP1.output [3] = (uint8) ((Op02VVA>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op02CX&0xFF);
+ DSP1.output [5] = (uint8) ((Op02CX>>8)&0xFF);
+ DSP1.output [6] = (uint8) (Op02CY&0xFF);
+ DSP1.output [7] = (uint8) ((Op02CY>>8)&0xFF);
+ break;
+
+ case 0x3a: //1a Mirror
+ case 0x2a: //1a Mirror
+ case 0x1a: // Raster mode 7 matrix data
+ case 0x0a:
+ Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+
+ DSPOp0A ();
+
+ DSP1.out_count = 8;
+ DSP1.output [0] = (uint8) (Op0AA&0xFF);
+ DSP1.output [2] = (uint8) (Op0AB&0xFF);
+ DSP1.output [4] = (uint8) (Op0AC&0xFF);
+ DSP1.output [6] = (uint8) (Op0AD&0xFF);
+ DSP1.output [1] = (uint8) ((Op0AA>>8)&0xFF);
+ DSP1.output [3] = (uint8) ((Op0AB>>8)&0xFF);
+ DSP1.output [5] = (uint8) ((Op0AC>>8)&0xFF);
+ DSP1.output [7] = (uint8) ((Op0AD>>8)&0xFF);
+ DSP1.in_index=0;
+ break;
+
+ case 0x16:
+ case 0x26:
+ case 0x36:
+ case 0x06: // Project object
+ Op06X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op06Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op06Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp06 ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op06H&0xff);
+ DSP1.output [1] = (uint8) ((Op06H>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op06V&0xFF);
+ DSP1.output [3] = (uint8) ((Op06V>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op06S&0xFF);
+ DSP1.output [5] = (uint8) ((Op06S>>8)&0xFF);
+ break;
+
+ case 0x1e:
+ case 0x2e:
+ case 0x3e:
+ case 0x0e: // Target
+ Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+
+ DSPOp0E ();
+
+ DSP1.out_count = 4;
+ DSP1.output [0] = (uint8) (Op0EX&0xFF);
+ DSP1.output [1] = (uint8) ((Op0EX>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op0EY&0xFF);
+ DSP1.output [3] = (uint8) ((Op0EY>>8)&0xFF);
+ break;
+
+ // Extra commands used by Pilot Wings
+ case 0x05:
+ case 0x35:
+ case 0x31:
+ case 0x01: // Set attitude matrix A
+ Op01m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op01Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op01Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op01Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+
+ DSPOp01 ();
+ break;
+
+ case 0x15:
+ case 0x11: // Set attitude matrix B
+ Op11m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op11Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op11Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op11Xr = (int16) (DSP1.parameters [7]|(DSP1.parameters[7]<<8));
+
+ DSPOp11 ();
+ break;
+
+ case 0x25:
+ case 0x21: // Set attitude matrix C
+ Op21m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op21Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op21Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op21Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+
+ DSPOp21 ();
+ break;
+
+ case 0x09:
+ case 0x39:
+ case 0x3d:
+ case 0x0d: // Objective matrix A
+ Op0DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op0DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op0DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp0D ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op0DF&0xFF);
+ DSP1.output [1] = (uint8) ((Op0DF>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op0DL&0xFF);
+ DSP1.output [3] = (uint8) ((Op0DL>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op0DU&0xFF);
+ DSP1.output [5] = (uint8) ((Op0DU>>8)&0xFF);
+ break;
+
+ case 0x19:
+ case 0x1d: // Objective matrix B
+ Op1DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op1DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op1DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp1D ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op1DF&0xFF);
+ DSP1.output [1] = (uint8) ((Op1DF>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op1DL&0xFF);
+ DSP1.output [3] = (uint8) ((Op1DL>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op1DU&0xFF);
+ DSP1.output [5] = (uint8) ((Op1DU>>8)&0xFF);
+ break;
+
+ case 0x29:
+ case 0x2d: // Objective matrix C
+ Op2DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op2DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op2DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp2D ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op2DF&0xFF);
+ DSP1.output [1] = (uint8) ((Op2DF>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op2DL&0xFF);
+ DSP1.output [3] = (uint8) ((Op2DL>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op2DU&0xFF);
+ DSP1.output [5] = (uint8) ((Op2DU>>8)&0xFF);
+ break;
+
+ case 0x33:
+ case 0x03: // Subjective matrix A
+ Op03F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op03L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op03U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp03 ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op03X&0xFF);
+ DSP1.output [1] = (uint8) ((Op03X>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op03Y&0xFF);
+ DSP1.output [3] = (uint8) ((Op03Y>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op03Z&0xFF);
+ DSP1.output [5] = (uint8) ((Op03Z>>8)&0xFF);
+ break;
+
+ case 0x13: // Subjective matrix B
+ Op13F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op13L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op13U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp13 ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op13X&0xFF);
+ DSP1.output [1] = (uint8) ((Op13X>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op13Y&0xFF);
+ DSP1.output [3] = (uint8) ((Op13Y>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op13Z&0xFF);
+ DSP1.output [5] = (uint8) ((Op13Z>>8)&0xFF);
+ break;
+
+ case 0x23: // Subjective matrix C
+ Op23F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op23L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op23U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp23 ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op23X&0xFF);
+ DSP1.output [1] = (uint8) ((Op23X>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op23Y&0xFF);
+ DSP1.output [3] = (uint8) ((Op23Y>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op23Z&0xFF);
+ DSP1.output [5] = (uint8) ((Op23Z>>8)&0xFF);
+ break;
+
+ case 0x3b:
+ case 0x0b:
+ Op0BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op0BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op0BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp0B ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8) (Op0BS&0xFF);
+ DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF);
+ break;
+
+ case 0x1b:
+ Op1BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op1BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op1BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp1B ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8) (Op1BS&0xFF);
+ DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF);
+ break;
+
+ case 0x2b:
+ Op2BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op2BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op2BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+
+ DSPOp2B ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8) (Op2BS&0xFF);
+ DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF);
+ break;
+
+ case 0x34:
+ case 0x14:
+ Op14Zr = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+ Op14Xr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
+ Op14Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
+ Op14U = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
+ Op14F = (int16) (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
+ Op14L = (int16) (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
+
+ DSPOp14 ();
+
+ DSP1.out_count = 6;
+ DSP1.output [0] = (uint8) (Op14Zrr&0xFF);
+ DSP1.output [1] = (uint8) ((Op14Zrr>>8)&0xFF);
+ DSP1.output [2] = (uint8) (Op14Xrr&0xFF);
+ DSP1.output [3] = (uint8) ((Op14Xrr>>8)&0xFF);
+ DSP1.output [4] = (uint8) (Op14Yrr&0xFF);
+ DSP1.output [5] = (uint8) ((Op14Yrr>>8)&0xFF);
+ break;
+
+ case 0x27:
+ case 0x2F:
+ Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+
+ DSPOp2F ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8)(Op2FSize&0xFF);
+ DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF);
+ break;
+
+
+ case 0x07:
+ case 0x0F:
+ Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
+
+ DSPOp0F ();
+
+ DSP1.out_count = 2;
+ DSP1.output [0] = (uint8)(Op0FPass&0xFF);
+ DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+uint8 DSP1GetByte(uint16 address)
+{
+ uint8 t;
+ if ((address & 0xf000) == 0x6000 ||
+// (address >= 0x8000 && address < 0xc000))
+ (address&0x7fff) < 0x4000)
+ {
+ if (DSP1.out_count)
+ {
+ //if ((address & 1) == 0)
+ t = (uint8) DSP1.output [DSP1.out_index];
+ //else
+ //{
+ // t = (uint8) (DSP1.output [DSP1.out_index] >> 8);
+ DSP1.out_index++;
+ if (--DSP1.out_count == 0)
+ {
+ if (DSP1.command == 0x1a || DSP1.command == 0x0a)
+ {
+ DSPOp0A ();
+ DSP1.out_count = 8;
+ DSP1.out_index = 0;
+ DSP1.output [0] = (Op0AA&0xFF);
+ DSP1.output [1] = (Op0AA>>8)&0xFF;
+ DSP1.output [2] = (Op0AB&0xFF);
+ DSP1.output [3] = (Op0AB>>8)&0xFF;
+ DSP1.output [4] = (Op0AC&0xFF);
+ DSP1.output [5] = (Op0AC>>8)&0xFF;
+ DSP1.output [6] = (Op0AD&0xFF);
+ DSP1.output [7] = (Op0AD>>8)&0xFF;
+ }
+ if(DSP1.command==0x1f)
+ {
+ if((DSP1.out_index%2)!=0)
+ {
+ t=(uint8)DSP1ROM[DSP1.out_index>>1];
+ }
+ else
+ {
+ t=DSP1ROM[DSP1.out_index>>1]>>8;
+ }
+ }
+ }
+ DSP1.waiting4command = TRUE;
+ //}
+ }
+ else
+ {
+ // Top Gear 3000 requires this value....
+ // if(4==Settings.DSPVersion)
+ t = 0xff;
+ //Ballz3d requires this one:
+ // else t = 0x00;
+ }
+ }
+ else t = 0x80;
+ return t;
+}
+
+void DSP2SetByte(uint8 byte, uint16 address)
+{
+ if ((address & 0xf000) == 0x6000 ||
+ (address >= 0x8000 && address < 0xc000))
+ {
+ if (DSP1.waiting4command)
+ {
+ DSP1.command = byte;
+ DSP1.in_index = 0;
+ DSP1.waiting4command = FALSE;
+// DSP1.first_parameter = TRUE;
+// printf("Op%02X\n",byte);
+ switch (byte)
+ {
+ case 0x01:DSP1.in_count=32;break;
+ case 0x03:DSP1.in_count=1;break;
+ case 0x05:DSP1.in_count=1;break;
+ case 0x09:DSP1.in_count=4;break;
+ case 0x06:DSP1.in_count=1;break;
+ case 0x0D:DSP1.in_count=2;break;
+ default:
+ printf("Op%02X\n",byte);
+ case 0x0f:DSP1.in_count=0;break;
+ }
+ }
+ else
+ {
+ DSP1.parameters [DSP1.in_index] = byte;
+// DSP1.first_parameter = FALSE;
+ DSP1.in_index++;
+ }
+
+ if (DSP1.in_count==DSP1.in_index)
+ {
+ //DSP1.parameters [DSP1.in_index] |= (byte << 8);
+ // Actually execute the command
+ DSP1.waiting4command = TRUE;
+ DSP1.out_index = 0;
+ switch (DSP1.command)
+ {
+ case 0x0D:
+ if(DSP2Op0DHasLen)
+ {
+ DSP2Op0DHasLen=false;
+ DSP1.out_count=DSP2Op0DOutLen;
+ //execute Op5
+ DSP2_Op0D();
+ }
+ else
+ {
+ DSP2Op0DInLen=DSP1.parameters[0];
+ DSP2Op0DOutLen=DSP1.parameters[1];
+ DSP1.in_index=0;
+ DSP1.in_count=(DSP2Op0DInLen+1)>>1;
+ DSP2Op0DHasLen=true;
+ if(byte)
+ DSP1.waiting4command=false;
+ }
+ break;
+ case 0x06:
+ if(DSP2Op06HasLen)
+ {
+ DSP2Op06HasLen=false;
+ DSP1.out_count=DSP2Op06Len;
+ //execute Op5
+ DSP2_Op06();
+ }
+ else
+ {
+ DSP2Op06Len=DSP1.parameters[0];
+ DSP1.in_index=0;
+ DSP1.in_count=DSP2Op06Len;
+ DSP2Op06HasLen=true;
+ if(byte)
+ DSP1.waiting4command=false;
+ }
+ break;
+ case 0x01:
+ DSP1.out_count=32;
+ DSP2_Op01();
+ break;
+ case 0x09:
+ // Multiply - don't yet know if this is signed or unsigned
+ DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1]<<8);
+ DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3]<<8);
+ DSP1.out_count=4;
+#ifdef FAST_LSB_WORD_ACCESS
+ *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2;
+#else
+ uint32 temp;
+ temp=DSP2Op09Word1 * DSP2Op09Word2;
+ DSP1.output[0]=temp&0xFF;
+ DSP1.output[1]=(temp>>8)&0xFF;
+ DSP1.output[2]=(temp>>16)&0xFF;
+ DSP1.output[3]=(temp>>24)&0xFF;
+#endif
+ break;
+ case 0x05:
+ if(DSP2Op05HasLen)
+ {
+ DSP2Op05HasLen=false;
+ DSP1.out_count=DSP2Op05Len;
+ //execute Op5
+ DSP2_Op05();
+ }
+ else
+ {
+ DSP2Op05Len=DSP1.parameters[0];
+ DSP1.in_index=0;
+ DSP1.in_count=2*DSP2Op05Len;
+ DSP2Op05HasLen=true;
+ if(byte)
+ DSP1.waiting4command=false;
+ }
+ break;
+
+ case 0x03:
+ DSP2Op05Transparent= DSP1.parameters[0];
+ //DSP2Op03();
+ break;
+ case 0x0f:
+ default:
+ break;
+ }
+ }
+ }
+}
+
+uint8 DSP2GetByte(uint16 address)
+{
+ uint8 t;
+ if ((address & 0xf000) == 0x6000 ||
+ (address >= 0x8000 && address < 0xc000))
+ {
+ if (DSP1.out_count)
+ {
+ t = (uint8) DSP1.output [DSP1.out_index];
+ DSP1.out_index++;
+ if(DSP1.out_count==DSP1.out_index)
+ DSP1.out_count=0;
+ }
+ else
+ {
+ t = 0xff;
+ }
+ }
+ else t = 0x80;
+ return t;
+}
+
+//Disable non-working chips?
+#ifdef DSP_DUMMY_LOOPS
+
+uint16 Dsp3Rom[1024] = {
+ 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100,
+ 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001,
+ 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+ 0x0000, 0x000f, 0x0400, 0x0200, 0x0140, 0x0400, 0x0200, 0x0040,
+ 0x007d, 0x007e, 0x007e, 0x007b, 0x007c, 0x007d, 0x007b, 0x007c,
+ 0x0002, 0x0020, 0x0030, 0x0000, 0x000d, 0x0019, 0x0026, 0x0032,
+ 0x003e, 0x004a, 0x0056, 0x0062, 0x006d, 0x0079, 0x0084, 0x008e,
+ 0x0098, 0x00a2, 0x00ac, 0x00b5, 0x00be, 0x00c6, 0x00ce, 0x00d5,
+ 0x00dc, 0x00e2, 0x00e7, 0x00ec, 0x00f1, 0x00f5, 0x00f8, 0x00fb,
+ 0x00fd, 0x00ff, 0x0100, 0x0100, 0x0100, 0x00ff, 0x00fd, 0x00fb,
+ 0x00f8, 0x00f5, 0x00f1, 0x00ed, 0x00e7, 0x00e2, 0x00dc, 0x00d5,
+ 0x00ce, 0x00c6, 0x00be, 0x00b5, 0x00ac, 0x00a2, 0x0099, 0x008e,
+ 0x0084, 0x0079, 0x006e, 0x0062, 0x0056, 0x004a, 0x003e, 0x0032,
+ 0x0026, 0x0019, 0x000d, 0x0000, 0xfff3, 0xffe7, 0xffdb, 0xffce,
+ 0xffc2, 0xffb6, 0xffaa, 0xff9e, 0xff93, 0xff87, 0xff7d, 0xff72,
+ 0xff68, 0xff5e, 0xff54, 0xff4b, 0xff42, 0xff3a, 0xff32, 0xff2b,
+ 0xff25, 0xff1e, 0xff19, 0xff14, 0xff0f, 0xff0b, 0xff08, 0xff05,
+ 0xff03, 0xff01, 0xff00, 0xff00, 0xff00, 0xff01, 0xff03, 0xff05,
+ 0xff08, 0xff0b, 0xff0f, 0xff13, 0xff18, 0xff1e, 0xff24, 0xff2b,
+ 0xff32, 0xff3a, 0xff42, 0xff4b, 0xff54, 0xff5d, 0xff67, 0xff72,
+ 0xff7c, 0xff87, 0xff92, 0xff9e, 0xffa9, 0xffb5, 0xffc2, 0xffce,
+ 0xffda, 0xffe7, 0xfff3, 0x002b, 0x007f, 0x0020, 0x00ff, 0xff00,
+ 0xffbe, 0x0000, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0x0045,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffc5, 0x0003, 0x0004, 0x0005, 0x0047, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x004a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x004e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
+ 0x0012, 0x0013, 0x0014, 0x0053, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
+ 0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
+ 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0060, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
+ 0x002b, 0x002c, 0x0068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0071,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
+ 0x003e, 0x003f, 0x0040, 0x0041, 0x007b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
+ 0x000b, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
+ 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0050, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
+ 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x005d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
+ 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x006b, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
+ 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0044, 0x0000, 0x0000,
+ 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
+ 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
+ 0x001f, 0x0020, 0x0054, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
+ 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0065,
+ 0xffbe, 0x0000, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0xfead,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffc5, 0x0003, 0x0004, 0x0005, 0xfeaf, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0xfeb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0xfeb6, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
+ 0x0012, 0x0013, 0x0014, 0xfebb, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
+ 0xfec1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
+ 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0xfec8, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
+ 0x002b, 0x002c, 0xfed0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0xfed9,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
+ 0x003e, 0x003f, 0x0040, 0x0041, 0xfee3, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
+ 0x000b, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
+ 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0xfeb8, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
+ 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0xfec5, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
+ 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0xfed3, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
+ 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xfeac, 0x0000, 0x0000,
+ 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
+ 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
+ 0x001f, 0x0020, 0xfebc, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
+ 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0xfecd,
+ 0x0154, 0x0218, 0x0110, 0x00b0, 0x00cc, 0x00b0, 0x0088, 0x00b0,
+ 0x0044, 0x00b0, 0x0000, 0x00b0, 0x00fe, 0xff07, 0x0002, 0x00ff,
+ 0x00f8, 0x0007, 0x00fe, 0x00ee, 0x07ff, 0x0200, 0x00ef, 0xf800,
+ 0x0700, 0x00ee, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0001,
+ 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000,
+ 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0x0001, 0x0000, 0x0001,
+ 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000,
+ 0xffff, 0x0001, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff,
+ 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0044, 0x0088, 0x00cc,
+ 0x0110, 0x0154, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
+};
+
+void DSP3SetByte(uint8 byte, uint16 address)
+{
+ if ((address & 0xf000) == 0x6000 ||
+ (address >= 0x8000 && address < 0xc000))
+ {
+ if (DSP1.waiting4command)
+ {
+ DSP1.command = byte;
+ DSP1.in_index = 0;
+ DSP1.waiting4command = FALSE;
+// DSP1.first_parameter = TRUE;
+// printf("Op%02X\n",byte);
+ switch (byte)
+ {
+ case 0x2F:DSP1.in_count=2;break;
+ case 0x1F:DSP1.in_count=2;break;
+ case 0x0F:DSP1.in_count=2;break;
+ case 0x38:DSP1.in_count=4;break;
+ default:
+// printf("Op%02X\n",byte);
+ break;
+ }
+ }
+ else
+ {
+ DSP1.parameters [DSP1.in_index] = byte;
+// DSP1.first_parameter = FALSE;
+ DSP1.in_index++;
+ }
+
+ if (DSP1.in_count==DSP1.in_index)
+ {
+ //DSP1.parameters [DSP1.in_index] |= (byte << 8);
+ // Actually execute the command
+ DSP1.waiting4command = TRUE;
+ DSP1.out_index = 0;
+ switch (DSP1.command)
+ {
+ case 0x2F:DSP1.out_count=2;break;
+ case 0x1F:DSP1.out_count=2048;break;
+ case 0x0F:DSP1.out_count=2;
+ DSP1.output[0]=0;
+ DSP1.output[1]=0;
+ break;
+ case 0x38:
+ {
+ DSP1.out_count=2;
+ // 176B
+ DSP1.output[0]=0;
+ DSP1.output[1]=0x80;
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+}
+
+uint8 DSP3GetByte(uint16 address)
+{
+ uint8 t;
+ if ((address & 0xf000) == 0x6000 ||
+ (address >= 0x8000 && address < 0xc000))
+ {
+ if(DSP1.command==0x38&&DSP1.out_index==1)
+ {
+ t=4;
+ }
+
+ if (DSP1.out_count)
+ {
+ if(DSP1.command==0x1f)
+ {
+ if((DSP1.out_index%2)!=0)
+ {
+ t=(uint8)Dsp3Rom[DSP1.out_index>>1];
+ }
+ else
+ {
+ t=Dsp3Rom[DSP1.out_index>>1]>>8;
+ }
+// t=Dsp3Rom[DSP1.out_index];
+ DSP1.out_index++;
+ }
+ else
+ {
+ t = (uint8) DSP1.output [DSP1.out_index];
+ DSP1.out_index++;
+ DSP1.out_index%=512;
+ if(DSP1.out_count==DSP1.out_index)
+ DSP1.out_count=0;
+ }
+ }
+ else
+ {
+ t = 0xff;
+ }
+ }
+ else
+ {
+ t = 0x80;
+/* if(DSP1.command=0x38&&DSP1.out_count==0)
+ {
+ t=0xC0;
+ static int Op38c;
+ if(Op38c==14)
+ {
+ Op38c=0;
+ t=0x80;
+ DSP1.in_count=4;
+ }
+ Op38c++;
+ }*/
+ }
+ return t;
+}
+
+#endif
+
+struct SDSP4 {
+ bool8 waiting4command;
+ bool8 half_command;
+ uint16 command;
+ uint32 in_count;
+ uint32 in_index;
+ uint32 out_count;
+ uint32 out_index;
+ uint8 parameters [512];
+ uint8 output [512];
+};
+
+SDSP4 DSP4;
+
+#include "dsp4emu.cpp"
+
+bool DSP4_init=FALSE;
+
+void DSP4SetByte(uint8 byte, uint16 address)
+{
+ if(!DSP4_init)
+ {
+ // bootup
+ DSP4.waiting4command=1;
+ DSP4_init=TRUE;
+ }
+
+ if ((address & 0xf000) == 0x6000 ||
+ (address >= 0x8000 && address < 0xc000))
+ {
+ if(DSP4.out_index<DSP4.out_count)
+ {
+ DSP4.out_index++;
+ return;
+ }
+
+ if (DSP4.waiting4command)
+ {
+ if(DSP4.half_command)
+ {
+ DSP4.command |= (byte<<8);
+ DSP4.in_index = 0;
+ DSP4.waiting4command = FALSE;
+ // DSP4.first_parameter = TRUE;
+ DSP4.half_command=0;
+ DSP4.out_count=0;
+ DSP4.out_index=0;
+ DSP4_Logic=0;
+
+ switch (DSP4.command)
+ {
+ case 0x0000:DSP4.in_count=4;break;
+ case 0x0001:DSP4.in_count=36;break;
+ case 0x0003:DSP4.in_count=0;break;
+ case 0x0005:DSP4.in_count=0;break;
+ case 0x0006:DSP4.in_count=0;break;
+ case 0x0007:DSP4.in_count=22;break;
+ case 0x0008:DSP4.in_count=72;break;
+ case 0x0009:DSP4.in_count=14;break;
+ case 0x000A:DSP4.in_count=6;break;
+ case 0x000B:DSP4.in_count=6;break;
+ case 0x000D:DSP4.in_count=34;break;
+ case 0x000E:DSP4.in_count=0;break;
+ case 0x0011:DSP4.in_count=8;break;
+ default:
+ DSP4.waiting4command=TRUE;
+ //printf("(line %d) Unknown Op%02X\n",line,DSP4.command);
+ break;
+ }
+ }
+ else
+ {
+ DSP4.command=byte;
+ DSP4.half_command=1;
+ }
+ }
+ else
+ {
+ DSP4.parameters [DSP4.in_index] = byte;
+// DSP4.first_parameter = FALSE;
+ DSP4.in_index++;
+ }
+
+ if (!DSP4.waiting4command && DSP4.in_count==DSP4.in_index)
+ {
+ //DSP4.parameters [DSP4.in_index] |= (byte << 8);
+ // Actually execute the command
+ DSP4.waiting4command = TRUE;
+ DSP4.out_index = 0;
+ DSP4.in_index=0;
+ switch (DSP4.command)
+ {
+ // 16-bit multiplication
+ case 0x0000:
+ {
+ int16 multiplier, multiplicand;
+ int product;
+
+ multiplier = DSP4_READ_WORD(0);
+ multiplicand = DSP4_READ_WORD(2);
+
+ DSP4_Multiply(multiplicand,multiplier,product);
+
+ DSP4.out_count = 4;
+ DSP4_WRITE_WORD(0,product);
+ DSP4_WRITE_WORD(2,product>>16);
+ }
+ break;
+
+ // unknown: horizontal mapping command
+ case 0x0011:
+ {
+ int16 a,b,c,d,m;
+
+ a = DSP4_READ_WORD(6);
+ b = DSP4_READ_WORD(4);
+ c = DSP4_READ_WORD(2);
+ d = DSP4_READ_WORD(0);
+
+ DSP4_UnknownOP11(a,b,c,d,m);
+
+ DSP4.out_count = 2;
+ DSP4_WRITE_WORD(0,m);
+ break;
+ }
+
+ // track projection
+ case 0x0001: DSP4_Op01(); break;
+
+ // track projection (pass 2)
+ case 0x0007: DSP4_Op07(); break;
+
+ // zone projections (fuel/repair/lap/teleport/...)
+ case 0x0008: DSP4_Op08(); break;
+
+ // sprite transformation
+ case 0x0009: DSP4_Op09(); break;
+
+ // fast track projection
+ case 0x000D: DSP4_Op0D(); break;
+
+ // internal memory management (01)
+ case 0x0003:
+ {
+ // reset op09 data
+ op09_mode = 0;
+ break;
+ }
+
+ // internal memory management (06)
+ case 0x0005:
+ {
+ // clear OAM tables
+ op06_index = 0;
+ op06_offset = 0;
+ for( int lcv=0; lcv<32; lcv++ )
+ op06_OAM[lcv] = 0;
+ break;
+ }
+
+ // internal memory management (0D)
+ case 0x000E:
+ {
+ // reset op09 data
+ op09_mode = 1;
+ break;
+ }
+
+ // sprite OAM post-table data
+ case 0x0006:
+ {
+ DSP4.out_count = 32;
+ for( int lcv=0; lcv<32; lcv++ )
+ DSP4.output[lcv] = op06_OAM[lcv];
+ }
+ break;
+
+ // unknown
+ case 0x000A:
+ {
+ int16 in1a = DSP4_READ_WORD(0);
+ int16 in2a = DSP4_READ_WORD(2);
+ int16 in3a = DSP4_READ_WORD(4);
+ int16 out1a,out2a;
+
+ out1a=(short)0xff40;
+ out2a=(short)0x00c0;
+
+ DSP4.out_count=8;
+
+ DSP4_WRITE_WORD(0,out1a);
+ DSP4_WRITE_WORD(2,out2a);
+ DSP4_WRITE_WORD(4,out1a);
+ DSP4_WRITE_WORD(6,out2a);
+ }
+ break;
+
+ // render player positions around track
+ case 0x000B:
+ {
+ int16 sp_x = DSP4_READ_WORD(0);
+ int16 sp_y = DSP4_READ_WORD(2);
+ int16 oam = DSP4_READ_WORD(4);
+
+ // Only allow 1p/1p-split to yield output (???)
+ if(!op09_mode)
+ {
+ // yield OAM output
+ DSP4.out_count = 6;
+ DSP4_WRITE_WORD(0,1);
+
+ // pack OAM data: x,y,name,attr
+ DSP4.output[2] = sp_x & 0xff;
+ DSP4.output[3] = sp_y & 0xff;
+ DSP4_WRITE_WORD(4,oam);
+
+ // OAM: size,msb data
+ DSP4_Op06(0,0);
+ }
+ // 4p mode
+ else
+ {
+ // no OAM available
+ DSP4.out_count=0;
+ DSP4_WRITE_WORD(0,0);
+ }
+ }
+ break;
+
+ default: break;
+ }
+ }
+ }
+}
+
+uint8 DSP4GetByte(uint16 address)
+{
+ uint8 t;
+ if ((address & 0xf000) == 0x6000 ||
+ (address >= 0x8000 && address < 0xc000))
+ {
+ if (DSP4.out_count)
+ {
+ t = (uint8) DSP4.output [DSP4.out_index];
+ DSP4.out_index++;
+ if(DSP4.out_count==DSP4.out_index)
+ DSP4.out_count=0;
+ }
+ else
+ t = 0xff;
+ }
+ else
+ {
+ t = 0x80;
+ }
+
+ return t;
+}
+
diff --git a/source/dsp1.h b/source/dsp1.h
new file mode 100644
index 0000000..269f4ad
--- /dev/null
+++ b/source/dsp1.h
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _DSP1_H_
+#define _DSP1_H_
+
+extern void (*SetDSP)(uint8, uint16);
+extern uint8 (*GetDSP)(uint16);
+
+void DSP1SetByte(uint8 byte, uint16 address);
+uint8 DSP1GetByte(uint16 address);
+
+void DSP2SetByte(uint8 byte, uint16 address);
+uint8 DSP2GetByte(uint16 address);
+
+void DSP3SetByte(uint8 byte, uint16 address);
+uint8 DSP3GetByte(uint16 address);
+
+void DSP4SetByte(uint8 byte, uint16 address);
+uint8 DSP4GetByte(uint16 address);
+
+struct SDSP1 {
+ bool8 waiting4command;
+ bool8 first_parameter;
+ uint8 command;
+ uint32 in_count;
+ uint32 in_index;
+ uint32 out_count;
+ uint32 out_index;
+ uint8 parameters [512];
+//output was 512 for DSP-2 work, updated to reflect current thinking on DSP-3
+ uint8 output [512];
+};
+
+START_EXTERN_C
+void S9xResetDSP1 ();
+uint8 S9xGetDSP (uint16 Address);
+void S9xSetDSP (uint8 Byte, uint16 Address);
+extern struct SDSP1 DSP1;
+END_EXTERN_C
+
+//extern struct SDSP1 DSP1;
+
+#endif
+
diff --git a/source/dsp1emu.c b/source/dsp1emu.c
new file mode 100644
index 0000000..6b4172a
--- /dev/null
+++ b/source/dsp1emu.c
@@ -0,0 +1,1397 @@
+//Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.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 2 of the License, or (at your option) any later
+//version.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//GNU General Public License for more details.
+//
+//You should have received a copy of the GNU General Public License
+//along with this program; if not, write to the Free Software
+//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+//#define __ZSNES__
+
+#if (defined __ZSNES__ && __LINUX__)
+#include "../gblhdr.h"
+#else
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#endif
+//#define DebugDSP1
+
+// uncomment some lines to test
+//#define printinfo
+//#define debug06
+
+#define __OPT__
+#define __OPT06__
+
+#ifdef DebugDSP1
+
+FILE * LogFile = NULL;
+
+void Log_Message (char *Message, ...)
+{
+ char Msg[400];
+ va_list ap;
+
+ va_start(ap,Message);
+ vsprintf(Msg,Message,ap );
+ va_end(ap);
+
+ strcat(Msg,"\r\n\0");
+ fwrite(Msg,strlen(Msg),1,LogFile);
+ fflush (LogFile);
+}
+
+void Start_Log (void)
+{
+ char LogFileName[255];
+// [4/15/2001] char *p;
+
+ strcpy(LogFileName,"dsp1emu.log\0");
+
+ LogFile = fopen(LogFileName,"wb");
+}
+
+void Stop_Log (void)
+{
+ if (LogFile)
+ {
+ fclose(LogFile);
+ LogFile = NULL;
+ }
+}
+
+#endif
+
+const unsigned short DSP1ROM[1024] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020,
+ 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000,
+ 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200,
+ 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002,
+ 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08,
+ 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba,
+ 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038,
+ 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64,
+ 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523,
+ 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060,
+ 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c,
+ 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816,
+ 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474,
+ 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c,
+ 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05,
+ 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28,
+ 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f,
+ 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604,
+ 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4,
+ 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189,
+ 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1,
+ 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194,
+ 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a,
+ 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0,
+ 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122,
+ 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9,
+ 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324,
+ 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b,
+ 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de,
+ 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4,
+ 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4,
+ 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24,
+ 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c,
+ 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d,
+ 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6,
+ 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3,
+ 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504,
+ 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6,
+ 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842,
+ 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a,
+ 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11,
+ 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2,
+ 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6,
+ 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3,
+ 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504,
+ 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6,
+ 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842,
+ 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a,
+ 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11,
+ 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2,
+ 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc,
+ 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5,
+ 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22,
+ 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c,
+ 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c,
+ 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc,
+ 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894,
+ 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3,
+ 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080,
+ 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86,
+ 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40,
+ 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9,
+ 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2,
+ 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69,
+ 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920,
+ 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4,
+ 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686,
+ 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536,
+ 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3,
+ 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c,
+ 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131,
+ 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2,
+ 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e,
+ 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05,
+ 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94,
+ 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d,
+ 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d,
+ 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714,
+ 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581,
+ 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1,
+ 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232,
+ 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074,
+ 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1,
+ 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8,
+ 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1,
+ 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887,
+ 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e,
+ 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395,
+ 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e,
+ 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a,
+ 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811,
+ 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080,
+ 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488,
+ 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
+
+/***************************************************************************\
+* Math tables *
+\***************************************************************************/
+
+#define INCR 2048
+#define Angle(x) (((x)/(65536/INCR)) & (INCR-1))
+#define Cos(x) ((double) CosTable2[x])
+#define Sin(x) ((double) SinTable2[x])
+#ifdef PI
+#undef PI
+#endif
+#define PI 3.1415926535897932384626433832795
+double CosTable2[INCR];
+double SinTable2[INCR];
+
+
+double Atan(double x)
+{
+ if ((x>=1) || (x<=1))
+ return (x/(1+0.28*x*x));
+ else
+ return (PI/2 - Atan(1/x));
+}
+
+#ifdef __ZSNES__
+/***************************************************************************\
+* C4 C code *
+\***************************************************************************/
+
+short C4WFXVal;
+short C4WFYVal;
+short C4WFZVal;
+short C4WFX2Val;
+short C4WFY2Val;
+short C4WFDist;
+short C4WFScale;
+double tanval;
+double c4x,c4y,c4z;
+double c4x2,c4y2,c4z2;
+
+void C4TransfWireFrame()
+{
+ c4x=(double)C4WFXVal;
+ c4y=(double)C4WFYVal;
+ c4z=(double)C4WFZVal-0x95;
+
+ // Rotate X
+ tanval=-(double)C4WFX2Val*PI*2/128;
+ c4y2=c4y*cos(tanval)-c4z*sin(tanval);
+ c4z2=c4y*sin(tanval)+c4z*cos(tanval);
+
+ // Rotate Y
+ tanval=-(double)C4WFY2Val*PI*2/128;
+ c4x2=c4x*cos(tanval)+c4z2*sin(tanval);
+ c4z=c4x*-sin(tanval)+c4z2*cos(tanval);
+
+ // Rotate Z
+ tanval=-(double)C4WFDist*PI*2/128;
+ c4x=c4x2*cos(tanval)-c4y2*sin(tanval);
+ c4y=c4x2*sin(tanval)+c4y2*cos(tanval);
+
+ // Scale
+ C4WFXVal=(short)(c4x*C4WFScale/(0x90*(c4z+0x95))*0x95);
+ C4WFYVal=(short)(c4y*C4WFScale/(0x90*(c4z+0x95))*0x95);
+}
+
+void C4TransfWireFrame2()
+{
+ c4x=(double)C4WFXVal;
+ c4y=(double)C4WFYVal;
+ c4z=(double)C4WFZVal;
+
+ // Rotate X
+ tanval=-(double)C4WFX2Val*PI*2/128;
+ c4y2=c4y*cos(tanval)-c4z*sin(tanval);
+ c4z2=c4y*sin(tanval)+c4z*cos(tanval);
+
+ // Rotate Y
+ tanval=-(double)C4WFY2Val*PI*2/128;
+ c4x2=c4x*cos(tanval)+c4z2*sin(tanval);
+ c4z=c4x*-sin(tanval)+c4z2*cos(tanval);
+
+ // Rotate Z
+ tanval=-(double)C4WFDist*PI*2/128;
+ c4x=c4x2*cos(tanval)-c4y2*sin(tanval);
+ c4y=c4x2*sin(tanval)+c4y2*cos(tanval);
+
+ // Scale
+ C4WFXVal=(short)(c4x*C4WFScale/0x100);
+ C4WFYVal=(short)(c4y*C4WFScale/0x100);
+}
+
+void C4CalcWireFrame()
+{
+ C4WFXVal=C4WFX2Val-C4WFXVal;
+ C4WFYVal=C4WFY2Val-C4WFYVal;
+ if (abs(C4WFXVal)>abs(C4WFYVal)){
+ C4WFDist=abs(C4WFXVal)+1;
+ C4WFYVal=(256*(long)C4WFYVal)/abs(C4WFXVal);
+ if (C4WFXVal<0) C4WFXVal=-256;
+ else C4WFXVal=256;
+ }
+ else
+ if (C4WFYVal!=0) {
+ C4WFDist=abs(C4WFYVal)+1;
+ C4WFXVal=(256*(long)C4WFXVal)/abs(C4WFYVal);
+ if (C4WFYVal<0) C4WFYVal=-256;
+ else C4WFYVal=256;
+ }
+ else C4WFDist=0;
+}
+
+short C41FXVal;
+short C41FYVal;
+short C41FAngleRes;
+short C41FDist;
+short C41FDistVal;
+
+void C4Op1F()
+{
+ if (C41FXVal == 0) {
+ if (C41FYVal>0) C41FAngleRes=0x80;
+ else C41FAngleRes=0x180;
+ }
+ else {
+ tanval = ((double)C41FYVal)/((double)C41FXVal);
+ C41FAngleRes=(short)(atan(tanval)/(PI*2)*512);
+ C41FAngleRes=C41FAngleRes;
+ if (C41FXVal<0) C41FAngleRes+=0x100;
+ C41FAngleRes&=0x1FF;
+ }
+}
+
+void C4Op15()
+{
+ tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)*
+ ((double)C41FXVal));
+ C41FDist=(short)tanval;
+}
+
+void C4Op0D()
+{
+ tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)*
+ ((double)C41FXVal));
+ tanval=(double)C41FDistVal/tanval;
+ C41FYVal=(short)(((double)C41FYVal*tanval)*0.99);
+ C41FXVal=(short)(((double)C41FXVal*tanval)*0.98);
+}
+#endif
+
+/***************************************************************************\
+* DSP1 code *
+\***************************************************************************/
+
+void InitDSP(void)
+{
+#ifdef __OPT__
+ unsigned int i;
+ for (i=0; i<INCR; i++){
+ CosTable2[i] = (cos((double)(2*PI*i/INCR)));
+ SinTable2[i] = (sin((double)(2*PI*i/INCR)));
+ }
+#endif
+#ifdef DebugDSP1
+ Start_Log();
+#endif
+}
+
+
+short Op00Multiplicand;
+short Op00Multiplier;
+short Op00Result;
+
+void DSPOp00()
+{
+ Op00Result= Op00Multiplicand * Op00Multiplier >> 15;
+
+ #ifdef DebugDSP1
+ Log_Message("OP00 MULT %d*%d/32768=%d",Op00Multiplicand,Op00Multiplier,Op00Result);
+ #endif
+}
+
+short Op20Multiplicand;
+short Op20Multiplier;
+short Op20Result;
+
+void DSPOp20()
+{
+ Op20Result= Op20Multiplicand * Op20Multiplier >> 15;
+ Op20Result++;
+
+ #ifdef DebugDSP1
+ Log_Message("OP20 MULT %d*%d/32768=%d",Op20Multiplicand,Op20Multiplier,Op20Result);
+ #endif
+}
+
+signed short Op10Coefficient;
+signed short Op10Exponent;
+signed short Op10CoefficientR;
+signed short Op10ExponentR;
+
+void DSP1_Inverse(short Coefficient, short Exponent, short *iCoefficient, short *iExponent)
+{
+ // Step One: Division by Zero
+ if (Coefficient == 0x0000)
+ {
+ *iCoefficient = 0x7fff;
+ *iExponent = 0x002f;
+ }
+ else
+ {
+ short Sign = 1;
+
+ // Step Two: Remove Sign
+ if (Coefficient < 0)
+ {
+ if (Coefficient < -32767) Coefficient = -32767;
+ Coefficient = -Coefficient;
+ Sign = -1;
+ }
+
+ // Step Three: Normalize
+ while (Coefficient < 0x4000)
+ {
+ Coefficient <<= 1;
+ Exponent--;
+ }
+
+ // Step Four: Special Case
+ if (Coefficient == 0x4000)
+ if (Sign == 1) *iCoefficient = 0x7fff;
+ else {
+ *iCoefficient = -0x4000;
+ Exponent--;
+ }
+ else {
+ // Step Five: Initial Guess
+ short i = DSP1ROM[((Coefficient - 0x4000) >> 7) + 0x0065];
+
+ // Step Six: Iterate "estimated" Newton's Method
+ i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
+ i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
+
+ *iCoefficient = i * Sign;
+ }
+
+ *iExponent = 1 - Exponent;
+ }
+}
+
+void DSPOp10()
+{
+ DSP1_Inverse(Op10Coefficient, Op10Exponent, &Op10CoefficientR, &Op10ExponentR);
+ #ifdef DebugDSP1
+ Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, Op10CoefficientR, Op10ExponentR);
+ #endif
+}
+
+short Op04Angle;
+short Op04Radius;
+short Op04Sin;
+short Op04Cos;
+
+const short DSP1_MulTable[256] = {
+ 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015,
+ 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f,
+ 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048,
+ 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061,
+ 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a,
+ 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093,
+ 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac,
+ 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5,
+ 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df,
+ 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8,
+ 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111,
+ 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a,
+ 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143,
+ 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c,
+ 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175,
+ 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e,
+ 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8,
+ 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1,
+ 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da,
+ 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3,
+ 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c,
+ 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225,
+ 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e,
+ 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258,
+ 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271,
+ 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a,
+ 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3,
+ 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc,
+ 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5,
+ 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee,
+ 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307,
+ 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321};
+
+const short DSP1_SinTable[256] = {
+ 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2,
+ 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
+ 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a,
+ 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842,
+ 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6,
+ 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504,
+ 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3,
+ 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6,
+ 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d,
+ 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c,
+ 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24,
+ 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4,
+ 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4,
+ 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de,
+ 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b,
+ 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324,
+ -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2,
+ -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
+ -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a,
+ -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
+ -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6,
+ -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504,
+ -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3,
+ -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6,
+ -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d,
+ -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c,
+ -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24,
+ -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4,
+ -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4,
+ -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de,
+ -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b,
+ -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324};
+
+short DSP1_Sin(short Angle)
+{
+ if (Angle < 0) {
+ if (Angle == -32768) return 0;
+ return -DSP1_Sin(-Angle);
+ }
+ int S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15);
+ if (S > 32767) S = 32767;
+ return (short) S;
+}
+
+short DSP1_Cos(short Angle)
+{
+ if (Angle < 0) {
+ if (Angle == -32768) return -32768;
+ Angle = -Angle;
+ }
+ int S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15);
+ if (S < -32768) S = -32767;
+ return (short) S;
+}
+
+void DSP1_Normalize(short m, short *Coefficient, short *Exponent)
+{
+ short i = 0x4000;
+ short e = 0;
+
+ if (m < 0)
+ while ((m & i) && i) {
+ i >>= 1;
+ e++;
+ }
+ else
+ while (!(m & i) && i) {
+ i >>= 1;
+ e++;
+ }
+
+ if (e > 0)
+ *Coefficient = m * DSP1ROM[0x21 + e] << 1;
+ else
+ *Coefficient = m;
+
+ *Exponent -= e;
+}
+
+void DSP1_NormalizeDouble(int Product, short *Coefficient, short *Exponent)
+{
+ short n = Product & 0x7fff;
+ short m = Product >> 15;
+ short i = 0x4000;
+ short e = 0;
+
+ if (m < 0)
+ while ((m & i) && i) {
+ i >>= 1;
+ e++;
+ }
+ else
+ while (!(m & i) && i) {
+ i >>= 1;
+ e++;
+ }
+
+ if (e > 0)
+ {
+ *Coefficient = m * DSP1ROM[0x0021 + e] << 1;
+
+ if (e < 15)
+ *Coefficient += n * DSP1ROM[0x0040 - e] >> 15;
+ else
+ {
+ i = 0x4000;
+
+ if (m < 0)
+ while ((n & i) && i) {
+ i >>= 1;
+ e++;
+ }
+ else
+ while (!(n & i) && i) {
+ i >>= 1;
+ e++;
+ }
+
+ if (e > 15)
+ *Coefficient = n * DSP1ROM[0x0012 + e] << 1;
+ else
+ *Coefficient += n;
+ }
+ }
+ else
+ *Coefficient = m;
+
+ *Exponent = e;
+}
+
+short DSP1_Truncate(short C, short E)
+{
+ if (E > 0) {
+ if (C > 0) return 32767; else if (C < 0) return -32767;
+ } else {
+ if (E < 0) return C * DSP1ROM[0x0031 + E] >> 15;
+ }
+ return C;
+}
+
+void DSPOp04()
+{
+ Op04Sin = DSP1_Sin(Op04Angle) * Op04Radius >> 15;
+ Op04Cos = DSP1_Cos(Op04Angle) * Op04Radius >> 15;
+}
+
+short Op0CA;
+short Op0CX1;
+short Op0CY1;
+short Op0CX2;
+short Op0CY2;
+
+void DSPOp0C()
+{
+ Op0CX2 = (Op0CY1 * DSP1_Sin(Op0CA) >> 15) + (Op0CX1 * DSP1_Cos(Op0CA) >> 15);
+ Op0CY2 = (Op0CY1 * DSP1_Cos(Op0CA) >> 15) - (Op0CX1 * DSP1_Sin(Op0CA) >> 15);
+}
+
+short CentreX;
+short CentreY;
+short VOffset;
+
+short VPlane_C;
+short VPlane_E;
+
+// Azimuth and Zenith angles
+short SinAas;
+short CosAas;
+short SinAzs;
+short CosAzs;
+
+// Clipped Zenith angle
+short SinAZS;
+short CosAZS;
+short SecAZS_C1;
+short SecAZS_E1;
+short SecAZS_C2;
+short SecAZS_E2;
+
+const short MaxAZS_Exp[16] = {
+ 0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca,
+ 0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4
+};
+
+void DSP1_Parameter(short Fx, short Fy, short Fz, short Lfe, short Les, short Aas, short Azs, short *Vof, short *Vva, short *Cx, short *Cy)
+{
+ short CSec, C, E;
+
+ // Copy Zenith angle for clipping
+ short AZS = Azs;
+
+ // Store Sin and Cos of Azimuth and Zenith angles
+ SinAas = DSP1_Sin(Aas);
+ CosAas = DSP1_Cos(Aas);
+ SinAzs = DSP1_Sin(Azs);
+ CosAzs = DSP1_Cos(Azs);
+
+ // Center of Projection
+ CentreX = Fx + (Lfe * (SinAzs * -SinAas >> 15) >> 15);
+ CentreY = Fy + (Lfe * (SinAzs * CosAas >> 15) >> 15);
+
+ E = 0;
+ DSP1_Normalize(Fz + (Lfe * (CosAzs * 0x7fff >> 15) >> 15), &C, &E);
+
+ VPlane_C = C;
+ VPlane_E = E;
+
+ // Determine clip boundary and clip Zenith angle if necessary
+ short MaxAZS = MaxAZS_Exp[-E];
+
+ if (AZS < 0) {
+ MaxAZS = -MaxAZS;
+ if (AZS < MaxAZS + 1) AZS = MaxAZS + 1;
+ } else {
+ if (AZS > MaxAZS) AZS = MaxAZS;
+ }
+
+ // Store Sin and Cos of clipped Zenith angle
+ SinAZS = DSP1_Sin(AZS);
+ CosAZS = DSP1_Cos(AZS);
+
+ DSP1_Inverse(CosAZS, 0, &SecAZS_C1, &SecAZS_E1);
+ DSP1_Normalize(C * SecAZS_C1 >> 15, &C, &E);
+ E += SecAZS_E1;
+
+ C = DSP1_Truncate(C, E) * SinAZS >> 15;
+
+ CentreX += C * SinAas >> 15;
+ CentreY -= C * CosAas >> 15;
+
+ *Cx = CentreX;
+ *Cy = CentreY;
+
+ // Raster number of imaginary center and horizontal line
+ *Vof = 0;
+
+ if ((Azs != AZS) || (Azs == MaxAZS))
+ {
+ if (Azs == -32768) Azs = -32767;
+
+ C = Azs - MaxAZS;
+ if (C >= 0) C--;
+ short Aux = ~(C << 2);
+
+ C = Aux * DSP1ROM[0x0328] >> 15;
+ C = (C * Aux >> 15) + DSP1ROM[0x0327];
+ *Vof -= (C * Aux >> 15) * Les >> 15;
+
+ C = Aux * Aux >> 15;
+ Aux = (C * DSP1ROM[0x0324] >> 15) + DSP1ROM[0x0325];
+ CosAZS += (C * Aux >> 15) * CosAZS >> 15;
+ }
+
+ VOffset = Les * CosAZS >> 15;
+
+ DSP1_Inverse(SinAZS, 0, &CSec, &E);
+ DSP1_Normalize(VOffset, &C, &E);
+ DSP1_Normalize(C * CSec >> 15, &C, &E);
+
+ if (C == -32768) { C >>= 1; E++; }
+
+ *Vva = DSP1_Truncate(-C, E);
+
+ // Store Sec of clipped Zenith angle
+ DSP1_Inverse(CosAZS, 0, &SecAZS_C2, &SecAZS_E2);
+}
+
+void DSP1_Raster(short Vs, short *An, short *Bn, short *Cn, short *Dn)
+{
+ short C, E, C1, E1;
+
+ DSP1_Inverse((Vs * SinAzs >> 15) + VOffset, 7, &C, &E);
+ E += VPlane_E;
+
+ C1 = C * VPlane_C >> 15;
+ E1 = E + SecAZS_E2;
+
+ DSP1_Normalize(C1, &C, &E);
+
+ C = DSP1_Truncate(C, E);
+
+ *An = C * CosAas >> 15;
+ *Cn = C * SinAas >> 15;
+
+ DSP1_Normalize(C1 * SecAZS_C2 >> 15, &C, &E1);
+
+ C = DSP1_Truncate(C, E1);
+
+ *Bn = C * -SinAas >> 15;
+ *Dn = C * CosAas >> 15;
+}
+
+short Op02FX;
+short Op02FY;
+short Op02FZ;
+short Op02LFE;
+short Op02LES;
+short Op02AAS;
+short Op02AZS;
+short Op02VOF;
+short Op02VVA;
+short Op02CX;
+short Op02CY;
+
+void DSPOp02()
+{
+ DSP1_Parameter(Op02FX, Op02FY, Op02FZ, Op02LFE, Op02LES, Op02AAS, Op02AZS, &Op02VOF, &Op02VVA, &Op02CX, &Op02CY);
+}
+
+short Op0AVS;
+short Op0AA;
+short Op0AB;
+short Op0AC;
+short Op0AD;
+
+void DSPOp0A()
+{
+ DSP1_Raster(Op0AVS, &Op0AA, &Op0AB, &Op0AC, &Op0AD);
+ Op0AVS++;
+}
+
+short Op06X;
+short Op06Y;
+short Op06Z;
+short Op06H;
+short Op06V;
+unsigned short Op06S;
+
+double ObjPX;
+double ObjPY;
+double ObjPZ;
+double ObjPX1;
+double ObjPY1;
+double ObjPZ1;
+double ObjPX2;
+double ObjPY2;
+double ObjPZ2;
+double DivideOp06;
+int Temp;
+int tanval2;
+
+#ifdef __OPT06__
+void DSPOp06()
+{
+ ObjPX=Op06X-Op02FX;
+ ObjPY=Op06Y-Op02FY;
+ ObjPZ=Op06Z-Op02FZ;
+
+ // rotate around Z
+ tanval2 = Angle(-Op02AAS+32768);
+// tanval2 = (-Op02AAS+32768)/(65536/INCR);
+ ObjPX1=(ObjPX*Cos(tanval2)+ObjPY*-Sin(tanval2));
+ ObjPY1=(ObjPX*Sin(tanval2)+ObjPY*Cos(tanval2));
+ ObjPZ1=ObjPZ;
+
+ // rotate around X
+// tanval2 = (-Op02AZS/(65536/INCR)) & 1023;
+ tanval2 = Angle(-Op02AZS);
+// tanval2 = (-Op02AZS)/256;
+ ObjPX2=ObjPX1;
+ ObjPY2=(ObjPY1*Cos(tanval2)+ObjPZ1*-Sin(tanval2));
+ ObjPZ2=(ObjPY1*Sin(tanval2)+ObjPZ1*Cos(tanval2));
+
+ #ifdef debug06
+ Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2);
+ #endif
+
+ ObjPZ2=ObjPZ2-Op02LFE;
+
+ if (ObjPZ2<0)
+ {
+ double d;
+ Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2;
+ Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2;
+ d=(double)Op02LES;
+ d*=256.0;
+ d/=(-ObjPZ2);
+ if(d>65535.0)
+ d=65535.0;
+ else if(d<0.0)
+ d=0.0;
+ Op06S=(unsigned short)d;
+ //Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2);
+ //Op06S=(unsigned short)((double)(256.0*((double)Op02LES)/(-ObjPZ2)));
+ }
+ else
+ {
+ Op06H=0;
+ Op06V=14*16;
+ Op06S=0xFFFF;
+ }
+
+
+ #ifdef DebugDSP1
+ Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z);
+ Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S);
+ #endif
+}
+#else
+
+void DSPOp06()
+{
+ ObjPX=Op06X-Op02FX;
+ ObjPY=Op06Y-Op02FY;
+ ObjPZ=Op06Z-Op02FZ;
+
+ // rotate around Z
+ tanval = (-Op02AAS+32768)/65536.0*6.2832;
+ ObjPX1=(ObjPX*cos(tanval)+ObjPY*-sin(tanval));
+ ObjPY1=(ObjPX*sin(tanval)+ObjPY*cos(tanval));
+ ObjPZ1=ObjPZ;
+
+ #ifdef debug06
+ Log_Message("Angle : %f", tanval);
+ Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n",ObjPX1,ObjPY1,ObjPZ1);
+ Log_Message("cos(tanval) : %f sin(tanval) : %f", cos(tanval), sin(tanval));
+ #endif
+
+ // rotate around X
+ tanval = (-Op02AZS)/65536.0*6.2832;
+ ObjPX2=ObjPX1;
+ ObjPY2=(ObjPY1*cos(tanval)+ObjPZ1*-sin(tanval));
+ ObjPZ2=(ObjPY1*sin(tanval)+ObjPZ1*cos(tanval));
+
+ #ifdef debug06
+ Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2);
+ #endif
+
+ ObjPZ2=ObjPZ2-Op02LFE;
+
+ if (ObjPZ2<0)
+ {
+ Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2;
+ Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2;
+ double d=(double)Op02LES;
+ d*=256.0;
+ d/=(-ObjPZ2);
+ if(d>65535.0)
+ d=65535.0;
+ else if(d<0.0)
+ d=0.0;
+ Op06S=(unsigned short)d;
+// Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2);
+ }
+ else
+ {
+ Op06H=0;
+ Op06V=14*16;
+ Op06S=0xFFFF;
+ }
+
+ #ifdef DebugDSP1
+ Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z);
+ Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S);
+ #endif
+}
+#endif
+
+
+short matrixC[3][3];
+short matrixB[3][3];
+short matrixA[3][3];
+
+short Op01m;
+short Op01Zr;
+short Op01Xr;
+short Op01Yr;
+short Op11m;
+short Op11Zr;
+short Op11Xr;
+short Op11Yr;
+short Op21m;
+short Op21Zr;
+short Op21Xr;
+short Op21Yr;
+
+void DSPOp01()
+{
+ short SinAz = DSP1_Sin(Op01Zr);
+ short CosAz = DSP1_Cos(Op01Zr);
+ short SinAy = DSP1_Sin(Op01Yr);
+ short CosAy = DSP1_Cos(Op01Yr);
+ short SinAx = DSP1_Sin(Op01Xr);
+ short CosAx = DSP1_Cos(Op01Xr);
+
+ Op01m >>= 1;
+
+ matrixA[0][0] = (Op01m * CosAz >> 15) * CosAy >> 15;
+ matrixA[0][1] = -((Op01m * SinAz >> 15) * CosAy >> 15);
+ matrixA[0][2] = Op01m * SinAy >> 15;
+
+ matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + (((Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
+ matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - (((Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
+ matrixA[1][2] = -((Op01m * SinAx >> 15) * CosAy >> 15);
+
+ matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - (((Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
+ matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + (((Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
+ matrixA[2][2] = (Op01m * CosAx >> 15) * CosAy >> 15;
+}
+
+void DSPOp11()
+{
+ short SinAz = DSP1_Sin(Op11Zr);
+ short CosAz = DSP1_Cos(Op11Zr);
+ short SinAy = DSP1_Sin(Op11Yr);
+ short CosAy = DSP1_Cos(Op11Yr);
+ short SinAx = DSP1_Sin(Op11Xr);
+ short CosAx = DSP1_Cos(Op11Xr);
+
+ Op11m >>= 1;
+
+ matrixB[0][0] = (Op11m * CosAz >> 15) * CosAy >> 15;
+ matrixB[0][1] = -((Op11m * SinAz >> 15) * CosAy >> 15);
+ matrixB[0][2] = Op11m * SinAy >> 15;
+
+ matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + (((Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
+ matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - (((Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
+ matrixB[1][2] = -((Op11m * SinAx >> 15) * CosAy >> 15);
+
+ matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - (((Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
+ matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + (((Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
+ matrixB[2][2] = (Op11m * CosAx >> 15) * CosAy >> 15;
+}
+
+void DSPOp21()
+{
+ short SinAz = DSP1_Sin(Op21Zr);
+ short CosAz = DSP1_Cos(Op21Zr);
+ short SinAy = DSP1_Sin(Op21Yr);
+ short CosAy = DSP1_Cos(Op21Yr);
+ short SinAx = DSP1_Sin(Op21Xr);
+ short CosAx = DSP1_Cos(Op21Xr);
+
+ Op21m >>= 1;
+
+ matrixC[0][0] = (Op21m * CosAz >> 15) * CosAy >> 15;
+ matrixC[0][1] = -((Op21m * SinAz >> 15) * CosAy >> 15);
+ matrixC[0][2] = Op21m * SinAy >> 15;
+
+ matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + (((Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
+ matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - (((Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
+ matrixC[1][2] = -((Op21m * SinAx >> 15) * CosAy >> 15);
+
+ matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - (((Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
+ matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + (((Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
+ matrixC[2][2] = (Op21m * CosAx >> 15) * CosAy >> 15;
+}
+
+short Op0DX;
+short Op0DY;
+short Op0DZ;
+short Op0DF;
+short Op0DL;
+short Op0DU;
+short Op1DX;
+short Op1DY;
+short Op1DZ;
+short Op1DF;
+short Op1DL;
+short Op1DU;
+short Op2DX;
+short Op2DY;
+short Op2DZ;
+short Op2DF;
+short Op2DL;
+short Op2DU;
+
+void DSPOp0D()
+{
+ Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + (Op0DZ * matrixA[0][2] >> 15);
+ Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + (Op0DZ * matrixA[1][2] >> 15);
+ Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + (Op0DZ * matrixA[2][2] >> 15);
+
+ #ifdef DebugDSP1
+ Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op0DX,Op0DY,Op0DZ,Op0DF,Op0DL,Op0DU);
+ #endif
+}
+
+void DSPOp1D()
+{
+ Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + (Op1DZ * matrixB[0][2] >> 15);
+ Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + (Op1DZ * matrixB[1][2] >> 15);
+ Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + (Op1DZ * matrixB[2][2] >> 15);
+
+ #ifdef DebugDSP1
+ Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op1DX,Op1DY,Op1DZ,Op1DF,Op1DL,Op1DU);
+ #endif
+}
+
+void DSPOp2D()
+{
+ Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + (Op2DZ * matrixC[0][2] >> 15);
+ Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + (Op2DZ * matrixC[1][2] >> 15);
+ Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + (Op2DZ * matrixC[2][2] >> 15);
+
+ #ifdef DebugDSP1
+ Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op2DX,Op2DY,Op2DZ,Op2DF,Op2DL,Op2DU);
+ #endif
+}
+
+short Op03F;
+short Op03L;
+short Op03U;
+short Op03X;
+short Op03Y;
+short Op03Z;
+short Op13F;
+short Op13L;
+short Op13U;
+short Op13X;
+short Op13Y;
+short Op13Z;
+short Op23F;
+short Op23L;
+short Op23U;
+short Op23X;
+short Op23Y;
+short Op23Z;
+
+void DSPOp03()
+{
+ Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + (Op03U * matrixA[2][0] >> 15);
+ Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + (Op03U * matrixA[2][1] >> 15);
+ Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + (Op03U * matrixA[2][2] >> 15);
+
+ #ifdef DebugDSP1
+ Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op03F,Op03L,Op03U,Op03X,Op03Y,Op03Z);
+ #endif
+}
+
+void DSPOp13()
+{
+ Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + (Op13U * matrixB[2][0] >> 15);
+ Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + (Op13U * matrixB[2][1] >> 15);
+ Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + (Op13U * matrixB[2][2] >> 15);
+
+ #ifdef DebugDSP1
+ Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op13F,Op13L,Op13U,Op13X,Op13Y,Op13Z);
+ #endif
+}
+
+void DSPOp23()
+{
+ Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + (Op23U * matrixC[2][0] >> 15);
+ Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + (Op23U * matrixC[2][1] >> 15);
+ Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + (Op23U * matrixC[2][2] >> 15);
+
+ #ifdef DebugDSP1
+ Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op23F,Op23L,Op23U,Op23X,Op23Y,Op23Z);
+ #endif
+}
+
+short Op14Zr;
+short Op14Xr;
+short Op14Yr;
+short Op14U;
+short Op14F;
+short Op14L;
+short Op14Zrr;
+short Op14Xrr;
+short Op14Yrr;
+
+void DSPOp14()
+{
+ short CSec, ESec, CTan, CSin, C, E;
+
+ DSP1_Inverse(DSP1_Cos(Op14Xr), 0, &CSec, &ESec);
+
+ // Rotation Around Z
+ DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, &E);
+
+ E = ESec - E;
+
+ DSP1_Normalize(C * CSec >> 15, &C, &E);
+
+ Op14Zrr = Op14Zr + DSP1_Truncate(C, E);
+
+ // Rotation Around X
+ Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos(Op14Yr) >> 15);
+
+ // Rotation Around Y
+ DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, &E);
+
+ E = ESec - E;
+
+ DSP1_Normalize(DSP1_Sin(Op14Xr), &CSin, &E);
+
+ CTan = CSec * CSin >> 15;
+
+ DSP1_Normalize(-(C * CTan >> 15), &C, &E);
+
+ Op14Yrr = Op14Yr + DSP1_Truncate(C, E) + Op14L;
+}
+
+void DSP1_Target(short H, short V, short *X, short *Y)
+{
+ short C, E, C1, E1;
+
+ DSP1_Inverse((V * SinAzs >> 15) + VOffset, 8, &C, &E);
+ E += VPlane_E;
+
+ C1 = C * VPlane_C >> 15;
+ E1 = E + SecAZS_E1;
+
+ H <<= 8;
+
+ DSP1_Normalize(C1, &C, &E);
+
+ C = DSP1_Truncate(C, E) * H >> 15;
+
+ *X = CentreX + (C * CosAas >> 15);
+ *Y = CentreY - (C * SinAas >> 15);
+
+ V <<= 8;
+
+ DSP1_Normalize(C1 * SecAZS_C1 >> 15, &C, &E1);
+
+ C = DSP1_Truncate(C, E1) * V >> 15;
+
+ *X += C * -SinAas >> 15;
+ *Y += C * CosAas >> 15;
+}
+
+short Op0EH;
+short Op0EV;
+short Op0EX;
+short Op0EY;
+
+void DSPOp0E()
+{
+ DSP1_Target(Op0EH, Op0EV, &Op0EX, &Op0EY);
+}
+
+short Op0BX;
+short Op0BY;
+short Op0BZ;
+short Op0BS;
+short Op1BX;
+short Op1BY;
+short Op1BZ;
+short Op1BS;
+short Op2BX;
+short Op2BY;
+short Op2BZ;
+short Op2BS;
+
+void DSPOp0B()
+{
+ Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) >> 15;
+
+ #ifdef DebugDSP1
+ Log_Message("OP0B");
+ #endif
+}
+
+void DSPOp1B()
+{
+ Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) >> 15;
+
+ #ifdef DebugDSP1
+ Log_Message("OP1B X: %d Y: %d Z: %d S: %d",Op1BX,Op1BY,Op1BZ,Op1BS);
+ Log_Message(" MX: %d MY: %d MZ: %d Scale: %d",(short)(matrixB[0][0]*100),(short)(matrixB[0][1]*100),(short)(matrixB[0][2]*100),(short)(sc2*100));
+ #endif
+}
+
+void DSPOp2B()
+{
+ Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) >> 15;
+
+ #ifdef DebugDSP1
+ Log_Message("OP2B");
+ #endif
+}
+
+short Op08X,Op08Y,Op08Z,Op08Ll,Op08Lh;
+
+void DSPOp08()
+{
+ int Op08Size = (Op08X * Op08X + Op08Y * Op08Y + Op08Z * Op08Z) << 1;
+ Op08Ll = Op08Size & 0xffff;
+ Op08Lh = (Op08Size >> 16) & 0xffff;
+
+ #ifdef DebugDSP1
+ Log_Message("OP08 %d,%d,%d",Op08X,Op08Y,Op08Z);
+ Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x",Op08Size );
+ #endif
+}
+
+short Op18X,Op18Y,Op18Z,Op18R,Op18D;
+
+void DSPOp18()
+{
+ Op18D = (Op18X * Op18X + Op18Y * Op18Y + Op18Z * Op18Z - Op18R * Op18R) >> 15;
+
+ #ifdef DebugDSP1
+ Log_Message("Op18 X: %d Y: %d Z: %d R: %D DIFF %d",Op18X,Op18Y,Op38Z,Op18D);
+ #endif
+}
+
+short Op38X,Op38Y,Op38Z,Op38R,Op38D;
+
+void DSPOp38()
+{
+ Op38D = (Op38X * Op38X + Op38Y * Op38Y + Op38Z * Op38Z - Op38R * Op38R) >> 15;
+ Op38D++;
+
+ #ifdef DebugDSP1
+ Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d",Op38X,Op38Y,Op38Z,Op38D);
+ #endif
+}
+
+short Op28X;
+short Op28Y;
+short Op28Z;
+short Op28R;
+
+void DSPOp28()
+{
+ int Radius = Op28X * Op28X + Op28Y * Op28Y + Op28Z * Op28Z;
+
+ if (Radius == 0) Op28R = 0;
+ else
+ {
+ short C, E;
+ DSP1_NormalizeDouble(Radius, &C, &E);
+ if (E & 1) C = C * 0x4000 >> 15;
+
+ short Pos = C * 0x0040 >> 15;
+
+ short Node1 = DSP1ROM[0x00d5 + Pos];
+ short Node2 = DSP1ROM[0x00d6 + Pos];
+
+ Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1;
+ Op28R >>= (E >> 1);
+ }
+
+ #ifdef DebugDSP1
+ Log_Message("OP28 X:%d Y:%d Z:%d",Op28X,Op28Y,Op28Z);
+ Log_Message("OP28 Vector Length %d",Op28R);
+ #endif
+}
+
+short Op1CX,Op1CY,Op1CZ;
+short Op1CXBR,Op1CYBR,Op1CZBR,Op1CXAR,Op1CYAR,Op1CZAR;
+short Op1CX1;
+short Op1CY1;
+short Op1CZ1;
+short Op1CX2;
+short Op1CY2;
+short Op1CZ2;
+
+void DSPOp1C()
+{
+ // Rotate Around Op1CZ1
+ Op1CX1 = (Op1CYBR * DSP1_Sin(Op1CZ) >> 15) + (Op1CXBR * DSP1_Cos(Op1CZ) >> 15);
+ Op1CY1 = (Op1CYBR * DSP1_Cos(Op1CZ) >> 15) - (Op1CXBR * DSP1_Sin(Op1CZ) >> 15);
+ Op1CXBR = Op1CX1; Op1CYBR = Op1CY1;
+
+ // Rotate Around Op1CY1
+ Op1CZ1 = (Op1CXBR * DSP1_Sin(Op1CY) >> 15) + (Op1CZBR * DSP1_Cos(Op1CY) >> 15);
+ Op1CX1 = (Op1CXBR * DSP1_Cos(Op1CY) >> 15) - (Op1CZBR * DSP1_Sin(Op1CY) >> 15);
+ Op1CXAR = Op1CX1; Op1CZBR = Op1CZ1;
+
+ // Rotate Around Op1CX1
+ Op1CY1 = (Op1CZBR * DSP1_Sin(Op1CX) >> 15) + (Op1CYBR * DSP1_Cos(Op1CX) >> 15);
+ Op1CZ1 = (Op1CZBR * DSP1_Cos(Op1CX) >> 15) - (Op1CYBR * DSP1_Sin(Op1CX) >> 15);
+ Op1CYAR = Op1CY1; Op1CZAR = Op1CZ1;
+
+ #ifdef DebugDSP1
+ Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR);
+ #endif
+}
+
+unsigned short Op0FRamsize;
+unsigned short Op0FPass;
+
+void DSPOp0F()
+{
+ Op0FPass = 0x0000;
+
+ #ifdef DebugDSP1
+ Log_Message("OP0F RAM Test Pass:%d", Op0FPass);
+ #endif
+}
+
+short Op2FUnknown;
+short Op2FSize;
+
+void DSPOp2F()
+{
+ Op2FSize=0x100;
+}
diff --git a/source/dsp2emu.c b/source/dsp2emu.c
new file mode 100644
index 0000000..7b74c3b
--- /dev/null
+++ b/source/dsp2emu.c
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+
+uint16 DSP2Op09Word1=0;
+uint16 DSP2Op09Word2=0;
+bool DSP2Op05HasLen=false;
+int DSP2Op05Len=0;
+bool DSP2Op06HasLen=false;
+int DSP2Op06Len=0;
+uint8 DSP2Op05Transparent=0;
+
+void DSP2_Op05 ()
+{
+ uint8 color;
+ // Overlay bitmap with transparency.
+ // Input:
+ //
+ // Bitmap 1: i[0] <=> i[size-1]
+ // Bitmap 2: i[size] <=> i[2*size-1]
+ //
+ // Output:
+ //
+ // Bitmap 3: o[0] <=> o[size-1]
+ //
+ // Processing:
+ //
+ // Process all 4-bit pixels (nibbles) in the bitmap
+ //
+ // if ( BM2_pixel == transparent_color )
+ // pixelout = BM1_pixel
+ // else
+ // pixelout = BM2_pixel
+
+ // The max size bitmap is limited to 255 because the size parameter is a byte
+ // I think size=0 is an error. The behavior of the chip on size=0 is to
+ // return the last value written to DR if you read DR on Op05 with
+ // size = 0. I don't think it's worth implementing this quirk unless it's
+ // proven necessary.
+
+ int n;
+ unsigned char c1;
+ unsigned char c2;
+ unsigned char *p1 = DSP1.parameters;
+ unsigned char *p2 = &DSP1.parameters[DSP2Op05Len];
+ unsigned char *p3 = DSP1.output;
+
+ color = DSP2Op05Transparent&0x0f;
+
+ for( n = 0; n < DSP2Op05Len; n++ )
+ {
+ c1 = *p1++;
+ c2 = *p2++;
+ *p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0: c2 & 0xf0 ) |
+ ( ((c2 & 0x0f)==color) ? c1 & 0x0f: c2 & 0x0f );
+ }
+}
+
+void DSP2_Op01 ()
+{
+ // Op01 size is always 32 bytes input and output.
+ // The hardware does strange things if you vary the size.
+
+ int j;
+ unsigned char c0, c1, c2, c3;
+ unsigned char *p1 = DSP1.parameters;
+ unsigned char *p2a = DSP1.output;
+ unsigned char *p2b = &DSP1.output[16]; // halfway
+
+ // Process 8 blocks of 4 bytes each
+
+ for ( j = 0; j < 8; j++ )
+ {
+ c0 = *p1++;
+ c1 = *p1++;
+ c2 = *p1++;
+ c3 = *p1++;
+
+ *p2a++ = (c0 & 0x10) << 3 |
+ (c0 & 0x01) << 6 |
+ (c1 & 0x10) << 1 |
+ (c1 & 0x01) << 4 |
+ (c2 & 0x10) >> 1 |
+ (c2 & 0x01) << 2 |
+ (c3 & 0x10) >> 3 |
+ (c3 & 0x01);
+
+ *p2a++ = (c0 & 0x20) << 2 |
+ (c0 & 0x02) << 5 |
+ (c1 & 0x20) |
+ (c1 & 0x02) << 3 |
+ (c2 & 0x20) >> 2 |
+ (c2 & 0x02) << 1 |
+ (c3 & 0x20) >> 4 |
+ (c3 & 0x02) >> 1;
+
+ *p2b++ = (c0 & 0x40) << 1 |
+ (c0 & 0x04) << 4 |
+ (c1 & 0x40) >> 1 |
+ (c1 & 0x04) << 2 |
+ (c2 & 0x40) >> 3 |
+ (c2 & 0x04) |
+ (c3 & 0x40) >> 5 |
+ (c3 & 0x04) >> 2;
+
+
+ *p2b++ = (c0 & 0x80) |
+ (c0 & 0x08) << 3 |
+ (c1 & 0x80) >> 2 |
+ (c1 & 0x08) << 1 |
+ (c2 & 0x80) >> 4 |
+ (c2 & 0x08) >> 1 |
+ (c3 & 0x80) >> 6 |
+ (c3 & 0x08) >> 3;
+ }
+ return;
+}
+
+void DSP2_Op06 ()
+{
+ // Input:
+ // size
+ // bitmap
+
+ int i, j;
+
+ for ( i = 0, j = DSP2Op06Len - 1; i < DSP2Op06Len; i++, j-- )
+ {
+ DSP1.output[j] = (DSP1.parameters[i] << 4) | (DSP1.parameters[i] >> 4);
+ }
+}
+
+bool DSP2Op0DHasLen=false;
+int DSP2Op0DOutLen=0;
+int DSP2Op0DInLen=0;
+
+#ifndef DSP2_BIT_ACCURRATE_CODE
+
+// Scale bitmap based on input length out output length
+
+void DSP2_Op0D()
+{
+ // Overload's algorithm - use this unless doing hardware testing
+
+ // One note: the HW can do odd byte scaling but since we divide
+ // by two to get the count of bytes this won't work well for
+ // odd byte scaling (in any of the current algorithm implementations).
+ // So far I haven't seen Dungeon Master use it.
+ // If it does we can adjust the parameters and code to work with it
+
+ int i;
+ int pixel_offset;
+ uint8 pixelarray[512];
+
+ for(i=0; i<DSP2Op0DOutLen*2; i++)
+ {
+ pixel_offset = (i * DSP2Op0DInLen) / DSP2Op0DOutLen;
+ if ( (pixel_offset&1) == 0 )
+ pixelarray[i] = DSP1.parameters[pixel_offset>>1] >> 4;
+ else
+ pixelarray[i] = DSP1.parameters[pixel_offset>>1] & 0x0f;
+ }
+
+ for ( i=0; i < DSP2Op0DOutLen; i++ )
+ DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1];
+}
+
+#else
+
+void DSP2_Op0D()
+{
+ // Bit accurate hardware algorithm - uses fixed point math
+ // This should match the DSP2 Op0D output exactly
+ // I wouldn't recommend using this unless you're doing hardware debug.
+ // In some situations it has small visual artifacts that
+ // are not readily apparent on a TV screen but show up clearly
+ // on a monitor. Use Overload's scaling instead.
+ // This is for hardware verification testing.
+ //
+ // One note: the HW can do odd byte scaling but since we divide
+ // by two to get the count of bytes this won't work well for
+ // odd byte scaling (in any of the current algorithm implementations).
+ // So far I haven't seen Dungeon Master use it.
+ // If it does we can adjust the parameters and code to work with it
+
+
+ uint32 multiplier; // Any size int >= 32-bits
+ uint32 pixloc; // match size of multiplier
+ int i, j;
+ uint8 pixelarray[512];
+
+ if (DSP2Op0DInLen <= DSP2Op0DOutLen)
+ multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
+ else
+ multiplier = (DSP2Op0DInLen << 17) / ((DSP2Op0DOutLen<<1) + 1);
+
+ pixloc = 0;
+ for ( i=0; i < DSP2Op0DOutLen * 2; i++ )
+ {
+ j = pixloc >> 16;
+
+ if ( j & 1 )
+ pixelarray[i] = DSP1.parameters[j>>1] & 0x0f;
+ else
+ pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4;
+
+ pixloc += multiplier;
+ }
+
+ for ( i=0; i < DSP2Op0DOutLen; i++ )
+ DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1];
+}
+
+#endif
+
+#if 0 // Probably no reason to use this code - it's not quite bit accurate and it doesn't look as good as Overload's algorithm
+
+void DSP2_Op0D()
+{
+ // Float implementation of Neviksti's algorithm
+ // This is the right algorithm to match the DSP2 bits but the precision
+ // of the PC float does not match the precision of the fixed point math
+ // on the DSP2 causing occasional one off data mismatches (which should
+ // be no problem because its just a one pixel difference in a scaled image
+ // to be displayed).
+
+ float multiplier;
+ float pixloc;
+ int i, j;
+ uint8 pixelarray[512];
+
+ if (DSP2Op0DInLen <= DSP2Op0DOutLen)
+ multiplier = (float) 1.0;
+ else
+ multiplier = (float) ((DSP2Op0DInLen * 2.0) / (DSP2Op0DOutLen * 2.0 + 1.0));
+
+ pixloc = 0.0;
+ for ( i=0; i < DSP2Op0DOutLen * 2; i++ )
+ {
+ // j = (int)(i * multiplier);
+ j = (int) pixloc;
+
+ if ( j & 1 )
+ pixelarray[i] = DSP1.parameters[j>>1] & 0x0f;
+ else
+ pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4;
+
+ pixloc += multiplier; // use an add in the loop instead of multiply to increase loop speed
+ }
+
+ for ( i=0; i < DSP2Op0DOutLen; i++ )
+ DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1];
+}
+
+#endif
+
diff --git a/source/dsp4.h b/source/dsp4.h
new file mode 100644
index 0000000..2e7e711
--- /dev/null
+++ b/source/dsp4.h
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _DSP4_H_
+#define _DSP4_H_
+
+// debug
+int block; // current block number
+extern int c;
+
+// op control
+int8 DSP4_Logic; // controls op flow
+
+// projection format
+const int16 PLANE_START = 0x7fff; // starting distance
+
+int16 view_plane; // viewer location
+int16 far_plane; // next milestone into screen
+int16 segments; // # raster segments to draw
+int16 raster; // current raster line
+
+int16 project_x; // current x-position
+int16 project_y; // current y-position
+
+int16 project_centerx; // x-target of projection
+int16 project_centery; // y-target of projection
+
+int16 project_x1; // current x-distance
+int16 project_x1low; // lower 16-bits
+int16 project_y1; // current y-distance
+int16 project_y1low; // lower 16-bits
+
+int16 project_x2; // next projected x-distance
+int16 project_y2; // next projected y-distance
+
+int16 project_pitchx; // delta center
+int16 project_pitchxlow; // lower 16-bits
+int16 project_pitchy; // delta center
+int16 project_pitchylow; // lower 16-bits
+
+int16 project_focalx; // x-point of projection at viewer plane
+int16 project_focaly; // y-point of projection at viewer plane
+
+int16 project_ptr; // data structure pointer
+
+// render window
+int16 center_x; // x-center of viewport
+int16 center_y; // y-center of viewport
+int16 viewport_left; // x-left of viewport
+int16 viewport_right; // x-right of viewport
+int16 viewport_top; // y-top of viewport
+int16 viewport_bottom; // y-bottom of viewport
+
+// sprite structure
+int16 sprite_x; // projected x-pos of sprite
+int16 sprite_y; // projected y-pos of sprite
+int16 sprite_offset; // data pointer offset
+int8 sprite_type; // vehicle, terrain
+bool8 sprite_size; // sprite size: 8x8 or 16x16
+
+// path strips
+int16 path_clipRight[4]; // value to clip to for x>b
+int16 path_clipLeft[4]; // value to clip to for x<a
+int16 path_pos[4]; // x-positions of lanes
+int16 path_ptr[4]; // data structure pointers
+int16 path_raster[4]; // current raster
+int16 path_top[4]; // viewport_top
+
+int16 path_y[2]; // current y-position
+int16 path_x[2]; // current focals
+int16 path_plane[2]; // previous plane
+
+// op09 window sorting
+int16 multi_index1; // index counter
+int16 multi_index2; // index counter
+bool8 op09_mode; // window mode
+
+// multi-op storage
+int16 multi_focaly[64]; // focal_y values
+int16 multi_farplane[4]; // farthest drawn distance
+int16 multi_raster[4]; // line where track stops
+
+// OAM
+int8 op06_OAM[32]; // OAM (size,MSB) data
+int8 op06_index; // index into OAM table
+int8 op06_offset; // offset into OAM table
+
+#endif
diff --git a/source/dsp4emu.cpp b/source/dsp4emu.cpp
new file mode 100644
index 0000000..115b9e4
--- /dev/null
+++ b/source/dsp4emu.cpp
@@ -0,0 +1,1488 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "dsp4.h"
+
+#define DSP4_READ_WORD(x) \
+ READ_WORD(DSP4.parameters+x)
+
+#define DSP4_WRITE_WORD(x,d) \
+ WRITE_WORD(DSP4.output+x,d);
+
+// used to wait for dsp i/o
+#define DSP4_WAIT(x) \
+ DSP4_Logic = x; return;
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void DSP4_Multiply(short Multiplicand, short Multiplier, int &Product)
+{
+ Product = Multiplicand * Multiplier;
+}
+
+void DSP4_UnknownOP11(short A, short B, short C, short D, short &M)
+{
+ M = ((A * 0x0155 >> 2) & 0xf000) | ((B * 0x0155 >> 6) & 0x0f00) |
+ ((C * 0x0155 >> 10) & 0x00f0) | ((D * 0x0155 >> 14) & 0x000f);
+}
+
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+
+void DSP4_Op06(bool8 size, bool8 msb)
+{
+ // save post-oam table data for future retrieval
+ op06_OAM[op06_index] |= (msb<<(op06_offset+0));
+ op06_OAM[op06_index] |= (size<<(op06_offset+1));
+ op06_offset += 2;
+
+ if(op06_offset==8)
+ {
+ // move to next byte in buffer
+ op06_offset=0;
+ op06_index++;
+ }
+}
+
+#if OP==0x0001
+#define PRINT
+#endif
+
+void DSP4_Op01()
+{
+ uint16 command;
+
+ DSP4.waiting4command = FALSE;
+
+ // op flow control
+ switch(DSP4_Logic) {
+ case 1: goto resume1; break;
+ case 2: goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // sort inputs
+ // 0x00 = DSP4_READ_WORD(0x00);
+ project_focaly = DSP4_READ_WORD(0x02);
+ raster = DSP4_READ_WORD(0x04);
+ viewport_top = DSP4_READ_WORD(0x06);
+ project_y = DSP4_READ_WORD(0x08);
+ viewport_bottom = DSP4_READ_WORD(0x0a);
+ project_x1low = DSP4_READ_WORD(0x0c);
+ project_focalx = DSP4_READ_WORD(0x0e);
+ project_centerx = DSP4_READ_WORD(0x10);
+ project_ptr = DSP4_READ_WORD(0x12);
+ // (envelope?) 0xc0 = DSP4_READ_WORD(0x14);
+ project_pitchylow = DSP4_READ_WORD(0x16);
+ project_pitchy = DSP4_READ_WORD(0x18);
+ project_pitchxlow = DSP4_READ_WORD(0x1a);
+ project_pitchx = DSP4_READ_WORD(0x1c);
+ far_plane = DSP4_READ_WORD(0x1e);
+ // ? = DSP4_READ_WORD(0x20);
+ project_y1low = DSP4_READ_WORD(0x22);
+
+ // pre-compute
+ view_plane = PLANE_START;
+
+ // find starting projection points
+ project_x1 = project_focalx;
+ project_y -= viewport_bottom;
+ project_x = project_centerx + project_x1;
+
+ // multi-op storage
+ multi_index1 = 0;
+ multi_index2 = 0;
+
+ // debug
+ block=0;
+
+ ////////////////////////////////////////////////////
+ // command check
+
+ do {
+ // scan next command
+ DSP4.in_count = 2;
+
+ DSP4_WAIT(1) resume1:
+
+ // inspect input
+ command = DSP4_READ_WORD(0);
+
+ // check for termination
+ if(command == 0x8000) break;
+
+ // already have 2 bytes in queue
+ DSP4.in_index = 2;
+ DSP4.in_count = 8;
+
+ DSP4_WAIT(2) resume2:
+
+ ////////////////////////////////////////////////////
+ // process one iteration of projection
+
+ // inspect inputs
+ int16 plane = DSP4_READ_WORD(0);
+ int16 index, lcv;
+ int16 py_dy=0, px_dx=0;
+ int16 y_out, x_out;
+ int8 envelope = DSP4.parameters[6];// | (DSP4.parameters[7]<<8);
+
+ // ignore invalid data
+ if((uint16) plane == 0x8001) continue;
+
+ // one-time init
+ if(far_plane)
+ {
+ // setup final parameters
+ project_focalx += plane;
+ project_x1 = project_focalx;
+ project_y1 = project_focaly;
+ plane = far_plane;
+ far_plane = 0;
+ }
+
+ // use proportional triangles to project new coords
+ project_x2 = project_focalx * plane / view_plane;
+ project_y2 = project_focaly * plane / view_plane;
+
+ // quadratic regression (rough)
+ if(project_focaly>=-0x0f)
+ py_dy = (short) (project_focaly * project_focaly * -0.20533553
+ - 1.08330005 * project_focaly - 69.61094639);
+ else
+ py_dy = (short) (project_focaly * project_focaly * -0.000657035759
+ - 1.07629051 * project_focaly - 65.69315963);
+
+ // approximate # of raster lines
+ segments = abs(project_y2-project_y1);
+
+ // prevent overdraw
+ if(project_y2>=raster) segments=0;
+ else raster=project_y2;
+
+ // don't draw outside the window
+ if(project_y2<viewport_top) segments=0;
+
+ // project new positions
+ if(segments>0)
+ {
+ // interpolate between projected points
+ px_dx = ((project_x2-project_x1)<<8)/segments;
+ }
+
+ // debug
+ ++block;
+#ifdef PRINT
+ printf("(line %d) Op01 check %02X, plane %04X, focal_y %04X, y2 %04X\n",c,(uint16)segments,(uint16)(plane),(uint16)project_focaly,(uint16)project_y2);
+#endif
+
+ // prepare output
+ DSP4.out_count=8+2+6*segments;
+
+ // pre-block data
+ DSP4_WRITE_WORD(0,project_focalx);
+ DSP4_WRITE_WORD(2,project_x2);
+ DSP4_WRITE_WORD(4,project_focaly);
+ DSP4_WRITE_WORD(6,project_y2);
+ DSP4_WRITE_WORD(8,segments);
+
+#if 0
+ DSP4_WRITE_WORD(0,-1);
+ DSP4_WRITE_WORD(2,-1);
+ DSP4_WRITE_WORD(4,-1);
+ DSP4_WRITE_WORD(6,-1);
+ DSP4_WRITE_WORD(8,-1);
+#endif
+
+ index=10;
+
+ // iterate through each point
+ for( lcv=0; lcv<segments; lcv++ )
+ {
+ // step through the projected line
+ y_out = project_y+((py_dy*lcv)>>8);
+ x_out = project_x+((px_dx*lcv)>>8);
+
+#if 0
+ project_ptr=-1;
+ y_out=-1;
+ x_out=-1;
+#endif
+
+ // data
+ DSP4_WRITE_WORD(index+0,project_ptr);
+ DSP4_WRITE_WORD(index+2,y_out);
+ DSP4_WRITE_WORD(index+4,x_out);
+ index += 6;
+
+ // post-update
+ project_ptr -= 4;
+ }
+
+ // post-update
+ project_y += ((py_dy*lcv)>>8);
+ project_x += ((px_dx*lcv)>>8);
+
+ // new positions
+ if(segments>0)
+ {
+ project_x1 = project_x2;
+ project_y1 = project_y2;
+
+ // multi-op storage
+ multi_focaly[multi_index2++] = project_focaly;
+ multi_farplane[1] = plane;
+ multi_raster[1] = project_y1-1;
+ }
+
+ // update projection points
+ project_pitchy += (int8)DSP4.parameters[3];
+ project_pitchx += (int8)DSP4.parameters[5];
+
+ project_focaly += project_pitchy;
+ project_focalx += project_pitchx;
+ } while (1);
+
+ // terminate op
+ DSP4.waiting4command = TRUE;
+ DSP4.out_count = 0;
+}
+
+#undef PRINT
+
+#if OP==0x0007
+#define PRINT
+#endif
+
+void DSP4_Op07()
+{
+ uint16 command;
+
+ DSP4.waiting4command = FALSE;
+
+ // op flow control
+ switch(DSP4_Logic) {
+ case 1: goto resume1; break;
+ case 2: goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // sort inputs
+
+ // 0x00 = DSP4_READ_WORD(0x00);
+ project_focaly = DSP4_READ_WORD(0x02);
+ raster = DSP4_READ_WORD(0x04);
+ viewport_top = DSP4_READ_WORD(0x06);
+ project_y = DSP4_READ_WORD(0x08);
+ viewport_bottom = DSP4_READ_WORD(0x0a);
+ project_x1low = DSP4_READ_WORD(0x0c);
+ project_x1 = DSP4_READ_WORD(0x0e);
+ project_centerx = DSP4_READ_WORD(0x10);
+ project_ptr = DSP4_READ_WORD(0x12);
+ // (envelope?) 0xc0 = DSP4_READ_WORD(0x14);
+
+ // pre-compute
+ view_plane = PLANE_START;
+
+ // find projection targets
+ project_y1 = project_focaly;
+ project_y -= viewport_bottom;
+ project_x = project_centerx + project_x1;
+
+ // multi-op storage
+ multi_index2 = 0;
+
+ // debug
+ block=0;
+
+#ifdef PRINT
+ printf("(line %d) Op07 data %04X\n",c,(uint16)project_y1);
+#endif
+
+ ////////////////////////////////////////////////////
+ // command check
+
+ do {
+ // scan next command
+ DSP4.in_count = 2;
+
+ DSP4_WAIT(1) resume1:
+
+ // inspect input
+ command = DSP4_READ_WORD(0);
+
+ // check for opcode termination
+ if(command == 0x8000) break;
+
+ // already have 2 bytes in queue
+ DSP4.in_index = 2;
+ DSP4.in_count = 12;
+
+ DSP4_WAIT(2) resume2:
+
+ ////////////////////////////////////////////////////
+ // process one loop of projection
+
+ int16 plane;
+ int16 index,lcv;
+ int16 y_out,x_out;
+ int16 py_dy=0,px_dx=0;
+
+ // debug
+ ++block;
+
+ // inspect inputs
+ plane = DSP4_READ_WORD(0);
+ project_y2 = DSP4_READ_WORD(2);
+ // ? = DSP4_READ_WORD(4);
+ project_x2 = DSP4_READ_WORD(6);
+ int8 envelope = DSP4.parameters[8];// | (DSP4.parameters[9]<<8);
+
+ // ignore invalid data
+ if((uint16) plane == 0x8001) continue;
+
+ // multi-op storage
+ project_focaly = multi_focaly[multi_index2];
+
+ // quadratic regression (rough)
+ if(project_focaly>=-0x0f)
+ py_dy = (short) (project_focaly * project_focaly * -0.20533553
+ - 1.08330005 * project_focaly - 69.61094639);
+ else
+ py_dy = (short) (project_focaly * project_focaly * -0.000657035759
+ - 1.07629051 * project_focaly - 65.69315963);
+
+ // approximate # of raster lines
+ segments = abs(project_y2-project_y1);
+
+ // prevent overdraw
+ if(project_y2>=raster) segments=0;
+ else raster=project_y2;
+
+ // don't draw outside the window
+ if(project_y2<viewport_top) segments=0;
+
+ // project new positions
+ if(segments>0)
+ {
+ // interpolate between projected points
+ px_dx = ((project_x2-project_x1)<<8)/segments;
+ }
+
+#ifdef PRINT
+ printf("(line %d) Op07 block %d, loc %04X, out %02X, project_x2 %04X\n",c,block,plane,segments,(uint16)project_x2);
+#endif
+
+ // prepare pre-output
+ DSP4.out_count=4+2+6*segments;
+
+ DSP4_WRITE_WORD(0,project_x2);
+ DSP4_WRITE_WORD(2,project_y2);
+ DSP4_WRITE_WORD(4,segments);
+
+#if 0
+ DSP4_WRITE_WORD(0,-1);
+ DSP4_WRITE_WORD(2,-1);
+ DSP4_WRITE_WORD(4,-1);
+#endif
+
+ index=6;
+ for( lcv=0; lcv<segments; lcv++ )
+ {
+ // pre-compute
+ y_out = project_y+((py_dy*lcv)>>8);
+ x_out = project_x+((px_dx*lcv)>>8);
+
+#if 0
+ project_ptr = -1;
+ //y_out = -1;
+ x_out = -1;
+#endif
+
+ // data
+ DSP4_WRITE_WORD(index+0,project_ptr);
+ DSP4_WRITE_WORD(index+2,y_out);
+ DSP4_WRITE_WORD(index+4,x_out);
+ index += 6;
+
+ // post-update
+ project_ptr -= 4;
+ }
+
+ // update internal variables
+ project_y += ((py_dy*lcv)>>8);
+ project_x += ((px_dx*lcv)>>8);
+
+ // new positions
+ if(segments>0)
+ {
+ project_x1 = project_x2;
+ project_y1 = project_y2;
+
+ // multi-op storage
+ multi_index2++;
+ }
+ } while(1);
+
+ DSP4.waiting4command = TRUE;
+ DSP4.out_count = 0;
+}
+
+#undef PRINT
+
+#if OP==0x0008
+#define PRINT
+#endif
+
+void DSP4_Op08()
+{
+ uint16 command;
+
+ DSP4.waiting4command = FALSE;
+
+ // op flow control
+ switch(DSP4_Logic) {
+ case 1: goto resume1; break;
+ case 2: goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // clip values
+ path_clipRight[0] = DSP4_READ_WORD(0x00);
+ path_clipRight[1] = DSP4_READ_WORD(0x02);
+ path_clipRight[2] = DSP4_READ_WORD(0x04);
+ path_clipRight[3] = DSP4_READ_WORD(0x06);
+
+ path_clipLeft[0] = DSP4_READ_WORD(0x08);
+ path_clipLeft[1] = DSP4_READ_WORD(0x0a);
+ path_clipLeft[2] = DSP4_READ_WORD(0x0c);
+ path_clipLeft[3] = DSP4_READ_WORD(0x0e);
+
+ // unknown (constant)
+ // unknown (constant)
+
+ // path positions
+ path_pos[0] = DSP4_READ_WORD(0x20);
+ path_pos[1] = DSP4_READ_WORD(0x22);
+ path_pos[2] = DSP4_READ_WORD(0x24);
+ path_pos[3] = DSP4_READ_WORD(0x26);
+
+ // data locations
+ path_ptr[0] = DSP4_READ_WORD(0x28);
+ path_ptr[1] = DSP4_READ_WORD(0x2a);
+ path_ptr[2] = DSP4_READ_WORD(0x2c);
+ path_ptr[3] = DSP4_READ_WORD(0x2e);
+
+ // project_y1 lines
+ path_raster[0] = DSP4_READ_WORD(0x30);
+ path_raster[1] = DSP4_READ_WORD(0x32);
+ path_raster[2] = DSP4_READ_WORD(0x34);
+ path_raster[3] = DSP4_READ_WORD(0x36);
+
+ // viewport_top
+ path_top[0] = DSP4_READ_WORD(0x38);
+ path_top[1] = DSP4_READ_WORD(0x3a);
+ path_top[2] = DSP4_READ_WORD(0x3c);
+ path_top[3] = DSP4_READ_WORD(0x3e);
+
+ // unknown (constants)
+
+ view_plane = PLANE_START;
+
+ // debug
+ block=0;
+
+ ////////////////////////////////////////////////////
+ // command check
+
+ do {
+ // scan next command
+ DSP4.in_count = 2;
+
+ DSP4_WAIT(1) resume1:
+
+ // inspect input
+ command = DSP4_READ_WORD(0);
+
+ // terminate op
+ if(command == 0x8000) break;
+
+ // already have 2 bytes in queue
+ DSP4.in_index = 2;
+ DSP4.in_count = 18;
+
+ DSP4_WAIT(2) resume2:
+
+ ////////////////////////////////////////////////////
+ // projection begins
+
+ // debug
+ ++block;
+
+ // used in envelope shaping
+ int16 x1_final;
+ int16 x2_final;
+
+ // look at guidelines
+ int16 plane = DSP4_READ_WORD(0x00);
+ int16 x_left = DSP4_READ_WORD(0x02);
+ int16 y_left = DSP4_READ_WORD(0x04);
+ int16 x_right = DSP4_READ_WORD(0x06);
+ int16 y_right = DSP4_READ_WORD(0x08);
+
+ // envelope guidelines (one frame only)
+ int16 envelope1 = DSP4_READ_WORD(0x0a);
+ int16 envelope2 = DSP4_READ_WORD(0x0c);
+ int16 envelope3 = DSP4_READ_WORD(0x0e);
+ int16 envelope4 = DSP4_READ_WORD(0x10);
+
+ // ignore invalid data
+ if((uint16) plane == 0x8001) continue;
+
+ // first init
+ if(plane == 0x7fff)
+ {
+ int pos1,pos2;
+
+ // initialize projection
+ path_x[0] = x_left;
+ path_x[1] = x_right;
+
+ path_y[0] = y_left;
+ path_y[1] = y_right;
+
+ // update coordinates
+ path_pos[0]-=x_left;
+ path_pos[1]-=x_left;
+ path_pos[2]-=x_right;
+ path_pos[3]-=x_right;
+
+ pos1 = path_pos[0]+envelope1;
+ pos2 = path_pos[1]+envelope2;
+
+ // clip offscreen data
+ if(pos1<path_clipLeft[0]) pos1 = path_clipLeft[0];
+ if(pos1>path_clipRight[0]) pos1 = path_clipRight[0];
+ if(pos2<path_clipLeft[1]) pos2 = path_clipLeft[1];
+ if(pos2>path_clipRight[1]) pos2 = path_clipRight[1];
+
+#if 0
+ pos1=-1;
+ //pos2=-1;
+#endif
+
+ path_plane[0] = plane;
+ path_plane[1] = plane;
+
+ // initial output
+ DSP4.out_count = 2;
+ DSP4.output[0]=pos1&0xFF;
+ DSP4.output[1]=pos2&0xFF;
+
+#ifdef PRINT
+ printf("(line %d) Op08 x_left %04X\n",c,(uint16)x_left);
+#endif
+ }
+ // proceed with projection
+ else
+ {
+ int16 index=0, lcv;
+ int16 left_inc=0,right_inc=0;
+ int16 dx1,dx2,dx3,dx4;
+
+ // # segments to traverse
+ segments = abs(y_left - path_y[0]);
+
+ // prevent overdraw
+ if(y_left>=path_raster[0]) segments=0;
+ else path_raster[0]=y_left;
+
+ // don't draw outside the window
+ if(path_raster[0]<path_top[0]) segments=0;
+
+ // proceed if visibility rules apply
+ if(segments>0)
+ {
+ // use previous data
+ dx1 = (envelope1 * path_plane[0] / view_plane);
+ dx2 = (envelope2 * path_plane[0] / view_plane);
+
+ // use temporary envelope pitch (this frame only)
+ dx3 = (envelope1 * plane / view_plane);
+ dx4 = (envelope2 * plane / view_plane);
+
+ // project new shapes (left side)
+ x1_final = x_left+dx1;
+ x2_final = path_x[0]+dx3;
+
+ // interpolate between projected points with shaping
+ left_inc = ((x2_final-x1_final)<<8)/segments;
+
+ // project new shapes (right side)
+ x1_final = x_left+dx2;
+ x2_final = path_x[0]+dx4;
+
+ // interpolate between projected points with shaping
+ right_inc = ((x2_final-x1_final)<<8)/segments;
+
+ path_plane[0] = plane;
+ }
+
+#ifdef PRINT
+ printf("(line %d) Op08 block %d, out %02X, raster %02X\n",c,block,segments,(uint16)y_left);
+#endif
+
+ // zone 1
+ DSP4.out_count = (2+4*segments);
+ DSP4_WRITE_WORD(index,segments); index+=2;
+
+ for( lcv=1; lcv<=segments; lcv++ )
+ {
+ int16 pos1,pos2;
+
+ // pre-compute
+ pos1 = path_pos[0]+((left_inc*lcv)>>8)+dx1;
+ pos2 = path_pos[1]+((right_inc*lcv)>>8)+dx2;
+
+ // clip offscreen data
+ if(pos1<path_clipLeft[0]) pos1 = path_clipLeft[0];
+ if(pos1>path_clipRight[0]) pos1 = path_clipRight[0];
+ if(pos2<path_clipLeft[1]) pos2 = path_clipLeft[1];
+ if(pos2>path_clipRight[1]) pos2 = path_clipRight[1];
+
+#if 0
+ if(pos1==0x00ff) pos1=0;
+ if(pos2==0x00ff) pos2=0;
+ path_ptr[0] = -1;
+ pos1 = -1;
+ pos2 = -1;
+#endif
+
+ // data
+ DSP4_WRITE_WORD(index,path_ptr[0]); index+=2;
+ DSP4.output[index++]=pos1&0xFF;
+ DSP4.output[index++]=pos2&0xFF;
+
+ // post-update
+ path_ptr[0] -= 4;
+ path_ptr[1] -= 4;
+ }
+ lcv--;
+
+ if(segments>0)
+ {
+ // project points w/out the envelopes
+ int16 inc = ((path_x[0]-x_left)<<8)/segments;
+
+ // post-store
+ path_pos[0] += ((inc*lcv)>>8);
+ path_pos[1] += ((inc*lcv)>>8);
+
+ path_x[0] = x_left;
+ path_y[0] = y_left;
+ }
+
+ //////////////////////////////////////////////
+ // zone 2
+ segments = abs(y_right - path_y[1]);
+
+ // prevent overdraw
+ if(y_right>=path_raster[2]) segments=0;
+ else path_raster[2]=y_right;
+
+ // don't draw outside the window
+ if(path_raster[2]<path_top[2]) segments=0;
+
+ // proceed if visibility rules apply
+ if(segments>0)
+ {
+ // use previous data
+ dx1 = (envelope1 * path_plane[1] / view_plane);
+ dx2 = (envelope2 * path_plane[1] / view_plane);
+
+ // use temporary envelope pitch (this frame only)
+ dx3 = (envelope1 * plane / view_plane);
+ dx4 = (envelope2 * plane / view_plane);
+
+ // project new shapes (left side)
+ x1_final = x_left+dx1;
+ x2_final = path_x[1]+dx3;
+
+ // interpolate between projected points with shaping
+ left_inc = ((x2_final-x1_final)<<8)/segments;
+
+ // project new shapes (right side)
+ x1_final = x_left+dx2;
+ x2_final = path_x[1]+dx4;
+
+ // interpolate between projected points with shaping
+ right_inc = ((x2_final-x1_final)<<8)/segments;
+
+ path_plane[1] = plane;
+ }
+
+ // write out results
+ DSP4.out_count += (2+4*segments);
+ DSP4_WRITE_WORD(index,segments); index+=2;
+
+ for( lcv=1; lcv<=segments; lcv++ )
+ {
+ int16 pos1,pos2;
+
+ // pre-compute
+ pos1 = path_pos[2]+((left_inc*lcv)>>8)+dx1;
+ pos2 = path_pos[3]+((right_inc*lcv)>>8)+dx2;
+
+ // clip offscreen data
+ if(pos1<path_clipLeft[2]) pos1 = path_clipLeft[2];
+ if(pos1>path_clipRight[2]) pos1 = path_clipRight[2];
+ if(pos2<path_clipLeft[3]) pos2 = path_clipLeft[3];
+ if(pos2>path_clipRight[3]) pos2 = path_clipRight[3];
+
+#if 0
+ if(pos1==0x00ff) pos1=0;
+ if(pos2==0x00ff) pos2=0;
+ path_ptr[2] = -1;
+ //pos1 = -1;
+ pos2 = -1;
+#endif
+
+ // data
+ DSP4_WRITE_WORD(index,path_ptr[2]); index+=2;
+ DSP4.output[index++]=pos1&0xFF;
+ DSP4.output[index++]=pos2&0xFF;
+
+ // post-update
+ path_ptr[2] -= 4;
+ path_ptr[3] -= 4;
+ }
+ lcv--;
+
+ if(segments>0)
+ {
+ // project points w/out the envelopes
+ int16 inc = ((path_x[1]-x_right)<<8)/segments;
+
+ // post-store
+ path_pos[2] += ((inc*lcv)>>8);
+ path_pos[3] += ((inc*lcv)>>8);
+
+ path_x[1] = x_right;
+ path_y[1] = y_right;
+ }
+ }
+ } while(1);
+
+ DSP4.waiting4command = TRUE;
+ DSP4.out_count = 2;
+ DSP4_WRITE_WORD(0,0);
+}
+
+#undef PRINT
+
+#if OP==0x000D
+#define PRINT
+#endif
+
+void DSP4_Op0D()
+{
+ uint16 command;
+
+ DSP4.waiting4command = FALSE;
+
+ // op flow control
+ switch(DSP4_Logic) {
+ case 1: goto resume1; break;
+ case 2: goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // sort inputs
+ // 0x00 = DSP4_READ_WORD(0x00);
+ project_focaly = DSP4_READ_WORD(0x02);
+ raster = DSP4_READ_WORD(0x04);
+ viewport_top = DSP4_READ_WORD(0x06);
+ project_y = DSP4_READ_WORD(0x08);
+ viewport_bottom = DSP4_READ_WORD(0x0a);
+ project_x1low = DSP4_READ_WORD(0x0c);
+ project_x1 = DSP4_READ_WORD(0x0e);
+ project_focalx = DSP4_READ_WORD(0x0e);
+ project_centerx = DSP4_READ_WORD(0x10);
+ project_ptr = DSP4_READ_WORD(0x12);
+ // 0xc0 = DSP4_READ_WORD(0x14);
+ project_pitchylow = DSP4_READ_WORD(0x16);
+ project_pitchy = DSP4_READ_WORD(0x18);
+ project_pitchxlow = DSP4_READ_WORD(0x1a);
+ project_pitchx = DSP4_READ_WORD(0x1c);
+ far_plane = DSP4_READ_WORD(0x1e);
+ // ? = DSP4_READ_WORD(0x20);
+
+ // multi-op storage
+ multi_index1++;
+ multi_index1%=4;
+
+ // remap 0D->09 window data ahead of time
+ // index starts at 1-3,0
+ //
+ // Op0D: BL,TL,BR,TR
+ // Op09: TL,TR,BL,BR (1,2,3,0)
+ switch(multi_index1)
+ {
+ case 1: multi_index2=3; break;
+ case 2: multi_index2=1; break;
+ case 3: multi_index2=0; break;
+ case 0: multi_index2=2; break;
+ }
+
+ // pre-compute
+ view_plane = PLANE_START;
+
+ // figure out projection data
+ project_y -= viewport_bottom;
+ project_x = project_centerx + project_x1;
+
+ // debug
+ block=0;
+
+ ////////////////////////////////////////////////////
+ // command check
+
+ do {
+ // scan next command
+ DSP4.in_count = 2;
+
+ DSP4_WAIT(1) resume1:
+
+ // inspect input
+ command = DSP4_READ_WORD(0);
+
+ // terminate op
+ if(command == 0x8000) break;
+
+ // already have 2 bytes in queue
+ DSP4.in_index = 2;
+ DSP4.in_count = 8;
+
+ DSP4_WAIT(2) resume2:
+
+ ////////////////////////////////////////////////////
+ // project section of the track
+
+ // inspect inputs
+ int16 plane = DSP4_READ_WORD(0);
+ int16 index, lcv;
+ int16 py_dy=0, px_dx=0;
+ int16 y_out, x_out;
+ int8 envelope = DSP4.parameters[6];// | (DSP4.parameters[7]<<8);
+
+ // ignore invalid data
+ if((uint16) plane == 0x8001) continue;
+
+ // one-time init
+ if(far_plane)
+ {
+ // setup final data
+ // low16=plane
+ project_x1 = project_focalx;
+ project_y1 = project_focaly;
+ plane = far_plane;
+ far_plane = 0;
+ }
+
+ // use proportional triangles to project new coords
+ project_x2 = project_focalx * plane / view_plane;
+ project_y2 = project_focaly * plane / view_plane;
+
+ // quadratic regression (rough)
+ if(project_focaly>=-0x0f)
+ py_dy = (short) (project_focaly * project_focaly * -0.20533553
+ - 1.08330005 * project_focaly - 69.61094639);
+ else
+ py_dy = (short) (project_focaly * project_focaly * -0.000657035759
+ - 1.07629051 * project_focaly - 65.69315963);
+
+ // approximate # of raster lines
+ segments = abs(project_y2-project_y1);
+
+ // prevent overdraw
+ if(project_y2>=raster) segments=0;
+ else raster=project_y2;
+
+ // don't draw outside the window
+ if(project_y2<viewport_top) segments=0;
+
+ // project new positions
+ if(segments>0)
+ {
+ // interpolate between projected points
+ px_dx = ((project_x2-project_x1)<<8)/segments;
+ }
+
+ // debug
+ ++block;
+
+#ifdef PRINT
+ printf("(line %d) Op0D check %02X, plane %04X\n",c,(uint16)segments,(uint16)(plane));
+#endif
+
+ // prepare output
+ DSP4.out_count=8+2+6*segments;
+
+ DSP4_WRITE_WORD(0,project_focalx);
+ DSP4_WRITE_WORD(2,project_x2);
+ DSP4_WRITE_WORD(4,project_focaly);
+ DSP4_WRITE_WORD(6,project_y2);
+ DSP4_WRITE_WORD(8,segments);
+#if 0
+ DSP4_WRITE_WORD(0,-1);
+ DSP4_WRITE_WORD(2,-1);
+ DSP4_WRITE_WORD(4,-1);
+ DSP4_WRITE_WORD(6,-1);
+ DSP4_WRITE_WORD(8,-1);
+#endif
+
+ index=10;
+
+ // iterate through each point
+ for( lcv=0; lcv<segments; lcv++ )
+ {
+ // step through the projected line
+ y_out = project_y+((py_dy*lcv)>>8);
+ x_out = project_x+((px_dx*lcv)>>8);
+
+#if 0
+ project_ptr=-1;
+ //y_out=-1;
+ x_out=-1;
+#endif
+
+ // data
+ DSP4_WRITE_WORD(index+0,project_ptr);
+ DSP4_WRITE_WORD(index+2,y_out);
+ DSP4_WRITE_WORD(index+4,x_out);
+ index += 6;
+
+ // post-update
+ project_ptr -= 4;
+ }
+
+ // post-update
+ project_y += ((py_dy*lcv)>>8);
+ project_x += ((px_dx*lcv)>>8);
+
+ if(segments > 0)
+ {
+ project_x1 = project_x2;
+ project_y1 = project_y2;
+
+ // multi-op storage
+ multi_farplane[multi_index2] = plane;
+ multi_raster[multi_index2] = project_y1;
+ }
+
+ // update focal projection points
+ project_pitchy += (int8)DSP4.parameters[3];
+ project_pitchx += (int8)DSP4.parameters[5];
+
+ project_focaly += project_pitchy;
+ project_focalx += project_pitchx;
+ } while(1);
+
+ DSP4.waiting4command = TRUE;
+ DSP4.out_count = 0;
+}
+
+#undef PRINT
+
+#if OP==0x0009
+#define PRINT
+#endif
+
+#if OP==0x0006
+#define PRINT
+#endif
+
+void DSP4_Op09()
+{
+ uint16 command;
+
+ DSP4.waiting4command = FALSE;
+
+ // op flow control
+ switch(DSP4_Logic) {
+ case 1: goto resume1; break;
+ case 2: goto resume2; break;
+ case 3: goto resume3; break;
+ case 4: goto resume4; break;
+ case 5: goto resume5; break;
+ case 6: goto resume6; break;
+ case 7: goto resume7; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // debug
+ block=0;
+
+ // grab screen information
+ view_plane = PLANE_START;
+ center_x = DSP4_READ_WORD(0x00);
+ center_y = DSP4_READ_WORD(0x02);
+ // 0x00 = DSP4_READ_WORD(0x04);
+ viewport_left = DSP4_READ_WORD(0x06);
+ viewport_right = DSP4_READ_WORD(0x08);
+ viewport_top = DSP4_READ_WORD(0x0a);
+ viewport_bottom = DSP4_READ_WORD(0x0c);
+
+#ifdef PRINT2
+ printf("Window: (%04X,%04X) (%04X,%04X)\n",
+ viewport_left,viewport_right,viewport_top,viewport_bottom);
+#endif
+
+ // expand viewport dimensions
+ viewport_left -= 8;
+
+ // cycle through viewport window data
+ multi_index1++;
+ multi_index1%=4;
+
+#if 1
+ // convert track line to the window region
+ project_y2 = center_y + multi_raster[multi_index1] *
+ (viewport_bottom-center_y)/(0x33-0);
+ if(op09_mode==0) project_y2 -= 2;
+#endif
+
+ goto no_sprite;
+
+ do {
+ ////////////////////////////////////////////////////
+ // check for new sprites
+
+ do {
+ uint16 second;
+
+ DSP4.in_count = 4;
+ DSP4.in_index = 2;
+
+ DSP4_WAIT(1) resume1:
+
+ // try to classify sprite
+ second = DSP4_READ_WORD(2);
+
+ // op termination
+ if(second == 0x8000) goto terminate;
+
+ second >>= 8;
+ sprite_type = 0;
+
+ // vehicle sprite
+ if(second == 0x90)
+ {
+ sprite_type = 1;
+ break;
+ }
+ // terrain sprite
+ else if(second != 0)
+ {
+ sprite_type = 2;
+ break;
+ }
+
+no_sprite:
+ // no sprite. try again
+
+ DSP4.in_count = 2;
+
+ DSP4_WAIT(2) resume2:
+ ;
+ } while (1);
+
+ ////////////////////////////////////////////////////
+ // process projection information
+
+sprite_found:
+ // vehicle sprite
+ if(sprite_type == 1)
+ {
+ int16 plane;
+ int16 car_left, car_right, car_left_a;
+ int16 focal_back, focal_front;
+ uint8 distance, id;
+
+ // we already have 4 bytes we want
+ DSP4.in_count = 6+12;
+ DSP4.in_index = 4;
+
+ DSP4_WAIT(3) resume3:
+
+ // filter inputs
+ project_y1 = DSP4_READ_WORD(0x00);
+ // 0x9000 = DSP4_READ_WORD(0x02);
+ id = DSP4.parameters[0x04];
+ distance = DSP4.parameters[0x05];
+ focal_back = DSP4_READ_WORD(0x06);
+ focal_front = DSP4_READ_WORD(0x08);
+ car_left_a = DSP4_READ_WORD(0x0a);
+ car_left = DSP4_READ_WORD(0x0c);
+ plane = DSP4_READ_WORD(0x0e);
+ car_right = DSP4_READ_WORD(0x10);
+
+ // calculate car's x-center
+ project_focalx = car_right-car_left;
+
+ // determine how far into the screen to project
+ project_focaly = focal_back;
+ project_x = project_focalx * plane / view_plane;
+ segments = 0x33 - project_focaly * plane / view_plane;
+ far_plane = plane;
+
+ // prepare memory
+ sprite_x = center_x+project_x;
+ sprite_y = viewport_bottom-segments;
+ far_plane = plane;
+
+ // debug
+ ++block;
+#ifdef PRINT
+ printf("(line %d) Op09 vehicle block %d, Loop %04X\n",c,block,(uint16)project_y1);
+ //printf("%04X %04X %04X %04X / ",focal_back,focal_front,car_left_a,car_left);
+ //printf("%02X %02X ", distance, id);
+#endif
+
+ // make the car's x-center available
+ DSP4.out_count = 2;
+ DSP4_WRITE_WORD(0,project_focalx);
+
+#if 0
+ DSP4_WRITE_WORD(0,-1);
+#endif
+
+ // grab a few remaining vehicle values
+ DSP4.in_count = 4;
+
+ DSP4_WAIT(4) resume4:
+
+ // store final values
+ int height = DSP4_READ_WORD(0);
+ sprite_offset = DSP4_READ_WORD(2);
+
+ // vertical lift factor
+ sprite_y += height;
+
+#ifdef PRINT_09
+ printf("%04X\n",sprite_offset);
+#endif
+ }
+ // terrain sprite
+ else if(sprite_type == 2)
+ {
+ int16 plane;
+
+ // we already have 4 bytes we want
+ DSP4.in_count = 6+6+2;
+ DSP4.in_index = 4;
+
+ DSP4_WAIT(5) resume5:
+
+ // sort loop inputs
+ project_y1 = DSP4_READ_WORD(0x00);
+ plane = DSP4_READ_WORD(0x02);
+ project_centerx = DSP4_READ_WORD(0x04);
+ //project_y1 = DSP4_READ_WORD(0x06);
+ project_focalx = DSP4_READ_WORD(0x08);
+ project_focaly = DSP4_READ_WORD(0x0a);
+ sprite_offset = DSP4_READ_WORD(0x0c);
+
+ // determine distances into virtual world
+ segments = 0x33 - project_y1;
+ project_x = project_focalx * plane / view_plane;
+ project_y = project_focaly * plane / view_plane;
+
+ // prepare memory
+ sprite_x = center_x+project_x-project_centerx;
+ sprite_y = viewport_bottom-segments+project_y;
+ far_plane = plane;
+
+ // debug
+ ++block;
+#ifdef PRINT
+ printf("(line %d) Op09 terrain block %d, Loop %04X\n",c,block,(uint16)project_y1);
+#endif
+ }
+
+ // default sprite size: 16x16
+ sprite_size = 1;
+
+ ////////////////////////////////////////////////////
+ // convert tile data to OAM
+
+ do {
+ DSP4.in_count = 2;
+
+ DSP4_WAIT(6) resume6:
+
+ command = DSP4_READ_WORD(0);
+
+ // opcode termination
+ if(command == 0x8000) goto terminate;
+
+ // toggle sprite size
+ if(command == 0x0000)
+ {
+ sprite_size = !sprite_size;
+#ifdef PRINT
+ printf("TOGGLE=%02X\n",(uint8)sprite_size);
+#endif
+ continue;
+ }
+
+ // new sprite information
+ command >>= 8;
+ if(command != 0x20 && command != 0x40 &&
+ command != 0x60 && command != 0xa0 &&
+ command != 0xc0 && command != 0xe0)
+ break;
+
+ DSP4.in_count = 6;
+ DSP4.in_index = 2;
+
+ DSP4_WAIT(7) resume7:
+
+ /////////////////////////////////////
+ // process tile data
+
+ bool8 clip;
+ int16 sp_x, sp_y, sp_oam, sp_msb;
+ int16 sp_dx, sp_dy;
+
+ // sprite deltas
+ sp_dy = DSP4_READ_WORD(2);
+ sp_dx = DSP4_READ_WORD(4);
+
+ // update coordinates
+ sp_y = sprite_y + sp_dy;
+ sp_x = sprite_x + sp_dx;
+
+ // reject points outside the clipping window
+ clip = FALSE;
+ if(sp_x < viewport_left || sp_x > viewport_right) clip=TRUE;
+ if(sp_y < viewport_top || sp_y > viewport_bottom) clip=TRUE;
+
+ // track depth sorting
+ if(far_plane <= multi_farplane[multi_index1] &&
+ sp_y >= project_y2) clip=TRUE;
+
+#ifdef PRINT2
+ printf("(line %d) %04X, %04X, %04X / %04X %04X\n",line,
+ (uint16)sp_x,(uint16)sp_y,(uint16)far_plane,(uint16)multi_farplane[multi_index1],(uint16)project_y2);
+#endif
+
+ // don't draw offscreen coordinates
+ DSP4.out_count = 0;
+ if(!clip)
+ {
+ int16 out_index = 0;
+ int16 offset = DSP4_READ_WORD(0);
+
+ // update sprite nametable/attribute information
+ sp_oam = sprite_offset + offset;
+ sp_msb = (sp_x<0 || sp_x>255);
+
+#ifdef PRINT
+ printf("(line %d) %04X, %04X, %04X, %04X, %04X\n",line,
+ (uint16)sp_oam,(uint16)sprite_offset,(uint16)offset,
+ (uint16)sp_x,(uint16)sp_y);
+#endif
+
+ // emit transparency information
+ if(
+ (sprite_offset&0x08) &&
+ ((sprite_type==1 && sp_y>=0xcc) ||
+ (sprite_type==2 && sp_y>=0xbb))
+ )
+ {
+ DSP4.out_count = 6;
+
+ // one block of OAM data
+ DSP4_WRITE_WORD(0,1);
+
+ // OAM: x,y,tile,no attr
+ DSP4.output[2] = sp_x&0xFF;
+ DSP4.output[3] = (sp_y+6)&0xFF;
+ DSP4_WRITE_WORD(4,0xEE);
+
+ out_index = 6;
+
+ // OAM: size,msb data
+ DSP4_Op06(sprite_size,(char) sp_msb);
+ }
+
+ // normal data
+ DSP4.out_count += 8;
+
+ // one block of OAM data
+ DSP4_WRITE_WORD(out_index+0,1);
+
+ // OAM: x,y,tile,attr
+ DSP4.output[out_index+2] = sp_x&0xFF;
+ DSP4.output[out_index+3] = sp_y&0xFF;
+ DSP4_WRITE_WORD(out_index+4,sp_oam);
+
+ // no following OAM data
+ DSP4_WRITE_WORD(out_index+6,0);
+
+ // OAM: size,msb data
+ DSP4_Op06(sprite_size, (char) sp_msb);
+
+#if 0
+ DSP4_WRITE_WORD(0,-1);
+ DSP4_WRITE_WORD(2,-1);
+ DSP4_WRITE_WORD(4,-1);
+ DSP4_WRITE_WORD(6,-1);
+ DSP4_WRITE_WORD(8,-1);
+ DSP4_WRITE_WORD(10,-1);
+ DSP4_WRITE_WORD(12,-1);
+#endif
+ }
+
+ // no sprite information
+ if(DSP4.out_count == 0)
+ {
+ DSP4.out_count = 2;
+ DSP4_WRITE_WORD(0,0);
+ }
+ } while (1);
+
+ /////////////////////////////////////
+ // special cases: plane == 0x0000
+
+ // special vehicle case
+ if(command == 0x90)
+ {
+ sprite_type = 1;
+
+ // shift bytes
+ DSP4.parameters[2] = DSP4.parameters[0];
+ DSP4.parameters[3] = DSP4.parameters[1];
+ DSP4.parameters[0] = 0;
+ DSP4.parameters[1] = 0;
+
+ goto sprite_found;
+ }
+ // special terrain case
+ else if(command != 0x00 && command != 0xff)
+ {
+ sprite_type = 2;
+
+ // shift bytes
+ DSP4.parameters[2] = DSP4.parameters[0];
+ DSP4.parameters[3] = DSP4.parameters[1];
+ DSP4.parameters[0] = 0;
+ DSP4.parameters[1] = 0;
+
+ goto sprite_found;
+ }
+ } while (1);
+
+terminate:
+ DSP4.waiting4command = TRUE;
+ DSP4.out_count=0;
+}
+
+#undef PRINT
+
diff --git a/source/font.h b/source/font.h
new file mode 100644
index 0000000..f2edfd2
--- /dev/null
+++ b/source/font.h
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+static char *font[] = {
+" . . . . .. . . ",
+" .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ",
+" .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ",
+" .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ",
+" .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ",
+" . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ",
+" .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ",
+" . . . ... . . . . . . . . .#. .. ",
+" . ",
+" . . .. .... . .... .. .... .. .. . ",
+" .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ",
+".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ",
+".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ",
+".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ",
+".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ",
+" .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ",
+" . ... .... .. . .. .. . .. .. .. .#. . . . ",
+" . ",
+" .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ",
+" .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ",
+".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ",
+".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ",
+".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ",
+".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ",
+" .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ",
+" .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ",
+" ",
+" ... .. ... .. ... . . . . . . . . . . .... ... ... . ",
+".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ",
+".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ",
+".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ",
+".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ",
+".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ",
+".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ",
+" . ..#. . . .. . ... . . . . . . .... ... ... .... ",
+" . ",
+" .. . . . . . . . .. ",
+".##. .#. .#. .#. .#. .#. .#. .#. .##. ",
+" .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ",
+" .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ",
+" . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ",
+" .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ",
+" .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ",
+" . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ",
+" ... . ",
+" . . . . . . ",
+" .#. .#. .#. .#. .#.#. ",
+" ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ",
+".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ",
+".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ",
+".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ",
+".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ",
+".#.. ..#. . ... .. ... . . . . . .#. .... . . . ",
+" . . . ",
+};
+
+static int font_width = 8;
+static int font_height = 9;
+
diff --git a/source/fxdbg.cpp b/source/fxdbg.cpp
new file mode 100644
index 0000000..3479db1
--- /dev/null
+++ b/source/fxdbg.cpp
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "fxemu.h"
+#include "fxinst.h"
+#include <stdio.h>
+#include <string.h>
+
+extern const char *fx_apvMnemonicTable[];
+extern struct FxRegs_s GSU;
+
+
+/*
+ When printing a line from the pipe, it could look like this:
+
+ 01:8006 f4 fb 86 iwt r4,#$86fb
+
+ The values are:
+ program bank: 01
+ adress: 8006
+ values at memory address 8006: f4 fb 86
+ instruction in the pipe: iwt r4,#$86fb
+
+ Note! If the instruction has more than one byte (like in 'iwt')
+ and the instruction is in a delay slot, the second and third
+ byte displayed will not be the same as those used.
+ Since the instrction is in a delay slot, the first byte
+ of the instruction will be taken from the pipe at the address
+ after the branch instruction, and the next one or two bytes
+ will be taken from the address that the branch points to.
+ This is a bit complicated, but I've taken this into account,
+ in this debug function. (See the diffrence of how the values
+ vPipe1 and vPipe2 are read, compared to the values vByte1 and
+ vByte2)
+
+ */
+void FxPipeString(char * pvString)
+{
+ char *p;
+ uint32 vOpcode = (GSU.vStatusReg & 0x300) | ((uint32)PIPE);
+ const char *m = fx_apvMnemonicTable[vOpcode];
+ uint8 vPipe1,vPipe2,vByte1,vByte2;
+ uint8 vPipeBank = GSU.vPipeAdr >> 16;
+
+ /* The next two bytes after the pipe's address */
+ vPipe1 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr+1)];
+ vPipe2 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr+2)];
+
+ /* The actual next two bytes to be read */
+ vByte1 = PRGBANK(USEX16(R15));
+ vByte2 = PRGBANK(USEX16(R15+1));
+
+ /* Print ROM address of the pipe */
+ sprintf(pvString, "%02x:%04x %02x ",
+ USEX8(vPipeBank), USEX16(GSU.vPipeAdr), USEX8(PIPE));
+ p = &pvString[strlen(pvString)];
+
+ /* Check if it's a branch instruction */
+ if( PIPE >= 0x05 && PIPE <= 0x0f )
+ {
+ sprintf(&pvString[11], "%02x ", USEX8(vPipe1));
+#ifdef BRANCH_DELAY_RELATIVE
+ sprintf(p, m, USEX16(R15 + SEX8(vByte1) + 1 ) );
+#else
+ sprintf(p, m, USEX16(R15 + SEX8(vByte1) - 1 ) );
+#endif
+ }
+ /* Check for 'move' instruction */
+ else if( PIPE >= 0x10 && PIPE <= 0x1f && TF(B) )
+ sprintf(p, "move r%d,r%d", USEX8(PIPE & 0x0f), GSU.pvSreg - GSU.avReg);
+ /* Check for 'ibt', 'lms' or 'sms' */
+ else if( PIPE >= 0xa0 && PIPE <= 0xaf )
+ {
+ sprintf(&pvString[11], "%02x ", USEX8(vPipe1));
+ if( (GSU.vStatusReg & 0x300) == 0x100 || (GSU.vStatusReg & 0x300) == 0x200 )
+ sprintf(p, m, USEX16(vByte1) << 1 );
+ else
+ sprintf(p, m, USEX16(vByte1) );
+ }
+ /* Check for 'moves' */
+ else if( PIPE >= 0xb0 && PIPE <= 0xbf && TF(B) )
+ sprintf(p, "moves r%d,r%d", GSU.pvDreg - GSU.avReg, USEX8(PIPE & 0x0f) );
+ /* Check for 'iwt', 'lm' or 'sm' */
+ else if( PIPE >= 0xf0 )
+ {
+ sprintf(&pvString[11], "%02x %02x ", USEX8(vPipe1), USEX8(vPipe2));
+ sprintf(p, m, USEX8(vByte1) | (USEX16(vByte2)<<8) );
+ }
+ /* Normal instruction */
+ else
+ strcpy(p, m);
+}
+
+const char *fx_apvMnemonicTable[] =
+{
+ /*
+ * ALT0 Table
+ */
+ /* 00 - 0f */
+ "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x",
+ "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x",
+ /* 10 - 1f */
+ "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7",
+ "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15",
+ /* 20 - 2f */
+ "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7",
+ "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15",
+ /* 30 - 3f */
+ "stw (r0)","stw (r1)","stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)",
+ "stw (r8)","stw (r9)","stw (r10)","stw (r11)","loop", "alt1", "alt2", "alt3",
+ /* 40 - 4f */
+ "ldw (r0)","ldw (r1)","ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)",
+ "ldw (r8)","ldw (r9)","ldw (r10)","ldw (r11)","plot", "swap", "color", "not",
+ /* 50 - 5f */
+ "add r0", "add r1", "add r2", "add r3", "add r4", "add r5", "add r6", "add r7",
+ "add r8", "add r9", "add r10", "add r11", "add r12", "add r13", "add r14", "add r15",
+ /* 60 - 6f */
+ "sub r0", "sub r1", "sub r2", "sub r3", "sub r4", "sub r5", "sub r6", "sub r7",
+ "sub r8", "sub r9", "sub r10", "sub r11", "sub r12", "sub r13", "sub r14", "sub r15",
+ /* 70 - 7f */
+ "merge", "and r1", "and r2", "and r3", "and r4", "and r5", "and r6", "and r7",
+ "and r8", "and r9", "and r10", "and r11", "and r12", "and r13", "and r14", "and r15",
+ /* 80 - 8f */
+ "mult r0", "mult r1", "mult r2", "mult r3", "mult r4", "mult r5", "mult r6", "mult r7",
+ "mult r8", "mult r9", "mult r10", "mult r11", "mult r12", "mult r13", "mult r14", "mult r15",
+ /* 90 - 9f */
+ "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror",
+ "jmp (r8)","jmp (r9)","jmp (r10)","jmp (r11)","jmp (r12)","jmp (r13)","lob", "fmult",
+ /* a0 - af */
+ "ibt r0,#$%02x", "ibt r1,#$%02x", "ibt r2,#$%02x", "ibt r3,#$%02x",
+ "ibt r4,#$%02x", "ibt r5,#$%02x", "ibt r6,#$%02x", "ibt r7,#$%02x",
+ "ibt r8,#$%02x", "ibt r9,#$%02x", "ibt r10,#$%02x", "ibt r11,#$%02x",
+ "ibt r12,#$%02x", "ibt r13,#$%02x", "ibt r14,#$%02x", "ibt r15,#$%02x",
+ /* b0 - bf */
+ "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7",
+ "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15",
+ /* c0 - cf */
+ "hib", "or r1", "or r2", "or r3", "or r4", "or r5", "or r6", "or r7",
+ "or r8", "or r9", "or r10", "or r11", "or r12", "or r13", "or r14", "or r15",
+ /* d0 - df */
+ "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7",
+ "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc",
+ /* e0 - ef */
+ "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7",
+ "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getb",
+ /* f0 - ff */
+ "iwt r0,#$%04x", "iwt r1,#$%04x", "iwt r2,#$%04x", "iwt r3,#$%04x",
+ "iwt r4,#$%04x", "iwt r5,#$%04x", "iwt r6,#$%04x", "iwt r7,#$%04x",
+ "iwt r8,#$%04x", "iwt r9,#$%04x", "iwt r10,#$%04x", "iwt r11,#$%04x",
+ "iwt r12,#$%04x", "iwt r13,#$%04x", "iwt r14,#$%04x", "iwt r15,#$%04x",
+
+ /*
+ * ALT1 Table
+ */
+
+ /* 00 - 0f */
+ "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x",
+ "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x",
+ /* 10 - 1f */
+ "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7",
+ "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15",
+ /* 20 - 2f */
+ "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7",
+ "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15",
+ /* 30 - 3f */
+ "stb (r0)","stb (r1)","stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)",
+ "stb (r8)","stb (r9)","stb (r10)","stb (r11)","loop", "alt1", "alt2", "alt3",
+ /* 40 - 4f */
+ "ldb (r0)","ldb (r1)","ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)",
+ "ldb (r8)","ldb (r9)","ldb (r10)","ldb (r11)","rpix", "swap", "cmode", "not",
+ /* 50 - 5f */
+ "adc r0", "adc r1", "adc r2", "adc r3", "adc r4", "adc r5", "adc r6", "adc r7",
+ "adc r8", "adc r9", "adc r10", "adc r11", "adc r12", "adc r13", "adc r14", "adc r15",
+ /* 60 - 6f */
+ "sbc r0", "sbc r1", "sbc r2", "sbc r3", "sbc r4", "sbc r5", "sbc r6", "sbc r7",
+ "sbc r8", "sbc r9", "sbc r10", "sbc r11", "sbc r12", "sbc r13", "sbc r14", "sbc r15",
+ /* 70 - 7f */
+ "merge", "bic r1", "bic r2", "bic r3", "bic r4", "bic r5", "bic r6", "bic r7",
+ "bic r8", "bic r9", "bic r10", "bic r11", "bic r12", "bic r13", "bic r14", "bic r15",
+ /* 80 - 8f */
+ "umult r0","umult r1","umult r2", "umult r3", "umult r4", "umult r5", "umult r6", "umult r7",
+ "umult r8","umult r9","umult r10","umult r11","umult r12","umult r13","umult r14","umult r15",
+ /* 90 - 9f */
+ "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror",
+ "ljmp (r8)","ljmp (r9)","ljmp (r10)","ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult",
+ /* a0 - af */
+ "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)",
+ "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)",
+ "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)",
+ "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)",
+ /* b0 - bf */
+ "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7",
+ "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15",
+ /* c0 - cf */
+ "hib", "xor r1", "xor r2", "xor r3", "xor r4", "xor r5", "xor r6", "xor r7",
+ "xor r8", "xor r9", "xor r10", "xor r11", "xor r12", "xor r13", "xor r14", "xor r15",
+ /* d0 - df */
+ "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7",
+ "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc",
+ /* e0 - ef */
+ "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7",
+ "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbh",
+ /* f0 - ff */
+ "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)",
+ "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)",
+ "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)",
+ "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)",
+
+ /*
+ * ALT2 Table
+ */
+
+ /* 00 - 0f */
+ "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x",
+ "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x",
+ /* 10 - 1f */
+ "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7",
+ "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15",
+ /* 20 - 2f */
+ "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7",
+ "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15",
+ /* 30 - 3f */
+ "stw (r0)","stw (r1)","stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)",
+ "stw (r8)","stw (r9)","stw (r10)","stw (r11)","loop", "alt1", "alt2", "alt3",
+ /* 40 - 4f */
+ "ldw (r0)","ldw (r1)","ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)",
+ "ldw (r8)","ldw (r9)","ldw (r10)","ldw (r11)","plot", "swap", "color", "not",
+ /* 50 - 5f */
+ "add #0", "add #1", "add #2", "add #3", "add #4", "add #5", "add #6", "add #7",
+ "add #8", "add #9", "add #10", "add #11", "add #12", "add #13", "add #14", "add #15",
+ /* 60 - 6f */
+ "sub #0", "sub #1", "sub #2", "sub #3", "sub #4", "sub #5", "sub #6", "sub #7",
+ "sub #8", "sub #9", "sub #10", "sub #11", "sub #12", "sub #13", "sub #14", "sub #15",
+ /* 70 - 7f */
+ "merge", "and #1", "and #2", "and #3", "and #4", "and #5", "and #6", "and #7",
+ "and #8", "and #9", "and #10", "and #11", "and #12", "and #13", "and #14", "and #15",
+ /* 80 - 8f */
+ "mult #0", "mult #1", "mult #2", "mult #3", "mult #4", "mult #5", "mult #6", "mult #7",
+ "mult #8", "mult #9", "mult #10", "mult #11", "mult #12", "mult #13", "mult #14", "mult #15",
+ /* 90 - 9f */
+ "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror",
+ "jmp (r8)","jmp (r9)","jmp (r10)","jmp (r11)","jmp (r12)","jmp (r13)","lob", "fmult",
+ /* a0 - af */
+ "sms ($%04x),r0", "sms ($%04x),r1", "sms ($%04x),r2", "sms ($%04x),r3",
+ "sms ($%04x),r4", "sms ($%04x),r5", "sms ($%04x),r6", "sms ($%04x),r7",
+ "sms ($%04x),r8", "sms ($%04x),r9", "sms ($%04x),r10", "sms ($%04x),r11",
+ "sms ($%04x),r12", "sms ($%04x),r13", "sms ($%04x),r14", "sms ($%04x),r15",
+ /* b0 - bf */
+ "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7",
+ "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15",
+ /* c0 - cf */
+ "hib", "or #1", "or #2", "or #3", "or #4", "or #5", "or #6", "or #7",
+ "or #8", "or #9", "or #10", "or #11", "or #12", "or #13", "or #14", "or #15",
+ /* d0 - df */
+ "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7",
+ "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "ramb",
+ /* e0 - ef */
+ "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7",
+ "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbl",
+ /* f0 - ff */
+ "sm ($%04x),r0", "sm ($%04x),r1", "sm ($%04x),r2", "sm ($%04x),r3",
+ "sm ($%04x),r4", "sm ($%04x),r5", "sm ($%04x),r6", "sm ($%04x),r7",
+ "sm ($%04x),r8", "sm ($%04x),r9", "sm ($%04x),r10", "sm ($%04x),r11",
+ "sm ($%04x),r12", "sm ($%04x),r13", "sm ($%04x),r14", "sm ($%04x),r15",
+
+ /*
+ * ALT3 Table
+ */
+
+ /* 00 - 0f */
+ "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x",
+ "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x",
+ /* 10 - 1f */
+ "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7",
+ "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15",
+ /* 20 - 2f */
+ "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7",
+ "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15",
+ /* 30 - 3f */
+ "stb (r0)","stb (r1)","stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)",
+ "stb (r8)","stb (r9)","stb (r10)","stb (r11)","loop", "alt1", "alt2", "alt3",
+ /* 40 - 4f */
+ "ldb (r0)","ldb (r1)","ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)",
+ "ldb (r8)","ldb (r9)","ldb (r10)","ldb (r11)","rpix", "swap", "cmode", "not",
+ /* 50 - 5f */
+ "adc #0", "adc #1", "adc #2", "adc #3", "adc #4", "adc #5", "adc #6", "adc #7",
+ "adc #8", "adc #9", "adc #10", "adc #11", "adc #12", "adc #13", "adc #14", "adc #15",
+ /* 60 - 6f */
+ "cmp r0", "cmp r1", "cmp r2", "cmp r3", "cmp r4", "cmp r5", "cmp r6", "cmp r7",
+ "cmp r8", "cmp r9", "cmp r10", "cmp r11", "cmp r12", "cmp r13", "cmp r14", "cmp r15",
+ /* 70 - 7f */
+ "merge", "bic #1", "bic #2", "bic #3", "bic #4", "bic #5", "bic #6", "bic #7",
+ "bic #8", "bic #9", "bic #10", "bic #11", "bic #12", "bic #13", "bic #14", "bic #15",
+ /* 80 - 8f */
+ "umult #0","umult #1","umult #2", "umult #3", "umult #4", "umult #5", "umult #6", "umult #7",
+ "umult #8","umult #9","umult #10","umult #11","umult #12","umult #13","umult #14","umult #15",
+ /* 90 - 9f */
+ "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror",
+ "ljmp (r8)","ljmp (r9)","ljmp (r10)","ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult",
+ /* a0 - af */
+ "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)",
+ "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)",
+ "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)",
+ "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)",
+ /* b0 - bf */
+ "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7",
+ "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15",
+ /* c0 - cf */
+ "hib", "xor #1", "xor #2", "xor #3", "xor #4", "xor #5", "xor #6", "xor #7",
+ "xor #8", "xor #9", "xor #10", "xor #11", "xor #12", "xor #13", "xor #14", "xor #15",
+ /* d0 - df */
+ "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7",
+ "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "romb",
+ /* e0 - ef */
+ "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7",
+ "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbs",
+ /* f0 - ff */
+ "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)",
+ "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)",
+ "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)",
+ "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)",
+};
+
diff --git a/source/fxemu.cpp b/source/fxemu.cpp
new file mode 100644
index 0000000..8dd7a15
--- /dev/null
+++ b/source/fxemu.cpp
@@ -0,0 +1,726 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "fxemu.h"
+#include "fxinst.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/* The FxChip Emulator's internal variables */
+struct FxRegs_s GSU = FxRegs_s_null;
+
+uint32 (**fx_ppfFunctionTable)(uint32) = 0;
+void (**fx_ppfPlotTable)() = 0;
+void (**fx_ppfOpcodeTable)() = 0;
+
+#if 0
+void fx_setCache()
+{
+ uint32 c;
+ GSU.bCacheActive = TRUE;
+ GSU.pvRegisters[0x3e] &= 0xf0;
+ c = (uint32)GSU.pvRegisters[0x3e];
+ c |= ((uint32)GSU.pvRegisters[0x3f])<<8;
+ if(c == GSU.vCacheBaseReg)
+ return;
+ GSU.vCacheBaseReg = c;
+ GSU.vCacheFlags = 0;
+ if(c < (0x10000-512))
+ {
+ uint8 const* t = &ROM(c);
+ memcpy(GSU.pvCache,t,512);
+ }
+ else
+ {
+ uint8 const* t1;
+ uint8 const* t2;
+ uint32 i = 0x10000 - c;
+ t1 = &ROM(c);
+ t2 = &ROM(0);
+ memcpy(GSU.pvCache,t1,i);
+ memcpy(&GSU.pvCache[i],t2,512-i);
+ }
+}
+#endif
+
+void FxCacheWriteAccess(uint16 vAddress)
+{
+#if 0
+ if(!GSU.bCacheActive)
+ {
+ uint8 v = GSU.pvCache[GSU.pvCache[vAddress&0x1ff];
+ fx_setCache();
+ GSU.pvCache[GSU.pvCache[vAddress&0x1ff] = v;
+ }
+#endif
+ if((vAddress & 0x00f) == 0x00f)
+ GSU.vCacheFlags |= 1 << ((vAddress&0x1f0) >> 4);
+}
+
+void FxFlushCache()
+{
+ GSU.vCacheFlags = 0;
+ GSU.vCacheBaseReg = 0;
+ GSU.bCacheActive = FALSE;
+// GSU.vPipe = 0x1;
+}
+
+static void fx_backupCache()
+{
+#if 0
+ uint32 i;
+ uint32 v = GSU.vCacheFlags;
+ uint32 c = USEX16(GSU.vCacheBaseReg);
+ if(v)
+ for(i=0; i<32; i++)
+ {
+ if(v&1)
+ {
+ if(c < (0x10000-16))
+ {
+ uint8 * t = &GSU.pvPrgBank[c];
+ memcpy(&GSU.avCacheBackup[i<<4],t,16);
+ memcpy(t,&GSU.pvCache[i<<4],16);
+ }
+ else
+ {
+ uint8 * t1;
+ uint8 * t2;
+ uint32 a = 0x10000 - c;
+ t1 = &GSU.pvPrgBank[c];
+ t2 = &GSU.pvPrgBank[0];
+ memcpy(&GSU.avCacheBackup[i<<4],t1,a);
+ memcpy(t1,&GSU.pvCache[i<<4],a);
+ memcpy(&GSU.avCacheBackup[(i<<4)+a],t2,16-a);
+ memcpy(t2,&GSU.pvCache[(i<<4)+a],16-a);
+ }
+ }
+ c = USEX16(c+16);
+ v >>= 1;
+ }
+#endif
+}
+
+static void fx_restoreCache()
+{
+#if 0
+ uint32 i;
+ uint32 v = GSU.vCacheFlags;
+ uint32 c = USEX16(GSU.vCacheBaseReg);
+ if(v)
+ for(i=0; i<32; i++)
+ {
+ if(v&1)
+ {
+ if(c < (0x10000-16))
+ {
+ uint8 * t = &GSU.pvPrgBank[c];
+ memcpy(t,&GSU.avCacheBackup[i<<4],16);
+ memcpy(&GSU.pvCache[i<<4],t,16);
+ }
+ else
+ {
+ uint8 * t1;
+ uint8 * t2;
+ uint32 a = 0x10000 - c;
+ t1 = &GSU.pvPrgBank[c];
+ t2 = &GSU.pvPrgBank[0];
+ memcpy(t1,&GSU.avCacheBackup[i<<4],a);
+ memcpy(&GSU.pvCache[i<<4],t1,a);
+ memcpy(t2,&GSU.avCacheBackup[(i<<4)+a],16-a);
+ memcpy(&GSU.pvCache[(i<<4)+a],t2,16-a);
+ }
+ }
+ c = USEX16(c+16);
+ v >>= 1;
+ }
+#endif
+}
+
+void fx_flushCache()
+{
+ fx_restoreCache();
+ GSU.vCacheFlags = 0;
+ GSU.bCacheActive = FALSE;
+}
+
+
+void fx_updateRamBank(uint8 Byte)
+{
+ // Update BankReg and Bank pointer
+ GSU.vRamBankReg = (uint32)Byte & (FX_RAM_BANKS-1);
+ GSU.pvRamBank = GSU.apvRamBank[Byte & 0x3];
+}
+
+
+static void fx_readRegisterSpace()
+{
+ int i;
+ uint8 *p;
+ static uint32 avHeight[] = { 128, 160, 192, 256 };
+ static uint32 avMult[] = { 16, 32, 32, 64 };
+
+ GSU.vErrorCode = 0;
+
+ /* Update R0-R15 */
+ p = GSU.pvRegisters;
+ for(i=0; i<16; i++)
+ {
+ GSU.avReg[i] = *p++;
+ GSU.avReg[i] += ((uint32)(*p++)) << 8;
+ }
+
+ /* Update other registers */
+ p = GSU.pvRegisters;
+ GSU.vStatusReg = (uint32)p[GSU_SFR];
+ GSU.vStatusReg |= ((uint32)p[GSU_SFR+1]) << 8;
+ GSU.vPrgBankReg = (uint32)p[GSU_PBR];
+ GSU.vRomBankReg = (uint32)p[GSU_ROMBR];
+ GSU.vRamBankReg = ((uint32)p[GSU_RAMBR]) & (FX_RAM_BANKS-1);
+ GSU.vCacheBaseReg = (uint32)p[GSU_CBR];
+ GSU.vCacheBaseReg |= ((uint32)p[GSU_CBR+1]) << 8;
+
+ /* Update status register variables */
+ GSU.vZero = !(GSU.vStatusReg & FLG_Z);
+ GSU.vSign = (GSU.vStatusReg & FLG_S) << 12;
+ GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16;
+ GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2;
+
+ /* Set bank pointers */
+ GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3];
+ GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg];
+ GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg];
+
+ /* Set screen pointers */
+ GSU.pvScreenBase = &GSU.pvRam[ USEX8(p[GSU_SCBR]) << 10 ];
+ i = (int)(!!(p[GSU_SCMR] & 0x04));
+ i |= ((int)(!!(p[GSU_SCMR] & 0x20))) << 1;
+ GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[i];
+ GSU.vMode = p[GSU_SCMR] & 0x03;
+#if 0
+ if(GSU.vMode == 2)
+ error illegal color depth GSU.vMode;
+#endif
+ if(i == 3)
+ GSU.vScreenSize = (256/8) * (256/8) * 32;
+ else
+ GSU.vScreenSize = (GSU.vScreenHeight/8) * (256/8) * avMult[GSU.vMode];
+ if (GSU.vPlotOptionReg & 0x10)
+ {
+ /* OBJ Mode (for drawing into sprites) */
+ GSU.vScreenHeight = 256;
+ }
+#if 0
+ if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
+ error illegal address for screen base register
+#else
+ if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
+ GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize;
+#endif
+ GSU.pfPlot = fx_apfPlotTable[GSU.vMode];
+ GSU.pfRpix = fx_apfPlotTable[GSU.vMode + 5];
+
+ fx_ppfOpcodeTable[0x04c] = GSU.pfPlot;
+ fx_ppfOpcodeTable[0x14c] = GSU.pfRpix;
+ fx_ppfOpcodeTable[0x24c] = GSU.pfPlot;
+ fx_ppfOpcodeTable[0x34c] = GSU.pfRpix;
+
+ fx_computeScreenPointers ();
+
+ fx_backupCache();
+}
+
+void fx_dirtySCBR()
+{
+ GSU.vSCBRDirty = TRUE;
+}
+
+void fx_computeScreenPointers ()
+{
+ if (GSU.vMode != GSU.vPrevMode ||
+ GSU.vPrevScreenHeight != GSU.vScreenHeight ||
+ GSU.vSCBRDirty)
+ {
+ int i;
+
+ GSU.vSCBRDirty = FALSE;
+
+ /* Make a list of pointers to the start of each screen column */
+ switch (GSU.vScreenHeight)
+ {
+ case 128:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
+ GSU.x[i] = i << 8;
+ }
+ break;
+ case 1:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
+ GSU.x[i] = i << 9;
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
+ GSU.x[i] = i << 10;
+ }
+ break;
+ }
+ break;
+ case 160:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
+ GSU.x[i] = (i << 8) + (i << 6);
+ }
+ break;
+ case 1:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
+ GSU.x[i] = (i << 9) + (i << 7);
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
+ GSU.x[i] = (i << 10) + (i << 8);
+ }
+ break;
+ }
+ break;
+ case 192:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
+ GSU.x[i] = (i << 8) + (i << 7);
+ }
+ break;
+ case 1:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
+ GSU.x[i] = (i << 9) + (i << 8);
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
+ GSU.x[i] = (i << 10) + (i << 9);
+ }
+ break;
+ }
+ break;
+ case 256:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase +
+ ((i & 0x10) << 9) + ((i & 0xf) << 8);
+ GSU.x[i] = ((i & 0x10) << 8) + ((i & 0xf) << 4);
+ }
+ break;
+ case 1:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase +
+ ((i & 0x10) << 10) + ((i & 0xf) << 9);
+ GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5);
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase +
+ ((i & 0x10) << 11) + ((i & 0xf) << 10);
+ GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6);
+ }
+ break;
+ }
+ break;
+ }
+ GSU.vPrevMode = GSU.vMode;
+ GSU.vPrevScreenHeight = GSU.vScreenHeight;
+ }
+}
+
+static void fx_writeRegisterSpace()
+{
+ int i;
+ uint8 *p;
+
+ p = GSU.pvRegisters;
+ for(i=0; i<16; i++)
+ {
+ *p++ = (uint8)GSU.avReg[i];
+ *p++ = (uint8)(GSU.avReg[i] >> 8);
+ }
+
+ /* Update status register */
+ if( USEX16(GSU.vZero) == 0 ) SF(Z);
+ else CF(Z);
+ if( GSU.vSign & 0x8000 ) SF(S);
+ else CF(S);
+ if(GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000) SF(OV);
+ else CF(OV);
+ if(GSU.vCarry) SF(CY);
+ else CF(CY);
+
+ p = GSU.pvRegisters;
+ p[GSU_SFR] = (uint8)GSU.vStatusReg;
+ p[GSU_SFR+1] = (uint8)(GSU.vStatusReg>>8);
+ p[GSU_PBR] = (uint8)GSU.vPrgBankReg;
+ p[GSU_ROMBR] = (uint8)GSU.vRomBankReg;
+ p[GSU_RAMBR] = (uint8)GSU.vRamBankReg;
+ p[GSU_CBR] = (uint8)GSU.vCacheBaseReg;
+ p[GSU_CBR+1] = (uint8)(GSU.vCacheBaseReg>>8);
+
+ fx_restoreCache();
+}
+
+/* Reset the FxChip */
+void FxReset(struct FxInit_s *psFxInfo)
+{
+ int i;
+ static uint32 (**appfFunction[])(uint32) = {
+ &fx_apfFunctionTable[0],
+#if 0
+ &fx_a_apfFunctionTable[0],
+ &fx_r_apfFunctionTable[0],
+ &fx_ar_apfFunctionTable[0],
+#endif
+ };
+ static void (**appfPlot[])() = {
+ &fx_apfPlotTable[0],
+#if 0
+ &fx_a_apfPlotTable[0],
+ &fx_r_apfPlotTable[0],
+ &fx_ar_apfPlotTable[0],
+#endif
+ };
+ static void (**appfOpcode[])() = {
+ &fx_apfOpcodeTable[0],
+#if 0
+ &fx_a_apfOpcodeTable[0],
+ &fx_r_apfOpcodeTable[0],
+ &fx_ar_apfOpcodeTable[0],
+#endif
+ };
+
+ /* Get function pointers for the current emulation mode */
+ fx_ppfFunctionTable = appfFunction[psFxInfo->vFlags & 0x3];
+ fx_ppfPlotTable = appfPlot[psFxInfo->vFlags & 0x3];
+ fx_ppfOpcodeTable = appfOpcode[psFxInfo->vFlags & 0x3];
+
+ /* Clear all internal variables */
+ memset((uint8*)&GSU,0,sizeof(struct FxRegs_s));
+
+ /* Set default registers */
+ GSU.pvSreg = GSU.pvDreg = &R0;
+
+ /* Set RAM and ROM pointers */
+ GSU.pvRegisters = psFxInfo->pvRegisters;
+ GSU.nRamBanks = psFxInfo->nRamBanks;
+ GSU.pvRam = psFxInfo->pvRam;
+ GSU.nRomBanks = psFxInfo->nRomBanks;
+ GSU.pvRom = psFxInfo->pvRom;
+ GSU.vPrevScreenHeight = ~0;
+ GSU.vPrevMode = ~0;
+
+ /* The GSU can't access more than 2mb (16mbits) */
+ if(GSU.nRomBanks > 0x20)
+ GSU.nRomBanks = 0x20;
+
+ /* Clear FxChip register space */
+ memset(GSU.pvRegisters,0,0x300);
+
+ /* Set FxChip version Number */
+ GSU.pvRegisters[0x3b] = 0;
+
+ /* Make ROM bank table */
+ for(i=0; i<256; i++)
+ {
+ uint32 b = i & 0x7f;
+ if (b >= 0x40)
+ {
+ if (GSU.nRomBanks > 1)
+ b %= GSU.nRomBanks;
+ else
+ b &= 1;
+
+ GSU.apvRomBank[i] = &GSU.pvRom[ b << 16 ];
+ }
+ else
+ {
+ b %= GSU.nRomBanks * 2;
+ GSU.apvRomBank[i] = &GSU.pvRom[ (b << 16) + 0x200000];
+ }
+ }
+
+ /* Make RAM bank table */
+ for(i=0; i<4; i++)
+ {
+ GSU.apvRamBank[i] = &GSU.pvRam[(i % GSU.nRamBanks) << 16];
+ GSU.apvRomBank[0x70 + i] = GSU.apvRamBank[i];
+ }
+
+ /* Start with a nop in the pipe */
+ GSU.vPipe = 0x01;
+
+ /* Set pointer to GSU cache */
+ GSU.pvCache = &GSU.pvRegisters[0x100];
+
+ fx_readRegisterSpace();
+}
+
+static uint8 fx_checkStartAddress()
+{
+ /* Check if we start inside the cache */
+ if(GSU.bCacheActive && R15 >= GSU.vCacheBaseReg && R15 < (GSU.vCacheBaseReg+512))
+ return TRUE;
+
+ /* Check if we're in an unused area */
+ if(GSU.vPrgBankReg < 0x40 && R15 < 0x8000)
+ return FALSE;
+ if(GSU.vPrgBankReg >= 0x60 && GSU.vPrgBankReg <= 0x6f)
+ return FALSE;
+ if(GSU.vPrgBankReg >= 0x74)
+ return FALSE;
+
+ /* Check if we're in RAM and the RAN flag is not set */
+ if(GSU.vPrgBankReg >= 0x70 && GSU.vPrgBankReg <= 0x73 && !(SCMR&(1<<3)) )
+ return FALSE;
+
+ /* If not, we're in ROM, so check if the RON flag is set */
+ if(!(SCMR&(1<<4)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Execute until the next stop instruction */
+int FxEmulate(uint32 nInstructions)
+{
+ uint32 vCount;
+
+ /* Read registers and initialize GSU session */
+ fx_readRegisterSpace();
+
+ /* Check if the start address is valid */
+ if(!fx_checkStartAddress())
+ {
+ CF(G);
+ fx_writeRegisterSpace();
+#if 0
+ GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;
+ return FX_ERROR_ILLEGAL_ADDRESS;
+#else
+ return 0;
+#endif
+ }
+
+ /* Execute GSU session */
+ CF(IRQ);
+
+ if(GSU.bBreakPoint)
+ vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN_TO_BREAKPOINT](nInstructions);
+ else
+ vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN](nInstructions);
+
+ /* Store GSU registers */
+ fx_writeRegisterSpace();
+
+ /* Check for error code */
+ if(GSU.vErrorCode)
+ return GSU.vErrorCode;
+ else
+ return vCount;
+}
+
+/* Breakpoints */
+void FxBreakPointSet(uint32 vAddress)
+{
+ GSU.bBreakPoint = TRUE;
+ GSU.vBreakPoint = USEX16(vAddress);
+}
+void FxBreakPointClear()
+{
+ GSU.bBreakPoint = FALSE;
+}
+
+/* Step by step execution */
+int FxStepOver(uint32 nInstructions)
+{
+ uint32 vCount;
+ fx_readRegisterSpace();
+
+ /* Check if the start address is valid */
+ if(!fx_checkStartAddress())
+ {
+ CF(G);
+#if 0
+ GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;
+ return FX_ERROR_ILLEGAL_ADDRESS;
+#else
+ return 0;
+#endif
+ }
+
+ if( PIPE >= 0xf0 )
+ GSU.vStepPoint = USEX16(R15+3);
+ else if( (PIPE >= 0x05 && PIPE <= 0x0f) || (PIPE >= 0xa0 && PIPE <= 0xaf) )
+ GSU.vStepPoint = USEX16(R15+2);
+ else
+ GSU.vStepPoint = USEX16(R15+1);
+ vCount = fx_ppfFunctionTable[FX_FUNCTION_STEP_OVER](nInstructions);
+ fx_writeRegisterSpace();
+ if(GSU.vErrorCode)
+ return GSU.vErrorCode;
+ else
+ return vCount;
+}
+
+/* Errors */
+int FxGetErrorCode()
+{
+ return GSU.vErrorCode;
+}
+
+int FxGetIllegalAddress()
+{
+ return GSU.vIllegalAddress;
+}
+
+/* Access to internal registers */
+uint32 FxGetColorRegister()
+{
+ return GSU.vColorReg & 0xff;
+}
+
+uint32 FxGetPlotOptionRegister()
+{
+ return GSU.vPlotOptionReg & 0x1f;
+}
+
+uint32 FxGetSourceRegisterIndex()
+{
+ return GSU.pvSreg - GSU.avReg;
+}
+
+uint32 FxGetDestinationRegisterIndex()
+{
+ return GSU.pvDreg - GSU.avReg;
+}
+
+uint8 FxPipe()
+{
+ return GSU.vPipe;
+}
+
diff --git a/source/fxemu.h b/source/fxemu.h
new file mode 100644
index 0000000..270ea5c
--- /dev/null
+++ b/source/fxemu.h
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _FXEMU_H_
+#define _FXEMU_H_ 1
+
+/* Types used by structures and code */
+#ifndef snes9x_types_defined
+#define snes9x_types_defined
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned char bool8;
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator */
+struct FxInit_s
+{
+ uint32 vFlags;
+ uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */
+ uint32 nRamBanks; /* Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73) */
+ uint8 * pvRam; /* Pointer to GSU-RAM */
+ uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */
+ uint8 * pvRom; /* Pointer to Cart-ROM */
+};
+
+/* Reset the FxChip */
+extern void FxReset(struct FxInit_s *psFxInfo);
+
+/* Execute until the next stop instruction */
+extern int FxEmulate(uint32 nInstructions);
+
+/* Write access to the cache */
+extern void FxCacheWriteAccess(uint16 vAddress);
+extern void FxFlushCache(); /* Callled when the G flag in SFR is set to zero */
+
+/* Breakpoint */
+extern void FxBreakPointSet(uint32 vAddress);
+extern void FxBreakPointClear();
+
+/* Step by step execution */
+extern int FxStepOver(uint32 nInstructions);
+
+/* Errors */
+extern int FxGetErrorCode();
+extern int FxGetIllegalAddress();
+
+/* Access to internal registers */
+extern uint32 FxGetColorRegister();
+extern uint32 FxGetPlotOptionRegister();
+extern uint32 FxGetSourceRegisterIndex();
+extern uint32 FxGetDestinationRegisterIndex();
+
+/* Get string for opcode currently in the pipe */
+extern void FxPipeString(char * pvString);
+
+/* Get the byte currently in the pipe */
+extern uint8 FxPipe();
+
+/* SCBR write seen. We need to update our cached screen pointers */
+extern void fx_dirtySCBR (void);
+
+/* Update RamBankReg and RAM Bank pointer */
+extern void fx_updateRamBank(uint8 Byte);
+
+/* Option flags */
+#define FX_FLAG_ADDRESS_CHECKING 0x01
+#define FX_FLAG_ROM_BUFFER 0x02
+
+/* Return codes from FxEmulate(), FxStepInto() or FxStepOver() */
+#define FX_BREAKPOINT -1
+#define FX_ERROR_ILLEGAL_ADDRESS -2
+
+/* Return the number of bytes in an opcode */
+#define OPCODE_BYTES(op) ((((op)>=0x05&&(op)<=0xf)||((op)>=0xa0&&(op)<=0xaf))?2:(((op)>=0xf0)?3:1))
+
+extern void fx_computeScreenPointers ();
+
+#endif
+
diff --git a/source/fxinst.cpp b/source/fxinst.cpp
new file mode 100644
index 0000000..a5cdf01
--- /dev/null
+++ b/source/fxinst.cpp
@@ -0,0 +1,1916 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#define FX_DO_ROMBUFFER
+
+#include "fxemu.h"
+#include "fxinst.h"
+#include <string.h>
+#include <stdio.h>
+
+extern struct FxRegs_s GSU;
+int gsu_bank [512] = {0};
+
+/* Set this define if you wish the plot instruction to check for y-pos limits */
+/* (I don't think it's nessecary) */
+#define CHECK_LIMITS
+
+/* Codes used:
+ *
+ * rn = a GSU register (r0-r15)
+ * #n = 4 bit immediate value
+ * #pp = 8 bit immediate value
+ * (yy) = 8 bit word address (0x0000 - 0x01fe)
+ * #xx = 16 bit immediate value
+ * (xx) = 16 bit address (0x0000 - 0xffff)
+ *
+ */
+
+/* 00 - stop - stop GSU execution (and maybe generate an IRQ) */
+static void fx_stop()
+{
+ CF(G);
+ GSU.vCounter = 0;
+ GSU.vInstCount = GSU.vCounter;
+
+ /* Check if we need to generate an IRQ */
+ if(!(GSU.pvRegisters[GSU_CFGR] & 0x80))
+ SF(IRQ);
+
+ GSU.vPlotOptionReg = 0;
+ GSU.vPipe = 1;
+ CLRFLAGS;
+ R15++;
+}
+
+/* 01 - nop - no operation */
+static void fx_nop() { CLRFLAGS; R15++; }
+
+extern void fx_flushCache();
+
+/* 02 - cache - reintialize GSU cache */
+static void fx_cache()
+{
+ uint32 c = R15 & 0xfff0;
+ if(GSU.vCacheBaseReg != c || !GSU.bCacheActive)
+ {
+ fx_flushCache();
+ GSU.vCacheBaseReg = c;
+ GSU.bCacheActive = TRUE;
+#if 0
+ if(c < (0x10000-512))
+ {
+ uint8 const* t = &ROM(c);
+ memcpy(GSU.pvCache,t,512);
+ }
+ else
+ {
+ uint8 const* t1;
+ uint8 const* t2;
+ uint32 i = 0x10000 - c;
+ t1 = &ROM(c);
+ t2 = &ROM(0);
+ memcpy(GSU.pvCache,t1,i);
+ memcpy(&GSU.pvCache[i],t2,512-i);
+ }
+#endif
+ }
+ R15++;
+ CLRFLAGS;
+}
+
+/* 03 - lsr - logic shift right */
+static void fx_lsr()
+{
+ uint32 v;
+ GSU.vCarry = SREG & 1;
+ v = USEX16(SREG) >> 1;
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 04 - rol - rotate left */
+static void fx_rol()
+{
+ uint32 v = USEX16((SREG << 1) + GSU.vCarry);
+ GSU.vCarry = (SREG >> 15) & 1;
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 05 - bra - branch always */
+static void fx_bra() { uint8 v = PIPE; R15++; FETCHPIPE; R15 += SEX8(v); }
+
+/* Branch on condition */
+#define BRA_COND(cond) uint8 v = PIPE; R15++; FETCHPIPE; if(cond) R15 += SEX8(v); else R15++;
+
+#define TEST_S (GSU.vSign & 0x8000)
+#define TEST_Z (USEX16(GSU.vZero) == 0)
+#define TEST_OV (GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000)
+#define TEST_CY (GSU.vCarry & 1)
+
+/* 06 - blt - branch on less than */
+static void fx_blt() { BRA_COND( (TEST_S!=0) != (TEST_OV!=0) ); }
+
+/* 07 - bge - branch on greater or equals */
+static void fx_bge() { BRA_COND( (TEST_S!=0) == (TEST_OV!=0)); }
+
+/* 08 - bne - branch on not equal */
+static void fx_bne() { BRA_COND( !TEST_Z ); }
+
+/* 09 - beq - branch on equal */
+static void fx_beq() { BRA_COND( TEST_Z ); }
+
+/* 0a - bpl - branch on plus */
+static void fx_bpl() { BRA_COND( !TEST_S ); }
+
+/* 0b - bmi - branch on minus */
+static void fx_bmi() { BRA_COND( TEST_S ); }
+
+/* 0c - bcc - branch on carry clear */
+static void fx_bcc() { BRA_COND( !TEST_CY ); }
+
+/* 0d - bcs - branch on carry set */
+static void fx_bcs() { BRA_COND( TEST_CY ); }
+
+/* 0e - bvc - branch on overflow clear */
+static void fx_bvc() { BRA_COND( !TEST_OV ); }
+
+/* 0f - bvs - branch on overflow set */
+static void fx_bvs() { BRA_COND( TEST_OV ); }
+
+/* 10-1f - to rn - set register n as destination register */
+/* 10-1f(B) - move rn - move one register to another (if B flag is set) */
+#define FX_TO(reg) \
+if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \
+else { GSU.pvDreg = &GSU.avReg[reg]; } R15++;
+#define FX_TO_R14(reg) \
+if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; READR14; } \
+else { GSU.pvDreg = &GSU.avReg[reg]; } R15++;
+#define FX_TO_R15(reg) \
+if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \
+else { GSU.pvDreg = &GSU.avReg[reg]; R15++; }
+static void fx_to_r0() { FX_TO(0); }
+static void fx_to_r1() { FX_TO(1); }
+static void fx_to_r2() { FX_TO(2); }
+static void fx_to_r3() { FX_TO(3); }
+static void fx_to_r4() { FX_TO(4); }
+static void fx_to_r5() { FX_TO(5); }
+static void fx_to_r6() { FX_TO(6); }
+static void fx_to_r7() { FX_TO(7); }
+static void fx_to_r8() { FX_TO(8); }
+static void fx_to_r9() { FX_TO(9); }
+static void fx_to_r10() { FX_TO(10); }
+static void fx_to_r11() { FX_TO(11); }
+static void fx_to_r12() { FX_TO(12); }
+static void fx_to_r13() { FX_TO(13); }
+static void fx_to_r14() { FX_TO_R14(14); }
+static void fx_to_r15() { FX_TO_R15(15); }
+
+/* 20-2f - to rn - set register n as source and destination register */
+#define FX_WITH(reg) SF(B); GSU.pvSreg = GSU.pvDreg = &GSU.avReg[reg]; R15++;
+static void fx_with_r0() { FX_WITH(0); }
+static void fx_with_r1() { FX_WITH(1); }
+static void fx_with_r2() { FX_WITH(2); }
+static void fx_with_r3() { FX_WITH(3); }
+static void fx_with_r4() { FX_WITH(4); }
+static void fx_with_r5() { FX_WITH(5); }
+static void fx_with_r6() { FX_WITH(6); }
+static void fx_with_r7() { FX_WITH(7); }
+static void fx_with_r8() { FX_WITH(8); }
+static void fx_with_r9() { FX_WITH(9); }
+static void fx_with_r10() { FX_WITH(10); }
+static void fx_with_r11() { FX_WITH(11); }
+static void fx_with_r12() { FX_WITH(12); }
+static void fx_with_r13() { FX_WITH(13); }
+static void fx_with_r14() { FX_WITH(14); }
+static void fx_with_r15() { FX_WITH(15); }
+
+/* 30-3b - stw (rn) - store word */
+#define FX_STW(reg) \
+GSU.vLastRamAdr = GSU.avReg[reg]; \
+RAM(GSU.avReg[reg]) = (uint8)SREG; \
+RAM(GSU.avReg[reg]^1) = (uint8)(SREG>>8); \
+CLRFLAGS; R15++
+static void fx_stw_r0() { FX_STW(0); }
+static void fx_stw_r1() { FX_STW(1); }
+static void fx_stw_r2() { FX_STW(2); }
+static void fx_stw_r3() { FX_STW(3); }
+static void fx_stw_r4() { FX_STW(4); }
+static void fx_stw_r5() { FX_STW(5); }
+static void fx_stw_r6() { FX_STW(6); }
+static void fx_stw_r7() { FX_STW(7); }
+static void fx_stw_r8() { FX_STW(8); }
+static void fx_stw_r9() { FX_STW(9); }
+static void fx_stw_r10() { FX_STW(10); }
+static void fx_stw_r11() { FX_STW(11); }
+
+/* 30-3b(ALT1) - stb (rn) - store byte */
+#define FX_STB(reg) \
+GSU.vLastRamAdr = GSU.avReg[reg]; \
+RAM(GSU.avReg[reg]) = (uint8)SREG; \
+CLRFLAGS; R15++
+static void fx_stb_r0() { FX_STB(0); }
+static void fx_stb_r1() { FX_STB(1); }
+static void fx_stb_r2() { FX_STB(2); }
+static void fx_stb_r3() { FX_STB(3); }
+static void fx_stb_r4() { FX_STB(4); }
+static void fx_stb_r5() { FX_STB(5); }
+static void fx_stb_r6() { FX_STB(6); }
+static void fx_stb_r7() { FX_STB(7); }
+static void fx_stb_r8() { FX_STB(8); }
+static void fx_stb_r9() { FX_STB(9); }
+static void fx_stb_r10() { FX_STB(10); }
+static void fx_stb_r11() { FX_STB(11); }
+
+/* 3c - loop - decrement loop counter, and branch on not zero */
+static void fx_loop()
+{
+ GSU.vSign = GSU.vZero = --R12;
+ if( (uint16) R12 != 0 )
+ R15 = R13;
+ else
+ R15++;
+
+ CLRFLAGS;
+}
+
+/* 3d - alt1 - set alt1 mode */
+static void fx_alt1() { SF(ALT1); CF(B); R15++; }
+
+/* 3e - alt2 - set alt2 mode */
+static void fx_alt2() { SF(ALT2); CF(B); R15++; }
+
+/* 3f - alt3 - set alt3 mode */
+static void fx_alt3() { SF(ALT1); SF(ALT2); CF(B); R15++; }
+
+/* 40-4b - ldw (rn) - load word from RAM */
+#define FX_LDW(reg) uint32 v; \
+GSU.vLastRamAdr = GSU.avReg[reg]; \
+v = (uint32)RAM(GSU.avReg[reg]); \
+v |= ((uint32)RAM(GSU.avReg[reg]^1))<<8; \
+R15++; DREG = v; \
+TESTR14; \
+CLRFLAGS
+static void fx_ldw_r0() { FX_LDW(0); }
+static void fx_ldw_r1() { FX_LDW(1); }
+static void fx_ldw_r2() { FX_LDW(2); }
+static void fx_ldw_r3() { FX_LDW(3); }
+static void fx_ldw_r4() { FX_LDW(4); }
+static void fx_ldw_r5() { FX_LDW(5); }
+static void fx_ldw_r6() { FX_LDW(6); }
+static void fx_ldw_r7() { FX_LDW(7); }
+static void fx_ldw_r8() { FX_LDW(8); }
+static void fx_ldw_r9() { FX_LDW(9); }
+static void fx_ldw_r10() { FX_LDW(10); }
+static void fx_ldw_r11() { FX_LDW(11); }
+
+/* 40-4b(ALT1) - ldb (rn) - load byte */
+#define FX_LDB(reg) uint32 v; \
+GSU.vLastRamAdr = GSU.avReg[reg]; \
+v = (uint32)RAM(GSU.avReg[reg]); \
+R15++; DREG = v; \
+TESTR14; \
+CLRFLAGS
+static void fx_ldb_r0() { FX_LDB(0); }
+static void fx_ldb_r1() { FX_LDB(1); }
+static void fx_ldb_r2() { FX_LDB(2); }
+static void fx_ldb_r3() { FX_LDB(3); }
+static void fx_ldb_r4() { FX_LDB(4); }
+static void fx_ldb_r5() { FX_LDB(5); }
+static void fx_ldb_r6() { FX_LDB(6); }
+static void fx_ldb_r7() { FX_LDB(7); }
+static void fx_ldb_r8() { FX_LDB(8); }
+static void fx_ldb_r9() { FX_LDB(9); }
+static void fx_ldb_r10() { FX_LDB(10); }
+static void fx_ldb_r11() { FX_LDB(11); }
+
+/* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */
+static void fx_plot_2bit()
+{
+ uint32 x = USEX8(R1);
+ uint32 y = USEX8(R2);
+ uint8 *a;
+ uint8 v,c;
+
+ R15++;
+ CLRFLAGS;
+ R1++;
+
+#ifdef CHECK_LIMITS
+ if(y >= GSU.vScreenHeight) return;
+#endif
+ if(GSU.vPlotOptionReg & 0x02)
+ c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg;
+ else
+ c = (uint8)GSU.vColorReg;
+
+ if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return;
+ a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1);
+ v = 128 >> (x&7);
+
+ if(c & 0x01) a[0] |= v;
+ else a[0] &= ~v;
+ if(c & 0x02) a[1] |= v;
+ else a[1] &= ~v;
+}
+
+/* 2c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */
+static void fx_rpix_2bit()
+{
+ uint32 x = USEX8(R1);
+ uint32 y = USEX8(R2);
+ uint8 *a;
+ uint8 v;
+
+ R15++;
+ CLRFLAGS;
+#ifdef CHECK_LIMITS
+ if(y >= GSU.vScreenHeight) return;
+#endif
+
+ a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1);
+ v = 128 >> (x&7);
+
+ DREG = 0;
+ DREG |= ((uint32)((a[0] & v) != 0)) << 0;
+ DREG |= ((uint32)((a[1] & v) != 0)) << 1;
+ TESTR14;
+}
+
+/* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */
+static void fx_plot_4bit()
+{
+ uint32 x = USEX8(R1);
+ uint32 y = USEX8(R2);
+ uint8 *a;
+ uint8 v,c;
+
+ R15++;
+ CLRFLAGS;
+ R1++;
+
+#ifdef CHECK_LIMITS
+ if(y >= GSU.vScreenHeight) return;
+#endif
+ if(GSU.vPlotOptionReg & 0x02)
+ c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg;
+ else
+ c = (uint8)GSU.vColorReg;
+
+ if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return;
+
+ a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1);
+ v = 128 >> (x&7);
+
+ if(c & 0x01) a[0x00] |= v;
+ else a[0x00] &= ~v;
+ if(c & 0x02) a[0x01] |= v;
+ else a[0x01] &= ~v;
+ if(c & 0x04) a[0x10] |= v;
+ else a[0x10] &= ~v;
+ if(c & 0x08) a[0x11] |= v;
+ else a[0x11] &= ~v;
+}
+
+/* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */
+static void fx_rpix_4bit()
+{
+ uint32 x = USEX8(R1);
+ uint32 y = USEX8(R2);
+ uint8 *a;
+ uint8 v;
+
+ R15++;
+ CLRFLAGS;
+
+#ifdef CHECK_LIMITS
+ if(y >= GSU.vScreenHeight) return;
+#endif
+
+ a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1);
+ v = 128 >> (x&7);
+
+ DREG = 0;
+ DREG |= ((uint32)((a[0x00] & v) != 0)) << 0;
+ DREG |= ((uint32)((a[0x01] & v) != 0)) << 1;
+ DREG |= ((uint32)((a[0x10] & v) != 0)) << 2;
+ DREG |= ((uint32)((a[0x11] & v) != 0)) << 3;
+ TESTR14;
+}
+
+/* 8c - plot - plot pixel with R1,R2 as x,y and the color register as the color */
+static void fx_plot_8bit()
+{
+ uint32 x = USEX8(R1);
+ uint32 y = USEX8(R2);
+ uint8 *a;
+ uint8 v,c;
+
+ R15++;
+ CLRFLAGS;
+ R1++;
+
+#ifdef CHECK_LIMITS
+ if(y >= GSU.vScreenHeight) return;
+#endif
+ c = (uint8)GSU.vColorReg;
+ if( !(GSU.vPlotOptionReg & 0x10) )
+ {
+ if( !(GSU.vPlotOptionReg & 0x01) && !(c&0xf)) return;
+ }
+ else
+ if( !(GSU.vPlotOptionReg & 0x01) && !c) return;
+
+ a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1);
+ v = 128 >> (x&7);
+
+ if(c & 0x01) a[0x00] |= v;
+ else a[0x00] &= ~v;
+ if(c & 0x02) a[0x01] |= v;
+ else a[0x01] &= ~v;
+ if(c & 0x04) a[0x10] |= v;
+ else a[0x10] &= ~v;
+ if(c & 0x08) a[0x11] |= v;
+ else a[0x11] &= ~v;
+ if(c & 0x10) a[0x20] |= v;
+ else a[0x20] &= ~v;
+ if(c & 0x20) a[0x21] |= v;
+ else a[0x21] &= ~v;
+ if(c & 0x40) a[0x30] |= v;
+ else a[0x30] &= ~v;
+ if(c & 0x80) a[0x31] |= v;
+ else a[0x31] &= ~v;
+}
+
+/* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */
+static void fx_rpix_8bit()
+{
+ uint32 x = USEX8(R1);
+ uint32 y = USEX8(R2);
+ uint8 *a;
+ uint8 v;
+
+ R15++;
+ CLRFLAGS;
+
+#ifdef CHECK_LIMITS
+ if(y >= GSU.vScreenHeight) return;
+#endif
+ a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1);
+ v = 128 >> (x&7);
+
+ DREG = 0;
+ DREG |= ((uint32)((a[0x00] & v) != 0)) << 0;
+ DREG |= ((uint32)((a[0x01] & v) != 0)) << 1;
+ DREG |= ((uint32)((a[0x10] & v) != 0)) << 2;
+ DREG |= ((uint32)((a[0x11] & v) != 0)) << 3;
+ DREG |= ((uint32)((a[0x20] & v) != 0)) << 4;
+ DREG |= ((uint32)((a[0x21] & v) != 0)) << 5;
+ DREG |= ((uint32)((a[0x30] & v) != 0)) << 6;
+ DREG |= ((uint32)((a[0x31] & v) != 0)) << 7;
+ GSU.vZero = DREG;
+ TESTR14;
+}
+
+/* 4o - plot - plot pixel with R1,R2 as x,y and the color register as the color */
+static void fx_plot_obj()
+{
+ printf ("ERROR fx_plot_obj called\n");
+}
+
+/* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */
+static void fx_rpix_obj()
+{
+ printf ("ERROR fx_rpix_obj called\n");
+}
+
+/* 4d - swap - swap upper and lower byte of a register */
+static void fx_swap()
+{
+ uint8 c = (uint8)SREG;
+ uint8 d = (uint8)(SREG>>8);
+ uint32 v = (((uint32)c)<<8)|((uint32)d);
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 4e - color - copy source register to color register */
+static void fx_color()
+{
+ uint8 c = (uint8)SREG;
+ if(GSU.vPlotOptionReg & 0x04)
+ c = (c&0xf0) | (c>>4);
+ if(GSU.vPlotOptionReg & 0x08)
+ {
+ GSU.vColorReg &= 0xf0;
+ GSU.vColorReg |= c & 0x0f;
+ }
+ else
+ GSU.vColorReg = USEX8(c);
+ CLRFLAGS;
+ R15++;
+}
+
+/* 4e(ALT1) - cmode - set plot option register */
+static void fx_cmode()
+{
+ GSU.vPlotOptionReg = SREG;
+
+ if(GSU.vPlotOptionReg & 0x10)
+ {
+ /* OBJ Mode (for drawing into sprites) */
+ GSU.vScreenHeight = 256;
+ }
+ else
+ GSU.vScreenHeight = GSU.vScreenRealHeight;
+
+ fx_computeScreenPointers ();
+ CLRFLAGS;
+ R15++;
+}
+
+/* 4f - not - perform exclusive exor with 1 on all bits */
+static void fx_not()
+{
+ uint32 v = ~SREG;
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 50-5f - add rn - add, register + register */
+#define FX_ADD(reg) \
+int32 s = SUSEX16(SREG) + SUSEX16(GSU.avReg[reg]); \
+GSU.vCarry = s >= 0x10000; \
+GSU.vOverflow = ~(SREG ^ GSU.avReg[reg]) & (GSU.avReg[reg] ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_add_r0() { FX_ADD(0); }
+static void fx_add_r1() { FX_ADD(1); }
+static void fx_add_r2() { FX_ADD(2); }
+static void fx_add_r3() { FX_ADD(3); }
+static void fx_add_r4() { FX_ADD(4); }
+static void fx_add_r5() { FX_ADD(5); }
+static void fx_add_r6() { FX_ADD(6); }
+static void fx_add_r7() { FX_ADD(7); }
+static void fx_add_r8() { FX_ADD(8); }
+static void fx_add_r9() { FX_ADD(9); }
+static void fx_add_r10() { FX_ADD(10); }
+static void fx_add_r11() { FX_ADD(11); }
+static void fx_add_r12() { FX_ADD(12); }
+static void fx_add_r13() { FX_ADD(13); }
+static void fx_add_r14() { FX_ADD(14); }
+static void fx_add_r15() { FX_ADD(15); }
+
+/* 50-5f(ALT1) - adc rn - add with carry, register + register */
+#define FX_ADC(reg) \
+int32 s = SUSEX16(SREG) + SUSEX16(GSU.avReg[reg]) + SEX16(GSU.vCarry); \
+GSU.vCarry = s >= 0x10000; \
+GSU.vOverflow = ~(SREG ^ GSU.avReg[reg]) & (GSU.avReg[reg] ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_adc_r0() { FX_ADC(0); }
+static void fx_adc_r1() { FX_ADC(1); }
+static void fx_adc_r2() { FX_ADC(2); }
+static void fx_adc_r3() { FX_ADC(3); }
+static void fx_adc_r4() { FX_ADC(4); }
+static void fx_adc_r5() { FX_ADC(5); }
+static void fx_adc_r6() { FX_ADC(6); }
+static void fx_adc_r7() { FX_ADC(7); }
+static void fx_adc_r8() { FX_ADC(8); }
+static void fx_adc_r9() { FX_ADC(9); }
+static void fx_adc_r10() { FX_ADC(10); }
+static void fx_adc_r11() { FX_ADC(11); }
+static void fx_adc_r12() { FX_ADC(12); }
+static void fx_adc_r13() { FX_ADC(13); }
+static void fx_adc_r14() { FX_ADC(14); }
+static void fx_adc_r15() { FX_ADC(15); }
+
+/* 50-5f(ALT2) - add #n - add, register + immediate */
+#define FX_ADD_I(imm) \
+int32 s = SUSEX16(SREG) + imm; \
+GSU.vCarry = s >= 0x10000; \
+GSU.vOverflow = ~(SREG ^ imm) & (imm ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_add_i0() { FX_ADD_I(0); }
+static void fx_add_i1() { FX_ADD_I(1); }
+static void fx_add_i2() { FX_ADD_I(2); }
+static void fx_add_i3() { FX_ADD_I(3); }
+static void fx_add_i4() { FX_ADD_I(4); }
+static void fx_add_i5() { FX_ADD_I(5); }
+static void fx_add_i6() { FX_ADD_I(6); }
+static void fx_add_i7() { FX_ADD_I(7); }
+static void fx_add_i8() { FX_ADD_I(8); }
+static void fx_add_i9() { FX_ADD_I(9); }
+static void fx_add_i10() { FX_ADD_I(10); }
+static void fx_add_i11() { FX_ADD_I(11); }
+static void fx_add_i12() { FX_ADD_I(12); }
+static void fx_add_i13() { FX_ADD_I(13); }
+static void fx_add_i14() { FX_ADD_I(14); }
+static void fx_add_i15() { FX_ADD_I(15); }
+
+/* 50-5f(ALT3) - adc #n - add with carry, register + immediate */
+#define FX_ADC_I(imm) \
+int32 s = SUSEX16(SREG) + imm + SUSEX16(GSU.vCarry); \
+GSU.vCarry = s >= 0x10000; \
+GSU.vOverflow = ~(SREG ^ imm) & (imm ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_adc_i0() { FX_ADC_I(0); }
+static void fx_adc_i1() { FX_ADC_I(1); }
+static void fx_adc_i2() { FX_ADC_I(2); }
+static void fx_adc_i3() { FX_ADC_I(3); }
+static void fx_adc_i4() { FX_ADC_I(4); }
+static void fx_adc_i5() { FX_ADC_I(5); }
+static void fx_adc_i6() { FX_ADC_I(6); }
+static void fx_adc_i7() { FX_ADC_I(7); }
+static void fx_adc_i8() { FX_ADC_I(8); }
+static void fx_adc_i9() { FX_ADC_I(9); }
+static void fx_adc_i10() { FX_ADC_I(10); }
+static void fx_adc_i11() { FX_ADC_I(11); }
+static void fx_adc_i12() { FX_ADC_I(12); }
+static void fx_adc_i13() { FX_ADC_I(13); }
+static void fx_adc_i14() { FX_ADC_I(14); }
+static void fx_adc_i15() { FX_ADC_I(15); }
+
+/* 60-6f - sub rn - subtract, register - register */
+#define FX_SUB(reg) \
+int32 s = SUSEX16(SREG) - SUSEX16(GSU.avReg[reg]); \
+GSU.vCarry = s >= 0; \
+GSU.vOverflow = (SREG ^ GSU.avReg[reg]) & (SREG ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_sub_r0() { FX_SUB(0); }
+static void fx_sub_r1() { FX_SUB(1); }
+static void fx_sub_r2() { FX_SUB(2); }
+static void fx_sub_r3() { FX_SUB(3); }
+static void fx_sub_r4() { FX_SUB(4); }
+static void fx_sub_r5() { FX_SUB(5); }
+static void fx_sub_r6() { FX_SUB(6); }
+static void fx_sub_r7() { FX_SUB(7); }
+static void fx_sub_r8() { FX_SUB(8); }
+static void fx_sub_r9() { FX_SUB(9); }
+static void fx_sub_r10() { FX_SUB(10); }
+static void fx_sub_r11() { FX_SUB(11); }
+static void fx_sub_r12() { FX_SUB(12); }
+static void fx_sub_r13() { FX_SUB(13); }
+static void fx_sub_r14() { FX_SUB(14); }
+static void fx_sub_r15() { FX_SUB(15); }
+
+/* 60-6f(ALT1) - sbc rn - subtract with carry, register - register */
+#define FX_SBC(reg) \
+int32 s = SUSEX16(SREG) - SUSEX16(GSU.avReg[reg]) - (SUSEX16(GSU.vCarry^1)); \
+GSU.vCarry = s >= 0; \
+GSU.vOverflow = (SREG ^ GSU.avReg[reg]) & (SREG ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_sbc_r0() { FX_SBC(0); }
+static void fx_sbc_r1() { FX_SBC(1); }
+static void fx_sbc_r2() { FX_SBC(2); }
+static void fx_sbc_r3() { FX_SBC(3); }
+static void fx_sbc_r4() { FX_SBC(4); }
+static void fx_sbc_r5() { FX_SBC(5); }
+static void fx_sbc_r6() { FX_SBC(6); }
+static void fx_sbc_r7() { FX_SBC(7); }
+static void fx_sbc_r8() { FX_SBC(8); }
+static void fx_sbc_r9() { FX_SBC(9); }
+static void fx_sbc_r10() { FX_SBC(10); }
+static void fx_sbc_r11() { FX_SBC(11); }
+static void fx_sbc_r12() { FX_SBC(12); }
+static void fx_sbc_r13() { FX_SBC(13); }
+static void fx_sbc_r14() { FX_SBC(14); }
+static void fx_sbc_r15() { FX_SBC(15); }
+
+/* 60-6f(ALT2) - sub #n - subtract, register - immediate */
+#define FX_SUB_I(imm) \
+int32 s = SUSEX16(SREG) - imm; \
+GSU.vCarry = s >= 0; \
+GSU.vOverflow = (SREG ^ imm) & (SREG ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; DREG = s; \
+TESTR14; \
+CLRFLAGS
+static void fx_sub_i0() { FX_SUB_I(0); }
+static void fx_sub_i1() { FX_SUB_I(1); }
+static void fx_sub_i2() { FX_SUB_I(2); }
+static void fx_sub_i3() { FX_SUB_I(3); }
+static void fx_sub_i4() { FX_SUB_I(4); }
+static void fx_sub_i5() { FX_SUB_I(5); }
+static void fx_sub_i6() { FX_SUB_I(6); }
+static void fx_sub_i7() { FX_SUB_I(7); }
+static void fx_sub_i8() { FX_SUB_I(8); }
+static void fx_sub_i9() { FX_SUB_I(9); }
+static void fx_sub_i10() { FX_SUB_I(10); }
+static void fx_sub_i11() { FX_SUB_I(11); }
+static void fx_sub_i12() { FX_SUB_I(12); }
+static void fx_sub_i13() { FX_SUB_I(13); }
+static void fx_sub_i14() { FX_SUB_I(14); }
+static void fx_sub_i15() { FX_SUB_I(15); }
+
+/* 60-6f(ALT3) - cmp rn - compare, register, register */
+#define FX_CMP(reg) \
+int32 s = SUSEX16(SREG) - SUSEX16(GSU.avReg[reg]); \
+GSU.vCarry = s >= 0; \
+GSU.vOverflow = (SREG ^ GSU.avReg[reg]) & (SREG ^ s) & 0x8000; \
+GSU.vSign = s; \
+GSU.vZero = s; \
+R15++; \
+CLRFLAGS;
+static void fx_cmp_r0() { FX_CMP(0); }
+static void fx_cmp_r1() { FX_CMP(1); }
+static void fx_cmp_r2() { FX_CMP(2); }
+static void fx_cmp_r3() { FX_CMP(3); }
+static void fx_cmp_r4() { FX_CMP(4); }
+static void fx_cmp_r5() { FX_CMP(5); }
+static void fx_cmp_r6() { FX_CMP(6); }
+static void fx_cmp_r7() { FX_CMP(7); }
+static void fx_cmp_r8() { FX_CMP(8); }
+static void fx_cmp_r9() { FX_CMP(9); }
+static void fx_cmp_r10() { FX_CMP(10); }
+static void fx_cmp_r11() { FX_CMP(11); }
+static void fx_cmp_r12() { FX_CMP(12); }
+static void fx_cmp_r13() { FX_CMP(13); }
+static void fx_cmp_r14() { FX_CMP(14); }
+static void fx_cmp_r15() { FX_CMP(15); }
+
+/* 70 - merge - R7 as upper byte, R8 as lower byte (used for texture-mapping) */
+static void fx_merge()
+{
+ uint32 v = (R7&0xff00) | ((R8&0xff00)>>8);
+ R15++; DREG = v;
+ GSU.vOverflow = (v & 0xc0c0) << 16;
+ GSU.vZero = !(v & 0xf0f0);
+ GSU.vSign = ((v | (v<<8)) & 0x8000);
+ GSU.vCarry = (v & 0xe0e0) != 0;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 71-7f - and rn - reister & register */
+#define FX_AND(reg) \
+uint32 v = SREG & GSU.avReg[reg]; \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_and_r1() { FX_AND(1); }
+static void fx_and_r2() { FX_AND(2); }
+static void fx_and_r3() { FX_AND(3); }
+static void fx_and_r4() { FX_AND(4); }
+static void fx_and_r5() { FX_AND(5); }
+static void fx_and_r6() { FX_AND(6); }
+static void fx_and_r7() { FX_AND(7); }
+static void fx_and_r8() { FX_AND(8); }
+static void fx_and_r9() { FX_AND(9); }
+static void fx_and_r10() { FX_AND(10); }
+static void fx_and_r11() { FX_AND(11); }
+static void fx_and_r12() { FX_AND(12); }
+static void fx_and_r13() { FX_AND(13); }
+static void fx_and_r14() { FX_AND(14); }
+static void fx_and_r15() { FX_AND(15); }
+
+/* 71-7f(ALT1) - bic rn - reister & ~register */
+#define FX_BIC(reg) \
+uint32 v = SREG & ~GSU.avReg[reg]; \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_bic_r1() { FX_BIC(1); }
+static void fx_bic_r2() { FX_BIC(2); }
+static void fx_bic_r3() { FX_BIC(3); }
+static void fx_bic_r4() { FX_BIC(4); }
+static void fx_bic_r5() { FX_BIC(5); }
+static void fx_bic_r6() { FX_BIC(6); }
+static void fx_bic_r7() { FX_BIC(7); }
+static void fx_bic_r8() { FX_BIC(8); }
+static void fx_bic_r9() { FX_BIC(9); }
+static void fx_bic_r10() { FX_BIC(10); }
+static void fx_bic_r11() { FX_BIC(11); }
+static void fx_bic_r12() { FX_BIC(12); }
+static void fx_bic_r13() { FX_BIC(13); }
+static void fx_bic_r14() { FX_BIC(14); }
+static void fx_bic_r15() { FX_BIC(15); }
+
+/* 71-7f(ALT2) - and #n - reister & immediate */
+#define FX_AND_I(imm) \
+uint32 v = SREG & imm; \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_and_i1() { FX_AND_I(1); }
+static void fx_and_i2() { FX_AND_I(2); }
+static void fx_and_i3() { FX_AND_I(3); }
+static void fx_and_i4() { FX_AND_I(4); }
+static void fx_and_i5() { FX_AND_I(5); }
+static void fx_and_i6() { FX_AND_I(6); }
+static void fx_and_i7() { FX_AND_I(7); }
+static void fx_and_i8() { FX_AND_I(8); }
+static void fx_and_i9() { FX_AND_I(9); }
+static void fx_and_i10() { FX_AND_I(10); }
+static void fx_and_i11() { FX_AND_I(11); }
+static void fx_and_i12() { FX_AND_I(12); }
+static void fx_and_i13() { FX_AND_I(13); }
+static void fx_and_i14() { FX_AND_I(14); }
+static void fx_and_i15() { FX_AND_I(15); }
+
+/* 71-7f(ALT3) - bic #n - reister & ~immediate */
+#define FX_BIC_I(imm) \
+uint32 v = SREG & ~imm; \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_bic_i1() { FX_BIC_I(1); }
+static void fx_bic_i2() { FX_BIC_I(2); }
+static void fx_bic_i3() { FX_BIC_I(3); }
+static void fx_bic_i4() { FX_BIC_I(4); }
+static void fx_bic_i5() { FX_BIC_I(5); }
+static void fx_bic_i6() { FX_BIC_I(6); }
+static void fx_bic_i7() { FX_BIC_I(7); }
+static void fx_bic_i8() { FX_BIC_I(8); }
+static void fx_bic_i9() { FX_BIC_I(9); }
+static void fx_bic_i10() { FX_BIC_I(10); }
+static void fx_bic_i11() { FX_BIC_I(11); }
+static void fx_bic_i12() { FX_BIC_I(12); }
+static void fx_bic_i13() { FX_BIC_I(13); }
+static void fx_bic_i14() { FX_BIC_I(14); }
+static void fx_bic_i15() { FX_BIC_I(15); }
+
+/* 80-8f - mult rn - 8 bit to 16 bit signed multiply, register * register */
+#define FX_MULT(reg) \
+uint32 v = (uint32)(SEX8(SREG) * SEX8(GSU.avReg[reg])); \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_mult_r0() { FX_MULT(0); }
+static void fx_mult_r1() { FX_MULT(1); }
+static void fx_mult_r2() { FX_MULT(2); }
+static void fx_mult_r3() { FX_MULT(3); }
+static void fx_mult_r4() { FX_MULT(4); }
+static void fx_mult_r5() { FX_MULT(5); }
+static void fx_mult_r6() { FX_MULT(6); }
+static void fx_mult_r7() { FX_MULT(7); }
+static void fx_mult_r8() { FX_MULT(8); }
+static void fx_mult_r9() { FX_MULT(9); }
+static void fx_mult_r10() { FX_MULT(10); }
+static void fx_mult_r11() { FX_MULT(11); }
+static void fx_mult_r12() { FX_MULT(12); }
+static void fx_mult_r13() { FX_MULT(13); }
+static void fx_mult_r14() { FX_MULT(14); }
+static void fx_mult_r15() { FX_MULT(15); }
+
+/* 80-8f(ALT1) - umult rn - 8 bit to 16 bit unsigned multiply, register * register */
+#define FX_UMULT(reg) \
+uint32 v = USEX8(SREG) * USEX8(GSU.avReg[reg]); \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_umult_r0() { FX_UMULT(0); }
+static void fx_umult_r1() { FX_UMULT(1); }
+static void fx_umult_r2() { FX_UMULT(2); }
+static void fx_umult_r3() { FX_UMULT(3); }
+static void fx_umult_r4() { FX_UMULT(4); }
+static void fx_umult_r5() { FX_UMULT(5); }
+static void fx_umult_r6() { FX_UMULT(6); }
+static void fx_umult_r7() { FX_UMULT(7); }
+static void fx_umult_r8() { FX_UMULT(8); }
+static void fx_umult_r9() { FX_UMULT(9); }
+static void fx_umult_r10() { FX_UMULT(10); }
+static void fx_umult_r11() { FX_UMULT(11); }
+static void fx_umult_r12() { FX_UMULT(12); }
+static void fx_umult_r13() { FX_UMULT(13); }
+static void fx_umult_r14() { FX_UMULT(14); }
+static void fx_umult_r15() { FX_UMULT(15); }
+
+/* 80-8f(ALT2) - mult #n - 8 bit to 16 bit signed multiply, register * immediate */
+#define FX_MULT_I(imm) \
+uint32 v = (uint32) (SEX8(SREG) * ((int32)imm)); \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_mult_i0() { FX_MULT_I(0); }
+static void fx_mult_i1() { FX_MULT_I(1); }
+static void fx_mult_i2() { FX_MULT_I(2); }
+static void fx_mult_i3() { FX_MULT_I(3); }
+static void fx_mult_i4() { FX_MULT_I(4); }
+static void fx_mult_i5() { FX_MULT_I(5); }
+static void fx_mult_i6() { FX_MULT_I(6); }
+static void fx_mult_i7() { FX_MULT_I(7); }
+static void fx_mult_i8() { FX_MULT_I(8); }
+static void fx_mult_i9() { FX_MULT_I(9); }
+static void fx_mult_i10() { FX_MULT_I(10); }
+static void fx_mult_i11() { FX_MULT_I(11); }
+static void fx_mult_i12() { FX_MULT_I(12); }
+static void fx_mult_i13() { FX_MULT_I(13); }
+static void fx_mult_i14() { FX_MULT_I(14); }
+static void fx_mult_i15() { FX_MULT_I(15); }
+
+/* 80-8f(ALT3) - umult #n - 8 bit to 16 bit unsigned multiply, register * immediate */
+#define FX_UMULT_I(imm) \
+uint32 v = USEX8(SREG) * ((uint32)imm); \
+R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_umult_i0() { FX_UMULT_I(0); }
+static void fx_umult_i1() { FX_UMULT_I(1); }
+static void fx_umult_i2() { FX_UMULT_I(2); }
+static void fx_umult_i3() { FX_UMULT_I(3); }
+static void fx_umult_i4() { FX_UMULT_I(4); }
+static void fx_umult_i5() { FX_UMULT_I(5); }
+static void fx_umult_i6() { FX_UMULT_I(6); }
+static void fx_umult_i7() { FX_UMULT_I(7); }
+static void fx_umult_i8() { FX_UMULT_I(8); }
+static void fx_umult_i9() { FX_UMULT_I(9); }
+static void fx_umult_i10() { FX_UMULT_I(10); }
+static void fx_umult_i11() { FX_UMULT_I(11); }
+static void fx_umult_i12() { FX_UMULT_I(12); }
+static void fx_umult_i13() { FX_UMULT_I(13); }
+static void fx_umult_i14() { FX_UMULT_I(14); }
+static void fx_umult_i15() { FX_UMULT_I(15); }
+
+/* 90 - sbk - store word to last accessed RAM address */
+static void fx_sbk()
+{
+ RAM(GSU.vLastRamAdr) = (uint8)SREG;
+ RAM(GSU.vLastRamAdr^1) = (uint8)(SREG>>8);
+ CLRFLAGS;
+ R15++;
+}
+
+/* 91-94 - link #n - R11 = R15 + immediate */
+#define FX_LINK_I(lkn) R11 = R15 + lkn; CLRFLAGS; R15++
+static void fx_link_i1() { FX_LINK_I(1); }
+static void fx_link_i2() { FX_LINK_I(2); }
+static void fx_link_i3() { FX_LINK_I(3); }
+static void fx_link_i4() { FX_LINK_I(4); }
+
+/* 95 - sex - sign extend 8 bit to 16 bit */
+static void fx_sex()
+{
+ uint32 v = (uint32)SEX8(SREG);
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 96 - asr - aritmetric shift right by one */
+static void fx_asr()
+{
+ uint32 v;
+ GSU.vCarry = SREG & 1;
+ v = (uint32)(SEX16(SREG)>>1);
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 96(ALT1) - div2 - aritmetric shift right by one */
+static void fx_div2()
+{
+ uint32 v;
+ int32 s = SEX16(SREG);
+ GSU.vCarry = s & 1;
+ if(s == -1)
+ v = 0;
+ else
+ v = (uint32)(s>>1);
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 97 - ror - rotate right by one */
+static void fx_ror()
+{
+ uint32 v = (USEX16(SREG)>>1) | (GSU.vCarry<<15);
+ GSU.vCarry = SREG & 1;
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 98-9d - jmp rn - jump to address of register */
+#define FX_JMP(reg) \
+R15 = GSU.avReg[reg]; \
+CLRFLAGS;
+static void fx_jmp_r8() { FX_JMP(8); }
+static void fx_jmp_r9() { FX_JMP(9); }
+static void fx_jmp_r10() { FX_JMP(10); }
+static void fx_jmp_r11() { FX_JMP(11); }
+static void fx_jmp_r12() { FX_JMP(12); }
+static void fx_jmp_r13() { FX_JMP(13); }
+
+/* 98-9d(ALT1) - ljmp rn - set program bank to source register and jump to address of register */
+#define FX_LJMP(reg) \
+GSU.vPrgBankReg = GSU.avReg[reg] & 0x7f; \
+GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg]; \
+R15 = SREG; \
+GSU.bCacheActive = FALSE; fx_cache(); R15--;
+static void fx_ljmp_r8() { FX_LJMP(8); }
+static void fx_ljmp_r9() { FX_LJMP(9); }
+static void fx_ljmp_r10() { FX_LJMP(10); }
+static void fx_ljmp_r11() { FX_LJMP(11); }
+static void fx_ljmp_r12() { FX_LJMP(12); }
+static void fx_ljmp_r13() { FX_LJMP(13); }
+
+/* 9e - lob - set upper byte to zero (keep low byte) */
+static void fx_lob()
+{
+ uint32 v = USEX8(SREG);
+ R15++; DREG = v;
+ GSU.vSign = v<<8;
+ GSU.vZero = v<<8;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 9f - fmult - 16 bit to 32 bit signed multiplication, upper 16 bits only */
+static void fx_fmult()
+{
+ uint32 v;
+ uint32 c = (uint32) (SEX16(SREG) * SEX16(R6));
+ v = c >> 16;
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ GSU.vCarry = (c >> 15) & 1;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* 9f(ALT1) - lmult - 16 bit to 32 bit signed multiplication */
+static void fx_lmult()
+{
+ uint32 v;
+ uint32 c = (uint32) (SEX16(SREG) * SEX16(R6));
+ R4 = c;
+ v = c >> 16;
+ R15++; DREG = v;
+ GSU.vSign = v;
+ GSU.vZero = v;
+ /* XXX R6 or R4? */
+ GSU.vCarry = (R4 >> 15) & 1; /* should it be bit 15 of R4 instead? */
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* a0-af - ibt rn,#pp - immediate byte transfer */
+#define FX_IBT(reg) \
+uint8 v = PIPE; R15++; \
+FETCHPIPE; R15++; \
+GSU.avReg[reg] = SEX8(v); \
+CLRFLAGS;
+static void fx_ibt_r0() { FX_IBT(0); }
+static void fx_ibt_r1() { FX_IBT(1); }
+static void fx_ibt_r2() { FX_IBT(2); }
+static void fx_ibt_r3() { FX_IBT(3); }
+static void fx_ibt_r4() { FX_IBT(4); }
+static void fx_ibt_r5() { FX_IBT(5); }
+static void fx_ibt_r6() { FX_IBT(6); }
+static void fx_ibt_r7() { FX_IBT(7); }
+static void fx_ibt_r8() { FX_IBT(8); }
+static void fx_ibt_r9() { FX_IBT(9); }
+static void fx_ibt_r10() { FX_IBT(10); }
+static void fx_ibt_r11() { FX_IBT(11); }
+static void fx_ibt_r12() { FX_IBT(12); }
+static void fx_ibt_r13() { FX_IBT(13); }
+static void fx_ibt_r14() { FX_IBT(14); READR14; }
+static void fx_ibt_r15() { FX_IBT(15); }
+
+/* a0-af(ALT1) - lms rn,(yy) - load word from RAM (short address) */
+#define FX_LMS(reg) \
+GSU.vLastRamAdr = ((uint32)PIPE) << 1; \
+R15++; FETCHPIPE; R15++; \
+GSU.avReg[reg] = (uint32)RAM(GSU.vLastRamAdr); \
+GSU.avReg[reg] |= ((uint32)RAM(GSU.vLastRamAdr+1))<<8; \
+CLRFLAGS;
+static void fx_lms_r0() { FX_LMS(0); }
+static void fx_lms_r1() { FX_LMS(1); }
+static void fx_lms_r2() { FX_LMS(2); }
+static void fx_lms_r3() { FX_LMS(3); }
+static void fx_lms_r4() { FX_LMS(4); }
+static void fx_lms_r5() { FX_LMS(5); }
+static void fx_lms_r6() { FX_LMS(6); }
+static void fx_lms_r7() { FX_LMS(7); }
+static void fx_lms_r8() { FX_LMS(8); }
+static void fx_lms_r9() { FX_LMS(9); }
+static void fx_lms_r10() { FX_LMS(10); }
+static void fx_lms_r11() { FX_LMS(11); }
+static void fx_lms_r12() { FX_LMS(12); }
+static void fx_lms_r13() { FX_LMS(13); }
+static void fx_lms_r14() { FX_LMS(14); READR14; }
+static void fx_lms_r15() { FX_LMS(15); }
+
+/* a0-af(ALT2) - sms (yy),rn - store word in RAM (short address) */
+/* If rn == r15, is the value of r15 before or after the extra byte is read? */
+#define FX_SMS(reg) \
+uint32 v = GSU.avReg[reg]; \
+GSU.vLastRamAdr = ((uint32)PIPE) << 1; \
+R15++; FETCHPIPE; \
+RAM(GSU.vLastRamAdr) = (uint8)v; \
+RAM(GSU.vLastRamAdr+1) = (uint8)(v>>8); \
+CLRFLAGS; R15++;
+static void fx_sms_r0() { FX_SMS(0); }
+static void fx_sms_r1() { FX_SMS(1); }
+static void fx_sms_r2() { FX_SMS(2); }
+static void fx_sms_r3() { FX_SMS(3); }
+static void fx_sms_r4() { FX_SMS(4); }
+static void fx_sms_r5() { FX_SMS(5); }
+static void fx_sms_r6() { FX_SMS(6); }
+static void fx_sms_r7() { FX_SMS(7); }
+static void fx_sms_r8() { FX_SMS(8); }
+static void fx_sms_r9() { FX_SMS(9); }
+static void fx_sms_r10() { FX_SMS(10); }
+static void fx_sms_r11() { FX_SMS(11); }
+static void fx_sms_r12() { FX_SMS(12); }
+static void fx_sms_r13() { FX_SMS(13); }
+static void fx_sms_r14() { FX_SMS(14); }
+static void fx_sms_r15() { FX_SMS(15); }
+
+/* b0-bf - from rn - set source register */
+/* b0-bf(B) - moves rn - move register to register, and set flags, (if B flag is set) */
+#define FX_FROM(reg) \
+if(TF(B)) { uint32 v = GSU.avReg[reg]; R15++; DREG = v; \
+GSU.vOverflow = (v&0x80) << 16; GSU.vSign = v; GSU.vZero = v; TESTR14; CLRFLAGS; } \
+else { GSU.pvSreg = &GSU.avReg[reg]; R15++; }
+static void fx_from_r0() { FX_FROM(0); }
+static void fx_from_r1() { FX_FROM(1); }
+static void fx_from_r2() { FX_FROM(2); }
+static void fx_from_r3() { FX_FROM(3); }
+static void fx_from_r4() { FX_FROM(4); }
+static void fx_from_r5() { FX_FROM(5); }
+static void fx_from_r6() { FX_FROM(6); }
+static void fx_from_r7() { FX_FROM(7); }
+static void fx_from_r8() { FX_FROM(8); }
+static void fx_from_r9() { FX_FROM(9); }
+static void fx_from_r10() { FX_FROM(10); }
+static void fx_from_r11() { FX_FROM(11); }
+static void fx_from_r12() { FX_FROM(12); }
+static void fx_from_r13() { FX_FROM(13); }
+static void fx_from_r14() { FX_FROM(14); }
+static void fx_from_r15() { FX_FROM(15); }
+
+/* c0 - hib - move high-byte to low-byte */
+static void fx_hib()
+{
+ uint32 v = USEX8(SREG>>8);
+ R15++; DREG = v;
+ GSU.vSign = v<<8;
+ GSU.vZero = v<<8;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* c1-cf - or rn */
+#define FX_OR(reg) \
+uint32 v = SREG | GSU.avReg[reg]; R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_or_r1() { FX_OR(1); }
+static void fx_or_r2() { FX_OR(2); }
+static void fx_or_r3() { FX_OR(3); }
+static void fx_or_r4() { FX_OR(4); }
+static void fx_or_r5() { FX_OR(5); }
+static void fx_or_r6() { FX_OR(6); }
+static void fx_or_r7() { FX_OR(7); }
+static void fx_or_r8() { FX_OR(8); }
+static void fx_or_r9() { FX_OR(9); }
+static void fx_or_r10() { FX_OR(10); }
+static void fx_or_r11() { FX_OR(11); }
+static void fx_or_r12() { FX_OR(12); }
+static void fx_or_r13() { FX_OR(13); }
+static void fx_or_r14() { FX_OR(14); }
+static void fx_or_r15() { FX_OR(15); }
+
+/* c1-cf(ALT1) - xor rn */
+#define FX_XOR(reg) \
+uint32 v = SREG ^ GSU.avReg[reg]; R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_xor_r1() { FX_XOR(1); }
+static void fx_xor_r2() { FX_XOR(2); }
+static void fx_xor_r3() { FX_XOR(3); }
+static void fx_xor_r4() { FX_XOR(4); }
+static void fx_xor_r5() { FX_XOR(5); }
+static void fx_xor_r6() { FX_XOR(6); }
+static void fx_xor_r7() { FX_XOR(7); }
+static void fx_xor_r8() { FX_XOR(8); }
+static void fx_xor_r9() { FX_XOR(9); }
+static void fx_xor_r10() { FX_XOR(10); }
+static void fx_xor_r11() { FX_XOR(11); }
+static void fx_xor_r12() { FX_XOR(12); }
+static void fx_xor_r13() { FX_XOR(13); }
+static void fx_xor_r14() { FX_XOR(14); }
+static void fx_xor_r15() { FX_XOR(15); }
+
+/* c1-cf(ALT2) - or #n */
+#define FX_OR_I(imm) \
+uint32 v = SREG | imm; R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_or_i1() { FX_OR_I(1); }
+static void fx_or_i2() { FX_OR_I(2); }
+static void fx_or_i3() { FX_OR_I(3); }
+static void fx_or_i4() { FX_OR_I(4); }
+static void fx_or_i5() { FX_OR_I(5); }
+static void fx_or_i6() { FX_OR_I(6); }
+static void fx_or_i7() { FX_OR_I(7); }
+static void fx_or_i8() { FX_OR_I(8); }
+static void fx_or_i9() { FX_OR_I(9); }
+static void fx_or_i10() { FX_OR_I(10); }
+static void fx_or_i11() { FX_OR_I(11); }
+static void fx_or_i12() { FX_OR_I(12); }
+static void fx_or_i13() { FX_OR_I(13); }
+static void fx_or_i14() { FX_OR_I(14); }
+static void fx_or_i15() { FX_OR_I(15); }
+
+/* c1-cf(ALT3) - xor #n */
+#define FX_XOR_I(imm) \
+uint32 v = SREG ^ imm; R15++; DREG = v; \
+GSU.vSign = v; \
+GSU.vZero = v; \
+TESTR14; \
+CLRFLAGS;
+static void fx_xor_i1() { FX_XOR_I(1); }
+static void fx_xor_i2() { FX_XOR_I(2); }
+static void fx_xor_i3() { FX_XOR_I(3); }
+static void fx_xor_i4() { FX_XOR_I(4); }
+static void fx_xor_i5() { FX_XOR_I(5); }
+static void fx_xor_i6() { FX_XOR_I(6); }
+static void fx_xor_i7() { FX_XOR_I(7); }
+static void fx_xor_i8() { FX_XOR_I(8); }
+static void fx_xor_i9() { FX_XOR_I(9); }
+static void fx_xor_i10() { FX_XOR_I(10); }
+static void fx_xor_i11() { FX_XOR_I(11); }
+static void fx_xor_i12() { FX_XOR_I(12); }
+static void fx_xor_i13() { FX_XOR_I(13); }
+static void fx_xor_i14() { FX_XOR_I(14); }
+static void fx_xor_i15() { FX_XOR_I(15); }
+
+/* d0-de - inc rn - increase by one */
+#define FX_INC(reg) \
+GSU.avReg[reg] += 1; \
+GSU.vSign = GSU.avReg[reg]; \
+GSU.vZero = GSU.avReg[reg]; \
+CLRFLAGS; R15++;
+static void fx_inc_r0() { FX_INC(0); }
+static void fx_inc_r1() { FX_INC(1); }
+static void fx_inc_r2() { FX_INC(2); }
+static void fx_inc_r3() { FX_INC(3); }
+static void fx_inc_r4() { FX_INC(4); }
+static void fx_inc_r5() { FX_INC(5); }
+static void fx_inc_r6() { FX_INC(6); }
+static void fx_inc_r7() { FX_INC(7); }
+static void fx_inc_r8() { FX_INC(8); }
+static void fx_inc_r9() { FX_INC(9); }
+static void fx_inc_r10() { FX_INC(10); }
+static void fx_inc_r11() { FX_INC(11); }
+static void fx_inc_r12() { FX_INC(12); }
+static void fx_inc_r13() { FX_INC(13); }
+static void fx_inc_r14() { FX_INC(14); READR14; }
+
+/* df - getc - transfer ROM buffer to color register */
+static void fx_getc()
+{
+#ifndef FX_DO_ROMBUFFER
+ uint8 c;
+ c = ROM(R14);
+#else
+ uint8 c = GSU.vRomBuffer;
+#endif
+ if(GSU.vPlotOptionReg & 0x04)
+ c = (c&0xf0) | (c>>4);
+ if(GSU.vPlotOptionReg & 0x08)
+ {
+ GSU.vColorReg &= 0xf0;
+ GSU.vColorReg |= c & 0x0f;
+ }
+ else
+ GSU.vColorReg = USEX8(c);
+ CLRFLAGS;
+ R15++;
+}
+
+/* df(ALT2) - ramb - set current RAM bank */
+static void fx_ramb()
+{
+ GSU.vRamBankReg = SREG & (FX_RAM_BANKS-1);
+ GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3];
+ CLRFLAGS;
+ R15++;
+}
+
+/* df(ALT3) - romb - set current ROM bank */
+static void fx_romb()
+{
+ GSU.vRomBankReg = USEX8(SREG) & 0x7f;
+ GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg];
+ CLRFLAGS;
+ R15++;
+}
+
+/* e0-ee - dec rn - decrement by one */
+#define FX_DEC(reg) \
+GSU.avReg[reg] -= 1; \
+GSU.vSign = GSU.avReg[reg]; \
+GSU.vZero = GSU.avReg[reg]; \
+CLRFLAGS; R15++;
+static void fx_dec_r0() { FX_DEC(0); }
+static void fx_dec_r1() { FX_DEC(1); }
+static void fx_dec_r2() { FX_DEC(2); }
+static void fx_dec_r3() { FX_DEC(3); }
+static void fx_dec_r4() { FX_DEC(4); }
+static void fx_dec_r5() { FX_DEC(5); }
+static void fx_dec_r6() { FX_DEC(6); }
+static void fx_dec_r7() { FX_DEC(7); }
+static void fx_dec_r8() { FX_DEC(8); }
+static void fx_dec_r9() { FX_DEC(9); }
+static void fx_dec_r10() { FX_DEC(10); }
+static void fx_dec_r11() { FX_DEC(11); }
+static void fx_dec_r12() { FX_DEC(12); }
+static void fx_dec_r13() { FX_DEC(13); }
+static void fx_dec_r14() { FX_DEC(14); READR14; }
+
+/* ef - getb - get byte from ROM at address R14 */
+static void fx_getb()
+{
+ uint32 v;
+#ifndef FX_DO_ROMBUFFER
+ v = (uint32)ROM(R14);
+#else
+ v = (uint32)GSU.vRomBuffer;
+#endif
+ R15++; DREG = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* ef(ALT1) - getbh - get high-byte from ROM at address R14 */
+static void fx_getbh()
+{
+ uint32 v;
+#ifndef FX_DO_ROMBUFFER
+ uint32 c;
+ c = (uint32)ROM(R14);
+#else
+ uint32 c = USEX8(GSU.vRomBuffer);
+#endif
+ v = USEX8(SREG) | (c<<8);
+ R15++; DREG = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* ef(ALT2) - getbl - get low-byte from ROM at address R14 */
+static void fx_getbl()
+{
+ uint32 v;
+#ifndef FX_DO_ROMBUFFER
+ uint32 c;
+ c = (uint32)ROM(R14);
+#else
+ uint32 c = USEX8(GSU.vRomBuffer);
+#endif
+ v = (SREG & 0xff00) | c;
+ R15++; DREG = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* ef(ALT3) - getbs - get sign extended byte from ROM at address R14 */
+static void fx_getbs()
+{
+ uint32 v;
+#ifndef FX_DO_ROMBUFFER
+ int8 c;
+ c = ROM(R14);
+ v = SEX8(c);
+#else
+ v = SEX8(GSU.vRomBuffer);
+#endif
+ R15++; DREG = v;
+ TESTR14;
+ CLRFLAGS;
+}
+
+/* f0-ff - iwt rn,#xx - immediate word transfer to register */
+#define FX_IWT(reg) \
+uint32 v = PIPE; R15++; FETCHPIPE; R15++; \
+v |= USEX8(PIPE) << 8; FETCHPIPE; R15++; \
+GSU.avReg[reg] = v; \
+CLRFLAGS;
+static void fx_iwt_r0() { FX_IWT(0); }
+static void fx_iwt_r1() { FX_IWT(1); }
+static void fx_iwt_r2() { FX_IWT(2); }
+static void fx_iwt_r3() { FX_IWT(3); }
+static void fx_iwt_r4() { FX_IWT(4); }
+static void fx_iwt_r5() { FX_IWT(5); }
+static void fx_iwt_r6() { FX_IWT(6); }
+static void fx_iwt_r7() { FX_IWT(7); }
+static void fx_iwt_r8() { FX_IWT(8); }
+static void fx_iwt_r9() { FX_IWT(9); }
+static void fx_iwt_r10() { FX_IWT(10); }
+static void fx_iwt_r11() { FX_IWT(11); }
+static void fx_iwt_r12() { FX_IWT(12); }
+static void fx_iwt_r13() { FX_IWT(13); }
+static void fx_iwt_r14() { FX_IWT(14); READR14; }
+static void fx_iwt_r15() { FX_IWT(15); }
+
+/* f0-ff(ALT1) - lm rn,(xx) - load word from RAM */
+#define FX_LM(reg) \
+GSU.vLastRamAdr = PIPE; R15++; FETCHPIPE; R15++; \
+GSU.vLastRamAdr |= USEX8(PIPE) << 8; FETCHPIPE; R15++; \
+GSU.avReg[reg] = RAM(GSU.vLastRamAdr); \
+GSU.avReg[reg] |= USEX8(RAM(GSU.vLastRamAdr^1)) << 8; \
+CLRFLAGS;
+static void fx_lm_r0() { FX_LM(0); }
+static void fx_lm_r1() { FX_LM(1); }
+static void fx_lm_r2() { FX_LM(2); }
+static void fx_lm_r3() { FX_LM(3); }
+static void fx_lm_r4() { FX_LM(4); }
+static void fx_lm_r5() { FX_LM(5); }
+static void fx_lm_r6() { FX_LM(6); }
+static void fx_lm_r7() { FX_LM(7); }
+static void fx_lm_r8() { FX_LM(8); }
+static void fx_lm_r9() { FX_LM(9); }
+static void fx_lm_r10() { FX_LM(10); }
+static void fx_lm_r11() { FX_LM(11); }
+static void fx_lm_r12() { FX_LM(12); }
+static void fx_lm_r13() { FX_LM(13); }
+static void fx_lm_r14() { FX_LM(14); READR14; }
+static void fx_lm_r15() { FX_LM(15); }
+
+/* f0-ff(ALT2) - sm (xx),rn - store word in RAM */
+/* If rn == r15, is the value of r15 before or after the extra bytes are read? */
+#define FX_SM(reg) \
+uint32 v = GSU.avReg[reg]; \
+GSU.vLastRamAdr = PIPE; R15++; FETCHPIPE; R15++; \
+GSU.vLastRamAdr |= USEX8(PIPE) << 8; FETCHPIPE; \
+RAM(GSU.vLastRamAdr) = (uint8)v; \
+RAM(GSU.vLastRamAdr^1) = (uint8)(v>>8); \
+CLRFLAGS; R15++;
+static void fx_sm_r0() { FX_SM(0); }
+static void fx_sm_r1() { FX_SM(1); }
+static void fx_sm_r2() { FX_SM(2); }
+static void fx_sm_r3() { FX_SM(3); }
+static void fx_sm_r4() { FX_SM(4); }
+static void fx_sm_r5() { FX_SM(5); }
+static void fx_sm_r6() { FX_SM(6); }
+static void fx_sm_r7() { FX_SM(7); }
+static void fx_sm_r8() { FX_SM(8); }
+static void fx_sm_r9() { FX_SM(9); }
+static void fx_sm_r10() { FX_SM(10); }
+static void fx_sm_r11() { FX_SM(11); }
+static void fx_sm_r12() { FX_SM(12); }
+static void fx_sm_r13() { FX_SM(13); }
+static void fx_sm_r14() { FX_SM(14); }
+static void fx_sm_r15() { FX_SM(15); }
+
+/*** GSU executions functions ***/
+
+static uint32 fx_run(uint32 nInstructions)
+{
+ GSU.vCounter = nInstructions;
+ READR14;
+ while( TF(G) && (GSU.vCounter-- > 0) )
+ FX_STEP;
+ /*
+#ifndef FX_ADDRESS_CHECK
+ GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16);
+#endif
+*/
+ return (nInstructions - GSU.vInstCount);
+}
+
+static uint32 fx_run_to_breakpoint(uint32 nInstructions)
+{
+ uint32 vCounter = 0;
+ while(TF(G) && vCounter < nInstructions)
+ {
+ vCounter++;
+ FX_STEP;
+ if(USEX16(R15) == GSU.vBreakPoint)
+ {
+ GSU.vErrorCode = FX_BREAKPOINT;
+ break;
+ }
+ }
+ /*
+#ifndef FX_ADDRESS_CHECK
+ GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16);
+#endif
+*/
+ return vCounter;
+}
+
+static uint32 fx_step_over(uint32 nInstructions)
+{
+ uint32 vCounter = 0;
+ while(TF(G) && vCounter < nInstructions)
+ {
+ vCounter++;
+ FX_STEP;
+ if(USEX16(R15) == GSU.vBreakPoint)
+ {
+ GSU.vErrorCode = FX_BREAKPOINT;
+ break;
+ }
+ if(USEX16(R15) == GSU.vStepPoint)
+ break;
+ }
+ /*
+#ifndef FX_ADDRESS_CHECK
+ GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16);
+#endif
+*/
+ return vCounter;
+}
+
+#ifdef FX_FUNCTION_TABLE
+uint32 (*FX_FUNCTION_TABLE[])(uint32) =
+#else
+uint32 (*fx_apfFunctionTable[])(uint32) =
+#endif
+{
+ &fx_run,
+ &fx_run_to_breakpoint,
+ &fx_step_over,
+};
+
+/*** Special table for the different plot configurations ***/
+
+#ifdef FX_PLOT_TABLE
+void (*FX_PLOT_TABLE[])() =
+#else
+void (*fx_apfPlotTable[])() =
+#endif
+{
+ &fx_plot_2bit, &fx_plot_4bit, &fx_plot_4bit, &fx_plot_8bit, &fx_plot_obj,
+ &fx_rpix_2bit, &fx_rpix_4bit, &fx_rpix_4bit, &fx_rpix_8bit, &fx_rpix_obj,
+};
+
+/*** Opcode table ***/
+
+#ifdef FX_OPCODE_TABLE
+void (*FX_OPCODE_TABLE[])() =
+#else
+void (*fx_apfOpcodeTable[])() =
+#endif
+{
+ /*
+ * ALT0 Table
+ */
+ /* 00 - 0f */
+ &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt,
+ &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs,
+ /* 10 - 1f */
+ &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7,
+ &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15,
+ /* 20 - 2f */
+ &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7,
+ &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15,
+ /* 30 - 3f */
+ &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7,
+ &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3,
+ /* 40 - 4f */
+ &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7,
+ &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit,&fx_swap, &fx_color, &fx_not,
+ /* 50 - 5f */
+ &fx_add_r0, &fx_add_r1, &fx_add_r2, &fx_add_r3, &fx_add_r4, &fx_add_r5, &fx_add_r6, &fx_add_r7,
+ &fx_add_r8, &fx_add_r9, &fx_add_r10, &fx_add_r11, &fx_add_r12, &fx_add_r13, &fx_add_r14, &fx_add_r15,
+ /* 60 - 6f */
+ &fx_sub_r0, &fx_sub_r1, &fx_sub_r2, &fx_sub_r3, &fx_sub_r4, &fx_sub_r5, &fx_sub_r6, &fx_sub_r7,
+ &fx_sub_r8, &fx_sub_r9, &fx_sub_r10, &fx_sub_r11, &fx_sub_r12, &fx_sub_r13, &fx_sub_r14, &fx_sub_r15,
+ /* 70 - 7f */
+ &fx_merge, &fx_and_r1, &fx_and_r2, &fx_and_r3, &fx_and_r4, &fx_and_r5, &fx_and_r6, &fx_and_r7,
+ &fx_and_r8, &fx_and_r9, &fx_and_r10, &fx_and_r11, &fx_and_r12, &fx_and_r13, &fx_and_r14, &fx_and_r15,
+ /* 80 - 8f */
+ &fx_mult_r0, &fx_mult_r1, &fx_mult_r2, &fx_mult_r3, &fx_mult_r4, &fx_mult_r5, &fx_mult_r6, &fx_mult_r7,
+ &fx_mult_r8, &fx_mult_r9, &fx_mult_r10, &fx_mult_r11, &fx_mult_r12, &fx_mult_r13, &fx_mult_r14, &fx_mult_r15,
+ /* 90 - 9f */
+ &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror,
+ &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult,
+ /* a0 - af */
+ &fx_ibt_r0, &fx_ibt_r1, &fx_ibt_r2, &fx_ibt_r3, &fx_ibt_r4, &fx_ibt_r5, &fx_ibt_r6, &fx_ibt_r7,
+ &fx_ibt_r8, &fx_ibt_r9, &fx_ibt_r10, &fx_ibt_r11, &fx_ibt_r12, &fx_ibt_r13, &fx_ibt_r14, &fx_ibt_r15,
+ /* b0 - bf */
+ &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7,
+ &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15,
+ /* c0 - cf */
+ &fx_hib, &fx_or_r1, &fx_or_r2, &fx_or_r3, &fx_or_r4, &fx_or_r5, &fx_or_r6, &fx_or_r7,
+ &fx_or_r8, &fx_or_r9, &fx_or_r10, &fx_or_r11, &fx_or_r12, &fx_or_r13, &fx_or_r14, &fx_or_r15,
+ /* d0 - df */
+ &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7,
+ &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc,
+ /* e0 - ef */
+ &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7,
+ &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getb,
+ /* f0 - ff */
+ &fx_iwt_r0, &fx_iwt_r1, &fx_iwt_r2, &fx_iwt_r3, &fx_iwt_r4, &fx_iwt_r5, &fx_iwt_r6, &fx_iwt_r7,
+ &fx_iwt_r8, &fx_iwt_r9, &fx_iwt_r10, &fx_iwt_r11, &fx_iwt_r12, &fx_iwt_r13, &fx_iwt_r14, &fx_iwt_r15,
+
+ /*
+ * ALT1 Table
+ */
+
+ /* 00 - 0f */
+ &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt,
+ &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs,
+ /* 10 - 1f */
+ &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7,
+ &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15,
+ /* 20 - 2f */
+ &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7,
+ &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15,
+ /* 30 - 3f */
+ &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7,
+ &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3,
+ /* 40 - 4f */
+ &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7,
+ &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit,&fx_swap, &fx_cmode, &fx_not,
+ /* 50 - 5f */
+ &fx_adc_r0, &fx_adc_r1, &fx_adc_r2, &fx_adc_r3, &fx_adc_r4, &fx_adc_r5, &fx_adc_r6, &fx_adc_r7,
+ &fx_adc_r8, &fx_adc_r9, &fx_adc_r10, &fx_adc_r11, &fx_adc_r12, &fx_adc_r13, &fx_adc_r14, &fx_adc_r15,
+ /* 60 - 6f */
+ &fx_sbc_r0, &fx_sbc_r1, &fx_sbc_r2, &fx_sbc_r3, &fx_sbc_r4, &fx_sbc_r5, &fx_sbc_r6, &fx_sbc_r7,
+ &fx_sbc_r8, &fx_sbc_r9, &fx_sbc_r10, &fx_sbc_r11, &fx_sbc_r12, &fx_sbc_r13, &fx_sbc_r14, &fx_sbc_r15,
+ /* 70 - 7f */
+ &fx_merge, &fx_bic_r1, &fx_bic_r2, &fx_bic_r3, &fx_bic_r4, &fx_bic_r5, &fx_bic_r6, &fx_bic_r7,
+ &fx_bic_r8, &fx_bic_r9, &fx_bic_r10, &fx_bic_r11, &fx_bic_r12, &fx_bic_r13, &fx_bic_r14, &fx_bic_r15,
+ /* 80 - 8f */
+ &fx_umult_r0,&fx_umult_r1,&fx_umult_r2, &fx_umult_r3, &fx_umult_r4, &fx_umult_r5, &fx_umult_r6, &fx_umult_r7,
+ &fx_umult_r8,&fx_umult_r9,&fx_umult_r10,&fx_umult_r11,&fx_umult_r12,&fx_umult_r13,&fx_umult_r14,&fx_umult_r15,
+ /* 90 - 9f */
+ &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror,
+ &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult,
+ /* a0 - af */
+ &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7,
+ &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15,
+ /* b0 - bf */
+ &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7,
+ &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15,
+ /* c0 - cf */
+ &fx_hib, &fx_xor_r1, &fx_xor_r2, &fx_xor_r3, &fx_xor_r4, &fx_xor_r5, &fx_xor_r6, &fx_xor_r7,
+ &fx_xor_r8, &fx_xor_r9, &fx_xor_r10, &fx_xor_r11, &fx_xor_r12, &fx_xor_r13, &fx_xor_r14, &fx_xor_r15,
+ /* d0 - df */
+ &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7,
+ &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc,
+ /* e0 - ef */
+ &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7,
+ &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbh,
+ /* f0 - ff */
+ &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7,
+ &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15,
+
+ /*
+ * ALT2 Table
+ */
+
+ /* 00 - 0f */
+ &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt,
+ &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs,
+ /* 10 - 1f */
+ &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7,
+ &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15,
+ /* 20 - 2f */
+ &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7,
+ &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15,
+ /* 30 - 3f */
+ &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7,
+ &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3,
+ /* 40 - 4f */
+ &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7,
+ &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit,&fx_swap, &fx_color, &fx_not,
+ /* 50 - 5f */
+ &fx_add_i0, &fx_add_i1, &fx_add_i2, &fx_add_i3, &fx_add_i4, &fx_add_i5, &fx_add_i6, &fx_add_i7,
+ &fx_add_i8, &fx_add_i9, &fx_add_i10, &fx_add_i11, &fx_add_i12, &fx_add_i13, &fx_add_i14, &fx_add_i15,
+ /* 60 - 6f */
+ &fx_sub_i0, &fx_sub_i1, &fx_sub_i2, &fx_sub_i3, &fx_sub_i4, &fx_sub_i5, &fx_sub_i6, &fx_sub_i7,
+ &fx_sub_i8, &fx_sub_i9, &fx_sub_i10, &fx_sub_i11, &fx_sub_i12, &fx_sub_i13, &fx_sub_i14, &fx_sub_i15,
+ /* 70 - 7f */
+ &fx_merge, &fx_and_i1, &fx_and_i2, &fx_and_i3, &fx_and_i4, &fx_and_i5, &fx_and_i6, &fx_and_i7,
+ &fx_and_i8, &fx_and_i9, &fx_and_i10, &fx_and_i11, &fx_and_i12, &fx_and_i13, &fx_and_i14, &fx_and_i15,
+ /* 80 - 8f */
+ &fx_mult_i0, &fx_mult_i1, &fx_mult_i2, &fx_mult_i3, &fx_mult_i4, &fx_mult_i5, &fx_mult_i6, &fx_mult_i7,
+ &fx_mult_i8, &fx_mult_i9, &fx_mult_i10, &fx_mult_i11, &fx_mult_i12, &fx_mult_i13, &fx_mult_i14, &fx_mult_i15,
+ /* 90 - 9f */
+ &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror,
+ &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult,
+ /* a0 - af */
+ &fx_sms_r0, &fx_sms_r1, &fx_sms_r2, &fx_sms_r3, &fx_sms_r4, &fx_sms_r5, &fx_sms_r6, &fx_sms_r7,
+ &fx_sms_r8, &fx_sms_r9, &fx_sms_r10, &fx_sms_r11, &fx_sms_r12, &fx_sms_r13, &fx_sms_r14, &fx_sms_r15,
+ /* b0 - bf */
+ &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7,
+ &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15,
+ /* c0 - cf */
+ &fx_hib, &fx_or_i1, &fx_or_i2, &fx_or_i3, &fx_or_i4, &fx_or_i5, &fx_or_i6, &fx_or_i7,
+ &fx_or_i8, &fx_or_i9, &fx_or_i10, &fx_or_i11, &fx_or_i12, &fx_or_i13, &fx_or_i14, &fx_or_i15,
+ /* d0 - df */
+ &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7,
+ &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_ramb,
+ /* e0 - ef */
+ &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7,
+ &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbl,
+ /* f0 - ff */
+ &fx_sm_r0, &fx_sm_r1, &fx_sm_r2, &fx_sm_r3, &fx_sm_r4, &fx_sm_r5, &fx_sm_r6, &fx_sm_r7,
+ &fx_sm_r8, &fx_sm_r9, &fx_sm_r10, &fx_sm_r11, &fx_sm_r12, &fx_sm_r13, &fx_sm_r14, &fx_sm_r15,
+
+ /*
+ * ALT3 Table
+ */
+
+ /* 00 - 0f */
+ &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt,
+ &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs,
+ /* 10 - 1f */
+ &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7,
+ &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15,
+ /* 20 - 2f */
+ &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7,
+ &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15,
+ /* 30 - 3f */
+ &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7,
+ &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3,
+ /* 40 - 4f */
+ &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7,
+ &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit,&fx_swap, &fx_cmode, &fx_not,
+ /* 50 - 5f */
+ &fx_adc_i0, &fx_adc_i1, &fx_adc_i2, &fx_adc_i3, &fx_adc_i4, &fx_adc_i5, &fx_adc_i6, &fx_adc_i7,
+ &fx_adc_i8, &fx_adc_i9, &fx_adc_i10, &fx_adc_i11, &fx_adc_i12, &fx_adc_i13, &fx_adc_i14, &fx_adc_i15,
+ /* 60 - 6f */
+ &fx_cmp_r0, &fx_cmp_r1, &fx_cmp_r2, &fx_cmp_r3, &fx_cmp_r4, &fx_cmp_r5, &fx_cmp_r6, &fx_cmp_r7,
+ &fx_cmp_r8, &fx_cmp_r9, &fx_cmp_r10, &fx_cmp_r11, &fx_cmp_r12, &fx_cmp_r13, &fx_cmp_r14, &fx_cmp_r15,
+ /* 70 - 7f */
+ &fx_merge, &fx_bic_i1, &fx_bic_i2, &fx_bic_i3, &fx_bic_i4, &fx_bic_i5, &fx_bic_i6, &fx_bic_i7,
+ &fx_bic_i8, &fx_bic_i9, &fx_bic_i10, &fx_bic_i11, &fx_bic_i12, &fx_bic_i13, &fx_bic_i14, &fx_bic_i15,
+ /* 80 - 8f */
+ &fx_umult_i0,&fx_umult_i1,&fx_umult_i2, &fx_umult_i3, &fx_umult_i4, &fx_umult_i5, &fx_umult_i6, &fx_umult_i7,
+ &fx_umult_i8,&fx_umult_i9,&fx_umult_i10,&fx_umult_i11,&fx_umult_i12,&fx_umult_i13,&fx_umult_i14,&fx_umult_i15,
+ /* 90 - 9f */
+ &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror,
+ &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult,
+ /* a0 - af */
+ &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7,
+ &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15,
+ /* b0 - bf */
+ &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7,
+ &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15,
+ /* c0 - cf */
+ &fx_hib, &fx_xor_i1, &fx_xor_i2, &fx_xor_i3, &fx_xor_i4, &fx_xor_i5, &fx_xor_i6, &fx_xor_i7,
+ &fx_xor_i8, &fx_xor_i9, &fx_xor_i10, &fx_xor_i11, &fx_xor_i12, &fx_xor_i13, &fx_xor_i14, &fx_xor_i15,
+ /* d0 - df */
+ &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7,
+ &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_romb,
+ /* e0 - ef */
+ &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7,
+ &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbs,
+ /* f0 - ff */
+ &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7,
+ &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15,
+};
+
diff --git a/source/fxinst.h b/source/fxinst.h
new file mode 100644
index 0000000..43b6a28
--- /dev/null
+++ b/source/fxinst.h
@@ -0,0 +1,475 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _FXINST_H_
+#define _FXINST_H_ 1
+
+/*
+ * FxChip(GSU) register space specification
+ * (Register address space 3000->32ff)
+ *
+ * The 16 generic 16 bit registers:
+ * (Some have a special function in special circumstances)
+ * 3000 - R0 default source/destination register
+ * 3002 - R1 pixel plot X position register
+ * 3004 - R2 pixel plot Y position register
+ * 3006 - R3
+ * 3008 - R4 lower 16 bit result of lmult
+ * 300a - R5
+ * 300c - R6 multiplier for fmult and lmult
+ * 300e - R7 fixed point texel X position for merge
+ * 3010 - R8 fixed point texel Y position for merge
+ * 3012 - R9
+ * 3014 - R10
+ * 3016 - R11 return address set by link
+ * 3018 - R12 loop counter
+ * 301a - R13 loop point address
+ * 301c - R14 rom address for getb, getbh, getbl, getbs
+ * 301e - R15 program counter
+ *
+ * 3020-302f - unused
+ *
+ * Other internal registers
+ * 3030 - SFR status flag register (16bit)
+ * 3032 - unused
+ * 3033 - BRAMR Backup RAM register (8bit)
+ * 3034 - PBR program bank register (8bit)
+ * 3035 - unused
+ * 3036 - ROMBR rom bank register (8bit)
+ * 3037 - CFGR control flags register (8bit)
+ * 3038 - SCBR screen base register (8bit)
+ * 3039 - CLSR clock speed register (8bit)
+ * 303a - SCMR screen mode register (8bit)
+ * 303b - VCR version code register (8bit) (read only)
+ * 303c - RAMBR ram bank register (8bit)
+ * 303d - unused
+ * 303e - CBR cache base register (16bit)
+ *
+ * 3040-30ff - unused
+ *
+ * 3100-32ff - CACHERAM 512 bytes of GSU cache memory
+ *
+ * SFR status flag register bits:
+ * 0 -
+ * 1 Z Zero flag
+ * 2 CY Carry flag
+ * 3 S Sign flag
+ * 4 OV Overflow flag
+ * 5 G Go flag (set to 1 when the GSU is running)
+ * 6 R Set to 1 when reading ROM using R14 address
+ * 7 -
+ * 8 ALT1 Mode set-up flag for the next instruction
+ * 9 ALT2 Mode set-up flag for the next instruction
+ * 10 IL Immediate lower 8-bit flag
+ * 11 IH Immediate higher 8-bit flag
+ * 12 B Set to 1 when the WITH instruction is executed
+ * 13 -
+ * 14 -
+ * 15 IRQ Set to 1 when GSU caused an interrupt
+ * Set to 0 when read by 658c16
+ *
+ * BRAMR = 0, BackupRAM is disabled
+ * BRAMR = 1, BackupRAM is enabled
+ *
+ * CFGR control flags register bits:
+ * 0 -
+ * 1 -
+ * 2 -
+ * 3 -
+ * 4 -
+ * 5 MS0 Multiplier speed, 0=standard, 1=high speed
+ * 6 -
+ * 7 IRQ Set to 1 when GSU interrupt request is masked
+ *
+ * CLSR clock speed register bits:
+ * 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz
+ *
+ * SCMR screen mode register bits:
+ * 0 MD0 color depth mode bit 0
+ * 1 MD1 color depth mode bit 1
+ * 2 HT0 screen height bit 1
+ * 3 RAN RAM access control
+ * 4 RON ROM access control
+ * 5 HT1 screen height bit 2
+ * 6 -
+ * 7 -
+ *
+ * RON = 0 SNES CPU has ROM access
+ * RON = 1 GSU has ROM access
+ *
+ * RAN = 0 SNES has game pak RAM access
+ * RAN = 1 GSU has game pak RAM access
+ *
+ * HT1 HT0 Screen height mode
+ * 0 0 128 pixels high
+ * 0 1 160 pixels high
+ * 1 0 192 pixels high
+ * 1 1 OBJ mode
+ *
+ * MD1 MD0 Color depth mode
+ * 0 0 4 color mode
+ * 0 1 16 color mode
+ * 1 0 not used
+ * 1 1 256 color mode
+ *
+ * CBR cache base register bits:
+ * 15-4 Specify base address for data to cache from ROM or RAM
+ * 3-0 Are 0 when address is read
+ *
+ * Write access to the program counter (301e) from
+ * the SNES-CPU will start the GSU, and it will not
+ * stop until it reaches a stop instruction.
+ *
+ */
+
+/* Number of banks in GSU RAM */
+#define FX_RAM_BANKS 4
+
+/* Emulate proper R14 ROM access (slower, but safer) */
+/* #define FX_DO_ROMBUFFER */
+
+/* Address checking (definately slow) */
+/* #define FX_ADDRESS_CHECK */
+
+struct FxRegs_s
+{
+ /* FxChip registers */
+ uint32 avReg[16]; /* 16 Generic registers */
+ uint32 vColorReg; /* Internal color register */
+ uint32 vPlotOptionReg; /* Plot option register */
+ uint32 vStatusReg; /* Status register */
+ uint32 vPrgBankReg; /* Program bank index register */
+ uint32 vRomBankReg; /* Rom bank index register */
+ uint32 vRamBankReg; /* Ram bank index register */
+ uint32 vCacheBaseReg; /* Cache base address register */
+ uint32 vCacheFlags; /* Saying what parts of the cache was written to */
+ uint32 vLastRamAdr; /* Last RAM address accessed */
+ uint32 * pvDreg; /* Pointer to current destination register */
+ uint32 * pvSreg; /* Pointer to current source register */
+ uint8 vRomBuffer; /* Current byte read by R14 */
+ uint8 vPipe; /* Instructionset pipe */
+ uint32 vPipeAdr; /* The address of where the pipe was read from */
+
+ /* status register optimization stuff */
+ uint32 vSign; /* v & 0x8000 */
+ uint32 vZero; /* v == 0 */
+ uint32 vCarry; /* a value of 1 or 0 */
+ int32 vOverflow; /* (v >= 0x8000 || v < -0x8000) */
+
+ /* Other emulator variables */
+
+ int32 vErrorCode;
+ uint32 vIllegalAddress;
+
+ uint8 bBreakPoint;
+ uint32 vBreakPoint;
+ uint32 vStepPoint;
+
+ uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */
+ uint32 nRamBanks; /* Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!) */
+ uint8 * pvRam; /* Pointer to FxRam */
+ uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */
+ uint8 * pvRom; /* Pointer to Cart-ROM */
+
+ uint32 vMode; /* Color depth/mode */
+ uint32 vPrevMode; /* Previous depth */
+ uint8 * pvScreenBase;
+ uint8 * apvScreen[32]; /* Pointer to each of the 32 screen colums */
+ int x[32];
+ uint32 vScreenHeight; /* 128, 160, 192 or 256 (could be overriden by cmode) */
+ uint32 vScreenRealHeight; /* 128, 160, 192 or 256 */
+ uint32 vPrevScreenHeight;
+ uint32 vScreenSize;
+ void (*pfPlot)();
+ void (*pfRpix)();
+
+ uint8 * pvRamBank; /* Pointer to current RAM-bank */
+ uint8 * pvRomBank; /* Pointer to current ROM-bank */
+ uint8 * pvPrgBank; /* Pointer to current program ROM-bank */
+
+ uint8 * apvRamBank[FX_RAM_BANKS];/* Ram bank table (max 256kb) */
+ uint8 * apvRomBank[256]; /* Rom bank table */
+
+ uint8 bCacheActive;
+ uint8 * pvCache; /* Pointer to the GSU cache */
+ uint8 avCacheBackup[512]; /* Backup of ROM when the cache has replaced it */
+ uint32 vCounter;
+ uint32 vInstCount;
+ uint32 vSCBRDirty; /* if SCBR is written, our cached screen pointers need updating */
+};
+
+#define FxRegs_s_null { \
+ {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0, \
+ 0, NULL, {NULL}, {0}, 0, 0, 0, 0, NULL, NULL, \
+ NULL, NULL, NULL, {NULL}, {NULL}, 0, NULL, {0}, 0, 0, \
+}
+
+/* GSU registers */
+#define GSU_R0 0x000
+#define GSU_R1 0x002
+#define GSU_R2 0x004
+#define GSU_R3 0x006
+#define GSU_R4 0x008
+#define GSU_R5 0x00a
+#define GSU_R6 0x00c
+#define GSU_R7 0x00e
+#define GSU_R8 0x010
+#define GSU_R9 0x012
+#define GSU_R10 0x014
+#define GSU_R11 0x016
+#define GSU_R12 0x018
+#define GSU_R13 0x01a
+#define GSU_R14 0x01c
+#define GSU_R15 0x01e
+#define GSU_SFR 0x030
+#define GSU_BRAMR 0x033
+#define GSU_PBR 0x034
+#define GSU_ROMBR 0x036
+#define GSU_CFGR 0x037
+#define GSU_SCBR 0x038
+#define GSU_CLSR 0x039
+#define GSU_SCMR 0x03a
+#define GSU_VCR 0x03b
+#define GSU_RAMBR 0x03c
+#define GSU_CBR 0x03e
+#define GSU_CACHERAM 0x100
+
+/* SFR flags */
+#define FLG_Z (1<<1)
+#define FLG_CY (1<<2)
+#define FLG_S (1<<3)
+#define FLG_OV (1<<4)
+#define FLG_G (1<<5)
+#define FLG_R (1<<6)
+#define FLG_ALT1 (1<<8)
+#define FLG_ALT2 (1<<9)
+#define FLG_IL (1<<10)
+#define FLG_IH (1<<11)
+#define FLG_B (1<<12)
+#define FLG_IRQ (1<<15)
+
+/* Test flag */
+#define TF(a) (GSU.vStatusReg & FLG_##a )
+#define CF(a) (GSU.vStatusReg &= ~FLG_##a )
+#define SF(a) (GSU.vStatusReg |= FLG_##a )
+
+/* Test and set flag if condition, clear if not */
+#define TS(a,b) GSU.vStatusReg = ( (GSU.vStatusReg & (~FLG_##a)) | ( (!!(##b)) * FLG_##a ) )
+
+/* Testing ALT1 & ALT2 bits */
+#define ALT0 (!TF(ALT1)&&!TF(ALT2))
+#define ALT1 (TF(ALT1)&&!TF(ALT2))
+#define ALT2 (!TF(ALT1)&&TF(ALT2))
+#define ALT3 (TF(ALT1)&&TF(ALT2))
+
+/* Sign extend from 8/16 bit to 32 bit */
+#define SEX16(a) ((int32)((int16)(a)))
+#define SEX8(a) ((int32)((int8)(a)))
+
+/* Unsign extend from 8/16 bit to 32 bit */
+#define USEX16(a) ((uint32)((uint16)(a)))
+#define USEX8(a) ((uint32)((uint8)(a)))
+
+#define SUSEX16(a) ((int32)((uint16)(a)))
+
+/* Set/Clr Sign and Zero flag */
+#define TSZ(num) TS(S, (num & 0x8000)); TS(Z, (!USEX16(num)) )
+
+/* Clear flags */
+#define CLRFLAGS GSU.vStatusReg &= ~(FLG_ALT1|FLG_ALT2|FLG_B); GSU.pvDreg = GSU.pvSreg = &R0;
+
+/* Read current RAM-Bank */
+#define RAM(adr) GSU.pvRamBank[USEX16(adr)]
+
+/* Read current ROM-Bank */
+#define ROM(idx) (GSU.pvRomBank[USEX16(idx)])
+
+/* Access the current value in the pipe */
+#define PIPE GSU.vPipe
+
+/* Access data in the current program bank */
+#define PRGBANK(idx) GSU.pvPrgBank[USEX16(idx)]
+
+/* Update pipe from ROM */
+#if 0
+#define FETCHPIPE { PIPE = PRGBANK(R15); GSU.vPipeAdr = (GSU.vPrgBankReg<<16) + R15; }
+#else
+#define FETCHPIPE { PIPE = PRGBANK(R15); }
+#endif
+
+/* ABS */
+#define ABS(x) ((x)<0?-(x):(x))
+
+/* Access source register */
+#define SREG (*GSU.pvSreg)
+
+/* Access destination register */
+#define DREG (*GSU.pvDreg)
+
+#ifndef FX_DO_ROMBUFFER
+
+/* Don't read R14 */
+#define READR14
+
+/* Don't test and/or read R14 */
+#define TESTR14
+
+#else
+
+/* Read R14 */
+#define READR14 GSU.vRomBuffer = ROM(R14)
+
+/* Test and/or read R14 */
+#define TESTR14 if(GSU.pvDreg == &R14) READR14
+
+#endif
+
+/* Access to registers */
+#define R0 GSU.avReg[0]
+#define R1 GSU.avReg[1]
+#define R2 GSU.avReg[2]
+#define R3 GSU.avReg[3]
+#define R4 GSU.avReg[4]
+#define R5 GSU.avReg[5]
+#define R6 GSU.avReg[6]
+#define R7 GSU.avReg[7]
+#define R8 GSU.avReg[8]
+#define R9 GSU.avReg[9]
+#define R10 GSU.avReg[10]
+#define R11 GSU.avReg[11]
+#define R12 GSU.avReg[12]
+#define R13 GSU.avReg[13]
+#define R14 GSU.avReg[14]
+#define R15 GSU.avReg[15]
+#define SFR GSU.vStatusReg
+#define PBR GSU.vPrgBankReg
+#define ROMBR GSU.vRomBankReg
+#define RAMBR GSU.vRamBankReg
+#define CBR GSU.vCacheBaseReg
+#define SCBR USEX8(GSU.pvRegisters[GSU_SCBR])
+#define SCMR USEX8(GSU.pvRegisters[GSU_SCMR])
+#define COLR GSU.vColorReg
+#define POR GSU.vPlotOptionReg
+#define BRAMR USEX8(GSU.pvRegisters[GSU_BRAMR])
+#define VCR USEX8(GSU.pvRegisters[GSU_VCR])
+#define CFGR USEX8(GSU.pvRegisters[GSU_CFGR])
+#define CLSR USEX8(GSU.pvRegisters[GSU_CLSR])
+
+/* Execute instruction from the pipe, and fetch next byte to the pipe */
+#define FX_STEP { uint32 vOpcode = (uint32)PIPE; FETCHPIPE; \
+(*fx_ppfOpcodeTable[ (GSU.vStatusReg & 0x300) | vOpcode ])(); } \
+
+#define FX_FUNCTION_RUN 0
+#define FX_FUNCTION_RUN_TO_BREAKPOINT 1
+#define FX_FUNCTION_STEP_OVER 2
+
+extern uint32 (**fx_ppfFunctionTable)(uint32);
+extern void (**fx_ppfPlotTable)();
+extern void (**fx_ppfOpcodeTable)();
+
+extern uint32 (*fx_apfFunctionTable[])(uint32);
+extern void (*fx_apfOpcodeTable[])();
+extern void (*fx_apfPlotTable[])();
+extern uint32 (*fx_a_apfFunctionTable[])(uint32);
+extern void (*fx_a_apfOpcodeTable[])();
+extern void (*fx_a_apfPlotTable[])();
+extern uint32 (*fx_r_apfFunctionTable[])(uint32);
+extern void (*fx_r_apfOpcodeTable[])();
+extern void (*fx_r_apfPlotTable[])();
+extern uint32 (*fx_ar_apfFunctionTable[])(uint32);
+extern void (*fx_ar_apfOpcodeTable[])();
+extern void (*fx_ar_apfPlotTable[])();
+
+/* Set this define if branches are relative to the instruction in the delay slot */
+/* (I think they are) */
+#define BRANCH_DELAY_RELATIVE
+
+#endif
+
diff --git a/source/getset.h b/source/getset.h
new file mode 100644
index 0000000..2368ac2
--- /dev/null
+++ b/source/getset.h
@@ -0,0 +1,785 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _GETSET_H_
+#define _GETSET_H_
+
+#include "ppu.h"
+#include "dsp1.h"
+#include "cpuexec.h"
+#include "sa1.h"
+#include "spc7110.h"
+#include "obc1.h"
+#include "seta.h"
+
+extern "C"
+{
+ extern uint8 OpenBus;
+}
+
+INLINE uint8 S9xGetByte (uint32 Address)
+{
+ int block;
+ uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+
+ if(!CPU.InDMA)
+ CPU.Cycles += Memory.MemorySpeed [block];
+
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+#ifdef CPU_SHUTDOWN
+ if (Memory.BlockIsRAM [block])
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+#endif
+ return (*(GetAddress + (Address & 0xffff)));
+ }
+
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_PPU:
+ return (S9xGetPPU (Address & 0xffff));
+ case CMemory::MAP_CPU:
+ return (S9xGetCPU (Address & 0xffff));
+ case CMemory::MAP_DSP:
+#ifdef DSP_DUMMY_LOOPS
+ printf("Get DSP Byte @ %06X\n", Address);
+#endif
+ return (S9xGetDSP (Address & 0xffff));
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ //Address &0x7FFF -offset into bank
+ //Address&0xFF0000 -bank
+ //bank>>1 | offset = s-ram address, unbound
+ //unbound & SRAMMask = Sram offset
+ return (*(Memory.SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask)));
+// return (*(Memory.SRAM + ((Address & Memory.SRAMMask))));
+
+ case CMemory::MAP_RONLY_SRAM:
+ case CMemory::MAP_HIROM_SRAM:
+ return (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 +
+ ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)));
+
+ case CMemory::MAP_BWRAM:
+ return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)));
+
+ case CMemory::MAP_C4:
+ return (S9xGetC4 (Address & 0xffff));
+
+ case CMemory::MAP_SPC7110_ROM:
+#ifdef SPC7110_DEBUG
+ printf("reading spc7110 ROM (byte) at %06X\n", Address);
+#endif
+ return S9xGetSPC7110Byte(Address);
+
+ case CMemory::MAP_SPC7110_DRAM:
+#ifdef SPC7110_DEBUG
+ printf("reading Bank 50 (byte)\n");
+#endif
+ return S9xGetSPC7110(0x4800);
+
+ case CMemory::MAP_OBC_RAM:
+ return GetOBC1(Address & 0xffff);
+
+ case CMemory::MAP_SETA_DSP:
+ return S9xGetSetaDSP(Address);
+
+ case CMemory::MAP_SETA_RISC:
+ return S9xGetST018(Address);
+
+
+
+ case CMemory::MAP_DEBUG:
+ #ifdef DEBUGGER
+ printf ("DEBUG R(B) %06x\n", Address);
+ #endif
+ return OpenBus;
+
+
+
+ default:
+ case CMemory::MAP_NONE:
+#ifdef MK_TRACE_BAD_READS
+ char address[20];
+ sprintf(address, TEXT("%06X"),Address);
+ MessageBox(GUI.hWnd, address, TEXT("GetByte"), MB_OK);
+#endif
+
+#ifdef DEBUGGER
+ printf ("R(B) %06x\n", Address);
+#endif
+ return OpenBus;
+ }
+}
+
+INLINE uint16 S9xGetWord (uint32 Address)
+{
+ if ((Address & 0x0fff) == 0x0fff)
+ {
+ OpenBus=S9xGetByte (Address);
+ return (OpenBus | (S9xGetByte (Address + 1) << 8));
+ }
+ int block;
+ uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+
+ if(!CPU.InDMA)
+ CPU.Cycles += (Memory.MemorySpeed [block]<<1);
+
+
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+#ifdef CPU_SHUTDOWN
+ if (Memory.BlockIsRAM [block])
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+#endif
+#ifdef FAST_LSB_WORD_ACCESS
+ return (*(uint16 *) (GetAddress + (Address & 0xffff)));
+#else
+ return (*(GetAddress + (Address & 0xffff)) |
+ (*(GetAddress + (Address & 0xffff) + 1) << 8));
+#endif
+ }
+
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_PPU:
+ return (S9xGetPPU (Address & 0xffff) |
+ (S9xGetPPU ((Address + 1) & 0xffff) << 8));
+ case CMemory::MAP_CPU:
+ return (S9xGetCPU (Address & 0xffff) |
+ (S9xGetCPU ((Address + 1) & 0xffff) << 8));
+ case CMemory::MAP_DSP:
+#ifdef DSP_DUMMY_LOOPS
+ printf("Get DSP Word @ %06X\n", Address);
+#endif
+ return (S9xGetDSP (Address & 0xffff) |
+ (S9xGetDSP ((Address + 1) & 0xffff) << 8));
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ //Address &0x7FFF -offset into bank
+ //Address&0xFF0000 -bank
+ //bank>>1 | offset = s-ram address, unbound
+ //unbound & SRAMMask = Sram offset
+ /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff
+ * then the high byte doesn't follow the low byte. */
+ return
+ (*(Memory.SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask)))|
+ ((*(Memory.SRAM + (((((Address+1)&0xFF0000)>>1) |((Address+1)&0x7FFF)) &Memory.SRAMMask)))<<8);
+
+ //return (*(uint16*)(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF)) & Memory.SRAMMask));// |
+ // (*(Memory.SRAM + ((Address + 1) & Memory.SRAMMask)) << 8));
+
+ case CMemory::MAP_RONLY_SRAM:
+ case CMemory::MAP_HIROM_SRAM:
+ /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff
+ * then the high byte doesn't follow the low byte. */
+ return (*(Memory.SRAM +
+ (((Address & 0x7fff) - 0x6000 +
+ ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) |
+ (*(Memory.SRAM +
+ ((((Address + 1) & 0x7fff) - 0x6000 +
+ (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8));
+
+ case CMemory::MAP_BWRAM:
+#ifdef FAST_LSB_WORD_ACCESS
+ return (*(uint16 *) (Memory.BWRAM + ((Address & 0x7fff) - 0x6000)));
+#else
+ return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) |
+ (*(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) << 8));
+#endif
+
+ case CMemory::MAP_C4:
+ return (S9xGetC4 (Address & 0xffff) |
+ (S9xGetC4 ((Address + 1) & 0xffff) << 8));
+
+ case CMemory::MAP_SPC7110_ROM:
+#ifdef SPC7110_DEBUG
+ printf("reading spc7110 ROM (word) at %06X\n", Address);
+#endif
+ return (S9xGetSPC7110Byte(Address)|
+ (S9xGetSPC7110Byte (Address+1))<<8);
+ case CMemory::MAP_SPC7110_DRAM:
+#ifdef SPC7110_DEBUG
+ printf("reading Bank 50 (word)\n");
+#endif
+ return (S9xGetSPC7110(0x4800)|
+ (S9xGetSPC7110 (0x4800) << 8));
+ case CMemory::MAP_OBC_RAM:
+ return GetOBC1(Address&0xFFFF)| (GetOBC1((Address+1)&0xFFFF)<<8);
+
+ case CMemory::MAP_SETA_DSP:
+ return S9xGetSetaDSP(Address)| (S9xGetSetaDSP((Address+1))<<8);
+
+ case CMemory::MAP_SETA_RISC:
+ return S9xGetST018(Address)| (S9xGetST018((Address+1))<<8);
+
+ case CMemory::MAP_DEBUG:
+ #ifdef DEBUGGER
+ printf ("DEBUG R(W) %06x\n", Address);
+ #endif
+ return (OpenBus | (OpenBus<<8));
+
+
+ default:
+ case CMemory::MAP_NONE:
+#ifdef MK_TRACE_BAD_READS
+ char address[20];
+ sprintf(address, TEXT("%06X"),Address);
+ MessageBox(GUI.hWnd, address, TEXT("GetWord"), MB_OK);
+#endif
+
+#ifdef DEBUGGER
+ printf ("R(W) %06x\n", Address);
+#endif
+ return (OpenBus | (OpenBus<<8));
+ }
+}
+
+INLINE void S9xSetByte (uint8 Byte, uint32 Address)
+{
+#if defined(CPU_SHUTDOWN)
+ CPU.WaitAddress = NULL;
+#endif
+ int block;
+ uint8 *SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)];
+
+ if (!CPU.InDMA)
+ CPU.Cycles += Memory.MemorySpeed [block];
+
+
+ if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+#ifdef CPU_SHUTDOWN
+ SetAddress += Address & 0xffff;
+ if (SetAddress == SA1.WaitByteAddress1 ||
+ SetAddress == SA1.WaitByteAddress2)
+ {
+ SA1.Executing = SA1.S9xOpcodes != NULL;
+ SA1.WaitCounter = 0;
+ }
+ *SetAddress = Byte;
+#else
+ *(SetAddress + (Address & 0xffff)) = Byte;
+#endif
+ return;
+ }
+
+ switch ((int) SetAddress)
+ {
+ case CMemory::MAP_PPU:
+ S9xSetPPU (Byte, Address & 0xffff);
+ return;
+
+ case CMemory::MAP_CPU:
+ S9xSetCPU (Byte, Address & 0xffff);
+ return;
+
+ case CMemory::MAP_DSP:
+#ifdef DSP_DUMMY_LOOPS
+ printf("DSP Byte: %02X to %06X\n", Byte, Address);
+#endif
+ S9xSetDSP (Byte, Address & 0xffff);
+ return;
+
+ case CMemory::MAP_LOROM_SRAM:
+ if (Memory.SRAMMask)
+ {
+ *(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))& Memory.SRAMMask))=Byte;
+// *(Memory.SRAM + (Address & Memory.SRAMMask)) = Byte;
+ CPU.SRAMModified = TRUE;
+ }
+ return;
+
+ case CMemory::MAP_HIROM_SRAM:
+ if (Memory.SRAMMask)
+ {
+ *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 +
+ ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = Byte;
+ CPU.SRAMModified = TRUE;
+ }
+ return;
+
+ case CMemory::MAP_BWRAM:
+ *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte;
+ CPU.SRAMModified = TRUE;
+ return;
+
+ case CMemory::MAP_DEBUG:
+#ifdef DEBUGGER
+ printf ("W(B) %06x\n", Address);
+#endif
+
+ case CMemory::MAP_SA1RAM:
+ *(Memory.SRAM + (Address & 0xffff)) = Byte;
+ SA1.Executing = !SA1.Waiting;
+ break;
+
+ case CMemory::MAP_C4:
+ S9xSetC4 (Byte, Address & 0xffff);
+ return;
+
+ case CMemory::MAP_SPC7110_DRAM:
+#ifdef SPC7110_DEBUG
+ printf("Writing Byte at %06X\n", Address);
+#endif
+ s7r.bank50[(Address & 0xffff)]= (uint8) Byte;
+ break;
+
+ case CMemory::MAP_OBC_RAM:
+ SetOBC1(Byte, Address &0xFFFF);
+ return;
+
+ case CMemory::MAP_SETA_DSP:
+ S9xSetSetaDSP(Byte,Address);
+ return;
+
+ case CMemory::MAP_SETA_RISC:
+ S9xSetST018(Byte,Address);
+ return;
+ default:
+ case CMemory::MAP_NONE:
+#ifdef MK_TRACE_BAD_WRITES
+ char address[20];
+ sprintf(address, TEXT("%06X"),Address);
+ MessageBox(GUI.hWnd, address, TEXT("SetByte"), MB_OK);
+#endif
+
+#ifdef DEBUGGER
+ printf ("W(B) %06x\n", Address);
+#endif
+ return;
+ }
+}
+
+INLINE void S9xSetWord (uint16 Word, uint32 Address)
+{
+ if((Address & 0x0FFF)==0x0FFF)
+ {
+ S9xSetByte(Word&0x00FF, Address);
+ S9xSetByte(Word>>8, Address+1);
+ return;
+ }
+
+#if defined(CPU_SHUTDOWN)
+ CPU.WaitAddress = NULL;
+#endif
+ int block;
+ uint8 *SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)];
+
+ if (!CPU.InDMA)
+ CPU.Cycles += Memory.MemorySpeed [block] << 1;
+
+
+ if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+#ifdef CPU_SHUTDOWN
+ SetAddress += Address & 0xffff;
+ if (SetAddress == SA1.WaitByteAddress1 ||
+ SetAddress == SA1.WaitByteAddress2)
+ {
+ SA1.Executing = SA1.S9xOpcodes != NULL;
+ SA1.WaitCounter = 0;
+ }
+#ifdef FAST_LSB_WORD_ACCESS
+ *(uint16 *) SetAddress = Word;
+#else
+ *SetAddress = (uint8) Word;
+ *(SetAddress + 1) = Word >> 8;
+#endif
+#else
+#ifdef FAST_LSB_WORD_ACCESS
+ *(uint16 *) (SetAddress + (Address & 0xffff)) = Word;
+#else
+ *(SetAddress + (Address & 0xffff)) = (uint8) Word;
+ *(SetAddress + ((Address + 1) & 0xffff)) = Word >> 8;
+#endif
+#endif
+ return;
+ }
+
+ switch ((int) SetAddress)
+ {
+ case CMemory::MAP_PPU:
+ S9xSetPPU ((uint8) Word, Address & 0xffff);
+ S9xSetPPU (Word >> 8, (Address & 0xffff) + 1);
+ return;
+
+ case CMemory::MAP_CPU:
+ S9xSetCPU ((uint8) Word, (Address & 0xffff));
+ S9xSetCPU (Word >> 8, (Address & 0xffff) + 1);
+ return;
+
+ case CMemory::MAP_DSP:
+#ifdef DSP_DUMMY_LOOPS
+ printf("DSP Word: %04X to %06X\n", Word, Address);
+#endif
+ S9xSetDSP ((uint8) Word, (Address & 0xffff));
+ S9xSetDSP (Word >> 8, (Address & 0xffff) + 1);
+ return;
+
+ case CMemory::MAP_LOROM_SRAM:
+ if (Memory.SRAMMask)
+ {
+ /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff
+ * then the high byte doesn't follow the low byte. */
+ *(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))& Memory.SRAMMask)) = (uint8) Word;
+ *(Memory.SRAM + (((((Address+1)&0xFF0000)>>1)|((Address+1)&0x7FFF))& Memory.SRAMMask)) = Word >> 8;
+
+// *(Memory.SRAM + (Address & Memory.SRAMMask)) = (uint8) Word;
+// *(Memory.SRAM + ((Address + 1) & Memory.SRAMMask)) = Word >> 8;
+ CPU.SRAMModified = TRUE;
+ }
+ return;
+
+ case CMemory::MAP_HIROM_SRAM:
+ if (Memory.SRAMMask)
+ {
+ /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff
+ * then the high byte doesn't follow the low byte. */
+ *(Memory.SRAM +
+ (((Address & 0x7fff) - 0x6000 +
+ ((Address & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) Word;
+ *(Memory.SRAM +
+ ((((Address + 1) & 0x7fff) - 0x6000 +
+ (((Address + 1) & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) (Word >> 8);
+ CPU.SRAMModified = TRUE;
+ }
+ return;
+
+ case CMemory::MAP_BWRAM:
+#ifdef FAST_LSB_WORD_ACCESS
+ *(uint16 *) (Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Word;
+#else
+ *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = (uint8) Word;
+ *(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) = (uint8) (Word >> 8);
+#endif
+ CPU.SRAMModified = TRUE;
+ return;
+
+ case CMemory::MAP_DEBUG:
+#ifdef DEBUGGER
+ printf ("W(W) %06x\n", Address);
+#endif
+
+ case CMemory::MAP_SPC7110_DRAM:
+#ifdef SPC7110_DEBUG
+ printf("Writing Word at %06X\n", Address);
+#endif
+ s7r.bank50[(Address & 0xffff)]= (uint8) Word;
+ s7r.bank50[((Address + 1) & 0xffff)]= (uint8) Word;
+ break;
+ case CMemory::MAP_SA1RAM:
+ *(Memory.SRAM + (Address & 0xffff)) = (uint8) Word;
+ *(Memory.SRAM + ((Address + 1) & 0xffff)) = (uint8) (Word >> 8);
+ SA1.Executing = !SA1.Waiting;
+ break;
+
+ case CMemory::MAP_C4:
+ S9xSetC4 (Word & 0xff, Address & 0xffff);
+ S9xSetC4 ((uint8) (Word >> 8), (Address + 1) & 0xffff);
+ return;
+
+ case CMemory::MAP_OBC_RAM:
+ SetOBC1(Word & 0xff, Address &0xFFFF);
+ SetOBC1 ((uint8) (Word >> 8), (Address + 1) & 0xffff);
+ return;
+
+ case CMemory::MAP_SETA_DSP:
+ S9xSetSetaDSP (Word & 0xff, Address);
+ S9xSetSetaDSP ((uint8) (Word >> 8),(Address + 1));
+ return;
+
+ case CMemory::MAP_SETA_RISC:
+ S9xSetST018 (Word & 0xff, Address);
+ S9xSetST018 ((uint8) (Word >> 8),(Address + 1));
+ return;
+
+ default:
+ case CMemory::MAP_NONE:
+#ifdef MK_TRACE_BAD_WRITES
+ char address[20];
+ sprintf(address, TEXT("%06X"),Address);
+ MessageBox(GUI.hWnd, address, TEXT("SetWord"), MB_OK);
+#endif
+
+#ifdef DEBUGGER
+ printf ("W(W) %06x\n", Address);
+#endif
+ return;
+ }
+}
+
+INLINE uint8 *GetBasePointer (uint32 Address)
+{
+ uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ return (GetAddress);
+ if(Settings.SPC7110&&((Address&0x7FFFFF)==0x4800))
+ {
+ return s7r.bank50;
+ }
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_SPC7110_DRAM:
+#ifdef SPC7110_DEBUG
+ printf("Getting Base pointer to DRAM\n");
+#endif
+ {
+ return s7r.bank50;
+ }
+ case CMemory::MAP_SPC7110_ROM:
+#ifdef SPC7110_DEBUG
+ printf("Getting Base pointer to SPC7110ROM\n");
+#endif
+ return Get7110BasePtr(Address);
+ case CMemory::MAP_PPU:
+//just a guess, but it looks like this should match the CPU as a source.
+ return (Memory.FillRAM);
+// return (Memory.FillRAM - 0x2000);
+ case CMemory::MAP_CPU:
+//fixes Ogre Battle's green lines
+ return (Memory.FillRAM);
+// return (Memory.FillRAM - 0x4000);
+ case CMemory::MAP_DSP:
+ return (Memory.FillRAM - 0x6000);
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ return (Memory.SRAM);
+ case CMemory::MAP_BWRAM:
+ return (Memory.BWRAM - 0x6000);
+ case CMemory::MAP_HIROM_SRAM:
+ return (Memory.SRAM - 0x6000);
+ case CMemory::MAP_C4:
+ return (Memory.C4RAM - 0x6000);
+ case CMemory::MAP_OBC_RAM:
+ return GetBasePointerOBC1(Address);
+ case CMemory::MAP_SETA_DSP:
+ return Memory.SRAM;
+ case CMemory::MAP_DEBUG:
+#ifdef DEBUGGER
+ printf ("GBP %06x\n", Address);
+#endif
+
+ default:
+ case CMemory::MAP_NONE:
+#if defined(MK_TRACE_BAD_READS) || defined(MK_TRACE_BAD_WRITES)
+ char fsd[12];
+ sprintf(fsd, TEXT("%06X"), Address);
+ MessageBox(GUI.hWnd, fsd, TEXT("Rogue DMA"), MB_OK);
+#endif
+
+#ifdef DEBUGGER
+ printf ("GBP %06x\n", Address);
+#endif
+ return (0);
+ }
+}
+
+INLINE uint8 *S9xGetMemPointer (uint32 Address)
+{
+ uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ return (GetAddress + (Address & 0xffff));
+
+ if(Settings.SPC7110&&((Address&0x7FFFFF)==0x4800))
+ return s7r.bank50;
+
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_SPC7110_DRAM:
+#ifdef SPC7110_DEBUG
+ printf("Getting Base pointer to DRAM\n");
+#endif
+ return &s7r.bank50[Address&0x0000FFFF];
+ case CMemory::MAP_PPU:
+ return (Memory.FillRAM + (Address & 0xffff));
+ case CMemory::MAP_CPU:
+ return (Memory.FillRAM + (Address & 0xffff));
+ case CMemory::MAP_DSP:
+ return (Memory.FillRAM - 0x6000 + (Address & 0xffff));
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ return (Memory.SRAM + (Address & 0xffff));
+ case CMemory::MAP_BWRAM:
+ return (Memory.BWRAM - 0x6000 + (Address & 0xffff));
+ case CMemory::MAP_HIROM_SRAM:
+ return (Memory.SRAM - 0x6000 + (Address & 0xffff));
+ case CMemory::MAP_C4:
+ return (Memory.C4RAM - 0x6000 + (Address & 0xffff));
+ case CMemory::MAP_OBC_RAM:
+ return GetMemPointerOBC1(Address);
+ case CMemory::MAP_SETA_DSP:
+ return Memory.SRAM+ ((Address & 0xffff) & Memory.SRAMMask);
+ case CMemory::MAP_DEBUG:
+#ifdef DEBUGGER
+ printf ("GMP %06x\n", Address);
+#endif
+ default:
+ case CMemory::MAP_NONE:
+#if defined(MK_TRACE_BAD_READS) || defined(MK_TRACE_BAD_WRITES)
+ char fsd[12];
+ sprintf(fsd, TEXT("%06X"), Address);
+ MessageBox(GUI.hWnd, fsd, TEXT("Rogue DMA"), MB_OK);
+#endif
+
+#ifdef DEBUGGER
+ printf ("GMP %06x\n", Address);
+#endif
+ return (0);
+ }
+}
+
+INLINE void S9xSetPCBase (uint32 Address)
+{
+ int block;
+ uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+
+ CPU.MemSpeed = Memory.MemorySpeed [block];
+ CPU.MemSpeedx2 = CPU.MemSpeed << 1;
+
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+ CPU.PCBase = GetAddress;
+ CPU.PC = GetAddress + (Address & 0xffff);
+ return;
+ }
+
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_PPU:
+ CPU.PCBase = Memory.FillRAM;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+
+ case CMemory::MAP_CPU:
+ CPU.PCBase = Memory.FillRAM;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+
+ case CMemory::MAP_DSP:
+ CPU.PCBase = Memory.FillRAM - 0x6000;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ CPU.PCBase = Memory.SRAM;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+
+ case CMemory::MAP_BWRAM:
+ CPU.PCBase = Memory.BWRAM - 0x6000;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+ case CMemory::MAP_HIROM_SRAM:
+ CPU.PCBase = Memory.SRAM - 0x6000;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+
+ case CMemory::MAP_C4:
+ CPU.PCBase = Memory.C4RAM - 0x6000;
+ CPU.PC = CPU.PCBase + (Address & 0xffff);
+ return;
+
+ case CMemory::MAP_DEBUG:
+#ifdef DEBUGGER
+ printf ("SBP %06x\n", Address);
+#endif
+
+ default:
+ case CMemory::MAP_NONE:
+#ifdef DEBUGGER
+ printf ("SBP %06x\n", Address);
+#endif
+ CPU.PCBase = Memory.SRAM;
+ CPU.PC = Memory.SRAM + (Address & 0xffff);
+ return;
+ }
+}
+#endif
+
diff --git a/source/gfx.cpp b/source/gfx.cpp
new file mode 100644
index 0000000..14e28a5
--- /dev/null
+++ b/source/gfx.cpp
@@ -0,0 +1,4026 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+
+#include "memmap.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "display.h"
+#include "gfx.h"
+#include "apu.h"
+#include "cheats.h"
+#include "screenshot.h"
+
+#define M7 19
+#define M8 19
+
+void output_png();
+void ComputeClipWindows ();
+static void S9xDisplayFrameRate ();
+static void S9xDisplayString (const char *string);
+
+extern uint8 BitShifts[8][4];
+extern uint8 TileShifts[8][4];
+extern uint8 PaletteShifts[8][4];
+extern uint8 PaletteMasks[8][4];
+extern uint8 Depths[8][4];
+extern uint8 BGSizes [2];
+
+extern NormalTileRenderer DrawTilePtr;
+extern ClippedTileRenderer DrawClippedTilePtr;
+extern NormalTileRenderer DrawHiResTilePtr;
+extern ClippedTileRenderer DrawHiResClippedTilePtr;
+extern LargePixelRenderer DrawLargePixelPtr;
+
+extern struct SBG BG;
+
+extern struct SLineData LineData[240];
+extern struct SLineMatrixData LineMatrixData [240];
+
+extern uint8 Mode7Depths [2];
+
+#define CLIP_10_BIT_SIGNED(a) \
+ ((a) & ((1 << 10) - 1)) + (((((a) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3)
+
+#define ON_MAIN(N) \
+(GFX.r212c & (1 << (N)) && \
+ !(PPU.BG_Forced & (1 << (N))))
+
+#define SUB_OR_ADD(N) \
+(GFX.r2131 & (1 << (N)))
+
+#define ON_SUB(N) \
+((GFX.r2130 & 0x30) != 0x30 && \
+ (GFX.r2130 & 2) && \
+ (GFX.r212d & (1 << N)) && \
+ !(PPU.BG_Forced & (1 << (N))))
+
+#define ANYTHING_ON_SUB \
+((GFX.r2130 & 0x30) != 0x30 && \
+ (GFX.r2130 & 2) && \
+ (GFX.r212d & 0x1f))
+
+#define ADD_OR_SUB_ON_ANYTHING \
+(GFX.r2131 & 0x3f)
+
+#define FIX_INTERLACE(SCREEN, DO_DEPTH, DEPTH) \
+ if (IPPU.DoubleHeightPixels && ((PPU.BGMode != 5 && PPU.BGMode != 6) || !IPPU.Interlace)) \
+ for (uint32 y = GFX.StartY; y <= GFX.EndY; y++) \
+ { \
+ memmove (SCREEN + (y * 2 + 1) * GFX.Pitch2, \
+ SCREEN + y * 2 * GFX.Pitch2, \
+ GFX.Pitch2); \
+ if(DO_DEPTH){ \
+ memmove (DEPTH + (y * 2 + 1) * (GFX.PPLx2>>1), \
+ DEPTH + y * GFX.PPL, \
+ GFX.PPLx2>>1); \
+ } \
+ }
+
+
+#define BLACK BUILD_PIXEL(0,0,0)
+
+void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTile (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTilex2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+void DrawTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+void DrawLargePixel (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTile16 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTile16x2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+void DrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTile16x2x2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+void DrawLargePixel16 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+
+void DrawClippedTile16Add (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+
+void DrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+
+void DrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+
+void DrawClippedTile16Sub (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+
+void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+
+void DrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawLargePixel16Add (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawLargePixel16Sub (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+void DrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+bool8 S9xGraphicsInit ()
+{
+ register uint32 PixelOdd = 1;
+ register uint32 PixelEven = 2;
+
+#ifdef GFX_MULTI_FORMAT
+ if (GFX.BuildPixel == NULL)
+ S9xSetRenderPixelFormat (RGB565);
+#endif
+
+ for (uint8 bitshift = 0; bitshift < 4; bitshift++)
+ {
+ for (register int i = 0; i < 16; i++)
+ {
+ register uint32 h = 0;
+ register uint32 l = 0;
+
+#if defined(LSB_FIRST)
+ if (i & 8)
+ h |= PixelOdd;
+ if (i & 4)
+ h |= PixelOdd << 8;
+ if (i & 2)
+ h |= PixelOdd << 16;
+ if (i & 1)
+ h |= PixelOdd << 24;
+ if (i & 8)
+ l |= PixelOdd;
+ if (i & 4)
+ l |= PixelOdd << 8;
+ if (i & 2)
+ l |= PixelOdd << 16;
+ if (i & 1)
+ l |= PixelOdd << 24;
+#else
+ if (i & 8)
+ h |= (PixelOdd << 24);
+ if (i & 4)
+ h |= (PixelOdd << 16);
+ if (i & 2)
+ h |= (PixelOdd << 8);
+ if (i & 1)
+ h |= PixelOdd;
+ if (i & 8)
+ l |= (PixelOdd << 24);
+ if (i & 4)
+ l |= (PixelOdd << 16);
+ if (i & 2)
+ l |= (PixelOdd << 8);
+ if (i & 1)
+ l |= PixelOdd;
+#endif
+
+ odd_high[bitshift][i] = h;
+ odd_low[bitshift][i] = l;
+ h = l = 0;
+
+#if defined(LSB_FIRST)
+ if (i & 8)
+ h |= PixelEven;
+ if (i & 4)
+ h |= PixelEven << 8;
+ if (i & 2)
+ h |= PixelEven << 16;
+ if (i & 1)
+ h |= PixelEven << 24;
+ if (i & 8)
+ l |= PixelEven;
+ if (i & 4)
+ l |= PixelEven << 8;
+ if (i & 2)
+ l |= PixelEven << 16;
+ if (i & 1)
+ l |= PixelEven << 24;
+#else
+ if (i & 8)
+ h |= (PixelEven << 24);
+ if (i & 4)
+ h |= (PixelEven << 16);
+ if (i & 2)
+ h |= (PixelEven << 8);
+ if (i & 1)
+ h |= PixelEven;
+ if (i & 8)
+ l |= (PixelEven << 24);
+ if (i & 4)
+ l |= (PixelEven << 16);
+ if (i & 2)
+ l |= (PixelEven << 8);
+ if (i & 1)
+ l |= PixelEven;
+#endif
+
+ even_high[bitshift][i] = h;
+ even_low[bitshift][i] = l;
+ }
+ PixelEven <<= 2;
+ PixelOdd <<= 2;
+ }
+
+ GFX.RealPitch = GFX.Pitch2 = GFX.Pitch;
+ GFX.ZPitch = GFX.Pitch;
+ if (Settings.SixteenBit)
+ GFX.ZPitch >>= 1;
+ GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
+ GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer;
+ //GFX.InfoStringTimeout = 0;
+ //GFX.InfoString = NULL;
+
+ PPU.BG_Forced = 0;
+ IPPU.OBJChanged = TRUE;
+ if (Settings.Transparency)
+ Settings.SixteenBit = TRUE;
+
+ IPPU.DirectColourMapsNeedRebuild = TRUE;
+ GFX.PixSize = 1;
+ if (Settings.SixteenBit)
+ {
+ DrawTilePtr = DrawTile16;
+ DrawClippedTilePtr = DrawClippedTile16;
+ DrawLargePixelPtr = DrawLargePixel16;
+ DrawHiResTilePtr= DrawTile16;
+ DrawHiResClippedTilePtr = DrawClippedTile16;
+ GFX.PPL = GFX.Pitch >> 1;
+ GFX.PPLx2 = GFX.Pitch;
+ }
+ else
+ {
+ DrawTilePtr = DrawTile;
+ DrawClippedTilePtr = DrawClippedTile;
+ DrawLargePixelPtr = DrawLargePixel;
+ DrawHiResTilePtr = DrawTile;
+ DrawHiResClippedTilePtr = DrawClippedTile;
+ GFX.PPL = GFX.Pitch;
+ GFX.PPLx2 = GFX.Pitch * 2;
+ }
+ S9xFixColourBrightness ();
+
+ if (Settings.SixteenBit)
+ {
+ if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000)))
+ return (FALSE);
+
+ if (!(GFX.ZERO_OR_X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000)) ||
+ !(GFX.ZERO = (uint16 *) malloc (sizeof (uint16) * 0x10000)))
+ {
+ if (GFX.ZERO_OR_X2)
+ {
+ free ((char *) GFX.ZERO_OR_X2);
+ GFX.ZERO_OR_X2 = NULL;
+ }
+ if (GFX.X2)
+ {
+ free ((char *) GFX.X2);
+ GFX.X2 = NULL;
+ }
+ return (FALSE);
+ }
+ uint32 r, g, b;
+
+ // Build a lookup table that multiplies a packed RGB value by 2 with
+ // saturation.
+ for (r = 0; r <= MAX_RED; r++)
+ {
+ uint32 r2 = r << 1;
+ if (r2 > MAX_RED)
+ r2 = MAX_RED;
+ for (g = 0; g <= MAX_GREEN; g++)
+ {
+ uint32 g2 = g << 1;
+ if (g2 > MAX_GREEN)
+ g2 = MAX_GREEN;
+ for (b = 0; b <= MAX_BLUE; b++)
+ {
+ uint32 b2 = b << 1;
+ if (b2 > MAX_BLUE)
+ b2 = MAX_BLUE;
+ GFX.X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2);
+ GFX.X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2);
+ }
+ }
+ }
+ ZeroMemory (GFX.ZERO, 0x10000 * sizeof (uint16));
+ ZeroMemory (GFX.ZERO_OR_X2, 0x10000 * sizeof (uint16));
+ // Build a lookup table that if the top bit of the color value is zero
+ // then the value is zero, otherwise multiply the value by 2. Used by
+ // the color subtraction code.
+
+#if defined(OLD_COLOUR_BLENDING)
+ for (r = 0; r <= MAX_RED; r++)
+ {
+ uint32 r2 = r;
+ if ((r2 & 0x10) == 0)
+ r2 = 0;
+ else
+ r2 = (r2 << 1) & MAX_RED;
+
+ for (g = 0; g <= MAX_GREEN; g++)
+ {
+ uint32 g2 = g;
+ if ((g2 & GREEN_HI_BIT) == 0)
+ g2 = 0;
+ else
+ g2 = (g2 << 1) & MAX_GREEN;
+
+ for (b = 0; b <= MAX_BLUE; b++)
+ {
+ uint32 b2 = b;
+ if ((b2 & 0x10) == 0)
+ b2 = 0;
+ else
+ b2 = (b2 << 1) & MAX_BLUE;
+
+ GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2);
+ GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2);
+ }
+ }
+ }
+#else
+ for (r = 0; r <= MAX_RED; r++)
+ {
+ uint32 r2 = r;
+ if ((r2 & 0x10) == 0)
+ r2 = 0;
+ else
+ r2 = (r2 << 1) & MAX_RED;
+
+ if (r2 == 0)
+ r2 = 1;
+ for (g = 0; g <= MAX_GREEN; g++)
+ {
+ uint32 g2 = g;
+ if ((g2 & GREEN_HI_BIT) == 0)
+ g2 = 0;
+ else
+ g2 = (g2 << 1) & MAX_GREEN;
+
+ if (g2 == 0)
+ g2 = 1;
+ for (b = 0; b <= MAX_BLUE; b++)
+ {
+ uint32 b2 = b;
+ if ((b2 & 0x10) == 0)
+ b2 = 0;
+ else
+ b2 = (b2 << 1) & MAX_BLUE;
+
+ if (b2 == 0)
+ b2 = 1;
+ GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2);
+ GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2);
+ }
+ }
+ }
+#endif
+
+ // Build a lookup table that if the top bit of the color value is zero
+ // then the value is zero, otherwise its just the value.
+ for (r = 0; r <= MAX_RED; r++)
+ {
+ uint32 r2 = r;
+ if ((r2 & 0x10) == 0)
+ r2 = 0;
+ else
+ r2 &= ~0x10;
+
+ for (g = 0; g <= MAX_GREEN; g++)
+ {
+ uint32 g2 = g;
+ if ((g2 & GREEN_HI_BIT) == 0)
+ g2 = 0;
+ else
+ g2 &= ~GREEN_HI_BIT;
+ for (b = 0; b <= MAX_BLUE; b++)
+ {
+ uint32 b2 = b;
+ if ((b2 & 0x10) == 0)
+ b2 = 0;
+ else
+ b2 &= ~0x10;
+
+ GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2);
+ GFX.ZERO [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2);
+ }
+ }
+ }
+ }
+ else
+ {
+ GFX.X2 = NULL;
+ GFX.ZERO_OR_X2 = NULL;
+ GFX.ZERO = NULL;
+ }
+
+ return (TRUE);
+}
+
+void S9xGraphicsDeinit (void)
+{
+ // Free any memory allocated in S9xGraphicsInit
+ if (GFX.X2)
+ {
+ free ((char *) GFX.X2);
+ GFX.X2 = NULL;
+ }
+ if (GFX.ZERO_OR_X2)
+ {
+ free ((char *) GFX.ZERO_OR_X2);
+ GFX.ZERO_OR_X2 = NULL;
+ }
+ if (GFX.ZERO)
+ {
+ free ((char *) GFX.ZERO);
+ GFX.ZERO = NULL;
+ }
+}
+
+void S9xBuildDirectColourMaps ()
+{
+ for (uint32 p = 0; p < 8; p++)
+ {
+ for (uint32 c = 0; c < 256; c++)
+ {
+// XXX: Brightness
+ DirectColourMaps [p][c] = BUILD_PIXEL (((c & 7) << 2) | ((p & 1) << 1),
+ ((c & 0x38) >> 1) | (p & 2),
+ ((c & 0xc0) >> 3) | (p & 4));
+ }
+ }
+ IPPU.DirectColourMapsNeedRebuild = FALSE;
+}
+
+void S9xStartScreenRefresh ()
+{
+ if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0)
+ GFX.InfoString = NULL;
+
+ if (IPPU.RenderThisFrame)
+ {
+ if (!S9xInitUpdate ())
+ {
+ IPPU.RenderThisFrame = FALSE;
+ return;
+ }
+
+ IPPU.RenderedFramesCount++;
+ IPPU.PreviousLine = IPPU.CurrentLine = 0;
+ IPPU.MaxBrightness = PPU.Brightness;
+ IPPU.LatchedBlanking = PPU.ForcedBlanking;
+
+ if(PPU.BGMode == 5 || PPU.BGMode == 6)
+ IPPU.Interlace = (Memory.FillRAM[0x2133] & 1);
+ if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace))
+ {
+ if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace)
+ {
+ IPPU.RenderedScreenWidth = 512;
+ IPPU.DoubleWidthPixels = TRUE;
+ }
+ else
+ {
+ IPPU.RenderedScreenWidth = 256;
+ IPPU.DoubleWidthPixels = FALSE;
+ }
+
+ if (IPPU.Interlace)
+ {
+ IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1;
+ IPPU.DoubleHeightPixels = TRUE;
+ GFX.Pitch2 = GFX.RealPitch;
+ GFX.Pitch = GFX.RealPitch * 2;
+ if (Settings.SixteenBit)
+ GFX.PPL = GFX.PPLx2 = GFX.RealPitch;
+ else
+ GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1;
+ }
+ else
+ {
+ IPPU.RenderedScreenHeight = PPU.ScreenHeight;
+ GFX.Pitch2 = GFX.Pitch = GFX.RealPitch;
+ IPPU.DoubleHeightPixels = FALSE;
+ if (Settings.SixteenBit)
+ GFX.PPL = GFX.Pitch >> 1;
+ else
+ GFX.PPL = GFX.Pitch;
+ GFX.PPLx2 = GFX.PPL << 1;
+ }
+ }
+ else
+ {
+ IPPU.RenderedScreenWidth = 256;
+ IPPU.RenderedScreenHeight = PPU.ScreenHeight;
+ IPPU.DoubleWidthPixels = FALSE;
+ IPPU.DoubleHeightPixels = FALSE;
+ {
+ GFX.Pitch2 = GFX.Pitch = GFX.RealPitch;
+ GFX.PPL = GFX.PPLx2 >> 1;
+ GFX.ZPitch = GFX.RealPitch;
+ if (Settings.SixteenBit)
+ GFX.ZPitch >>= 1;
+ }
+ }
+
+ PPU.RecomputeClipWindows = TRUE;
+ GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer;
+ GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
+ }
+
+ if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0)
+ {
+ IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount;
+ IPPU.RenderedFramesCount = 0;
+ IPPU.FrameCount = 0;
+ }
+}
+
+void RenderLine (uint8 C)
+{
+ if (IPPU.RenderThisFrame)
+ {
+ LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1;
+ LineData[C].BG[0].HOffset = PPU.BG[0].HOffset;
+ LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1;
+ LineData[C].BG[1].HOffset = PPU.BG[1].HOffset;
+
+ if (PPU.BGMode == 7)
+ {
+ struct SLineMatrixData *p = &LineMatrixData [C];
+ p->MatrixA = PPU.MatrixA;
+ p->MatrixB = PPU.MatrixB;
+ p->MatrixC = PPU.MatrixC;
+ p->MatrixD = PPU.MatrixD;
+ p->CentreX = PPU.CentreX;
+ p->CentreY = PPU.CentreY;
+ }
+ else
+ {
+ if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 &&
+ PPU.BG[2].HOffset == 0xe000)
+ {
+ LineData[C].BG[2].VOffset = 0xe1;
+ LineData[C].BG[2].HOffset = 0;
+ }
+ else
+ {
+ LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1;
+ LineData[C].BG[2].HOffset = PPU.BG[2].HOffset;
+ LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1;
+ LineData[C].BG[3].HOffset = PPU.BG[3].HOffset;
+ }
+ }
+ IPPU.CurrentLine = C + 1;
+ } else {
+ /* if we're not rendering this frame, we still need to update this */
+ // XXX: Check ForceBlank? Or anything else?
+ if(IPPU.OBJChanged) S9xSetupOBJ();
+ PPU.RangeTimeOver |= GFX.OBJLines[C].RTOFlags;
+ }
+}
+
+void S9xEndScreenRefresh ()
+{
+ IPPU.HDMAStarted = FALSE;
+ if (IPPU.RenderThisFrame)
+ {
+ FLUSH_REDRAW ();
+ if (IPPU.ColorsChanged)
+ {
+ uint32 saved = PPU.CGDATA[0];
+ if (!Settings.SixteenBit)
+ {
+ // Hack for Super Mario World - to get its sky blue
+ // (It uses Fixed colour addition on the backdrop colour)
+ if (!(Memory.FillRAM [0x2131] & 0x80) && (Memory.FillRAM[0x2131] & 0x20) &&
+ (PPU.FixedColourRed || PPU.FixedColourGreen || PPU.FixedColourBlue))
+ {
+ PPU.CGDATA[0] = PPU.FixedColourRed | (PPU.FixedColourGreen << 5) |
+ (PPU.FixedColourBlue << 10);
+ }
+ }
+ IPPU.ColorsChanged = FALSE;
+ PPU.CGDATA[0] = saved;
+ }
+
+ GFX.Pitch = GFX.Pitch2 = GFX.RealPitch;
+ GFX.PPL = GFX.PPLx2 >> 1;
+#if 0
+ //take screenshot here.
+ if(Settings.TakeScreenshot)
+ {
+ S9xDoScreenshot(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight);
+ cprintf("%s:%d\n", __FILE__, __LINE__);
+ }
+ if (Settings.DisplayFrameRate)
+ {
+ S9xDisplayFrameRate ();
+ cprintf("%s:%d\n", __FILE__, __LINE__);
+ }
+ if (GFX.InfoString)
+ {
+ S9xDisplayString (GFX.InfoString);
+ cprintf("%s:%d\n", __FILE__, __LINE__);
+ }
+#endif
+ S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight,
+ Settings.SixteenBit);
+ }
+
+ //S9xApplyCheats ();
+ S9xApplyCheats_ex ();
+#ifdef DEBUGGER
+ if (CPU.Flags & FRAME_ADVANCE_FLAG)
+ {
+ if (ICPU.FrameAdvanceCount)
+ {
+ ICPU.FrameAdvanceCount--;
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.FrameSkip = 0;
+ }
+ else
+ {
+ CPU.Flags &= ~FRAME_ADVANCE_FLAG;
+ CPU.Flags |= DEBUG_MODE_FLAG;
+ }
+ }
+#endif
+
+
+ if (CPU.SRAMModified)
+ {
+ S9xAutoSaveSRAM ();
+ CPU.SRAMModified = FALSE;
+ /*if (!CPU.AutoSaveTimer)
+ {
+ if (!(CPU.AutoSaveTimer = Settings.AutoSaveDelay * Memory.ROMFramesPerSecond))
+ CPU.SRAMModified = FALSE;
+ }
+ else
+ {
+ if (!--CPU.AutoSaveTimer)
+ {
+ S9xAutoSaveSRAM ();
+ CPU.SRAMModified = FALSE;
+ }
+ }*/
+ }
+
+}
+
+void S9xSetInfoString (const char *string)
+{
+ GFX.InfoString = string;
+ GFX.InfoStringTimeout = 120;
+}
+
+inline void SelectTileRenderer (bool8 normal)
+{
+ if (normal)
+ {
+ DrawTilePtr = DrawTile16;
+ DrawClippedTilePtr = DrawClippedTile16;
+ DrawLargePixelPtr = DrawLargePixel16;
+ }
+ else
+ {
+ if (GFX.r2131 & 0x80)
+ {
+ if (GFX.r2131 & 0x40)
+ {
+ if (GFX.r2130 & 2)
+ {
+ DrawTilePtr = DrawTile16Sub1_2;
+ DrawClippedTilePtr = DrawClippedTile16Sub1_2;
+ }
+ else
+ {
+ // Fixed colour substraction
+ DrawTilePtr = DrawTile16FixedSub1_2;
+ DrawClippedTilePtr = DrawClippedTile16FixedSub1_2;
+ }
+ DrawLargePixelPtr = DrawLargePixel16Sub1_2;
+ }
+ else
+ {
+ DrawTilePtr = DrawTile16Sub;
+ DrawClippedTilePtr = DrawClippedTile16Sub;
+ DrawLargePixelPtr = DrawLargePixel16Sub;
+ }
+ }
+ else
+ {
+ if (GFX.r2131 & 0x40)
+ {
+ if (GFX.r2130 & 2)
+ {
+ DrawTilePtr = DrawTile16Add1_2;
+ DrawClippedTilePtr = DrawClippedTile16Add1_2;
+ }
+ else
+ {
+ // Fixed colour addition
+ DrawTilePtr = DrawTile16FixedAdd1_2;
+ DrawClippedTilePtr = DrawClippedTile16FixedAdd1_2;
+ }
+ DrawLargePixelPtr = DrawLargePixel16Add1_2;
+ }
+ else
+ {
+ DrawTilePtr = DrawTile16Add;
+ DrawClippedTilePtr = DrawClippedTile16Add;
+ DrawLargePixelPtr = DrawLargePixel16Add;
+ }
+ }
+ }
+}
+
+void S9xSetupOBJ ()
+{
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "Entering SetupOBJS()\n");
+#endif
+ int SmallWidth, SmallHeight;
+ int LargeWidth, LargeHeight;
+
+ switch (PPU.OBJSizeSelect)
+ {
+ case 0:
+ SmallWidth = SmallHeight = 8;
+ LargeWidth = LargeHeight = 16;
+ break;
+ case 1:
+ SmallWidth = SmallHeight = 8;
+ LargeWidth = LargeHeight = 32;
+ break;
+ case 2:
+ SmallWidth = SmallHeight = 8;
+ LargeWidth = LargeHeight = 64;
+ break;
+ case 3:
+ SmallWidth = SmallHeight = 16;
+ LargeWidth = LargeHeight = 32;
+ break;
+ case 4:
+ SmallWidth = SmallHeight = 16;
+ LargeWidth = LargeHeight = 64;
+ break;
+ default:
+ case 5:
+ SmallWidth = SmallHeight = 32;
+ LargeWidth = LargeHeight = 64;
+ break;
+ case 6:
+ SmallWidth = 16; SmallHeight = 32;
+ LargeWidth = 32; LargeHeight = 64;
+ break;
+ case 7:
+ SmallWidth = 16; SmallHeight = 32;
+ LargeWidth = LargeHeight = 32;
+ break;
+ }
+ if(IPPU.InterlaceSprites)
+ {
+ SmallHeight>>=1; LargeHeight>>=1;
+ }
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "Sizes are %dx%d and %dx%d\n", SmallWidth, SmallHeight, LargeWidth, LargeHeight);
+#endif
+
+ /* OK, we have three cases here. Either there's no priority, priority is
+ * normal FirstSprite, or priority is FirstSprite+Y. The first two are
+ * easy, the last is somewhat more ... interesting. So we split them up. */
+
+ int Height;
+ uint8 S;
+
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "Priority rotation=%d, OAMAddr=%d -> ", PPU.OAMPriorityRotation, PPU.OAMAddr*2 | (PPU.OAMFlip&1));
+#endif
+ if(!PPU.OAMPriorityRotation || !(PPU.OAMFlip&PPU.OAMAddr&1)){
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "normal FirstSprite = %02x\n", PPU.FirstSprite);
+#endif
+ /* normal case */
+ uint8 LineOBJ[SNES_HEIGHT_EXTENDED];
+ memset(LineOBJ, 0, sizeof(LineOBJ));
+ for(int i=0; i<SNES_HEIGHT_EXTENDED; i++){
+ GFX.OBJLines[i].RTOFlags=0;
+ GFX.OBJLines[i].Tiles=34;
+ for(int j=0; j<32; j++){ GFX.OBJLines[i].OBJ[j].Sprite=-1; }
+ }
+ uint8 FirstSprite=PPU.FirstSprite;
+ S=FirstSprite;
+ do {
+ if(PPU.OBJ[S].Size){
+ GFX.OBJWidths[S]=LargeWidth; Height=LargeHeight;
+ } else {
+ GFX.OBJWidths[S]=SmallWidth; Height=SmallHeight;
+ }
+ int HPos=PPU.OBJ[S].HPos; if(HPos==-256) HPos=256;
+ if(HPos>-GFX.OBJWidths[S] && HPos<=256)
+ {
+ if(HPos<0){
+ GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3;
+ } else if(HPos+GFX.OBJWidths[S]>=257){
+ GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3;
+ } else {
+ GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3;
+ }
+ for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line<Height; Y++, line++){
+ if(Y>=SNES_HEIGHT_EXTENDED) continue;
+ if(LineOBJ[Y]>=32){
+ GFX.OBJLines[Y].RTOFlags|=0x40;
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S);
+#endif
+ continue;
+ }
+ GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S];
+ if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80;
+ GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite=S;
+ if(PPU.OBJ[S].VFlip){
+ // Yes, Width not Height. It so happens that the
+ // sprites with H=2*W flip as two WxW sprites.
+ GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line^(GFX.OBJWidths[S]-1);
+ } else {
+ GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line;
+ }
+ LineOBJ[Y]++;
+ }
+ }
+ S=(S+1)&0x7F;
+ } while(S!=FirstSprite);
+
+ for(int Y=1; Y<SNES_HEIGHT_EXTENDED; Y++){
+ GFX.OBJLines[Y].RTOFlags |= GFX.OBJLines[Y-1].RTOFlags;
+ }
+ } else {
+ /* evil FirstSprite+Y case */
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "FirstSprite+Y\n");
+#endif
+
+ /* First, find out which sprites are on which lines */
+ uint8 OBJOnLine[SNES_HEIGHT_EXTENDED][128];
+ memset(OBJOnLine, 0, sizeof(OBJOnLine));
+
+ for(S=0; S<128; S++){
+ if(PPU.OBJ[S].Size){
+ GFX.OBJWidths[S]=LargeWidth; Height=LargeHeight;
+ } else {
+ GFX.OBJWidths[S]=SmallWidth; Height=SmallHeight;
+ }
+ int HPos=PPU.OBJ[S].HPos; if(HPos==-256) HPos=256;
+ if(HPos>-GFX.OBJWidths[S] && HPos<=256)
+ {
+ if(HPos<0){
+ GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3;
+ } else if(HPos+GFX.OBJWidths[S]>=257){
+ GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3;
+ } else {
+ GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3;
+ }
+ for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line<Height; Y++, line++){
+ if(Y>=SNES_HEIGHT_EXTENDED) continue;
+ if(PPU.OBJ[S].VFlip){
+ // Yes, Width not Height. It so happens that the
+ // sprites with H=2*W flip as two WxW sprites.
+ OBJOnLine[Y][S]=(line^(GFX.OBJWidths[S]-1)) | 0x80;
+ } else {
+ OBJOnLine[Y][S]=line | 0x80;
+ }
+ }
+ }
+ }
+
+ /* Now go through and pull out those OBJ that are actually visible. */
+ int j;
+ for(int Y=0; Y<SNES_HEIGHT_EXTENDED; Y++){
+ GFX.OBJLines[Y].RTOFlags=Y?0:GFX.OBJLines[Y-1].RTOFlags;
+
+ GFX.OBJLines[Y].Tiles=34;
+ uint8 FirstSprite=(PPU.FirstSprite+Y)&0x7F;
+ S=FirstSprite; j=0;
+ do {
+ if(OBJOnLine[Y][S]){
+ if(j>=32){
+ GFX.OBJLines[Y].RTOFlags|=0x40;
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S);
+#endif
+ break;
+ }
+ GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S];
+ if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80;
+ GFX.OBJLines[Y].OBJ[j].Sprite=S;
+ GFX.OBJLines[Y].OBJ[j++].Line=OBJOnLine[Y][S]&~0x80;
+ }
+ S=(S+1)&0x7F;
+ } while(S!=FirstSprite);
+ if(j<32) GFX.OBJLines[Y].OBJ[j].Sprite=-1;
+ }
+ }
+
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) {
+ fprintf(stderr, "Sprites per line:\n");
+ for(int xxx=0; xxx<SNES_HEIGHT_EXTENDED; xxx++){
+ fprintf(stderr, "Line %d: RTO=%02x Tiles=%d", xxx, GFX.OBJLines[xxx].RTOFlags, 34-GFX.OBJLines[xxx].Tiles);
+ for(int j=0; j<32 && GFX.OBJLines[xxx].OBJ[j].Sprite>=0; j++){
+ fprintf(stderr, " %02x.%d", GFX.OBJLines[xxx].OBJ[j].Sprite, GFX.OBJLines[xxx].OBJ[j].Line);
+ }
+ fprintf(stderr, "\n");
+ }
+
+ fprintf(stderr, "Exiting SetupObj()\n");
+ }
+#endif
+
+ IPPU.OBJChanged = FALSE;
+}
+
+void DrawOBJS (bool8 OnMain = FALSE, uint8 D = 0)
+{
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "Entering DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY);
+#endif
+ CHECK_SOUND();
+
+ BG.BitShift = 4;
+ BG.TileShift = 5;
+ BG.TileAddress = PPU.OBJNameBase;
+ BG.StartPalette = 128;
+ BG.PaletteShift = 4;
+ BG.PaletteMask = 7;
+ BG.Buffer = IPPU.TileCache [TILE_4BIT];
+ BG.Buffered = IPPU.TileCached [TILE_4BIT];
+ BG.NameSelect = PPU.OBJNameSelect;
+ BG.DirectColourMode = FALSE;
+
+ GFX.PixSize = 1;
+
+ struct {
+ uint16 Pos;
+ bool8 Value;
+ } Windows[7];
+ int clipcount = GFX.pCurrentClip->Count [4];
+ if (!clipcount){
+ Windows[0].Pos=0;
+ Windows[0].Value=TRUE;
+ Windows[1].Pos=256;
+ Windows[1].Value=FALSE;
+ Windows[2].Pos=1000;
+ Windows[2].Value=FALSE;
+ } else {
+ Windows[0].Pos=1000;
+ Windows[0].Value=FALSE;
+ for(int clip=0, i=1; clip<clipcount; clip++){
+ if(GFX.pCurrentClip->Right[clip][4]<=GFX.pCurrentClip->Left[clip][4]) continue;
+ int j;
+ for(j=0; j<i && Windows[j].Pos<GFX.pCurrentClip->Left[clip][4]; j++);
+ if(j<i && Windows[j].Pos==GFX.pCurrentClip->Left[clip][4]){
+ Windows[j].Value = TRUE;
+ } else {
+ if(j<i) memmove(&Windows[j+1], &Windows[j], sizeof(Windows[0])*(i-j));
+ Windows[j].Pos = GFX.pCurrentClip->Left[clip][4];
+ Windows[j].Value = TRUE;
+ i++;
+ }
+ for(j=0; j<i && Windows[j].Pos<GFX.pCurrentClip->Right[clip][4]; j++);
+ if(j>=i || Windows[j].Pos!=GFX.pCurrentClip->Right[clip][4]){
+ if(j<i) memmove(&Windows[j+1], &Windows[j], sizeof(Windows[0])*(i-j));
+ Windows[j].Pos = GFX.pCurrentClip->Right[clip][4];
+ Windows[j].Value = FALSE;
+ i++;
+ }
+ }
+ }
+
+#ifdef MK_DEBUG_RTO
+if(Settings.BGLayering) {
+ fprintf(stderr, "Windows:\n");
+ for(int xxx=0; xxx<6; xxx++){ fprintf(stderr, "%d: %d = %d\n", xxx, Windows[xxx].Pos, Windows[xxx].Value); }
+}
+#endif
+
+ if (Settings.SupportHiRes)
+ {
+ if (PPU.BGMode == 5 || PPU.BGMode == 6)
+ {
+ // Bah, OnMain is never used except to determine if calling
+ // SelectTileRenderer is necessary. So let's hack it to false here
+ // to stop SelectTileRenderer from being called when it causes
+ // problems.
+ OnMain = FALSE;
+ GFX.PixSize = 2;
+ if (IPPU.DoubleHeightPixels)
+
+ {
+ if (Settings.SixteenBit)
+ {
+ DrawTilePtr = DrawTile16x2x2;
+ DrawClippedTilePtr = DrawClippedTile16x2x2;
+ }
+ else
+ {
+ DrawTilePtr = DrawTilex2x2;
+ DrawClippedTilePtr = DrawClippedTilex2x2;
+ }
+ }
+ else
+ {
+ if (Settings.SixteenBit)
+ {
+ DrawTilePtr = DrawTile16x2;
+ DrawClippedTilePtr = DrawClippedTile16x2;
+ }
+ else
+ {
+ DrawTilePtr = DrawTilex2;
+ DrawClippedTilePtr = DrawClippedTilex2;
+ }
+ }
+ }
+ else
+ {
+ if (Settings.SixteenBit)
+ {
+ DrawTilePtr = DrawTile16;
+ DrawClippedTilePtr = DrawClippedTile16;
+ }
+ else
+ {
+ DrawTilePtr = DrawTile;
+ DrawClippedTilePtr = DrawClippedTile;
+ }
+ }
+ }
+ GFX.Z1 = D + 2;
+
+ for(uint32 Y=GFX.StartY, Offset=Y*GFX.PPL; Y<=GFX.EndY; Y++, Offset+=GFX.PPL){
+#ifdef MK_DEBUG_RTO
+ bool8 Flag=0;
+#endif
+ int I = 0;
+#ifdef MK_DISABLE_TIME_OVER
+ int tiles=0;
+#else
+ int tiles=GFX.OBJLines[Y].Tiles;
+#endif
+ for (int S = GFX.OBJLines[Y].OBJ[I].Sprite; S >= 0 && I<32; S = GFX.OBJLines[Y].OBJ[++I].Sprite)
+ {
+ tiles+=GFX.OBJVisibleTiles[S];
+ if(tiles<=0){
+#ifdef MK_DEBUG_RTO
+if(Settings.BGLayering) {
+ if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); }
+ fprintf(stderr, " [%02x]", S);
+}
+#endif
+ continue;
+ }
+
+#ifdef MK_DEBUG_RTO
+if(Settings.BGLayering) {
+ if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); }
+ fprintf(stderr, " %02x", S);
+}
+#endif
+
+ if (OnMain && SUB_OR_ADD(4))
+ {
+ SelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4);
+ }
+
+ int BaseTile = (((GFX.OBJLines[Y].OBJ[I].Line<<1) + (PPU.OBJ[S].Name&0xf0))&0xf0) | (PPU.OBJ[S].Name&0x100) | (PPU.OBJ[S].Palette << 10);
+ int TileX = PPU.OBJ[S].Name&0x0f;
+ int TileLine = (GFX.OBJLines[Y].OBJ[I].Line&7)*8;
+ int TileInc = 1;
+
+ if (PPU.OBJ[S].HFlip)
+ {
+ TileX = (TileX + (GFX.OBJWidths[S] >> 3) - 1) & 0x0f;
+ BaseTile |= H_FLIP;
+ TileInc = -1;
+ }
+
+ GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D;
+
+ bool8 WinStat=TRUE;
+ int WinIdx=0, NextPos=-1000;
+ int X=PPU.OBJ[S].HPos; if(X==-256) X=256;
+ for(int t=tiles, O=Offset+X*GFX.PixSize; X<=256 && X<PPU.OBJ[S].HPos+GFX.OBJWidths[S]; TileX=(TileX+TileInc)&0x0f, X+=8, O+=8*GFX.PixSize){
+#ifdef MK_DEBUG_RTO
+if(Settings.BGLayering) {
+ if(X<-7) continue;
+ if((t-1)<0) fprintf(stderr, "-[%d]", 35-t);
+ else fprintf(stderr, "-%d", 35-t);
+}
+#endif
+ if(X<-7 || --t<0 || X==256) continue;
+ if(X>=NextPos){
+ for(; WinIdx<7 && Windows[WinIdx].Pos<=X; WinIdx++);
+ if(WinIdx==0) WinStat=FALSE;
+ else WinStat=Windows[WinIdx-1].Value;
+ NextPos=(WinIdx<7)?Windows[WinIdx].Pos:1000;
+ }
+
+ if(X+8<NextPos){
+ if(WinStat) (*DrawTilePtr) (BaseTile|TileX, O, TileLine, 1);
+ } else {
+ int x=X;
+ while(x<X+8){
+ if(WinStat) (*DrawClippedTilePtr) (BaseTile|TileX, O, x-X, NextPos-x, TileLine, 1);
+ x=NextPos;
+ for(; WinIdx<7 && Windows[WinIdx].Pos<=x; WinIdx++);
+ if(WinIdx==0) WinStat=FALSE;
+ else WinStat=Windows[WinIdx-1].Value;
+ NextPos=(WinIdx<7)?Windows[WinIdx].Pos:1000;
+ if(NextPos>X+8) NextPos=X+8;
+ }
+ }
+ }
+ }
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) if(Flag) fprintf(stderr, "\n");
+#endif
+ }
+#ifdef MK_DEBUG_RTO
+ if(Settings.BGLayering) fprintf(stderr, "Exiting DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY);
+#endif
+}
+
+void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
+{
+ CHECK_SOUND();
+
+ uint32 Tile;
+ uint16 *SC0;
+ uint16 *SC1;
+ uint16 *SC2;
+ uint16 *SC3;
+ uint8 depths [2] = {Z1, Z2};
+
+ if (BGMode == 0)
+ BG.StartPalette = bg << 5;
+ else
+ BG.StartPalette = 0;
+
+ SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1];
+
+ if (PPU.BG[bg].SCSize & 1)
+ SC1 = SC0 + 1024;
+ else
+ SC1 = SC0;
+
+ if(((uint8*)SC1-Memory.VRAM)>=0x10000)
+ SC1-=0x08000;
+
+
+ if (PPU.BG[bg].SCSize & 2)
+ SC2 = SC1 + 1024;
+ else
+ SC2 = SC0;
+
+ if(((uint8*)SC2-Memory.VRAM)>=0x10000)
+ SC2-=0x08000;
+
+
+ if (PPU.BG[bg].SCSize & 1)
+ SC3 = SC2 + 1024;
+ else
+ SC3 = SC2;
+
+ if(((uint8*)SC3-Memory.VRAM)>=0x10000)
+ SC3-=0x08000;
+
+ uint32 Lines;
+ uint32 OffsetMask;
+ uint32 OffsetShift;
+
+ if (BG.TileSize == 16)
+ {
+ OffsetMask = 0x3ff;
+ OffsetShift = 4;
+ }
+ else
+ {
+ OffsetMask = 0x1ff;
+ OffsetShift = 3;
+ }
+
+ int m5 = (BGMode == 5 || BGMode == 6) ? 1 : 0;
+
+ for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines)
+ {
+ uint32 VOffset = LineData [Y].BG[bg].VOffset;
+ uint32 HOffset = LineData [Y].BG[bg].HOffset;
+ uint32 MosaicOffset = Y % PPU.Mosaic;
+
+ for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++)
+ if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) ||
+ (HOffset != LineData [Y + Lines].BG[bg].HOffset))
+ break;
+
+ uint32 MosaicLine = VOffset + Y - MosaicOffset;
+
+ if (Y + Lines > GFX.EndY)
+ Lines = GFX.EndY + 1 - Y;
+ uint32 VirtAlign = (MosaicLine & 7) << 3;
+
+ uint16 *b1;
+ uint16 *b2;
+
+ uint32 ScreenLine = MosaicLine >> OffsetShift;
+ uint32 Rem16 = MosaicLine & 15;
+
+ if (ScreenLine & 0x20)
+ b1 = SC2, b2 = SC3;
+ else
+ b1 = SC0, b2 = SC1;
+
+ b1 += (ScreenLine & 0x1f) << 5;
+ b2 += (ScreenLine & 0x1f) << 5;
+ uint16 *t;
+ uint32 Left = 0;
+ uint32 Right = 256 << m5;
+
+ HOffset <<= m5;
+
+ uint32 ClipCount = GFX.pCurrentClip->Count [bg];
+ uint32 HPos = HOffset;
+ uint32 PixWidth = (PPU.Mosaic << m5);
+
+
+ if (!ClipCount)
+ ClipCount = 1;
+
+ for (uint32 clip = 0; clip < ClipCount; clip++)
+ {
+ if (GFX.pCurrentClip->Count [bg])
+ {
+ Left = GFX.pCurrentClip->Left [clip][bg] << m5;
+ Right = GFX.pCurrentClip->Right [clip][bg] << m5;
+
+ uint32 r = Left % (PPU.Mosaic << m5);
+ HPos = HOffset + Left;
+ PixWidth = (PPU.Mosaic << m5) - r;
+ }
+ uint32 s = Y * GFX.PPL + Left * GFX.PixSize;
+ for (uint32 x = Left; x < Right; x += PixWidth,
+ s += PixWidth * GFX.PixSize,
+ HPos += PixWidth, PixWidth = (PPU.Mosaic << m5))
+ {
+ uint32 Quot = (HPos & OffsetMask) >> 3;
+
+ if (x + PixWidth >= Right)
+ PixWidth = Right - x;
+
+ if (BG.TileSize == 8 && !m5)
+ {
+ if (Quot > 31)
+ t = b2 + (Quot & 0x1f);
+ else
+ t = b1 + Quot;
+ }
+ else
+ {
+ if (Quot > 63)
+ t = b2 + ((Quot >> 1) & 0x1f);
+ else
+ t = b1 + (Quot >> 1);
+ }
+
+ Tile = READ_2BYTES (t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+
+ // Draw tile...
+ if (BG.TileSize != 8)
+ {
+ if (Tile & H_FLIP)
+ {
+ // Horizontal flip, but what about vertical flip ?
+ if (Tile & V_FLIP)
+ {
+ // Both horzontal & vertical flip
+ if (Rem16 < 8)
+ {
+ (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ else
+ {
+ (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // Horizontal flip only
+ if (Rem16 > 7)
+ {
+ (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ else
+ {
+ (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ }
+ }
+ else
+ {
+ // No horizontal flip, but is there a vertical flip ?
+ if (Tile & V_FLIP)
+ {
+ // Vertical flip only
+ if (Rem16 < 8)
+ {
+ (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ else
+ {
+ (*DrawLargePixelPtr) (Tile + (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // Normal unflipped
+ if (Rem16 > 7)
+ {
+ (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ else
+ {
+ (*DrawLargePixelPtr) (Tile + (Quot & 1), s,
+ HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ }
+ }
+ }
+ else
+ (*DrawLargePixelPtr) (Tile + (Quot & 1) * m5, s, HPos & 7, PixWidth,
+ VirtAlign, Lines);
+ }
+ }
+ }
+}
+
+void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
+{
+ CHECK_SOUND();
+
+ uint32 Tile;
+ uint16 *SC0;
+ uint16 *SC1;
+ uint16 *SC2;
+ uint16 *SC3;
+ uint16 *BPS0;
+ uint16 *BPS1;
+ uint16 *BPS2;
+ uint16 *BPS3;
+ uint32 Width;
+ int VOffsetOffset = BGMode == 4 ? 0 : 32;
+ uint8 depths [2] = {Z1, Z2};
+
+ BG.StartPalette = 0;
+
+ BPS0 = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1];
+
+ if (PPU.BG[2].SCSize & 1)
+ BPS1 = BPS0 + 1024;
+ else
+ BPS1 = BPS0;
+
+ if (PPU.BG[2].SCSize & 2)
+ BPS2 = BPS1 + 1024;
+ else
+ BPS2 = BPS0;
+
+ if (PPU.BG[2].SCSize & 1)
+ BPS3 = BPS2 + 1024;
+ else
+ BPS3 = BPS2;
+
+ SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1];
+
+ if (PPU.BG[bg].SCSize & 1)
+ SC1 = SC0 + 1024;
+ else
+ SC1 = SC0;
+
+ if(((uint8*)SC1-Memory.VRAM)>=0x10000)
+ SC1-=0x08000;
+
+
+ if (PPU.BG[bg].SCSize & 2)
+ SC2 = SC1 + 1024;
+ else
+ SC2 = SC0;
+
+ if(((uint8*)SC2-Memory.VRAM)>=0x10000)
+ SC2-=0x08000;
+
+
+ if (PPU.BG[bg].SCSize & 1)
+ SC3 = SC2 + 1024;
+ else
+ SC3 = SC2;
+
+ if(((uint8*)SC3-Memory.VRAM)>=0x10000)
+ SC3-=0x08000;
+
+
+ static const int Lines = 1;
+ int OffsetMask;
+ int OffsetShift;
+ int OffsetEnableMask = 1 << (bg + 13);
+
+ if (BG.TileSize == 16)
+ {
+ OffsetMask = 0x3ff;
+ OffsetShift = 4;
+ }
+ else
+ {
+ OffsetMask = 0x1ff;
+ OffsetShift = 3;
+ }
+
+ for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y++)
+ {
+ uint32 VOff = LineData [Y].BG[2].VOffset - 1;
+// uint32 VOff = LineData [Y].BG[2].VOffset;
+ uint32 HOff = LineData [Y].BG[2].HOffset;
+
+ int VirtAlign;
+ int ScreenLine = VOff >> 3;
+ int t1;
+ int t2;
+ uint16 *s0;
+ uint16 *s1;
+ uint16 *s2;
+
+ if (ScreenLine & 0x20)
+ s1 = BPS2, s2 = BPS3;
+ else
+ s1 = BPS0, s2 = BPS1;
+
+ s1 += (ScreenLine & 0x1f) << 5;
+ s2 += (ScreenLine & 0x1f) << 5;
+
+ if(BGMode != 4)
+ {
+ if((ScreenLine & 0x1f) == 0x1f)
+ {
+ if(ScreenLine & 0x20)
+ VOffsetOffset = BPS0 - BPS2 - 0x1f*32;
+ else
+ VOffsetOffset = BPS2 - BPS0 - 0x1f*32;
+ }
+ else
+ {
+ VOffsetOffset = 32;
+ }
+ }
+
+ int clipcount = GFX.pCurrentClip->Count [bg];
+ if (!clipcount)
+ clipcount = 1;
+
+ for (int clip = 0; clip < clipcount; clip++)
+ {
+ uint32 Left;
+ uint32 Right;
+
+ if (!GFX.pCurrentClip->Count [bg])
+ {
+ Left = 0;
+ Right = 256;
+ }
+ else
+ {
+ Left = GFX.pCurrentClip->Left [clip][bg];
+ Right = GFX.pCurrentClip->Right [clip][bg];
+
+ if (Right <= Left)
+ continue;
+ }
+
+ uint32 VOffset;
+ uint32 HOffset;
+ //added:
+ uint32 LineHOffset=LineData [Y].BG[bg].HOffset;
+
+ uint32 Offset;
+ uint32 HPos;
+ uint32 Quot;
+ uint32 Count;
+ uint16 *t;
+ uint32 Quot2;
+ uint32 VCellOffset;
+ uint32 HCellOffset;
+ uint16 *b1;
+ uint16 *b2;
+ uint32 TotalCount = 0;
+ uint32 MaxCount = 8;
+
+ uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
+ bool8 left_hand_edge = (Left == 0);
+ Width = Right - Left;
+
+ if (Left & 7)
+ MaxCount = 8 - (Left & 7);
+
+ while (Left < Right)
+ {
+ if (left_hand_edge)
+ {
+ // The SNES offset-per-tile background mode has a
+ // hardware limitation that the offsets cannot be set
+ // for the tile at the left-hand edge of the screen.
+ VOffset = LineData [Y].BG[bg].VOffset;
+
+ //MKendora; use temp var to reduce memory accesses
+ //HOffset = LineData [Y].BG[bg].HOffset;
+
+ HOffset = LineHOffset;
+ //End MK
+
+ left_hand_edge = FALSE;
+ }
+ else
+
+ {
+ // All subsequent offset tile data is shifted left by one,
+ // hence the - 1 below.
+
+ Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3;
+
+ if (Quot2 > 31)
+ s0 = s2 + (Quot2 & 0x1f);
+ else
+ s0 = s1 + Quot2;
+
+ HCellOffset = READ_2BYTES (s0);
+
+ if (BGMode == 4)
+ {
+ VOffset = LineData [Y].BG[bg].VOffset;
+
+ //MKendora another mem access hack
+ //HOffset = LineData [Y].BG[bg].HOffset;
+ HOffset=LineHOffset;
+ //end MK
+
+ if ((HCellOffset & OffsetEnableMask))
+ {
+ if (HCellOffset & 0x8000)
+ VOffset = HCellOffset + 1;
+ else
+ HOffset = HCellOffset;
+ }
+ }
+ else
+ {
+ VCellOffset = READ_2BYTES (s0 + VOffsetOffset);
+ if ((VCellOffset & OffsetEnableMask))
+ VOffset = VCellOffset + 1;
+ else
+ VOffset = LineData [Y].BG[bg].VOffset;
+
+ //MKendora Strike Gunner fix
+ if ((HCellOffset & OffsetEnableMask))
+ {
+ //HOffset= HCellOffset;
+
+ HOffset = (HCellOffset & ~7)|(LineHOffset&7);
+ //HOffset |= LineData [Y].BG[bg].HOffset&7;
+ }
+ else
+ HOffset=LineHOffset;
+ //HOffset = LineData [Y].BG[bg].HOffset -
+ //Settings.StrikeGunnerOffsetHack;
+ //HOffset &= (~7);
+ //end MK
+ }
+ }
+ VirtAlign = ((Y + VOffset) & 7) << 3;
+ ScreenLine = (VOffset + Y) >> OffsetShift;
+
+ if (((VOffset + Y) & 15) > 7)
+ {
+ t1 = 16;
+ t2 = 0;
+ }
+ else
+ {
+ t1 = 0;
+ t2 = 16;
+ }
+
+ if (ScreenLine & 0x20)
+ b1 = SC2, b2 = SC3;
+ else
+ b1 = SC0, b2 = SC1;
+
+ b1 += (ScreenLine & 0x1f) << 5;
+ b2 += (ScreenLine & 0x1f) << 5;
+
+ HPos = (HOffset + Left) & OffsetMask;
+
+ Quot = HPos >> 3;
+
+ if (BG.TileSize == 8)
+ {
+ if (Quot > 31)
+ t = b2 + (Quot & 0x1f);
+ else
+ t = b1 + Quot;
+ }
+ else
+ {
+ if (Quot > 63)
+ t = b2 + ((Quot >> 1) & 0x1f);
+ else
+ t = b1 + (Quot >> 1);
+ }
+
+ if (MaxCount + TotalCount > Width)
+ MaxCount = Width - TotalCount;
+
+ Offset = HPos & 7;
+
+ //Count =1;
+ Count = 8 - Offset;
+ if (Count > MaxCount)
+ Count = MaxCount;
+
+ s -= Offset * GFX.PixSize;
+ Tile = READ_2BYTES(t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+
+ if (BG.TileSize == 8)
+ (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines);
+ else
+ {
+ if (!(Tile & (V_FLIP | H_FLIP)))
+ {
+ // Normal, unflipped
+ (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ if (Tile & H_FLIP)
+ {
+ if (Tile & V_FLIP)
+ {
+ // H & V flip
+ (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip only
+ (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // V flip only
+ (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ }
+
+ Left += Count;
+ TotalCount += Count;
+ s += (Offset + Count) * GFX.PixSize;
+ MaxCount = 8;
+ }
+ }
+ }
+}
+
+void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
+{
+ CHECK_SOUND();
+
+ if(IPPU.Interlace)
+ {
+ GFX.Pitch = GFX.RealPitch;
+ GFX.PPL = GFX.PPLx2 >> 1;
+ }
+ GFX.PixSize = 1;
+ uint8 depths [2] = {Z1, Z2};
+
+ uint32 Tile;
+ uint16 *SC0;
+ uint16 *SC1;
+ uint16 *SC2;
+ uint16 *SC3;
+ uint32 Width;
+
+ BG.StartPalette = 0;
+
+ SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1];
+
+ if ((PPU.BG[bg].SCSize & 1))
+ SC1 = SC0 + 1024;
+ else
+ SC1 = SC0;
+
+ if((SC1-(unsigned short*)Memory.VRAM)>0x10000)
+ SC1=(uint16*)&Memory.VRAM[(((uint8*)SC1)-Memory.VRAM)%0x10000];
+
+ if ((PPU.BG[bg].SCSize & 2))
+ SC2 = SC1 + 1024;
+ else SC2 = SC0;
+
+ if(((uint8*)SC2-Memory.VRAM)>=0x10000)
+ SC2-=0x08000;
+
+
+
+ if ((PPU.BG[bg].SCSize & 1))
+ SC3 = SC2 + 1024;
+ else
+ SC3 = SC2;
+
+ if(((uint8*)SC3-Memory.VRAM)>=0x10000)
+ SC3-=0x08000;
+
+
+
+ int Lines;
+ int VOffsetMask;
+ int VOffsetShift;
+
+ if (BG.TileSize == 16)
+ {
+ VOffsetMask = 0x3ff;
+ VOffsetShift = 4;
+ }
+ else
+ {
+ VOffsetMask = 0x1ff;
+ VOffsetShift = 3;
+ }
+ int endy = IPPU.Interlace ? 1 + (GFX.EndY << 1) : GFX.EndY;
+
+ for (int Y = IPPU.Interlace ? GFX.StartY << 1 : GFX.StartY; Y <= endy; Y += Lines)
+ {
+ int y = IPPU.Interlace ? (Y >> 1) : Y;
+ uint32 VOffset = LineData [y].BG[bg].VOffset;
+ uint32 HOffset = LineData [y].BG[bg].HOffset;
+ int VirtAlign = (Y + VOffset) & 7;
+
+ for (Lines = 1; Lines < 8 - VirtAlign; Lines++)
+ if ((VOffset != LineData [y + Lines].BG[bg].VOffset) ||
+ (HOffset != LineData [y + Lines].BG[bg].HOffset))
+ break;
+
+ HOffset <<= 1;
+ if (Y + Lines > endy)
+ Lines = endy + 1 - Y;
+ VirtAlign <<= 3;
+
+ int ScreenLine = (VOffset + Y) >> VOffsetShift;
+ int t1;
+ int t2;
+ if (((VOffset + Y) & 15) > 7)
+ {
+ t1 = 16;
+ t2 = 0;
+ }
+ else
+ {
+ t1 = 0;
+ t2 = 16;
+ }
+ uint16 *b1;
+ uint16 *b2;
+
+ if (ScreenLine & 0x20)
+ b1 = SC2, b2 = SC3;
+ else
+ b1 = SC0, b2 = SC1;
+
+ b1 += (ScreenLine & 0x1f) << 5;
+ b2 += (ScreenLine & 0x1f) << 5;
+
+ int clipcount = GFX.pCurrentClip->Count [bg];
+ if (!clipcount)
+ clipcount = 1;
+ for (int clip = 0; clip < clipcount; clip++)
+ {
+ int Left;
+ int Right;
+
+ if (!GFX.pCurrentClip->Count [bg])
+ {
+ Left = 0;
+ Right = 512;
+ }
+ else
+ {
+ Left = GFX.pCurrentClip->Left [clip][bg] * 2;
+ Right = GFX.pCurrentClip->Right [clip][bg] * 2;
+
+ if (Right <= Left)
+ continue;
+ }
+
+ uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
+ uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff;
+
+ uint32 Quot = HPos >> 3;
+ uint32 Count = 0;
+
+ uint16 *t;
+ if (Quot > 63)
+ t = b2 + ((Quot >> 1) & 0x1f);
+ else
+ t = b1 + (Quot >> 1);
+
+ Width = Right - Left;
+ // Left hand edge clipped tile
+ if (HPos & 7)
+ {
+ int Offset = (HPos & 7);
+ Count = 8 - Offset;
+ if (Count > Width)
+ Count = Width;
+ s -= Offset;
+ Tile = READ_2BYTES (t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+
+ if (BG.TileSize == 8)
+ {
+ if (!(Tile & H_FLIP))
+ {
+ // Normal, unflipped
+ (*DrawHiResClippedTilePtr) (Tile + (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip
+ (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ if (!(Tile & (V_FLIP | H_FLIP)))
+ {
+ // Normal, unflipped
+ (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ if (Tile & H_FLIP)
+ {
+ if (Tile & V_FLIP)
+ {
+ // H & V flip
+ (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip only
+ (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // V flip only
+ (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ }
+
+ t += Quot & 1;
+ if (Quot == 63)
+ t = b2;
+ else if (Quot == 127)
+ t = b1;
+ Quot++;
+ s += 8;
+ }
+
+ // Middle, unclipped tiles
+ Count = Width - Count;
+ int Middle = Count >> 3;
+ Count &= 7;
+ for (int C = Middle; C > 0; s += 8, Quot++, C--)
+ {
+ Tile = READ_2BYTES(t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+ if (BG.TileSize == 8)
+ {
+ if (!(Tile & H_FLIP))
+ {
+ // Normal, unflipped
+ (*DrawHiResTilePtr) (Tile + (Quot & 1),
+ s, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip
+ (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1),
+ s, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ if (!(Tile & (V_FLIP | H_FLIP)))
+ {
+ // Normal, unflipped
+ (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1),
+ s, VirtAlign, Lines);
+ }
+ else
+ if (Tile & H_FLIP)
+ {
+ if (Tile & V_FLIP)
+ {
+ // H & V flip
+ (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1),
+ s, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip only
+ (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1),
+ s, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // V flip only
+ (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1),
+ s, VirtAlign, Lines);
+ }
+ }
+
+ t += Quot & 1;
+ if (Quot == 63)
+ t = b2;
+ else
+ if (Quot == 127)
+ t = b1;
+ }
+
+ // Right-hand edge clipped tiles
+ if (Count)
+ {
+ Tile = READ_2BYTES(t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+ if (BG.TileSize == 8)
+ {
+ if (!(Tile & H_FLIP))
+ {
+ // Normal, unflipped
+ (*DrawHiResClippedTilePtr) (Tile + (Quot & 1),
+ s, 0, Count, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip
+ (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1),
+ s, 0, Count, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ if (!(Tile & (V_FLIP | H_FLIP)))
+ {
+ // Normal, unflipped
+ (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1),
+ s, 0, Count, VirtAlign, Lines);
+ }
+ else
+ if (Tile & H_FLIP)
+ {
+ if (Tile & V_FLIP)
+ {
+ // H & V flip
+ (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
+ s, 0, Count, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip only
+ (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
+ s, 0, Count, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // V flip only
+ (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1),
+ s, 0, Count, VirtAlign, Lines);
+ }
+ }
+ }
+ }
+ }
+ GFX.Pitch = IPPU.DoubleHeightPixels ? GFX.RealPitch * 2 : GFX.RealPitch;
+ GFX.PPL = IPPU.DoubleHeightPixels ? GFX.PPLx2 : (GFX.PPLx2 >> 1);
+
+}
+
+void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
+{
+ GFX.PixSize = 1;
+
+ BG.TileSize = BGSizes [PPU.BG[bg].BGSize];
+ BG.BitShift = BitShifts[BGMode][bg];
+ BG.TileShift = TileShifts[BGMode][bg];
+ BG.TileAddress = PPU.BG[bg].NameBase << 1;
+ BG.NameSelect = 0;
+ BG.Buffer = IPPU.TileCache [Depths [BGMode][bg]];
+ BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]];
+ BG.PaletteShift = PaletteShifts[BGMode][bg];
+ BG.PaletteMask = PaletteMasks[BGMode][bg];
+ BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 &&
+ (GFX.r2130 & 1);
+
+ if (PPU.BGMosaic [bg] && PPU.Mosaic > 1)
+ {
+ DrawBackgroundMosaic (BGMode, bg, Z1, Z2);
+ return;
+
+ }
+ switch (BGMode)
+ {
+ case 2:
+ case 4: // Used by Puzzle Bobble
+ DrawBackgroundOffset (BGMode, bg, Z1, Z2);
+ return;
+
+ case 5:
+ case 6: // XXX: is also offset per tile.
+ if (Settings.SupportHiRes)
+ {
+ DrawBackgroundMode5 (BGMode, bg, Z1, Z2);
+ return;
+ }
+ break;
+ }
+ CHECK_SOUND();
+
+ uint32 Tile;
+ uint16 *SC0;
+ uint16 *SC1;
+ uint16 *SC2;
+ uint16 *SC3;
+ uint32 Width;
+ uint8 depths [2] = {Z1, Z2};
+
+ if (BGMode == 0)
+ BG.StartPalette = bg << 5;
+ else BG.StartPalette = 0;
+
+ SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1];
+
+ if (PPU.BG[bg].SCSize & 1)
+ SC1 = SC0 + 1024;
+ else
+ SC1 = SC0;
+
+ if(SC1>=(unsigned short*)(Memory.VRAM+0x10000))
+ SC1=(uint16*)&Memory.VRAM[((uint8*)SC1-&Memory.VRAM[0])%0x10000];
+
+ if (PPU.BG[bg].SCSize & 2)
+ SC2 = SC1 + 1024;
+ else
+ SC2 = SC0;
+
+ if(((uint8*)SC2-Memory.VRAM)>=0x10000)
+ SC2-=0x08000;
+
+ if (PPU.BG[bg].SCSize & 1)
+ SC3 = SC2 + 1024;
+ else
+ SC3 = SC2;
+
+ if(((uint8*)SC3-Memory.VRAM)>=0x10000)
+ SC3-=0x08000;
+
+
+
+ int Lines;
+ int OffsetMask;
+ int OffsetShift;
+
+ if (BG.TileSize == 16)
+ {
+ OffsetMask = 0x3ff;
+ OffsetShift = 4;
+ }
+ else
+ {
+ OffsetMask = 0x1ff;
+ OffsetShift = 3;
+ }
+
+ for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines)
+ {
+ uint32 VOffset = LineData [Y].BG[bg].VOffset;
+ uint32 HOffset = LineData [Y].BG[bg].HOffset;
+ int VirtAlign = (Y + VOffset) & 7;
+
+ for (Lines = 1; Lines < 8 - VirtAlign; Lines++)
+ if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) ||
+ (HOffset != LineData [Y + Lines].BG[bg].HOffset))
+ break;
+
+ if (Y + Lines > GFX.EndY)
+ Lines = GFX.EndY + 1 - Y;
+
+ VirtAlign <<= 3;
+
+ uint32 ScreenLine = (VOffset + Y) >> OffsetShift;
+ uint32 t1;
+ uint32 t2;
+ if (((VOffset + Y) & 15) > 7)
+ {
+ t1 = 16;
+ t2 = 0;
+ }
+ else
+ {
+ t1 = 0;
+ t2 = 16;
+ }
+ uint16 *b1;
+ uint16 *b2;
+
+ if (ScreenLine & 0x20)
+ b1 = SC2, b2 = SC3;
+ else
+ b1 = SC0, b2 = SC1;
+
+ b1 += (ScreenLine & 0x1f) << 5;
+ b2 += (ScreenLine & 0x1f) << 5;
+
+ int clipcount = GFX.pCurrentClip->Count [bg];
+ if (!clipcount)
+ clipcount = 1;
+ for (int clip = 0; clip < clipcount; clip++)
+ {
+ uint32 Left;
+ uint32 Right;
+
+ if (!GFX.pCurrentClip->Count [bg])
+ {
+ Left = 0;
+ Right = 256;
+ }
+ else
+ {
+ Left = GFX.pCurrentClip->Left [clip][bg];
+ Right = GFX.pCurrentClip->Right [clip][bg];
+
+ if (Right <= Left)
+ continue;
+ }
+
+ uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
+ uint32 HPos = (HOffset + Left) & OffsetMask;
+
+ uint32 Quot = HPos >> 3;
+ uint32 Count = 0;
+
+ uint16 *t;
+ if (BG.TileSize == 8)
+ {
+ if (Quot > 31)
+ t = b2 + (Quot & 0x1f);
+ else
+ t = b1 + Quot;
+ }
+ else
+ {
+ if (Quot > 63)
+ t = b2 + ((Quot >> 1) & 0x1f);
+ else
+ t = b1 + (Quot >> 1);
+ }
+
+ Width = Right - Left;
+ // Left hand edge clipped tile
+ if (HPos & 7)
+ {
+ uint32 Offset = (HPos & 7);
+ Count = 8 - Offset;
+ if (Count > Width)
+ Count = Width;
+ s -= Offset * GFX.PixSize;
+ Tile = READ_2BYTES(t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+
+ if (BG.TileSize == 8)
+ {
+ (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign,
+ Lines);
+ }
+ else
+ {
+ if (!(Tile & (V_FLIP | H_FLIP)))
+ {
+ // Normal, unflipped
+ (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ if (Tile & H_FLIP)
+ {
+ if (Tile & V_FLIP)
+ {
+ // H & V flip
+ (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ else
+ {
+ // H flip only
+ (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
+ s, Offset, Count, VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // V flip only
+ (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s,
+ Offset, Count, VirtAlign, Lines);
+ }
+ }
+
+ if (BG.TileSize == 8)
+ {
+ t++;
+ if (Quot == 31)
+ t = b2;
+ else if (Quot == 63)
+ t = b1;
+ }
+ else
+ {
+ t += Quot & 1;
+ if (Quot == 63)
+ t = b2;
+ else if (Quot == 127)
+ t = b1;
+ }
+ Quot++;
+ s += 8 * GFX.PixSize;
+ }
+
+ // Middle, unclipped tiles
+ Count = Width - Count;
+ int Middle = Count >> 3;
+ Count &= 7;
+ for (int C = Middle; C > 0; s += 8 * GFX.PixSize, Quot++, C--)
+ {
+ Tile = READ_2BYTES(t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+
+ if (BG.TileSize != 8)
+ {
+ if (Tile & H_FLIP)
+ {
+ // Horizontal flip, but what about vertical flip ?
+ if (Tile & V_FLIP)
+ {
+ // Both horzontal & vertical flip
+ (*DrawTilePtr) (Tile + t2 + 1 - (Quot & 1), s,
+ VirtAlign, Lines);
+ }
+ else
+ {
+ // Horizontal flip only
+ (*DrawTilePtr) (Tile + t1 + 1 - (Quot & 1), s,
+ VirtAlign, Lines);
+ }
+ }
+ else
+ {
+ // No horizontal flip, but is there a vertical flip ?
+ if (Tile & V_FLIP)
+ {
+ // Vertical flip only
+ (*DrawTilePtr) (Tile + t2 + (Quot & 1), s,
+ VirtAlign, Lines);
+ }
+ else
+ {
+ // Normal unflipped
+ (*DrawTilePtr) (Tile + t1 + (Quot & 1), s,
+ VirtAlign, Lines);
+ }
+ }
+ }
+ else
+ {
+ (*DrawTilePtr) (Tile, s, VirtAlign, Lines);
+ }
+
+ if (BG.TileSize == 8)
+ {
+ t++;
+ if (Quot == 31)
+ t = b2;
+ else
+ if (Quot == 63)
+ t = b1;
+ }
+ else
+ {
+ t += Quot & 1;
+ if (Quot == 63)
+ t = b2;
+ else
+ if (Quot == 127)
+ t = b1;
+ }
+ }
+ // Right-hand edge clipped tiles
+ if (Count)
+ {
+ Tile = READ_2BYTES(t);
+ GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
+
+ if (BG.TileSize == 8)
+ (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign,
+ Lines);
+ else
+ {
+ if (!(Tile & (V_FLIP | H_FLIP)))
+ {
+ // Normal, unflipped
+ (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0,
+ Count, VirtAlign, Lines);
+ }
+ else if (Tile & H_FLIP)
+ {
+ if (Tile & V_FLIP)
+ {
+ // H & V flip
+ (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
+ s, 0, Count, VirtAlign,
+ Lines);
+ }
+ else
+ {
+ // H flip only
+ (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
+ s, 0, Count, VirtAlign,
+ Lines);
+ }
+ }
+ else
+ {
+ // V flip only
+ (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1),
+ s, 0, Count, VirtAlign,
+ Lines);
+ }
+ }
+ }
+ }
+ }
+}
+
+#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \
+ CHECK_SOUND(); \
+\
+ uint8 *VRAM1 = Memory.VRAM + 1; \
+ if (GFX.r2130 & 1) \
+ { \
+ if (IPPU.DirectColourMapsNeedRebuild) \
+ S9xBuildDirectColourMaps (); \
+ GFX.ScreenColors = DirectColourMaps [0]; \
+ } \
+ else \
+ GFX.ScreenColors = IPPU.ScreenColors; \
+\
+ int aa, cc; \
+ int dir; \
+ int startx, endx; \
+ uint32 Left = 0; \
+ uint32 Right = 256; \
+ uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \
+\
+ if (!ClipCount) \
+ ClipCount = 1; \
+\
+ Screen += GFX.StartY * GFX.Pitch; \
+ uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \
+ struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \
+\
+ for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \
+ { \
+ int yy; \
+\
+ int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \
+ int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \
+\
+ int32 CentreX = ((int32) l->CentreX << M7) >> M7; \
+ int32 CentreY = ((int32) l->CentreY << M7) >> M7; \
+\
+ if (PPU.Mode7VFlip) \
+ yy = 255 - (int) Line; \
+ else \
+ yy = Line; \
+\
+ yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \
+\
+ int BB = l->MatrixB * yy + (CentreX << 8); \
+ int DD = l->MatrixD * yy + (CentreY << 8); \
+\
+ for (uint32 clip = 0; clip < ClipCount; clip++) \
+ { \
+ if (GFX.pCurrentClip->Count [bg]) \
+ { \
+ Left = GFX.pCurrentClip->Left [clip][bg]; \
+ Right = GFX.pCurrentClip->Right [clip][bg]; \
+ if (Right <= Left) \
+ continue; \
+ } \
+ TYPE *p = (TYPE *) Screen + Left; \
+ uint8 *d = Depth + Left; \
+\
+ if (PPU.Mode7HFlip) \
+ { \
+ startx = Right - 1; \
+ endx = Left - 1; \
+ dir = -1; \
+ aa = -l->MatrixA; \
+ cc = -l->MatrixC; \
+ } \
+ else \
+ { \
+ startx = Left; \
+ endx = Right; \
+ dir = 1; \
+ aa = l->MatrixA; \
+ cc = l->MatrixC; \
+ } \
+\
+ int xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \
+ int AA = l->MatrixA * xx; \
+ int CC = l->MatrixC * xx; \
+\
+ if (!PPU.Mode7Repeat) \
+ { \
+ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
+ { \
+ int X = ((AA + BB) >> 8) & 0x3ff; \
+ int Y = ((CC + DD) >> 8) & 0x3ff; \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ *p = (FUNC); \
+ *d = GFX.Z1; \
+ } \
+ } \
+ } \
+ else \
+ { \
+ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
+ { \
+ int X = ((AA + BB) >> 8); \
+ int Y = ((CC + DD) >> 8); \
+\
+ if (((X | Y) & ~0x3ff) == 0) \
+ { \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ *p = (FUNC); \
+ *d = GFX.Z1; \
+ } \
+ } \
+ else \
+ { \
+ if (PPU.Mode7Repeat == 3) \
+ { \
+ X = (x + HOffset) & 7; \
+ Y = (yy + CentreY) & 7; \
+ uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ *p = (FUNC); \
+ *d = GFX.Z1; \
+ } \
+ } \
+ } \
+ } \
+ } \
+ } \
+ }
+
+void DrawBGMode7Background (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask))
+}
+
+void DrawBGMode7Background16 (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & GFX.Mode7Mask]);
+}
+
+void DrawBGMode7Background16Add (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask],
+ p [GFX.Delta]) :
+ COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask],
+ GFX.FixedColour)) :
+ GFX.ScreenColors [b & GFX.Mode7Mask]);
+}
+
+void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_ADD1_2 (GFX.ScreenColors [b & GFX.Mode7Mask],
+ p [GFX.Delta]) :
+ COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask],
+ GFX.FixedColour)) :
+ GFX.ScreenColors [b & GFX.Mode7Mask]);
+}
+
+void DrawBGMode7Background16Sub (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask],
+ p [GFX.Delta]) :
+ COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask],
+ GFX.FixedColour)) :
+ GFX.ScreenColors [b & GFX.Mode7Mask]);
+}
+
+void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_SUB1_2 (GFX.ScreenColors [b & GFX.Mode7Mask],
+ p [GFX.Delta]) :
+ COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask],
+ GFX.FixedColour)) :
+ GFX.ScreenColors [b & GFX.Mode7Mask]);
+}
+
+#define RENDER_BACKGROUND_MODE7_i(TYPE,FUNC,COLORFUNC) \
+ CHECK_SOUND(); \
+\
+ uint8 *VRAM1 = Memory.VRAM + 1; \
+ if (GFX.r2130 & 1) \
+ { \
+ if (IPPU.DirectColourMapsNeedRebuild) \
+ S9xBuildDirectColourMaps (); \
+ GFX.ScreenColors = DirectColourMaps [0]; \
+ } \
+ else \
+ GFX.ScreenColors = IPPU.ScreenColors; \
+ \
+ int aa, cc; \
+ int dir; \
+ int startx, endx; \
+ uint32 Left = 0; \
+ uint32 Right = 256; \
+ uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \
+ \
+ if (!ClipCount) \
+ ClipCount = 1; \
+ \
+ Screen += GFX.StartY * GFX.Pitch; \
+ uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \
+ struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \
+ bool8 allowSimpleCase = FALSE; \
+ if (!l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100) \
+ && !LineMatrixData[GFX.EndY].MatrixB && !LineMatrixData[GFX.EndY].MatrixC \
+ && (LineMatrixData[GFX.EndY].MatrixA == 0x0100) && (LineMatrixData[GFX.EndY].MatrixD == 0x0100) \
+ ) \
+ allowSimpleCase = TRUE; \
+ \
+ for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \
+ { \
+ int yy; \
+ \
+ int HOffset = ((int) LineData [Line].BG[0].HOffset << M7) >> M7; \
+ int VOffset = ((int) LineData [Line].BG[0].VOffset << M7) >> M7; \
+ \
+ int CentreX = ((int) l->CentreX << M7) >> M7; \
+ int CentreY = ((int) l->CentreY << M7) >> M7; \
+ \
+ if (PPU.Mode7VFlip) \
+ yy = 255 - (int) Line; \
+ else \
+ yy = Line; \
+ \
+ \
+ yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \
+ bool8 simpleCase = FALSE; \
+ int BB; \
+ int DD; \
+ /* Make a special case for the identity matrix, since it's a common case and */ \
+ /* can be done much more quickly without special effects */ \
+ if (allowSimpleCase && !l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100)) \
+ { \
+ BB = CentreX << 8; \
+ DD = (yy + CentreY) << 8; \
+ simpleCase = TRUE; \
+ } \
+ else \
+ { \
+ BB = l->MatrixB * yy + (CentreX << 8); \
+ DD = l->MatrixD * yy + (CentreY << 8); \
+ } \
+ \
+ for (uint32 clip = 0; clip < ClipCount; clip++) \
+ { \
+ if (GFX.pCurrentClip->Count [bg]) \
+ { \
+ Left = GFX.pCurrentClip->Left [clip][bg]; \
+ Right = GFX.pCurrentClip->Right [clip][bg]; \
+ if (Right <= Left) \
+ continue; \
+ } \
+ TYPE *p = (TYPE *) Screen + Left; \
+ uint8 *d = Depth + Left; \
+ \
+ if (PPU.Mode7HFlip) \
+ { \
+ startx = Right - 1; \
+ endx = Left - 1; \
+ dir = -1; \
+ aa = -l->MatrixA; \
+ cc = -l->MatrixC; \
+ } \
+ else \
+ { \
+ startx = Left; \
+ endx = Right; \
+ dir = 1; \
+ aa = l->MatrixA; \
+ cc = l->MatrixC; \
+ } \
+ int xx; \
+ \
+ xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \
+ int AA, CC = 0; \
+ if (simpleCase) \
+ { \
+ AA = xx << 8; \
+ } \
+ else \
+ { \
+ AA = l->MatrixA * xx; \
+ CC = l->MatrixC * xx; \
+ } \
+ if (simpleCase) \
+ { \
+ if (!PPU.Mode7Repeat) \
+ { \
+ int x = startx; \
+ do \
+ { \
+ int X = ((AA + BB) >> 8) & 0x3ff; \
+ int Y = (DD >> 8) & 0x3ff; \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ TYPE theColor = COLORFUNC; \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ AA += aa, p++, d++; \
+ x += dir; \
+ } while (x != endx); \
+ } \
+ else \
+ { \
+ int x = startx; \
+ do { \
+ int X = (AA + BB) >> 8; \
+ int Y = DD >> 8; \
+\
+ if (((X | Y) & ~0x3ff) == 0) \
+ { \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ TYPE theColor = COLORFUNC; \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ } \
+ else if (PPU.Mode7Repeat == 3) \
+ { \
+ X = (x + HOffset) & 7; \
+ Y = (yy + CentreY) & 7; \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ TYPE theColor = COLORFUNC; \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ } \
+ AA += aa; p++; d++; \
+ x += dir; \
+ } while (x != endx); \
+ } \
+ } \
+ else if (!PPU.Mode7Repeat) \
+ { \
+ /* The bilinear interpolator: get the colors at the four points surrounding */ \
+ /* the location of one point in the _sampled_ image, and weight them according */ \
+ /* to their (city block) distance. It's very smooth, but blurry with "close up" */ \
+ /* points. */ \
+ \
+ /* 460 (slightly less than 2 source pixels per displayed pixel) is an educated */ \
+ /* guess for where bilinear filtering will become a poor method for averaging. */ \
+ /* (When reducing the image, the weighting used by a bilinear filter becomes */ \
+ /* arbitrary, and a simple mean is a better way to represent the source image.) */ \
+ /* You can think of this as a kind of mipmapping. */ \
+ if ((aa < 460 && aa > -460) && (cc < 460 && cc > -460)) \
+ {\
+ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
+ { \
+ uint32 xPos = AA + BB; \
+ uint32 xPix = xPos >> 8; \
+ uint32 yPos = CC + DD; \
+ uint32 yPix = yPos >> 8; \
+ uint32 X = xPix & 0x3ff; \
+ uint32 Y = yPix & 0x3ff; \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \
+ uint32 X10 = (xPix + dir) & 0x3ff; \
+ uint32 Y01 = (yPix + (PPU.Mode7VFlip?-1:1)) & 0x3ff; \
+ uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \
+ uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \
+ uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 p1 = COLORFUNC; \
+ p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \
+ b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \
+ uint32 p2 = COLORFUNC; \
+ p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \
+ b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \
+ uint32 p4 = COLORFUNC; \
+ p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \
+ b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \
+ uint32 p3 = COLORFUNC; \
+ p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \
+ /* Xdel, Ydel: position (in 1/32nds) between the points */ \
+ uint32 Xdel = (xPos >> 3) & 0x1F; \
+ uint32 Ydel = (yPos >> 3) & 0x1F; \
+ uint32 XY = (Xdel*Ydel) >> 5; \
+ uint32 area1 = 0x20 + XY - Xdel - Ydel; \
+ uint32 area2 = Xdel - XY; \
+ uint32 area3 = Ydel - XY; \
+ uint32 area4 = XY; \
+ if(PPU.Mode7HFlip){ \
+ uint32 tmp=area1; area1=area2; area2=tmp; \
+ tmp=area3; area3=area4; area4=tmp; \
+ } \
+ if(PPU.Mode7VFlip){ \
+ uint32 tmp=area1; area1=area3; area3=tmp; \
+ tmp=area2; area2=area4; area4=tmp; \
+ } \
+ uint32 tempColor = ((area1 * p1) + \
+ (area2 * p2) + \
+ (area3 * p3) + \
+ (area4 * p4)) >> 5; \
+ TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ } \
+ } \
+ else \
+ /* The oversampling method: get the colors at four corners of a square */ \
+ /* in the _displayed_ image, and average them. It's sharp and clean, but */ \
+ /* gives the usual huge pixels when the source image gets "close." */ \
+ { \
+ /* Find the dimensions of the square in the source image whose corners will be examined. */ \
+ uint32 aaDelX = aa >> 1; \
+ uint32 ccDelX = cc >> 1; \
+ uint32 bbDelY = l->MatrixB >> 1; \
+ uint32 ddDelY = l->MatrixD >> 1; \
+ /* Offset the location within the source image so that the four sampled points */ \
+ /* center around where the single point would otherwise have been drawn. */ \
+ BB -= (bbDelY >> 1); \
+ DD -= (ddDelY >> 1); \
+ AA -= (aaDelX >> 1); \
+ CC -= (ccDelX >> 1); \
+ uint32 BB10 = BB + aaDelX; \
+ uint32 BB01 = BB + bbDelY; \
+ uint32 BB11 = BB + aaDelX + bbDelY; \
+ uint32 DD10 = DD + ccDelX; \
+ uint32 DD01 = DD + ddDelY; \
+ uint32 DD11 = DD + ccDelX + ddDelY; \
+ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
+ { \
+ uint32 X = ((AA + BB) >> 8) & 0x3ff; \
+ uint32 Y = ((CC + DD) >> 8) & 0x3ff; \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ /* X, Y, X10, Y10, etc. are the coordinates of the four pixels within the */ \
+ /* source image that we're going to examine. */ \
+ uint32 X10 = ((AA + BB10) >> 8) & 0x3ff; \
+ uint32 Y10 = ((CC + DD10) >> 8) & 0x3ff; \
+ uint32 X01 = ((AA + BB01) >> 8) & 0x3ff; \
+ uint32 Y01 = ((CC + DD01) >> 8) & 0x3ff; \
+ uint32 X11 = ((AA + BB11) >> 8) & 0x3ff; \
+ uint32 Y11 = ((CC + DD11) >> 8) & 0x3ff; \
+ uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y10 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \
+ uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X01 >> 2) & ~1)] << 7); \
+ uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y11 & ~7) << 5) + ((X11 >> 2) & ~1)] << 7); \
+ TYPE p1 = COLORFUNC; \
+ b = *(TileData10 + ((Y10 & 7) << 4) + ((X10 & 7) << 1)); \
+ TYPE p2 = COLORFUNC; \
+ b = *(TileData01 + ((Y01 & 7) << 4) + ((X01 & 7) << 1)); \
+ TYPE p3 = COLORFUNC; \
+ b = *(TileData11 + ((Y11 & 7) << 4) + ((X11 & 7) << 1)); \
+ TYPE p4 = COLORFUNC; \
+ TYPE theColor = Q_INTERPOLATE(p1, p2, p3, p4); \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ } \
+ } \
+ } \
+ else \
+ { \
+ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
+ { \
+ uint32 xPos = AA + BB; \
+ uint32 xPix = xPos >> 8; \
+ uint32 yPos = CC + DD; \
+ uint32 yPix = yPos >> 8; \
+ uint32 X = xPix; \
+ uint32 Y = yPix; \
+ \
+\
+ if (((X | Y) & ~0x3ff) == 0) \
+ { \
+ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \
+ uint32 X10 = (xPix + dir) & 0x3ff; \
+ uint32 Y01 = (yPix + dir) & 0x3ff; \
+ uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \
+ uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \
+ uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+ uint32 p1 = COLORFUNC; \
+ p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \
+ b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \
+ uint32 p2 = COLORFUNC; \
+ p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \
+ b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \
+ uint32 p4 = COLORFUNC; \
+ p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \
+ b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \
+ uint32 p3 = COLORFUNC; \
+ p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \
+ /* Xdel, Ydel: position (in 1/32nds) between the points */ \
+ uint32 Xdel = (xPos >> 3) & 0x1F; \
+ uint32 Ydel = (yPos >> 3) & 0x1F; \
+ uint32 XY = (Xdel*Ydel) >> 5; \
+ uint32 area1 = 0x20 + XY - Xdel - Ydel; \
+ uint32 area2 = Xdel - XY; \
+ uint32 area3 = Ydel - XY; \
+ uint32 area4 = XY; \
+ uint32 tempColor = ((area1 * p1) + \
+ (area2 * p2) + \
+ (area3 * p3) + \
+ (area4 * p4)) >> 5; \
+ TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ } \
+ else \
+ { \
+ if (PPU.Mode7Repeat == 3) \
+ { \
+ X = (x + HOffset) & 7; \
+ Y = (yy + CentreY) & 7; \
+ uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \
+ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
+ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \
+ { \
+ TYPE theColor = COLORFUNC; \
+ *p = (FUNC) | ALPHA_BITS_MASK; \
+ *d = GFX.Z1; \
+ } \
+ } \
+ } \
+ } \
+ } \
+ } \
+ }
+
+STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
+{
+ register uint32 x = ((A >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) +
+ ((B >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) +
+ ((C >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) +
+ ((D >> 2) & HIGH_BITS_SHIFTED_TWO_MASK);
+ register uint32 y = (A & TWO_LOW_BITS_MASK) +
+ (B & TWO_LOW_BITS_MASK) +
+ (C & TWO_LOW_BITS_MASK) +
+ (D & TWO_LOW_BITS_MASK);
+ y = (y>>2) & TWO_LOW_BITS_MASK;
+ return x+y;
+}
+
+void DrawBGMode7Background16_i (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7_i (uint16, theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
+}
+
+void DrawBGMode7Background16Add_i (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ (COLOR_ADD (theColor,
+ p [GFX.Delta])) :
+ (COLOR_ADD (theColor,
+ GFX.FixedColour))) :
+ theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
+}
+
+void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_ADD1_2 (theColor,
+ p [GFX.Delta]) :
+ COLOR_ADD (theColor,
+ GFX.FixedColour)) :
+ theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
+}
+
+void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_SUB (theColor,
+ p [GFX.Delta]) :
+ COLOR_SUB (theColor,
+ GFX.FixedColour)) :
+ theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
+}
+
+void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg)
+{
+ RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
+ (*(d + GFX.DepthDelta) != 1 ?
+ COLOR_SUB1_2 (theColor,
+ p [GFX.Delta]) :
+ COLOR_SUB (theColor,
+ GFX.FixedColour)) :
+ theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
+}
+
+#define _BUILD_SETUP(F) \
+GFX.BuildPixel = BuildPixel##F; \
+GFX.BuildPixel2 = BuildPixel2##F; \
+GFX.DecomposePixel = DecomposePixel##F; \
+RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_##F; \
+GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_##F; \
+BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_##F; \
+RED_HI_BIT_MASK = RED_HI_BIT_MASK_##F; \
+GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_##F; \
+BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_##F; \
+MAX_RED = MAX_RED_##F; \
+MAX_GREEN = MAX_GREEN_##F; \
+MAX_BLUE = MAX_BLUE_##F; \
+GREEN_HI_BIT = ((MAX_GREEN_##F + 1) >> 1); \
+SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_##F; \
+RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_##F | \
+ GREEN_LOW_BIT_MASK_##F | \
+ BLUE_LOW_BIT_MASK_##F); \
+RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_##F | \
+ GREEN_HI_BIT_MASK_##F | \
+ BLUE_HI_BIT_MASK_##F); \
+RGB_HI_BITS_MASKx2 = ((RED_HI_BIT_MASK_##F | \
+ GREEN_HI_BIT_MASK_##F | \
+ BLUE_HI_BIT_MASK_##F) << 1); \
+RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK; \
+FIRST_COLOR_MASK = FIRST_COLOR_MASK_##F; \
+SECOND_COLOR_MASK = SECOND_COLOR_MASK_##F; \
+THIRD_COLOR_MASK = THIRD_COLOR_MASK_##F; \
+ALPHA_BITS_MASK = ALPHA_BITS_MASK_##F; \
+FIRST_THIRD_COLOR_MASK = FIRST_COLOR_MASK | THIRD_COLOR_MASK; \
+TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \
+HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \
+ ~TWO_LOW_BITS_MASK ) >> 2);
+
+void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D)
+{
+ bool8 BG0;
+ bool8 BG1;
+ bool8 BG2;
+ bool8 BG3;
+ bool8 OB;
+
+ GFX.S = Screen;
+
+ if (!sub)
+ {
+ GFX.pCurrentClip = &IPPU.Clip [0];
+ BG0 = ON_MAIN (0);
+ BG1 = ON_MAIN (1);
+ BG2 = ON_MAIN (2);
+ BG3 = ON_MAIN (3);
+ OB = ON_MAIN (4);
+ }
+ else
+ {
+ GFX.pCurrentClip = &IPPU.Clip [1];
+ BG0 = ON_SUB (0);
+ BG1 = ON_SUB (1);
+ BG2 = ON_SUB (2);
+ BG3 = ON_SUB (3);
+ OB = ON_SUB (4);
+ }
+
+ sub |= force_no_add;
+
+ if (PPU.BGMode <= 1)
+ {
+ if (OB)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(4));
+ DrawOBJS (!sub, D);
+ }
+ if (BG0)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(0));
+ DrawBackground (PPU.BGMode, 0, D + 10, D + 14);
+ }
+ if (BG1)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(1));
+ DrawBackground (PPU.BGMode, 1, D + 9, D + 13);
+ }
+ if (BG2)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(2));
+ DrawBackground (PPU.BGMode, 2, D + 3,
+ PPU.BG3Priority ? D + 17 : D + 6);
+ }
+ if (BG3 && PPU.BGMode == 0)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(3));
+ DrawBackground (PPU.BGMode, 3, D + 2, D + 5);
+ }
+ }
+ else if (PPU.BGMode != 7)
+ {
+ if (OB)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(4));
+ DrawOBJS (!sub, D);
+ }
+ if (BG0)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(0));
+ DrawBackground (PPU.BGMode, 0, D + 5, D + 13);
+ }
+ if (PPU.BGMode != 6 && BG1)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(1));
+ DrawBackground (PPU.BGMode, 1, D + 2, D + 9);
+ }
+ }
+ else
+ {
+ if (OB)
+ {
+ SelectTileRenderer (sub || !SUB_OR_ADD(4));
+ DrawOBJS (!sub, D);
+ }
+ if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1))
+ {
+ int bg;
+
+ if ((Memory.FillRAM [0x2133] & 0x40)&&BG1)
+ {
+ GFX.Mode7Mask = 0x7f;
+ GFX.Mode7PriorityMask = 0x80;
+ Mode7Depths [0] = (BG0?5:1) + D;
+ Mode7Depths [1] = 9 + D;
+ bg = 1;
+ }
+ else
+ {
+ GFX.Mode7Mask = 0xff;
+ GFX.Mode7PriorityMask = 0;
+ Mode7Depths [0] = 5 + D;
+ Mode7Depths [1] = 5 + D;
+ bg = 0;
+ }
+ if (sub || !SUB_OR_ADD(0))
+ {
+ if (!Settings.Mode7Interpolate)
+ DrawBGMode7Background16 (Screen, bg);
+ else
+ DrawBGMode7Background16_i (Screen, bg);
+ }
+ else
+ {
+ if (GFX.r2131 & 0x80)
+ {
+ if (GFX.r2131 & 0x40)
+ {
+ if (!Settings.Mode7Interpolate)
+ DrawBGMode7Background16Sub1_2 (Screen, bg);
+ else
+ DrawBGMode7Background16Sub1_2_i (Screen, bg);
+ }
+ else
+ {
+ if (!Settings.Mode7Interpolate)
+ DrawBGMode7Background16Sub (Screen, bg);
+ else
+ DrawBGMode7Background16Sub_i (Screen, bg);
+ }
+ }
+ else
+ {
+ if (GFX.r2131 & 0x40)
+ {
+ if (!Settings.Mode7Interpolate)
+ DrawBGMode7Background16Add1_2 (Screen, bg);
+ else
+ DrawBGMode7Background16Add1_2_i (Screen, bg);
+ }
+ else
+ {
+ if (!Settings.Mode7Interpolate)
+ DrawBGMode7Background16Add (Screen, bg);
+ else
+ DrawBGMode7Background16Add_i (Screen, bg);
+ }
+ }
+ }
+ }
+ }
+}
+
+#include "font.h"
+
+void DisplayChar (uint8 *Screen, uint8 c)
+{
+ int line = (((c & 0x7f) - 32) >> 4) * font_height;
+ int offset = (((c & 0x7f) - 32) & 15) * font_width;
+ if (Settings.SixteenBit)
+ {
+ int h, w;
+ uint16 *s = (uint16 *) Screen;
+ for (h = 0; h < font_height; h++, line++,
+ s += GFX.PPL - font_width)
+ {
+ for (w = 0; w < font_width; w++, s++)
+ {
+ uint8 p = font [line][offset + w];
+
+ if (p == '#')
+ {
+ /*
+ if(Memory.Hacked)
+ *s= BUILD_PIXEL(31,0,0);
+ else if(Memory.Iffy)
+ *s= BUILD_PIXEL(31,31,0);
+ else if(Memory.Iformat==1)
+ *s= BUILD_PIXEL(0,31,0);
+ else if(Memory.Iformat==2)
+ *s= BUILD_PIXEL(0,31,31);
+ else *s = 0xffff;
+ */
+ *s=Settings.DisplayColor;
+ }
+ else
+ if (p == '.')
+ *s = BLACK;
+ }
+ }
+ }
+ else
+ {
+ int h, w;
+ uint8 *s = Screen;
+ for (h = 0; h < font_height; h++, line++,
+ s += GFX.PPL - font_width)
+ {
+ for (w = 0; w < font_width; w++, s++)
+ {
+ uint8 p = font [line][offset + w];
+
+ if (p == '#')
+ *s = 255;
+ else
+ if (p == '.')
+ *s = BLACK;
+ }
+ }
+ }
+}
+
+static void S9xDisplayFrameRate ()
+{
+ uint8 *Screen = GFX.Screen + 2 +
+ (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch2;
+ char string [10];
+ int len = 5;
+
+ sprintf (string, "%02d/%02d", IPPU.DisplayedRenderedFrameCount,
+ (int) Memory.ROMFramesPerSecond);
+
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ DisplayChar (Screen, string [i]);
+ Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) :
+ (font_width - 1);
+ }
+}
+
+static void S9xDisplayString (const char *string)
+{
+ uint8 *Screen = GFX.Screen + 2 +
+ (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch2;
+ int len = strlen (string);
+ int max_chars = IPPU.RenderedScreenWidth / (font_width - 1);
+ int char_count = 0;
+ int i;
+
+ for (i = 0; i < len; i++, char_count++)
+ {
+ if (char_count >= max_chars || string [i] < 32)
+ {
+ Screen -= Settings.SixteenBit ?
+ (font_width - 1) * sizeof (uint16) * max_chars :
+ (font_width - 1) * max_chars;
+ Screen += font_height * GFX.Pitch;
+ if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight)
+ break;
+ char_count -= max_chars;
+ }
+ if (string [i] < 32)
+ continue;
+ DisplayChar (Screen, string [i]);
+ Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) :
+ (font_width - 1);
+ }
+}
+
+void S9xUpdateScreen ()
+{
+ int32 x2 = 1;
+
+ GFX.S = GFX.Screen;
+ GFX.r2131 = Memory.FillRAM [0x2131];
+ GFX.r212c = Memory.FillRAM [0x212c];
+ GFX.r212d = Memory.FillRAM [0x212d];
+ GFX.r2130 = Memory.FillRAM [0x2130];
+
+#ifdef JP_FIX
+
+ GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 &&
+ (GFX.r212c & 15) != (GFX.r212d & 15) &&
+ (GFX.r2131 == 0x3f);
+
+#else
+
+ GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 &&
+ (GFX.r212c & 15) != (GFX.r212d & 15) &&
+ (GFX.r2131 & 0x3f) == 0;
+
+#endif
+
+ if (IPPU.OBJChanged)
+ S9xSetupOBJ ();
+
+ if (PPU.RecomputeClipWindows)
+ {
+ ComputeClipWindows ();
+ PPU.RecomputeClipWindows = FALSE;
+ }
+
+ GFX.StartY = IPPU.PreviousLine;
+ if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight)
+ GFX.EndY = PPU.ScreenHeight - 1;
+
+ // XXX: Check ForceBlank? Or anything else?
+ PPU.RangeTimeOver |= GFX.OBJLines[GFX.EndY].RTOFlags;
+
+ uint32 starty = GFX.StartY;
+ uint32 endy = GFX.EndY;
+
+ if (Settings.SupportHiRes &&
+ (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace || IPPU.DoubleHeightPixels))
+ {
+ if (PPU.BGMode == 5 || PPU.BGMode == 6|| IPPU.Interlace)
+ {
+ IPPU.RenderedScreenWidth = 512;
+ x2 = 2;
+ }
+
+ if (IPPU.DoubleHeightPixels)
+ {
+ starty = GFX.StartY * 2;
+ endy = GFX.EndY * 2 + 1;
+ }
+
+ if ((PPU.BGMode == 5 || PPU.BGMode == 6) && !IPPU.DoubleWidthPixels)
+ {
+ // The game has switched from lo-res to hi-res mode part way down
+ // the screen. Scale any existing lo-res pixels on screen
+ if (Settings.SixteenBit)
+ {
+ for (register uint32 y = 0; y < starty; y++)
+ {
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255;
+ register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510;
+
+ for (register int x = 255; x >= 0; x--, p--, q -= 2)
+ *q = *(q + 1) = *p;
+ }
+ }
+ else
+ {
+ for (register uint32 y = 0; y < starty; y++)
+ {
+ register uint8 *p = GFX.Screen + y * GFX.Pitch2 + 255;
+ register uint8 *q = GFX.Screen + y * GFX.Pitch2 + 510;
+ for (register int x = 255; x >= 0; x--, p--, q -= 2)
+ *q = *(q + 1) = *p;
+ }
+ }
+ IPPU.DoubleWidthPixels = TRUE;
+ }
+ // BJ: And we have to change the height if Interlace gets set,
+ // too.
+ if (IPPU.Interlace && !IPPU.DoubleHeightPixels)
+ {
+ starty = GFX.StartY * 2;
+ endy = GFX.EndY * 2 + 1;
+ IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1;
+ IPPU.DoubleHeightPixels = TRUE;
+ GFX.Pitch2 = GFX.RealPitch;
+ GFX.Pitch = GFX.RealPitch * 2;
+ if (Settings.SixteenBit)
+ GFX.PPL = GFX.PPLx2 = GFX.RealPitch;
+ else
+ GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1;
+
+ // The game has switched from non-interlaced to interlaced mode
+ // part way down the screen. Scale everything.
+ for (register int32 y = (int32) GFX.StartY - 1; y >= 0; y--)
+ {
+ memmove (GFX.Screen + y * 2 * GFX.Pitch2,
+ GFX.Screen + y * GFX.Pitch2,
+ GFX.Pitch2);
+ memmove (GFX.Screen + (y * 2 + 1) * GFX.Pitch2,
+ GFX.Screen + y * GFX.Pitch2,
+ GFX.Pitch2);
+ }
+ }
+ }
+
+ uint32 black = BLACK | (BLACK << 16);
+
+ if (Settings.Transparency && Settings.SixteenBit)
+ {
+ if (GFX.Pseudo)
+ {
+ GFX.r2131 = 0x5f;
+ GFX.r212c &= (Memory.FillRAM [0x212d] | 0xf0);
+ GFX.r212d |= (Memory.FillRAM [0x212c] & 0x0f);
+ GFX.r2130 |= 2;
+ }
+
+ if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING &&
+ (GFX.r2130 & 0x30) != 0x30 &&
+ !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0))
+ {
+ struct ClipData *pClip;
+
+ GFX.FixedColour = BUILD_PIXEL (IPPU.XB [PPU.FixedColourRed],
+ IPPU.XB [PPU.FixedColourGreen],
+ IPPU.XB [PPU.FixedColourBlue]);
+
+ // Clear the z-buffer, marking areas 'covered' by the fixed
+ // colour as depth 1.
+ pClip = &IPPU.Clip [1];
+
+ // Clear the z-buffer
+ if (pClip->Count [5])
+ {
+ // Colour window enabled.
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth);
+ ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth);
+
+ if (IPPU.Clip [0].Count [5])
+ {
+ uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2);
+ uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth);
+ while (p < q)
+ *p++ = black;
+ }
+
+ for (uint32 c = 0; c < pClip->Count [5]; c++)
+ {
+ if (pClip->Right [c][5] > pClip->Left [c][5])
+ {
+ memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2,
+ 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2);
+
+ if (IPPU.Clip [0].Count [5])
+ {
+ // Blast, have to clear the sub-screen to the fixed-colour
+ // because there is a colour window in effect clipping
+ // the main screen that will allow the sub-screen
+ // 'underneath' to show through.
+
+ uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2);
+ uint16 *q = p + pClip->Right [c][5] * x2;
+ p += pClip->Left [c][5] * x2;
+
+ while (p < q)
+ *p++ = (uint16) GFX.FixedColour;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth);
+ memset (GFX.SubZBuffer + y * GFX.ZPitch, 1, IPPU.RenderedScreenWidth);
+
+ if (IPPU.Clip [0].Count [5])
+ {
+ // Blast, have to clear the sub-screen to the fixed-colour
+ // because there is a colour window in effect clipping
+ // the main screen that will allow the sub-screen
+ // 'underneath' to show through.
+
+ uint32 b = GFX.FixedColour | (GFX.FixedColour << 16);
+ uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2);
+ uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth);
+
+ while (p < q)
+ *p++ = b;
+ }
+ }
+ }
+
+ if (ANYTHING_ON_SUB)
+ {
+ GFX.DB = GFX.SubZBuffer;
+ RenderScreen (GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH);
+ }
+
+ if (IPPU.Clip [0].Count [5])
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2);
+ register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch;
+ register uint8 *e = d + IPPU.RenderedScreenWidth;
+
+ while (d < e)
+ {
+ if (*d > 1)
+ *p = *(p + GFX.Delta);
+ else
+ *p = BLACK;
+ d++;
+ p++;
+ }
+ }
+ }
+
+ GFX.DB = GFX.ZBuffer;
+ RenderScreen (GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH);
+
+ if (SUB_OR_ADD(5))
+ {
+ uint32 back = IPPU.ScreenColors [0];
+ uint32 Left = 0;
+ uint32 Right = 256;
+ uint32 Count;
+
+ pClip = &IPPU.Clip [0];
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ if (!(Count = pClip->Count [5]))
+ {
+ Left = 0;
+ Right = 256 * x2;
+ Count = 1;
+ }
+
+ for (uint32 b = 0; b < Count; b++)
+ {
+ if (pClip->Count [5])
+ {
+ Left = pClip->Left [b][5] * x2;
+ Right = pClip->Right [b][5] * x2;
+ if (Right <= Left)
+ continue;
+ }
+
+ if (GFX.r2131 & 0x80)
+ {
+ if (GFX.r2131 & 0x40)
+ {
+ // Subtract, halving the result.
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+ register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
+ register uint8 *e = d + Right;
+ uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour);
+
+ d += Left;
+ while (d < e)
+ {
+ if (*d == 0)
+ {
+ if (*s)
+ {
+ if (*s != 1)
+ *p = COLOR_SUB1_2 (back, *(p + GFX.Delta));
+ else
+ *p = back_fixed;
+ }
+ else
+ *p = (uint16) back;
+ }
+ d++;
+ p++;
+ s++;
+ }
+ }
+ else
+ {
+ // Subtract
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+ register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
+ register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ register uint8 *e = d + Right;
+ uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour);
+
+ d += Left;
+ while (d < e)
+ {
+ if (*d == 0)
+ {
+ if (*s)
+ {
+ if (*s != 1)
+ *p = COLOR_SUB (back, *(p + GFX.Delta));
+ else
+ *p = back_fixed;
+ }
+ else
+ *p = (uint16) back;
+ }
+ d++;
+ p++;
+ s++;
+ }
+ }
+ }
+ else if (GFX.r2131 & 0x40)
+ {
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+ register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
+ register uint8 *e = d + Right;
+ uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour);
+ d += Left;
+ while (d < e)
+ {
+ if (*d == 0)
+ {
+ if (*s)
+ {
+ if (*s != 1)
+ *p = COLOR_ADD1_2 (back, *(p + GFX.Delta));
+ else
+ *p = back_fixed;
+ }
+ else
+ *p = (uint16) back;
+ }
+ d++;
+ p++;
+ s++;
+ }
+ }
+ else if (back != 0)
+ {
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+ register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
+ register uint8 *e = d + Right;
+ uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour);
+ d += Left;
+ while (d < e)
+ {
+ if (*d == 0)
+ {
+ if (*s)
+ {
+ if (*s != 1)
+ *p = COLOR_ADD (back, *(p + GFX.Delta));
+ else
+ *p = back_fixed;
+ }
+ else
+ *p = (uint16) back;
+ }
+ d++;
+ p++;
+ s++;
+ }
+ }
+ else
+ {
+ if (!pClip->Count [5])
+ {
+ // The backdrop has not been cleared yet - so
+ // copy the sub-screen to the main screen
+ // or fill it with the back-drop colour if the
+ // sub-screen is clear.
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+ register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
+ register uint8 *e = d + Right;
+ d += Left;
+ while (d < e)
+ {
+ if (*d == 0)
+ {
+ if (*s)
+ {
+ if (*s != 1)
+ *p = *(p + GFX.Delta);
+ else
+ *p = GFX.FixedColour;
+ }
+ else
+ *p = (uint16) back;
+ }
+ d++;
+ p++;
+ s++;
+ }
+ }
+ }
+ }
+ }
+ } // --if (SUB_OR_ADD(5))
+ else
+ {
+ // Subscreen not being added to back
+ uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16);
+ pClip = &IPPU.Clip [0];
+
+ if (pClip->Count [5])
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ for (uint32 b = 0; b < pClip->Count [5]; b++)
+ {
+ uint32 Left = pClip->Left [b][5] * x2;
+ uint32 Right = pClip->Right [b][5] * x2;
+ uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+ uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ uint8 *e = d + Right;
+ d += Left;
+
+ while (d < e)
+ {
+ if (*d == 0)
+ *p = (int16) back;
+ d++;
+ p++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2);
+ uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
+ uint8 *e = d + 256 * x2;
+
+ while (d < e)
+ {
+ if (*d == 0)
+ *p = (int16) back;
+ d++;
+ p++;
+ }
+ }
+ }
+ }
+ } //force blanking
+ else
+ {
+ // 16bit and transparency but currently no transparency effects in
+ // operation.
+
+ uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16);
+
+ if (PPU.ForcedBlanking)
+ back = black;
+
+ if (IPPU.Clip [0].Count[5])
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2);
+ uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth);
+
+ while (p < q)
+ *p++ = black;
+
+ for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++)
+ {
+ if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5])
+ {
+ uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2);
+ uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2;
+ p += IPPU.Clip [0].Left [c][5] * x2;
+
+ while (p < q)
+ *p++ = (uint16) back;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2);
+ uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth);
+ while (p < q)
+ *p++ = back;
+ }
+ }
+
+ if (!PPU.ForcedBlanking)
+ {
+ for (uint32 y = starty; y <= endy; y++)
+ {
+ ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth);
+ }
+ GFX.DB = GFX.ZBuffer;
+ RenderScreen (GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH);
+ }
+ }
+ }
+ else
+ {
+ }
+
+ if (Settings.SupportHiRes)
+ {
+ if (PPU.BGMode != 5 && PPU.BGMode != 6 && IPPU.DoubleWidthPixels)
+ {
+ // Mixure of background modes used on screen - scale width
+ // of all non-mode 5 and 6 pixels.
+ if (Settings.SixteenBit)
+ {
+ for (register uint32 y = starty; y <= endy; y++)
+ {
+ register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255;
+ register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510;
+ for (register int x = 255; x >= 0; x--, p--, q -= 2)
+ *q = *(q + 1) = *p;
+ }
+ }
+ else
+ {
+ for (register uint32 y = starty; y <= endy; y++)
+ {
+ register uint8 *p = GFX.Screen + y * GFX.Pitch2 + 255;
+ register uint8 *q = GFX.Screen + y * GFX.Pitch2 + 510;
+ for (register int x = 255; x >= 0; x--, p--, q -= 2)
+ *q = *(q + 1) = *p;
+ }
+ }
+ }
+
+ // Double the height of the pixels just drawn
+ FIX_INTERLACE(GFX.Screen, FALSE, GFX.ZBuffer);
+ }
+
+ IPPU.PreviousLine = IPPU.CurrentLine;
+}
+
+
diff --git a/source/gfx.h b/source/gfx.h
new file mode 100644
index 0000000..b145f49
--- /dev/null
+++ b/source/gfx.h
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _GFX_H_
+#define _GFX_H_
+
+#include "port.h"
+#include "snes9x.h"
+
+struct SGFX{
+ // Initialize these variables
+ uint8 *Screen;
+ uint8 *SubScreen;
+ uint8 *ZBuffer;
+ uint8 *SubZBuffer;
+ uint32 Pitch;
+
+ // Setup in call to S9xGraphicsInit()
+ int Delta;
+ uint16 *X2;
+ uint16 *ZERO_OR_X2;
+ uint16 *ZERO;
+ uint32 RealPitch; // True pitch of Screen buffer.
+ uint32 Pitch2; // Same as RealPitch except while using speed up hack for Glide.
+ uint32 ZPitch; // Pitch of ZBuffer
+ uint32 PPL; // Number of pixels on each of Screen buffer
+ uint32 PPLx2;
+ uint32 PixSize;
+ uint8 *S;
+ uint8 *DB;
+ uint16 *ScreenColors;
+ uint32 DepthDelta;
+ uint8 Z1; // Depth for comparison
+ uint8 Z2; // Depth to save
+ uint8 ZSprite; // Used to ensure only 1st sprite is drawn per pixel
+ uint32 FixedColour;
+ const char *InfoString;
+ uint32 InfoStringTimeout;
+ uint32 StartY;
+ uint32 EndY;
+ struct ClipData *pCurrentClip;
+ uint32 Mode7Mask;
+ uint32 Mode7PriorityMask;
+ uint8 OBJWidths[128];
+ uint8 OBJVisibleTiles[128];
+ struct {
+ uint8 RTOFlags;
+ int16 Tiles;
+ struct {
+ int8 Sprite;
+ uint8 Line;
+ } OBJ[32];
+ } OBJLines [SNES_HEIGHT_EXTENDED];
+
+ uint8 r212c;
+ uint8 r212d;
+ uint8 r2130;
+ uint8 r2131;
+ bool8 Pseudo;
+
+#ifdef GFX_MULTI_FORMAT
+ uint32 PixelFormat;
+ uint32 (*BuildPixel) (uint32 R, uint32 G, uint32 B);
+ uint32 (*BuildPixel2) (uint32 R, uint32 G, uint32 B);
+ void (*DecomposePixel) (uint32 Pixel, uint32 &R, uint32 &G, uint32 &B);
+#endif
+};
+
+struct SLineData {
+ struct {
+ uint16 VOffset;
+ uint16 HOffset;
+ } BG [4];
+};
+
+#define H_FLIP 0x4000
+#define V_FLIP 0x8000
+#define BLANK_TILE 2
+
+struct SBG
+{
+ uint32 TileSize;
+ uint32 BitShift;
+ uint32 TileShift;
+ uint32 TileAddress;
+ uint32 NameSelect;
+ uint32 SCBase;
+
+ uint32 StartPalette;
+ uint32 PaletteShift;
+ uint32 PaletteMask;
+
+ uint8 *Buffer;
+ uint8 *Buffered;
+ bool8 DirectColourMode;
+};
+
+struct SLineMatrixData
+{
+ short MatrixA;
+ short MatrixB;
+ short MatrixC;
+ short MatrixD;
+ short CentreX;
+ short CentreY;
+};
+
+extern uint32 odd_high [4][16];
+extern uint32 odd_low [4][16];
+extern uint32 even_high [4][16];
+extern uint32 even_low [4][16];
+extern SBG BG;
+extern uint16 DirectColourMaps [8][256];
+
+extern uint8 add32_32 [32][32];
+extern uint8 add32_32_half [32][32];
+extern uint8 sub32_32 [32][32];
+extern uint8 sub32_32_half [32][32];
+extern uint8 mul_brightness [16][32];
+
+// Could use BSWAP instruction on Intel port...
+#define SWAP_DWORD(dw) dw = ((dw & 0xff) << 24) | ((dw & 0xff00) << 8) | \
+ ((dw & 0xff0000) >> 8) | ((dw & 0xff000000) >> 24)
+
+#ifdef FAST_LSB_WORD_ACCESS
+#define READ_2BYTES(s) (*(uint16 *) (s))
+#define WRITE_2BYTES(s, d) *(uint16 *) (s) = (d)
+#else
+#ifdef LSB_FIRST
+#define READ_2BYTES(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8))
+#define WRITE_2BYTES(s, d) *(uint8 *) (s) = (d), \
+ *((uint8 *) (s) + 1) = (d) >> 8
+#else // else MSB_FISRT
+#define READ_2BYTES(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8))
+#define WRITE_2BYTES(s, d) *(uint8 *) (s) = (d), \
+ *((uint8 *) (s) + 1) = (d) >> 8
+#endif // LSB_FIRST
+#endif // i386
+
+#define SUB_SCREEN_DEPTH 0
+#define MAIN_SCREEN_DEPTH 32
+
+#if defined(OLD_COLOUR_BLENDING)
+#define COLOR_ADD(C1, C2) \
+GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
+ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
+ ((C1) & (C2) & RGB_LOW_BITS_MASK)]
+#else
+#define COLOR_ADD(C1, C2) \
+(GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
+ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
+ ((C1) & (C2) & RGB_LOW_BITS_MASK)] | \
+ (((C1) ^ (C2)) & RGB_LOW_BITS_MASK))
+#endif
+
+#define COLOR_ADD1_2(C1, C2) \
+(((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
+ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
+ ((C1) & (C2) & RGB_LOW_BITS_MASK) | ALPHA_BITS_MASK)
+
+#if defined(OLD_COLOUR_BLENDING)
+#define COLOR_SUB(C1, C2) \
+GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \
+ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
+#elif !defined(NEW_COLOUR_BLENDING)
+#define COLOR_SUB(C1, C2) \
+(GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \
+ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + \
+((C1) & RGB_LOW_BITS_MASK) - ((C2) & RGB_LOW_BITS_MASK))
+#else
+inline uint16 COLOR_SUB(uint16, uint16);
+
+inline uint16 COLOR_SUB(uint16 C1, uint16 C2)
+{
+ uint16 mC1, mC2, v = 0;
+
+ mC1 = C1 & FIRST_COLOR_MASK;
+ mC2 = C2 & FIRST_COLOR_MASK;
+ if (mC1 > mC2) v += (mC1 - mC2);
+
+ mC1 = C1 & SECOND_COLOR_MASK;
+ mC2 = C2 & SECOND_COLOR_MASK;
+ if (mC1 > mC2) v += (mC1 - mC2);
+
+ mC1 = C1 & THIRD_COLOR_MASK;
+ mC2 = C2 & THIRD_COLOR_MASK;
+ if (mC1 > mC2) v += (mC1 - mC2);
+
+ return v;
+}
+#endif
+
+#define COLOR_SUB1_2(C1, C2) \
+GFX.ZERO [(((C1) | RGB_HI_BITS_MASKx2) - \
+ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
+
+typedef void (*NormalTileRenderer) (uint32 Tile, uint32 Offset,
+ uint32 StartLine, uint32 LineCount);
+typedef void (*ClippedTileRenderer) (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
+typedef void (*LargePixelRenderer) (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount);
+
+START_EXTERN_C
+void S9xStartScreenRefresh ();
+void S9xDrawScanLine (uint8 Line);
+void S9xEndScreenRefresh ();
+void S9xSetupOBJ ();
+void S9xUpdateScreen ();
+void RenderLine (uint8 line);
+void S9xBuildDirectColourMaps ();
+
+// External port interface which must be implemented or initialised for each
+// port.
+extern struct SGFX GFX;
+
+bool8 S9xGraphicsInit ();
+void S9xGraphicsDeinit();
+bool8 S9xInitUpdate (void);
+bool8 S9xDeinitUpdate (int Width, int Height, bool8 sixteen_bit);
+void S9xSyncSpeed ();
+
+#ifdef GFX_MULTI_FORMAT
+bool8 S9xSetRenderPixelFormat (int format);
+#endif
+
+END_EXTERN_C
+
+#endif
+
diff --git a/source/globals.cpp b/source/globals.cpp
new file mode 100644
index 0000000..0103f7e
--- /dev/null
+++ b/source/globals.cpp
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "dsp1.h"
+#include "missing.h"
+#include "cpuexec.h"
+#include "debug.h"
+#include "apu.h"
+#include "dma.h"
+#include "fxemu.h"
+#include "gfx.h"
+#include "soundux.h"
+#include "cheats.h"
+#include "sa1.h"
+#include "netplay.h"
+#include "spc7110.h"
+
+START_EXTERN_C
+char String[513];
+
+struct Missing missing;
+
+struct SICPU ICPU;
+
+struct SCPUState CPU;
+
+struct SRegisters Registers;
+
+struct SAPU APU;
+
+struct SIAPU IAPU;
+
+struct SAPURegisters APURegisters;
+
+struct SSettings Settings;
+
+struct SDSP1 DSP1;
+
+struct SSA1Registers SA1Registers;
+
+struct SSA1 SA1;
+
+SSoundData SoundData;
+
+SnesModel M1SNES={1,3,2};
+SnesModel M2SNES={2,4,3};
+SnesModel* Model=&M1SNES;
+
+
+uint8 *SRAM = NULL;
+uint8 *ROM = NULL;
+uint8 *RegRAM = NULL;
+uint8 *C4RAM = NULL;
+
+long OpAddress = 0;
+
+CMemory Memory;
+
+struct SSNESGameFixes SNESGameFixes;
+
+uint8 A1 = 0, A2 = 0, A3 = 0, A4 = 0, W1 = 0, W2 = 0, W3 = 0, W4 = 0;
+uint8 Ans8 = 0;
+uint16 Ans16 = 0;
+uint32 Ans32 = 0;
+uint8 Work8 = 0;
+uint16 Work16 = 0;
+uint32 Work32 = 0;
+signed char Int8 = 0;
+short Int16 = 0;
+long Int32 = 0;
+unsigned char OpenBus = 0;
+
+
+END_EXTERN_C
+
+#ifndef ZSNES_FX
+struct FxInit_s SuperFX;
+#else
+START_EXTERN_C
+uint8 *SFXPlotTable = NULL;
+END_EXTERN_C
+#endif
+
+struct SPPU PPU;
+struct InternalPPU IPPU;
+
+struct SDMA DMA[8];
+
+uint8 *HDMAMemPointers [8];
+uint8 *HDMABasePointers [8];
+
+struct SBG BG;
+
+struct SGFX GFX;
+struct SLineData LineData[240];
+struct SLineMatrixData LineMatrixData [240];
+
+uint8 Mode7Depths [2];
+NormalTileRenderer DrawTilePtr = NULL;
+ClippedTileRenderer DrawClippedTilePtr = NULL;
+NormalTileRenderer DrawHiResTilePtr = NULL;
+ClippedTileRenderer DrawHiResClippedTilePtr = NULL;
+LargePixelRenderer DrawLargePixelPtr = NULL;
+
+uint32 odd_high[4][16];
+uint32 odd_low[4][16];
+uint32 even_high[4][16];
+uint32 even_low[4][16];
+
+#ifdef GFX_MULTI_FORMAT
+
+uint32 RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_RGB565;
+uint32 GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_RGB565;
+uint32 BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_RGB565;
+uint32 RED_HI_BIT_MASK = RED_HI_BIT_MASK_RGB565;
+uint32 GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_RGB565;
+uint32 BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_RGB565;
+uint32 MAX_RED = MAX_RED_RGB565;
+uint32 MAX_GREEN = MAX_GREEN_RGB565;
+uint32 MAX_BLUE = MAX_BLUE_RGB565;
+uint32 SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_RGB565;
+uint32 GREEN_HI_BIT = (MAX_GREEN_RGB565 + 1) >> 1;
+uint32 RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_RGB565 |
+ GREEN_LOW_BIT_MASK_RGB565 |
+ BLUE_LOW_BIT_MASK_RGB565);
+uint32 RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_RGB565 |
+ GREEN_HI_BIT_MASK_RGB565 |
+ BLUE_HI_BIT_MASK_RGB565);
+uint32 RGB_HI_BITS_MASKx2 = (RED_HI_BIT_MASK_RGB565 |
+ GREEN_HI_BIT_MASK_RGB565 |
+ BLUE_HI_BIT_MASK_RGB565) << 1;
+uint32 RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK;
+uint32 FIRST_COLOR_MASK = FIRST_COLOR_MASK_RGB565;
+uint32 SECOND_COLOR_MASK = SECOND_COLOR_MASK_RGB565;
+uint32 THIRD_COLOR_MASK = THIRD_COLOR_MASK_RGB565;
+uint32 ALPHA_BITS_MASK = ALPHA_BITS_MASK_RGB565;
+uint32 FIRST_THIRD_COLOR_MASK = 0;
+uint32 TWO_LOW_BITS_MASK = 0;
+uint32 HIGH_BITS_SHIFTED_TWO_MASK = 0;
+
+uint32 current_graphic_format = RGB565;
+#endif
+
+uint8 GetBank = 0;
+struct SCheatData Cheat;
+
+volatile SoundStatus so;
+
+int Echo [24000];
+int DummyEchoBuffer [SOUND_BUFFER_SIZE];
+int MixBuffer [SOUND_BUFFER_SIZE];
+int EchoBuffer [SOUND_BUFFER_SIZE];
+int FilterTaps [8];
+unsigned long Z = 0;
+int Loop [16];
+
+uint16 SignExtend [2] = {
+ 0x00, 0xff00
+};
+
+//modified per anomie Mode 5 findings
+int HDMA_ModeByteCounts [8] = {
+ 1, 2, 2, 4, 4, 4, 2, 4
+};
+
+uint8 BitShifts[8][4] =
+{
+ {2, 2, 2, 2}, // 0
+ {4, 4, 2, 0}, // 1
+ {4, 4, 0, 0}, // 2
+ {8, 4, 0, 0}, // 3
+ {8, 2, 0, 0}, // 4
+ {4, 2, 0, 0}, // 5
+ {4, 0, 0, 0}, // 6
+ {8, 0, 0, 0} // 7
+};
+uint8 TileShifts[8][4] =
+{
+ {4, 4, 4, 4}, // 0
+ {5, 5, 4, 0}, // 1
+ {5, 5, 0, 0}, // 2
+ {6, 5, 0, 0}, // 3
+ {6, 4, 0, 0}, // 4
+ {5, 4, 0, 0}, // 5
+ {5, 0, 0, 0}, // 6
+ {6, 0, 0, 0} // 7
+};
+uint8 PaletteShifts[8][4] =
+{
+ {2, 2, 2, 2}, // 0
+ {4, 4, 2, 0}, // 1
+ {4, 4, 0, 0}, // 2
+ {0, 4, 0, 0}, // 3
+ {0, 2, 0, 0}, // 4
+ {4, 2, 0, 0}, // 5
+ {4, 0, 0, 0}, // 6
+ {0, 0, 0, 0} // 7
+};
+uint8 PaletteMasks[8][4] =
+{
+ {7, 7, 7, 7}, // 0
+ {7, 7, 7, 0}, // 1
+ {7, 7, 0, 0}, // 2
+ {0, 7, 0, 0}, // 3
+ {0, 7, 0, 0}, // 4
+ {7, 7, 0, 0}, // 5
+ {7, 0, 0, 0}, // 6
+ {0, 0, 0, 0} // 7
+};
+uint8 Depths[8][4] =
+{
+ {TILE_2BIT, TILE_2BIT, TILE_2BIT, TILE_2BIT}, // 0
+ {TILE_4BIT, TILE_4BIT, TILE_2BIT, 0}, // 1
+ {TILE_4BIT, TILE_4BIT, 0, 0}, // 2
+ {TILE_8BIT, TILE_4BIT, 0, 0}, // 3
+ {TILE_8BIT, TILE_2BIT, 0, 0}, // 4
+ {TILE_4BIT, TILE_2BIT, 0, 0}, // 5
+ {TILE_4BIT, 0, 0, 0}, // 6
+ {0, 0, 0, 0} // 7
+};
+uint8 BGSizes [2] = {
+ 8, 16
+};
+uint16 DirectColourMaps [8][256];
+
+long FilterValues[4][2] =
+{
+ {0, 0},
+ {240, 0},
+ {488, -240},
+ {460, -208}
+};
+
+int NoiseFreq [32] = {
+ 0, 16, 21, 25, 31, 42, 50, 63, 84, 100, 125, 167, 200, 250, 333,
+ 400, 500, 667, 800, 1000, 1300, 1600, 2000, 2700, 3200, 4000,
+ 5300, 6400, 8000, 10700, 16000, 32000
+};
+
+uint32 HeadMask [4] = {
+#ifdef LSB_FIRST
+ 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000
+#else
+ 0xffffffff, 0x00ffffff, 0x0000ffff, 0x000000ff
+#endif
+};
+
+uint32 TailMask [5] = {
+#ifdef LSB_FIRST
+ 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
+#else
+ 0x00000000, 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff
+#endif
+};
+
+START_EXTERN_C
+uint8 APUROM [64] =
+{
+ 0xCD,0xEF,0xBD,0xE8,0x00,0xC6,0x1D,0xD0,0xFC,0x8F,0xAA,0xF4,0x8F,
+ 0xBB,0xF5,0x78,0xCC,0xF4,0xD0,0xFB,0x2F,0x19,0xEB,0xF4,0xD0,0xFC,
+ 0x7E,0xF4,0xD0,0x0B,0xE4,0xF5,0xCB,0xF4,0xD7,0x00,0xFC,0xD0,0xF3,
+ 0xAB,0x01,0x10,0xEF,0x7E,0xF4,0x10,0xEB,0xBA,0xF6,0xDA,0x00,0xBA,
+ 0xF4,0xC4,0xF4,0xDD,0x5D,0xD0,0xDB,0x1F,0x00,0x00,0xC0,0xFF
+};
+
+#ifdef NETPLAY_SUPPORT
+struct SNetPlay NetPlay;
+#endif
+
+// Raw SPC700 instruction cycle lengths
+int32 S9xAPUCycleLengths [256] =
+{
+ /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */
+ /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
+ /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
+ /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
+ /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
+ /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
+ /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
+ /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
+ /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
+ /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
+ /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
+ /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
+ /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
+ /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
+ /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3,
+ /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
+ /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
+};
+
+// Actual data used by CPU emulation, will be scaled by APUReset routine
+// to be relative to the 65c816 instruction lengths.
+int32 S9xAPUCycles [256] =
+{
+ /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */
+ /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
+ /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
+ /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
+ /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
+ /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
+ /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
+ /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
+ /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
+ /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
+ /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
+ /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
+ /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
+ /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
+ /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3,
+ /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
+ /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
+};
+
+END_EXTERN_C
+
diff --git a/source/hardware.txt b/source/hardware.txt
new file mode 100644
index 0000000..ec6f2e5
--- /dev/null
+++ b/source/hardware.txt
@@ -0,0 +1,502 @@
+This document gives a brief description of the known hardware features of the
+SNES giving you some idea what SNES emulation authors are up against.
+
+Quick Overview
+--------------
+
+o 65c816 CPU running at up to 3.58MHz.
+
+o SPC700 CPU core running at 2.48MHz with built-in custom sound digital
+ signal processor.
+
+o Two custom graphics processors used to produce displays of up to 512x478
+ pixels with up to 32768 colours, 128 sprites, scaling, rotation, and mosaic
+ effects, scrolling over a virtual screen, transparency, coloured lens and
+ window effects and raster effects.
+
+o 128k work RAM, 64k sound CPU RAM and 64k video RAM.
+
+Game packs can include:
+
+o Up to 6MBytes (or more) of ROM containing the game code, graphics and sound
+ data.
+
+o Additional, battery-backed RAM (S-RAM) used to save game positions.
+
+o 10.5/21MHz RISC CPU (Super FX) used to implement some 3D games and add
+ special effects to games.
+
+o A maths co-processor (DSP1) used by some games with lots of physics
+ calculations involved (Pilot Wings) or mainly as a protection device
+ (Mario Kart).
+
+o Other custom chips produced by some software companies to help speed up
+ games, fit more graphics into a given sized ROM or act as a protection
+ device.
+
+Users could buy:
+
+o A five player adapter, allowing up to five people to play at once on games
+ that supported it.
+
+o A 2-button mouse, originally supplied with a paint program.
+
+o A light-gun that looked like riffle; it used infra-red to provide wire-less
+ communication between the gun and the console unit. About 10 games
+ supported it.
+
+o A GameBoy adapter that allowed the owners to play GameBoy games on their
+ SNES, some in colour.
+
+o Copier units that plugged into the cartridge slot on the SNES and allowed
+ game pak ROMs to be downloaded into RAM on the copier and saved onto
+ disk. The game could then be played without the original ROM being present
+ - unless the game pack contained additional hardware, or the game ROM code
+ tried to detect the copier being present and deliberately crashed the game.
+
+More Detail
+-----------
+
+65c816
+------
+
+The 65c816 is an 8/16-bit CPU that is basically an enhanced 6502: it even
+has an emulation mode to make it behave almost exactly like a real 6502. No
+doubt Nintendo were hoping to provide a compatibility mode for old NES
+games, but failed.
+
+The CPU features a 24-bit address bus and 8-bit data bus allowing a 16Mb
+address space. It has an accumulator and two index registers, all can be
+switch to either 8 or 16-bit mode.
+
+The address space is broken up into 256 banks, each bank being 64k in size,
+although there are addressing modes to treat the entire address space as one
+continuous block. Bank 0 is special in that the stack, a few addressing
+modes and the interrupt and reset vectors all reside there. The stack
+pointer is 16-bits wide.
+
+The 6502 has an addressing mode called zero-page, where the 1-byte address
+specified in the instruction refers to a location in the first 256 bytes of
+memory, allowing for 2-byte instructions and increased execution speed. The
+65c816 extends this idea by allowing the 'zero-page' to be moved anywhere
+inside bank 0 by use of the 16-bit direct page register.
+
+There are other addressing modes available that use the bank specified in
+the data bank register, again to help reduce code size and speed up
+execution.
+
+Code normally executes in single bank at a time, the current bank number
+being specified by the 8-bit program bank register. There are instructions
+available to call subroutines in other banks or just jump to code in other
+banks.
+
+The 65c816 internally runs at 3.58MHz, but other SNES hardware can temporarily
+slow it down to 2.58MHz or even 1.56MHz when the CPU attempts read from them
+or write to them. In particular, there are a mixture of fast and slow ROMs
+inside game packs, slow ROMs can only be accessed at 2.58MHz.
+
+The 65c816 has direct access to 128k of work RAM plus any additional RAM that
+might be in the game pack. Video RAM and sound RAM cannot be accessed
+directly.
+
+SPC700
+------
+
+The SPC700 is an 8-bit CPU core, similar to a 6502, but with a different
+instruction set, some new addressing modes and multiple and divide
+instructions, together with a custom sound digital signal processor, all
+contained inside one module.
+
+The SPC700 and the 65c816 communicate via 4 bi-directional, 8-bit I/O ports.
+The SPC700 has its own 64k RAM used to store a program downloaded from 65c816
+and sound sample data.
+
+The CPU has a built-in, small, 64 byte ROM used as boot-strap code to
+download a more complex program and sample data from the game ROM via the
+65c816. The ROM can be switched off and replaced with 64 bytes of RAM once
+the boot-strap code has done its work.
+
+The sound DSP can only play compresses sound samples, compressed using a
+custom fixed-ratio compression algorithm that compresses 16 16-bit samples
+into 8 bytes plus a one byte header. The minimum unit of a sample is one
+block. The block header byte contains a shift and filter value (algorithm
+decompression information) plus a last block flag and a loop flag; the loop
+flag is only used if the last block flag is also set.
+
+There are 8 separate sound channels allowing up to 8 samples to be played
+simultaneously. Each sound channel has a left and right volume setting and
+frequency setting. A hardware volume envelope can be defined for each
+channel, and echo effects can be turned on and off individually for each
+channel. The combined echo waveform can be subjected to an 8-tap FIR
+digital filter. The wave output of a channel can be used to modulate the
+frequency of the next sound channel, in numerical order.
+
+The DSP also has a white noise source that can played on a sound channel
+instead of sample data. All 8 channels, and any echo sound data, are mixed
+together and subjected to a left and right master volume control.
+
+The DSP also provides 3 interval timers, the first two running at 8kHz and
+the last at 64kHz; games normally only use one of them to provide a constant
+music playback rate.
+
+Interrupts
+----------
+
+The 65c816 provides two external interrupt sources: IRQ, which can be masked,
+and NMI, which cannot.
+
+The IRQ line is connected to an output on one of the graphics chips, that,
+it turn can be programmed to generate an IRQ at the start of a scanline, at
+a particular position on a scanline or at a particular position of every
+scanline. The IRQ line also is connected to one of the pins on the ROM
+connector, so additional hardware inside the ROM game pak, such as the Super FX
+and SA-1 chips, can also generate interrupts.
+
+The NMI line is connected to another output of one of the graphics chips and
+it can be programmed to generate an interrupt when the vertical blank period
+starts.
+
+The SPC700 chip can also generate interrupts, but they are not used on the
+SNES and probably physically not connected.
+
+Joypad Reading
+--------------
+
+Data from the SNES joy-pads is sent serially between the pad and the console.
+Games can choose to read each bit in, one at a time or allow hardware inside
+one of the custom chips to automatically read the joy-pad values once every
+frame. The game can then read the values from registers.
+
+SNES joy-pads themselves have direction controls and 8 other buttons named
+A, B, X, Y, Left, Right, Start and Select.
+
+Colour Palette
+--------------
+
+The SNES has a 256 entry 15-bit colour palette, allowing for 256 colours on
+screen out of a total palette of 32768. However, games can and do change
+colour entries during a frame, this combined with hardware colour value
+addition and subtraction and an overall brightness setting, can easily boost
+the number of colours on screen to several thousand!
+
+Tiles
+-----
+
+All SNES graphics data is made up of tiles, a tile being an 8x8 block of
+pixels, with each pixel made up of 2, 4 or 8 bits, allowing for 4, 16 or 256
+colours per pixel.
+
+To complicate matters, the SNES hardware stores tile data in planar format,
+that is all the bit 1's of all the pixels of a tile are stored together,
+then all the bit 2's and so on. Its like a sequence of 1-bit deep 8x8 pixel
+blocks.
+
+When a tile is used as background data, a 3-bit palette start address is
+associated with each tile, allowing the programmer to choose a different
+block of colours for each tile from the larger SNES colour palette. Sprites
+can only use tiles of depth 4 (16 colours), but each sprite has a palette
+start address.
+
+Background Graphic Modes
+------------------------
+
+The SNES has eight background graphics modes, each mode varies the number of
+individual background layers available, the depth of each layer and what
+other features are available. Programmers can change the background mode
+during a frame.
+
+The two most commonly used modes are mode 1, which allows two 16-colour
+background layers and one 4-colour layer and mode 7, which allows one 256-
+colour layer, but the layer can be rotated, stretched, squashed, sheared and
+generally messed around with.
+
+Each background is made up 32x32 8x8 tiles. However, the number of tiles in
+each direction can be double as can the individual tile size. This allows for
+a virtual background size of 256x256 up to 1024x1024. Switching to 16x16 tile
+size actually just groups four 8x8 tiles together, there is no true 16x16 tile
+on the SNES.
+
+Backgrounds have a pre-defined priority order - when pixels from one
+background layer overlap on the screen pixels from another background layer,
+the pixels from the lower numbered background are displayed.
+
+Each tile can be flipped horizontally or vertically, has a 3-bit "palette
+number" and a priority bit. The priority bit is used to make all the pixels
+in the tile appear in front of pixels from another background layer or
+sprite that would otherwise normally appear in front of them. Colour 0 from
+each tile is special and means "transparent", allowing non-transparent
+pixels from background layers or sprites "underneath" to be visible.
+
+Normally only 256x224 or 256x239 pixels are visible on screen and backgrounds
+have a scroll setting that allows the screen to act as a window onto any
+portion of their virtual size.
+
+Two background modes are available that can display up to 512x478 pixels,
+but they're not used by many games because the flicker, caused by the
+interlace used display the image on a standard television, would give game
+players headaches.
+
+Sprites
+-------
+
+The SNES has 128 hardware sprites, each sprite can be made up of one or
+several 16-colour, 8x8 tiles. Each sprite is assigned a number which defines
+its pixel priority when two sprites overlap on screen, it also has a separate
+sprite-to-background priority value which defines whether the sprite should
+appear in front or behind of the various background layers. Each sprite also
+has a 3-bit palette number, horizontal and vertical flip flags, a start tile
+number and, of course, an X and Y position.
+
+There's no way to turn off a sprite - if you don't want it to be visible you
+have to place the sprite at off-screen position.
+
+The SNES hardware seems to impose limits on the number of sprites that can
+appear on each scanline; there are one or two games out there that rely on
+this 'feature' to hide sprites they don't want visible.
+
+Mosaic
+------
+
+The SNES has a hardware mosaic effect. The upper left-hand pixel from a block
+of pixels up to 16 pixels wide can be made to cover the area of the other
+15; the pixel appears up to 16 times its original size. The effect can only
+be used on the background layers, not sprites. All backgrounds share the
+same size setting but the effect can be turned on and off per background
+layer.
+
+Many ROMs combine the mosaic effect with a brightness fade to zoom out of one
+game screen then zoom on to the next.
+
+Offset Per Tile
+---------------
+
+Three of the background screen modes reduce the number of visible background
+layers by one, and use its screen data as per-tile background scroll data
+for the remaining visible layers.
+
+The background modes vary as to whether the vertical and horizontal scroll
+values can both be altered, or just one of them. Tetris Attack uses the
+effect to allow different parts of the screen to scroll vertically at
+different rates.
+
+The horizontal per-tile offset feature is very limited and only allows
+adjustment in steps of 8 pixels.
+
+Mode 7
+------
+
+Nintendo use this background screen mode to really show off the SNES compared
+to the Sega's Mega Drive.
+
+By specifying a centre of rotation and a 2 by 2 transformation matrix, the
+mode 7 screen can be rotated, scaled, stretched, squashed, etc. just by
+writing to a few PPU registers. By varying the values on each scanline, some
+very interesting effects can be produced, these include a perspective
+effect, shears, split-screen zooms, etc.
+
+Each pixel is 8-bit (256 colours per pixel) and the screen itself has a
+virtual screen size of 1024x1024.
+
+Mode 7 has another feature where the number of colours are reduced to 128
+and the spare bit is used to swap a pixel between background layer 0 and 1,
+thus altering the sprite to background priority. This allows some pixels to
+be appear in front of sprites and others appear behind.
+
+Colour Addition / Subtraction
+-----------------------------
+
+The pixels of background layers and sprites can be directed to one of two
+places, the main-screen or the sub-screen. The sub-screen is like a virtual
+screen that cannot normally be seen, but the SNES has hardware that can add
+or subtract the RGB colour palette values of each pixel on the sub-screen to
+or from RGB values of pixels on the main-screen. The effect is that
+background layers on the on the main-screen appear translucent, allowing the
+sub-screen partly to show through. Examples are cloud, mist and water effects.
+
+The effect can be turned on and off for each background layer on the
+main-screen. There's a master switch for sprites as well, but when turned
+on, only sprites with certain colour palette numbers actually have their
+pixel values added to or subtracted from.
+
+The SNES also has a separate fixed colour value; if colour addition or
+subtraction is enabled and there's nothing on the sub-screen, the fixed
+colour is added or subtracted instead. I've seen it used by games to darken
+an area of the screen then overlay a menu on top, to implement a
+fade-to-white effect and to tint an area of the screen a particular colour.
+
+Windows
+-------
+
+The SNES provides two "clip windows". Each window is just an area defined by
+a left and right position. A background layer or all sprites can be selected
+to appear only inside or outside the window.
+
+If both windows are enabled on the same background layer or for all sprites,
+the areas they define are combined using one of four logical combination
+modes: OR, AND, XOR and N-XOR.
+
+If the left and/or right values are altered on each scanline (normally using
+H-DMA), many different shaped windows can be created; I've seen circles,
+pentagons, wavy lines, doughnuts, G's, etc.
+
+There's also the colour window. Each window or both windows can be used to
+define the area of the colour window. When the colour window is enabled for
+the sub-screen, transparency effects occur only inside or outside the colour
+window. When the colour window is enabled for the main-screen, it acts like
+a master clip window, clipping all background layers and sprites and even
+the back-drop colour to the area either inside or outside the colour window;
+in the clipped areas, the sub-screen is displayed or just black.
+
+Direct Colour Mode
+------------------
+
+On the 256 colour background modes, the otherwise unused 3-bit per-tile
+colour palette number can be used in combination with the 8-bit tile pixel
+data to form an 11-bit colour value (2048 colours) without using the SNES
+colour palette registers.
+
+Mode 7 has the same feature, but since mode 7 uses a different tile layout
+with no 3-bit colour palette number, a fixed 256 colours are available
+instead, again without using the SNES colour palette registers.
+
+Interlace
+---------
+
+The SNES normally generates a non-interlaced picture. Interlace can turned
+on and the only thing that happens is that the screen appears to flicker
+slightly due to the way a television works. However, in the two hi-res.
+background screen modes, if interlace is turned on the vertical resolution
+doubles from 512x224 to 512x448 (or 512x478 if the expand vertical flag is
+also set).
+
+Not many games use the feature due to the flicker introduced by the
+interlace, so its use is normally limited to title screens. However, one
+game I know of, RPM Racing, uses the effect during the game.
+
+DMA
+---
+
+The SNES provides 8 DMA (direct-memory-access) channels, although only one can
+be active at once. Without any intervention of the 65c816 CPU, up to 64K of
+data can be transferred from RAM or ROM to any PPU (picture processing unit)
+register. Since V-RAM, colour palette and sprite position and display data can
+only be written to via PPU registers, DMA provides a very convenient method of
+transferring data faster than the CPU alone could provide. There are PPU
+registers to read or write to the 128k work RAM, so DMA could be used to copy
+data from ROM to RAM as well.
+
+There is also a DMA read mode, where data is transferred from PPU registers
+to RAM.
+
+There are various limitations on DMA - if multiple DMA channels are started
+at once, they execute in order, the numerically lowest one first, then the
+next highest and so on. The 65c816 is stopped while DMA takes place. Each
+DMA operation can only access one 64k bank at once. However, the biggest
+limitation is that DMA can only take place when the graphics chips aren't
+also performing graphics data DMA, i.e. DMA can only be used during the
+v-blank period or when the screen is forcible blanked.
+
+H-DMA
+-----
+
+H-DMA is like DMA in that data is transferred from ROM or RAM to PPU
+registers without the intervention of the CPU. However, instead of all the
+data being transferred in one block, a few bytes are transferred at a time,
+just before the start of the each scanline.
+
+H-DMA shares the same channels as normal DMA, so each channel can be set up
+for DMA or H-DMA, but since normal DMA only occurs during v-blank and H-DMA
+is disabled during this time, its actually easy to reuse a channel for both
+types of DMA.
+
+There are various H-DMA modes that define how many bytes should be
+transferred each scanline, whether the destination PPU register is 8-bit or
+16-bit, should new data be transferred each scanline, or can the same data
+be reused if a count value hasn't reached zero, etc.
+
+H-DMA gives a very powerful weapon to programmers, it allows PPU register
+values to be easily changed each scanline, so many games can and do use it
+to change screen colours, background scroll values, window shape values,
+mode 7 matrix values, transparency effects, etc. during the frame.
+
+Extra Chips Used by the SNES Inside Some Game Paks
+==================================================
+
+Super FX
+--------
+
+The Super FX is just a fast integer RISC-type processor but with a built-in
+plot instruction that can draw a single pixel in the SNES' planar format into
+a virtual screen very quickly, very handy for 3d polygon rendering. Its a
+strange chip though - no stack, a 512 byte cache and a one stage pipe-line
+that causes the instruction following a branch instruction to be executed.
+Instructions fetched from the cache often execute in a single cycle.
+
+Super FX games came with additional RAM inside the game pak that is used as
+work RAM for the 'FX chip and as save-game positions, if the ROM supports it.
+
+The 'FX chip has 16 16-bit registers and built-in fast integer multiply.
+Although the Super FX and the 65c816 can run in parallel, the 'FX chip can't
+access the game pack ROM or RAM at the same time as the main SNES CPU, so most
+games just get the SNES CPU to execute a wait loop in the SNES work RAM.
+
+The 'FX can't access the SNES custom hardware chips, so if the 'FX has
+rendered a screen image in its work RAM, it has to go to sleep while the SNES
+CPU copies the screen to video RAM, usually using DMA. The SNES CPU can pass
+parameters to 'FX routines either by writing them into the 'FX work RAM or
+writing directly into the 'FX registers, which it can be accessed by the CPU
+only when the 'FX chip is sleeping.
+
+There are two versions of the 'FX chip, the original 10MHz chip used in Star
+Fox and limited to 1Mb of ROM access and 64K RAM and a newer version used in
+Yoshi's Island, Doom, Vortex, Winter Gold, Star Fox 2, etc. which can be
+clocked at 21MHz and can access twice as much ROM and RAM.
+
+DSP1
+----
+
+The DSP1 is an early digital signal processor with an on-board ROM,
+manufactured by NEC. The on-board ROM was loaded with a program developed
+by Nintendo to turn the chip into a 3d maths co-processor, able to perform
+most primitive, but time-consuming, calculations required when manipulating
+objects in a 3d coordinate system relatively quickly, compared to the
+speed of the 65c816 CPU alone, that is.
+
+Most of the calculations supported seemed to be those required by a simple
+flight simulator, i.e. the calculations available were choosen with Pilot
+Wings in mind.
+
+The DSP1 has been used in several other games, may be as many as 20, though
+most ignore a lot of the available features. The games include Mario Kart, Top
+Gear 3000, Battle Racers, Super Air Diver and Bases Loaded 2.
+
+SA-1
+----
+
+The SA-1 is a fast, custom 65c816 8/16-bit processor, the same as inside the
+SNES itself, but clocked at 10MHz compared to a maximum of 3.58MHz for the CPU
+inside the SNES.
+
+The SA-1 isn't just a CPU, it also contains some extra circuits developed by
+Nintendo which includes some very fast RAM, a memory mapper, DMA, several
+real-time timers, and the region lock-out chip.
+
+The SNES (or ROM copiers) can only access the ROM inside the game pak via the
+SA-1; and the SA-1 only enables access to the ROM once its internal region
+lock-out chip has verified it has successfully communicated with a lock-out
+chip inside the SNES. This very effectively prevents SNES ROM copiers from
+being able to copy the ROM.
+
+The SA-1 is used in Mario RPG and seems to be used in several other games
+that Nintendo released in 1996 and beyond.
+
+S-DD1
+-----
+
+Very little is known about this chip. It seems to be another digital signal
+processor, possibly made by Texas Instruments, dedicated to decompressing
+graphics data. Only two games I know of use the chip, Street Fighter Alpha 2
+and Star Ocean.
+
+Like the SA-1, the SNES and ROM copiers can only access the ROM via the S-DD1,
+again preventing ROM copiers from dumping the ROM image.
diff --git a/source/language.h b/source/language.h
new file mode 100644
index 0000000..abcdcaf
--- /dev/null
+++ b/source/language.h
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+/* This is where all the GUI text strings will eventually end up */
+
+#define WINDOW_TITLE "Snes9X v%s for Windows"
+
+#define MY_REG_KEY "Software\\Emulators\\Snes9X"
+
+#define REG_KEY_VER "1.31"
+
+#define DISCLAIMER_TEXT "Snes9X v%s for Windows.\r\n" \
+ "(c) Copyright 1996 - 2002 Gary Henderson and Jerremy Koot.\r\n" \
+ "(c) Copyright 2001- 2004 John Weidman.\r\n" \
+ "(c) Copyright 2002 - 2004 blip, Brad Jorsch, funkyass, Joel Yliluoma, Kris Bleakley, Matthew Kendora, Nach, Peter Bortas, zones.\r\n\r\n" \
+ "Snes9X is a Super Nintendo Entertainment System\r\n" \
+ "emulator that allows you to play most games designed\r\n" \
+ "for the SNES on your PC.\r\n\r\n" \
+ "Please visit http://www.snes9x.com for\r\n" \
+ "up-to-the-minute information and help on Snes9X.\r\n\r\n" \
+ "Nintendo is a trade mark."
+
+
+#define APP_NAME "Snes9x"
+// possible global strings
+#define SNES9X_INFO "Snes9x: Information"
+#define SNES9X_WARN "Snes9x: WARNING!"
+#define SNES9X_DXS "Snes9X: DirectSound"
+#define SNES9X_SNDQ "Snes9X: Sound CPU Question"
+#define SNES9X_NP_ERROR "Snes9X: NetPlay Error"
+#define BUTTON_OK "&OK"
+#define BUTTON_CANCEL "&Cancel"
+
+// Gamepad Dialog Strings
+#define INPUTCONFIG_TITLE "Input Configuration"
+#define INPUTCONFIG_JPTOGGLE "Disabled"
+#define INPUTCONFIG_DIAGTOGGLE "Toggle Diagonals"
+//#define INPUTCONFIG_OK "&OK"
+//#define INPUTCONFIG_CANCEL "&Cancel"
+#define INPUTCONFIG_JPCOMBO "Joypad #%d"
+#define INPUTCONFIG_LABEL_UP "Up"
+#define INPUTCONFIG_LABEL_DOWN "Down"
+#define INPUTCONFIG_LABEL_LEFT "Left"
+#define INPUTCONFIG_LABEL_RIGHT "Right"
+#define INPUTCONFIG_LABEL_A "A"
+#define INPUTCONFIG_LABEL_B "B"
+#define INPUTCONFIG_LABEL_X "X"
+#define INPUTCONFIG_LABEL_Y "Y"
+#define INPUTCONFIG_LABEL_L "L"
+#define INPUTCONFIG_LABEL_R "R"
+#define INPUTCONFIG_LABEL_START "Start"
+#define INPUTCONFIG_LABEL_SELECT "Select"
+#define INPUTCONFIG_LABEL_UPLEFT "Up Left"
+#define INPUTCONFIG_LABEL_UPRIGHT "Up Right"
+#define INPUTCONFIG_LABEL_DOWNRIGHT "Down Right"
+#define INPUTCONFIG_LABEL_DOWNLEFT "Down Left"
+#define INPUTCONFIG_LABEL_BLUE "Blue means the current key/button is already mapped"
+
+//gaming buttons and axises
+#define GAMEDEVICE_JOYNUMPREFIX "(J%d)"
+#define GAMEDEVICE_JOYBUTPREFIX "#[%d]"
+#define GAMEDEVICE_XNEG "Left"
+#define GAMEDEVICE_XPOS "Right"
+#define GAMEDEVICE_YPOS "Up"
+#define GAMEDEVICE_YNEG "Down"
+#define GAMEDEVICE_POVLEFT "POV Left"
+#define GAMEDEVICE_POVRIGHT "POV Right"
+#define GAMEDEVICE_POVUP "POV Up"
+#define GAMEDEVICE_POVDOWN "POV Down"
+#define GAMEDEVICE_POVDNLEFT "POV Dn Left"
+#define GAMEDEVICE_POVDNRIGHT "POV Dn Right"
+#define GAMEDEVICE_POVUPLEFT "POV Up Left"
+#define GAMEDEVICE_POVUPRIGHT "POV Up Right"
+#define GAMEDEVICE_ZPOS "Z Up"
+#define GAMEDEVICE_ZNEG "Z Down"
+#define GAMEDEVICE_RPOS "R Up"
+#define GAMEDEVICE_RNEG "R Down"
+#define GAMEDEVICE_UPOS "U Up"
+#define GAMEDEVICE_UNEG "U Down"
+#define GAMEDEVICE_VPOS "V Up"
+#define GAMEDEVICE_VNEG "V Down"
+#define GAMEDEVICE_BUTTON "Button %d"
+
+//gaming general
+#define GAMEDEVICE_DISABLED "Disabled"
+
+//gaming keys
+#define GAMEDEVICE_KEY "#%d"
+#define GAMEDEVICE_NUMPADPREFIX "Numpad-%c"
+#define GAMEDEVICE_VK_TAB "Tab"
+#define GAMEDEVICE_VK_BACK "Backspace"
+#define GAMEDEVICE_VK_CLEAR "Delete"
+#define GAMEDEVICE_VK_RETURN "Enter"
+#define GAMEDEVICE_VK_LSHIFT "LShift"
+#define GAMEDEVICE_VK_RSHIFT "RShift"
+#define GAMEDEVICE_VK_LCONTROL "LCTRL"
+#define GAMEDEVICE_VK_RCONTROL "RCTRL"
+#define GAMEDEVICE_VK_LMENU "LAlt"
+#define GAMEDEVICE_VK_RMENU "RAlt"
+#define GAMEDEVICE_VK_PAUSE "Pause"
+#define GAMEDEVICE_VK_CAPITAL "Capslock"
+#define GAMEDEVICE_VK_ESCAPE "Disabled"
+#define GAMEDEVICE_VK_SPACE "Space"
+#define GAMEDEVICE_VK_PRIOR "PgUp"
+#define GAMEDEVICE_VK_NEXT "PgDn"
+#define GAMEDEVICE_VK_HOME "Home"
+#define GAMEDEVICE_VK_END "End"
+#define GAMEDEVICE_VK_LEFT "Left"
+#define GAMEDEVICE_VK_RIGHT "Right"
+#define GAMEDEVICE_VK_UP "Up"
+#define GAMEDEVICE_VK_DOWN "Down"
+#define GAMEDEVICE_VK_SELECT "Select"
+#define GAMEDEVICE_VK_PRINT "Print"
+#define GAMEDEVICE_VK_EXECUTE "Execute"
+#define GAMEDEVICE_VK_SNAPSHOT "SnapShot"
+#define GAMEDEVICE_VK_INSERT "Insert"
+#define GAMEDEVICE_VK_DELETE "Delete"
+#define GAMEDEVICE_VK_HELP "Help"
+#define GAMEDEVICE_VK_LWIN "LWinKey"
+#define GAMEDEVICE_VK_RWIN "RWinKey"
+#define GAMEDEVICE_VK_APPS "AppKey"
+#define GAMEDEVICE_VK_MULTIPLY "Numpad *"
+#define GAMEDEVICE_VK_ADD "Numpad +"
+#define GAMEDEVICE_VK_SEPARATOR "\\"
+#define GAMEDEVICE_VK_OEM_1 "Semi-Colon"
+#define GAMEDEVICE_VK_OEM_7 "Apostrophe"
+#define GAMEDEVICE_VK_OEM_COMMA "Comma"
+#define GAMEDEVICE_VK_OEM_PERIOD "Period"
+#define GAMEDEVICE_VK_SUBTRACT "Numpad -"
+#define GAMEDEVICE_VK_DECIMAL "Numpad ."
+#define GAMEDEVICE_VK_DIVIDE "Numpad /"
+#define GAMEDEVICE_VK_NUMLOCK "Num-lock"
+#define GAMEDEVICE_VK_SCROLL "Scroll-lock"
+
+//evil things I found in WinProc
+
+#define WINPROC_TURBOMODE_ON "Turbo Mode Activated"
+#define WINPROC_TURBOMODE_OFF "Turbo Mode Deactivated"
+#define WINPROC_TURBOMODE_TEXT "Turbo Mode"
+#define WINPROC_HDMA_TEXT "HDMA emulation"
+#define WINPROC_BG1 "BG#1" //Background Layers
+#define WINPROC_BG2 "BG#2"
+#define WINPROC_BG3 "BG#3"
+#define WINPROC_BG4 "BG#4"
+#define WINPROC_SPRITES "Sprites"
+#define WINPROC_PADSWAP "Joypad swapping"
+#define WINPROC_CONTROLERS0 "Multiplayer 5 on #0"
+#define WINPROC_CONTROLERS1 "Joypad on #0"
+#define WINPROC_CONTROLERS2 "Mouse on #1"
+#define WINPROC_CONTROLERS3 "Mouse on #0"
+#define WINPROC_CONTROLERS4 "Superscope on #1"
+#define WINPROC_CONTROLERS5 "Justifier 1 on #1"
+#define WINPROC_CONTROLERS6 "Justifier 2 on #1"
+#define WINPROC_BGHACK "Background layering hack"
+#define WINPROC_MODE7INTER "Mode 7 Interpolation"
+#define WINPROC_TRANSPARENCY "Transparency effects"
+#define WINPROC_CLIPWIN "Graphic clip windows"
+#define WINPROC_PAUSE "Pause"
+#define WINPROC_EMUFRAMETIME "Emulated frame time: %dms"
+#define WINPROC_AUTOSKIP "Auto Frame Skip"
+#define WINPROC_FRAMESKIP "Frame skip: %d"
+#define WINPROC_TURBO_R_ON "Turbo R Activated"
+#define WINPROC_TURBO_R_OFF "Turbo R Deactivated"
+#define WINPROC_TURBO_L_ON "Turbo L Activated"
+#define WINPROC_TURBO_L_OFF "Turbo L Deactivated"
+#define WINPROC_TURBO_X_ON "Turbo X Activated"
+#define WINPROC_TURBO_X_OFF "Turbo X Deactivated"
+#define WINPROC_TURBO_Y_ON "Turbo Y Activated"
+#define WINPROC_TURBO_Y_OFF "Turbo Y Deactivated"
+#define WINPROC_TURBO_A_ON "Turbo A Activated"
+#define WINPROC_TURBO_A_OFF "Turbo A Deactivated"
+#define WINPROC_TURBO_B_ON "Turbo B Activated"
+#define WINPROC_TURBO_B_OFF "Turbo B Deactivated"
+#define WINPROC_TURBO_SEL_ON "Turbo Select Activated"
+#define WINPROC_TURBO_SEL_OFF "Turbo Select Deactivated"
+#define WINPROC_TURBO_START_ON "Turbo Start Activated"
+#define WINPROC_TURBO_START_OFF "Turbo Start Deactivated"
+#define WINPROC_FILTER_RESTART "You will need to restart Snes9x before the output image\nprocessing option change will take effect."
+#define WINPROC_DISCONNECT "Disconnect from the NetPlay server first."
+#define WINPROC_NET_RESTART "Your game will be reset after the ROM has been sent due to\nyour 'Sync Using Reset Game' setting.\n\n"
+#define WINPROC_INTERPOLATED_SND "Interpolated sound"
+#define WINPROC_SYNC_SND "Sync sound"
+#define WINPROC_SND_OFF "Disabling the sound CPU emulation will help to improve\nemulation speed but you will not hear any sound effects\nor music. If you later want to re-enable the sound CPU\nemulation you will need to reset your game before it will\ntake effect.\n\nAre you sure this is what you want?"
+#define WINPROC_SND_RESTART "You will need to reset your game or load another one\nbefore enabling the sound CPU will take effect."
+
+//Emulator Settings
+
+#define EMUSET_TITLE "Emulation Settings"
+#define EMUSET_LABEL_FREEZE "Freeze Folder Directory"
+#define EMUSET_BROWSE "&Browse..."
+#define EMUSET_LABEL_ASRAM "Auto-Save S-RAM"
+#define EMUSET_LABEL_ASRAM_TEXT "seconds after last change (0 disables auto-save)"
+#define EMUSET_LABEL_SMAX "Skip at most"
+#define EMUSET_LABEL_SMAX_TEXT "frames in auto-frame rate mode"
+#define EMUSET_LABEL_STURBO "Skip Rendering"
+#define EMUSET_LABEL_STURBO_TEXT "frames in Turbo mode"
+#define EMUSET_TOGGLE_TURBO "Tab Toggles Turbo"
+
+//Netplay Options
+
+#define NPOPT_TITLE "Netplay Options"
+#define NPOPT_LABEL_PORTNUM "Socket Port Number"
+#define NPOPT_LABEL_PAUSEINTERVAL "Ask Server to Pause when"
+#define NPOPT_LABEL_PAUSEINTERVAL_TEXT "frames behind"
+#define NPOPT_LABEL_MAXSKIP "Maximum Frame Rate Skip"
+#define NPOPT_SYNCBYRESET "Sync By Reset"
+#define NPOPT_SENDROM "Send ROM Image to Client on Connect"
+#define NPOPT_ACTASSERVER "Act As Server"
+#define NPOPT_PORTNUMBLOCK "Port Settings"
+#define NPOPT_CLIENTSETTINGSBLOCK "Client Settings"
+#define NPOPT_SERVERSETTINGSBLOCK "Server Settings"
+
+//Netplay Connect
+
+
+#define NPCON_TITLE "Connect to Server"
+#define NPCON_LABEL_SERVERADDY "Server Address"
+#define NPCON_LABEL_PORTNUM "Port Number"
+#define NPCON_CLEARHISTORY "Clear History"
+
+
+//Movie Messages
+
+#define MOVIE_INFO_REPLAY "Movie replay"
+#define MOVIE_INFO_RECORD "Movie record"
+#define MOVIE_INFO_RERECORD "Movie re-record"
+#define MOVIE_INFO_REWIND "Movie rewind"
+#define MOVIE_INFO_STOP "Movie stop"
+#define MOVIE_INFO_END "Movie end"
+#define MOVIE_INFO_RECORDING_ENABLED "Recording enabled"
+#define MOVIE_INFO_RECORDING_DISABLED "Recording disabled"
+#define MOVIE_ERR_SNAPSHOT_WRONG_MOVIE "Snapshot not from this movie"
+#define MOVIE_ERR_SNAPSHOT_NOT_MOVIE "Not a movie snapshot"
+#define MOVIE_ERR_COULD_NOT_OPEN "Could not open movie file."
+#define MOVIE_ERR_NOT_FOUND "File not found."
+#define MOVIE_ERR_WRONG_FORMAT "File is wrong format."
+#define MOVIE_ERR_WRONG_VERSION "File is wrong version."
+
+
+// AVI Messages
+
+#define AVI_CONFIGURATION_CHANGED "AVI recording stopped (configuration settings changed)."
diff --git a/source/loadzip.cpp b/source/loadzip.cpp
new file mode 100644
index 0000000..4ee3bcb
--- /dev/null
+++ b/source/loadzip.cpp
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifdef UNZIP_SUPPORT
+/**********************************************************************************************/
+/* Loadzip.CPP */
+/* This file contains a function for loading a SNES ROM image from a zip file */
+/**********************************************************************************************/
+
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <ctype.h>
+
+#ifndef NO_INLINE_SET_GET
+#define NO_INLINE_SET_GET
+#endif
+
+#include "snes9x.h"
+#include "memmap.h"
+
+#include "unzip.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+bool8 LoadZip(const char* zipname,
+ int32 *TotalFileSize,
+ int32 *headers, uint8* buffer)
+{
+ *TotalFileSize = 0;
+ *headers = 0;
+
+ unzFile file = unzOpen(zipname);
+ if(file == NULL)
+ return (FALSE);
+
+ // find largest file in zip file (under MAX_ROM_SIZE)
+ // or a file with extension .1
+ char filename[132];
+ int filesize = 0;
+ int port = unzGoToFirstFile(file);
+ unz_file_info info;
+ while(port == UNZ_OK)
+ {
+ char name[132];
+ unzGetCurrentFileInfo(file, &info, name,128, NULL,0, NULL,0);
+
+ int calc_size = info.uncompressed_size / 0x2000;
+ calc_size *= 0x2000;
+ if(!(info.uncompressed_size - calc_size == 512 || info.uncompressed_size == calc_size))
+ {
+ port = unzGoToNextFile(file);
+ continue;
+ }
+
+ if(info.uncompressed_size > (CMemory::MAX_ROM_SIZE + 512))
+ {
+ port = unzGoToNextFile(file);
+ continue;
+ }
+
+ if ((int) info.uncompressed_size > filesize)
+ {
+ strcpy(filename,name);
+ filesize = info.uncompressed_size;
+ }
+ int len = strlen(name);
+ if(name[len-2] == '.' && name[len-1] == '1')
+ {
+ strcpy(filename,name);
+ filesize = info.uncompressed_size;
+ break;
+ }
+ port = unzGoToNextFile(file);
+ }
+ if( !(port == UNZ_END_OF_LIST_OF_FILE || port == UNZ_OK) || filesize == 0)
+ {
+// assert( unzClose(file) == UNZ_OK );
+ return (FALSE);
+ }
+
+ // Find extension
+ char tmp[2];
+ tmp[0] = tmp[1] = 0;
+ char *ext = strrchr(filename,'.');
+ if(ext) ext++;
+ else ext = tmp;
+
+ uint8 *ptr = buffer;
+ bool8 more = FALSE;
+
+ unzLocateFile(file,filename,1);
+ unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0);
+
+ if( unzOpenCurrentFile(file) != UNZ_OK )
+ {
+ unzClose(file);
+ return (FALSE);
+ }
+
+ do
+ {
+// assert(info.uncompressed_size <= CMemory::MAX_ROM_SIZE + 512);
+ int FileSize = info.uncompressed_size;
+
+ int calc_size = FileSize / 0x2000;
+ calc_size *= 0x2000;
+
+ int l = unzReadCurrentFile(file,ptr,FileSize);
+ if(unzCloseCurrentFile(file) == UNZ_CRCERROR)
+ {
+ unzClose(file);
+ return (FALSE);
+ }
+
+ if(l <= 0 || l != FileSize)
+ {
+ unzClose(file);
+ switch(l)
+ {
+ case UNZ_ERRNO:
+ break;
+ case UNZ_EOF:
+ break;
+ case UNZ_PARAMERROR:
+ break;
+ case UNZ_BADZIPFILE:
+ break;
+ case UNZ_INTERNALERROR:
+ break;
+ case UNZ_CRCERROR:
+ break;
+ }
+ return (FALSE);
+ }
+
+ if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) ||
+ Settings.ForceHeader)
+ {
+ memmove (ptr, ptr + 512, calc_size);
+ (*headers)++;
+ FileSize -= 512;
+ }
+ ptr += FileSize;
+ (*TotalFileSize) += FileSize;
+
+ int len;
+ if (ptr - Memory.ROM < CMemory::MAX_ROM_SIZE + 0x200 &&
+ (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9'))
+ {
+ more = TRUE;
+ ext [0]++;
+ }
+ else if (ptr - Memory.ROM < CMemory::MAX_ROM_SIZE + 0x200 &&
+ (((len = strlen (filename)) == 7 || len == 8) &&
+ strncasecmp (filename, "sf", 2) == 0 &&
+ isdigit (filename [2]) && isdigit (filename [3]) && isdigit (filename [4]) &&
+ isdigit (filename [5]) && isalpha (filename [len - 1])))
+ {
+ more = TRUE;
+ filename [len - 1]++;
+ }
+ else
+ more = FALSE;
+
+ if(more)
+ {
+ if( unzLocateFile(file,filename,1) != UNZ_OK ||
+ unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0) != UNZ_OK ||
+ unzOpenCurrentFile(file) != UNZ_OK)
+ break;
+ }
+
+ } while(more);
+
+ unzClose(file);
+ return (TRUE);
+}
+#endif
+
diff --git a/source/memmap.cpp b/source/memmap.cpp
new file mode 100644
index 0000000..65b8739
--- /dev/null
+++ b/source/memmap.cpp
@@ -0,0 +1,4397 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <ctype.h>
+
+#ifdef __linux
+#include <unistd.h>
+#endif
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "cpuexec.h"
+#include "ppu.h"
+#include "display.h"
+#include "cheats.h"
+#include "apu.h"
+#include "sa1.h"
+#include "dsp1.h"
+#include "srtc.h"
+#include "sdd1.h"
+#include "spc7110.h"
+#include "seta.h"
+
+#include "unzip/unzip.h"
+
+#ifdef __W32_HEAP
+#include <malloc.h>
+#endif
+
+#ifndef ZSNES_FX
+#include "fxemu.h"
+extern struct FxInit_s SuperFX;
+#else
+START_EXTERN_C
+extern uint8 *SFXPlotTable;
+END_EXTERN_C
+#endif
+
+#ifndef SET_UI_COLOR
+#define SET_UI_COLOR(r,g,b) ;
+#endif
+
+//you would think everyone would have these
+//since they're so useful.
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+static int retry_count=0;
+static uint8 bytes0x2000 [0x2000];
+int is_bsx(unsigned char *);
+int bs_name(unsigned char *);
+int check_char(unsigned);
+void S9xDeinterleaveType2 (bool8 reset=TRUE);
+inline uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32 = 0xFFFFFFFF);
+
+extern char *rom_filename;
+
+const uint32 crc32Table[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
+};
+
+
+
+void S9xDeinterleaveType1(int TotalFileSize, uint8 * base)
+{
+ if(Settings.DisplayColor==0xffff)
+ {
+ Settings.DisplayColor=BUILD_PIXEL(0,31,0);
+ SET_UI_COLOR(0,255,0);
+ }
+
+ int i;
+ int nblocks = TotalFileSize >> 16;
+ uint8 blocks [256];
+ for (i = 0; i < nblocks; i++)
+ {
+ blocks [i * 2] = i + nblocks;
+ blocks [i * 2 + 1] = i;
+ }
+ uint8 *tmp = (uint8 *) malloc (0x8000);
+ if (tmp)
+ {
+ for (i = 0; i < nblocks * 2; i++)
+ {
+ for (int j = i; j < nblocks * 2; j++)
+ {
+ if (blocks [j] == i)
+ {
+ memmove (tmp, &base [blocks [j] * 0x8000], 0x8000);
+ memmove (&base [blocks [j] * 0x8000],
+ &base [blocks [i] * 0x8000], 0x8000);
+ memmove (&base [blocks [i] * 0x8000], tmp, 0x8000);
+ uint8 b = blocks [j];
+ blocks [j] = blocks [i];
+ blocks [i] = b;
+ break;
+ }
+ }
+ }
+ free ((char *) tmp);
+ }
+}
+
+void S9xDeinterleaveGD24(int TotalFileSize, uint8 * base)
+{
+
+ if(TotalFileSize!=0x300000)
+ return;
+
+ if(Settings.DisplayColor==0xffff)
+ {
+ Settings.DisplayColor=BUILD_PIXEL(0,31,31);
+ SET_UI_COLOR(0,255,255);
+ }
+
+ uint8 *tmp = (uint8 *) malloc (0x80000);
+ if (tmp)
+ {
+ memmove(tmp, &base[0x180000], 0x80000);
+ memmove(&base[0x180000], &base[0x200000], 0x80000);
+ memmove(&base[0x200000], &base[0x280000], 0x80000);
+ memmove(&base[0x280000], tmp, 0x80000);
+ free ((char *) tmp);
+
+ S9xDeinterleaveType1(TotalFileSize, base);
+ }
+}
+
+bool8 CMemory::AllASCII (uint8 *b, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ if (b[i] < 32 || b[i] > 126)
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+int CMemory::ScoreHiROM (bool8 skip_header, int32 romoff)
+{
+ int score = 0;
+ int o = skip_header ? 0xff00 + 0x200 : 0xff00;
+
+ o+=romoff;
+
+ if(Memory.ROM [o + 0xd5] & 0x1)
+ score+=2;
+
+ //Mode23 is SA-1
+ if(Memory.ROM [o + 0xd5] == 0x23)
+ score-=2;
+
+ if(Memory.ROM [o+0xd4] == 0x20)
+ score +=2;
+
+ if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) +
+ Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff)
+ {
+ score += 2;
+ if(0!=(Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)))
+ score++;
+ }
+
+ if (Memory.ROM [o + 0xda] == 0x33)
+ score += 2;
+ if ((Memory.ROM [o + 0xd5] & 0xf) < 4)
+ score += 2;
+ if (!(Memory.ROM [o + 0xfd] & 0x80))
+ score -= 6;
+ if ((Memory.ROM [o + 0xfc]|(Memory.ROM [o + 0xfd]<<8))>0xFFB0)
+ score -= 2; //reduced after looking at a scan by Cowering
+ if (CalculatedSize > 1024 * 1024 * 3)
+ score += 4;
+ if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48)
+ score -= 1;
+ if (!AllASCII (&Memory.ROM [o + 0xb0], 6))
+ score -= 1;
+ if (!AllASCII (&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1))
+ score -= 1;
+
+ return (score);
+}
+
+int CMemory::ScoreLoROM (bool8 skip_header, int32 romoff)
+{
+ int score = 0;
+ int o = skip_header ? 0x7f00 + 0x200 : 0x7f00;
+
+ o+=romoff;
+
+ if(!(Memory.ROM [o + 0xd5] & 0x1))
+ score+=3;
+
+ //Mode23 is SA-1
+ if(Memory.ROM [o + 0xd5] == 0x23)
+ score+=2;
+
+ if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) +
+ Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff)
+ {
+ score += 2;
+ if(0!=(Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)))
+ score++;
+ }
+
+ if (Memory.ROM [o + 0xda] == 0x33)
+ score += 2;
+ if ((Memory.ROM [o + 0xd5] & 0xf) < 4)
+ score += 2;
+ if (CalculatedSize <= 1024 * 1024 * 16)
+ score += 2;
+ if (!(Memory.ROM [o + 0xfd] & 0x80))
+ score -= 6;
+ if ((Memory.ROM [o + 0xfc]|(Memory.ROM [o + 0xfd]<<8))>0xFFB0)
+ score -= 2;//reduced per Cowering suggestion
+ if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48)
+ score -= 1;
+ if (!AllASCII (&Memory.ROM [o + 0xb0], 6))
+ score -= 1;
+ if (!AllASCII (&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1))
+ score -= 1;
+
+ return (score);
+}
+
+char *CMemory::Safe (const char *s)
+{
+ static char *safe;
+ static int safe_len = 0;
+
+ if(s==NULL)
+ {
+ if(safe!=NULL)
+ {
+ free((char*)safe);
+ safe = NULL;
+ }
+ return NULL;
+ }
+ int len = strlen (s);
+ if (!safe || len + 1 > safe_len)
+ {
+ if (safe)
+ free ((char *) safe);
+ safe = (char *) malloc (safe_len = len + 1);
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ if (s [i] >= 32 && s [i] < 127)
+ safe [i] = s[i];
+ else
+ safe [i] = '?';
+ }
+ safe [len] = 0;
+ return (safe);
+}
+
+/**********************************************************************************************/
+/* Init() */
+/* This function allocates all the memory needed by the emulator */
+/**********************************************************************************************/
+bool8 CMemory::Init ()
+{
+ RAM = (uint8 *) malloc (0x20000);
+ SRAM = (uint8 *) malloc (0x20000);
+ VRAM = (uint8 *) malloc (0x10000);
+ ROM = (uint8 *) malloc (MAX_ROM_SIZE + 0x200 + 0x8000);
+ memset (RAM, 0, 0x20000);
+ memset (SRAM, 0, 0x20000);
+ memset (VRAM, 0, 0x10000);
+ memset (ROM, 0, MAX_ROM_SIZE + 0x200 + 0x8000);
+
+ BSRAM = (uint8 *) malloc (0x80000);
+ memset (BSRAM, 0, 0x80000);
+
+ FillRAM = NULL;
+
+ IPPU.TileCache [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES * 128);
+ IPPU.TileCache [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES * 128);
+ IPPU.TileCache [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES * 128);
+
+ IPPU.TileCached [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES);
+ IPPU.TileCached [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES);
+ IPPU.TileCached [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES);
+
+ if (!RAM || !SRAM || !VRAM || !ROM || !BSRAM ||
+ !IPPU.TileCache [TILE_2BIT] || !IPPU.TileCache [TILE_4BIT] ||
+ !IPPU.TileCache [TILE_8BIT] || !IPPU.TileCached [TILE_2BIT] ||
+ !IPPU.TileCached [TILE_4BIT] || !IPPU.TileCached [TILE_8BIT])
+ {
+ Deinit ();
+ return (FALSE);
+ }
+
+ // FillRAM uses first 32K of ROM image area, otherwise space just
+ // wasted. Might be read by the SuperFX code.
+
+ FillRAM = ROM;
+
+ // Add 0x8000 to ROM image pointer to stop SuperFX code accessing
+ // unallocated memory (can cause crash on some ports).
+ ROM += 0x8000;
+
+ C4RAM = ROM + 0x400000 + 8192 * 8;
+ ::ROM = ROM;
+ ::SRAM = SRAM;
+ ::RegRAM = FillRAM;
+
+#ifdef ZSNES_FX
+ SFXPlotTable = ROM + 0x400000;
+#else
+ SuperFX.pvRegisters = &Memory.FillRAM [0x3000];
+ SuperFX.nRamBanks = 2; // Most only use 1. 1=64KB, 2=128KB=1024Mb
+ SuperFX.pvRam = ::SRAM;
+ SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024);
+ SuperFX.pvRom = (uint8 *) ROM;
+#endif
+
+ ZeroMemory (IPPU.TileCache [TILE_2BIT], MAX_2BIT_TILES * 128);
+ ZeroMemory (IPPU.TileCache [TILE_4BIT], MAX_4BIT_TILES * 128);
+ ZeroMemory (IPPU.TileCache [TILE_8BIT], MAX_8BIT_TILES * 128);
+
+ ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES);
+ ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES);
+ ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES);
+
+ SDD1Data = NULL;
+ SDD1Index = NULL;
+
+ return (TRUE);
+}
+
+void CMemory::Deinit ()
+{
+#ifdef __W32_HEAP
+ if(_HEAPOK!=_heapchk())
+ MessageBox(GUI.hWnd, "CMemory::Deinit", "Heap Corrupt", MB_OK);
+#endif
+
+ if (RAM)
+ {
+ free ((char *) RAM);
+ RAM = NULL;
+ }
+ if (SRAM)
+ {
+ free ((char *) SRAM);
+ SRAM = NULL;
+ }
+ if (VRAM)
+ {
+ free ((char *) VRAM);
+ VRAM = NULL;
+ }
+ if (ROM)
+ {
+ ROM -= 0x8000;
+ free ((char *) ROM);
+ ROM = NULL;
+ }
+
+ if(BSRAM)
+ {
+ free((char*) BSRAM);
+ BSRAM=NULL;
+ }
+
+ if (IPPU.TileCache [TILE_2BIT])
+ {
+ free ((char *) IPPU.TileCache [TILE_2BIT]);
+ IPPU.TileCache [TILE_2BIT] = NULL;
+ }
+ if (IPPU.TileCache [TILE_4BIT])
+ {
+ free ((char *) IPPU.TileCache [TILE_4BIT]);
+ IPPU.TileCache [TILE_4BIT] = NULL;
+ }
+ if (IPPU.TileCache [TILE_8BIT])
+ {
+ free ((char *) IPPU.TileCache [TILE_8BIT]);
+ IPPU.TileCache [TILE_8BIT] = NULL;
+ }
+
+ if (IPPU.TileCached [TILE_2BIT])
+ {
+ free ((char *) IPPU.TileCached [TILE_2BIT]);
+ IPPU.TileCached [TILE_2BIT] = NULL;
+ }
+ if (IPPU.TileCached [TILE_4BIT])
+ {
+ free ((char *) IPPU.TileCached [TILE_4BIT]);
+ IPPU.TileCached [TILE_4BIT] = NULL;
+ }
+ if (IPPU.TileCached [TILE_8BIT])
+ {
+ free ((char *) IPPU.TileCached [TILE_8BIT]);
+ IPPU.TileCached [TILE_8BIT] = NULL;
+ }
+ FreeSDD1Data ();
+ Safe(NULL);
+}
+
+void CMemory::FreeSDD1Data ()
+{
+ if (SDD1Index)
+ {
+ free ((char *) SDD1Index);
+ SDD1Index = NULL;
+ }
+ if (SDD1Data)
+ {
+ free ((char *) SDD1Data);
+ SDD1Data = NULL;
+ }
+}
+
+/**********************************************************************************************/
+/* LoadROM() */
+/* This function loads a Snes-Backup image */
+/**********************************************************************************************/
+
+bool8 CMemory::LoadROM (const char *filename)
+{
+ int32 TotalFileSize = 0;
+ bool8 Interleaved = FALSE;
+ bool8 Tales = FALSE;
+
+ uint8* RomHeader=ROM;
+
+ ExtendedFormat=NOPE;
+
+
+ if(CleanUp7110!=NULL)
+ (*CleanUp7110)();
+
+ memset (&SNESGameFixes, 0, sizeof(SNESGameFixes));
+ SNESGameFixes.SRAMInitialValue = 0x60;
+
+ memset (bytes0x2000, 0, 0x2000);
+ CPU.TriedInterleavedMode2 = FALSE;
+
+ CalculatedSize = 0;
+ retry_count =0;
+
+again:
+ Settings.DisplayColor=0xffff;
+ SET_UI_COLOR(255,255,255);
+
+ TotalFileSize = FileLoader(ROM, filename, MAX_ROM_SIZE);
+
+ if (!TotalFileSize)
+ return FALSE; // it ends here
+ else if(!Settings.NoPatch)
+ CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize);
+
+ //fix hacked games here.
+ if((strncmp("HONKAKUHA IGO GOSEI", (char*)&ROM[0x7FC0],19)==0)&&(ROM[0x7FD5]!=0x31))
+ {
+ ROM[0x7FD5]=0x31;
+ ROM[0x7FD6]=0x02;
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ S9xMessage(S9X_ERROR,S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!");
+ }
+
+ if((strncmp("HONKAKUHA IGO GOSEI", (char*)&ROM[0xFFC0],19)==0)&&(ROM[0xFFD5]!=0x31))
+ {
+ ROM[0xFFD5]=0x31;
+ ROM[0xFFD6]=0x02;
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ S9xMessage(S9X_ERROR,S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!");
+ }
+
+ if((ROM[0x7FD5]==0x42)&&(ROM[0x7FD6]==0x13)&&(strncmp("METAL COMBAT",(char*)&ROM[0x7FC0],12)==0))
+ {
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ S9xMessage(S9X_ERROR,S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!");
+ }
+
+ int orig_hi_score, orig_lo_score;
+ int hi_score, lo_score;
+
+ orig_hi_score = hi_score = ScoreHiROM (FALSE);
+ orig_lo_score = lo_score = ScoreLoROM (FALSE);
+
+ if (HeaderCount == 0 && !Settings.ForceNoHeader &&
+ ((hi_score > lo_score && ScoreHiROM (TRUE) > hi_score) ||
+ (hi_score <= lo_score && ScoreLoROM (TRUE) > lo_score)))
+ {
+ memmove (Memory.ROM, Memory.ROM + 512, TotalFileSize - 512);
+ TotalFileSize -= 512;
+ S9xMessage (S9X_INFO, S9X_HEADER_WARNING,
+ "Try specifying the -nhd command line option if the game doesn't work\n");
+ //modifying ROM, so we need to rescore
+ orig_hi_score = hi_score = ScoreHiROM (FALSE);
+ orig_lo_score = lo_score = ScoreLoROM (FALSE);
+ }
+
+ CalculatedSize = (TotalFileSize / 0x2000) * 0x2000;
+ ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize);
+
+ if(CalculatedSize >0x400000&&
+ !(ROM[0x7FD5]==0x32&&((ROM[0x7FD6]&0xF0)==0x40)) && //exclude S-DD1
+ !(ROM[0xFFD5]==0x3A&&((ROM[0xFFD6]&0xF0)==0xF0))) //exclude SPC7110
+ {
+ //you might be a Jumbo!
+ ExtendedFormat=YEAH;
+ }
+
+ //If both vectors are invalid, it's type 1 LoROM
+
+ if(ExtendedFormat==NOPE&&((ROM[0x7FFC]|(ROM[0x7FFD]<<8))<0x8000)&&((ROM[0xFFFC]|(ROM[0xFFFD]<<8)) <0x8000))
+ {
+ if(Settings.DisplayColor==0xffff)
+ {
+ Settings.DisplayColor=BUILD_PIXEL(0,31,0);
+ SET_UI_COLOR(0,255,0);
+ }
+ if(!Settings.ForceInterleaved)
+ S9xDeinterleaveType1(TotalFileSize, ROM);
+ }
+
+ //CalculatedSize is now set, so rescore
+ orig_hi_score = hi_score = ScoreHiROM (FALSE);
+ orig_lo_score = lo_score = ScoreLoROM (FALSE);
+
+ if(NOPE!=ExtendedFormat)
+ {
+ int loromscore, hiromscore, swappedlorom, swappedhirom;
+ loromscore=ScoreLoROM(FALSE);
+ hiromscore=ScoreHiROM(FALSE);
+ swappedlorom=ScoreLoROM(FALSE, 0x400000);
+ swappedhirom=ScoreHiROM(FALSE, 0x400000);
+
+ //set swapped here.
+
+ if(max(swappedlorom, swappedhirom) >= max(loromscore, hiromscore))
+ {
+ ExtendedFormat = BIGFIRST;
+ hi_score=swappedhirom;
+ lo_score=swappedlorom;
+ RomHeader=ROM+0x400000;
+ }
+ else
+ {
+ ExtendedFormat = SMALLFIRST;
+ lo_score=loromscore;
+ hi_score=hiromscore;
+ RomHeader=ROM;
+ }
+
+
+ }
+
+ Interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2;
+ if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score))
+ {
+ LoROM = TRUE;
+ HiROM = FALSE;
+
+ // Ignore map type byte if not 0x2x or 0x3x
+ if ((RomHeader [0x7fd5] & 0xf0) == 0x20 || (RomHeader [0x7fd5] & 0xf0) == 0x30)
+ {
+ switch (RomHeader [0x7fd5] & 0xf)
+ {
+ case 1:
+ Interleaved = TRUE;
+ break;
+ case 5:
+ Interleaved = TRUE;
+ Tales = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if ((RomHeader [0xffd5] & 0xf0) == 0x20 || (RomHeader [0xffd5] & 0xf0) == 0x30)
+ {
+ switch (RomHeader [0xffd5] & 0xf)
+ {
+ case 0:
+ case 3:
+ Interleaved = TRUE;
+ break;
+ }
+ }
+ LoROM = FALSE;
+ HiROM = TRUE;
+ }
+
+ // More
+ if (!Settings.ForceHiROM && !Settings.ForceLoROM &&
+ !Settings.ForceInterleaved && !Settings.ForceInterleaved2 &&
+ !Settings.ForceNotInterleaved && !Settings.ForcePAL &&
+ !Settings.ForceSuperFX && !Settings.ForceDSP1 &&
+ !Settings.ForceSA1 && !Settings.ForceC4 &&
+ !Settings.ForceSDD1)
+ {
+
+
+#ifdef DETECT_NASTY_FX_INTERLEAVE
+//MK: Damn. YI trips a BRK currently. Maybe even on a real cart.
+
+#ifdef LSB_FIRST
+ if(strncmp((char *) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0&&(*(uint16*)&ROM[0x7FDE])==57611&&ROM[0x10002]==0xA9)
+#else
+ if(strncmp((char *) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0&&(ROM[0x7FDE]+(ROM[0x7FDF]<<8))==57611&&ROM[0x10002]==0xA9)
+#endif
+ {
+ Interleaved=true;
+ Settings.ForceInterleaved2=true;
+ }
+#endif
+ if (strncmp ((char *) &ROM [0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0)
+ {
+ LoROM = TRUE;
+ HiROM = FALSE;
+ Interleaved = FALSE;
+ }
+ }
+
+ if (!Settings.ForceNotInterleaved && Interleaved)
+ {
+ CPU.TriedInterleavedMode2 = TRUE;
+ S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO,
+ "ROM image is in interleaved format - converting...");
+
+ if (Tales)
+ {
+ if(Memory.ExtendedFormat==BIGFIRST)
+ {
+ S9xDeinterleaveType1(0x400000, ROM);
+ S9xDeinterleaveType1(CalculatedSize-0x400000, ROM+0x400000);
+ }
+ else
+ {
+ S9xDeinterleaveType1(CalculatedSize-0x400000, ROM);
+ S9xDeinterleaveType1(0x400000, ROM+CalculatedSize-0x400000);
+
+ }
+
+ LoROM = FALSE;
+ HiROM = TRUE;
+
+
+ }
+ else if (Settings.ForceInterleaved2)
+ {
+ S9xDeinterleaveType2(FALSE);
+ }
+ else if (Settings.ForceInterleaveGD24 && CalculatedSize ==0x300000)
+ {
+ bool8 t = LoROM;
+
+ LoROM = HiROM;
+ HiROM = t;
+ S9xDeinterleaveGD24(CalculatedSize, ROM);
+ }
+ else
+ {
+ if(Settings.DisplayColor==0xffff)
+ {
+ Settings.DisplayColor=BUILD_PIXEL(0,31,0);
+ SET_UI_COLOR(0,255,0);
+ }
+ bool8 t = LoROM;
+
+ LoROM = HiROM;
+ HiROM = t;
+
+ S9xDeinterleaveType1(CalculatedSize, ROM);
+ }
+
+ hi_score = ScoreHiROM (FALSE);
+ lo_score = ScoreLoROM (FALSE);
+
+ if ((HiROM &&
+ (lo_score >= hi_score || hi_score < 0)) ||
+ (LoROM &&
+ (hi_score > lo_score || lo_score < 0)))
+ {
+ if (retry_count == 0)
+ {
+ S9xMessage (S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO,
+ "ROM lied about its type! Trying again.");
+ Settings.ForceNotInterleaved = TRUE;
+ Settings.ForceInterleaved = FALSE;
+ retry_count++;
+ goto again;
+ }
+ }
+ }
+
+ if(ExtendedFormat==SMALLFIRST)
+ Tales=true;
+
+ FreeSDD1Data ();
+ InitROM (Tales);
+ S9xLoadCheatFile (S9xGetFilename(".cht"));
+ S9xInitCheatData ();
+ S9xApplyCheats ();
+
+ S9xReset ();
+
+ return (TRUE);
+}
+
+uint32 CMemory::FileLoader (uint8* buffer, const char* filename, int32 maxsize)
+{
+
+
+ FILE* ROMFile;
+ int32 TotalFileSize = 0;
+ int len = 0;
+ int nFormat=DEFAULT;
+
+ char dir [_MAX_DIR + 1];
+ char drive [_MAX_DRIVE + 1];
+ char name [_MAX_FNAME + 1];
+ char ext [_MAX_EXT + 1];
+ char fname [_MAX_PATH + 1];
+
+ unsigned long FileSize = 0;
+
+#ifdef UNZIP_SUPPORT
+ unzFile file=NULL;
+#endif
+
+ _splitpath (filename, drive, dir, name, ext);
+ _makepath (fname, drive, dir, name, ext);
+
+#ifdef __WIN32__
+ memmove (&ext [0], &ext[1], 4);
+#endif
+
+ if (strcasecmp (ext, "zip") == 0)
+ nFormat = ZIP;
+ else if (strcasecmp (ext, "rar") == 0)
+ nFormat = RAR;
+ else
+ nFormat = DEFAULT;
+
+
+ switch( nFormat )
+ {
+ case ZIP:
+
+#ifdef UNZIP_SUPPORT
+
+ file = unzOpen(fname);
+
+ if(file != NULL)
+ {
+
+ // its a valid ZIP, close it and let LoadZIP handle it.
+
+ unzClose(file);
+
+ if (!LoadZip (fname, &TotalFileSize, &HeaderCount, ROM))
+ return (0);
+
+ strcpy (ROMFilename, fname);
+
+ }
+ else
+ {
+ // its a bad zip file. Walk away
+
+ S9xMessage (S9X_ERROR, S9X_ROM_INFO, "Invalid Zip Archive.");
+ return (0);
+ }
+#endif
+ break;
+
+ case RAR:
+ // non existant rar loading
+ S9xMessage (S9X_ERROR, S9X_ROM_INFO, "Rar Archives are not currently supported.");
+ return (0);
+ break;
+
+ case DEFAULT:
+ default:
+ // any other roms go here
+ if ((ROMFile = fopen(fname, "rb")) == NULL)
+ return (0);
+
+ strcpy (ROMFilename, fname);
+
+ HeaderCount = 0;
+ uint8 *ptr = buffer;
+ bool8 more = FALSE;
+
+ do
+ {
+ FileSize = fread (ptr, 1, maxsize + 0x200 - (ptr - ROM), ROMFile);
+ fclose (ROMFile);
+
+ int calc_size = (FileSize / 0x2000) * 0x2000;
+
+ if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) ||
+ Settings.ForceHeader)
+ {
+ memmove (ptr, ptr + 512, calc_size);
+ HeaderCount++;
+ FileSize -= 512;
+ }
+
+ ptr += FileSize;
+ TotalFileSize += FileSize;
+
+
+ // check for multi file roms
+
+ if ((ptr - ROM) < (maxsize + 0x200) &&
+ (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9'))
+ {
+ more = TRUE;
+ ext [0]++;
+#ifdef __WIN32__
+ memmove (&ext [1], &ext [0], 4);
+ ext [0] = '.';
+#endif
+ _makepath (fname, drive, dir, name, ext);
+ }
+ else if (ptr - ROM < maxsize + 0x200 &&
+ (((len = strlen (name)) == 7 || len == 8) &&
+ strncasecmp (name, "sf", 2) == 0 &&
+ isdigit (name [2]) && isdigit (name [3]) && isdigit (name [4]) &&
+ isdigit (name [5]) && isalpha (name [len - 1])))
+ {
+ more = TRUE;
+ name [len - 1]++;
+#ifdef __WIN32__
+ memmove (&ext [1], &ext [0], 4);
+ ext [0] = '.';
+#endif
+ _makepath (fname, drive, dir, name, ext);
+ }
+ else
+ more = FALSE;
+
+ } while (more && (ROMFile = fopen (fname, "rb")) != NULL);
+
+ break;
+ }
+
+
+
+ if (HeaderCount == 0)
+ S9xMessage (S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found.");
+ else
+ {
+ if (HeaderCount == 1)
+ S9xMessage (S9X_INFO, S9X_HEADERS_INFO,
+ "Found ROM file header (and ignored it).");
+ else
+ S9xMessage (S9X_INFO, S9X_HEADERS_INFO,
+ "Found multiple ROM file headers (and ignored them).");
+ }
+
+ return TotalFileSize;
+
+}
+
+#if 0
+/**********************************************************************************************/
+/* LoadMulti() */
+/* This function loads a Slotted SNES-Backup image and fills the slot. */
+/**********************************************************************************************/
+
+bool8 CMemory::LoadMulti (const char *basename, const char *slot1name, const char *slot2name)
+{
+ unsigned long FileSize = 0;
+
+ if(*basename=='\0')
+ return FALSE;
+
+ SufamiTurbo=TRUE;
+
+ int32 offset;
+
+ memset (&SNESGameFixes, 0, sizeof(SNESGameFixes));
+ SNESGameFixes.SRAMInitialValue = 0x60;
+
+ memset (bytes0x2000, 0, 0x2000);
+
+ CalculatedSize = 0;
+
+ Settings.DisplayColor=0xffff;
+ SET_UI_COLOR(255,255,255);
+
+ int32 TotalFileSize = FileLoader(ROM, basename, MAX_ROM_SIZE);
+
+ if(0== TotalFileSize)
+ return FALSE;
+ else CheckForIPSPatch (basename, HeaderCount != 0, TotalFileSize);
+
+ CalculatedSize=TotalFileSize;
+
+ for(offset=0; offset<TotalFileSize; offset+=0x100000);
+
+ //insert base type test here.
+
+ if(slot1name[0]!='\0')
+ {
+
+ TotalFileSize = FileLoader(ROM+offset, slot1name, MAX_ROM_SIZE);
+
+ if(0== TotalFileSize)
+ return FALSE;
+ else CheckForIPSPatch (slot1name, HeaderCount != 0, TotalFileSize);
+ ROMOffset1=&ROM[offset];
+ Slot1Size=TotalFileSize;
+ }
+ int32 temp=offset;
+ for(; offset<temp+TotalFileSize; offset+=0x100000);
+
+ if(slot2name[0]!='\0')
+ {
+ TotalFileSize = FileLoader(ROM+offset, slot2name, MAX_ROM_SIZE);
+
+ if(0== TotalFileSize)
+ return FALSE;
+ else CheckForIPSPatch (slot2name, HeaderCount != 0, TotalFileSize);
+ ROMOffset2=&ROM[offset];
+ Slot2Size=TotalFileSize;
+ }
+
+ InitROM (FALSE);
+ S9xLoadCheatFile (S9xGetFilename(".cht"));
+ S9xInitCheatData ();
+ S9xApplyCheats ();
+
+ S9xReset ();
+
+ return (TRUE);
+}
+
+bool8 SufamiTurboBIOSSig(uint8* file, int32 size)
+{
+ if(!strcmp((char*)file, "BANDAI SFC-ADX")&&!strcmp((char*)(file+0x10), "SFC-ADX BACKUP"))
+ {
+ //possible match.
+ //check size
+ if(size!=0x40000)
+ return FALSE;
+ //and CRC32
+ if(0x9B4CA911==caCRC32(file, size))
+ {
+ return TRUE;
+ }
+
+ }
+ return FALSE;
+}
+
+bool8 SufamiTurboCartSig(uint8* file, int32 size)
+{
+ //test not a BIOS
+ if(!strcmp((char*)file, "BANDAI SFC-ADX")&&strcmp((char*)(file+0x10), "SFC-ADX BACKUP"))
+ {
+ //possible match.
+ //check size
+ if(size>0x100000||size <0x80000)
+ return FALSE;
+ //probably a minicart
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 SameGameSig(uint8* file, int32 size)
+{
+ //preheader sig
+ if(strcmp((char*)(file+0xFFA0),"1995/12/16 10:2018ZS5J"))
+ return FALSE;
+ if(size!=0x100000)
+ return FALSE;
+ if(0x133E1C5B==caCRC32(file, size))
+ return TRUE;
+ return FALSE;
+}
+bool8 GNextSig(uint8* file, int32 size)
+{
+ //preheader sig
+ if(strcmp((char*)(file+0xFFAA),"GNEXT B2ZX3J"))
+ return FALSE;
+ if(size!=0x180000)
+ return FALSE;
+ if(0x845E420D==caCRC32(file, size))
+ return TRUE;
+ return FALSE;
+}
+int MultiType(uint8* file, int32 size)
+{
+ //check for ST signiture
+ if(SufamiTurboBIOSSig(file, size))
+ return 1;
+ //check for Same Game signiture
+ if(SameGameSig(file, size))
+ return 2;
+ //check for G-Next signiture
+ if(GNextSig(file, size))
+ return 3;
+ return 0;
+}
+
+#endif
+
+//compatibility wrapper
+void S9xDeinterleaveMode2 ()
+{
+ S9xDeinterleaveType2();
+}
+
+void S9xDeinterleaveType2 (bool8 reset)
+{
+ if(Settings.DisplayColor==0xffff||Settings.DisplayColor==BUILD_PIXEL(0,31,0))
+ {
+ Settings.DisplayColor=BUILD_PIXEL(31,14,6);
+ SET_UI_COLOR(255,119,25);
+
+ }
+ S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO,
+ "ROM image is in interleaved format - converting...");
+
+ int nblocks = Memory.CalculatedSize >> 16;
+ int step = 64;
+
+ while (nblocks <= step)
+ step >>= 1;
+
+ nblocks = step;
+ uint8 blocks [256];
+ int i;
+
+ for (i = 0; i < nblocks * 2; i++)
+ {
+ blocks [i] = (i & ~0xF) | ((i & 3) << 2) |
+ ((i & 12) >> 2);
+ }
+
+ uint8 *tmp = (uint8 *) malloc (0x10000);
+
+ if (tmp)
+ {
+ for (i = 0; i < nblocks * 2; i++)
+ {
+ for (int j = i; j < nblocks * 2; j++)
+ {
+ if (blocks [j] == i)
+ {
+ memmove (tmp, &Memory.ROM [blocks [j] * 0x10000], 0x10000);
+ memmove (&Memory.ROM [blocks [j] * 0x10000],
+ &Memory.ROM [blocks [i] * 0x10000], 0x10000);
+ memmove (&Memory.ROM [blocks [i] * 0x10000], tmp, 0x10000);
+ uint8 b = blocks [j];
+ blocks [j] = blocks [i];
+ blocks [i] = b;
+ break;
+ }
+ }
+ }
+ free ((char *) tmp);
+ tmp=NULL;
+ }
+ if(reset)
+ {
+ Memory.InitROM (FALSE);
+ S9xReset ();
+ }
+}
+
+//CRC32 for char arrays
+inline uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32)
+{
+ for (register uint32 i = 0; i < size; i++)
+ {
+ crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF];
+ }
+ return ~crc32;
+}
+
+void CMemory::InitROM (bool8 Interleaved)
+{
+#ifndef ZSNES_FX
+ SuperFX.nRomBanks = CalculatedSize >> 15;
+#endif
+ Settings.MultiPlayer5Master = Settings.MultiPlayer5;
+ Settings.MouseMaster = Settings.Mouse;
+ Settings.SuperScopeMaster = Settings.SuperScope;
+ Settings.DSP1Master = Settings.ForceDSP1;
+ Settings.SuperFX = FALSE;
+ Settings.SA1 = FALSE;
+ Settings.C4 = FALSE;
+ Settings.SDD1 = FALSE;
+ Settings.SRTC = FALSE;
+ Settings.SPC7110=FALSE;
+ Settings.SPC7110RTC=FALSE;
+ Settings.BS=FALSE;
+ Settings.OBC1=FALSE;
+ Settings.SETA=FALSE;
+ s7r.DataRomSize = 0;
+ CalculatedChecksum=0;
+ uint8* RomHeader;
+
+ RomHeader=ROM+0x7FB0;
+
+ if(ExtendedFormat==BIGFIRST)
+ RomHeader+=0x400000;
+
+ if(HiROM)
+ RomHeader+=0x8000;
+
+ if(!Settings.BS)
+ {
+ Settings.BS=(-1!=is_bsx(ROM+0x7FC0));
+
+ if(Settings.BS)
+ {
+ Memory.LoROM=TRUE;
+ Memory.HiROM=FALSE;
+ }
+
+ else
+ {
+ Settings.BS=(-1!=is_bsx(ROM+0xFFC0));
+ if(Settings.BS)
+ {
+ Memory.HiROM=TRUE;
+ Memory.LoROM=FALSE;
+ }
+ }
+ }
+
+ ZeroMemory (BlockIsRAM, MEMMAP_NUM_BLOCKS);
+ ZeroMemory (BlockIsROM, MEMMAP_NUM_BLOCKS);
+
+ ::SRAM = SRAM;
+ memset (ROMId, 0, 5);
+ memset (CompanyId, 0, 3);
+
+ ParseSNESHeader(RomHeader);
+
+ // Try to auto-detect the DSP1 chip
+ if (!Settings.ForceNoDSP1 &&
+ (ROMType & 0xf) >= 3 && (ROMType & 0xf0) == 0)
+ Settings.DSP1Master = TRUE;
+
+ if (Memory.HiROM)
+ {
+ // Enable S-RTC (Real Time Clock) emulation for Dai Kaijyu Monogatari 2
+ Settings.SRTC = ((ROMType & 0xf0) >> 4) == 5;
+
+ if(((ROMSpeed&0x0F)==0x0A)&&((ROMType&0xF0)==0xF0))
+ {
+ Settings.SPC7110=true;
+ if((ROMType&0x0F)==0x09)
+ Settings.SPC7110RTC=true;
+ }
+
+ if (Settings.BS)
+ BSHiROMMap ();
+ else if(Settings.SPC7110)
+ {
+ SPC7110HiROMMap();
+ }
+ else if ((ROMSpeed & ~0x10) == 0x25)
+ {
+ TalesROMMap (Interleaved);
+ }
+ else HiROMMap ();
+ }
+ else
+ {
+ Settings.SuperFX = Settings.ForceSuperFX;
+
+ if(ROMType==0x25)
+ {
+ Settings.OBC1=TRUE;
+ }
+
+ //BS-X BIOS
+ if(ROMType==0xE5)
+ {
+ Settings.BS=TRUE;
+ }
+
+ if ((ROMType & 0xf0) == 0x10)
+ Settings.SuperFX = !Settings.ForceNoSuperFX;
+
+ Settings.SDD1 = Settings.ForceSDD1;
+ if ((ROMType & 0xf0) == 0x40)
+ Settings.SDD1 = !Settings.ForceNoSDD1;
+
+ if (Settings.SDD1)
+ S9xLoadSDD1Data ();
+
+ if(((ROMType &0xF0) == 0xF0)&((ROMSpeed&0x0F)!=5))
+ {
+ SRAMSize=2;
+ SNESGameFixes.SRAMInitialValue = 0x00;
+ if((ROMType &0x0F)==6)
+ {
+ if(ROM[0x7FD7]==0x09)
+ {
+ Settings.SETA=ST_011;
+ SetSETA=&S9xSetST011;
+ GetSETA=&S9xGetST011;
+ }
+ else
+ {
+ Settings.SETA=ST_010;
+ SetSETA=&S9xSetST010;
+ GetSETA=&S9xGetST010;
+ }
+ }
+ else
+ {
+ Settings.SETA=ST_018;
+ SRAMSize=2;
+ }
+ }
+ Settings.C4 = Settings.ForceC4;
+ if ((ROMType & 0xf0) == 0xf0 &&
+ (strncmp (ROMName, "MEGAMAN X", 9) == 0 ||
+ strncmp (ROMName, "ROCKMAN X", 9) == 0))
+ {
+ Settings.C4 = !Settings.ForceNoC4;
+ }
+
+ if(Settings.SETA&&Settings.SETA!=ST_018)
+ {
+ SetaDSPMap();
+ }
+ else if (Settings.SuperFX)
+ {
+ //::SRAM = ROM + 1024 * 1024 * 4;
+ SuperFXROMMap ();
+ Settings.MultiPlayer5Master = FALSE;
+ //Settings.MouseMaster = FALSE;
+ //Settings.SuperScopeMaster = FALSE;
+ Settings.DSP1Master = FALSE;
+ Settings.SA1 = FALSE;
+ Settings.C4 = FALSE;
+ Settings.SDD1 = FALSE;
+ }
+ else if (Settings.ForceSA1 ||
+ (!Settings.ForceNoSA1 && (ROMSpeed & ~0x10) == 0x23 &&
+ (ROMType & 0xf) > 3 && (ROMType & 0xf0) == 0x30))
+ {
+ Settings.SA1 = TRUE;
+// Settings.MultiPlayer5Master = FALSE;
+ //Settings.MouseMaster = FALSE;
+ //Settings.SuperScopeMaster = FALSE;
+ Settings.DSP1Master = FALSE;
+ Settings.C4 = FALSE;
+ Settings.SDD1 = FALSE;
+ SA1ROMMap ();
+ }
+ else if ((ROMSpeed & ~0x10) == 0x25)
+ TalesROMMap (Interleaved);
+ else if(ExtendedFormat!=NOPE)
+ JumboLoROMMap(Interleaved);
+ else if (strncmp ((char *) &Memory.ROM [0x7fc0], "SOUND NOVEL-TCOOL", 17) == 0 ||
+ strncmp ((char *) &Memory.ROM [0x7fc0], "DERBY STALLION 96", 17) == 0)
+ {
+ LoROM24MBSMap ();
+ Settings.DSP1Master = FALSE;
+ }
+
+ else if (strncmp ((char *) &Memory.ROM [0x7fc0], "THOROUGHBRED BREEDER3", 21) == 0 ||
+ strncmp ((char *) &Memory.ROM [0x7fc0], "RPG-TCOOL 2", 11) == 0)
+ {
+ SRAM512KLoROMMap ();
+ Settings.DSP1Master = FALSE;
+ }
+ else if (strncmp ((char *) &Memory.ROM [0x7fc0], "ADD-ON BASE CASSETE", 19) == 0)
+ {
+ Settings.MultiPlayer5Master = FALSE;
+ Settings.MouseMaster = FALSE;
+ Settings.SuperScopeMaster = FALSE;
+ Settings.DSP1Master = FALSE;
+ SufamiTurboLoROMMap();
+ Memory.SRAMSize = 3;
+ }
+ else if ((ROMSpeed & ~0x10) == 0x22 &&
+ strncmp (ROMName, "Super Street Fighter", 20) != 0)
+ {
+ AlphaROMMap ();
+ }
+ else if (Settings.BS)
+ BSLoROMMap();
+ else LoROMMap ();
+ }
+
+ if(Settings.BS)
+ {
+ ROMRegion=0;
+ }
+
+ uint32 sum1 = 0;
+ uint32 sum2 = 0;
+ if(0==CalculatedChecksum)
+ {
+ int power2 = 0;
+ int size = CalculatedSize;
+
+ while (size >>= 1)
+ power2++;
+
+ size = 1 << power2;
+ uint32 remainder = CalculatedSize - size;
+
+
+ int i;
+
+ for (i = 0; i < size; i++)
+ sum1 += ROM [i];
+
+ for (i = 0; i < (int) remainder; i++)
+ sum2 += ROM [size + i];
+
+ int sub = 0;
+ if (Settings.BS&& ROMType!=0xE5)
+ {
+ if (Memory.HiROM)
+ {
+ for (i = 0; i < 48; i++)
+ sub += ROM[0xffb0 + i];
+ }
+ else if (Memory.LoROM)
+ {
+ for (i = 0; i < 48; i++)
+ sub += ROM[0x7fb0 + i];
+ }
+ sum1 -= sub;
+ }
+
+
+ if (remainder)
+ {
+ sum1 += sum2 * (size / remainder);
+ }
+
+
+ sum1 &= 0xffff;
+ Memory.CalculatedChecksum=sum1;
+ }
+ //now take a CRC32
+ ROMCRC32 = caCRC32(ROM, CalculatedSize);
+
+ if (Settings.ForceNTSC)
+ Settings.PAL = FALSE;
+ else if (Settings.ForcePAL)
+ Settings.PAL = TRUE;
+ else
+ {
+ //Korea refers to South Korea, which uses NTSC
+ switch(ROMRegion)
+ {
+ case 13:
+ case 1:
+ case 0:
+ Settings.PAL=FALSE;
+ break;
+ default: Settings.PAL=TRUE;
+ break;
+ }
+ }
+ if (Settings.PAL)
+ {
+ Settings.FrameTime = Settings.FrameTimePAL;
+ Memory.ROMFramesPerSecond = 50;
+ }
+ else
+ {
+ Settings.FrameTime = Settings.FrameTimeNTSC;
+ Memory.ROMFramesPerSecond = 60;
+ }
+
+ ROMName[ROM_NAME_LEN - 1] = 0;
+ if (strlen (ROMName))
+ {
+ char *p = ROMName + strlen (ROMName) - 1;
+
+ while (p > ROMName && *(p - 1) == ' ')
+ p--;
+ *p = 0;
+ }
+
+ {
+ SRAMMask = Memory.SRAMSize ?
+ ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0;
+ }
+ if((ROMChecksum + ROMComplementChecksum != 0xffff) || ROMChecksum != CalculatedChecksum || ((uint32)CalculatedSize > (uint32)(((1<<(ROMSize-7))*128)*1024)))
+ {
+ if(Settings.DisplayColor==0xffff || Settings.DisplayColor!=BUILD_PIXEL(31,0,0))
+ {
+ Settings.DisplayColor=BUILD_PIXEL(31,31,0);
+ SET_UI_COLOR(255,255,0);
+ }
+ }
+
+ IAPU.OneCycle = ONE_APU_CYCLE;
+ Settings.Shutdown = Settings.ShutdownMaster;
+
+ SetDSP=&DSP1SetByte;
+ GetDSP=&DSP1GetByte;
+
+ ResetSpeedMap();
+ ApplyROMFixes ();
+ sprintf (ROMName, "%s", Safe (ROMName));
+ sprintf (ROMId, "%s", Safe (ROMId));
+ sprintf (CompanyId, "%s", Safe (CompanyId));
+
+ sprintf (String, "\"%s\" [%s] %s, %s, Type: %s, Mode: %s, TV: %s, S-RAM: %s, ROMId: %s Company: %2.2s CRC32: %08X",
+ ROMName,
+ (ROMChecksum + ROMComplementChecksum != 0xffff ||
+ ROMChecksum != CalculatedChecksum) ? "bad checksum" : "checksum ok",
+ MapType (),
+ Size (),
+ KartContents (),
+ MapMode (),
+ TVStandard (),
+ StaticRAMSize (),
+ ROMId,
+ CompanyId,
+ ROMCRC32);
+
+ S9xMessage (S9X_INFO, S9X_ROM_INFO, String);
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_ROM_INFO, MF_ENABLED);
+ #endif
+ #ifdef RTC_DEBUGGER
+ if(Settings.SPC7110RTC)
+ EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_ENABLED);
+ else EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_GRAYED);
+ #endif
+#endif
+ Settings.ForceHeader = Settings.ForceHiROM = Settings.ForceLoROM =
+ Settings.ForceInterleaved = Settings.ForceNoHeader = Settings.ForceNotInterleaved =
+ Settings.ForceInterleaved2=false;
+}
+
+bool8 CMemory::LoadSRAM (const char *filename)
+{
+ int size = Memory.SRAMSize ?
+ (1 << (Memory.SRAMSize + 3)) * 128 : 0;
+
+ memset (SRAM, SNESGameFixes.SRAMInitialValue, 0x20000);
+
+ if (size > 0x20000)
+ size = 0x20000;
+
+ if (size)
+ {
+ FILE *file;
+ if ((file = fopen (filename, "rb")))
+ {
+ int len = fread ((unsigned char*) ::SRAM, 1, 0x20000, file);
+ fclose (file);
+ if (len - size == 512)
+ {
+ // S-RAM file has a header - remove it
+ memmove (::SRAM, ::SRAM + 512, size);
+ }
+ if (len == size + SRTC_SRAM_PAD)
+ {
+ S9xSRTCPostLoadState ();
+ S9xResetSRTC ();
+ rtc.index = -1;
+ rtc.mode = MODE_READ;
+ }
+ else
+ S9xHardResetSRTC ();
+
+ if(Settings.SPC7110RTC)
+ {
+ S9xLoadSPC7110RTC (&rtc_f9);
+ }
+
+ return (TRUE);
+ }
+ S9xHardResetSRTC ();
+ return (FALSE);
+ }
+ if (Settings.SDD1)
+ S9xSDD1LoadLoggedData ();
+
+ return (TRUE);
+}
+
+bool8 CMemory::SaveSRAM (const char *filename)
+{
+ if(Settings.SuperFX && Memory.ROMType < 0x15)
+ return TRUE;
+ if(Settings.SA1 && Memory.ROMType == 0x34)
+ return TRUE;
+
+ int size = Memory.SRAMSize ?
+ (1 << (Memory.SRAMSize + 3)) * 128 : 0;
+ if (Settings.SRTC)
+ {
+ size += SRTC_SRAM_PAD;
+ S9xSRTCPreSaveState ();
+ }
+
+ if (Settings.SDD1)
+ S9xSDD1SaveLoggedData ();
+
+ if (size > 0x20000)
+ size = 0x20000;
+
+ if (size && *Memory.ROMFilename)
+ {
+
+ FILE *file= fopen(filename, "w");
+ if (file)
+ {
+ fwrite((unsigned char *) ::SRAM, size, 1, file);
+ fclose(file);
+ if(Settings.SPC7110RTC)
+ {
+ S9xSaveSPC7110RTC (&rtc_f9);
+ }
+
+ return (TRUE);
+ }
+ }
+ return (FALSE);
+}
+
+void CMemory::FixROMSpeed ()
+{
+ int c;
+
+ if(CPU.FastROMSpeed==0)
+ CPU.FastROMSpeed=SLOW_ONE_CYCLE;
+
+
+ for (c = 0x800; c < 0x1000; c++)
+ {
+ if (c&0x8 || c&0x400)
+ MemorySpeed [c] = (uint8) CPU.FastROMSpeed;
+ }
+}
+
+
+void CMemory::ResetSpeedMap()
+{
+ int i;
+ memset(MemorySpeed, SLOW_ONE_CYCLE, 0x1000);
+ for(i=0;i<0x400;i+=0x10)
+ {
+ MemorySpeed[i+2]=MemorySpeed[0x800+i+2]= ONE_CYCLE;
+ MemorySpeed[i+3]=MemorySpeed[0x800+i+3]= ONE_CYCLE;
+ MemorySpeed[i+4]=MemorySpeed[0x800+i+4]= ONE_CYCLE;
+ MemorySpeed[i+5]=MemorySpeed[0x800+i+5]= ONE_CYCLE;
+ }
+ CMemory::FixROMSpeed ();
+}
+
+void CMemory::WriteProtectROM ()
+{
+ memmove ((void *) WriteMap, (void *) Map, sizeof (Map));
+ for (int c = 0; c < 0x1000; c++)
+ {
+ if (BlockIsROM [c])
+ WriteMap [c] = (uint8 *) MAP_NONE;
+ }
+}
+
+void CMemory::MapRAM ()
+{
+ int c;
+
+ if(Memory.LoROM&&!Settings.SDD1)
+ {
+ // Banks 70->77, S-RAM
+ for (c = 0; c < 0x0f; c++)
+ {
+ for(int i=0;i<8;i++)
+ {
+ Map [(c<<4) + 0xF00+i]=Map [(c<<4) + 0x700+i] = (uint8 *) MAP_LOROM_SRAM;
+ BlockIsRAM [(c<<4) + 0xF00+i] =BlockIsRAM [(c<<4) + 0x700+i] = TRUE;
+ BlockIsROM [(c<<4) + 0xF00+i] =BlockIsROM [(c<<4) + 0x700+i] = FALSE;
+ }
+ }
+ }
+ else if(Memory.LoROM&&Settings.SDD1)
+ {
+ // Banks 70->77, S-RAM
+ for (c = 0; c < 0x0f; c++)
+ {
+ for(int i=0;i<8;i++)
+ {
+ Map [(c<<4) + 0x700+i] = (uint8 *) MAP_LOROM_SRAM;
+ BlockIsRAM [(c<<4) + 0x700+i] = TRUE;
+ BlockIsROM [(c<<4) + 0x700+i] = FALSE;
+ }
+ }
+ }
+ // Banks 7e->7f, RAM
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+ WriteProtectROM ();
+}
+
+void CMemory::MapExtraRAM ()
+{
+ int c;
+
+ // Banks 7e->7f, RAM
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+
+ // Banks 70->73, S-RAM
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x700] = ::SRAM;
+ Map [c + 0x710] = ::SRAM + 0x8000;
+ Map [c + 0x720] = ::SRAM + 0x10000;
+ Map [c + 0x730] = ::SRAM + 0x18000;
+
+ BlockIsRAM [c + 0x700] = TRUE;
+ BlockIsROM [c + 0x700] = FALSE;
+ BlockIsRAM [c + 0x710] = TRUE;
+ BlockIsROM [c + 0x710] = FALSE;
+ BlockIsRAM [c + 0x720] = TRUE;
+ BlockIsROM [c + 0x720] = FALSE;
+ BlockIsRAM [c + 0x730] = TRUE;
+ BlockIsROM [c + 0x730] = FALSE;
+ }
+}
+
+void CMemory::LoROMMap ()
+{
+ int c;
+ int i;
+ int j;
+ int mask[4];
+ for (j=0; j<4; j++)
+ mask[j]=0x00ff;
+
+ mask[0]=(CalculatedSize/0x8000)-1;
+
+ int x;
+ bool foundZeros;
+ bool pastZeros;
+
+ for(j=0;j<3;j++)
+ {
+ x=1;
+ foundZeros=false;
+ pastZeros=false;
+
+ mask[j+1]=mask[j];
+
+ while (x>0x100&&!pastZeros)
+ {
+ if(mask[j]&x)
+ {
+ x<<=1;
+ if(foundZeros)
+ pastZeros=true;
+ }
+ else
+ {
+ foundZeros=true;
+ pastZeros=false;
+ mask[j+1]|=x;
+ x<<=1;
+ }
+ }
+ }
+
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ if(Settings.SETA==ST_018)
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_SETA_RISC;
+ else Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ if (Settings.DSP1Master)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
+ }
+ else if (Settings.C4)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_C4;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_C4;
+ }
+ else if(Settings.OBC1)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_OBC_RAM;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_OBC_RAM;
+ }
+ else
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000;
+ }
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ int e=3;
+ int d=c>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+ Map [i] = Map [i + 0x800] = ROM + (((d)-1)*0x8000);
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ if (Settings.DSP1Master)
+ {
+ // Banks 30->3f and b0->bf
+ for (c = 0x300; c < 0x400; c += 16)
+ {
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = (uint8 *) MAP_DSP;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = FALSE;
+ }
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) % CalculatedSize];
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ int e=3;
+ int d=(c+0x400)>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+
+ Map [i + 0x400] = Map [i + 0xc00] = ROM + (((d)-1)*0x8000);
+ }
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ if (Settings.DSP1Master)
+ {
+ for (c = 0; c < 0x100; c++)
+ {
+ Map [c + 0xe00] = (uint8 *) MAP_DSP;
+ BlockIsROM [c + 0xe00] = FALSE;
+ }
+ }
+
+ int sum=0, k,l, bankcount;
+ bankcount=1<<(ROMSize-7);//Mbits
+
+ //safety for corrupt headers
+ if(bankcount > 128)
+ bankcount = (CalculatedSize/0x8000)/4;
+ bankcount*=4;//to banks
+ bankcount<<=4;//Map banks
+ bankcount+=0x800;//normalize
+ for(k=0x800;k<(bankcount);k+=16)
+ {
+ uint8* bank=0x8000+Map[k+8];
+ for(l=0;l<0x8000;l++)
+ sum+=bank[l];
+ }
+ CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::SetaDSPMap ()
+{
+ int c;
+ int i;
+ int j;
+ int mask[4];
+ for (j=0; j<4; j++)
+ mask[j]=0x00ff;
+
+ mask[0]=(CalculatedSize/0x8000)-1;
+
+ int x;
+ bool foundZeros;
+ bool pastZeros;
+
+ for(j=0;j<3;j++)
+ {
+ x=1;
+ foundZeros=false;
+ pastZeros=false;
+
+ mask[j+1]=mask[j];
+
+ while (x>0x100&&!pastZeros)
+ {
+ if(mask[j]&x)
+ {
+ x<<=1;
+ if(foundZeros)
+ pastZeros=true;
+ }
+ else
+ {
+ foundZeros=true;
+ pastZeros=false;
+ mask[j+1]|=x;
+ x<<=1;
+ }
+ }
+ }
+
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ int e=3;
+ int d=c>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+ Map [i] = Map [i + 0x800] = ROM + (((d)-1)*0x8000);
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c + 8; i < c + 16; i++)
+ {
+ int e=3;
+ int d=(c+0x400)>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+
+ Map [i + 0x400] = Map [i + 0xc00] = ROM + (((d)-1)*0x8000);
+ }
+
+ //only upper half is ROM
+ for (i = c+8; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ memset(SRAM, 0, 0x1000);
+ for (c=0x600;c<0x680;c+=0x10)
+ {
+ for(i=0;i<0x08;i++)
+ {
+ //where does the SETA chip access, anyway?
+ //please confirm this?
+ Map[c+0x80+i]=(uint8*)MAP_SETA_DSP;
+ BlockIsROM [c+0x80+i] = FALSE;
+ BlockIsRAM [c+0x80+i] = TRUE;
+ }
+
+ for(i=0;i<0x04;i++)
+ {
+ //and this!
+ Map[c+i]=(uint8*)MAP_SETA_DSP;
+ BlockIsROM [c+i] = FALSE;
+ }
+ }
+
+ int sum=0, k,l, bankcount;
+ bankcount=1<<(ROMSize-7);//Mbits
+ //safety for corrupt headers
+ if(bankcount > 128)
+ bankcount = (CalculatedSize/0x8000)/4;
+ bankcount*=4;//to banks
+ bankcount<<=4;//Map banks
+ bankcount+=0x800;//normalize
+ for(k=0x800;k<(bankcount);k+=16)
+ {
+ uint8* bank=0x8000+Map[k+8];
+ for(l=0;l<0x8000;l++)
+ sum+=bank[l];
+ }
+ CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::BSLoROMMap ()
+{
+ int c;
+ int i;
+
+ if(Settings.BS)
+ SRAMSize=5;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) RAM;
+// Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
+BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE;
+
+// Map [c + 6] = Map [c + 0x806] = (uint8 *)MAP_NONE;
+// Map [c + 7] = Map [c + 0x807] = (uint8 *)MAP_NONE;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) RAM;
+// Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
+BlockIsRAM [c + 6] = BlockIsRAM [c + 0x806] = TRUE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) RAM;
+// Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
+BlockIsRAM [c + 7] = BlockIsRAM [c + 0x807] = TRUE;
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [(c << 11) % CalculatedSize] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ for(c=0;c<8;c++)
+ {
+ Map[(c<<4)+0x105]=(uint8*)MAP_LOROM_SRAM;
+ BlockIsROM [(c<<4)+0x105] = FALSE;
+ BlockIsRAM [(c<<4)+0x105] = TRUE;
+ }
+
+
+ /* // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) % CalculatedSize];
+
+ for (i = c + 8; i < c + 16; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [((c << 11) + 0x200000) % CalculatedSize - 0x8000];
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+ */
+ for(c=1;c<=4;c++)
+ {
+ for(i=0;i<16; i++)
+ {
+ Map[0x400+i+(c<<4)]=(uint8*)MAP_LOROM_SRAM;
+ BlockIsRAM[0x400+i+(c<<4)]=TRUE;
+ BlockIsROM[0x400+i+(c<<4)]=FALSE;
+ }
+ }
+
+ for(i=0;i<0x80;i++)
+ {
+ Map[0x700+i]=&BSRAM[0x10000*(i/16)];
+ BlockIsRAM[0x700+i]=TRUE;
+ BlockIsROM[0x700+i]=FALSE;
+ }
+ for (i=0; i<8;i++)
+ {
+ Map[0x205+(i<<4)]=Map[0x285+(i<<4)]=Map[0x305+(i<<4)]=Map[0x385+(i<<4)]=Map[0x705+(i<<4)];
+ BlockIsRAM[0x205+(i<<4)]=BlockIsRAM[0x285+(i<<4)]=BlockIsRAM[0x305+(i<<4)]=BlockIsRAM[0x385+(i<<4)]=TRUE;
+ BlockIsROM[0x205+(i<<4)]=BlockIsROM[0x285+(i<<4)]=BlockIsROM[0x305+(i<<4)]=BlockIsROM[0x385+(i<<4)]=FALSE;
+ }
+ for(c=0;c<8;c++)
+ {
+ Map[(c<<4)+0x005]=BSRAM-0x5000;
+ BlockIsROM [(c<<4)+0x005] = FALSE;
+ BlockIsRAM [(c<<4)+0x005] = TRUE;
+ }
+ MapRAM ();
+ WriteProtectROM ();
+
+
+}
+
+void CMemory::HiROMMap ()
+{
+ int i;
+ int c;
+ int j;
+
+ int mask[4];
+ for (j=0; j<4; j++)
+ mask[j]=0x00ff;
+
+ mask[0]=(CalculatedSize/0x10000)-1;
+
+ if (Settings.ForceSA1 ||
+ (!Settings.ForceNoSA1 && (ROMSpeed & ~0x10) == 0x23 &&
+ (ROMType & 0xf) > 3 && (ROMType & 0xf0) == 0x30))
+ {
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ }
+
+
+ int x;
+ bool foundZeros;
+ bool pastZeros;
+
+ for(j=0;j<3;j++)
+ {
+ x=1;
+ foundZeros=false;
+ pastZeros=false;
+
+ mask[j+1]=mask[j];
+
+ while (x>0x100&&!pastZeros)
+ {
+ if(mask[j]&x)
+ {
+ x<<=1;
+ if(foundZeros)
+ pastZeros=true;
+ }
+ else
+ {
+ foundZeros=true;
+ pastZeros=false;
+ mask[j+1]|=x;
+ x<<=1;
+ }
+ }
+ }
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+
+ if (Settings.DSP1Master)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
+ }
+ else
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+ }
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ int e=3;
+ int d=c>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+ Map [i] = Map [i + 0x800] = ROM + (d*0x10000);
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM.
+ for (c = 0; c < 16; c++)
+ {
+ Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ BlockIsRAM [0x306 + (c << 4)] = TRUE;
+ BlockIsRAM [0x307 + (c << 4)] = TRUE;
+ BlockIsRAM [0xb06 + (c << 4)] = TRUE;
+ BlockIsRAM [0xb07 + (c << 4)] = TRUE;
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ int e=3;
+ int d=(c)>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+ Map [i + 0x400] = Map [i + 0xc00] = ROM + (d*0x10000);
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ int bankmax=0x40+ (1<<(ROMSize-6));
+ //safety for corrupt headers
+ if(bankmax > 128)
+ bankmax = 0x80;
+ int sum=0;
+ for(i=0x40;i<bankmax; i++)
+ {
+ uint8 * bank_low=(uint8*)Map[i<<4];
+ for (c=0;c<0x10000; c++)
+ {
+ sum+=bank_low[c];
+ }
+ }
+ CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::TalesROMMap (bool8 Interleaved)
+{
+ int c;
+ int i;
+
+ if(Interleaved)
+ {
+ if(Settings.DisplayColor==0xffff)
+ {
+ Settings.DisplayColor=BUILD_PIXEL(0,31,0);
+ SET_UI_COLOR(0,255,0);
+ }
+ }
+ uint32 OFFSET0 = 0x400000;
+ uint32 OFFSET1 = 0x400000;
+ uint32 OFFSET2 = 0x000000;
+
+ if (Interleaved)
+ {
+ OFFSET0 = 0x000000;
+ OFFSET1 = 0x000000;
+ OFFSET2 = CalculatedSize-0x400000; //changed to work with interleaved DKJM2.
+ }
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+
+ //makes more sense to map the range here.
+ //ToP seems to use sram to skip intro???
+ if(c>=0x300)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_HIROM_SRAM;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_HIROM_SRAM;
+ BlockIsRAM [6 + c] = BlockIsRAM [7 + c] =
+ BlockIsRAM [0x806 + c]= BlockIsRAM [0x807 + c] = TRUE;
+ }
+ else
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+ }
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = &ROM [((c << 12) % (CalculatedSize-0x400000)) + OFFSET0];
+ Map [i + 0x800] = &ROM [((c << 12) % 0x400000) + OFFSET2];
+ BlockIsROM [i] = TRUE;
+ BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ {
+ Map [i + 0x400] = &ROM [((c << 12) % (CalculatedSize-0x400000)) + OFFSET1];
+ Map [i + 0x408] = &ROM [((c << 12) % (CalculatedSize-0x400000)) + OFFSET1];
+ Map [i + 0xc00] = &ROM [((c << 12) %0x400000)+ OFFSET2];
+ Map [i + 0xc08] = &ROM [((c << 12) % 0x400000) + OFFSET2];
+ BlockIsROM [i + 0x400] = TRUE;
+ BlockIsROM [i + 0x408] = TRUE;
+ BlockIsROM [i + 0xc00] = TRUE;
+ BlockIsROM [i + 0xc08] = TRUE;
+ }
+ }
+
+ if((strncmp("TALES",(char*)Map[8]+0xFFC0, 5)==0))
+ {
+ if(((*(Map[8]+0xFFDE))==(*(Map[0x808]+0xFFDE))))
+ {
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ }
+ }
+
+ ROMChecksum = *(Map[8]+0xFFDE) + (*(Map[8]+0xFFDF) << 8);
+ ROMComplementChecksum = *(Map[8]+0xFFDC) + (*(Map[8]+0xFFDD) << 8);
+
+int sum=0;
+for(i=0x40;i<0x80; i++)
+{
+ uint8 * bank_low=(uint8*)Map[i<<4];
+ uint8 * bank_high=(uint8*)Map[(i<<4)+0x800];
+ for (c=0;c<0x10000; c++)
+ {
+ sum+=bank_low[c];
+ sum+=bank_high[c];
+ }
+}
+
+CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::AlphaROMMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ Map [i + 0x400] = &ROM [(c << 12) % CalculatedSize];
+ Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void DetectSuperFxRamSize()
+{
+ if(ROM[0x7FDA]==0x33)
+ {
+ Memory.SRAMSize=ROM[0x7FBD];
+ }
+ else
+ {
+ if(strncmp(Memory.ROMName, "STAR FOX 2", 10)==0)
+ {
+ Memory.SRAMSize=6;
+ }
+ else Memory.SRAMSize=5;
+ }
+}
+
+void CMemory::SuperFXROMMap ()
+{
+ int c;
+ int i;
+
+ DetectSuperFxRamSize();
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [0x006 + c] = Map [0x806 + c] = (uint8 *) ::SRAM - 0x6000;
+ Map [0x007 + c] = Map [0x807 + c] = (uint8 *) ::SRAM - 0x6000;
+ BlockIsRAM [0x006 + c] = BlockIsRAM [0x007 + c] = BlockIsRAM [0x806 + c] = BlockIsRAM [0x807 + c] = TRUE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ // Banks 7e->7f, RAM
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+
+ // Banks 70->71, S-RAM
+ for (c = 0; c < 32; c++)
+ {
+ Map [c + 0x700] = ::SRAM + (((c >> 4) & 1) << 16);
+ BlockIsRAM [c + 0x700] = TRUE;
+ BlockIsROM [c + 0x700] = FALSE;
+ }
+
+ // Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K
+ // block is repeated twice in each 64K block.
+ for (c = 0; c < 64; c++)
+ {
+ memmove (&ROM [0x200000 + c * 0x10000], &ROM [c * 0x8000], 0x8000);
+ memmove (&ROM [0x208000 + c * 0x10000], &ROM [c * 0x8000], 0x8000);
+ }
+
+ WriteProtectROM ();
+}
+
+void CMemory::SA1ROMMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) &Memory.FillRAM [0x3000] - 0x3000;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_BWRAM;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_BWRAM;
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ Map [i + 0x400] = (uint8 *) &SRAM [(c << 12) & 0x1ffff];
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = FALSE;
+ }
+ }
+
+ // c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+ WriteProtectROM ();
+
+ // Now copy the map and correct it for the SA1 CPU.
+ memmove ((void *) SA1.WriteMap, (void *) WriteMap, sizeof (WriteMap));
+ memmove ((void *) SA1.Map, (void *) Map, sizeof (Map));
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000];
+ SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8 *) MAP_NONE;
+ SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000];
+ SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8 *) MAP_NONE;
+ }
+
+ // Banks 60->6f
+ for (c = 0; c < 0x100; c++)
+ SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8 *) MAP_BWRAM_BITMAP;
+
+ BWRAM = SRAM;
+}
+
+void CMemory::LoROM24MBSMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x200; c += 16)
+ {
+ Map [c + 0x800] = RAM;
+ Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i + 0x800] = &ROM [c << 11] - 0x8000 + 0x200000;
+ BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000];
+
+ for (i = c + 8; i < c + 16; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000];
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ MapExtraRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::SufamiTurboLoROMMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000];
+
+ for (i = c + 8; i < c + 16; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000];
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ if (Settings.DSP1Master)
+ {
+ for (c = 0; c < 0x100; c++)
+ {
+ Map [c + 0xe00] = (uint8 *) MAP_DSP;
+ BlockIsROM [c + 0xe00] = FALSE;
+ }
+ }
+
+ // Banks 7e->7f, RAM
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+
+ // Banks 60->67, S-RAM
+ for (c = 0; c < 0x80; c++)
+ {
+ Map [c + 0x600] = (uint8 *) MAP_LOROM_SRAM;
+ BlockIsRAM [c + 0x600] = TRUE;
+ BlockIsROM [c + 0x600] = FALSE;
+ }
+
+ WriteProtectROM ();
+}
+
+#if 0
+
+//untested!!
+void CMemory::SameGameMap ()
+{
+ int i;
+ int c;
+ int j;
+
+ int mask[4];
+ int mask2[4];
+ for (j=0; j<4; j++)
+ mask[j]=mask2[j]=0x00ff;
+
+ mask[0]=(CalculatedSize/0x10000)-1;
+ mask2[0]=(Slot1Size/0x10000)-1;
+
+ int x;
+ bool foundZeros;
+ bool pastZeros;
+
+ for(j=0;j<3;j++)
+ {
+ x=1;
+ foundZeros=false;
+ pastZeros=false;
+
+ mask[j+1]=mask[j];
+
+ while (x>0x100&&!pastZeros)
+ {
+ if(mask[j]&x)
+ {
+ x<<=1;
+ if(foundZeros)
+ pastZeros=true;
+ }
+ else
+ {
+ foundZeros=true;
+ pastZeros=false;
+ mask[j+1]|=x;
+ x<<=1;
+ }
+ }
+ }
+
+ for(j=0;j<3;j++)
+ {
+ x=1;
+ foundZeros=false;
+ pastZeros=false;
+
+ mask2[j+1]=mask2[j];
+
+ while (x>0x100&&!pastZeros)
+ {
+ if(mask2[j]&x)
+ {
+ x<<=1;
+ if(foundZeros)
+ pastZeros=true;
+ }
+ else
+ {
+ foundZeros=true;
+ pastZeros=false;
+ mask2[j+1]|=x;
+ x<<=1;
+ }
+ }
+ }
+
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+ }
+
+ // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM.
+ for (c = 0; c < 16; c++)
+ {
+ Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ BlockIsRAM [0x306 + (c << 4)] = TRUE;
+ BlockIsRAM [0x307 + (c << 4)] = TRUE;
+ BlockIsRAM [0xb06 + (c << 4)] = TRUE;
+ BlockIsRAM [0xb07 + (c << 4)] = TRUE;
+ }
+
+ for c=0; c<0x200; c+=16)
+ {
+ for(i=0;i<8;i++)
+ {
+ int e=3;
+ int d=c>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+
+ int f=3;
+ int g=c>>4;
+ while(g>mask2[0])
+ {
+ g&=mask2[f];
+ f--;
+ }
+
+ //stuff in HiROM areas
+ Map[c+0x400+i]=&ROM[d*0x10000];
+ Map[c+0xC00+i]=&ROM[d*0x10000];
+ //MINI
+ Map[c+0x600+i]=&ROMOffset1[g*0x10000];
+ Map[c+0xE00+i]=&ROMOffset1[g*0x10000];
+
+ }
+ for(i=8;i<16;i++)
+ {
+ int e=3;
+ int d=c>>4;
+ while(d>mask[0])
+ {
+ d&=mask[e];
+ e--;
+ }
+
+ int f=3;
+ int g=c>>4;
+ while(g>mask2[0])
+ {
+ g&=mask2[f];
+ f--;
+ }
+
+
+ //all stuff
+ //BASE
+ Map[c+i]=&ROM[d*0x10000];
+ Map[c+0x800+i]=&ROM[d*0x10000];
+ Map[c+0x400+i]=&ROM[d*0x10000];
+ Map[c+0xC00+i]=&ROM[d*0x10000];
+ //MINI
+ Map[c+0x200+i]=&ROMOffset1[g*0x10000];
+ Map[c+0xA00+i]=&ROMOffset1[g*0x10000];
+ Map[c+0x600+i]=&ROMOffset1[g*0x10000];
+ Map[c+0xE00+i]=&ROMOffset1[g*0x10000];
+ }
+
+ }
+
+ int bankmax=0x40+ (1<<(ROMSize-6));
+ //safety for corrupt headers
+ if(bankmax > 128)
+ bankmax = 0x80;
+ int sum=0;
+ for(i=0x40;i<bankmax; i++)
+ {
+ uint8 * bank_low=(uint8*)Map[i<<4];
+ for (c=0;c<0x10000; c++)
+ {
+ sum+=bank_low[c];
+ }
+ }
+ CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+
+//Untested!!
+void CMemory::GNextROMMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) &Memory.FillRAM [0x3000] - 0x3000;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_BWRAM;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_BWRAM;
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+
+ // Banks 40->4f (was 7f, but SNES docs and GNext overdumping shows nothing here.)
+ for (c = 0; c < 0x100; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ Map [i + 0x400] = (uint8 *) &SRAM [(c << 12) & 0x1ffff];
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = FALSE;
+ }
+ }
+
+ for (c = 0; c < 0x100; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ Map [i + 0x700] = (uint8 *) &ROMOffset1 [(c << 12) & (Slot1Size-1)];
+ }
+
+ // c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+ WriteProtectROM ();
+
+ // Now copy the map and correct it for the SA1 CPU.
+ memmove ((void *) SA1.WriteMap, (void *) WriteMap, sizeof (WriteMap));
+ memmove ((void *) SA1.Map, (void *) Map, sizeof (Map));
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000];
+ SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8 *) MAP_NONE;
+ SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000];
+ SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8 *) MAP_NONE;
+ }
+
+ // Banks 60->6f
+ for (c = 0; c < 0x100; c++)
+ SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8 *) MAP_BWRAM_BITMAP;
+
+ BWRAM = SRAM;
+}
+
+void CMemory::SufamiTurboAltROMMap ()
+{
+ int c;
+ int i;
+
+ if(Slot1Size!=0)
+ Slot1SRAMSize=(1<<((uint8)ROMOffset1[0x32]))*1024;
+ else Slot1Size=0x8000;
+ if(Slot2Size!=0)
+ Slot2SRAMSize=(1<<((uint8)ROMOffset2[0x32]))*1024;
+else Slot2Size=0x8000;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+// for (i = c + 8; i < c + 16; i++)
+// {
+// Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+// BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+// }
+
+ }
+
+ //Map Bios
+
+ for (c=0; c<0x200; c+=16)
+ {
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [((c>>4)*0x8000)%CalculatedSize] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+
+ }
+
+
+ for (c=0x200; c<0x400; c+=16)
+ {
+ for (i = c + 8; i < c + 16; i++)
+ {
+ if(Slot1Size!=0)
+ {
+ Map [i] = Map [i + 0x800] = &ROMOffset1 [(((c>>4)*0x8000)%Slot1Size)] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ else Map [i] = Map [i + 0x800] = (uint8*)MAP_NONE;
+ }
+
+ }
+
+ for (c=0x400; c<0x600; c+=16)
+ {
+ for (i = c; i < c + 8; i++)
+ {
+ if(Slot2Size!=0)
+ {
+ Map [i] = Map [i + 0x800] = &ROMOffset2[(((c>>4)*0x8000)%Slot2Size)];
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ else Map [i] = Map [i + 0x800] = (uint8*)MAP_NONE;
+
+ }
+ for (i = c + 8; i < c + 16; i++)
+ {
+ if(Slot2Size!=0)
+ {
+ Map [i] = Map [i + 0x800] = &ROMOffset2[(((c>>4)*0x8000)%Slot2Size)] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ else Map [i] = Map [i + 0x800] = (uint8*)MAP_NONE;
+
+ }
+
+ }
+
+ // Banks 60->67 (7F?), S-RAM
+ if(Slot1SRAMSize!=0)
+ {
+ for (c = 0; c < 0x100; c++)
+ {
+ Map [c + 0xE00] = Map [c + 0x600] = (uint8 *) MAP_LOROM_SRAM;
+ BlockIsRAM [c + 0xE00] = BlockIsRAM [c + 0x600] = TRUE;
+ BlockIsROM [c + 0xE00] = BlockIsROM [c + 0x600] = FALSE;
+ }
+ }
+ if(Slot2SRAMSize!=0)
+ {
+ for (c = 0; c < 0x100; c++)
+ {
+ Map [c + 0xF00] = Map [c + 0x700] = (uint8 *) MAP_LOROM_SRAM;
+ BlockIsRAM [c + 0xF00] = BlockIsRAM [c + 0x700] = TRUE;
+ BlockIsROM [c + 0xF00] = BlockIsROM [c + 0x700] = FALSE;
+ }
+ }
+
+ // Banks 7e->7f, RAM
+ for (c = 0; c < 16; c++)
+ {
+ Map [c + 0x7e0] = RAM;
+ Map [c + 0x7f0] = RAM + 0x10000;
+ BlockIsRAM [c + 0x7e0] = TRUE;
+ BlockIsRAM [c + 0x7f0] = TRUE;
+ BlockIsROM [c + 0x7e0] = FALSE;
+ BlockIsROM [c + 0x7f0] = FALSE;
+ }
+
+ WriteProtectROM ();
+}
+#endif
+
+
+void CMemory::SRAM512KLoROMMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000];
+
+ for (i = c + 8; i < c + 16; i++)
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000];
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ MapExtraRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::BSHiROMMap ()
+{
+ int c;
+ int i;
+
+ SRAMSize=5;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ // XXX: How large is SRAM??
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) RAM;
+// Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
+ BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE;
+// Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
+// Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
+
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) RAM;
+// Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
+BlockIsRAM [c + 6] = BlockIsRAM [c + 0x806] = TRUE;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) RAM;
+// Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
+BlockIsRAM [c + 7] = BlockIsRAM [c + 0x807] = TRUE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 60->7d offset 0000->7fff & 60->7f offset 8000->ffff PSRAM
+ // XXX: How large is PSRAM?
+
+ //not adjusted, but The Dumper says "4 Mbits"
+ for (c = 0x600; c < 0x7e0; c += 16)
+ {
+ for (i = c; i < c + 8; i++)
+ {
+ Map [i] = &ROM [0x400000 + (c << 11)];
+ BlockIsRAM [i] = TRUE;
+ }
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = &ROM [0x400000 + (c << 11) - 0x8000];
+ BlockIsRAM [i] = TRUE;
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+ for(i=0;i<0x80;i++)
+ {
+ Map[0x700+i]=&BSRAM[0x10000*(i/16)];
+ BlockIsRAM[0x700+i]=TRUE;
+ BlockIsROM[0x700+i]=FALSE;
+ }
+ for (i=0; i<8;i++)
+ {
+ Map[0x205+(i<<4)]=Map[0x285+(i<<4)]=Map[0x305+(i<<4)]=Map[0x385+(i<<4)]=Map[0x705+(i<<4)];
+ BlockIsRAM[0x205+(i<<4)]=BlockIsRAM[0x285+(i<<4)]=BlockIsRAM[0x305+(i<<4)]=BlockIsRAM[0x385+(i<<4)]=TRUE;
+ BlockIsROM[0x205+(i<<4)]=BlockIsROM[0x285+(i<<4)]=BlockIsROM[0x305+(i<<4)]=BlockIsROM[0x385+(i<<4)]=FALSE;
+ }
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::JumboLoROMMap (bool8 Interleaved)
+{
+ int c;
+ int i;
+
+ uint32 OFFSET0 = 0x400000;
+ uint32 OFFSET1 = 0x400000;
+ uint32 OFFSET2 = 0x000000;
+
+ if (Interleaved)
+ {
+ OFFSET0 = 0x000000;
+ OFFSET1 = 0x000000;
+ OFFSET2 = CalculatedSize-0x400000; //changed to work with interleaved DKJM2.
+ }
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+ if (Settings.DSP1Master)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
+ }
+ else if (Settings.C4)
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_C4;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_C4;
+ }
+ else
+ {
+ Map [c + 6] = Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000;
+ Map [c + 7] = Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000;
+ }
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i]= &ROM [((c << 11) % (CalculatedSize - 0x400000)) + OFFSET0] - 0x8000;
+ Map [i + 0x800] = &ROM [((c << 11) % (0x400000)) + OFFSET2] - 0x8000;
+ BlockIsROM [i + 0x800] = BlockIsROM [i] = TRUE;
+ }
+ }
+
+ if (Settings.DSP1Master)
+ {
+ // Banks 30->3f and b0->bf
+ for (c = 0x300; c < 0x400; c += 16)
+ {
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i + 0x800] = (uint8 *) MAP_DSP;
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = FALSE;
+ }
+ }
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0x400; c < 0x800; c += 16)
+ {
+ //updated mappings to correct A15 mirroring
+ for (i = c; i < c + 8; i++)
+ {
+ Map [i]= &ROM [((c << 11) % (CalculatedSize - 0x400000)) + OFFSET0];
+ Map [i + 0x800] = &ROM [((c << 11) % 0x400000) +OFFSET2];
+ }
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i]= &ROM [((c << 11) % (CalculatedSize - 0x400000)) + OFFSET0] - 0x8000;
+ Map [i + 0x800] = &ROM [((c << 11) % 0x400000) + OFFSET2 ] - 0x8000;
+ }
+
+ for (i = c; i < c + 16; i++)
+ {
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ //ROM type has to be 64 Mbit header!
+ int sum=0, k,l;
+ for(k=0;k<256;k++)
+ {
+ uint8* bank=0x8000+Map[8+(k<<4)];//use upper half of the banks, and adjust for LoROM.
+ for(l=0;l<0x8000;l++)
+ sum+=bank[l];
+ }
+ CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+
+void CMemory::SPC7110HiROMMap ()
+{
+ int c;
+ int i;
+
+ // Banks 00->3f and 80->bf
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 0] = Map [c + 0x800] = RAM;
+ BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
+ Map [c + 1] = Map [c + 0x801] = RAM;
+ BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
+
+ Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
+ Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
+ Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
+ Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
+
+ Map [c + 6] /*= Map [c + 0x806]*/ = (uint8 *) MAP_HIROM_SRAM;
+ Map [c + 7] /*= Map [c + 0x807]*/ = (uint8 *) MAP_HIROM_SRAM;
+ Map [c + 0x806]=Map [c + 0x807]= (uint8 *) MAP_NONE;
+
+ for (i = c + 8; i < c + 16; i++)
+ {
+ Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
+ }
+ }
+
+ // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM.
+ for (c = 0; c < 16; c++)
+ {
+ Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
+ Map [0xb06 + (c << 4)] = (uint8 *) MAP_NONE;
+ Map [0xb07 + (c << 4)] = (uint8 *) MAP_NONE;
+ BlockIsRAM [0x306 + (c << 4)] = TRUE;
+ BlockIsRAM [0x307 + (c << 4)] = TRUE;
+ // BlockIsRAM [0xb06 + (c << 4)] = TRUE;
+ // BlockIsRAM [0xb07 + (c << 4)] = TRUE;
+ }
+
+ // Banks 40->7f and c0->ff
+ for (c = 0; c < 0x400; c += 16)
+ {
+ for (i = c; i < c + 16; i++)
+ {
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
+ }
+ }
+
+ for (c=0;c<0x10;c++)
+ {
+ Map [0x500+c]=(uint8 *)MAP_SPC7110_DRAM;
+ BlockIsROM [0x500+c]=TRUE;
+ }
+
+ for (c=0;c<0x100;c++)
+ {
+ Map [0xD00+c] = (uint8 *) MAP_SPC7110_ROM;
+ Map [0xE00+c] = (uint8 *) MAP_SPC7110_ROM;
+ Map [0xF00+c] = (uint8 *) MAP_SPC7110_ROM;
+ BlockIsROM [0xD00+c] = BlockIsROM [0xE00+c] = BlockIsROM [0xF00+c] = TRUE;
+
+ }
+ S9xSpc7110Init();
+
+int sum=0;
+for(i=0;i<(int)CalculatedSize; i++)
+{
+ sum+=ROM[i];
+}
+
+if(CalculatedSize==0x300000)
+ sum<<=1;
+CalculatedChecksum=sum&0xFFFF;
+
+ MapRAM ();
+ WriteProtectROM ();
+}
+void CMemory::SPC7110Sram(uint8 newstate)
+{
+ if(newstate&0x80)
+ {
+ Memory.Map[6]=(uint8 *)MAP_HIROM_SRAM;
+ Memory.Map[7]=(uint8 *)MAP_HIROM_SRAM;
+ Memory.Map[0x306]=(uint8 *)MAP_HIROM_SRAM;
+ Memory.Map[0x307]=(uint8 *)MAP_HIROM_SRAM;
+
+
+ }
+ else
+ {
+ Memory.Map[6]=(uint8 *)MAP_RONLY_SRAM;
+ Memory.Map[7]=(uint8 *)MAP_RONLY_SRAM;
+ Memory.Map[0x306]=(uint8 *)MAP_RONLY_SRAM;
+ Memory.Map[0x307]=(uint8 *)MAP_RONLY_SRAM;
+ }
+}
+const char *CMemory::TVStandard ()
+{
+ return (Settings.PAL ? "PAL" : "NTSC");
+}
+
+const char *CMemory::Speed ()
+{
+ return (ROMSpeed & 0x10 ? "120ns" : "200ns");
+}
+
+const char *CMemory::MapType ()
+{
+ return (HiROM ? "HiROM" : "LoROM");
+}
+
+const char *CMemory::StaticRAMSize ()
+{
+ static char tmp [20];
+
+ if (Memory.SRAMSize > 16)
+ return ("Corrupt");
+ sprintf (tmp, "%dKB", (SRAMMask + 1) / 1024);
+ return (tmp);
+}
+
+const char *CMemory::Size ()
+{
+ static char tmp [20];
+
+ if (ROMSize < 7 || ROMSize - 7 > 23)
+ return ("Corrupt");
+ sprintf (tmp, "%dMbits", 1 << (ROMSize - 7));
+ return (tmp);
+}
+
+const char *CMemory::KartContents ()
+{
+ static char tmp [30];
+ static const char *CoPro [16] = {
+ "DSP1", "SuperFX", "OBC1", "SA-1", "S-DD1", "S-RTC", "CoPro#6",
+ "CoPro#7", "CoPro#8", "CoPro#9", "CoPro#10", "CoPro#11", "CoPro#12",
+ "CoPro#13", "CoPro#14", "CoPro-Custom"
+ };
+ static const char *Contents [3] = {
+ "ROM", "ROM+RAM", "ROM+RAM+BAT"
+ };
+ if (ROMType == 0&&!Settings.BS)
+ return ("ROM only");
+
+ sprintf (tmp, "%s", Contents [(ROMType & 0xf) % 3]);
+
+
+ if(Settings.BS)
+ sprintf (tmp, "%s+%s", tmp, "BSX");
+ else if(Settings.SPC7110&&Settings.SPC7110RTC)
+ sprintf (tmp, "%s+%s", tmp, "SPC7110+RTC");
+ else if(Settings.SPC7110)
+ sprintf (tmp, "%s+%s", tmp, "SPC7110");
+ else if(Settings.SETA!=0)
+ {
+ switch(Settings.SETA)
+ {
+ case ST_010:
+ sprintf (tmp, "%s+%s", tmp, "ST-010");
+ break;
+ case ST_011:
+ sprintf (tmp, "%s+%s", tmp, "ST-011");
+ break;
+
+ case ST_018:
+ sprintf (tmp, "%s+%s", tmp, "ST-018");
+ break;
+
+ }
+ }
+ else if ((ROMType & 0xf) >= 3)
+ sprintf (tmp, "%s+%s", tmp, CoPro [(ROMType & 0xf0) >> 4]);
+
+ return (tmp);
+}
+
+const char *CMemory::MapMode ()
+{
+ static char tmp [4];
+ sprintf (tmp, "%02x", ROMSpeed & ~0x10);
+ return (tmp);
+}
+
+const char *CMemory::ROMID ()
+{
+ return (ROMId);
+}
+
+void CMemory::ApplyROMFixes ()
+{
+#ifdef __W32_HEAP
+ if(_HEAPOK!=_heapchk())
+ MessageBox(GUI.hWnd, "CMemory::ApplyROMFixes", "Heap Corrupt", MB_OK);
+#endif
+
+ //don't steal my work! -MK
+ if(ROMCRC32 == 0x1B4A5616 && strncmp(ROMName, "RUDORA NO HIHOU", 15)==0)
+ {
+ strncpy(ROMName, "THIS SCRIPT WAS STOLEN", 22);
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ }
+
+ /*
+ HACKS NSRT can fix that we hadn't detected before.
+[14:25:13] <@Nach> case 0x0c572ef0: //So called Hook (US)(2648)
+[14:25:13] <@Nach> case 0x6810aa95: //Bazooka Blitzkreig swapped sizes hack -handled
+[14:25:17] <@Nach> case 0x61E29C06: //The Tick region hack
+[14:25:19] <@Nach> case 0x1EF90F74: //Jikkyou Keiba Simulation Stable Star PAL hack
+[14:25:23] <@Nach> case 0x4ab225b5: //So called Krusty's Super Fun House (E)
+[14:25:25] <@Nach> case 0x77fd806a: //Donkey Kong Country 2 (E) v1.1 bad dump -handled
+[14:25:27] <@Nach> case 0x340f23e5: //Donkey Kong Country 3 (U) copier hack - handled
+ */
+
+ if(ROMCRC32==0x6810aa95 || ROMCRC32==0x340f23e5 || ROMCRC32==0x77fd806a ||
+ strncmp (ROMName, "HIGHWAY BATTLE 2", 16)==0 ||
+ (strcmp (ROMName, "FX SKIING NINTENDO 96") == 0 && ROM[0x7FDA]==0))
+ {
+ Settings.DisplayColor=BUILD_PIXEL(31,0,0);
+ SET_UI_COLOR(255,0,0);
+ }
+
+ //Ambiguous chip function pointer assignments
+
+ //DSP switching:
+ if(strncmp(ROMName, "DUNGEON MASTER", 14)==0)
+ {
+ //Set DSP-2
+ SetDSP=&DSP2SetByte;
+ GetDSP=&DSP2GetByte;
+ }
+
+#ifdef DSP_DUMMY_LOOPS
+ if(strncmp(ROMName, "SD\x0b6\x0de\x0dd\x0c0\x0de\x0d1GX", 10)==0)
+ {
+ //Set DSP-3
+ SetDSP=&DSP3SetByte;
+ GetDSP=&DSP3GetByte;
+ }
+#endif
+
+ if(strncmp(ROMName, "TOP GEAR 3000", 13)==0
+ ||strncmp(ROMName, "PLANETS CHAMP TG3000", 20)==0)
+ {
+ //Set DSP-4
+ SetDSP=&DSP4SetByte;
+ GetDSP=&DSP4GetByte;
+ }
+
+ //memory map corrections
+ if(strncmp(ROMName, "XBAND",5)==0)
+ {
+ for (int c=0xE00;c<0xE10;c++)
+ {
+ Map [c] = (uint8 *) MAP_LOROM_SRAM;
+ BlockIsRAM [c] = TRUE;
+ BlockIsROM [c] = FALSE;
+ }
+ WriteProtectROM ();
+ }
+
+ //not MAD-1 compliant
+ if(strcmp (ROMName, "WANDERERS FROM YS") == 0)
+ {
+ for(int c=0;c<0xE0;c++)
+ {
+ Map[c+0x700]=(uint8*)MAP_LOROM_SRAM;
+ BlockIsROM[c+0x700]=FALSE;
+ BlockIsRAM[c+0x700]=TRUE;
+ }
+ WriteProtectROM();
+ }
+
+ if (strcmp (ROMName, "GOGO ACKMAN3") == 0 ||
+ strcmp (ROMName, "HOME ALONE") == 0)
+ {
+ // Banks 00->3f and 80->bf
+ for (int c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 6] = Map [c + 0x806] = SRAM;
+ Map [c + 7] = Map [c + 0x807] = SRAM;
+ BlockIsROM [c + 6] = BlockIsROM [c + 0x806] = FALSE;
+ BlockIsROM [c + 7] = BlockIsROM [c + 0x807] = FALSE;
+ BlockIsRAM [c + 6] = BlockIsRAM [c + 0x806] = TRUE;
+ BlockIsRAM [c + 7] = BlockIsRAM [c + 0x807] = TRUE;
+ }
+ WriteProtectROM ();
+ }
+
+ if (strcmp (ROMName, "RADICAL DREAMERS") == 0 ||
+ strcmp (ROMName, "TREASURE CONFLIX") == 0)
+ {
+ int c;
+
+ for (c = 0; c < 0x80; c++)
+ {
+ Map [c + 0x700] = ROM + 0x200000 + 0x1000 * (c & 0xf0);
+ BlockIsRAM [c + 0x700] = TRUE;
+ BlockIsROM [c + 0x700] = FALSE;
+ }
+ for (c = 0; c < 0x400; c += 16)
+ {
+ Map [c + 5] = Map [c + 0x805] = ROM + 0x300000;
+ BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE;
+ }
+ WriteProtectROM ();
+ }
+
+ if(strncmp(ROMName, "WAR 2410", 8)==0)
+ {
+ Map [0x005] = (uint8 *) RAM;
+ BlockIsRAM [0x005] = TRUE;
+ BlockIsROM [0x005] = FALSE;
+ }
+
+ if (strcmp (ROMName, "BATMAN--REVENGE JOKER") == 0)
+ {
+ Memory.HiROM = FALSE;
+ Memory.LoROM = TRUE;
+ LoROMMap ();
+ }
+
+
+ //NMI hacks
+ CPU.NMITriggerPoint = 4;
+ if (strcmp (ROMName, "CACOMA KNIGHT") == 0)
+ CPU.NMITriggerPoint = 25;
+
+ //Disabling a speed-up
+ // Games which spool sound samples between the SNES and sound CPU using
+ // H-DMA as the sample is playing.
+ if (strcmp (ROMName, "EARTHWORM JIM 2") == 0 ||
+ strcmp (ROMName, "PRIMAL RAGE") == 0 ||
+ strcmp (ROMName, "CLAY FIGHTER") == 0 ||
+ strcmp (ROMName, "ClayFighter 2") == 0 ||
+ strncasecmp (ROMName, "MADDEN", 6) == 0 ||
+ strncmp (ROMName, "NHL", 3) == 0 ||
+ strcmp (ROMName, "WeaponLord") == 0||
+ strncmp(ROMName, "WAR 2410", 8)==0)
+ {
+ Settings.Shutdown = FALSE;
+ }
+
+
+ //APU timing hacks
+
+ // Stunt Racer FX
+ if (strcmp (ROMId, "CQ ") == 0 ||
+ // Illusion of Gaia
+ strncmp (ROMId, "JG", 2) == 0 ||
+ strcmp (ROMName, "GAIA GENSOUKI 1 JPN") == 0)
+ {
+ IAPU.OneCycle = 13;
+ }
+
+ // RENDERING RANGER R2
+ if (strcmp (ROMId, "AVCJ") == 0 ||
+ //Mark Davis
+ strncmp(ROMName, "THE FISHING MASTER", 18)==0 || //needs >= actual APU timing. (21 is .002 Mhz slower)
+ // Star Ocean
+ strncmp (ROMId, "ARF", 3) == 0 ||
+ // Tales of Phantasia
+ strncmp (ROMId, "ATV", 3) == 0 ||
+ // Act Raiser 1 & 2
+ strncasecmp (ROMName, "ActRaiser", 9) == 0 ||
+ // Soulblazer
+ strcmp (ROMName, "SOULBLAZER - 1 USA") == 0 ||
+ strcmp (ROMName, "SOULBLADER - 1") == 0 ||
+
+ // Terranigma
+ strncmp (ROMId, "AQT", 3) == 0 ||
+ // Robotrek
+ strncmp (ROMId, "E9 ", 3) == 0 ||
+ strcmp (ROMName, "SLAP STICK 1 JPN") == 0 ||
+ // ZENNIHON PURORESU2
+ strncmp (ROMId, "APR", 3) == 0 ||
+ // Bomberman 4
+ strncmp (ROMId, "A4B", 3) == 0 ||
+ // UFO KAMEN YAKISOBAN
+ strncmp (ROMId, "Y7 ", 3) == 0 ||
+ strncmp (ROMId, "Y9 ", 3) == 0 ||
+ // Panic Bomber World
+ strncmp (ROMId, "APB", 3) == 0 ||
+ ((strncmp (ROMName, "Parlor", 6) == 0 ||
+ strcmp (ROMName, "HEIWA Parlor!Mini8") == 0 ||
+ strncmp (ROMName, "SANKYO Fever! ̨°ÊÞ°!", 21) == 0) &&
+ strcmp (CompanyId, "A0") == 0) ||
+ strcmp (ROMName, "DARK KINGDOM") == 0 ||
+ strcmp (ROMName, "ZAN3 SFC") == 0 ||
+ strcmp (ROMName, "HIOUDEN") == 0 ||
+ strcmp (ROMName, "ÃݼɳÀ") == 0 || //Tenshi no Uta
+ strcmp (ROMName, "FORTUNE QUEST") == 0 ||
+ strcmp (ROMName, "FISHING TO BASSING") == 0 ||
+ strncmp (ROMName, "TokyoDome '95Battle 7", 21) == 0 ||
+ strcmp (ROMName, "OHMONO BLACKBASS") == 0 ||
+ strncmp (ROMName, "SWORD WORLD SFC", 15) == 0 ||
+ strcmp (ROMName, "MASTERS") ==0 || //Augusta 2 J
+ strcmp (ROMName, "SFC ¶ÒÝײÀÞ°") == 0 || //Kamen Rider
+ strncmp (ROMName, "LETs PACHINKO(", 14) == 0) //A set of BS games
+ {
+ IAPU.OneCycle = 15;
+ }
+
+
+ //Specific game fixes
+
+ Settings.StarfoxHack = strcmp (ROMName, "STAR FOX") == 0 ||
+ strcmp (ROMName, "STAR WING") == 0;
+ Settings.WinterGold = strcmp (ROMName, "FX SKIING NINTENDO 96") == 0 ||
+ strcmp (ROMName, "DIRT RACER") == 0 ||
+ Settings.StarfoxHack;
+
+
+ if((strcmp(ROMName, "LEGEND")==0&&!Settings.PAL)||
+ strcmp(ROMName, "King Arthurs World")==0)
+ {
+ SNESGameFixes.EchoOnlyOutput=TRUE;
+ }
+
+
+ Settings.DaffyDuck = (strcmp (ROMName, "DAFFY DUCK: MARV MISS") == 0) ||
+ (strcmp (ROMName, "ROBOCOP VS THE TERMIN") == 0) ||
+ (strcmp (ROMName, "ROBOCOP VS TERMINATOR") == 0); //ROBOCOP VS THE TERMIN
+ Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;
+
+ //OAM hacks because we don't fully understand the
+ //behavior of the SNES.
+
+ //Totally wacky display...
+ //seems to need a disproven behavior, so
+ //we're definitely overlooking some other bug?
+ if(strncmp(ROMName, "UNIRACERS", 9)==0)
+ SNESGameFixes.Uniracers=true;
+
+
+ //is this even useful now?
+ if (strcmp (ROMName, "ALIENS vs. PREDATOR") == 0)
+ SNESGameFixes.alienVSpredetorFix = TRUE;
+
+ if (strcmp (ROMName, "½°Ȩ̂߰нÀ") == 0 || //Super Famista
+ strcmp (ROMName, "½°Ȩ̂߰нÀ 2") == 0 || //Super Famista 2
+ strcmp (ROMName, "ZENKI TENCHIMEIDOU") == 0 ||
+ strcmp (ROMName, "GANBA LEAGUE") == 0)
+ {
+ SNESGameFixes.APU_OutPorts_ReturnValueFix = TRUE;
+ }
+
+ if (strcmp (ROMName, "FURAI NO SIREN") == 0)
+ SNESGameFixes.SoundEnvelopeHeightReading2 = TRUE;
+
+ //CPU timing hacks
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE *
+ Settings.CyclesPercentage) / 100;
+
+ //no need to ifdef for right now...
+//#ifdef HDMA_HACKS
+
+ // A Couple of HDMA related hacks - Lantus
+ if ((strcmp(ROMName, "SFX SUPERBUTOUDEN2")==0) ||
+ (strcmp(ROMName, "ALIEN vs. PREDATOR")==0) ||
+ (strcmp(ROMName, "STONE PROTECTORS")==0) ||
+ (strcmp(ROMName, "SUPER BATTLETANK 2")==0))
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 130) / 100;
+
+ if(strcmp(ROMName, "HOME IMPROVEMENT")==0)
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 200) / 100;
+
+ // End HDMA hacks
+//#endif
+
+
+ if (strcmp (ROMId, "ASRJ") == 0 && Settings.CyclesPercentage == 100)
+ // Street Racer
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 95) / 100;
+
+ // Power Rangers Fight
+ if (strncmp (ROMId, "A3R", 3) == 0 ||
+ // Clock Tower
+ strncmp (ROMId, "AJE", 3) == 0)
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 103) / 100;
+
+
+ if (strncmp (ROMId, "A3M", 3) == 0 && Settings.CyclesPercentage == 100)
+ // Mortal Kombat 3. Fixes cut off speech sample
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100;
+
+ //Darkness Beyond Twilight
+ //Crimson beyond blood that flows
+ //buried in the stream of time
+ //is where your power grows
+ //I pledge myself to conquer
+ //all the foes who stand
+ //before the might gift betsowed
+ //in my unworthy hand
+ if (strcmp (ROMName, "\x0bd\x0da\x0b2\x0d4\x0b0\x0bd\x0de") == 0 &&
+ Settings.CyclesPercentage == 100)
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 101) / 100;
+
+
+#ifdef DETECT_NASTY_FX_INTERLEAVE
+//XXX: Test without these. Win32 port indicates they aren't needed?
+//Apparently are needed!
+ if (strcmp (ROMName, "WILD TRAX") == 0 ||
+ strcmp (ROMName, "STAR FOX 2") == 0 ||
+ strcmp (ROMName, "YOSSY'S ISLAND") == 0 ||
+ strcmp (ROMName, "YOSHI'S ISLAND") == 0)
+ CPU.TriedInterleavedMode2 = TRUE;
+#endif
+
+ // Start Trek: Deep Sleep 9
+ if (strncmp (ROMId, "A9D", 3) == 0 && Settings.CyclesPercentage == 100)
+ Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100;
+
+
+ //SA-1 Speedup settings
+ SA1.WaitAddress = NULL;
+ SA1.WaitByteAddress1 = NULL;
+ SA1.WaitByteAddress2 = NULL;
+
+ /* Bass Fishing */
+ if (strcmp (ROMId, "ZBPJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0093f1 >> MEMMAP_SHIFT] + 0x93f1;
+ SA1.WaitByteAddress1 = FillRAM + 0x304a;
+ }
+ /* DAISENRYAKU EXPERTWW2 */
+ if (strcmp (ROMId, "AEVJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0ed18d >> MEMMAP_SHIFT] + 0xd18d;
+ SA1.WaitByteAddress1 = FillRAM + 0x3000;
+ }
+ /* debjk2 */
+ if (strcmp (ROMId, "A2DJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x008b62 >> MEMMAP_SHIFT] + 0x8b62;
+ }
+ /* Dragon Ballz HD */
+ if (strcmp (ROMId, "AZIJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x008083 >> MEMMAP_SHIFT] + 0x8083;
+ SA1.WaitByteAddress1 = FillRAM + 0x3020;
+ }
+ /* SFC SDGUNDAMGNEXT */
+ if (strcmp (ROMId, "ZX3J") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0087f2 >> MEMMAP_SHIFT] + 0x87f2;
+ SA1.WaitByteAddress1 = FillRAM + 0x30c4;
+ }
+ /* ShougiNoHanamichi */
+ if (strcmp (ROMId, "AARJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc1f85a >> MEMMAP_SHIFT] + 0xf85a;
+ SA1.WaitByteAddress1 = SRAM + 0x0c64;
+ SA1.WaitByteAddress2 = SRAM + 0x0c66;
+ }
+ /* KATO HIFUMI9DAN SYOGI */
+ if (strcmp (ROMId, "A23J") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc25037 >> MEMMAP_SHIFT] + 0x5037;
+ SA1.WaitByteAddress1 = SRAM + 0x0c06;
+ SA1.WaitByteAddress2 = SRAM + 0x0c08;
+ }
+ /* idaten */
+ if (strcmp (ROMId, "AIIJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc100be >> MEMMAP_SHIFT] + 0x00be;
+ SA1.WaitByteAddress1 = SRAM + 0x1002;
+ SA1.WaitByteAddress2 = SRAM + 0x1004;
+ }
+ /* igotais */
+ if (strcmp (ROMId, "AITJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0080b7 >> MEMMAP_SHIFT] + 0x80b7;
+ }
+ /* J96 DREAM STADIUM */
+ if (strcmp (ROMId, "AJ6J") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc0f74a >> MEMMAP_SHIFT] + 0xf74a;
+ }
+ /* JumpinDerby */
+ if (strcmp (ROMId, "AJUJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00d926 >> MEMMAP_SHIFT] + 0xd926;
+ }
+ /* JKAKINOKI SHOUGI */
+ if (strcmp (ROMId, "AKAJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00f070 >> MEMMAP_SHIFT] + 0xf070;
+ }
+ /* HOSHI NO KIRBY 3 & KIRBY'S DREAM LAND 3 JAP & US */
+ if (strcmp (ROMId, "AFJJ") == 0 || strcmp (ROMId, "AFJE") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0082d4 >> MEMMAP_SHIFT] + 0x82d4;
+ SA1.WaitByteAddress1 = SRAM + 0x72a4;
+ }
+ /* KIRBY SUPER DELUXE JAP */
+ if (strcmp (ROMId, "AKFJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x008c93 >> MEMMAP_SHIFT] + 0x8c93;
+ SA1.WaitByteAddress1 = FillRAM + 0x300a;
+ SA1.WaitByteAddress2 = FillRAM + 0x300e;
+ }
+ /* KIRBY SUPER DELUXE US */
+ if (strcmp (ROMId, "AKFE") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x008cb8 >> MEMMAP_SHIFT] + 0x8cb8;
+ SA1.WaitByteAddress1 = FillRAM + 0x300a;
+ SA1.WaitByteAddress2 = FillRAM + 0x300e;
+ }
+ /* SUPER MARIO RPG JAP & US */
+ if (strcmp (ROMId, "ARWJ") == 0 || strcmp (ROMId, "ARWE") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc0816f >> MEMMAP_SHIFT] + 0x816f;
+ SA1.WaitByteAddress1 = FillRAM + 0x3000;
+ }
+ /* marvelous.zip */
+ if (strcmp (ROMId, "AVRJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0085f2 >> MEMMAP_SHIFT] + 0x85f2;
+ SA1.WaitByteAddress1 = FillRAM + 0x3024;
+ }
+ /* AUGUSTA3 MASTERS NEW */
+ if (strcmp (ROMId, "AO3J") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00dddb >> MEMMAP_SHIFT] + 0xdddb;
+ SA1.WaitByteAddress1 = FillRAM + 0x37b4;
+ }
+ /* OSHABERI PARODIUS */
+ if (strcmp (ROMId, "AJOJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x8084e5 >> MEMMAP_SHIFT] + 0x84e5;
+ }
+ /* PANIC BOMBER WORLD */
+ if (strcmp (ROMId, "APBJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00857a >> MEMMAP_SHIFT] + 0x857a;
+ }
+ /* PEBBLE BEACH NEW */
+ if (strcmp (ROMId, "AONJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00df33 >> MEMMAP_SHIFT] + 0xdf33;
+ SA1.WaitByteAddress1 = FillRAM + 0x37b4;
+ }
+ /* PGA EUROPEAN TOUR */
+ if (strcmp (ROMId, "AEPE") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700;
+ SA1.WaitByteAddress1 = FillRAM + 0x3102;
+ }
+ /* PGA TOUR 96 */
+ if (strcmp (ROMId, "A3GE") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700;
+ SA1.WaitByteAddress1 = FillRAM + 0x3102;
+ }
+ /* POWER RANGERS 4 */
+ if (strcmp (ROMId, "A4RE") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x009899 >> MEMMAP_SHIFT] + 0x9899;
+ SA1.WaitByteAddress1 = FillRAM + 0x3000;
+ }
+ /* PACHISURO PALUSUPE */
+ if (strcmp (ROMId, "AGFJ") == 0)
+ {
+ // Never seems to turn on the SA-1!
+ }
+ /* SD F1 GRAND PRIX */
+ if (strcmp (ROMId, "AGFJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x0181bc >> MEMMAP_SHIFT] + 0x81bc;
+ }
+ /* SHOUGI MARJONG */
+ if (strcmp (ROMId, "ASYJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00f2cc >> MEMMAP_SHIFT] + 0xf2cc;
+ SA1.WaitByteAddress1 = SRAM + 0x7ffe;
+ SA1.WaitByteAddress2 = SRAM + 0x7ffc;
+ }
+ /* shogisai2 */
+ if (strcmp (ROMId, "AX2J") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0x00d675 >> MEMMAP_SHIFT] + 0xd675;
+ }
+
+ /* SHINING SCORPION */
+ if (strcmp (ROMId, "A4WJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc048be >> MEMMAP_SHIFT] + 0x48be;
+ }
+ /* SHIN SHOUGI CLUB */
+ if (strcmp (ROMId, "AHJJ") == 0)
+ {
+ SA1.WaitAddress = SA1.Map [0xc1002a >> MEMMAP_SHIFT] + 0x002a;
+ SA1.WaitByteAddress1 = SRAM + 0x0806;
+ SA1.WaitByteAddress2 = SRAM + 0x0808;
+ }
+
+
+ //Other
+
+ // Additional game fixes by sanmaiwashi ...
+ if (strcmp (ROMName, "SFX ŲĶÞÝÀÞÑÓɶÞÀØ 1") == 0) //Gundam Knight Story
+ {
+ bytes0x2000 [0xb18] = 0x4c;
+ bytes0x2000 [0xb19] = 0x4b;
+ bytes0x2000 [0xb1a] = 0xea;
+ SNESGameFixes.SRAMInitialValue = 0x6b;
+ }
+
+
+ // HITOMI3
+ if (strcmp (ROMName, "HITOMI3") == 0)
+ {
+ Memory.SRAMSize = 1;
+ SRAMMask = Memory.SRAMSize ?
+ ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0;
+ }
+
+ //sram value fixes
+ if (strcmp (Memory.ROMName, "SUPER DRIFT OUT") == 0 ||
+ strcmp(Memory.ROMName, "SATAN IS OUR FATHER!") == 0 ||
+ strcmp (ROMName, "goemon 4") == 0)
+ SNESGameFixes.SRAMInitialValue = 0x00;
+
+#if 0
+ if(strcmp (ROMName, "XBAND JAPANESE MODEM") == 0)
+ {
+ for (c = 0x200; c < 0x400; c += 16)
+ {
+ for (int i = c; i < c + 16; i++)
+ {
+ Map [i + 0x400] = Map [i + 0xc00] = &ROM[c * 0x1000];
+ BlockIsRAM [i + 0x400] = BlockIsRAM [i + 0xc00] = TRUE;
+ BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = FALSE;
+ }
+ }
+ WriteProtectROM ();
+ }
+#endif
+
+#define RomPatch(adr,ov,nv) \
+ if (ROM [adr] == ov) \
+ ROM [adr] = nv
+
+
+ // Love Quest
+ if (strcmp (ROMName, "LOVE QUEST") == 0)
+ {
+ RomPatch (0x1385ec, 0xd0, 0xea);
+ RomPatch (0x1385ed, 0xb2, 0xea);
+ }
+ //BNE D0 into nops
+
+ //seems like the next instruction is a BRA
+ //otherwise, this one's too complex for MKendora
+ // Nangoku Syonen Papuwa Kun
+ if (strcmp (ROMName, "NANGOKUSYONEN PAPUWA") == 0)
+ RomPatch (0x1f0d1, 0xa0, 0x6b);
+ //turns an LDY into an RTL?
+
+ //this is a cmp on $00:2140
+ // Super Batter Up
+ if (strcmp (ROMName, "Super Batter Up") == 0)
+ {
+ RomPatch (0x27ae0, 0xd0, 0xea);
+ RomPatch (0x27ae1, 0xfa, 0xea);
+ }
+ //BNE
+}
+
+// Read variable size MSB int from a file
+static long ReadInt (FILE *f, unsigned nbytes)
+{
+ long v = 0;
+ while (nbytes--)
+ {
+ int c = fgetc(f);
+ if (c == EOF)
+ return -1;
+ v = (v << 8) | (c & 0xFF);
+ }
+ return (v);
+}
+
+#define IPS_EOF 0x00454F46l
+
+void CMemory::CheckForIPSPatch (const char *rom_filename, bool8 header,
+ int32 &rom_size)
+{
+ char dir [_MAX_DIR + 1];
+ char drive [_MAX_DRIVE + 1];
+ char name [_MAX_FNAME + 1];
+ char ext [_MAX_EXT + 1];
+ char fname [_MAX_PATH + 1];
+ FILE *patch_file = NULL;
+ long offset = header ? 512 : 0;
+
+ _splitpath (rom_filename, drive, dir, name, ext);
+ _makepath (fname, drive, dir, name, "ips");
+
+ if (!(patch_file = fopen (fname, "rb")))
+ {
+ if (!(patch_file = fopen (S9xGetFilename (".ips"), "rb")))
+ return;
+ }
+
+ if (fread ((unsigned char*)fname, 1, 5, patch_file) != 5 ||
+ strncmp (fname, "PATCH", 5) != 0)
+ {
+ fclose (patch_file);
+ return;
+ }
+
+ int32 ofs;
+
+ for (;;)
+ {
+ long len;
+ long rlen;
+ int rchar;
+
+ ofs = ReadInt (patch_file, 3);
+ if (ofs == -1)
+ goto err_eof;
+
+ if (ofs == IPS_EOF)
+ break;
+
+ ofs -= offset;
+
+ len = ReadInt (patch_file, 2);
+ if (len == -1)
+ goto err_eof;
+
+ /* Apply patch block */
+ if (len)
+ {
+ if (ofs + len > MAX_ROM_SIZE)
+ goto err_eof;
+
+ while (len--)
+ {
+ rchar = fgetc (patch_file);
+ if (rchar == EOF)
+ goto err_eof;
+ ROM [ofs++] = (uint8) rchar;
+ }
+ if (ofs > rom_size)
+ rom_size = ofs;
+ }
+ else
+ {
+ rlen = ReadInt (patch_file, 2);
+ if (rlen == -1)
+ goto err_eof;
+
+ rchar = fgetc (patch_file);
+ if (rchar == EOF)
+ goto err_eof;
+
+ if (ofs + rlen > MAX_ROM_SIZE)
+ goto err_eof;
+
+ while (rlen--)
+ ROM [ofs++] = (uint8) rchar;
+
+ if (ofs > rom_size)
+ rom_size = ofs;
+ }
+ }
+
+ // Check if ROM image needs to be truncated
+ ofs = ReadInt (patch_file, 3);
+ if (ofs != -1 && ofs - offset < rom_size)
+ {
+ // Need to truncate ROM image
+ rom_size = ofs - offset;
+ }
+ fclose (patch_file);
+ return;
+
+err_eof:
+ if (patch_file)
+ fclose (patch_file);
+}
+
+int is_bsx(unsigned char *p)
+{
+ unsigned c;
+
+ if ( p[0x19] & 0x4f )
+ goto notbsx;
+ c = p[0x1a];
+ if ( (c != 0x33) && (c != 0xff) ) // 0x33 = Manufacturer: Nintendo
+ goto notbsx;
+ c = (p[0x17] << 8) | p[0x16];
+ if ( (c != 0x0000) && (c != 0xffff) )
+ {
+ if ( (c & 0x040f) != 0 )
+ goto notbsx;
+ if ( (c & 0xff) > 0xc0 )
+ goto notbsx;
+ }
+ c = p[0x18];
+ if ( (c & 0xce) || ((c & 0x30)==0) )
+ goto notbsx;
+ if ( (p[0x15] & 0x03) != 0 )
+ goto notbsx;
+ c = p[0x13];
+ if ( (c != 0x00) && (c != 0xff) )
+ goto notbsx;
+ if ( p[0x14] != 0x00 )
+ goto notbsx;
+ if ( bs_name(p) != 0 )
+ goto notbsx;
+ return 0; // It's a Satellaview ROM!
+notbsx:
+ return -1;
+}
+int bs_name(unsigned char *p)
+{
+ unsigned c;
+ int lcount;
+ int numv; // number of valid name characters seen so far
+ numv = 0;
+ for ( lcount = 16; lcount > 0; lcount-- )
+ {
+ if ( check_char( c = *p++ ) != 0 )
+ {
+ c = *p++;
+ if ( c < 0x20 )
+ {
+ if ( (numv != 0x0b) || (c != 0) ) // Dr. Mario Hack
+ goto notBsName;
+ }
+
+ numv++;
+ lcount--;
+ continue;
+ }
+ else
+ {
+ if ( c == 0 )
+ {
+ if ( numv == 0 )
+ goto notBsName;
+ continue;
+ }
+
+ if ( c < 0x20 )
+ goto notBsName;
+ if ( c >= 0x80 )
+ {
+ if ( (c < 0xa0) || ( c >= 0xf0 ) )
+ goto notBsName;
+ }
+ numv++;
+ }
+ }
+ if ( numv > 0 )
+ return 0;
+notBsName:
+ return -1;
+}
+int check_char(unsigned c)
+{
+ if ( ( c & 0x80 ) == 0 )
+ return 0;
+ if ( ( c - 0x20 ) & 0x40 )
+ return 1;
+ else
+ return 0;
+}
+
+void CMemory::ParseSNESHeader(uint8* RomHeader)
+{
+ Memory.SRAMSize = RomHeader [0x28];
+ strncpy (ROMName, (char *) &RomHeader[0x10], ROM_NAME_LEN - 1);
+ ROMSpeed = RomHeader [0x25];
+ ROMType = RomHeader [0x26];
+ ROMSize = RomHeader [0x27];
+ ROMChecksum = RomHeader [0x2e] + (RomHeader [0x2f] << 8);
+ ROMComplementChecksum = RomHeader [0x2c] + (RomHeader [0x2d] << 8);
+ ROMRegion= RomHeader[0x29];
+ memmove (ROMId, &RomHeader [0x2], 4);
+ if(RomHeader[0x2A]==0x33)
+ memmove (CompanyId, &RomHeader [0], 2);
+ else sprintf(CompanyId, "%02X", RomHeader[0x2A]);
+}
+
+#undef INLINE
+#define INLINE
+#include "getset.h"
+
diff --git a/source/memmap.h b/source/memmap.h
new file mode 100644
index 0000000..58f0c9f
--- /dev/null
+++ b/source/memmap.h
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _memmap_h_
+#define _memmap_h_
+
+#include "snes9x.h"
+
+#ifdef FAST_LSB_WORD_ACCESS
+#define READ_WORD(s) (*(uint16 *) (s))
+#define READ_DWORD(s) (*(uint32 *) (s))
+#define WRITE_WORD(s, d) (*(uint16 *) (s)) = (d)
+#define WRITE_DWORD(s, d) (*(uint32 *) (s)) = (d)
+
+#define READ_3WORD(s) (0x00ffffff & *(uint32 *) (s))
+#define WRITE_3WORD(s, d) *(uint16 *) (s) = (uint16)(d),\
+ *((uint8 *) (s) + 2) = (uint8) ((d) >> 16)
+
+
+#else
+#define READ_WORD(s) ( *(uint8 *) (s) |\
+ (*((uint8 *) (s) + 1) << 8))
+#define READ_DWORD(s) ( *(uint8 *) (s) |\
+ (*((uint8 *) (s) + 1) << 8) |\
+ (*((uint8 *) (s) + 2) << 16) |\
+ (*((uint8 *) (s) + 3) << 24))
+#define WRITE_WORD(s, d) *(uint8 *) (s) = (d), \
+ *((uint8 *) (s) + 1) = (d) >> 8
+#define WRITE_DWORD(s, d) *(uint8 *) (s) = (uint8) (d), \
+ *((uint8 *) (s) + 1) = (uint8) ((d) >> 8),\
+ *((uint8 *) (s) + 2) = (uint8) ((d) >> 16),\
+ *((uint8 *) (s) + 3) = (uint8) ((d) >> 24)
+#define WRITE_3WORD(s, d) *(uint8 *) (s) = (uint8) (d), \
+ *((uint8 *) (s) + 1) = (uint8) ((d) >> 8),\
+ *((uint8 *) (s) + 2) = (uint8) ((d) >> 16)
+#define READ_3WORD(s) ( *(uint8 *) (s) |\
+ (*((uint8 *) (s) + 1) << 8) |\
+ (*((uint8 *) (s) + 2) << 16))
+#endif
+
+#define MEMMAP_BLOCK_SIZE (0x1000)
+#define MEMMAP_NUM_BLOCKS (0x1000000 / MEMMAP_BLOCK_SIZE)
+#define MEMMAP_BLOCKS_PER_BANK (0x10000 / MEMMAP_BLOCK_SIZE)
+#define MEMMAP_SHIFT 12
+#define MEMMAP_MASK (MEMMAP_BLOCK_SIZE - 1)
+#define MEMMAP_MAX_SDD1_LOGGED_ENTRIES (0x10000 / 8)
+
+//Extended ROM Formats
+#define NOPE 0
+#define YEAH 1
+#define BIGFIRST 2
+#define SMALLFIRST 3
+
+//File Formats go here
+#define ZIP 0
+#define RAR 1
+#define DEFAULT 2
+
+class CMemory {
+public:
+ bool8 LoadROM (const char *);
+ uint32 FileLoader (uint8* buffer, const char* filename, int32 maxsize);
+ void InitROM (bool8);
+ bool8 LoadSRAM (const char *);
+ bool8 SaveSRAM (const char *);
+ bool8 Init ();
+ void Deinit ();
+ void FreeSDD1Data ();
+
+ void WriteProtectROM ();
+ void FixROMSpeed ();
+ void MapRAM ();
+ void MapExtraRAM ();
+ char *Safe (const char *);
+
+ void BSLoROMMap();
+ void JumboLoROMMap (bool8);
+ void LoROMMap ();
+ void LoROM24MBSMap ();
+ void SRAM512KLoROMMap ();
+// void SRAM1024KLoROMMap ();
+ void SufamiTurboLoROMMap ();
+ void HiROMMap ();
+ void SuperFXROMMap ();
+ void TalesROMMap (bool8);
+ void AlphaROMMap ();
+ void SA1ROMMap ();
+ void BSHiROMMap ();
+ void SPC7110HiROMMap();
+ void SPC7110Sram(uint8);
+ void SetaDSPMap();
+ bool8 AllASCII (uint8 *b, int size);
+ int ScoreHiROM (bool8 skip_header, int32 offset=0);
+ int ScoreLoROM (bool8 skip_header, int32 offset=0);
+#if 0
+ void SufamiTurboAltROMMap();
+#endif
+ void ApplyROMFixes ();
+ void CheckForIPSPatch (const char *rom_filename, bool8 header,
+ int32 &rom_size);
+
+ const char *TVStandard ();
+ const char *Speed ();
+ const char *StaticRAMSize ();
+ const char *MapType ();
+ const char *MapMode ();
+ const char *KartContents ();
+ const char *Size ();
+ const char *Headers ();
+ const char *ROMID ();
+ const char *CompanyID ();
+ void ParseSNESHeader(uint8*);
+ enum {
+ MAP_PPU, MAP_CPU, MAP_DSP, MAP_LOROM_SRAM, MAP_HIROM_SRAM,
+ MAP_NONE, MAP_DEBUG, MAP_C4, MAP_BWRAM, MAP_BWRAM_BITMAP,
+ MAP_BWRAM_BITMAP2, MAP_SA1RAM, MAP_SPC7110_ROM, MAP_SPC7110_DRAM,
+ MAP_RONLY_SRAM, MAP_OBC_RAM, MAP_SETA_DSP, MAP_SETA_RISC, MAP_LAST
+ };
+ enum { MAX_ROM_SIZE = 0x800000 };
+
+ uint8 *RAM;
+ uint8 *ROM;
+ uint8 *VRAM;
+ uint8 *SRAM;
+ uint8 *BWRAM;
+ uint8 *FillRAM;
+ uint8 *C4RAM;
+ bool8 HiROM;
+ bool8 LoROM;
+ uint32 SRAMMask;
+ uint8 SRAMSize;
+ uint8 *Map [MEMMAP_NUM_BLOCKS];
+ uint8 *WriteMap [MEMMAP_NUM_BLOCKS];
+ uint8 MemorySpeed [MEMMAP_NUM_BLOCKS];
+ uint8 BlockIsRAM [MEMMAP_NUM_BLOCKS];
+ uint8 BlockIsROM [MEMMAP_NUM_BLOCKS];
+ char ROMName [ROM_NAME_LEN];
+ char ROMId [5];
+ char CompanyId [3];
+ uint8 ROMSpeed;
+ uint8 ROMType;
+ uint8 ROMSize;
+ int32 ROMFramesPerSecond;
+ int32 HeaderCount;
+ uint32 CalculatedSize;
+ uint32 CalculatedChecksum;
+ uint32 ROMChecksum;
+ uint32 ROMComplementChecksum;
+ uint8 *SDD1Index;
+ uint8 *SDD1Data;
+ uint32 SDD1Entries;
+ uint32 SDD1LoggedDataCountPrev;
+ uint32 SDD1LoggedDataCount;
+ uint8 SDD1LoggedData [MEMMAP_MAX_SDD1_LOGGED_ENTRIES];
+ char ROMFilename [_MAX_PATH];
+ uint8 ROMRegion;
+ uint32 ROMCRC32;
+ uint8 ExtendedFormat;
+#if 0
+ bool8 SufamiTurbo;
+ char Slot1Filename [_MAX_PATH];
+ char Slot2Filename [_MAX_PATH];
+ uint8* ROMOffset1;
+ uint8* ROMOffset2;
+ uint8* SRAMOffset1;
+ uint8* SRAMOffset2;
+ uint32 Slot1Size;
+ uint32 Slot2Size;
+ uint32 Slot1SRAMSize;
+ uint32 Slot2SRAMSize;
+ uint8 SlotContents;
+#endif
+ uint8 *BSRAM;
+ void ResetSpeedMap();
+#if 0
+ bool8 LoadMulti (const char *,const char *,const char *);
+#endif
+};
+
+START_EXTERN_C
+extern CMemory Memory;
+extern uint8 *SRAM;
+extern uint8 *ROM;
+extern uint8 *RegRAM;
+void S9xDeinterleaveMode2 ();
+bool8 LoadZip(const char* zipname,
+ int32 *TotalFileSize,
+ int32 *headers,
+ uint8 *buffer);
+END_EXTERN_C
+
+extern "C" {
+void S9xAutoSaveSRAM ();
+}
+
+#ifdef NO_INLINE_SET_GET
+uint8 S9xGetByte (uint32 Address);
+uint16 S9xGetWord (uint32 Address);
+void S9xSetByte (uint8 Byte, uint32 Address);
+void S9xSetWord (uint16 Byte, uint32 Address);
+void S9xSetPCBase (uint32 Address);
+uint8 *S9xGetMemPointer (uint32 Address);
+uint8 *GetBasePointer (uint32 Address);
+
+extern "C"{
+extern uint8 OpenBus;
+}
+#else
+#define INLINE inline
+#include "getset.h"
+#endif // NO_INLINE_SET_GET
+
+#endif // _memmap_h_
+
diff --git a/source/messages.h b/source/messages.h
new file mode 100644
index 0000000..1f85576
--- /dev/null
+++ b/source/messages.h
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _messages_h_
+#define _messages_h_
+
+/* Types of message sent to S9xMessage routine */
+enum {
+ S9X_TRACE,
+ S9X_DEBUG,
+ S9X_WARNING,
+ S9X_INFO,
+ S9X_ERROR,
+ S9X_FATAL_ERROR
+};
+
+/* Individual message numbers */
+enum {
+ S9X_ROM_INFO,
+ S9X_HEADERS_INFO,
+ S9X_ROM_CONFUSING_FORMAT_INFO,
+ S9X_ROM_INTERLEAVED_INFO,
+ S9X_SOUND_DEVICE_OPEN_FAILED,
+ S9X_APU_STOPPED,
+ S9X_USAGE,
+ S9X_GAME_GENIE_CODE_ERROR,
+ S9X_ACTION_REPLY_CODE_ERROR,
+ S9X_GOLD_FINGER_CODE_ERROR,
+ S9X_DEBUG_OUTPUT,
+ S9X_DMA_TRACE,
+ S9X_HDMA_TRACE,
+ S9X_WRONG_FORMAT,
+ S9X_WRONG_VERSION,
+ S9X_ROM_NOT_FOUND,
+ S9X_FREEZE_FILE_NOT_FOUND,
+ S9X_PPU_TRACE,
+ S9X_TRACE_DSP1,
+ S9X_FREEZE_ROM_NAME,
+ S9X_HEADER_WARNING,
+ S9X_NETPLAY_NOT_SERVER,
+ S9X_FREEZE_FILE_INFO,
+ S9X_TURBO_MODE,
+ S9X_SOUND_NOT_BUILT,
+ S9X_MOVIE_INFO,
+ S9X_WRONG_MOVIE_SNAPSHOT,
+ S9X_NOT_A_MOVIE_SNAPSHOT,
+ S9X_AVI_INFO
+};
+
+#endif
+
diff --git a/source/missing.h b/source/missing.h
new file mode 100644
index 0000000..66ca71e
--- /dev/null
+++ b/source/missing.h
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _MISSING_H_
+#define _MISSING_H_
+
+struct HDMA
+{
+ uint8 used;
+ uint8 bbus_address;
+ uint8 abus_bank;
+ uint16 abus_address;
+ uint8 indirect_address;
+ uint8 force_table_address_write;
+ uint8 force_table_address_read;
+ uint8 line_count_write;
+ uint8 line_count_read;
+};
+
+struct Missing
+{
+ uint8 emulate6502;
+ uint8 decimal_mode;
+ uint8 mv_8bit_index;
+ uint8 mv_8bit_acc;
+ uint8 interlace;
+ uint8 lines_239;
+ uint8 pseudo_512;
+ struct HDMA hdma [8];
+ uint8 modes [8];
+ uint8 mode7_fx;
+ uint8 mode7_flip;
+ uint8 mode7_bgmode;
+ uint8 direct;
+ uint8 matrix_multiply;
+ uint8 oam_read;
+ uint8 vram_read;
+ uint8 cgram_read;
+ uint8 wram_read;
+ uint8 dma_read;
+ uint8 vram_inc;
+ uint8 vram_full_graphic_inc;
+ uint8 virq;
+ uint8 hirq;
+ uint16 virq_pos;
+ uint16 hirq_pos;
+ uint8 h_v_latch;
+ uint8 h_counter_read;
+ uint8 v_counter_read;
+ uint8 fast_rom;
+ uint8 window1 [6];
+ uint8 window2 [6];
+ uint8 sprite_priority_rotation;
+ uint8 subscreen;
+ uint8 subscreen_add;
+ uint8 subscreen_sub;
+ uint8 fixed_colour_add;
+ uint8 fixed_colour_sub;
+ uint8 mosaic;
+ uint8 sprite_double_height;
+ uint8 dma_channels;
+ uint8 dma_this_frame;
+ uint8 oam_address_read;
+ uint8 bg_offset_read;
+ uint8 matrix_read;
+ uint8 hdma_channels;
+ uint8 hdma_this_frame;
+ uint16 unknownppu_read;
+ uint16 unknownppu_write;
+ uint16 unknowncpu_read;
+ uint16 unknowncpu_write;
+ uint16 unknowndsp_read;
+ uint16 unknowndsp_write;
+};
+
+EXTERN_C struct Missing missing;
+#endif
+
diff --git a/source/movie.cpp b/source/movie.cpp
new file mode 100644
index 0000000..9156a48
--- /dev/null
+++ b/source/movie.cpp
@@ -0,0 +1,779 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+ Input recording/playback code
+ (c) Copyright 2004 blip
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+
+#if defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <time.h>
+
+#ifdef __WIN32__
+#include <io.h>
+#ifndef W_OK
+#define W_OK 2
+#endif
+#endif
+
+#include "movie.h"
+#include "snes9x.h"
+#include "cpuexec.h"
+#include "snapshot.h"
+
+#define SMV_MAGIC 0x1a564d53 // SMV0x1a
+#define SMV_VERSION 1
+#define SMV_HEADER_SIZE 32
+#define CONTROLLER_DATA_SIZE 2
+#define BUFFER_GROWTH_SIZE 4096
+
+enum MovieState
+{
+ MOVIE_STATE_NONE=0,
+ MOVIE_STATE_PLAY,
+ MOVIE_STATE_RECORD
+};
+
+static struct SMovie
+{
+ enum MovieState State;
+ char Filename [_MAX_PATH];
+ FILE* File;
+ uint32 SaveStateOffset;
+ uint32 ControllerDataOffset;
+ uint32 MovieId;
+ uint32 CurrentFrame;
+ uint32 MaxFrame;
+ uint32 RerecordCount;
+ uint8 ControllersMask;
+ uint8 Opts;
+ bool8 ReadOnly;
+ uint32 BytesPerFrame;
+ uint8* InputBuffer;
+ uint32 InputBufferSize;
+ uint8* InputBufferPtr;
+ bool8 FrameDisplay;
+ char FrameDisplayString[256];
+} Movie;
+
+/*
+ For illustration:
+struct MovieFileHeader
+{
+ uint32 magic; // SMV0x1a
+ uint32 version;
+ uint32 uid; // used to match savestates to a particular movie
+ uint32 rerecord_count;
+ uint32 length_frames;
+ uint8 flags[4];
+ uint32 offset_to_savestate; // smvs have an embedded savestate
+ uint32 offset_to_controller_data;
+ // after the header comes extra metadata
+ // sizeof(metadata) = offset_to_savestate - sizeof(MovieFileHeader)
+};
+*/
+
+static int bytes_per_frame()
+{
+ int i;
+ int num_controllers;
+
+ num_controllers=0;
+ for(i=0; i<5; ++i)
+ {
+ if(Movie.ControllersMask & (1<<i))
+ {
+ ++num_controllers;
+ }
+ }
+
+ return CONTROLLER_DATA_SIZE*num_controllers;
+}
+
+static inline uint32 Read32(const uint8*& ptr)
+{
+ uint32 v=(ptr[0] | (ptr[1]<<8) | (ptr[2]<<16) | (ptr[3]<<24));
+ ptr += 4;
+ return v;
+}
+
+static inline uint16 Read16(const uint8*& ptr) /* const version */
+{
+ uint16 v=(ptr[0] | (ptr[1]<<8));
+ ptr += 2;
+ return v;
+}
+
+static inline uint16 Read16(uint8*& ptr) /* non-const version */
+{
+ uint16 v=(ptr[0] | (ptr[1]<<8));
+ ptr += 2;
+ return v;
+}
+
+static void Write32(uint32 v, uint8*& ptr)
+{
+ ptr[0]=(uint8)(v&0xff);
+ ptr[1]=(uint8)((v>>8)&0xff);
+ ptr[2]=(uint8)((v>>16)&0xff);
+ ptr[3]=(uint8)((v>>24)&0xff);
+ ptr += 4;
+}
+
+static void Write16(uint16 v, uint8*& ptr)
+{
+ ptr[0]=(uint8)(v&0xff);
+ ptr[1]=(uint8)((v>>8)&0xff);
+ ptr += 2;
+}
+
+static int read_movie_header(FILE* fd, SMovie* movie)
+{
+ uint8 header[SMV_HEADER_SIZE];
+ if(fread(header, 1, SMV_HEADER_SIZE, fd) != SMV_HEADER_SIZE)
+ return WRONG_FORMAT;
+
+ const uint8* ptr=header;
+ uint32 magic=Read32(ptr);
+ if(magic!=SMV_MAGIC)
+ return WRONG_FORMAT;
+
+ uint32 version=Read32(ptr);
+ if(version!=SMV_VERSION)
+ return WRONG_VERSION;
+
+ movie->MovieId=Read32(ptr);
+ movie->RerecordCount=Read32(ptr);
+ movie->MaxFrame=Read32(ptr);
+
+ movie->ControllersMask=*ptr++;
+ movie->Opts=*ptr++;
+ ptr += 2;
+
+ movie->SaveStateOffset=Read32(ptr);
+ movie->ControllerDataOffset=Read32(ptr);
+
+ return SUCCESS;
+}
+
+static void write_movie_header(FILE* fd, const SMovie* movie)
+{
+ uint8 header[SMV_HEADER_SIZE];
+ uint8* ptr=header;
+
+ Write32(SMV_MAGIC, ptr);
+ Write32(SMV_VERSION, ptr);
+ Write32(movie->MovieId, ptr);
+ Write32(movie->RerecordCount, ptr);
+ Write32(movie->MaxFrame, ptr);
+
+ *ptr++=movie->ControllersMask;
+ *ptr++=movie->Opts;
+ *ptr++=0;
+ *ptr++=0;
+
+ Write32(movie->SaveStateOffset, ptr);
+ Write32(movie->ControllerDataOffset, ptr);
+
+ fwrite(header, 1, SMV_HEADER_SIZE, fd);
+}
+
+static void flush_movie()
+{
+ fseek(Movie.File, 0, SEEK_SET);
+ write_movie_header(Movie.File, &Movie);
+ fseek(Movie.File, Movie.ControllerDataOffset, SEEK_SET);
+ fwrite(Movie.InputBuffer, 1, Movie.BytesPerFrame*(Movie.MaxFrame+1), Movie.File);
+}
+
+static void change_state(MovieState new_state)
+{
+ if(new_state==Movie.State)
+ return;
+
+ if(Movie.State==MOVIE_STATE_RECORD)
+ {
+ flush_movie();
+ }
+
+ Movie.State=new_state;
+
+ if(new_state==MOVIE_STATE_NONE)
+ {
+ fclose(Movie.File);
+ Movie.File=NULL;
+ // FIXME: truncate movie to MaxFrame length
+ /* truncate() could be used, if it's certain
+ * that the savestate block is never after
+ * the controller data block. It is not guaranteed
+ * by the format.
+ */
+ }
+}
+
+static void reserve_buffer_space(uint32 space_needed)
+{
+ if(space_needed > Movie.InputBufferSize)
+ {
+ uint32 ptr_offset = Movie.InputBufferPtr - Movie.InputBuffer;
+ uint32 alloc_chunks = space_needed / BUFFER_GROWTH_SIZE;
+ Movie.InputBufferSize = BUFFER_GROWTH_SIZE * (alloc_chunks+1);
+ Movie.InputBuffer = (uint8*)realloc(Movie.InputBuffer, Movie.InputBufferSize);
+ Movie.InputBufferPtr = Movie.InputBuffer + ptr_offset;
+ }
+}
+
+static void read_frame_controller_data()
+{
+ int i;
+ for(i=0; i<5; ++i)
+ {
+ if(Movie.ControllersMask & (1<<i))
+ {
+ IPPU.Joypads[i]=(uint32)(Read16(Movie.InputBufferPtr)) | 0x80000000L;
+ }
+ else
+ {
+ IPPU.Joypads[i]=0; // pretend the controller is disconnected
+ }
+ }
+}
+
+static void write_frame_controller_data()
+{
+ reserve_buffer_space((uint32)((Movie.InputBufferPtr+Movie.BytesPerFrame)-Movie.InputBuffer));
+
+ int i;
+ for(i=0; i<5; ++i)
+ {
+ if(Movie.ControllersMask & (1<<i))
+ {
+ Write16((uint16)(IPPU.Joypads[i] & 0xffff), Movie.InputBufferPtr);
+ }
+ else
+ {
+ IPPU.Joypads[i]=0; // pretend the controller is disconnected
+ }
+ }
+}
+
+void S9xMovieInit ()
+{
+ memset(&Movie, 0, sizeof(Movie));
+ Movie.State = MOVIE_STATE_NONE;
+}
+
+int S9xMovieOpen (const char* filename, bool8 read_only)
+{
+ return FILE_NOT_FOUND;
+#if 0
+ FILE* fd;
+ STREAM stream;
+ int result;
+ int fn;
+
+ if(!(fd=fopen(filename, read_only ? "rb" : "rb+")))
+ return FILE_NOT_FOUND;
+
+ // stop current movie before opening
+ change_state(MOVIE_STATE_NONE);
+
+ // read header
+ if((result=read_movie_header(fd, &Movie))!=SUCCESS)
+ {
+ fclose(fd);
+ return result;
+ }
+
+ fn=dup(fileno(fd));
+ fclose(fd);
+
+ // apparently this lseek is necessary
+ lseek(fn, Movie.SaveStateOffset, SEEK_SET);
+ if(!(stream=REOPEN_STREAM(fn, "rb")))
+ return FILE_NOT_FOUND;
+
+ if(Movie.Opts & MOVIE_OPT_FROM_RESET)
+ {
+ S9xReset();
+ // save only SRAM for a from-reset snapshot
+ result=(READ_STREAM(SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT;
+ }
+ else
+ {
+ result=S9xUnfreezeFromStream(stream);
+ }
+ CLOSE_STREAM(stream);
+
+ if(result!=SUCCESS)
+ {
+ return result;
+ }
+
+ if(!(fd=fopen(filename, read_only ? "rb" : "rb+")))
+ return FILE_NOT_FOUND;
+
+ if(fseek(fd, Movie.ControllerDataOffset, SEEK_SET))
+ return WRONG_FORMAT;
+
+ // read controller data
+ Movie.File=fd;
+ Movie.BytesPerFrame=bytes_per_frame();
+ Movie.InputBufferPtr=Movie.InputBuffer;
+ uint32 to_read=Movie.BytesPerFrame * (Movie.MaxFrame+1);
+ reserve_buffer_space(to_read);
+ fread(Movie.InputBufferPtr, 1, to_read, fd);
+
+ // read "baseline" controller data
+ read_frame_controller_data();
+
+ strncpy(Movie.Filename, filename, _MAX_PATH);
+ Movie.Filename[_MAX_PATH-1]='\0';
+ Movie.CurrentFrame=0;
+ Movie.ReadOnly=read_only;
+ change_state(MOVIE_STATE_PLAY);
+
+ S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY);
+ return SUCCESS;
+#endif
+}
+
+int S9xMovieCreate (const char* filename, uint8 controllers_mask, uint8 opts, const wchar_t* metadata, int metadata_length)
+{
+ return FILE_NOT_FOUND;
+#if 0
+ FILE* fd;
+ STREAM stream;
+ int fn;
+
+ if(controllers_mask==0)
+ return WRONG_FORMAT;
+
+ if(!(fd=fopen(filename, "wb")))
+ return FILE_NOT_FOUND;
+
+ // stop current movie before opening
+ change_state(MOVIE_STATE_NONE);
+
+ if(metadata_length>MOVIE_MAX_METADATA)
+ {
+ metadata_length=MOVIE_MAX_METADATA;
+ }
+
+ Movie.MovieId=(uint32)time(NULL);
+ Movie.RerecordCount=0;
+ Movie.MaxFrame=0;
+ Movie.SaveStateOffset=SMV_HEADER_SIZE+(sizeof(uint16)*metadata_length);
+ Movie.ControllerDataOffset=0;
+ Movie.ControllersMask=controllers_mask;
+ Movie.Opts=opts;
+ if(Settings.PAL)
+ {
+ Movie.Opts |= MOVIE_OPT_PAL;
+ }
+ else
+ {
+ Movie.Opts &= ~MOVIE_OPT_PAL;
+ }
+
+ write_movie_header(fd, &Movie);
+
+ // convert wchar_t metadata string/array to a uint16 array
+ if(metadata_length>0)
+ {
+ uint8 meta_buf[MOVIE_MAX_METADATA * sizeof(uint16)];
+ int i;
+
+ for(i=0; i<metadata_length; ++i)
+ {
+ uint16 c=(uint16)metadata[i];
+ meta_buf[i+i] =(uint8)(c&0xff);
+ meta_buf[i+i+1]=(uint8)((c>>8)&0xff);
+ }
+
+ fwrite(meta_buf, sizeof(uint16), metadata_length, fd);
+ }
+
+ // write snapshot
+ fn=dup(fileno(fd));
+ fclose(fd);
+
+ // lseek(fn, Movie.SaveStateOffset, SEEK_SET);
+ if(!(stream=REOPEN_STREAM(fn, "ab")))
+ return FILE_NOT_FOUND;
+
+ if(opts & MOVIE_OPT_FROM_RESET)
+ {
+ S9xReset();
+ // save only SRAM for a from-reset snapshot
+ WRITE_STREAM(SRAM, 0x20000, stream);
+ }
+ else
+ {
+ S9xFreezeToStream(stream);
+ }
+ CLOSE_STREAM(stream);
+
+ if(!(fd=fopen(filename, "rb+")))
+ return FILE_NOT_FOUND;
+
+ fseek(fd, 0, SEEK_END);
+ Movie.ControllerDataOffset=(uint32)ftell(fd);
+
+ // write "baseline" controller data
+ Movie.File=fd;
+ Movie.BytesPerFrame=bytes_per_frame();
+ Movie.InputBufferPtr=Movie.InputBuffer;
+ write_frame_controller_data();
+
+ strncpy(Movie.Filename, filename, _MAX_PATH);
+ Movie.Filename[_MAX_PATH-1]='\0';
+ Movie.CurrentFrame=0;
+ Movie.ReadOnly=false;
+ change_state(MOVIE_STATE_RECORD);
+
+ S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_RECORD);
+ return SUCCESS;
+#endif
+}
+
+void S9xMovieUpdate ()
+{
+ switch(Movie.State)
+ {
+ case MOVIE_STATE_PLAY:
+ if(Movie.CurrentFrame>=Movie.MaxFrame)
+ {
+ change_state(MOVIE_STATE_NONE);
+ S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_END);
+ return;
+ }
+ else
+ {
+ if(Movie.FrameDisplay)
+ {
+ sprintf(Movie.FrameDisplayString, "Playing frame: %d", Movie.CurrentFrame);
+ S9xMessage (S9X_INFO, S9X_MOVIE_INFO, Movie.FrameDisplayString);
+ }
+ read_frame_controller_data();
+ ++Movie.CurrentFrame;
+ }
+ break;
+
+ case MOVIE_STATE_RECORD:
+ {
+ if(Movie.FrameDisplay)
+ {
+ sprintf(Movie.FrameDisplayString, "Recording frame: %d", Movie.CurrentFrame);
+ S9xMessage (S9X_INFO, S9X_MOVIE_INFO, Movie.FrameDisplayString);
+ }
+ write_frame_controller_data();
+ ++Movie.CurrentFrame;
+ Movie.MaxFrame=Movie.CurrentFrame;
+ fwrite((Movie.InputBufferPtr - Movie.BytesPerFrame), 1, Movie.BytesPerFrame, Movie.File);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void S9xMovieStop (bool8 suppress_message)
+{
+ if(Movie.State!=MOVIE_STATE_NONE)
+ {
+ change_state(MOVIE_STATE_NONE);
+
+ if(!suppress_message)
+ S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_STOP);
+ }
+}
+
+int S9xMovieGetInfo (const char* filename, struct MovieInfo* info)
+{
+ FILE* fd;
+ int result;
+ SMovie local_movie;
+ int metadata_length;
+
+ memset(info, 0, sizeof(*info));
+ if(!(fd=fopen(filename, "rb")))
+ return FILE_NOT_FOUND;
+
+ if((result=(read_movie_header(fd, &local_movie)))!=SUCCESS)
+ return result;
+
+ info->TimeCreated=(time_t)local_movie.MovieId;
+ info->LengthFrames=local_movie.MaxFrame;
+ info->RerecordCount=local_movie.RerecordCount;
+ info->Opts=local_movie.Opts;
+ info->ControllersMask=local_movie.ControllersMask;
+
+ if(local_movie.SaveStateOffset > SMV_HEADER_SIZE)
+ {
+ uint8 meta_buf[MOVIE_MAX_METADATA * sizeof(uint16)];
+ int i;
+
+ metadata_length=((int)local_movie.SaveStateOffset-SMV_HEADER_SIZE)/sizeof(uint16);
+ metadata_length=(metadata_length>=MOVIE_MAX_METADATA) ? MOVIE_MAX_METADATA-1 : metadata_length;
+ metadata_length=(int)fread(meta_buf, sizeof(uint16), metadata_length, fd);
+
+ for(i=0; i<metadata_length; ++i)
+ {
+ uint16 c=meta_buf[i+i] | (meta_buf[i+i+1] << 8);
+ info->Metadata[i]=(wchar_t)c;
+ }
+ info->Metadata[i]='\0';
+ }
+ else
+ {
+ info->Metadata[0]='\0';
+ }
+
+ fclose(fd);
+
+ if(access(filename, W_OK))
+ info->ReadOnly=true;
+
+ return SUCCESS;
+}
+
+bool8 S9xMovieActive ()
+{
+ return (Movie.State!=MOVIE_STATE_NONE);
+}
+
+bool8 S9xMovieReadOnly ()
+{
+ if(!S9xMovieActive())
+ return false;
+
+ return Movie.ReadOnly;
+}
+
+uint32 S9xMovieGetId ()
+{
+ if(!S9xMovieActive())
+ return 0;
+
+ return Movie.MovieId;
+}
+
+uint32 S9xMovieGetLength ()
+{
+ if(!S9xMovieActive())
+ return 0;
+
+ return Movie.MaxFrame;
+}
+
+uint32 S9xMovieGetFrameCounter ()
+{
+ if(!S9xMovieActive())
+ return 0;
+
+ return Movie.CurrentFrame;
+}
+
+void S9xMovieToggleFrameDisplay ()
+{
+ Movie.FrameDisplay = !Movie.FrameDisplay;
+ if(!Movie.FrameDisplay)
+ {
+ GFX.InfoStringTimeout = 1;
+ }
+}
+
+void S9xMovieFreeze (uint8** buf, uint32* size)
+{
+ // sanity check
+ if(!S9xMovieActive())
+ {
+ return;
+ }
+
+ *buf = NULL;
+ *size = 0;
+
+ // compute size needed for the buffer
+ uint32 size_needed = 4*3; // room for MovieId, CurrentFrame, and MaxFrame
+ size_needed += (uint32)(Movie.BytesPerFrame * (Movie.MaxFrame+1));
+ *buf=new uint8[size_needed];
+ *size=size_needed;
+
+ uint8* ptr = *buf;
+ if(!ptr)
+ {
+ return;
+ }
+
+ Write32(Movie.MovieId, ptr);
+ Write32(Movie.CurrentFrame, ptr);
+ Write32(Movie.MaxFrame, ptr);
+
+ memcpy(ptr, Movie.InputBuffer, Movie.BytesPerFrame * (Movie.MaxFrame+1));
+}
+
+bool8 S9xMovieUnfreeze (const uint8* buf, uint32 size)
+{
+ // sanity check
+ if(!S9xMovieActive())
+ {
+ return false;
+ }
+
+ const uint8* ptr = buf;
+ if(size < 4*3)
+ {
+ return false;
+ }
+
+ uint32 movie_id = Read32(ptr);
+ uint32 current_frame = Read32(ptr);
+ uint32 max_frame = Read32(ptr);
+ uint32 space_needed = (Movie.BytesPerFrame * (max_frame+1));
+
+ if(movie_id != Movie.MovieId ||
+ current_frame > max_frame ||
+ space_needed > size)
+ {
+ return false;
+ }
+
+ if(!Movie.ReadOnly)
+ {
+ // here, we are going to take the input data from the savestate
+ // and make it the input data for the current movie, then continue
+ // writing new input data at the currentframe pointer
+ change_state(MOVIE_STATE_RECORD);
+ S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_RERECORD);
+
+ Movie.CurrentFrame = current_frame;
+ Movie.MaxFrame = max_frame;
+ ++Movie.RerecordCount;
+
+ reserve_buffer_space(space_needed);
+ memcpy(Movie.InputBuffer, ptr, space_needed);
+ flush_movie();
+ fseek(Movie.File, Movie.ControllerDataOffset+(Movie.BytesPerFrame * (Movie.CurrentFrame+1)), SEEK_SET);
+ }
+ else
+ {
+ // here, we are going to keep the input data from the movie file
+ // and simply rewind to the currentframe pointer
+ // this will cause a desync if the savestate is not in sync
+ // with the on-disk recording data, but it's easily solved
+ // by loading another savestate or playing the movie from the beginning
+
+ // and older savestate might have a currentframe pointer past
+ // the end of the input data, so check for that here
+ if(current_frame > Movie.MaxFrame)
+ {
+ return false;
+ }
+
+ change_state(MOVIE_STATE_PLAY);
+ S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REWIND);
+
+ Movie.CurrentFrame = current_frame;
+ }
+
+ Movie.InputBufferPtr = Movie.InputBuffer + (Movie.BytesPerFrame * Movie.CurrentFrame);
+ read_frame_controller_data();
+
+ return true;
+}
diff --git a/source/movie.h b/source/movie.h
new file mode 100644
index 0000000..cf97442
--- /dev/null
+++ b/source/movie.h
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+ Input recording/playback code
+ (c) Copyright 2004 blip
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _MOVIE_H_
+#define _MOVIE_H_
+
+#include <stdio.h>
+#include <time.h>
+#include "snes9x.h"
+
+#ifndef SUCCESS
+# define SUCCESS 1
+# define WRONG_FORMAT (-1)
+# define WRONG_VERSION (-2)
+# define FILE_NOT_FOUND (-3)
+#endif
+
+#define MOVIE_OPT_FROM_SNAPSHOT 0
+#define MOVIE_OPT_FROM_RESET (1<<0)
+#define MOVIE_OPT_PAL (1<<1)
+#define MOVIE_MAX_METADATA 512
+
+START_EXTERN_C
+struct MovieInfo
+{
+ time_t TimeCreated;
+ uint32 LengthFrames;
+ uint32 RerecordCount;
+ wchar_t Metadata[MOVIE_MAX_METADATA]; // really should be wchar_t
+ uint8 Opts;
+ uint8 ControllersMask;
+ bool8 ReadOnly;
+};
+
+// methods used by the user-interface code
+int S9xMovieOpen (const char* filename, bool8 read_only);
+int S9xMovieCreate (const char* filename, uint8 controllers_mask, uint8 opts, const wchar_t* metadata, int metadata_length);
+int S9xMovieGetInfo (const char* filename, struct MovieInfo* info);
+void S9xMovieStop (bool8 suppress_message);
+void S9xMovieToggleFrameDisplay ();
+
+// methods used by the emulation
+void S9xMovieInit ();
+void S9xMovieUpdate ();
+//bool8 S9xMovieRewind (uint32 at_frame);
+void S9xMovieFreeze (uint8** buf, uint32* size);
+bool8 S9xMovieUnfreeze (const uint8* buf, uint32 size);
+
+// accessor functions
+bool8 S9xMovieActive ();
+// the following accessors return 0/false if !S9xMovieActive()
+bool8 S9xMovieReadOnly ();
+uint32 S9xMovieGetId ();
+uint32 S9xMovieGetLength ();
+uint32 S9xMovieGetFrameCounter ();
+
+END_EXTERN_C
+
+#endif
diff --git a/source/nds/bdf_font.c b/source/nds/bdf_font.c
new file mode 100644
index 0000000..5da57e3
--- /dev/null
+++ b/source/nds/bdf_font.c
@@ -0,0 +1,1112 @@
+/* bdf_font.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+//v1.1
+
+#include <string.h>
+#include "ds2_types.h"
+#include "ds2_malloc.h"
+#include "ds2io.h"
+#include "fs_api.h"
+#include "bdf_font.h"
+#include "gui.h"
+
+
+#define BDF_VERDANA "SYSTEM/verdana.bdf"
+#define BDF_SONG "SYSTEM/song.bdf"
+#define ODF_VERDANA "SYSTEM/verdana.odf"
+#define ODF_SONG "SYSTEM/song.odf"
+
+#define HAVE_ODF
+//#define DUMP_ODF
+
+#define BDF_LIB_NUM 2
+#define ODF_VERSION "1.0"
+
+struct bdflibinfo bdflib_info[BDF_LIB_NUM];
+struct bdffont *bdf_font; //ASCII charactor
+struct bdffont *bdf_nasci; //non-ASCII charactor
+static u32 font_height;
+static u32 fonts_max_height;
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+static u32 bitmap_code(unsigned char *code, unsigned char *bitmap)
+{
+ unsigned char *map;
+ u32 a, b, len;
+
+ len= 0;
+ map= (unsigned char*)bitmap;
+ while(*map)
+ {
+ //character to number, we assume the character can convert to number!
+ if(*map != 0x0A)
+ {
+ if(*map <= 0x39) a= *map - 0x30;
+ else a= *map - 0x37;
+ map++;
+
+ if(*map <= 0x39) b= *map - 0x30;
+ else b= *map - 0x37;
+
+ *code++ = (a << 4) | b;
+ len++;
+ }
+ map++;
+ }
+
+ return len;
+}
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+static u32 hatoi(char *string)
+{
+ char *pt;
+ u32 ret, num;
+
+ pt= string;
+ ret= 0;
+ while(*pt)
+ {
+ num= (((u32)*pt) & 0xFF) - 0x30;
+ if(num <= 0x9)
+ ret= (ret<<4) | num;
+ else if(num <= 0x16)
+ {
+ if(num >= 0x11)
+ ret= (ret<<4) | (num-0x7);
+ else
+ break;
+ }
+ else
+ break;
+ pt++;
+ }
+
+ return ret;
+}
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+/*
+* example
+*
+* STARTCHAR 2264
+* ENCODING 8804
+* SWIDTH 840 0
+* DWIDTH 14 0
+* BBX 10 12 2 1
+* BITMAP
+* 00C0
+* 0300
+* 1C00
+* 6000
+* 8000
+* 6000
+* 1C00
+* 0300
+* 00C0
+* 0000
+* 0000
+* FFC0
+* ENDCHAR
+*/
+
+/*-----------------------------------------------------------------------------
+* filename: bdf file's name, including path
+* start: the coding of first font to parse
+* span: number of fonts begin at start to parse
+* *bdflibinfop: font library information
+* method: font index method; 0-absolut sequence; 1-relative sequence; 2-compact;
+* others reserved
+* return: if error return < 0; else return= char numbers
+------------------------------------------------------------------------------*/
+static int parse_bdf(char *filename, u32 start, u32 span, struct bdflibinfo *bdflibinfop, u32 method)
+{
+ FILE *fp;
+ char string[256];
+ char map[256];
+ char *pt;
+ unsigned char *bitbuff;
+ int num, x_off, y_off, ret;
+ u32 tmp, i, end, length, index;
+ struct bdffont *bdffontp;
+
+ //initial bdflibinfo
+ bdflibinfop -> width= 0;
+ bdflibinfop -> height= 0;
+ bdflibinfop -> start= 0;
+ bdflibinfop -> span= 0;
+ bdflibinfop -> maplen= 0;
+ bdflibinfop -> mapmem= NULL;
+ bdflibinfop -> fonts= NULL;
+
+ fp= fopen(filename, "r"); //Open bdf font library
+ if(fp == NULL)
+ return -1;
+
+ ret= 0;
+ //SIZE
+ while(1)
+ {
+ pt= fgets(string, 255, fp);
+ if(pt == NULL)
+ {
+ ret= -2;
+ goto parse_bdf_error;
+ }
+ if(!(strncasecmp(string, "SIZE ", 5)))
+ break;
+ }
+
+ //FONTBOUNDINGBOX
+ pt= fgets(string, 255, fp);
+ pt += 16;
+ bdflibinfop -> width= atoi(pt);
+ pt = 1 + strchr(pt, ' ');
+ bdflibinfop -> height= atoi(pt);
+ pt = 1 + strchr(pt, ' ');
+ x_off= atoi(pt);
+ pt = 1 + strchr(pt, ' ');
+ y_off= atoi(pt);
+
+ //CHARS
+ while(1)
+ {
+ pt= fgets(string, 255, fp);
+ if(pt == NULL)
+ {
+ ret= -3;
+ goto parse_bdf_error;
+ }
+ if(!(strncasecmp(string, "CHARS ", 6)))
+ break;
+ }
+ pt += 6;
+ ret= atoi(pt);
+
+ bdflibinfop -> start= start;
+ bdflibinfop -> span= span;
+
+ //construct bdf font information
+ bdffontp= (struct bdffont*)malloc(span * sizeof(struct bdffont));
+ if(bdffontp == NULL)
+ {
+ ret= -4;
+ goto parse_bdf_error;
+ }
+ bdflibinfop -> fonts= bdffontp;
+
+ bitbuff= (unsigned char*)malloc((bdflibinfop -> width * bdflibinfop -> height * span) >> 3);
+ if(bitbuff == NULL)
+ {
+ ret= -5;
+ goto parse_bdf_error;
+ }
+ bdflibinfop -> mapmem= bitbuff;
+
+ tmp= bdflibinfop -> width << 16;
+ for(i= 0; i < span; i++)
+ {
+ bdffontp[i].dwidth= tmp;
+ bdffontp[i].bbx= 0;
+ }
+
+ end= start + span;
+ //STARTCHAR START
+ while(1)
+ {
+ pt= fgets(string, 255, fp);
+ if(pt == NULL)
+ {
+ ret= -6;
+ goto parse_bdf_error;
+ }
+ if(!(strncasecmp(string, "STARTCHAR ", 10)))
+ {
+ i= hatoi(pt +10);
+ if(i < start) continue;
+ else if(i < end) break;
+ else //Not found the start
+ {
+ ret= -7;
+ goto parse_bdf_error;
+ }
+ }
+ }
+
+ i= 0;
+ length= 0;
+ while(1)
+ {
+ //ENCODING
+ while(1)
+ {
+ pt= fgets(string, 255, fp);
+ if(pt == NULL) goto parse_bdf_error;
+ if(!(strncasecmp(string, "ENCODING ", 9))) break;
+ }
+
+ pt= string + 9;
+ index= atoi(pt);
+ if(index >= end) break;
+
+ if(method == 0) i= index;
+ else if(method == 1) i= index-start;
+ else i++;
+
+ //SWIDTH
+ pt= fgets(string, 255, fp);
+ if(pt == NULL) {ret= -8; goto parse_bdf_error;}
+
+ //DWIDTH
+ pt= fgets(string, 255, fp);
+ if(pt == NULL) {ret= -9; goto parse_bdf_error;}
+
+ pt += 7;
+ num= atoi(pt);
+ tmp= num << 16;
+ pt= 1+ strchr(pt, ' ');
+ num= atoi(pt);
+ tmp |= num & 0xFFFF;
+
+ bdffontp[i].dwidth= tmp;
+
+ //BBX
+ pt= fgets(string, 255, fp);
+ if(pt == NULL) {ret= -10; goto parse_bdf_error;}
+
+ pt += 4;
+ num= atoi(pt);
+ tmp= num & 0xFF;
+
+ pt= 1+ strchr(pt, ' ');
+ num= atoi(pt);
+ tmp= tmp<<8 | (num & 0xFF);
+
+ pt= 1+ strchr(pt, ' ');
+ num= atoi(pt);
+ num= num - x_off;
+ tmp= tmp<<8 | (num & 0xFF);
+
+ pt= 1+ strchr(pt, ' ');
+ num= atoi(pt);
+ num= num - y_off;
+ tmp= tmp <<8 | (num & 0xFF);
+
+ bdffontp[i].bbx= tmp;
+
+ //BITMAP
+ pt= fgets(string, 255, fp);
+ if(pt == NULL) {ret= -11; goto parse_bdf_error;}
+
+ map[0]= '\0';
+ while(1)
+ {
+ pt= fgets(string, 255, fp);
+ if(pt == NULL) {ret= -12; goto parse_bdf_error;}
+ if(!strncasecmp(pt, "ENDCHAR", 7)) break;
+ strcat(map, pt);
+ }
+
+ tmp = bitmap_code(bitbuff, (unsigned char*)map);
+
+ if(tmp)
+ bdffontp[i].bitmap = bitbuff;
+ else
+ bdffontp[i].bitmap = NULL;
+
+ bitbuff += tmp;
+ length += tmp;
+ }
+
+parse_bdf_error:
+ fclose(fp);
+ if(ret < 0)
+ {
+ if(bdflibinfop -> fonts != NULL)
+ free((void*)bdflibinfop -> fonts);
+ if(bdflibinfop -> mapmem != NULL)
+ free((void*)bdflibinfop -> mapmem);
+ bdflibinfop -> fonts = NULL;
+ bdflibinfop -> mapmem = NULL;
+ }
+ else
+ {
+ bdflibinfop -> maplen = length;
+ bdflibinfop -> mapmem = (unsigned char*)realloc((void*)bdflibinfop -> mapmem, length);
+ }
+
+ return ret;
+}
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+int dump2odf(char *filename, struct bdflibinfo *bdflibinfop)
+{
+ char *pt;
+ char string[256];
+ FILE *fp;
+ u32 mapaddr;
+ u32 fontaddr;
+ u32 num;
+ char buff[1024];
+ u32 i, j;
+
+
+ strcpy(string, filename);
+ pt= strrchr(string, '.');
+ if(!strcasecmp(pt, ".bdf"))
+ strcpy(pt, ".odf");
+ else
+ return -1;
+
+ fp= fopen(string, "wb");
+ if(fp == NULL)
+ return -2;
+
+ pt= buff;
+ strcpy(pt, "ODF");
+ pt += 4;
+ strcpy(pt, ODF_VERSION);
+ pt += 4;
+
+ struct bdflibinfo *bdflibinfo_i;
+
+ memcpy(pt, (char*)bdflibinfop, sizeof(struct bdflibinfo));
+ bdflibinfo_i= (struct bdflibinfo *)pt;
+ bdflibinfo_i -> mapmem= NULL;
+ bdflibinfo_i -> fonts= NULL;
+ pt += sizeof(struct bdflibinfo);
+
+ num= pt-buff;
+ fwrite(buff, num, 1, fp); //write odf file header
+
+ num= (u32)bdflibinfop -> span;
+ mapaddr= (u32)bdflibinfop -> mapmem;
+ fontaddr= (u32)bdflibinfop -> fonts;
+
+ while(num)
+ {
+ struct bdffont *bdffontp;
+
+ i= 1024/sizeof(struct bdffont);
+ if(num > i) num -= i;
+ else i= num, num= 0;
+
+ memcpy(buff, (char*)fontaddr, i*sizeof(struct bdffont));
+ fontaddr += i*sizeof(struct bdffont);
+ bdffontp= (struct bdffont*)buff;
+
+ for(j= 0; j< i; j++)
+ bdffontp[j].bitmap -= mapaddr;
+
+ fwrite(buff, i*sizeof(struct bdffont), 1, fp);
+ }
+
+ fwrite((char*)mapaddr, bdflibinfop -> maplen, 1, fp);
+
+ fclose(fp);
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+int init_from_odf(char *filename, struct bdflibinfo *bdflibinfop)
+{
+ FILE *fp;
+ char buff[512];
+ char *pt;
+ u32 len, tmp;
+ u32 span, maplen;
+ struct bdffont *bdffontp;
+
+ //initial bdflibinfo
+ bdflibinfop -> width= 0;
+ bdflibinfop -> height= 0;
+ bdflibinfop -> start= 0;
+ bdflibinfop -> span= 0;
+ bdflibinfop -> maplen= 0;
+ bdflibinfop -> mapmem= NULL;
+ bdflibinfop -> fonts= NULL;
+
+ fp= fopen(filename, "rb");
+ if(fp == NULL)
+ return -1;
+
+ tmp= 8 + sizeof(struct bdflibinfo);
+ len= fread(buff, 1, tmp, fp);
+ if(len < tmp)
+ {
+ fclose(fp);
+ return -2;
+ }
+
+ pt= buff;
+ if(strcmp(pt, "ODF"))
+ {
+ fclose(fp);
+ return -2;
+ }
+
+ pt += 4;
+ if(strcmp(pt, ODF_VERSION))
+ {
+ fclose(fp);
+ return -3;
+ }
+
+ pt += 4;
+ memcpy((char*)bdflibinfop, pt, sizeof(struct bdflibinfo));
+
+ span= bdflibinfop -> span;
+ if(span == 0)
+ {
+ fclose(fp);
+ return -4;
+ }
+
+ maplen= bdflibinfop -> maplen;
+ if(maplen == 0)
+ {
+ fclose(fp);
+ return -5;
+ }
+
+ bdffontp= (struct bdffont*)malloc(span * sizeof(struct bdffont));
+ if(bdffontp == NULL)
+ {
+ fclose(fp);
+ return -6;
+ }
+
+ len= fread((char*)bdffontp, 1, span * sizeof(struct bdffont), fp);
+ if(len != span * sizeof(struct bdffont))
+ {
+ free((void*)bdffontp);
+ fclose(fp);
+ return -7;
+ }
+
+ pt= (char*)malloc(maplen);
+ len= fread(pt, 1, maplen, fp);
+ if(len != maplen)
+ {
+ free((void*)bdffontp);
+ free((void*)pt);
+ fclose(fp);
+ return -8;
+ }
+
+ bdflibinfop -> mapmem = (unsigned char*)pt;
+ bdflibinfop -> fonts = bdffontp;
+
+ u32 i, j;
+ j= (u32)bdflibinfop -> mapmem;
+ for(i= 0; i < span; i++)
+ bdffontp[i].bitmap += j;
+
+ fclose(fp);
+ return 0;
+}
+
+int BDF_font_init(void)
+{
+ int err;
+ char tmp_path[MAX_PATH];
+
+ fonts_max_height= 0;
+#ifndef HAVE_ODF
+ sprintf(tmp_path, "%s/%s", main_path, BDF_VERDANA);
+ err= parse_bdf(tmp_path, 0, 128, &bdflib_info[0], 0);
+ if(err < 0)
+ {
+ printf("BDF 0 initial error: %d\n", err);
+ return -1;
+ }
+#else
+ sprintf(tmp_path, "%s/%s", main_path, ODF_VERDANA);
+ err= init_from_odf(tmp_path, &bdflib_info[0]);
+ if(err < 0)
+ {
+ printf("ODF 0 initial error: %d\n", err);
+ return -1;
+ }
+#endif
+ bdf_font= bdflib_info[0].fonts;
+ font_height= bdflib_info[0].height;
+ if(fonts_max_height < bdflib_info[0].height)
+ fonts_max_height = bdflib_info[0].height;
+
+#ifdef DUMP_ODF
+ sprintf(tmp_path, "%s/%s", main_path, BDF_VERDANA);
+ err= dump2odf(tmp_path, &bdflib_info[0]);
+ if(err < 0)
+ {
+ printf("BDF dump odf 0 error: %d\n", err);
+ }
+#endif
+
+#ifndef HAVE_ODF
+ sprintf(tmp_path, "%s/%s", main_path, BDF_SONG);
+ err= parse_bdf(tmp_path, 0x4E00, 20902, &bdflib_info[1], 1);
+ if(err < 0)
+ {
+ printf("BDF 1 initial error: %d\n", err);
+ return -1;
+ }
+#else
+ sprintf(tmp_path, "%s/%s", main_path, ODF_SONG);
+ err= init_from_odf(tmp_path, &bdflib_info[1]);
+ if(err < 0)
+ {
+ printf("ODF 1 initial error: %d\n", err);
+ return -1;
+ }
+#endif
+ bdf_nasci= bdflib_info[1].fonts;
+ if(fonts_max_height < bdflib_info[1].height)
+ fonts_max_height = bdflib_info[1].height;
+
+#ifdef DUMP_ODF
+ sprintf(tmp_path, "%s/%s", main_path, BDF_SONG);
+ err= dump2odf(tmp_path, &bdflib_info[1]);
+ if(err < 0)
+ {
+ printf("BDF dump odf 1 error: %d\n", err);
+ }
+#endif
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+// release resource of BDF fonts
+------------------------------------------------------------------------------*/
+void BDF_font_release(void)
+{
+ u32 i;
+
+ for(i= 0; i < BDF_LIB_NUM; i++)
+ {
+ if(bdflib_info[i].fonts)
+ free((void*)bdflib_info[i].fonts);
+ if(bdflib_info[i].mapmem)
+ free((void*)bdflib_info[i].mapmem);
+ }
+}
+
+/*-----------------------------------------------------------------------------
+//16-bit color
+// Unicode Character
+// back is background, 0x8000 is transparence, other are visable colors
+------------------------------------------------------------------------------*/
+u32 BDF_render16_ucs(void* screen_address, u32 screen_w, u32 v_align, u32 back, u32 front, u16 ch)
+{
+ unsigned short *screen, *screenp;
+ unsigned char *map;
+ u32 width, height, x_off, y_off, i, k, m, ret, fonts_height;
+ unsigned char cc;
+ struct bdffont *bdffontp;
+
+ if(ch < 128)
+ {
+ bdffontp= bdflib_info[0].fonts;
+ fonts_height= bdflib_info[0].height;
+ }
+ else if(bdflib_info[1].fonts != NULL)
+ {
+ k= bdflib_info[1].start;
+ m= k + bdflib_info[1].span;
+ if(ch >= k && ch < m)
+ {
+ ch -= k;
+ bdffontp= bdflib_info[1].fonts;
+ fonts_height= bdflib_info[0].height;
+ }
+ else
+ return 8;
+ }
+ else
+ return 8;
+
+ width= bdffontp[ch].dwidth >> 16;
+ ret= width;
+ height= fonts_max_height;
+ //if charactor is not transparent
+ if(!(back & 0x8000))
+ {
+ for(k= 0; k < height; k++)
+ {
+ screenp= (unsigned short*)screen_address + k *screen_w;
+ for(i= 0; i < width; i++)
+ *screenp++ = back;
+ }
+ }
+
+ width= bdffontp[ch].bbx >> 24;
+ if(width == 0)
+ return ret;
+
+ height= (bdffontp[ch].bbx >> 16) & 0xFF;
+ x_off= (bdffontp[ch].bbx >> 8) & 0xFF;
+ y_off= bdffontp[ch].bbx & 0xFF;
+
+ if(v_align== 0) //v align bottom
+ screen= (unsigned short*)screen_address + x_off + (fonts_max_height - height - y_off) *screen_w;
+ else if(v_align== 1) //v align center
+ screen= (unsigned short*)screen_address + x_off + (fonts_max_height - height - y_off)/2 *screen_w;
+ else //v align top
+ screen= (unsigned short*)screen_address + x_off;
+
+ x_off= width >> 3;
+ y_off= width & 7;
+
+ map= bdffontp[ch].bitmap;
+ for(k= 0; k < height; k++)
+ {
+ screenp = screen + k *screen_w;
+ i= x_off;
+ while(i--)
+ {
+ m= 0x80;
+ cc= *map++;
+ while(m)
+ {
+ if(m & cc) *screenp = front;
+ screenp++;
+ m >>= 1;
+ }
+ }
+
+ i= y_off;
+ if(i)
+ {
+ i= 8 - y_off;
+ cc= *map++;
+ cc >>= i;
+ m= 0x80 >> i;
+ while(m)
+ {
+ if(m & cc) *screenp = front;
+ screenp++;
+ m >>= 1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*-----------------------------------------------------------------------------
+//16-bit color
+// ASCII Character
+// back is background, 0x8000 is transparence, other are visable colors
+------------------------------------------------------------------------------*/
+static u32 BDF_render16_font(char *screen_address, u32 back, u32 front, u16 ch)
+{
+ unsigned short *screen, *screenp;
+ unsigned char *map;
+ u32 width, height, x_off, y_off, i, k, m, ret;
+ unsigned char cc;
+
+ if(ch > 127)
+ return 8;
+
+ width= bdf_font[ch].dwidth >> 16;
+ ret= width;
+ height= font_height;
+ //if charactor is not transparent
+ if(!(back & 0x8000))
+ {
+ for(k= 0; k < height; k++)
+ {
+ screenp= (unsigned short*)screen_address + k *SCREEN_WIDTH;
+ for(i= 0; i < width; i++)
+ *screenp++ = back;
+ }
+ }
+
+ width= bdf_font[ch].bbx >> 24;
+ if(width == 0)
+ return ret;
+ height= (bdf_font[ch].bbx >> 16) & 0xFF;
+ x_off= (bdf_font[ch].bbx >> 8) & 0xFF;
+ y_off= bdf_font[ch].bbx & 0xFF;
+ screen= (unsigned short*)screen_address + x_off + (font_height - height -y_off) *SCREEN_WIDTH;
+
+ x_off= width >> 3;
+ y_off= width & 7;
+
+ map= bdf_font[ch].bitmap;
+ for(k= 0; k < height; k++)
+ {
+ screenp = screen + k *SCREEN_WIDTH;
+ i= x_off;
+ while(i--)
+ {
+ m= 0x80;
+ cc= *map++;
+ while(m)
+ {
+ if(m & cc) *screenp = front;
+ screenp++;
+ m >>= 1;
+ }
+ }
+
+ i= y_off;
+ if(i)
+ {
+ i= 8 - y_off;
+ cc= *map++;
+ cc >>= i;
+ m= 0x80 >> i;
+ while(m)
+ {
+ if(m & cc) *screenp = front;
+ screenp++;
+ m >>= 1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*-----------------------------------------------------------------------------
+// ASCII Code Only
+------------------------------------------------------------------------------*/
+void BDF_render_string(void* screen_address, u32 x, u32 y, u32 back, u32 front, char *string)
+{
+ char *pt;
+ u32 screenp, line_start;
+ u32 width, line, cmp;
+
+ pt= string;
+ screenp= (u32)screen_address + (x + y *SCREEN_WIDTH)*2;
+ line= 1 + y;
+ line_start= (u32)screen_address + line *SCREEN_WIDTH *2;
+
+ width= 0;
+ while(*pt)
+ {
+ if(*pt == 0x0D)
+ {
+ pt++;
+ continue;
+ }
+ if(*pt == 0x0A)
+ {
+ line += font_height;
+ line_start= (u32)screen_address + line *SCREEN_WIDTH *2;
+ screenp = line_start - SCREEN_WIDTH *2;
+ pt++;
+ continue;
+ }
+
+ cmp = (bdf_font[(u32)(*pt)].dwidth >> 16) << 1;
+ if((screenp+cmp) >= line_start)
+ {
+ line += font_height;
+ line_start= (u32)screen_address + line *SCREEN_WIDTH *2;
+ screenp = line_start - SCREEN_WIDTH *2;
+ }
+ width= BDF_render16_font((char*)screenp, back, front, (u32)(*pt));
+ screenp += width*2;
+ pt++;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+char* utf8decode(char *utf8, u16 *ucs)
+{
+ unsigned char c = *utf8++;
+ unsigned long code;
+ int tail = 0;
+
+ if ((c <= 0x7f) || (c >= 0xc2)) {
+ /* Start of new character. */
+ if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */
+ code = c;
+ } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */
+ tail = 1;
+ code = c & 0x1f;
+ } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */
+ tail = 2;
+ code = c & 0x0f;
+ } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */
+ tail = 3;
+ code = c & 0x07;
+ } else {
+ /* Invalid size. */
+ code = 0;
+ }
+
+ while (tail-- && ((c = *utf8++) != 0)) {
+ if ((c & 0xc0) == 0x80) {
+ /* Valid continuation character. */
+ code = (code << 6) | (c & 0x3f);
+
+ } else {
+ /* Invalid continuation char */
+ code = 0xfffd;
+ utf8--;
+ break;
+ }
+ }
+ } else {
+ /* Invalid UTF-8 char */
+ code = 0;
+ }
+ /* currently we don't support chars above U-FFFF */
+ *ucs = (code < 0x10000) ? code : 0;
+ return utf8;
+}
+
+static u8 utf8_ucs2(const char *utf8, u16 *ucs)
+{
+ char *pt = (char*)utf8;
+
+ while(*pt !='\0')
+ {
+ pt = utf8decode(pt, ucs++);
+ }
+ *ucs = '\0';
+ return 0;
+}
+
+static u32 ucslen(const u16 *ucs)
+{
+ u32 len = 0;
+
+ while(ucs[len] != '\0')
+ len++;
+ return len;
+}
+
+unsigned char* skip_utf8_unit(unsigned char* utf8, unsigned int num)
+{
+ while(num--)
+ {
+ unsigned char c = *utf8++;
+ int tail = 0;
+ if ((c <= 0x7f) || (c >= 0xc2)) {
+ /* Start of new character. */
+ if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */
+ } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */
+ tail = 1;
+ } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */
+ tail = 2;
+ } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */
+ tail = 3;
+ } else { /* Invalid size. */
+ }
+
+ while (tail-- && ((c = *utf8++) != 0)) {
+ if ((c & 0xc0) != 0x80) {
+ /* Invalid continuation char */
+ utf8--;
+ break;
+ }
+ }
+ }
+ }
+
+ /* currently we don't support chars above U-FFFF */
+ return utf8;
+}
+
+/*-----------------------------------------------------------------------------
+// UTF8 Code String
+------------------------------------------------------------------------------*/
+void BDF_render_mix(void* screen_address, u32 screen_w, u32 x, u32 y, u32 v_align,
+ u32 back, u32 front, char *string)
+{
+ char *pt;
+ u32 screenp, line_start;
+ u32 width, line, cmp, start, end;
+ u16 unicode;
+ struct bdffont *bdf_fontp[2];
+
+ bdf_fontp[0]= bdflib_info[0].fonts;
+ start= bdflib_info[1].start;
+ end= start + bdflib_info[1].span;
+ bdf_fontp[1]= bdflib_info[1].fonts;
+
+ pt= string;
+ screenp= (u32)screen_address + (x + y *screen_w)*2;
+ line= 1 + y;
+ line_start= (u32)screen_address + line *screen_w *2;
+
+ width= 0;
+ while(*pt)
+ {
+ pt= utf8decode(pt, &unicode);
+
+ if(unicode == 0x0D) continue;
+ if(unicode == 0x0A)
+ {
+ line += font_height;
+ line_start= (u32)screen_address + line *screen_w *2;
+ screenp = line_start - screen_w *2;
+ continue;
+ }
+
+ if(unicode < 128)
+ cmp = bdf_fontp[0][unicode].dwidth>>16;
+ else if(unicode >= start && unicode < end)
+ cmp = bdf_fontp[1][unicode -start].dwidth>>16;
+
+ if((screenp+cmp) >= line_start)
+ {
+ line += font_height;
+ line_start= (u32)screen_address + line *screen_w *2;
+ screenp = line_start - screen_w *2;
+ }
+
+ width= BDF_render16_ucs((unsigned short*)screenp, screen_w, v_align, back, front, unicode);
+ screenp += width*2;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+- count UNICODE charactor numbers in width pixels, input are UTF8, not UNICODE-16
+- direction 0: count UNICODE charactor numbers in width pixels, from end,
+- return bytes numbers
+- direction 1: count UNICODE charactor numbers in width pixels, from front,
+- return bytes numbers
+- direction 2: count total pixel width of the string
+------------------------------------------------------------------------------*/
+u32 BDF_cut_string(char *string, u32 width, u32 direction)
+{
+ char *pt;
+ u16 unicode[256];
+ u32 len, xw;
+
+ if(direction > 2) return -1;
+
+ pt= string;
+ len= 0;
+ while(*pt)
+ {
+ pt= utf8decode(pt, &unicode[len]);
+ if(unicode[len] != 0x0A)
+ {
+ len++;
+ if(len >= 256) break;
+ }
+ }
+
+ if(len >= 256) return -1;
+
+ u16 *unicodep;
+ if(direction == 0)
+ unicodep= &unicode[len-1];
+ else
+ unicodep= &unicode[0];
+
+ if(direction == 2) direction = 3;
+ xw= BDF_cut_unicode(unicodep, len, width, direction);
+
+ if(direction < 2)
+ {
+ if(direction < 1)
+ xw= len - xw;
+
+ pt= string;
+ while(xw)
+ {
+ pt= utf8decode(pt, unicodep);
+ if(unicode[xw] != 0x0A) xw--;
+ }
+
+ xw= pt -string;
+ }
+
+ return xw;
+}
+
+/*-----------------------------------------------------------------------------
+- count UNICODE charactor numbers in width pixels
+- direction 0: count UNICODE charactor numbers in width pixels, from front
+- direction 1: count UNICODE charactor numbers in width pixels, from end
+- direction 2: conut total pixel width of len UNICODE charachtors, from end
+- direction 3: conut total pixel width of len UNICODE charachtors, from front
+------------------------------------------------------------------------------*/
+u32 BDF_cut_unicode(u16 *unicodes, u32 len, u32 width, u32 direction)
+{
+ u32 i, xw, num;
+ u16 unicode;
+ u32 start, end;
+ struct bdffont *bdf_fontp[2];
+
+ bdf_fontp[0]= bdflib_info[0].fonts;
+ start= bdflib_info[1].start;
+ end= start + bdflib_info[1].span;
+ bdf_fontp[1]= bdflib_info[1].fonts;
+
+ if(direction < 2)
+ {
+ if(direction < 1) direction = -1;
+
+ i= 0;
+ xw = 0;
+ num= len;
+ while(len > 0)
+ {
+ unicode= unicodes[i];
+ if(unicode < 128)
+ xw += bdf_fontp[0][unicode].dwidth>>16;
+ else if(unicode >= start && unicode < end)
+ xw += bdf_fontp[1][unicode -start].dwidth>>16;
+
+ if(xw >= width) break;
+ i += direction;
+ len--;
+ }
+
+ num -= len;
+ }
+ else
+ {
+ if(direction < 3) direction = -1;
+ else direction = 1;
+
+ i= 0;
+ xw = 0;
+ while(len-- > 0)
+ {
+ unicode= unicodes[i];
+ if(unicode < 128)
+ xw += bdf_fontp[0][unicode].dwidth>>16;
+ else if(unicode >= start && unicode < end)
+ xw += bdf_fontp[1][unicode -start].dwidth>>16;
+ i += direction;
+ }
+
+ num= xw;
+ }
+
+ return num;
+}
+
+
diff --git a/source/nds/bdf_font.h b/source/nds/bdf_font.h
new file mode 100644
index 0000000..074f5de
--- /dev/null
+++ b/source/nds/bdf_font.h
@@ -0,0 +1,64 @@
+/* bdf_font.h
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __BDF_FONT_H__
+#define __BDF_FONT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bdffont{
+ unsigned int dwidth; //byte 3:2 x-distance; 1:0 y-distance
+ unsigned int bbx; //byte 3 x-width; 2 y-height; 1 x-offset; 0 y-offset
+ unsigned char *bitmap;
+};
+
+struct bdflibinfo{
+ unsigned int width;
+ unsigned int height;
+ unsigned int start;
+ unsigned int span;
+ unsigned int maplen;
+ unsigned char *mapmem;
+ struct bdffont *fonts;
+};
+
+
+/*-----------------------------------------------------------------------------
+------------------------------------------------------------------------------*/
+extern int BDF_font_init(void);
+extern void BDF_render_string(void* screen_address, unsigned int x, unsigned int y, unsigned int back,
+ unsigned int front, char *string);
+extern unsigned int BDF_render16_ucs(void* screen_address, unsigned int screen_w,
+ unsigned int v_align, unsigned int back, unsigned int front, unsigned short ch);
+extern void BDF_render_mix(void* screen_address, unsigned int screen_w, unsigned int x,
+ unsigned int y, unsigned int v_align, unsigned int back, unsigned int front, char *string);
+//extern unsigned int BDF_string_width(char *string, unsigned int *len);
+extern char* utf8decode(char *utf8, unsigned short *ucs);
+extern unsigned char* skip_utf8_unit(unsigned char* utf8, unsigned int num);
+extern unsigned int BDF_cut_unicode(unsigned short *unicodes, unsigned int len, unsigned int width, unsigned int direction);
+extern unsigned int BDF_cut_string(char *string, unsigned int width, unsigned int direction);
+extern void BDF_font_release(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__BDF_FONT_H__
diff --git a/source/nds/bitmap.c b/source/nds/bitmap.c
new file mode 100644
index 0000000..bda4cf7
--- /dev/null
+++ b/source/nds/bitmap.c
@@ -0,0 +1,204 @@
+/* bitmap.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+//v1.1
+
+#include "fs_api.h"
+#include "bitmap.h"
+
+int BMP_read(char* filename, char *buf, unsigned int width, unsigned int height, unsigned int* type)
+{
+ FILE* fp;
+ BMPHEADER bmp_header;
+ int flag;
+ u32 bytepixel;
+ u32 x, y, sx, sy, m;
+ unsigned char *dest;
+ s32 fpos;
+ unsigned short st[54/2];
+
+ fp= fopen(filename, "rb");
+ if(fp == NULL)
+ return BMP_ERR_OPENFAILURE;
+
+ flag= fread(st, sizeof(st), 1, fp);
+ if(!flag) {
+ fclose(fp);
+ return BMP_ERR_FORMATE;
+ }
+
+ bmp_header.bfType= st[0];
+ bmp_header.bfSize= st[1] | (st[2]<<16);
+ bmp_header.bfReserved0= st[3];
+ bmp_header.bfReserved1= st[4];
+ bmp_header.bfImgoffst= st[5] | (st[6]<<16);
+ bmp_header.bfImghead.imHeadsize= st[7] | (st[8]<<16);
+ bmp_header.bfImghead.imBitmapW= st[9] | (st[10]<<16);
+ bmp_header.bfImghead.imBitmapH= st[11] | (st[12]<<16);
+ bmp_header.bfImghead.imPlanes= st[13];
+ bmp_header.bfImghead.imBitpixel= st[14];
+ bmp_header.bfImghead.imCompess= st[15] | (st[16]<<16);
+ bmp_header.bfImghead.imImgsize= st[17] | (st[18]<<16);
+ bmp_header.bfImghead.imHres= st[19] | (st[20]<<16);
+ bmp_header.bfImghead.imVres= st[21] | (st[22]<<16);
+ bmp_header.bfImghead.imColnum= st[23] | (st[24]<<16);
+ bmp_header.bfImghead.imImcolnum= st[25] | (st[26]<<16);
+
+ if(bmp_header.bfType != 0x4D42) //"BM"
+ return BMP_ERR_FORMATE;
+
+ if(bmp_header.bfImghead.imCompess != BI_RGB &&
+ bmp_header.bfImghead.imCompess != BI_BITFIELDS)
+ return BMP_ERR_NEED_GO_ON; //This funciton now not support...
+
+ bytepixel= bmp_header.bfImghead.imBitpixel >> 3;
+ if(bytepixel < 2) //byte per pixel >= 2
+ return BMP_ERR_NEED_GO_ON; //This funciton now not support...
+
+ *type = bytepixel;
+
+ x= width;
+ y= height;
+ sx= bmp_header.bfImghead.imBitmapW;
+ sy= bmp_header.bfImghead.imBitmapH;
+ if(x > sx)
+ x= sx;
+ if(y > sy)
+ y= sy;
+
+ //BMP scan from down to up
+ fpos= (s32)bmp_header.bfImgoffst;
+ dest= (unsigned char*)buf+(y-1)*x*bytepixel;
+ for(m= 0; m < y; m++) {
+ fseek(fp, fpos, SEEK_SET);
+ fread(dest, 1, x*bytepixel, fp);
+ fpos += ((sx*bytepixel+3)>>2)<<2;
+ dest -= x*bytepixel;
+ }
+
+ fclose(fp);
+
+ return BMP_OK;
+}
+
+/*
+* open BMP file
+*/
+int openBMP(BMPINFO* bmpInfo, const char* file)
+{
+ FILE* fp;
+ unsigned short st[54/2];
+ int len;
+
+ bmpInfo->fp = NULL;
+
+ fp = fopen(file, "r");
+ if(NULL == fp)
+ return BMP_ERR_OPENFAILURE;
+
+ len = fread((void*)st, 1, sizeof(BMPHEADER), fp);
+ if(len < sizeof(BMPHEADER)) {
+ fclose(fp);
+ return BMP_ERR_FORMATE;
+ }
+
+ bmpInfo->bmpHead.bfType= st[0];
+ bmpInfo->bmpHead.bfSize= st[1] | (st[2]<<16);
+ bmpInfo->bmpHead.bfReserved0= st[3];
+ bmpInfo->bmpHead.bfReserved1= st[4];
+ bmpInfo->bmpHead.bfImgoffst= st[5] | (st[6]<<16);
+ bmpInfo->bmpHead.bfImghead.imHeadsize= st[7] | (st[8]<<16);
+ bmpInfo->bmpHead.bfImghead.imBitmapW= st[9] | (st[10]<<16);
+ bmpInfo->bmpHead.bfImghead.imBitmapH= st[11] | (st[12]<<16);
+ bmpInfo->bmpHead.bfImghead.imPlanes= st[13];
+ bmpInfo->bmpHead.bfImghead.imBitpixel= st[14];
+ bmpInfo->bmpHead.bfImghead.imCompess= st[15] | (st[16]<<16);
+ bmpInfo->bmpHead.bfImghead.imImgsize= st[17] | (st[18]<<16);
+ bmpInfo->bmpHead.bfImghead.imHres= st[19] | (st[20]<<16);
+ bmpInfo->bmpHead.bfImghead.imVres= st[21] | (st[22]<<16);
+ bmpInfo->bmpHead.bfImghead.imColnum= st[23] | (st[24]<<16);
+ bmpInfo->bmpHead.bfImghead.imImcolnum= st[25] | (st[26]<<16);
+
+ if(bmpInfo->bmpHead.bfType != 0x4D42) //"BM"
+ {
+ fclose(fp);
+ return BMP_ERR_FORMATE;
+ }
+
+ if(bmpInfo->bmpHead.bfImghead.imCompess != BI_RGB &&
+ bmpInfo->bmpHead.bfImghead.imCompess != BI_BITFIELDS)
+ {
+ fclose(fp);
+ return BMP_ERR_NEED_GO_ON; //This funciton now not support...
+ }
+
+ bmpInfo->fp = fp;
+
+ return BMP_OK;
+}
+
+/*
+* read pixel form BMP file
+*/
+int readBMP(BMPINFO* bmpInfo, unsigned int start_x, unsigned int start_y,
+ unsigned int width, unsigned int height, void* buffer)
+{
+ unsigned int m, n;
+ unsigned int bmp_w, bmp_h;
+ int fpos;
+ unsigned char* dst;
+ unsigned int bytepixel;
+
+ bytepixel = bmpInfo->bmpHead.bfImghead.imBitpixel >> 3;
+ if(bytepixel < 2) //Not support <2 bytes per pixel now
+ return -1;
+
+ //BMP scan from down to up
+ bmp_w = bmpInfo->bmpHead.bfImghead.imBitmapW;
+ bmp_h = bmpInfo->bmpHead.bfImghead.imBitmapH;
+ if(((start_x +1) > bmp_w) || ((start_y+1) > bmp_h)) return -1;
+ n = bmp_w - start_x;
+ if(n > width) n = width; //start_x + width < bmp_w
+ m = bmp_h - start_y;
+ if(m > height) m = height; //start_y + height < bmp_h
+
+ fpos = (int)bmpInfo->bmpHead.bfImgoffst;
+
+ fpos += (((bmp_w*bytepixel+3)>>2)<<2)*(bmp_h - start_y -1) + start_x*bytepixel;
+ dst = (unsigned char*)buffer;
+ n *= bytepixel;
+ while(m--) {
+ fseek(bmpInfo->fp, fpos, SEEK_SET);
+ fread(dst, 1, n, bmpInfo->fp);
+ fpos -= ((bmp_w*bytepixel+3)>>2)<<2;
+ dst += width*bytepixel;
+ }
+
+ return 0;
+}
+
+/*
+* close BMP file
+*/
+void closeBMP(BMPINFO* bmpInfo)
+{
+ if(NULL != bmpInfo->fp)
+ fclose(bmpInfo->fp);
+}
+
+
diff --git a/source/nds/bitmap.h b/source/nds/bitmap.h
new file mode 100644
index 0000000..c8f9c52
--- /dev/null
+++ b/source/nds/bitmap.h
@@ -0,0 +1,111 @@
+/* bitmap.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __BITMAP_H__
+#define __BITMAP_H__
+#include "ds2_types.h"
+#include "fs_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _pixelmapheader{
+ u32 imHeadsize; //Bitmap information header size
+ u32 imBitmapW; //bitmap width in pixel
+ u32 imBitmapH; //bitmap height in pixel
+ u16 imPlanes; //bitmap planes numbers, must be set to 1
+ u16 imBitpixel; //bits per pixel
+ u32 imCompess; //compress method
+ u32 imImgsize; //image size, times of 4-byte
+ u32 imHres; //horizontal resolution, pixel/metel
+ u32 imVres; //vertical resolution, pixel/metel
+ u32 imColnum; //number of colors in color palette, 0 to exp(2)
+ u32 imImcolnum; //important colors numbers used
+} IMAGEHEADER;
+
+
+typedef struct _bitmapfileheader{
+ u16 bfType; //BMP file types
+ u32 bfSize; //BMP file size(Not the pixel image size)
+ u16 bfReserved0;//reserved area0
+ u16 bfReserved1;//reserved area1
+ u32 bfImgoffst; //pixel data area offset
+ IMAGEHEADER bfImghead;
+} BMPHEADER;
+
+
+typedef struct _bitmapInfo{
+ FILE* fp;
+ BMPHEADER bmpHead;
+} BMPINFO;
+
+//#define NULL 0
+
+//compression method
+/* Value Identified by Compression method Comments
+* 0 BI_RGB none Most common
+* 1 BI_RLE8 RLE 8-bit/pixel Can be used only with 8-bit/pixel bitmaps
+* 2 BI_RLE4 RLE 4-bit/pixel Can be used only with 4-bit/pixel bitmaps
+* 3 BI_BITFIELDS Bit field Can be used only with 16 and 32-bit/pixel bitmaps.
+* 4 BI_JPEG JPEG The bitmap contains a JPEG image
+* 5 BI_PNG PNG The bitmap contains a PNG image
+*/
+#define BI_RGB 0
+#define BI_RLE8 1
+#define BI_RLE4 2
+#define BI_BITFIELDS 3
+#define BI_JPEG 4
+#define BI_PNG 5
+
+//error message
+#define BMP_OK 0
+#define BMP_ERR_OPENFAILURE 1
+#define BMP_ERR_FORMATE 2
+#define BMP_ERR_NOTSUPPORT 3
+#define BMP_ERR_NEED_GO_ON 4
+
+
+#define FILEOPENCHECK(fp) (fp!=NULL)
+
+
+extern int BMP_read(char* filename, char *buf, unsigned int width,
+ unsigned int height, unsigned int *type);
+
+/*
+* open BMP file
+*/
+extern int openBMP(BMPINFO* bmpInfo, const char* file);
+
+/*
+* read pixel form BMP file
+*/
+extern int readBMP(BMPINFO* bmpInfo, unsigned int start_x, unsigned int start_y,
+ unsigned int width, unsigned int height, void* buffer);
+
+/*
+* close BMP file
+*/
+extern void closeBMP(BMPINFO* bmpInfo);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__BITMAP_H__
diff --git a/source/nds/charsets.c b/source/nds/charsets.c
new file mode 100644
index 0000000..e04a5b0
--- /dev/null
+++ b/source/nds/charsets.c
@@ -0,0 +1,12345 @@
+/* vim:set ts=4 sw=4 cindent ignorecase enc=gbk: */
+
+#include <string.h>
+#include "charsets.h"
+
+
+/* definitions */
+
+typedef unsigned int ucs4_t;
+
+#define RET_ILSEQ -1
+#define RET_TOOFEW(n) (-2-(n))
+#define RET_ILUNI -1
+#define RET_TOOSMALL -2
+
+typedef struct
+{
+ unsigned short indx; /* index into big table */
+ unsigned short used; /* bitmask of used entries */
+} Summary16;
+
+/* BIG5 table */
+
+static const unsigned short big5_2uni_pagea1[6121] = {
+ /* 0xa1 */
+ 0x3000, 0xff0c, 0x3001, 0x3002, 0xff0e, 0x2022, 0xff1b, 0xff1a,
+ 0xff1f, 0xff01, 0xfe30, 0x2026, 0x2025, 0xfe50, 0xff64, 0xfe52,
+ 0x00b7, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xff5c, 0x2013, 0xfe31,
+ 0x2014, 0xfe33, 0xfffd, 0xfe34, 0xfe4f, 0xff08, 0xff09, 0xfe35,
+ 0xfe36, 0xff5b, 0xff5d, 0xfe37, 0xfe38, 0x3014, 0x3015, 0xfe39,
+ 0xfe3a, 0x3010, 0x3011, 0xfe3b, 0xfe3c, 0x300a, 0x300b, 0xfe3d,
+ 0xfe3e, 0x3008, 0x3009, 0xfe3f, 0xfe40, 0x300c, 0x300d, 0xfe41,
+ 0xfe42, 0x300e, 0x300f, 0xfe43, 0xfe44, 0xfe59, 0xfe5a, 0xfe5b,
+ 0xfe5c, 0xfe5d, 0xfe5e, 0x2018, 0x2019, 0x201c, 0x201d, 0x301d,
+ 0x301e, 0x2035, 0x2032, 0xff03, 0xff06, 0xff0a, 0x203b, 0x00a7,
+ 0x3003, 0x25cb, 0x25cf, 0x25b3, 0x25b2, 0x25ce, 0x2606, 0x2605,
+ 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25bd, 0x25bc, 0x32a3, 0x2105,
+ 0x203e, 0xfffd, 0xff3f, 0xfffd, 0xfe49, 0xfe4a, 0xfe4d, 0xfe4e,
+ 0xfe4b, 0xfe4c, 0xfe5f, 0xfe60, 0xfe61, 0xff0b, 0xff0d, 0x00d7,
+ 0x00f7, 0x00b1, 0x221a, 0xff1c, 0xff1e, 0xff1d, 0x2266, 0x2267,
+ 0x2260, 0x221e, 0x2252, 0x2261, 0xfe62, 0xfe63, 0xfe64, 0xfe65,
+ 0xfe66, 0x223c, 0x2229, 0x222a, 0x22a5, 0x2220, 0x221f, 0x22bf,
+ 0x33d2, 0x33d1, 0x222b, 0x222e, 0x2235, 0x2234, 0x2640, 0x2642,
+ 0x2641, 0x2609, 0x2191, 0x2193, 0x2190, 0x2192, 0x2196, 0x2197,
+ 0x2199, 0x2198, 0x2225, 0x2223, 0xfffd,
+ /* 0xa2 */
+ 0xfffd, 0xff0f, 0xff3c, 0xff04, 0x00a5, 0x3012, 0x00a2, 0x00a3,
+ 0xff05, 0xff20, 0x2103, 0x2109, 0xfe69, 0xfe6a, 0xfe6b, 0x33d5,
+ 0x339c, 0x339d, 0x339e, 0x33ce, 0x33a1, 0x338e, 0x338f, 0x33c4,
+ 0x00b0, 0x5159, 0x515b, 0x515e, 0x515d, 0x5161, 0x5163, 0x55e7,
+ 0x74e9, 0x7cce, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586,
+ 0x2587, 0x2588, 0x258f, 0x258e, 0x258d, 0x258c, 0x258b, 0x258a,
+ 0x2589, 0x253c, 0x2534, 0x252c, 0x2524, 0x251c, 0x2594, 0x2500,
+ 0x2502, 0x2595, 0x250c, 0x2510, 0x2514, 0x2518, 0x256d, 0x256e,
+ 0x2570, 0x256f, 0x2550, 0x255e, 0x256a, 0x2561, 0x25e2, 0x25e3,
+ 0x25e5, 0x25e4, 0x2571, 0x2572, 0x2573, 0xff10, 0xff11, 0xff12,
+ 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0x2160,
+ 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168,
+ 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027,
+ 0x3028, 0x3029, 0xfffd, 0x5344, 0xfffd, 0xff21, 0xff22, 0xff23,
+ 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b,
+ 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33,
+ 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff41,
+ 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49,
+ 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51,
+ 0xff52, 0xff53, 0xff54, 0xff55, 0xff56,
+ /* 0xa3 */
+ 0xff57, 0xff58, 0xff59, 0xff5a, 0x0391, 0x0392, 0x0393, 0x0394,
+ 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c,
+ 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5,
+ 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, 0x03b3, 0x03b4,
+ 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc,
+ 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5,
+ 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x3105, 0x3106, 0x3107, 0x3108,
+ 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110,
+ 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118,
+ 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120,
+ 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128,
+ 0x3129, 0x02d9, 0x02c9, 0x02ca, 0x02c7, 0x02cb, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0xa4 */
+ 0x4e00, 0x4e59, 0x4e01, 0x4e03, 0x4e43, 0x4e5d, 0x4e86, 0x4e8c,
+ 0x4eba, 0x513f, 0x5165, 0x516b, 0x51e0, 0x5200, 0x5201, 0x529b,
+ 0x5315, 0x5341, 0x535c, 0x53c8, 0x4e09, 0x4e0b, 0x4e08, 0x4e0a,
+ 0x4e2b, 0x4e38, 0x51e1, 0x4e45, 0x4e48, 0x4e5f, 0x4e5e, 0x4e8e,
+ 0x4ea1, 0x5140, 0x5203, 0x52fa, 0x5343, 0x53c9, 0x53e3, 0x571f,
+ 0x58eb, 0x5915, 0x5927, 0x5973, 0x5b50, 0x5b51, 0x5b53, 0x5bf8,
+ 0x5c0f, 0x5c22, 0x5c38, 0x5c71, 0x5ddd, 0x5de5, 0x5df1, 0x5df2,
+ 0x5df3, 0x5dfe, 0x5e72, 0x5efe, 0x5f0b, 0x5f13, 0x624d, 0x4e11,
+ 0x4e10, 0x4e0d, 0x4e2d, 0x4e30, 0x4e39, 0x4e4b, 0x5c39, 0x4e88,
+ 0x4e91, 0x4e95, 0x4e92, 0x4e94, 0x4ea2, 0x4ec1, 0x4ec0, 0x4ec3,
+ 0x4ec6, 0x4ec7, 0x4ecd, 0x4eca, 0x4ecb, 0x4ec4, 0x5143, 0x5141,
+ 0x5167, 0x516d, 0x516e, 0x516c, 0x5197, 0x51f6, 0x5206, 0x5207,
+ 0x5208, 0x52fb, 0x52fe, 0x52ff, 0x5316, 0x5339, 0x5348, 0x5347,
+ 0x5345, 0x535e, 0x5384, 0x53cb, 0x53ca, 0x53cd, 0x58ec, 0x5929,
+ 0x592b, 0x592a, 0x592d, 0x5b54, 0x5c11, 0x5c24, 0x5c3a, 0x5c6f,
+ 0x5df4, 0x5e7b, 0x5eff, 0x5f14, 0x5f15, 0x5fc3, 0x6208, 0x6236,
+ 0x624b, 0x624e, 0x652f, 0x6587, 0x6597, 0x65a4, 0x65b9, 0x65e5,
+ 0x66f0, 0x6708, 0x6728, 0x6b20, 0x6b62, 0x6b79, 0x6bcb, 0x6bd4,
+ 0x6bdb, 0x6c0f, 0x6c34, 0x706b, 0x722a, 0x7236, 0x723b, 0x7247,
+ 0x7259, 0x725b, 0x72ac, 0x738b, 0x4e19,
+ /* 0xa5 */
+ 0x4e16, 0x4e15, 0x4e14, 0x4e18, 0x4e3b, 0x4e4d, 0x4e4f, 0x4e4e,
+ 0x4ee5, 0x4ed8, 0x4ed4, 0x4ed5, 0x4ed6, 0x4ed7, 0x4ee3, 0x4ee4,
+ 0x4ed9, 0x4ede, 0x5145, 0x5144, 0x5189, 0x518a, 0x51ac, 0x51f9,
+ 0x51fa, 0x51f8, 0x520a, 0x52a0, 0x529f, 0x5305, 0x5306, 0x5317,
+ 0x531d, 0x4edf, 0x534a, 0x5349, 0x5361, 0x5360, 0x536f, 0x536e,
+ 0x53bb, 0x53ef, 0x53e4, 0x53f3, 0x53ec, 0x53ee, 0x53e9, 0x53e8,
+ 0x53fc, 0x53f8, 0x53f5, 0x53eb, 0x53e6, 0x53ea, 0x53f2, 0x53f1,
+ 0x53f0, 0x53e5, 0x53ed, 0x53fb, 0x56db, 0x56da, 0x5916, 0x592e,
+ 0x5931, 0x5974, 0x5976, 0x5b55, 0x5b83, 0x5c3c, 0x5de8, 0x5de7,
+ 0x5de6, 0x5e02, 0x5e03, 0x5e73, 0x5e7c, 0x5f01, 0x5f18, 0x5f17,
+ 0x5fc5, 0x620a, 0x6253, 0x6254, 0x6252, 0x6251, 0x65a5, 0x65e6,
+ 0x672e, 0x672c, 0x672a, 0x672b, 0x672d, 0x6b63, 0x6bcd, 0x6c11,
+ 0x6c10, 0x6c38, 0x6c41, 0x6c40, 0x6c3e, 0x72af, 0x7384, 0x7389,
+ 0x74dc, 0x74e6, 0x7518, 0x751f, 0x7528, 0x7529, 0x7530, 0x7531,
+ 0x7532, 0x7533, 0x758b, 0x767d, 0x76ae, 0x76bf, 0x76ee, 0x77db,
+ 0x77e2, 0x77f3, 0x793a, 0x79be, 0x7a74, 0x7acb, 0x4e1e, 0x4e1f,
+ 0x4e52, 0x4e53, 0x4e69, 0x4e99, 0x4ea4, 0x4ea6, 0x4ea5, 0x4eff,
+ 0x4f09, 0x4f19, 0x4f0a, 0x4f15, 0x4f0d, 0x4f10, 0x4f11, 0x4f0f,
+ 0x4ef2, 0x4ef6, 0x4efb, 0x4ef0, 0x4ef3, 0x4efd, 0x4f01, 0x4f0b,
+ 0x5149, 0x5147, 0x5146, 0x5148, 0x5168,
+ /* 0xa6 */
+ 0x5171, 0x518d, 0x51b0, 0x5217, 0x5211, 0x5212, 0x520e, 0x5216,
+ 0x52a3, 0x5308, 0x5321, 0x5320, 0x5370, 0x5371, 0x5409, 0x540f,
+ 0x540c, 0x540a, 0x5410, 0x5401, 0x540b, 0x5404, 0x5411, 0x540d,
+ 0x5408, 0x5403, 0x540e, 0x5406, 0x5412, 0x56e0, 0x56de, 0x56dd,
+ 0x5733, 0x5730, 0x5728, 0x572d, 0x572c, 0x572f, 0x5729, 0x5919,
+ 0x591a, 0x5937, 0x5938, 0x5984, 0x5978, 0x5983, 0x597d, 0x5979,
+ 0x5982, 0x5981, 0x5b57, 0x5b58, 0x5b87, 0x5b88, 0x5b85, 0x5b89,
+ 0x5bfa, 0x5c16, 0x5c79, 0x5dde, 0x5e06, 0x5e76, 0x5e74, 0x5f0f,
+ 0x5f1b, 0x5fd9, 0x5fd6, 0x620e, 0x620c, 0x620d, 0x6210, 0x6263,
+ 0x625b, 0x6258, 0x6536, 0x65e9, 0x65e8, 0x65ec, 0x65ed, 0x66f2,
+ 0x66f3, 0x6709, 0x673d, 0x6734, 0x6731, 0x6735, 0x6b21, 0x6b64,
+ 0x6b7b, 0x6c16, 0x6c5d, 0x6c57, 0x6c59, 0x6c5f, 0x6c60, 0x6c50,
+ 0x6c55, 0x6c61, 0x6c5b, 0x6c4d, 0x6c4e, 0x7070, 0x725f, 0x725d,
+ 0x767e, 0x7af9, 0x7c73, 0x7cf8, 0x7f36, 0x7f8a, 0x7fbd, 0x8001,
+ 0x8003, 0x800c, 0x8012, 0x8033, 0x807f, 0x8089, 0x808b, 0x808c,
+ 0x81e3, 0x81ea, 0x81f3, 0x81fc, 0x820c, 0x821b, 0x821f, 0x826e,
+ 0x8272, 0x827e, 0x866b, 0x8840, 0x884c, 0x8863, 0x897f, 0x9621,
+ 0x4e32, 0x4ea8, 0x4f4d, 0x4f4f, 0x4f47, 0x4f57, 0x4f5e, 0x4f34,
+ 0x4f5b, 0x4f55, 0x4f30, 0x4f50, 0x4f51, 0x4f3d, 0x4f3a, 0x4f38,
+ 0x4f43, 0x4f54, 0x4f3c, 0x4f46, 0x4f63,
+ /* 0xa7 */
+ 0x4f5c, 0x4f60, 0x4f2f, 0x4f4e, 0x4f36, 0x4f59, 0x4f5d, 0x4f48,
+ 0x4f5a, 0x514c, 0x514b, 0x514d, 0x5175, 0x51b6, 0x51b7, 0x5225,
+ 0x5224, 0x5229, 0x522a, 0x5228, 0x52ab, 0x52a9, 0x52aa, 0x52ac,
+ 0x5323, 0x5373, 0x5375, 0x541d, 0x542d, 0x541e, 0x543e, 0x5426,
+ 0x544e, 0x5427, 0x5446, 0x5443, 0x5433, 0x5448, 0x5442, 0x541b,
+ 0x5429, 0x544a, 0x5439, 0x543b, 0x5438, 0x542e, 0x5435, 0x5436,
+ 0x5420, 0x543c, 0x5440, 0x5431, 0x542b, 0x541f, 0x542c, 0x56ea,
+ 0x56f0, 0x56e4, 0x56eb, 0x574a, 0x5751, 0x5740, 0x574d, 0x5747,
+ 0x574e, 0x573e, 0x5750, 0x574f, 0x573b, 0x58ef, 0x593e, 0x599d,
+ 0x5992, 0x59a8, 0x599e, 0x59a3, 0x5999, 0x5996, 0x598d, 0x59a4,
+ 0x5993, 0x598a, 0x59a5, 0x5b5d, 0x5b5c, 0x5b5a, 0x5b5b, 0x5b8c,
+ 0x5b8b, 0x5b8f, 0x5c2c, 0x5c40, 0x5c41, 0x5c3f, 0x5c3e, 0x5c90,
+ 0x5c91, 0x5c94, 0x5c8c, 0x5deb, 0x5e0c, 0x5e8f, 0x5e87, 0x5e8a,
+ 0x5ef7, 0x5f04, 0x5f1f, 0x5f64, 0x5f62, 0x5f77, 0x5f79, 0x5fd8,
+ 0x5fcc, 0x5fd7, 0x5fcd, 0x5ff1, 0x5feb, 0x5ff8, 0x5fea, 0x6212,
+ 0x6211, 0x6284, 0x6297, 0x6296, 0x6280, 0x6276, 0x6289, 0x626d,
+ 0x628a, 0x627c, 0x627e, 0x6279, 0x6273, 0x6292, 0x626f, 0x6298,
+ 0x626e, 0x6295, 0x6293, 0x6291, 0x6286, 0x6539, 0x653b, 0x6538,
+ 0x65f1, 0x66f4, 0x675f, 0x674e, 0x674f, 0x6750, 0x6751, 0x675c,
+ 0x6756, 0x675e, 0x6749, 0x6746, 0x6760,
+ /* 0xa8 */
+ 0x6753, 0x6757, 0x6b65, 0x6bcf, 0x6c42, 0x6c5e, 0x6c99, 0x6c81,
+ 0x6c88, 0x6c89, 0x6c85, 0x6c9b, 0x6c6a, 0x6c7a, 0x6c90, 0x6c70,
+ 0x6c8c, 0x6c68, 0x6c96, 0x6c92, 0x6c7d, 0x6c83, 0x6c72, 0x6c7e,
+ 0x6c74, 0x6c86, 0x6c76, 0x6c8d, 0x6c94, 0x6c98, 0x6c82, 0x7076,
+ 0x707c, 0x707d, 0x7078, 0x7262, 0x7261, 0x7260, 0x72c4, 0x72c2,
+ 0x7396, 0x752c, 0x752b, 0x7537, 0x7538, 0x7682, 0x76ef, 0x77e3,
+ 0x79c1, 0x79c0, 0x79bf, 0x7a76, 0x7cfb, 0x7f55, 0x8096, 0x8093,
+ 0x809d, 0x8098, 0x809b, 0x809a, 0x80b2, 0x826f, 0x8292, 0x828b,
+ 0x828d, 0x898b, 0x89d2, 0x8a00, 0x8c37, 0x8c46, 0x8c55, 0x8c9d,
+ 0x8d64, 0x8d70, 0x8db3, 0x8eab, 0x8eca, 0x8f9b, 0x8fb0, 0x8fc2,
+ 0x8fc6, 0x8fc5, 0x8fc4, 0x5de1, 0x9091, 0x90a2, 0x90aa, 0x90a6,
+ 0x90a3, 0x9149, 0x91c6, 0x91cc, 0x9632, 0x962e, 0x9631, 0x962a,
+ 0x962c, 0x4e26, 0x4e56, 0x4e73, 0x4e8b, 0x4e9b, 0x4e9e, 0x4eab,
+ 0x4eac, 0x4f6f, 0x4f9d, 0x4f8d, 0x4f73, 0x4f7f, 0x4f6c, 0x4f9b,
+ 0x4f8b, 0x4f86, 0x4f83, 0x4f70, 0x4f75, 0x4f88, 0x4f69, 0x4f7b,
+ 0x4f96, 0x4f7e, 0x4f8f, 0x4f91, 0x4f7a, 0x5154, 0x5152, 0x5155,
+ 0x5169, 0x5177, 0x5176, 0x5178, 0x51bd, 0x51fd, 0x523b, 0x5238,
+ 0x5237, 0x523a, 0x5230, 0x522e, 0x5236, 0x5241, 0x52be, 0x52bb,
+ 0x5352, 0x5354, 0x5353, 0x5351, 0x5366, 0x5377, 0x5378, 0x5379,
+ 0x53d6, 0x53d4, 0x53d7, 0x5473, 0x5475,
+ /* 0xa9 */
+ 0x5496, 0x5478, 0x5495, 0x5480, 0x547b, 0x5477, 0x5484, 0x5492,
+ 0x5486, 0x547c, 0x5490, 0x5471, 0x5476, 0x548c, 0x549a, 0x5462,
+ 0x5468, 0x548b, 0x547d, 0x548e, 0x56fa, 0x5783, 0x5777, 0x576a,
+ 0x5769, 0x5761, 0x5766, 0x5764, 0x577c, 0x591c, 0x5949, 0x5947,
+ 0x5948, 0x5944, 0x5954, 0x59be, 0x59bb, 0x59d4, 0x59b9, 0x59ae,
+ 0x59d1, 0x59c6, 0x59d0, 0x59cd, 0x59cb, 0x59d3, 0x59ca, 0x59af,
+ 0x59b3, 0x59d2, 0x59c5, 0x5b5f, 0x5b64, 0x5b63, 0x5b97, 0x5b9a,
+ 0x5b98, 0x5b9c, 0x5b99, 0x5b9b, 0x5c1a, 0x5c48, 0x5c45, 0x5c46,
+ 0x5cb7, 0x5ca1, 0x5cb8, 0x5ca9, 0x5cab, 0x5cb1, 0x5cb3, 0x5e18,
+ 0x5e1a, 0x5e16, 0x5e15, 0x5e1b, 0x5e11, 0x5e78, 0x5e9a, 0x5e97,
+ 0x5e9c, 0x5e95, 0x5e96, 0x5ef6, 0x5f26, 0x5f27, 0x5f29, 0x5f80,
+ 0x5f81, 0x5f7f, 0x5f7c, 0x5fdd, 0x5fe0, 0x5ffd, 0x5ff5, 0x5fff,
+ 0x600f, 0x6014, 0x602f, 0x6035, 0x6016, 0x602a, 0x6015, 0x6021,
+ 0x6027, 0x6029, 0x602b, 0x601b, 0x6216, 0x6215, 0x623f, 0x623e,
+ 0x6240, 0x627f, 0x62c9, 0x62cc, 0x62c4, 0x62bf, 0x62c2, 0x62b9,
+ 0x62d2, 0x62db, 0x62ab, 0x62d3, 0x62d4, 0x62cb, 0x62c8, 0x62a8,
+ 0x62bd, 0x62bc, 0x62d0, 0x62d9, 0x62c7, 0x62cd, 0x62b5, 0x62da,
+ 0x62b1, 0x62d8, 0x62d6, 0x62d7, 0x62c6, 0x62ac, 0x62ce, 0x653e,
+ 0x65a7, 0x65bc, 0x65fa, 0x6614, 0x6613, 0x660c, 0x6606, 0x6602,
+ 0x660e, 0x6600, 0x660f, 0x6615, 0x660a,
+ /* 0xaa */
+ 0x6607, 0x670d, 0x670b, 0x676d, 0x678b, 0x6795, 0x6771, 0x679c,
+ 0x6773, 0x6777, 0x6787, 0x679d, 0x6797, 0x676f, 0x6770, 0x677f,
+ 0x6789, 0x677e, 0x6790, 0x6775, 0x679a, 0x6793, 0x677c, 0x676a,
+ 0x6772, 0x6b23, 0x6b66, 0x6b67, 0x6b7f, 0x6c13, 0x6c1b, 0x6ce3,
+ 0x6ce8, 0x6cf3, 0x6cb1, 0x6ccc, 0x6ce5, 0x6cb3, 0x6cbd, 0x6cbe,
+ 0x6cbc, 0x6ce2, 0x6cab, 0x6cd5, 0x6cd3, 0x6cb8, 0x6cc4, 0x6cb9,
+ 0x6cc1, 0x6cae, 0x6cd7, 0x6cc5, 0x6cf1, 0x6cbf, 0x6cbb, 0x6ce1,
+ 0x6cdb, 0x6cca, 0x6cac, 0x6cef, 0x6cdc, 0x6cd6, 0x6ce0, 0x7095,
+ 0x708e, 0x7092, 0x708a, 0x7099, 0x722c, 0x722d, 0x7238, 0x7248,
+ 0x7267, 0x7269, 0x72c0, 0x72ce, 0x72d9, 0x72d7, 0x72d0, 0x73a9,
+ 0x73a8, 0x739f, 0x73ab, 0x73a5, 0x753d, 0x759d, 0x7599, 0x759a,
+ 0x7684, 0x76c2, 0x76f2, 0x76f4, 0x77e5, 0x77fd, 0x793e, 0x7940,
+ 0x7941, 0x79c9, 0x79c8, 0x7a7a, 0x7a79, 0x7afa, 0x7cfe, 0x7f54,
+ 0x7f8c, 0x7f8b, 0x8005, 0x80ba, 0x80a5, 0x80a2, 0x80b1, 0x80a1,
+ 0x80ab, 0x80a9, 0x80b4, 0x80aa, 0x80af, 0x81e5, 0x81fe, 0x820d,
+ 0x82b3, 0x829d, 0x8299, 0x82ad, 0x82bd, 0x829f, 0x82b9, 0x82b1,
+ 0x82ac, 0x82a5, 0x82af, 0x82b8, 0x82a3, 0x82b0, 0x82be, 0x82b7,
+ 0x864e, 0x8671, 0x521d, 0x8868, 0x8ecb, 0x8fce, 0x8fd4, 0x8fd1,
+ 0x90b5, 0x90b8, 0x90b1, 0x90b6, 0x91c7, 0x91d1, 0x9577, 0x9580,
+ 0x961c, 0x9640, 0x963f, 0x963b, 0x9644,
+ /* 0xab */
+ 0x9642, 0x96b9, 0x96e8, 0x9752, 0x975e, 0x4e9f, 0x4ead, 0x4eae,
+ 0x4fe1, 0x4fb5, 0x4faf, 0x4fbf, 0x4fe0, 0x4fd1, 0x4fcf, 0x4fdd,
+ 0x4fc3, 0x4fb6, 0x4fd8, 0x4fdf, 0x4fca, 0x4fd7, 0x4fae, 0x4fd0,
+ 0x4fc4, 0x4fc2, 0x4fda, 0x4fce, 0x4fde, 0x4fb7, 0x5157, 0x5192,
+ 0x5191, 0x51a0, 0x524e, 0x5243, 0x524a, 0x524d, 0x524c, 0x524b,
+ 0x5247, 0x52c7, 0x52c9, 0x52c3, 0x52c1, 0x530d, 0x5357, 0x537b,
+ 0x539a, 0x53db, 0x54ac, 0x54c0, 0x54a8, 0x54ce, 0x54c9, 0x54b8,
+ 0x54a6, 0x54b3, 0x54c7, 0x54c2, 0x54bd, 0x54aa, 0x54c1, 0x54c4,
+ 0x54c8, 0x54af, 0x54ab, 0x54b1, 0x54bb, 0x54a9, 0x54a7, 0x54bf,
+ 0x56ff, 0x5782, 0x578b, 0x57a0, 0x57a3, 0x57a2, 0x57ce, 0x57ae,
+ 0x5793, 0x5955, 0x5951, 0x594f, 0x594e, 0x5950, 0x59dc, 0x59d8,
+ 0x59ff, 0x59e3, 0x59e8, 0x5a03, 0x59e5, 0x59ea, 0x59da, 0x59e6,
+ 0x5a01, 0x59fb, 0x5b69, 0x5ba3, 0x5ba6, 0x5ba4, 0x5ba2, 0x5ba5,
+ 0x5c01, 0x5c4e, 0x5c4f, 0x5c4d, 0x5c4b, 0x5cd9, 0x5cd2, 0x5df7,
+ 0x5e1d, 0x5e25, 0x5e1f, 0x5e7d, 0x5ea0, 0x5ea6, 0x5efa, 0x5f08,
+ 0x5f2d, 0x5f65, 0x5f88, 0x5f85, 0x5f8a, 0x5f8b, 0x5f87, 0x5f8c,
+ 0x5f89, 0x6012, 0x601d, 0x6020, 0x6025, 0x600e, 0x6028, 0x604d,
+ 0x6070, 0x6068, 0x6062, 0x6046, 0x6043, 0x606c, 0x606b, 0x606a,
+ 0x6064, 0x6241, 0x62dc, 0x6316, 0x6309, 0x62fc, 0x62ed, 0x6301,
+ 0x62ee, 0x62fd, 0x6307, 0x62f1, 0x62f7,
+ /* 0xac */
+ 0x62ef, 0x62ec, 0x62fe, 0x62f4, 0x6311, 0x6302, 0x653f, 0x6545,
+ 0x65ab, 0x65bd, 0x65e2, 0x6625, 0x662d, 0x6620, 0x6627, 0x662f,
+ 0x661f, 0x6628, 0x6631, 0x6624, 0x66f7, 0x67ff, 0x67d3, 0x67f1,
+ 0x67d4, 0x67d0, 0x67ec, 0x67b6, 0x67af, 0x67f5, 0x67e9, 0x67ef,
+ 0x67c4, 0x67d1, 0x67b4, 0x67da, 0x67e5, 0x67b8, 0x67cf, 0x67de,
+ 0x67f3, 0x67b0, 0x67d9, 0x67e2, 0x67dd, 0x67d2, 0x6b6a, 0x6b83,
+ 0x6b86, 0x6bb5, 0x6bd2, 0x6bd7, 0x6c1f, 0x6cc9, 0x6d0b, 0x6d32,
+ 0x6d2a, 0x6d41, 0x6d25, 0x6d0c, 0x6d31, 0x6d1e, 0x6d17, 0x6d3b,
+ 0x6d3d, 0x6d3e, 0x6d36, 0x6d1b, 0x6cf5, 0x6d39, 0x6d27, 0x6d38,
+ 0x6d29, 0x6d2e, 0x6d35, 0x6d0e, 0x6d2b, 0x70ab, 0x70ba, 0x70b3,
+ 0x70ac, 0x70af, 0x70ad, 0x70b8, 0x70ae, 0x70a4, 0x7230, 0x7272,
+ 0x726f, 0x7274, 0x72e9, 0x72e0, 0x72e1, 0x73b7, 0x73ca, 0x73bb,
+ 0x73b2, 0x73cd, 0x73c0, 0x73b3, 0x751a, 0x752d, 0x754f, 0x754c,
+ 0x754e, 0x754b, 0x75ab, 0x75a4, 0x75a5, 0x75a2, 0x75a3, 0x7678,
+ 0x7686, 0x7687, 0x7688, 0x76c8, 0x76c6, 0x76c3, 0x76c5, 0x7701,
+ 0x76f9, 0x76f8, 0x7709, 0x770b, 0x76fe, 0x76fc, 0x7707, 0x77dc,
+ 0x7802, 0x7814, 0x780c, 0x780d, 0x7946, 0x7949, 0x7948, 0x7947,
+ 0x79b9, 0x79ba, 0x79d1, 0x79d2, 0x79cb, 0x7a7f, 0x7a81, 0x7aff,
+ 0x7afd, 0x7c7d, 0x7d02, 0x7d05, 0x7d00, 0x7d09, 0x7d07, 0x7d04,
+ 0x7d06, 0x7f38, 0x7f8e, 0x7fbf, 0x8004,
+ /* 0xad */
+ 0x8010, 0x800d, 0x8011, 0x8036, 0x80d6, 0x80e5, 0x80da, 0x80c3,
+ 0x80c4, 0x80cc, 0x80e1, 0x80db, 0x80ce, 0x80de, 0x80e4, 0x80dd,
+ 0x81f4, 0x8222, 0x82e7, 0x8303, 0x8305, 0x82e3, 0x82db, 0x82e6,
+ 0x8304, 0x82e5, 0x8302, 0x8309, 0x82d2, 0x82d7, 0x82f1, 0x8301,
+ 0x82dc, 0x82d4, 0x82d1, 0x82de, 0x82d3, 0x82df, 0x82ef, 0x8306,
+ 0x8650, 0x8679, 0x867b, 0x867a, 0x884d, 0x886b, 0x8981, 0x89d4,
+ 0x8a08, 0x8a02, 0x8a03, 0x8c9e, 0x8ca0, 0x8d74, 0x8d73, 0x8db4,
+ 0x8ecd, 0x8ecc, 0x8ff0, 0x8fe6, 0x8fe2, 0x8fea, 0x8fe5, 0x8fed,
+ 0x8feb, 0x8fe4, 0x8fe8, 0x90ca, 0x90ce, 0x90c1, 0x90c3, 0x914b,
+ 0x914a, 0x91cd, 0x9582, 0x9650, 0x964b, 0x964c, 0x964d, 0x9762,
+ 0x9769, 0x97cb, 0x97ed, 0x97f3, 0x9801, 0x98a8, 0x98db, 0x98df,
+ 0x9996, 0x9999, 0x4e58, 0x4eb3, 0x500c, 0x500d, 0x5023, 0x4fef,
+ 0x5026, 0x5025, 0x4ff8, 0x5029, 0x5016, 0x5006, 0x503c, 0x501f,
+ 0x501a, 0x5012, 0x5011, 0x4ffa, 0x5000, 0x5014, 0x5028, 0x4ff1,
+ 0x5021, 0x500b, 0x5019, 0x5018, 0x4ff3, 0x4fee, 0x502d, 0x502a,
+ 0x4ffe, 0x502b, 0x5009, 0x517c, 0x51a4, 0x51a5, 0x51a2, 0x51cd,
+ 0x51cc, 0x51c6, 0x51cb, 0x5256, 0x525c, 0x5254, 0x525b, 0x525d,
+ 0x532a, 0x537f, 0x539f, 0x539d, 0x53df, 0x54e8, 0x5510, 0x5501,
+ 0x5537, 0x54fc, 0x54e5, 0x54f2, 0x5506, 0x54fa, 0x5514, 0x54e9,
+ 0x54ed, 0x54e1, 0x5509, 0x54ee, 0x54ea,
+ /* 0xae */
+ 0x54e6, 0x5527, 0x5507, 0x54fd, 0x550f, 0x5703, 0x5704, 0x57c2,
+ 0x57d4, 0x57cb, 0x57c3, 0x5809, 0x590f, 0x5957, 0x5958, 0x595a,
+ 0x5a11, 0x5a18, 0x5a1c, 0x5a1f, 0x5a1b, 0x5a13, 0x59ec, 0x5a20,
+ 0x5a23, 0x5a29, 0x5a25, 0x5a0c, 0x5a09, 0x5b6b, 0x5c58, 0x5bb0,
+ 0x5bb3, 0x5bb6, 0x5bb4, 0x5bae, 0x5bb5, 0x5bb9, 0x5bb8, 0x5c04,
+ 0x5c51, 0x5c55, 0x5c50, 0x5ced, 0x5cfd, 0x5cfb, 0x5cea, 0x5ce8,
+ 0x5cf0, 0x5cf6, 0x5d01, 0x5cf4, 0x5dee, 0x5e2d, 0x5e2b, 0x5eab,
+ 0x5ead, 0x5ea7, 0x5f31, 0x5f92, 0x5f91, 0x5f90, 0x6059, 0x6063,
+ 0x6065, 0x6050, 0x6055, 0x606d, 0x6069, 0x606f, 0x6084, 0x609f,
+ 0x609a, 0x608d, 0x6094, 0x608c, 0x6085, 0x6096, 0x6247, 0x62f3,
+ 0x6308, 0x62ff, 0x634e, 0x633e, 0x632f, 0x6355, 0x6342, 0x6346,
+ 0x634f, 0x6349, 0x633a, 0x6350, 0x633d, 0x632a, 0x632b, 0x6328,
+ 0x634d, 0x634c, 0x6548, 0x6549, 0x6599, 0x65c1, 0x65c5, 0x6642,
+ 0x6649, 0x664f, 0x6643, 0x6652, 0x664c, 0x6645, 0x6641, 0x66f8,
+ 0x6714, 0x6715, 0x6717, 0x6821, 0x6838, 0x6848, 0x6846, 0x6853,
+ 0x6839, 0x6842, 0x6854, 0x6829, 0x68b3, 0x6817, 0x684c, 0x6851,
+ 0x683d, 0x67f4, 0x6850, 0x6840, 0x683c, 0x6843, 0x682a, 0x6845,
+ 0x6813, 0x6818, 0x6841, 0x6b8a, 0x6b89, 0x6bb7, 0x6c23, 0x6c27,
+ 0x6c28, 0x6c26, 0x6c24, 0x6cf0, 0x6d6a, 0x6d95, 0x6d88, 0x6d87,
+ 0x6d66, 0x6d78, 0x6d77, 0x6d59, 0x6d93,
+ /* 0xaf */
+ 0x6d6c, 0x6d89, 0x6d6e, 0x6d5a, 0x6d74, 0x6d69, 0x6d8c, 0x6d8a,
+ 0x6d79, 0x6d85, 0x6d65, 0x6d94, 0x70ca, 0x70d8, 0x70e4, 0x70d9,
+ 0x70c8, 0x70cf, 0x7239, 0x7279, 0x72fc, 0x72f9, 0x72fd, 0x72f8,
+ 0x72f7, 0x7386, 0x73ed, 0x7409, 0x73ee, 0x73e0, 0x73ea, 0x73de,
+ 0x7554, 0x755d, 0x755c, 0x755a, 0x7559, 0x75be, 0x75c5, 0x75c7,
+ 0x75b2, 0x75b3, 0x75bd, 0x75bc, 0x75b9, 0x75c2, 0x75b8, 0x768b,
+ 0x76b0, 0x76ca, 0x76cd, 0x76ce, 0x7729, 0x771f, 0x7720, 0x7728,
+ 0x77e9, 0x7830, 0x7827, 0x7838, 0x781d, 0x7834, 0x7837, 0x7825,
+ 0x782d, 0x7820, 0x781f, 0x7832, 0x7955, 0x7950, 0x7960, 0x795f,
+ 0x7956, 0x795e, 0x795d, 0x7957, 0x795a, 0x79e4, 0x79e3, 0x79e7,
+ 0x79df, 0x79e6, 0x79e9, 0x79d8, 0x7a84, 0x7a88, 0x7ad9, 0x7b06,
+ 0x7b11, 0x7c89, 0x7d21, 0x7d17, 0x7d0b, 0x7d0a, 0x7d20, 0x7d22,
+ 0x7d14, 0x7d10, 0x7d15, 0x7d1a, 0x7d1c, 0x7d0d, 0x7d19, 0x7d1b,
+ 0x7f3a, 0x7f5f, 0x7f94, 0x7fc5, 0x7fc1, 0x8006, 0x8018, 0x8015,
+ 0x8019, 0x8017, 0x803d, 0x803f, 0x80f1, 0x8102, 0x80f0, 0x8105,
+ 0x80ed, 0x80f4, 0x8106, 0x80f8, 0x80f3, 0x8108, 0x80fd, 0x810a,
+ 0x80fc, 0x80ef, 0x81ed, 0x81ec, 0x8200, 0x8210, 0x822a, 0x822b,
+ 0x8228, 0x822c, 0x82bb, 0x832b, 0x8352, 0x8354, 0x834a, 0x8338,
+ 0x8350, 0x8349, 0x8335, 0x8334, 0x834f, 0x8332, 0x8339, 0x8336,
+ 0x8317, 0x8340, 0x8331, 0x8328, 0x8343,
+ /* 0xb0 */
+ 0x8654, 0x868a, 0x86aa, 0x8693, 0x86a4, 0x86a9, 0x868c, 0x86a3,
+ 0x869c, 0x8870, 0x8877, 0x8881, 0x8882, 0x887d, 0x8879, 0x8a18,
+ 0x8a10, 0x8a0e, 0x8a0c, 0x8a15, 0x8a0a, 0x8a17, 0x8a13, 0x8a16,
+ 0x8a0f, 0x8a11, 0x8c48, 0x8c7a, 0x8c79, 0x8ca1, 0x8ca2, 0x8d77,
+ 0x8eac, 0x8ed2, 0x8ed4, 0x8ecf, 0x8fb1, 0x9001, 0x9006, 0x8ff7,
+ 0x9000, 0x8ffa, 0x8ff4, 0x9003, 0x8ffd, 0x9005, 0x8ff8, 0x9095,
+ 0x90e1, 0x90dd, 0x90e2, 0x9152, 0x914d, 0x914c, 0x91d8, 0x91dd,
+ 0x91d7, 0x91dc, 0x91d9, 0x9583, 0x9662, 0x9663, 0x9661, 0x965b,
+ 0x965d, 0x9664, 0x9658, 0x965e, 0x96bb, 0x98e2, 0x99ac, 0x9aa8,
+ 0x9ad8, 0x9b25, 0x9b32, 0x9b3c, 0x4e7e, 0x507a, 0x507d, 0x505c,
+ 0x5047, 0x5043, 0x504c, 0x505a, 0x5049, 0x5065, 0x5076, 0x504e,
+ 0x5055, 0x5075, 0x5074, 0x5077, 0x504f, 0x500f, 0x506f, 0x506d,
+ 0x515c, 0x5195, 0x51f0, 0x526a, 0x526f, 0x52d2, 0x52d9, 0x52d8,
+ 0x52d5, 0x5310, 0x530f, 0x5319, 0x533f, 0x5340, 0x533e, 0x53c3,
+ 0x66fc, 0x5546, 0x556a, 0x5566, 0x5544, 0x555e, 0x5561, 0x5543,
+ 0x554a, 0x5531, 0x5556, 0x554f, 0x5555, 0x552f, 0x5564, 0x5538,
+ 0x552e, 0x555c, 0x552c, 0x5563, 0x5533, 0x5541, 0x5557, 0x5708,
+ 0x570b, 0x5709, 0x57df, 0x5805, 0x580a, 0x5806, 0x57e0, 0x57e4,
+ 0x57fa, 0x5802, 0x5835, 0x57f7, 0x57f9, 0x5920, 0x5962, 0x5a36,
+ 0x5a41, 0x5a49, 0x5a66, 0x5a6a, 0x5a40,
+ /* 0xb1 */
+ 0x5a3c, 0x5a62, 0x5a5a, 0x5a46, 0x5a4a, 0x5b70, 0x5bc7, 0x5bc5,
+ 0x5bc4, 0x5bc2, 0x5bbf, 0x5bc6, 0x5c09, 0x5c08, 0x5c07, 0x5c60,
+ 0x5c5c, 0x5c5d, 0x5d07, 0x5d06, 0x5d0e, 0x5d1b, 0x5d16, 0x5d22,
+ 0x5d11, 0x5d29, 0x5d14, 0x5d19, 0x5d24, 0x5d27, 0x5d17, 0x5de2,
+ 0x5e38, 0x5e36, 0x5e33, 0x5e37, 0x5eb7, 0x5eb8, 0x5eb6, 0x5eb5,
+ 0x5ebe, 0x5f35, 0x5f37, 0x5f57, 0x5f6c, 0x5f69, 0x5f6b, 0x5f97,
+ 0x5f99, 0x5f9e, 0x5f98, 0x5fa1, 0x5fa0, 0x5f9c, 0x607f, 0x60a3,
+ 0x6089, 0x60a0, 0x60a8, 0x60cb, 0x60b4, 0x60e6, 0x60bd, 0x60c5,
+ 0x60bb, 0x60b5, 0x60dc, 0x60bc, 0x60d8, 0x60d5, 0x60c6, 0x60df,
+ 0x60b8, 0x60da, 0x60c7, 0x621a, 0x621b, 0x6248, 0x63a0, 0x63a7,
+ 0x6372, 0x6396, 0x63a2, 0x63a5, 0x6377, 0x6367, 0x6398, 0x63aa,
+ 0x6371, 0x63a9, 0x6389, 0x6383, 0x639b, 0x636b, 0x63a8, 0x6384,
+ 0x6388, 0x6399, 0x63a1, 0x63ac, 0x6392, 0x638f, 0x6380, 0x637b,
+ 0x6369, 0x6368, 0x637a, 0x655d, 0x6556, 0x6551, 0x6559, 0x6557,
+ 0x555f, 0x654f, 0x6558, 0x6555, 0x6554, 0x659c, 0x659b, 0x65ac,
+ 0x65cf, 0x65cb, 0x65cc, 0x65ce, 0x665d, 0x665a, 0x6664, 0x6668,
+ 0x6666, 0x665e, 0x66f9, 0x52d7, 0x671b, 0x6881, 0x68af, 0x68a2,
+ 0x6893, 0x68b5, 0x687f, 0x6876, 0x68b1, 0x68a7, 0x6897, 0x68b0,
+ 0x6883, 0x68c4, 0x68ad, 0x6886, 0x6885, 0x6894, 0x689d, 0x68a8,
+ 0x689f, 0x68a1, 0x6882, 0x6b32, 0x6bba,
+ /* 0xb2 */
+ 0x6beb, 0x6bec, 0x6c2b, 0x6d8e, 0x6dbc, 0x6df3, 0x6dd9, 0x6db2,
+ 0x6de1, 0x6dcc, 0x6de4, 0x6dfb, 0x6dfa, 0x6e05, 0x6dc7, 0x6dcb,
+ 0x6daf, 0x6dd1, 0x6dae, 0x6dde, 0x6df9, 0x6db8, 0x6df7, 0x6df5,
+ 0x6dc5, 0x6dd2, 0x6e1a, 0x6db5, 0x6dda, 0x6deb, 0x6dd8, 0x6dea,
+ 0x6df1, 0x6dee, 0x6de8, 0x6dc6, 0x6dc4, 0x6daa, 0x6dec, 0x6dbf,
+ 0x6de6, 0x70f9, 0x7109, 0x710a, 0x70fd, 0x70ef, 0x723d, 0x727d,
+ 0x7281, 0x731c, 0x731b, 0x7316, 0x7313, 0x7319, 0x7387, 0x7405,
+ 0x740a, 0x7403, 0x7406, 0x73fe, 0x740d, 0x74e0, 0x74f6, 0x74f7,
+ 0x751c, 0x7522, 0x7565, 0x7566, 0x7562, 0x7570, 0x758f, 0x75d4,
+ 0x75d5, 0x75b5, 0x75ca, 0x75cd, 0x768e, 0x76d4, 0x76d2, 0x76db,
+ 0x7737, 0x773e, 0x773c, 0x7736, 0x7738, 0x773a, 0x786b, 0x7843,
+ 0x784e, 0x7965, 0x7968, 0x796d, 0x79fb, 0x7a92, 0x7a95, 0x7b20,
+ 0x7b28, 0x7b1b, 0x7b2c, 0x7b26, 0x7b19, 0x7b1e, 0x7b2e, 0x7c92,
+ 0x7c97, 0x7c95, 0x7d46, 0x7d43, 0x7d71, 0x7d2e, 0x7d39, 0x7d3c,
+ 0x7d40, 0x7d30, 0x7d33, 0x7d44, 0x7d2f, 0x7d42, 0x7d32, 0x7d31,
+ 0x7f3d, 0x7f9e, 0x7f9a, 0x7fcc, 0x7fce, 0x7fd2, 0x801c, 0x804a,
+ 0x8046, 0x812f, 0x8116, 0x8123, 0x812b, 0x8129, 0x8130, 0x8124,
+ 0x8202, 0x8235, 0x8237, 0x8236, 0x8239, 0x838e, 0x839e, 0x8398,
+ 0x8378, 0x83a2, 0x8396, 0x83bd, 0x83ab, 0x8392, 0x838a, 0x8393,
+ 0x8389, 0x83a0, 0x8377, 0x837b, 0x837c,
+ /* 0xb3 */
+ 0x8386, 0x83a7, 0x8655, 0x5f6a, 0x86c7, 0x86c0, 0x86b6, 0x86c4,
+ 0x86b5, 0x86c6, 0x86cb, 0x86b1, 0x86af, 0x86c9, 0x8853, 0x889e,
+ 0x8888, 0x88ab, 0x8892, 0x8896, 0x888d, 0x888b, 0x8993, 0x898f,
+ 0x8a2a, 0x8a1d, 0x8a23, 0x8a25, 0x8a31, 0x8a2d, 0x8a1f, 0x8a1b,
+ 0x8a22, 0x8c49, 0x8c5a, 0x8ca9, 0x8cac, 0x8cab, 0x8ca8, 0x8caa,
+ 0x8ca7, 0x8d67, 0x8d66, 0x8dbe, 0x8dba, 0x8edb, 0x8edf, 0x9019,
+ 0x900d, 0x901a, 0x9017, 0x9023, 0x901f, 0x901d, 0x9010, 0x9015,
+ 0x901e, 0x9020, 0x900f, 0x9022, 0x9016, 0x901b, 0x9014, 0x90e8,
+ 0x90ed, 0x90fd, 0x9157, 0x91ce, 0x91f5, 0x91e6, 0x91e3, 0x91e7,
+ 0x91ed, 0x91e9, 0x9589, 0x966a, 0x9675, 0x9673, 0x9678, 0x9670,
+ 0x9674, 0x9676, 0x9677, 0x966c, 0x96c0, 0x96ea, 0x96e9, 0x7ae0,
+ 0x7adf, 0x9802, 0x9803, 0x9b5a, 0x9ce5, 0x9e75, 0x9e7f, 0x9ea5,
+ 0x9ebb, 0x50a2, 0x508d, 0x5085, 0x5099, 0x5091, 0x5080, 0x5096,
+ 0x5098, 0x509a, 0x6700, 0x51f1, 0x5272, 0x5274, 0x5275, 0x5269,
+ 0x52de, 0x52dd, 0x52db, 0x535a, 0x53a5, 0x557b, 0x5580, 0x55a7,
+ 0x557c, 0x558a, 0x559d, 0x5598, 0x5582, 0x559c, 0x55aa, 0x5594,
+ 0x5587, 0x558b, 0x5583, 0x55b3, 0x55ae, 0x559f, 0x553e, 0x55b2,
+ 0x559a, 0x55bb, 0x55ac, 0x55b1, 0x557e, 0x5589, 0x55ab, 0x5599,
+ 0x570d, 0x582f, 0x582a, 0x5834, 0x5824, 0x5830, 0x5831, 0x5821,
+ 0x581d, 0x5820, 0x58f9, 0x58fa, 0x5960,
+ /* 0xb4 */
+ 0x5a77, 0x5a9a, 0x5a7f, 0x5a92, 0x5a9b, 0x5aa7, 0x5b73, 0x5b71,
+ 0x5bd2, 0x5bcc, 0x5bd3, 0x5bd0, 0x5c0a, 0x5c0b, 0x5c31, 0x5d4c,
+ 0x5d50, 0x5d34, 0x5d47, 0x5dfd, 0x5e45, 0x5e3d, 0x5e40, 0x5e43,
+ 0x5e7e, 0x5eca, 0x5ec1, 0x5ec2, 0x5ec4, 0x5f3c, 0x5f6d, 0x5fa9,
+ 0x5faa, 0x5fa8, 0x60d1, 0x60e1, 0x60b2, 0x60b6, 0x60e0, 0x611c,
+ 0x6123, 0x60fa, 0x6115, 0x60f0, 0x60fb, 0x60f4, 0x6168, 0x60f1,
+ 0x610e, 0x60f6, 0x6109, 0x6100, 0x6112, 0x621f, 0x6249, 0x63a3,
+ 0x638c, 0x63cf, 0x63c0, 0x63e9, 0x63c9, 0x63c6, 0x63cd, 0x63d2,
+ 0x63e3, 0x63d0, 0x63e1, 0x63d6, 0x63ed, 0x63ee, 0x6376, 0x63f4,
+ 0x63ea, 0x63db, 0x6452, 0x63da, 0x63f9, 0x655e, 0x6566, 0x6562,
+ 0x6563, 0x6591, 0x6590, 0x65af, 0x666e, 0x6670, 0x6674, 0x6676,
+ 0x666f, 0x6691, 0x667a, 0x667e, 0x6677, 0x66fe, 0x66ff, 0x671f,
+ 0x671d, 0x68fa, 0x68d5, 0x68e0, 0x68d8, 0x68d7, 0x6905, 0x68df,
+ 0x68f5, 0x68ee, 0x68e7, 0x68f9, 0x68d2, 0x68f2, 0x68e3, 0x68cb,
+ 0x68cd, 0x690d, 0x6912, 0x690e, 0x68c9, 0x68da, 0x696e, 0x68fb,
+ 0x6b3e, 0x6b3a, 0x6b3d, 0x6b98, 0x6b96, 0x6bbc, 0x6bef, 0x6c2e,
+ 0x6c2f, 0x6c2c, 0x6e2f, 0x6e38, 0x6e54, 0x6e21, 0x6e32, 0x6e67,
+ 0x6e4a, 0x6e20, 0x6e25, 0x6e23, 0x6e1b, 0x6e5b, 0x6e58, 0x6e24,
+ 0x6e56, 0x6e6e, 0x6e2d, 0x6e26, 0x6e6f, 0x6e34, 0x6e4d, 0x6e3a,
+ 0x6e2c, 0x6e43, 0x6e1d, 0x6e3e, 0x6ecb,
+ /* 0xb5 */
+ 0x6e89, 0x6e19, 0x6e4e, 0x6e63, 0x6e44, 0x6e72, 0x6e69, 0x6e5f,
+ 0x7119, 0x711a, 0x7126, 0x7130, 0x7121, 0x7136, 0x716e, 0x711c,
+ 0x724c, 0x7284, 0x7280, 0x7336, 0x7325, 0x7334, 0x7329, 0x743a,
+ 0x742a, 0x7433, 0x7422, 0x7425, 0x7435, 0x7436, 0x7434, 0x742f,
+ 0x741b, 0x7426, 0x7428, 0x7525, 0x7526, 0x756b, 0x756a, 0x75e2,
+ 0x75db, 0x75e3, 0x75d9, 0x75d8, 0x75de, 0x75e0, 0x767b, 0x767c,
+ 0x7696, 0x7693, 0x76b4, 0x76dc, 0x774f, 0x77ed, 0x785d, 0x786c,
+ 0x786f, 0x7a0d, 0x7a08, 0x7a0b, 0x7a05, 0x7a00, 0x7a98, 0x7a97,
+ 0x7a96, 0x7ae5, 0x7ae3, 0x7b49, 0x7b56, 0x7b46, 0x7b50, 0x7b52,
+ 0x7b54, 0x7b4d, 0x7b4b, 0x7b4f, 0x7b51, 0x7c9f, 0x7ca5, 0x7d5e,
+ 0x7d50, 0x7d68, 0x7d55, 0x7d2b, 0x7d6e, 0x7d72, 0x7d61, 0x7d66,
+ 0x7d62, 0x7d70, 0x7d73, 0x5584, 0x7fd4, 0x7fd5, 0x800b, 0x8052,
+ 0x8085, 0x8155, 0x8154, 0x814b, 0x8151, 0x814e, 0x8139, 0x8146,
+ 0x813e, 0x814c, 0x8153, 0x8174, 0x8212, 0x821c, 0x83e9, 0x8403,
+ 0x83f8, 0x840d, 0x83e0, 0x83c5, 0x840b, 0x83c1, 0x83ef, 0x83f1,
+ 0x83f4, 0x8457, 0x840a, 0x83f0, 0x840c, 0x83cc, 0x83fd, 0x83f2,
+ 0x83ca, 0x8438, 0x840e, 0x8404, 0x83dc, 0x8407, 0x83d4, 0x83df,
+ 0x865b, 0x86df, 0x86d9, 0x86ed, 0x86d4, 0x86db, 0x86e4, 0x86d0,
+ 0x86de, 0x8857, 0x88c1, 0x88c2, 0x88b1, 0x8983, 0x8996, 0x8a3b,
+ 0x8a60, 0x8a55, 0x8a5e, 0x8a3c, 0x8a41,
+ /* 0xb6 */
+ 0x8a54, 0x8a5b, 0x8a50, 0x8a46, 0x8a34, 0x8a3a, 0x8a36, 0x8a56,
+ 0x8c61, 0x8c82, 0x8caf, 0x8cbc, 0x8cb3, 0x8cbd, 0x8cc1, 0x8cbb,
+ 0x8cc0, 0x8cb4, 0x8cb7, 0x8cb6, 0x8cbf, 0x8cb8, 0x8d8a, 0x8d85,
+ 0x8d81, 0x8dce, 0x8ddd, 0x8dcb, 0x8dda, 0x8dd1, 0x8dcc, 0x8ddb,
+ 0x8dc6, 0x8efb, 0x8ef8, 0x8efc, 0x8f9c, 0x902e, 0x9035, 0x9031,
+ 0x9038, 0x9032, 0x9036, 0x9102, 0x90f5, 0x9109, 0x90fe, 0x9163,
+ 0x9165, 0x91cf, 0x9214, 0x9215, 0x9223, 0x9209, 0x921e, 0x920d,
+ 0x9210, 0x9207, 0x9211, 0x9594, 0x958f, 0x958b, 0x9591, 0x9593,
+ 0x9592, 0x958e, 0x968a, 0x968e, 0x968b, 0x967d, 0x9685, 0x9686,
+ 0x968d, 0x9672, 0x9684, 0x96c1, 0x96c5, 0x96c4, 0x96c6, 0x96c7,
+ 0x96ef, 0x96f2, 0x97cc, 0x9805, 0x9806, 0x9808, 0x98e7, 0x98ea,
+ 0x98ef, 0x98e9, 0x98f2, 0x98ed, 0x99ae, 0x99ad, 0x9ec3, 0x9ecd,
+ 0x9ed1, 0x4e82, 0x50ad, 0x50b5, 0x50b2, 0x50b3, 0x50c5, 0x50be,
+ 0x50ac, 0x50b7, 0x50bb, 0x50af, 0x50c7, 0x527f, 0x5277, 0x527d,
+ 0x52df, 0x52e6, 0x52e4, 0x52e2, 0x52e3, 0x532f, 0x55df, 0x55e8,
+ 0x55d3, 0x55e6, 0x55ce, 0x55dc, 0x55c7, 0x55d1, 0x55e3, 0x55e4,
+ 0x55ef, 0x55da, 0x55e1, 0x55c5, 0x55c6, 0x55e5, 0x55c9, 0x5712,
+ 0x5713, 0x585e, 0x5851, 0x5858, 0x5857, 0x585a, 0x5854, 0x586b,
+ 0x584c, 0x586d, 0x584a, 0x5862, 0x5852, 0x584b, 0x5967, 0x5ac1,
+ 0x5ac9, 0x5acc, 0x5abe, 0x5abd, 0x5abc,
+ /* 0xb7 */
+ 0x5ab3, 0x5ac2, 0x5ab2, 0x5d69, 0x5d6f, 0x5e4c, 0x5e79, 0x5ec9,
+ 0x5ec8, 0x5f12, 0x5f59, 0x5fac, 0x5fae, 0x611a, 0x610f, 0x6148,
+ 0x611f, 0x60f3, 0x611b, 0x60f9, 0x6101, 0x6108, 0x614e, 0x614c,
+ 0x6144, 0x614d, 0x613e, 0x6134, 0x6127, 0x610d, 0x6106, 0x6137,
+ 0x6221, 0x6222, 0x6413, 0x643e, 0x641e, 0x642a, 0x642d, 0x643d,
+ 0x642c, 0x640f, 0x641c, 0x6414, 0x640d, 0x6436, 0x6416, 0x6417,
+ 0x6406, 0x656c, 0x659f, 0x65b0, 0x6697, 0x6689, 0x6687, 0x6688,
+ 0x6696, 0x6684, 0x6698, 0x668d, 0x6703, 0x6994, 0x696d, 0x695a,
+ 0x6977, 0x6960, 0x6954, 0x6975, 0x6930, 0x6982, 0x694a, 0x6968,
+ 0x696b, 0x695e, 0x6953, 0x6979, 0x6986, 0x695d, 0x6963, 0x695b,
+ 0x6b47, 0x6b72, 0x6bc0, 0x6bbf, 0x6bd3, 0x6bfd, 0x6ea2, 0x6eaf,
+ 0x6ed3, 0x6eb6, 0x6ec2, 0x6e90, 0x6e9d, 0x6ec7, 0x6ec5, 0x6ea5,
+ 0x6e98, 0x6ebc, 0x6eba, 0x6eab, 0x6ed1, 0x6e96, 0x6e9c, 0x6ec4,
+ 0x6ed4, 0x6eaa, 0x6ea7, 0x6eb4, 0x714e, 0x7159, 0x7169, 0x7164,
+ 0x7149, 0x7167, 0x715c, 0x716c, 0x7166, 0x714c, 0x7165, 0x715e,
+ 0x7146, 0x7168, 0x7156, 0x723a, 0x7252, 0x7337, 0x7345, 0x733f,
+ 0x733e, 0x746f, 0x745a, 0x7455, 0x745f, 0x745e, 0x7441, 0x743f,
+ 0x7459, 0x745b, 0x745c, 0x7576, 0x7578, 0x7600, 0x75f0, 0x7601,
+ 0x75f2, 0x75f1, 0x75fa, 0x75ff, 0x75f4, 0x75f3, 0x76de, 0x76df,
+ 0x775b, 0x776b, 0x7766, 0x775e, 0x7763,
+ /* 0xb8 */
+ 0x7779, 0x776a, 0x776c, 0x775c, 0x7765, 0x7768, 0x7762, 0x77ee,
+ 0x788e, 0x78b0, 0x7897, 0x7898, 0x788c, 0x7889, 0x787c, 0x7891,
+ 0x7893, 0x787f, 0x797a, 0x797f, 0x7981, 0x842c, 0x79bd, 0x7a1c,
+ 0x7a1a, 0x7a20, 0x7a14, 0x7a1f, 0x7a1e, 0x7a9f, 0x7aa0, 0x7b77,
+ 0x7bc0, 0x7b60, 0x7b6e, 0x7b67, 0x7cb1, 0x7cb3, 0x7cb5, 0x7d93,
+ 0x7d79, 0x7d91, 0x7d81, 0x7d8f, 0x7d5b, 0x7f6e, 0x7f69, 0x7f6a,
+ 0x7f72, 0x7fa9, 0x7fa8, 0x7fa4, 0x8056, 0x8058, 0x8086, 0x8084,
+ 0x8171, 0x8170, 0x8178, 0x8165, 0x816e, 0x8173, 0x816b, 0x8179,
+ 0x817a, 0x8166, 0x8205, 0x8247, 0x8482, 0x8477, 0x843d, 0x8431,
+ 0x8475, 0x8466, 0x846b, 0x8449, 0x846c, 0x845b, 0x843c, 0x8435,
+ 0x8461, 0x8463, 0x8469, 0x846d, 0x8446, 0x865e, 0x865c, 0x865f,
+ 0x86f9, 0x8713, 0x8708, 0x8707, 0x8700, 0x86fe, 0x86fb, 0x8702,
+ 0x8703, 0x8706, 0x870a, 0x8859, 0x88df, 0x88d4, 0x88d9, 0x88dc,
+ 0x88d8, 0x88dd, 0x88e1, 0x88ca, 0x88d5, 0x88d2, 0x899c, 0x89e3,
+ 0x8a6b, 0x8a72, 0x8a73, 0x8a66, 0x8a69, 0x8a70, 0x8a87, 0x8a7c,
+ 0x8a63, 0x8aa0, 0x8a71, 0x8a85, 0x8a6d, 0x8a62, 0x8a6e, 0x8a6c,
+ 0x8a79, 0x8a7b, 0x8a3e, 0x8a68, 0x8c62, 0x8c8a, 0x8c89, 0x8cca,
+ 0x8cc7, 0x8cc8, 0x8cc4, 0x8cb2, 0x8cc3, 0x8cc2, 0x8cc5, 0x8de1,
+ 0x8ddf, 0x8de8, 0x8def, 0x8df3, 0x8dfa, 0x8dea, 0x8de4, 0x8de6,
+ 0x8eb2, 0x8f03, 0x8f09, 0x8efe, 0x8f0a,
+ /* 0xb9 */
+ 0x8f9f, 0x8fb2, 0x904b, 0x904a, 0x9053, 0x9042, 0x9054, 0x903c,
+ 0x9055, 0x9050, 0x9047, 0x904f, 0x904e, 0x904d, 0x9051, 0x903e,
+ 0x9041, 0x9112, 0x9117, 0x916c, 0x916a, 0x9169, 0x91c9, 0x9237,
+ 0x9257, 0x9238, 0x923d, 0x9240, 0x923e, 0x925b, 0x924b, 0x9264,
+ 0x9251, 0x9234, 0x9249, 0x924d, 0x9245, 0x9239, 0x923f, 0x925a,
+ 0x9598, 0x9698, 0x9694, 0x9695, 0x96cd, 0x96cb, 0x96c9, 0x96ca,
+ 0x96f7, 0x96fb, 0x96f9, 0x96f6, 0x9756, 0x9774, 0x9776, 0x9810,
+ 0x9811, 0x9813, 0x980a, 0x9812, 0x980c, 0x98fc, 0x98f4, 0x98fd,
+ 0x98fe, 0x99b3, 0x99b1, 0x99b4, 0x9ae1, 0x9ce9, 0x9e82, 0x9f0e,
+ 0x9f13, 0x9f20, 0x50e7, 0x50ee, 0x50e5, 0x50d6, 0x50ed, 0x50da,
+ 0x50d5, 0x50cf, 0x50d1, 0x50f1, 0x50ce, 0x50e9, 0x5162, 0x51f3,
+ 0x5283, 0x5282, 0x5331, 0x53ad, 0x55fe, 0x5600, 0x561b, 0x5617,
+ 0x55fd, 0x5614, 0x5606, 0x5609, 0x560d, 0x560e, 0x55f7, 0x5616,
+ 0x561f, 0x5608, 0x5610, 0x55f6, 0x5718, 0x5716, 0x5875, 0x587e,
+ 0x5883, 0x5893, 0x588a, 0x5879, 0x5885, 0x587d, 0x58fd, 0x5925,
+ 0x5922, 0x5924, 0x596a, 0x5969, 0x5ae1, 0x5ae6, 0x5ae9, 0x5ad7,
+ 0x5ad6, 0x5ad8, 0x5ae3, 0x5b75, 0x5bde, 0x5be7, 0x5be1, 0x5be5,
+ 0x5be6, 0x5be8, 0x5be2, 0x5be4, 0x5bdf, 0x5c0d, 0x5c62, 0x5d84,
+ 0x5d87, 0x5e5b, 0x5e63, 0x5e55, 0x5e57, 0x5e54, 0x5ed3, 0x5ed6,
+ 0x5f0a, 0x5f46, 0x5f70, 0x5fb9, 0x6147,
+ /* 0xba */
+ 0x613f, 0x614b, 0x6177, 0x6162, 0x6163, 0x615f, 0x615a, 0x6158,
+ 0x6175, 0x622a, 0x6487, 0x6458, 0x6454, 0x64a4, 0x6478, 0x645f,
+ 0x647a, 0x6451, 0x6467, 0x6434, 0x646d, 0x647b, 0x6572, 0x65a1,
+ 0x65d7, 0x65d6, 0x66a2, 0x66a8, 0x669d, 0x699c, 0x69a8, 0x6995,
+ 0x69c1, 0x69ae, 0x69d3, 0x69cb, 0x699b, 0x69b7, 0x69bb, 0x69ab,
+ 0x69b4, 0x69d0, 0x69cd, 0x69ad, 0x69cc, 0x69a6, 0x69c3, 0x69a3,
+ 0x6b49, 0x6b4c, 0x6c33, 0x6f33, 0x6f14, 0x6efe, 0x6f13, 0x6ef4,
+ 0x6f29, 0x6f3e, 0x6f20, 0x6f2c, 0x6f0f, 0x6f02, 0x6f22, 0x6eff,
+ 0x6eef, 0x6f06, 0x6f31, 0x6f38, 0x6f32, 0x6f23, 0x6f15, 0x6f2b,
+ 0x6f2f, 0x6f88, 0x6f2a, 0x6eec, 0x6f01, 0x6ef2, 0x6ecc, 0x6ef7,
+ 0x7194, 0x7199, 0x717d, 0x718a, 0x7184, 0x7192, 0x723e, 0x7292,
+ 0x7296, 0x7344, 0x7350, 0x7464, 0x7463, 0x746a, 0x7470, 0x746d,
+ 0x7504, 0x7591, 0x7627, 0x760d, 0x760b, 0x7609, 0x7613, 0x76e1,
+ 0x76e3, 0x7784, 0x777d, 0x777f, 0x7761, 0x78c1, 0x789f, 0x78a7,
+ 0x78b3, 0x78a9, 0x78a3, 0x798e, 0x798f, 0x798d, 0x7a2e, 0x7a31,
+ 0x7aaa, 0x7aa9, 0x7aed, 0x7aef, 0x7ba1, 0x7b95, 0x7b8b, 0x7b75,
+ 0x7b97, 0x7b9d, 0x7b94, 0x7b8f, 0x7bb8, 0x7b87, 0x7b84, 0x7cb9,
+ 0x7cbd, 0x7cbe, 0x7dbb, 0x7db0, 0x7d9c, 0x7dbd, 0x7dbe, 0x7da0,
+ 0x7dca, 0x7db4, 0x7db2, 0x7db1, 0x7dba, 0x7da2, 0x7dbf, 0x7db5,
+ 0x7db8, 0x7dad, 0x7dd2, 0x7dc7, 0x7dac,
+ /* 0xbb */
+ 0x7f70, 0x7fe0, 0x7fe1, 0x7fdf, 0x805e, 0x805a, 0x8087, 0x8150,
+ 0x8180, 0x818f, 0x8188, 0x818a, 0x817f, 0x8182, 0x81e7, 0x81fa,
+ 0x8207, 0x8214, 0x821e, 0x824b, 0x84c9, 0x84bf, 0x84c6, 0x84c4,
+ 0x8499, 0x849e, 0x84b2, 0x849c, 0x84cb, 0x84b8, 0x84c0, 0x84d3,
+ 0x8490, 0x84bc, 0x84d1, 0x84ca, 0x873f, 0x871c, 0x873b, 0x8722,
+ 0x8725, 0x8734, 0x8718, 0x8755, 0x8737, 0x8729, 0x88f3, 0x8902,
+ 0x88f4, 0x88f9, 0x88f8, 0x88fd, 0x88e8, 0x891a, 0x88ef, 0x8aa6,
+ 0x8a8c, 0x8a9e, 0x8aa3, 0x8a8d, 0x8aa1, 0x8a93, 0x8aa4, 0x8aaa,
+ 0x8aa5, 0x8aa8, 0x8a98, 0x8a91, 0x8a9a, 0x8aa7, 0x8c6a, 0x8c8d,
+ 0x8c8c, 0x8cd3, 0x8cd1, 0x8cd2, 0x8d6b, 0x8d99, 0x8d95, 0x8dfc,
+ 0x8f14, 0x8f12, 0x8f15, 0x8f13, 0x8fa3, 0x9060, 0x9058, 0x905c,
+ 0x9063, 0x9059, 0x905e, 0x9062, 0x905d, 0x905b, 0x9119, 0x9118,
+ 0x911e, 0x9175, 0x9178, 0x9177, 0x9174, 0x9278, 0x9280, 0x9285,
+ 0x9298, 0x9296, 0x927b, 0x9293, 0x929c, 0x92a8, 0x927c, 0x9291,
+ 0x95a1, 0x95a8, 0x95a9, 0x95a3, 0x95a5, 0x95a4, 0x9699, 0x969c,
+ 0x969b, 0x96cc, 0x96d2, 0x9700, 0x977c, 0x9785, 0x97f6, 0x9817,
+ 0x9818, 0x98af, 0x98b1, 0x9903, 0x9905, 0x990c, 0x9909, 0x99c1,
+ 0x9aaf, 0x9ab0, 0x9ae6, 0x9b41, 0x9b42, 0x9cf4, 0x9cf6, 0x9cf3,
+ 0x9ebc, 0x9f3b, 0x9f4a, 0x5104, 0x5100, 0x50fb, 0x50f5, 0x50f9,
+ 0x5102, 0x5108, 0x5109, 0x5105, 0x51dc,
+ /* 0xbc */
+ 0x5287, 0x5288, 0x5289, 0x528d, 0x528a, 0x52f0, 0x53b2, 0x562e,
+ 0x563b, 0x5639, 0x5632, 0x563f, 0x5634, 0x5629, 0x5653, 0x564e,
+ 0x5657, 0x5674, 0x5636, 0x562f, 0x5630, 0x5880, 0x589f, 0x589e,
+ 0x58b3, 0x589c, 0x58ae, 0x58a9, 0x58a6, 0x596d, 0x5b09, 0x5afb,
+ 0x5b0b, 0x5af5, 0x5b0c, 0x5b08, 0x5bee, 0x5bec, 0x5be9, 0x5beb,
+ 0x5c64, 0x5c65, 0x5d9d, 0x5d94, 0x5e62, 0x5e5f, 0x5e61, 0x5ee2,
+ 0x5eda, 0x5edf, 0x5edd, 0x5ee3, 0x5ee0, 0x5f48, 0x5f71, 0x5fb7,
+ 0x5fb5, 0x6176, 0x6167, 0x616e, 0x615d, 0x6155, 0x6182, 0x617c,
+ 0x6170, 0x616b, 0x617e, 0x61a7, 0x6190, 0x61ab, 0x618e, 0x61ac,
+ 0x619a, 0x61a4, 0x6194, 0x61ae, 0x622e, 0x6469, 0x646f, 0x6479,
+ 0x649e, 0x64b2, 0x6488, 0x6490, 0x64b0, 0x64a5, 0x6493, 0x6495,
+ 0x64a9, 0x6492, 0x64ae, 0x64ad, 0x64ab, 0x649a, 0x64ac, 0x6499,
+ 0x64a2, 0x64b3, 0x6575, 0x6577, 0x6578, 0x66ae, 0x66ab, 0x66b4,
+ 0x66b1, 0x6a23, 0x6a1f, 0x69e8, 0x6a01, 0x6a1e, 0x6a19, 0x69fd,
+ 0x6a21, 0x6a13, 0x6a0a, 0x69f3, 0x6a02, 0x6a05, 0x69ed, 0x6a11,
+ 0x6b50, 0x6b4e, 0x6ba4, 0x6bc5, 0x6bc6, 0x6f3f, 0x6f7c, 0x6f84,
+ 0x6f51, 0x6f66, 0x6f54, 0x6f86, 0x6f6d, 0x6f5b, 0x6f78, 0x6f6e,
+ 0x6f8e, 0x6f7a, 0x6f70, 0x6f64, 0x6f97, 0x6f58, 0x6ed5, 0x6f6f,
+ 0x6f60, 0x6f5f, 0x719f, 0x71ac, 0x71b1, 0x71a8, 0x7256, 0x729b,
+ 0x734e, 0x7357, 0x7469, 0x748b, 0x7483,
+ /* 0xbd */
+ 0x747e, 0x7480, 0x757f, 0x7620, 0x7629, 0x761f, 0x7624, 0x7626,
+ 0x7621, 0x7622, 0x769a, 0x76ba, 0x76e4, 0x778e, 0x7787, 0x778c,
+ 0x7791, 0x778b, 0x78cb, 0x78c5, 0x78ba, 0x78ca, 0x78be, 0x78d5,
+ 0x78bc, 0x78d0, 0x7a3f, 0x7a3c, 0x7a40, 0x7a3d, 0x7a37, 0x7a3b,
+ 0x7aaf, 0x7aae, 0x7bad, 0x7bb1, 0x7bc4, 0x7bb4, 0x7bc6, 0x7bc7,
+ 0x7bc1, 0x7ba0, 0x7bcc, 0x7cca, 0x7de0, 0x7df4, 0x7def, 0x7dfb,
+ 0x7dd8, 0x7dec, 0x7ddd, 0x7de8, 0x7de3, 0x7dda, 0x7dde, 0x7de9,
+ 0x7d9e, 0x7dd9, 0x7df2, 0x7df9, 0x7f75, 0x7f77, 0x7faf, 0x7fe9,
+ 0x8026, 0x819b, 0x819c, 0x819d, 0x81a0, 0x819a, 0x8198, 0x8517,
+ 0x853d, 0x851a, 0x84ee, 0x852c, 0x852d, 0x8513, 0x8511, 0x8523,
+ 0x8521, 0x8514, 0x84ec, 0x8525, 0x84ff, 0x8506, 0x8782, 0x8774,
+ 0x8776, 0x8760, 0x8766, 0x8778, 0x8768, 0x8759, 0x8757, 0x874c,
+ 0x8753, 0x885b, 0x885d, 0x8910, 0x8907, 0x8912, 0x8913, 0x8915,
+ 0x890a, 0x8abc, 0x8ad2, 0x8ac7, 0x8ac4, 0x8a95, 0x8acb, 0x8af8,
+ 0x8ab2, 0x8ac9, 0x8ac2, 0x8abf, 0x8ab0, 0x8ad6, 0x8acd, 0x8ab6,
+ 0x8ab9, 0x8adb, 0x8c4c, 0x8c4e, 0x8c6c, 0x8ce0, 0x8cde, 0x8ce6,
+ 0x8ce4, 0x8cec, 0x8ced, 0x8ce2, 0x8ce3, 0x8cdc, 0x8cea, 0x8ce1,
+ 0x8d6d, 0x8d9f, 0x8da3, 0x8e2b, 0x8e10, 0x8e1d, 0x8e22, 0x8e0f,
+ 0x8e29, 0x8e1f, 0x8e21, 0x8e1e, 0x8eba, 0x8f1d, 0x8f1b, 0x8f1f,
+ 0x8f29, 0x8f26, 0x8f2a, 0x8f1c, 0x8f1e,
+ /* 0xbe */
+ 0x8f25, 0x9069, 0x906e, 0x9068, 0x906d, 0x9077, 0x9130, 0x912d,
+ 0x9127, 0x9131, 0x9187, 0x9189, 0x918b, 0x9183, 0x92c5, 0x92bb,
+ 0x92b7, 0x92ea, 0x92ac, 0x92e4, 0x92c1, 0x92b3, 0x92bc, 0x92d2,
+ 0x92c7, 0x92f0, 0x92b2, 0x95ad, 0x95b1, 0x9704, 0x9706, 0x9707,
+ 0x9709, 0x9760, 0x978d, 0x978b, 0x978f, 0x9821, 0x982b, 0x981c,
+ 0x98b3, 0x990a, 0x9913, 0x9912, 0x9918, 0x99dd, 0x99d0, 0x99df,
+ 0x99db, 0x99d1, 0x99d5, 0x99d2, 0x99d9, 0x9ab7, 0x9aee, 0x9aef,
+ 0x9b27, 0x9b45, 0x9b44, 0x9b77, 0x9b6f, 0x9d06, 0x9d09, 0x9d03,
+ 0x9ea9, 0x9ebe, 0x9ece, 0x58a8, 0x9f52, 0x5112, 0x5118, 0x5114,
+ 0x5110, 0x5115, 0x5180, 0x51aa, 0x51dd, 0x5291, 0x5293, 0x52f3,
+ 0x5659, 0x566b, 0x5679, 0x5669, 0x5664, 0x5678, 0x566a, 0x5668,
+ 0x5665, 0x5671, 0x566f, 0x566c, 0x5662, 0x5676, 0x58c1, 0x58be,
+ 0x58c7, 0x58c5, 0x596e, 0x5b1d, 0x5b34, 0x5b78, 0x5bf0, 0x5c0e,
+ 0x5f4a, 0x61b2, 0x6191, 0x61a9, 0x618a, 0x61cd, 0x61b6, 0x61be,
+ 0x61ca, 0x61c8, 0x6230, 0x64c5, 0x64c1, 0x64cb, 0x64bb, 0x64bc,
+ 0x64da, 0x64c4, 0x64c7, 0x64c2, 0x64cd, 0x64bf, 0x64d2, 0x64d4,
+ 0x64be, 0x6574, 0x66c6, 0x66c9, 0x66b9, 0x66c4, 0x66c7, 0x66b8,
+ 0x6a3d, 0x6a38, 0x6a3a, 0x6a59, 0x6a6b, 0x6a58, 0x6a39, 0x6a44,
+ 0x6a62, 0x6a61, 0x6a4b, 0x6a47, 0x6a35, 0x6a5f, 0x6a48, 0x6b59,
+ 0x6b77, 0x6c05, 0x6fc2, 0x6fb1, 0x6fa1,
+ /* 0xbf */
+ 0x6fc3, 0x6fa4, 0x6fc1, 0x6fa7, 0x6fb3, 0x6fc0, 0x6fb9, 0x6fb6,
+ 0x6fa6, 0x6fa0, 0x6fb4, 0x71be, 0x71c9, 0x71d0, 0x71d2, 0x71c8,
+ 0x71d5, 0x71b9, 0x71ce, 0x71d9, 0x71dc, 0x71c3, 0x71c4, 0x7368,
+ 0x749c, 0x74a3, 0x7498, 0x749f, 0x749e, 0x74e2, 0x750c, 0x750d,
+ 0x7634, 0x7638, 0x763a, 0x76e7, 0x76e5, 0x77a0, 0x779e, 0x779f,
+ 0x77a5, 0x78e8, 0x78da, 0x78ec, 0x78e7, 0x79a6, 0x7a4d, 0x7a4e,
+ 0x7a46, 0x7a4c, 0x7a4b, 0x7aba, 0x7bd9, 0x7c11, 0x7bc9, 0x7be4,
+ 0x7bdb, 0x7be1, 0x7be9, 0x7be6, 0x7cd5, 0x7cd6, 0x7e0a, 0x7e11,
+ 0x7e08, 0x7e1b, 0x7e23, 0x7e1e, 0x7e1d, 0x7e09, 0x7e10, 0x7f79,
+ 0x7fb2, 0x7ff0, 0x7ff1, 0x7fee, 0x8028, 0x81b3, 0x81a9, 0x81a8,
+ 0x81fb, 0x8208, 0x8258, 0x8259, 0x854a, 0x8559, 0x8548, 0x8568,
+ 0x8569, 0x8543, 0x8549, 0x856d, 0x856a, 0x855e, 0x8783, 0x879f,
+ 0x879e, 0x87a2, 0x878d, 0x8861, 0x892a, 0x8932, 0x8925, 0x892b,
+ 0x8921, 0x89aa, 0x89a6, 0x8ae6, 0x8afa, 0x8aeb, 0x8af1, 0x8b00,
+ 0x8adc, 0x8ae7, 0x8aee, 0x8afe, 0x8b01, 0x8b02, 0x8af7, 0x8aed,
+ 0x8af3, 0x8af6, 0x8afc, 0x8c6b, 0x8c6d, 0x8c93, 0x8cf4, 0x8e44,
+ 0x8e31, 0x8e34, 0x8e42, 0x8e39, 0x8e35, 0x8f3b, 0x8f2f, 0x8f38,
+ 0x8f33, 0x8fa8, 0x8fa6, 0x9075, 0x9074, 0x9078, 0x9072, 0x907c,
+ 0x907a, 0x9134, 0x9192, 0x9320, 0x9336, 0x92f8, 0x9333, 0x932f,
+ 0x9322, 0x92fc, 0x932b, 0x9304, 0x931a,
+ /* 0xc0 */
+ 0x9310, 0x9326, 0x9321, 0x9315, 0x932e, 0x9319, 0x95bb, 0x96a7,
+ 0x96a8, 0x96aa, 0x96d5, 0x970e, 0x9711, 0x9716, 0x970d, 0x9713,
+ 0x970f, 0x975b, 0x975c, 0x9766, 0x9798, 0x9830, 0x9838, 0x983b,
+ 0x9837, 0x982d, 0x9839, 0x9824, 0x9910, 0x9928, 0x991e, 0x991b,
+ 0x9921, 0x991a, 0x99ed, 0x99e2, 0x99f1, 0x9ab8, 0x9abc, 0x9afb,
+ 0x9aed, 0x9b28, 0x9b91, 0x9d15, 0x9d23, 0x9d26, 0x9d28, 0x9d12,
+ 0x9d1b, 0x9ed8, 0x9ed4, 0x9f8d, 0x9f9c, 0x512a, 0x511f, 0x5121,
+ 0x5132, 0x52f5, 0x568e, 0x5680, 0x5690, 0x5685, 0x5687, 0x568f,
+ 0x58d5, 0x58d3, 0x58d1, 0x58ce, 0x5b30, 0x5b2a, 0x5b24, 0x5b7a,
+ 0x5c37, 0x5c68, 0x5dbc, 0x5dba, 0x5dbd, 0x5db8, 0x5e6b, 0x5f4c,
+ 0x5fbd, 0x61c9, 0x61c2, 0x61c7, 0x61e6, 0x61cb, 0x6232, 0x6234,
+ 0x64ce, 0x64ca, 0x64d8, 0x64e0, 0x64f0, 0x64e6, 0x64ec, 0x64f1,
+ 0x64e2, 0x64ed, 0x6582, 0x6583, 0x66d9, 0x66d6, 0x6a80, 0x6a94,
+ 0x6a84, 0x6aa2, 0x6a9c, 0x6adb, 0x6aa3, 0x6a7e, 0x6a97, 0x6a90,
+ 0x6aa0, 0x6b5c, 0x6bae, 0x6bda, 0x6c08, 0x6fd8, 0x6ff1, 0x6fdf,
+ 0x6fe0, 0x6fdb, 0x6fe4, 0x6feb, 0x6fef, 0x6f80, 0x6fec, 0x6fe1,
+ 0x6fe9, 0x6fd5, 0x6fee, 0x6ff0, 0x71e7, 0x71df, 0x71ee, 0x71e6,
+ 0x71e5, 0x71ed, 0x71ec, 0x71f4, 0x71e0, 0x7235, 0x7246, 0x7370,
+ 0x7372, 0x74a9, 0x74b0, 0x74a6, 0x74a8, 0x7646, 0x7642, 0x764c,
+ 0x76ea, 0x77b3, 0x77aa, 0x77b0, 0x77ac,
+ /* 0xc1 */
+ 0x77a7, 0x77ad, 0x77ef, 0x78f7, 0x78fa, 0x78f4, 0x78ef, 0x7901,
+ 0x79a7, 0x79aa, 0x7a57, 0x7abf, 0x7c07, 0x7c0d, 0x7bfe, 0x7bf7,
+ 0x7c0c, 0x7be0, 0x7ce0, 0x7cdc, 0x7cde, 0x7ce2, 0x7cdf, 0x7cd9,
+ 0x7cdd, 0x7e2e, 0x7e3e, 0x7e46, 0x7e37, 0x7e32, 0x7e43, 0x7e2b,
+ 0x7e3d, 0x7e31, 0x7e45, 0x7e41, 0x7e34, 0x7e39, 0x7e48, 0x7e35,
+ 0x7e3f, 0x7e2f, 0x7f44, 0x7ff3, 0x7ffc, 0x8071, 0x8072, 0x8070,
+ 0x806f, 0x8073, 0x81c6, 0x81c3, 0x81ba, 0x81c2, 0x81c0, 0x81bf,
+ 0x81bd, 0x81c9, 0x81be, 0x81e8, 0x8209, 0x8271, 0x85aa, 0x8584,
+ 0x857e, 0x859c, 0x8591, 0x8594, 0x85af, 0x859b, 0x8587, 0x85a8,
+ 0x858a, 0x8667, 0x87c0, 0x87d1, 0x87b3, 0x87d2, 0x87c6, 0x87ab,
+ 0x87bb, 0x87ba, 0x87c8, 0x87cb, 0x893b, 0x8936, 0x8944, 0x8938,
+ 0x893d, 0x89ac, 0x8b0e, 0x8b17, 0x8b19, 0x8b1b, 0x8b0a, 0x8b20,
+ 0x8b1d, 0x8b04, 0x8b10, 0x8c41, 0x8c3f, 0x8c73, 0x8cfa, 0x8cfd,
+ 0x8cfc, 0x8cf8, 0x8cfb, 0x8da8, 0x8e49, 0x8e4b, 0x8e48, 0x8e4a,
+ 0x8f44, 0x8f3e, 0x8f42, 0x8f45, 0x8f3f, 0x907f, 0x907d, 0x9084,
+ 0x9081, 0x9082, 0x9080, 0x9139, 0x91a3, 0x919e, 0x919c, 0x934d,
+ 0x9382, 0x9328, 0x9375, 0x934a, 0x9365, 0x934b, 0x9318, 0x937e,
+ 0x936c, 0x935b, 0x9370, 0x935a, 0x9354, 0x95ca, 0x95cb, 0x95cc,
+ 0x95c8, 0x95c6, 0x96b1, 0x96b8, 0x96d6, 0x971c, 0x971e, 0x97a0,
+ 0x97d3, 0x9846, 0x98b6, 0x9935, 0x9a01,
+ /* 0xc2 */
+ 0x99ff, 0x9bae, 0x9bab, 0x9baa, 0x9bad, 0x9d3b, 0x9d3f, 0x9e8b,
+ 0x9ecf, 0x9ede, 0x9edc, 0x9edd, 0x9edb, 0x9f3e, 0x9f4b, 0x53e2,
+ 0x5695, 0x56ae, 0x58d9, 0x58d8, 0x5b38, 0x5f5d, 0x61e3, 0x6233,
+ 0x64f4, 0x64f2, 0x64fe, 0x6506, 0x64fa, 0x64fb, 0x64f7, 0x65b7,
+ 0x66dc, 0x6726, 0x6ab3, 0x6aac, 0x6ac3, 0x6abb, 0x6ab8, 0x6ac2,
+ 0x6aae, 0x6aaf, 0x6b5f, 0x6b78, 0x6baf, 0x7009, 0x700b, 0x6ffe,
+ 0x7006, 0x6ffa, 0x7011, 0x700f, 0x71fb, 0x71fc, 0x71fe, 0x71f8,
+ 0x7377, 0x7375, 0x74a7, 0x74bf, 0x7515, 0x7656, 0x7658, 0x7652,
+ 0x77bd, 0x77bf, 0x77bb, 0x77bc, 0x790e, 0x79ae, 0x7a61, 0x7a62,
+ 0x7a60, 0x7ac4, 0x7ac5, 0x7c2b, 0x7c27, 0x7c2a, 0x7c1e, 0x7c23,
+ 0x7c21, 0x7ce7, 0x7e54, 0x7e55, 0x7e5e, 0x7e5a, 0x7e61, 0x7e52,
+ 0x7e59, 0x7f48, 0x7ff9, 0x7ffb, 0x8077, 0x8076, 0x81cd, 0x81cf,
+ 0x820a, 0x85cf, 0x85a9, 0x85cd, 0x85d0, 0x85c9, 0x85b0, 0x85ba,
+ 0x85b9, 0x85a6, 0x87ef, 0x87ec, 0x87f2, 0x87e0, 0x8986, 0x89b2,
+ 0x89f4, 0x8b28, 0x8b39, 0x8b2c, 0x8b2b, 0x8c50, 0x8d05, 0x8e59,
+ 0x8e63, 0x8e66, 0x8e64, 0x8e5f, 0x8e55, 0x8ec0, 0x8f49, 0x8f4d,
+ 0x9087, 0x9083, 0x9088, 0x91ab, 0x91ac, 0x91d0, 0x9394, 0x938a,
+ 0x9396, 0x93a2, 0x93b3, 0x93ae, 0x93ac, 0x93b0, 0x9398, 0x939a,
+ 0x9397, 0x95d4, 0x95d6, 0x95d0, 0x95d5, 0x96e2, 0x96dc, 0x96d9,
+ 0x96db, 0x96de, 0x9724, 0x97a3, 0x97a6,
+ /* 0xc3 */
+ 0x97ad, 0x97f9, 0x984d, 0x984f, 0x984c, 0x984e, 0x9853, 0x98ba,
+ 0x993e, 0x993f, 0x993d, 0x992e, 0x99a5, 0x9a0e, 0x9ac1, 0x9b03,
+ 0x9b06, 0x9b4f, 0x9b4e, 0x9b4d, 0x9bca, 0x9bc9, 0x9bfd, 0x9bc8,
+ 0x9bc0, 0x9d51, 0x9d5d, 0x9d60, 0x9ee0, 0x9f15, 0x9f2c, 0x5133,
+ 0x56a5, 0x58de, 0x58df, 0x58e2, 0x5bf5, 0x9f90, 0x5eec, 0x61f2,
+ 0x61f7, 0x61f6, 0x61f5, 0x6500, 0x650f, 0x66e0, 0x66dd, 0x6ae5,
+ 0x6add, 0x6ada, 0x6ad3, 0x701b, 0x701f, 0x7028, 0x701a, 0x701d,
+ 0x7015, 0x7018, 0x7206, 0x720d, 0x7258, 0x72a2, 0x7378, 0x737a,
+ 0x74bd, 0x74ca, 0x74e3, 0x7587, 0x7586, 0x765f, 0x7661, 0x77c7,
+ 0x7919, 0x79b1, 0x7a6b, 0x7a69, 0x7c3e, 0x7c3f, 0x7c38, 0x7c3d,
+ 0x7c37, 0x7c40, 0x7e6b, 0x7e6d, 0x7e79, 0x7e69, 0x7e6a, 0x7f85,
+ 0x7e73, 0x7fb6, 0x7fb9, 0x7fb8, 0x81d8, 0x85e9, 0x85dd, 0x85ea,
+ 0x85d5, 0x85e4, 0x85e5, 0x85f7, 0x87fb, 0x8805, 0x880d, 0x87f9,
+ 0x87fe, 0x8960, 0x895f, 0x8956, 0x895e, 0x8b41, 0x8b5c, 0x8b58,
+ 0x8b49, 0x8b5a, 0x8b4e, 0x8b4f, 0x8b46, 0x8b59, 0x8d08, 0x8d0a,
+ 0x8e7c, 0x8e72, 0x8e87, 0x8e76, 0x8e6c, 0x8e7a, 0x8e74, 0x8f54,
+ 0x8f4e, 0x8fad, 0x908a, 0x908b, 0x91b1, 0x91ae, 0x93e1, 0x93d1,
+ 0x93df, 0x93c3, 0x93c8, 0x93dc, 0x93dd, 0x93d6, 0x93e2, 0x93cd,
+ 0x93d8, 0x93e4, 0x93d7, 0x93e8, 0x95dc, 0x96b4, 0x96e3, 0x972a,
+ 0x9727, 0x9761, 0x97dc, 0x97fb, 0x985e,
+ /* 0xc4 */
+ 0x9858, 0x985b, 0x98bc, 0x9945, 0x9949, 0x9a16, 0x9a19, 0x9b0d,
+ 0x9be8, 0x9be7, 0x9bd6, 0x9bdb, 0x9d89, 0x9d61, 0x9d72, 0x9d6a,
+ 0x9d6c, 0x9e92, 0x9e97, 0x9e93, 0x9eb4, 0x52f8, 0x56a8, 0x56b7,
+ 0x56b6, 0x56b4, 0x56bc, 0x58e4, 0x5b40, 0x5b43, 0x5b7d, 0x5bf6,
+ 0x5dc9, 0x61f8, 0x61fa, 0x6518, 0x6514, 0x6519, 0x66e6, 0x6727,
+ 0x6aec, 0x703e, 0x7030, 0x7032, 0x7210, 0x737b, 0x74cf, 0x7662,
+ 0x7665, 0x7926, 0x792a, 0x792c, 0x792b, 0x7ac7, 0x7af6, 0x7c4c,
+ 0x7c43, 0x7c4d, 0x7cef, 0x7cf0, 0x8fae, 0x7e7d, 0x7e7c, 0x7e82,
+ 0x7f4c, 0x8000, 0x81da, 0x8266, 0x85fb, 0x85f9, 0x8611, 0x85fa,
+ 0x8606, 0x860b, 0x8607, 0x860a, 0x8814, 0x8815, 0x8964, 0x89ba,
+ 0x89f8, 0x8b70, 0x8b6c, 0x8b66, 0x8b6f, 0x8b5f, 0x8b6b, 0x8d0f,
+ 0x8d0d, 0x8e89, 0x8e81, 0x8e85, 0x8e82, 0x91b4, 0x91cb, 0x9418,
+ 0x9403, 0x93fd, 0x95e1, 0x9730, 0x98c4, 0x9952, 0x9951, 0x99a8,
+ 0x9a2b, 0x9a30, 0x9a37, 0x9a35, 0x9c13, 0x9c0d, 0x9e79, 0x9eb5,
+ 0x9ee8, 0x9f2f, 0x9f5f, 0x9f63, 0x9f61, 0x5137, 0x5138, 0x56c1,
+ 0x56c0, 0x56c2, 0x5914, 0x5c6c, 0x5dcd, 0x61fc, 0x61fe, 0x651d,
+ 0x651c, 0x6595, 0x66e9, 0x6afb, 0x6b04, 0x6afa, 0x6bb2, 0x704c,
+ 0x721b, 0x72a7, 0x74d6, 0x74d4, 0x7669, 0x77d3, 0x7c50, 0x7e8f,
+ 0x7e8c, 0x7fbc, 0x8617, 0x862d, 0x861a, 0x8823, 0x8822, 0x8821,
+ 0x881f, 0x896a, 0x896c, 0x89bd, 0x8b74,
+ /* 0xc5 */
+ 0x8b77, 0x8b7d, 0x8d13, 0x8e8a, 0x8e8d, 0x8e8b, 0x8f5f, 0x8faf,
+ 0x91ba, 0x942e, 0x9433, 0x9435, 0x943a, 0x9438, 0x9432, 0x942b,
+ 0x95e2, 0x9738, 0x9739, 0x9732, 0x97ff, 0x9867, 0x9865, 0x9957,
+ 0x9a45, 0x9a43, 0x9a40, 0x9a3e, 0x9acf, 0x9b54, 0x9b51, 0x9c2d,
+ 0x9c25, 0x9daf, 0x9db4, 0x9dc2, 0x9db8, 0x9e9d, 0x9eef, 0x9f19,
+ 0x9f5c, 0x9f66, 0x9f67, 0x513c, 0x513b, 0x56c8, 0x56ca, 0x56c9,
+ 0x5b7f, 0x5dd4, 0x5dd2, 0x5f4e, 0x61ff, 0x6524, 0x6b0a, 0x6b61,
+ 0x7051, 0x7058, 0x7380, 0x74e4, 0x758a, 0x766e, 0x766c, 0x79b3,
+ 0x7c60, 0x7c5f, 0x807e, 0x807d, 0x81df, 0x8972, 0x896f, 0x89fc,
+ 0x8b80, 0x8d16, 0x8d17, 0x8e91, 0x8e93, 0x8f61, 0x9148, 0x9444,
+ 0x9451, 0x9452, 0x973d, 0x973e, 0x97c3, 0x97c1, 0x986b, 0x9955,
+ 0x9a55, 0x9a4d, 0x9ad2, 0x9b1a, 0x9c49, 0x9c31, 0x9c3e, 0x9c3b,
+ 0x9dd3, 0x9dd7, 0x9f34, 0x9f6c, 0x9f6a, 0x9f94, 0x56cc, 0x5dd6,
+ 0x6200, 0x6523, 0x652b, 0x652a, 0x66ec, 0x6b10, 0x74da, 0x7aca,
+ 0x7c64, 0x7c63, 0x7c65, 0x7e93, 0x7e96, 0x7e94, 0x81e2, 0x8638,
+ 0x863f, 0x8831, 0x8b8a, 0x9090, 0x908f, 0x9463, 0x9460, 0x9464,
+ 0x9768, 0x986f, 0x995c, 0x9a5a, 0x9a5b, 0x9a57, 0x9ad3, 0x9ad4,
+ 0x9ad1, 0x9c54, 0x9c57, 0x9c56, 0x9de5, 0x9e9f, 0x9ef4, 0x56d1,
+ 0x58e9, 0x652c, 0x705e, 0x7671, 0x7672, 0x77d7, 0x7f50, 0x7f88,
+ 0x8836, 0x8839, 0x8862, 0x8b93, 0x8b92,
+ /* 0xc6 */
+ 0x8b96, 0x8277, 0x8d1b, 0x91c0, 0x946a, 0x9742, 0x9748, 0x9744,
+ 0x97c6, 0x9870, 0x9a5f, 0x9b22, 0x9b58, 0x9c5f, 0x9df9, 0x9dfa,
+ 0x9e7c, 0x9e7d, 0x9f07, 0x9f77, 0x9f72, 0x5ef3, 0x6b16, 0x7063,
+ 0x7c6c, 0x7c6e, 0x883b, 0x89c0, 0x8ea1, 0x91c1, 0x9472, 0x9470,
+ 0x9871, 0x995e, 0x9ad6, 0x9b23, 0x9ecc, 0x7064, 0x77da, 0x8b9a,
+ 0x9477, 0x97c9, 0x9a62, 0x9a65, 0x7e9c, 0x8b9c, 0x8eaa, 0x91c5,
+ 0x947d, 0x947e, 0x947c, 0x9c77, 0x9c78, 0x9ef7, 0x8c54, 0x947f,
+ 0x9e1a, 0x7228, 0x9a6a, 0x9b31, 0x9e1b, 0x9e1e, 0x7c72, 0x30fe,
+ 0x309d, 0x309e, 0x3005, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045,
+ 0x3046, 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d,
+ 0x304e, 0x304f, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055,
+ 0x3056, 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d,
+ 0x305e, 0x305f, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065,
+ 0x3066, 0x3067, 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d,
+ 0x306e, 0x306f, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075,
+ 0x3076, 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d,
+ 0x307e, 0x307f, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085,
+ 0x3086, 0x3087, 0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d,
+ 0x308e, 0x308f, 0x3090, 0x3091, 0x3092, 0x3093, 0x30a1, 0x30a2,
+ 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7,
+ /* 0xc7 */
+ 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af,
+ 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7,
+ 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf,
+ 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7,
+ 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf,
+ 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7,
+ 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df,
+ 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7,
+ 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef,
+ 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x0414,
+ 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b,
+ 0x041c, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429,
+ 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431,
+ 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438,
+ 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440,
+ 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
+ 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x2460,
+ 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468,
+ 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247a,
+ 0x247b, 0x247c, 0x247d,
+};
+static const unsigned short big5_2uni_pagec9[7652] = {
+ /* 0xc9 */
+ 0x4e42, 0x4e5c, 0x51f5, 0x531a, 0x5382, 0x4e07, 0x4e0c, 0x4e47,
+ 0x4e8d, 0x56d7, 0xfa0c, 0x5c6e, 0x5f73, 0x4e0f, 0x5187, 0x4e0e,
+ 0x4e2e, 0x4e93, 0x4ec2, 0x4ec9, 0x4ec8, 0x5198, 0x52fc, 0x536c,
+ 0x53b9, 0x5720, 0x5903, 0x592c, 0x5c10, 0x5dff, 0x65e1, 0x6bb3,
+ 0x6bcc, 0x6c14, 0x723f, 0x4e31, 0x4e3c, 0x4ee8, 0x4edc, 0x4ee9,
+ 0x4ee1, 0x4edd, 0x4eda, 0x520c, 0x531c, 0x534c, 0x5722, 0x5723,
+ 0x5917, 0x592f, 0x5b81, 0x5b84, 0x5c12, 0x5c3b, 0x5c74, 0x5c73,
+ 0x5e04, 0x5e80, 0x5e82, 0x5fc9, 0x6209, 0x6250, 0x6c15, 0x6c36,
+ 0x6c43, 0x6c3f, 0x6c3b, 0x72ae, 0x72b0, 0x738a, 0x79b8, 0x808a,
+ 0x961e, 0x4f0e, 0x4f18, 0x4f2c, 0x4ef5, 0x4f14, 0x4ef1, 0x4f00,
+ 0x4ef7, 0x4f08, 0x4f1d, 0x4f02, 0x4f05, 0x4f22, 0x4f13, 0x4f04,
+ 0x4ef4, 0x4f12, 0x51b1, 0x5213, 0x5209, 0x5210, 0x52a6, 0x5322,
+ 0x531f, 0x534d, 0x538a, 0x5407, 0x56e1, 0x56df, 0x572e, 0x572a,
+ 0x5734, 0x593c, 0x5980, 0x597c, 0x5985, 0x597b, 0x597e, 0x5977,
+ 0x597f, 0x5b56, 0x5c15, 0x5c25, 0x5c7c, 0x5c7a, 0x5c7b, 0x5c7e,
+ 0x5ddf, 0x5e75, 0x5e84, 0x5f02, 0x5f1a, 0x5f74, 0x5fd5, 0x5fd4,
+ 0x5fcf, 0x625c, 0x625e, 0x6264, 0x6261, 0x6266, 0x6262, 0x6259,
+ 0x6260, 0x625a, 0x6265, 0x65ef, 0x65ee, 0x673e, 0x6739, 0x6738,
+ 0x673b, 0x673a, 0x673f, 0x673c, 0x6733, 0x6c18, 0x6c46, 0x6c52,
+ 0x6c5c, 0x6c4f, 0x6c4a, 0x6c54, 0x6c4b,
+ /* 0xca */
+ 0x6c4c, 0x7071, 0x725e, 0x72b4, 0x72b5, 0x738e, 0x752a, 0x767f,
+ 0x7a75, 0x7f51, 0x8278, 0x827c, 0x8280, 0x827d, 0x827f, 0x864d,
+ 0x897e, 0x9099, 0x9097, 0x9098, 0x909b, 0x9094, 0x9622, 0x9624,
+ 0x9620, 0x9623, 0x4f56, 0x4f3b, 0x4f62, 0x4f49, 0x4f53, 0x4f64,
+ 0x4f3e, 0x4f67, 0x4f52, 0x4f5f, 0x4f41, 0x4f58, 0x4f2d, 0x4f33,
+ 0x4f3f, 0x4f61, 0x518f, 0x51b9, 0x521c, 0x521e, 0x5221, 0x52ad,
+ 0x52ae, 0x5309, 0x5363, 0x5372, 0x538e, 0x538f, 0x5430, 0x5437,
+ 0x542a, 0x5454, 0x5445, 0x5419, 0x541c, 0x5425, 0x5418, 0x543d,
+ 0x544f, 0x5441, 0x5428, 0x5424, 0x5447, 0x56ee, 0x56e7, 0x56e5,
+ 0x5741, 0x5745, 0x574c, 0x5749, 0x574b, 0x5752, 0x5906, 0x5940,
+ 0x59a6, 0x5998, 0x59a0, 0x5997, 0x598e, 0x59a2, 0x5990, 0x598f,
+ 0x59a7, 0x59a1, 0x5b8e, 0x5b92, 0x5c28, 0x5c2a, 0x5c8d, 0x5c8f,
+ 0x5c88, 0x5c8b, 0x5c89, 0x5c92, 0x5c8a, 0x5c86, 0x5c93, 0x5c95,
+ 0x5de0, 0x5e0a, 0x5e0e, 0x5e8b, 0x5e89, 0x5e8c, 0x5e88, 0x5e8d,
+ 0x5f05, 0x5f1d, 0x5f78, 0x5f76, 0x5fd2, 0x5fd1, 0x5fd0, 0x5fed,
+ 0x5fe8, 0x5fee, 0x5ff3, 0x5fe1, 0x5fe4, 0x5fe3, 0x5ffa, 0x5fef,
+ 0x5ff7, 0x5ffb, 0x6000, 0x5ff4, 0x623a, 0x6283, 0x628c, 0x628e,
+ 0x628f, 0x6294, 0x6287, 0x6271, 0x627b, 0x627a, 0x6270, 0x6281,
+ 0x6288, 0x6277, 0x627d, 0x6272, 0x6274, 0x6537, 0x65f0, 0x65f4,
+ 0x65f3, 0x65f2, 0x65f5, 0x6745, 0x6747,
+ /* 0xcb */
+ 0x6759, 0x6755, 0x674c, 0x6748, 0x675d, 0x674d, 0x675a, 0x674b,
+ 0x6bd0, 0x6c19, 0x6c1a, 0x6c78, 0x6c67, 0x6c6b, 0x6c84, 0x6c8b,
+ 0x6c8f, 0x6c71, 0x6c6f, 0x6c69, 0x6c9a, 0x6c6d, 0x6c87, 0x6c95,
+ 0x6c9c, 0x6c66, 0x6c73, 0x6c65, 0x6c7b, 0x6c8e, 0x7074, 0x707a,
+ 0x7263, 0x72bf, 0x72bd, 0x72c3, 0x72c6, 0x72c1, 0x72ba, 0x72c5,
+ 0x7395, 0x7397, 0x7393, 0x7394, 0x7392, 0x753a, 0x7539, 0x7594,
+ 0x7595, 0x7681, 0x793d, 0x8034, 0x8095, 0x8099, 0x8090, 0x8092,
+ 0x809c, 0x8290, 0x828f, 0x8285, 0x828e, 0x8291, 0x8293, 0x828a,
+ 0x8283, 0x8284, 0x8c78, 0x8fc9, 0x8fbf, 0x909f, 0x90a1, 0x90a5,
+ 0x909e, 0x90a7, 0x90a0, 0x9630, 0x9628, 0x962f, 0x962d, 0x4e33,
+ 0x4f98, 0x4f7c, 0x4f85, 0x4f7d, 0x4f80, 0x4f87, 0x4f76, 0x4f74,
+ 0x4f89, 0x4f84, 0x4f77, 0x4f4c, 0x4f97, 0x4f6a, 0x4f9a, 0x4f79,
+ 0x4f81, 0x4f78, 0x4f90, 0x4f9c, 0x4f94, 0x4f9e, 0x4f92, 0x4f82,
+ 0x4f95, 0x4f6b, 0x4f6e, 0x519e, 0x51bc, 0x51be, 0x5235, 0x5232,
+ 0x5233, 0x5246, 0x5231, 0x52bc, 0x530a, 0x530b, 0x533c, 0x5392,
+ 0x5394, 0x5487, 0x547f, 0x5481, 0x5491, 0x5482, 0x5488, 0x546b,
+ 0x547a, 0x547e, 0x5465, 0x546c, 0x5474, 0x5466, 0x548d, 0x546f,
+ 0x5461, 0x5460, 0x5498, 0x5463, 0x5467, 0x5464, 0x56f7, 0x56f9,
+ 0x576f, 0x5772, 0x576d, 0x576b, 0x5771, 0x5770, 0x5776, 0x5780,
+ 0x5775, 0x577b, 0x5773, 0x5774, 0x5762,
+ /* 0xcc */
+ 0x5768, 0x577d, 0x590c, 0x5945, 0x59b5, 0x59ba, 0x59cf, 0x59ce,
+ 0x59b2, 0x59cc, 0x59c1, 0x59b6, 0x59bc, 0x59c3, 0x59d6, 0x59b1,
+ 0x59bd, 0x59c0, 0x59c8, 0x59b4, 0x59c7, 0x5b62, 0x5b65, 0x5b93,
+ 0x5b95, 0x5c44, 0x5c47, 0x5cae, 0x5ca4, 0x5ca0, 0x5cb5, 0x5caf,
+ 0x5ca8, 0x5cac, 0x5c9f, 0x5ca3, 0x5cad, 0x5ca2, 0x5caa, 0x5ca7,
+ 0x5c9d, 0x5ca5, 0x5cb6, 0x5cb0, 0x5ca6, 0x5e17, 0x5e14, 0x5e19,
+ 0x5f28, 0x5f22, 0x5f23, 0x5f24, 0x5f54, 0x5f82, 0x5f7e, 0x5f7d,
+ 0x5fde, 0x5fe5, 0x602d, 0x6026, 0x6019, 0x6032, 0x600b, 0x6034,
+ 0x600a, 0x6017, 0x6033, 0x601a, 0x601e, 0x602c, 0x6022, 0x600d,
+ 0x6010, 0x602e, 0x6013, 0x6011, 0x600c, 0x6009, 0x601c, 0x6214,
+ 0x623d, 0x62ad, 0x62b4, 0x62d1, 0x62be, 0x62aa, 0x62b6, 0x62ca,
+ 0x62ae, 0x62b3, 0x62af, 0x62bb, 0x62a9, 0x62b0, 0x62b8, 0x653d,
+ 0x65a8, 0x65bb, 0x6609, 0x65fc, 0x6604, 0x6612, 0x6608, 0x65fb,
+ 0x6603, 0x660b, 0x660d, 0x6605, 0x65fd, 0x6611, 0x6610, 0x66f6,
+ 0x670a, 0x6785, 0x676c, 0x678e, 0x6792, 0x6776, 0x677b, 0x6798,
+ 0x6786, 0x6784, 0x6774, 0x678d, 0x678c, 0x677a, 0x679f, 0x6791,
+ 0x6799, 0x6783, 0x677d, 0x6781, 0x6778, 0x6779, 0x6794, 0x6b25,
+ 0x6b80, 0x6b7e, 0x6bde, 0x6c1d, 0x6c93, 0x6cec, 0x6ceb, 0x6cee,
+ 0x6cd9, 0x6cb6, 0x6cd4, 0x6cad, 0x6ce7, 0x6cb7, 0x6cd0, 0x6cc2,
+ 0x6cba, 0x6cc3, 0x6cc6, 0x6ced, 0x6cf2,
+ /* 0xcd */
+ 0x6cd2, 0x6cdd, 0x6cb4, 0x6c8a, 0x6c9d, 0x6c80, 0x6cde, 0x6cc0,
+ 0x6d30, 0x6ccd, 0x6cc7, 0x6cb0, 0x6cf9, 0x6ccf, 0x6ce9, 0x6cd1,
+ 0x7094, 0x7098, 0x7085, 0x7093, 0x7086, 0x7084, 0x7091, 0x7096,
+ 0x7082, 0x709a, 0x7083, 0x726a, 0x72d6, 0x72cb, 0x72d8, 0x72c9,
+ 0x72dc, 0x72d2, 0x72d4, 0x72da, 0x72cc, 0x72d1, 0x73a4, 0x73a1,
+ 0x73ad, 0x73a6, 0x73a2, 0x73a0, 0x73ac, 0x739d, 0x74dd, 0x74e8,
+ 0x753f, 0x7540, 0x753e, 0x758c, 0x7598, 0x76af, 0x76f3, 0x76f1,
+ 0x76f0, 0x76f5, 0x77f8, 0x77fc, 0x77f9, 0x77fb, 0x77fa, 0x77f7,
+ 0x7942, 0x793f, 0x79c5, 0x7a78, 0x7a7b, 0x7afb, 0x7c75, 0x7cfd,
+ 0x8035, 0x808f, 0x80ae, 0x80a3, 0x80b8, 0x80b5, 0x80ad, 0x8220,
+ 0x82a0, 0x82c0, 0x82ab, 0x829a, 0x8298, 0x829b, 0x82b5, 0x82a7,
+ 0x82ae, 0x82bc, 0x829e, 0x82ba, 0x82b4, 0x82a8, 0x82a1, 0x82a9,
+ 0x82c2, 0x82a4, 0x82c3, 0x82b6, 0x82a2, 0x8670, 0x866f, 0x866d,
+ 0x866e, 0x8c56, 0x8fd2, 0x8fcb, 0x8fd3, 0x8fcd, 0x8fd6, 0x8fd5,
+ 0x8fd7, 0x90b2, 0x90b4, 0x90af, 0x90b3, 0x90b0, 0x9639, 0x963d,
+ 0x963c, 0x963a, 0x9643, 0x4fcd, 0x4fc5, 0x4fd3, 0x4fb2, 0x4fc9,
+ 0x4fcb, 0x4fc1, 0x4fd4, 0x4fdc, 0x4fd9, 0x4fbb, 0x4fb3, 0x4fdb,
+ 0x4fc7, 0x4fd6, 0x4fba, 0x4fc0, 0x4fb9, 0x4fec, 0x5244, 0x5249,
+ 0x52c0, 0x52c2, 0x533d, 0x537c, 0x5397, 0x5396, 0x5399, 0x5398,
+ 0x54ba, 0x54a1, 0x54ad, 0x54a5, 0x54cf,
+ /* 0xce */
+ 0x54c3, 0x830d, 0x54b7, 0x54ae, 0x54d6, 0x54b6, 0x54c5, 0x54c6,
+ 0x54a0, 0x5470, 0x54bc, 0x54a2, 0x54be, 0x5472, 0x54de, 0x54b0,
+ 0x57b5, 0x579e, 0x579f, 0x57a4, 0x578c, 0x5797, 0x579d, 0x579b,
+ 0x5794, 0x5798, 0x578f, 0x5799, 0x57a5, 0x579a, 0x5795, 0x58f4,
+ 0x590d, 0x5953, 0x59e1, 0x59de, 0x59ee, 0x5a00, 0x59f1, 0x59dd,
+ 0x59fa, 0x59fd, 0x59fc, 0x59f6, 0x59e4, 0x59f2, 0x59f7, 0x59db,
+ 0x59e9, 0x59f3, 0x59f5, 0x59e0, 0x59fe, 0x59f4, 0x59ed, 0x5ba8,
+ 0x5c4c, 0x5cd0, 0x5cd8, 0x5ccc, 0x5cd7, 0x5ccb, 0x5cdb, 0x5cde,
+ 0x5cda, 0x5cc9, 0x5cc7, 0x5cca, 0x5cd6, 0x5cd3, 0x5cd4, 0x5ccf,
+ 0x5cc8, 0x5cc6, 0x5cce, 0x5cdf, 0x5cf8, 0x5df9, 0x5e21, 0x5e22,
+ 0x5e23, 0x5e20, 0x5e24, 0x5eb0, 0x5ea4, 0x5ea2, 0x5e9b, 0x5ea3,
+ 0x5ea5, 0x5f07, 0x5f2e, 0x5f56, 0x5f86, 0x6037, 0x6039, 0x6054,
+ 0x6072, 0x605e, 0x6045, 0x6053, 0x6047, 0x6049, 0x605b, 0x604c,
+ 0x6040, 0x6042, 0x605f, 0x6024, 0x6044, 0x6058, 0x6066, 0x606e,
+ 0x6242, 0x6243, 0x62cf, 0x630d, 0x630b, 0x62f5, 0x630e, 0x6303,
+ 0x62eb, 0x62f9, 0x630f, 0x630c, 0x62f8, 0x62f6, 0x6300, 0x6313,
+ 0x6314, 0x62fa, 0x6315, 0x62fb, 0x62f0, 0x6541, 0x6543, 0x65aa,
+ 0x65bf, 0x6636, 0x6621, 0x6632, 0x6635, 0x661c, 0x6626, 0x6622,
+ 0x6633, 0x662b, 0x663a, 0x661d, 0x6634, 0x6639, 0x662e, 0x670f,
+ 0x6710, 0x67c1, 0x67f2, 0x67c8, 0x67ba,
+ /* 0xcf */
+ 0x67dc, 0x67bb, 0x67f8, 0x67d8, 0x67c0, 0x67b7, 0x67c5, 0x67eb,
+ 0x67e4, 0x67df, 0x67b5, 0x67cd, 0x67b3, 0x67f7, 0x67f6, 0x67ee,
+ 0x67e3, 0x67c2, 0x67b9, 0x67ce, 0x67e7, 0x67f0, 0x67b2, 0x67fc,
+ 0x67c6, 0x67ed, 0x67cc, 0x67ae, 0x67e6, 0x67db, 0x67fa, 0x67c9,
+ 0x67ca, 0x67c3, 0x67ea, 0x67cb, 0x6b28, 0x6b82, 0x6b84, 0x6bb6,
+ 0x6bd6, 0x6bd8, 0x6be0, 0x6c20, 0x6c21, 0x6d28, 0x6d34, 0x6d2d,
+ 0x6d1f, 0x6d3c, 0x6d3f, 0x6d12, 0x6d0a, 0x6cda, 0x6d33, 0x6d04,
+ 0x6d19, 0x6d3a, 0x6d1a, 0x6d11, 0x6d00, 0x6d1d, 0x6d42, 0x6d01,
+ 0x6d18, 0x6d37, 0x6d03, 0x6d0f, 0x6d40, 0x6d07, 0x6d20, 0x6d2c,
+ 0x6d08, 0x6d22, 0x6d09, 0x6d10, 0x70b7, 0x709f, 0x70be, 0x70b1,
+ 0x70b0, 0x70a1, 0x70b4, 0x70b5, 0x70a9, 0x7241, 0x7249, 0x724a,
+ 0x726c, 0x7270, 0x7273, 0x726e, 0x72ca, 0x72e4, 0x72e8, 0x72eb,
+ 0x72df, 0x72ea, 0x72e6, 0x72e3, 0x7385, 0x73cc, 0x73c2, 0x73c8,
+ 0x73c5, 0x73b9, 0x73b6, 0x73b5, 0x73b4, 0x73eb, 0x73bf, 0x73c7,
+ 0x73be, 0x73c3, 0x73c6, 0x73b8, 0x73cb, 0x74ec, 0x74ee, 0x752e,
+ 0x7547, 0x7548, 0x75a7, 0x75aa, 0x7679, 0x76c4, 0x7708, 0x7703,
+ 0x7704, 0x7705, 0x770a, 0x76f7, 0x76fb, 0x76fa, 0x77e7, 0x77e8,
+ 0x7806, 0x7811, 0x7812, 0x7805, 0x7810, 0x780f, 0x780e, 0x7809,
+ 0x7803, 0x7813, 0x794a, 0x794c, 0x794b, 0x7945, 0x7944, 0x79d5,
+ 0x79cd, 0x79cf, 0x79d6, 0x79ce, 0x7a80,
+ /* 0xd0 */
+ 0x7a7e, 0x7ad1, 0x7b00, 0x7b01, 0x7c7a, 0x7c78, 0x7c79, 0x7c7f,
+ 0x7c80, 0x7c81, 0x7d03, 0x7d08, 0x7d01, 0x7f58, 0x7f91, 0x7f8d,
+ 0x7fbe, 0x8007, 0x800e, 0x800f, 0x8014, 0x8037, 0x80d8, 0x80c7,
+ 0x80e0, 0x80d1, 0x80c8, 0x80c2, 0x80d0, 0x80c5, 0x80e3, 0x80d9,
+ 0x80dc, 0x80ca, 0x80d5, 0x80c9, 0x80cf, 0x80d7, 0x80e6, 0x80cd,
+ 0x81ff, 0x8221, 0x8294, 0x82d9, 0x82fe, 0x82f9, 0x8307, 0x82e8,
+ 0x8300, 0x82d5, 0x833a, 0x82eb, 0x82d6, 0x82f4, 0x82ec, 0x82e1,
+ 0x82f2, 0x82f5, 0x830c, 0x82fb, 0x82f6, 0x82f0, 0x82ea, 0x82e4,
+ 0x82e0, 0x82fa, 0x82f3, 0x82ed, 0x8677, 0x8674, 0x867c, 0x8673,
+ 0x8841, 0x884e, 0x8867, 0x886a, 0x8869, 0x89d3, 0x8a04, 0x8a07,
+ 0x8d72, 0x8fe3, 0x8fe1, 0x8fee, 0x8fe0, 0x90f1, 0x90bd, 0x90bf,
+ 0x90d5, 0x90c5, 0x90be, 0x90c7, 0x90cb, 0x90c8, 0x91d4, 0x91d3,
+ 0x9654, 0x964f, 0x9651, 0x9653, 0x964a, 0x964e, 0x501e, 0x5005,
+ 0x5007, 0x5013, 0x5022, 0x5030, 0x501b, 0x4ff5, 0x4ff4, 0x5033,
+ 0x5037, 0x502c, 0x4ff6, 0x4ff7, 0x5017, 0x501c, 0x5020, 0x5027,
+ 0x5035, 0x502f, 0x5031, 0x500e, 0x515a, 0x5194, 0x5193, 0x51ca,
+ 0x51c4, 0x51c5, 0x51c8, 0x51ce, 0x5261, 0x525a, 0x5252, 0x525e,
+ 0x525f, 0x5255, 0x5262, 0x52cd, 0x530e, 0x539e, 0x5526, 0x54e2,
+ 0x5517, 0x5512, 0x54e7, 0x54f3, 0x54e4, 0x551a, 0x54ff, 0x5504,
+ 0x5508, 0x54eb, 0x5511, 0x5505, 0x54f1,
+ /* 0xd1 */
+ 0x550a, 0x54fb, 0x54f7, 0x54f8, 0x54e0, 0x550e, 0x5503, 0x550b,
+ 0x5701, 0x5702, 0x57cc, 0x5832, 0x57d5, 0x57d2, 0x57ba, 0x57c6,
+ 0x57bd, 0x57bc, 0x57b8, 0x57b6, 0x57bf, 0x57c7, 0x57d0, 0x57b9,
+ 0x57c1, 0x590e, 0x594a, 0x5a19, 0x5a16, 0x5a2d, 0x5a2e, 0x5a15,
+ 0x5a0f, 0x5a17, 0x5a0a, 0x5a1e, 0x5a33, 0x5b6c, 0x5ba7, 0x5bad,
+ 0x5bac, 0x5c03, 0x5c56, 0x5c54, 0x5cec, 0x5cff, 0x5cee, 0x5cf1,
+ 0x5cf7, 0x5d00, 0x5cf9, 0x5e29, 0x5e28, 0x5ea8, 0x5eae, 0x5eaa,
+ 0x5eac, 0x5f33, 0x5f30, 0x5f67, 0x605d, 0x605a, 0x6067, 0x6041,
+ 0x60a2, 0x6088, 0x6080, 0x6092, 0x6081, 0x609d, 0x6083, 0x6095,
+ 0x609b, 0x6097, 0x6087, 0x609c, 0x608e, 0x6219, 0x6246, 0x62f2,
+ 0x6310, 0x6356, 0x632c, 0x6344, 0x6345, 0x6336, 0x6343, 0x63e4,
+ 0x6339, 0x634b, 0x634a, 0x633c, 0x6329, 0x6341, 0x6334, 0x6358,
+ 0x6354, 0x6359, 0x632d, 0x6347, 0x6333, 0x635a, 0x6351, 0x6338,
+ 0x6357, 0x6340, 0x6348, 0x654a, 0x6546, 0x65c6, 0x65c3, 0x65c4,
+ 0x65c2, 0x664a, 0x665f, 0x6647, 0x6651, 0x6712, 0x6713, 0x681f,
+ 0x681a, 0x6849, 0x6832, 0x6833, 0x683b, 0x684b, 0x684f, 0x6816,
+ 0x6831, 0x681c, 0x6835, 0x682b, 0x682d, 0x682f, 0x684e, 0x6844,
+ 0x6834, 0x681d, 0x6812, 0x6814, 0x6826, 0x6828, 0x682e, 0x684d,
+ 0x683a, 0x6825, 0x6820, 0x6b2c, 0x6b2f, 0x6b2d, 0x6b31, 0x6b34,
+ 0x6b6d, 0x8082, 0x6b88, 0x6be6, 0x6be4,
+ /* 0xd2 */
+ 0x6be8, 0x6be3, 0x6be2, 0x6be7, 0x6c25, 0x6d7a, 0x6d63, 0x6d64,
+ 0x6d76, 0x6d0d, 0x6d61, 0x6d92, 0x6d58, 0x6d62, 0x6d6d, 0x6d6f,
+ 0x6d91, 0x6d8d, 0x6def, 0x6d7f, 0x6d86, 0x6d5e, 0x6d67, 0x6d60,
+ 0x6d97, 0x6d70, 0x6d7c, 0x6d5f, 0x6d82, 0x6d98, 0x6d2f, 0x6d68,
+ 0x6d8b, 0x6d7e, 0x6d80, 0x6d84, 0x6d16, 0x6d83, 0x6d7b, 0x6d7d,
+ 0x6d75, 0x6d90, 0x70dc, 0x70d3, 0x70d1, 0x70dd, 0x70cb, 0x7f39,
+ 0x70e2, 0x70d7, 0x70d2, 0x70de, 0x70e0, 0x70d4, 0x70cd, 0x70c5,
+ 0x70c6, 0x70c7, 0x70da, 0x70ce, 0x70e1, 0x7242, 0x7278, 0x7277,
+ 0x7276, 0x7300, 0x72fa, 0x72f4, 0x72fe, 0x72f6, 0x72f3, 0x72fb,
+ 0x7301, 0x73d3, 0x73d9, 0x73e5, 0x73d6, 0x73bc, 0x73e7, 0x73e3,
+ 0x73e9, 0x73dc, 0x73d2, 0x73db, 0x73d4, 0x73dd, 0x73da, 0x73d7,
+ 0x73d8, 0x73e8, 0x74de, 0x74df, 0x74f4, 0x74f5, 0x7521, 0x755b,
+ 0x755f, 0x75b0, 0x75c1, 0x75bb, 0x75c4, 0x75c0, 0x75bf, 0x75b6,
+ 0x75ba, 0x768a, 0x76c9, 0x771d, 0x771b, 0x7710, 0x7713, 0x7712,
+ 0x7723, 0x7711, 0x7715, 0x7719, 0x771a, 0x7722, 0x7727, 0x7823,
+ 0x782c, 0x7822, 0x7835, 0x782f, 0x7828, 0x782e, 0x782b, 0x7821,
+ 0x7829, 0x7833, 0x782a, 0x7831, 0x7954, 0x795b, 0x794f, 0x795c,
+ 0x7953, 0x7952, 0x7951, 0x79eb, 0x79ec, 0x79e0, 0x79ee, 0x79ed,
+ 0x79ea, 0x79dc, 0x79de, 0x79dd, 0x7a86, 0x7a89, 0x7a85, 0x7a8b,
+ 0x7a8c, 0x7a8a, 0x7a87, 0x7ad8, 0x7b10,
+ /* 0xd3 */
+ 0x7b04, 0x7b13, 0x7b05, 0x7b0f, 0x7b08, 0x7b0a, 0x7b0e, 0x7b09,
+ 0x7b12, 0x7c84, 0x7c91, 0x7c8a, 0x7c8c, 0x7c88, 0x7c8d, 0x7c85,
+ 0x7d1e, 0x7d1d, 0x7d11, 0x7d0e, 0x7d18, 0x7d16, 0x7d13, 0x7d1f,
+ 0x7d12, 0x7d0f, 0x7d0c, 0x7f5c, 0x7f61, 0x7f5e, 0x7f60, 0x7f5d,
+ 0x7f5b, 0x7f96, 0x7f92, 0x7fc3, 0x7fc2, 0x7fc0, 0x8016, 0x803e,
+ 0x8039, 0x80fa, 0x80f2, 0x80f9, 0x80f5, 0x8101, 0x80fb, 0x8100,
+ 0x8201, 0x822f, 0x8225, 0x8333, 0x832d, 0x8344, 0x8319, 0x8351,
+ 0x8325, 0x8356, 0x833f, 0x8341, 0x8326, 0x831c, 0x8322, 0x8342,
+ 0x834e, 0x831b, 0x832a, 0x8308, 0x833c, 0x834d, 0x8316, 0x8324,
+ 0x8320, 0x8337, 0x832f, 0x8329, 0x8347, 0x8345, 0x834c, 0x8353,
+ 0x831e, 0x832c, 0x834b, 0x8327, 0x8348, 0x8653, 0x8652, 0x86a2,
+ 0x86a8, 0x8696, 0x868d, 0x8691, 0x869e, 0x8687, 0x8697, 0x8686,
+ 0x868b, 0x869a, 0x8685, 0x86a5, 0x8699, 0x86a1, 0x86a7, 0x8695,
+ 0x8698, 0x868e, 0x869d, 0x8690, 0x8694, 0x8843, 0x8844, 0x886d,
+ 0x8875, 0x8876, 0x8872, 0x8880, 0x8871, 0x887f, 0x886f, 0x8883,
+ 0x887e, 0x8874, 0x887c, 0x8a12, 0x8c47, 0x8c57, 0x8c7b, 0x8ca4,
+ 0x8ca3, 0x8d76, 0x8d78, 0x8db5, 0x8db7, 0x8db6, 0x8ed1, 0x8ed3,
+ 0x8ffe, 0x8ff5, 0x9002, 0x8fff, 0x8ffb, 0x9004, 0x8ffc, 0x8ff6,
+ 0x90d6, 0x90e0, 0x90d9, 0x90da, 0x90e3, 0x90df, 0x90e5, 0x90d8,
+ 0x90db, 0x90d7, 0x90dc, 0x90e4, 0x9150,
+ /* 0xd4 */
+ 0x914e, 0x914f, 0x91d5, 0x91e2, 0x91da, 0x965c, 0x965f, 0x96bc,
+ 0x98e3, 0x9adf, 0x9b2f, 0x4e7f, 0x5070, 0x506a, 0x5061, 0x505e,
+ 0x5060, 0x5053, 0x504b, 0x505d, 0x5072, 0x5048, 0x504d, 0x5041,
+ 0x505b, 0x504a, 0x5062, 0x5015, 0x5045, 0x505f, 0x5069, 0x506b,
+ 0x5063, 0x5064, 0x5046, 0x5040, 0x506e, 0x5073, 0x5057, 0x5051,
+ 0x51d0, 0x526b, 0x526d, 0x526c, 0x526e, 0x52d6, 0x52d3, 0x532d,
+ 0x539c, 0x5575, 0x5576, 0x553c, 0x554d, 0x5550, 0x5534, 0x552a,
+ 0x5551, 0x5562, 0x5536, 0x5535, 0x5530, 0x5552, 0x5545, 0x550c,
+ 0x5532, 0x5565, 0x554e, 0x5539, 0x5548, 0x552d, 0x553b, 0x5540,
+ 0x554b, 0x570a, 0x5707, 0x57fb, 0x5814, 0x57e2, 0x57f6, 0x57dc,
+ 0x57f4, 0x5800, 0x57ed, 0x57fd, 0x5808, 0x57f8, 0x580b, 0x57f3,
+ 0x57cf, 0x5807, 0x57ee, 0x57e3, 0x57f2, 0x57e5, 0x57ec, 0x57e1,
+ 0x580e, 0x57fc, 0x5810, 0x57e7, 0x5801, 0x580c, 0x57f1, 0x57e9,
+ 0x57f0, 0x580d, 0x5804, 0x595c, 0x5a60, 0x5a58, 0x5a55, 0x5a67,
+ 0x5a5e, 0x5a38, 0x5a35, 0x5a6d, 0x5a50, 0x5a5f, 0x5a65, 0x5a6c,
+ 0x5a53, 0x5a64, 0x5a57, 0x5a43, 0x5a5d, 0x5a52, 0x5a44, 0x5a5b,
+ 0x5a48, 0x5a8e, 0x5a3e, 0x5a4d, 0x5a39, 0x5a4c, 0x5a70, 0x5a69,
+ 0x5a47, 0x5a51, 0x5a56, 0x5a42, 0x5a5c, 0x5b72, 0x5b6e, 0x5bc1,
+ 0x5bc0, 0x5c59, 0x5d1e, 0x5d0b, 0x5d1d, 0x5d1a, 0x5d20, 0x5d0c,
+ 0x5d28, 0x5d0d, 0x5d26, 0x5d25, 0x5d0f,
+ /* 0xd5 */
+ 0x5d30, 0x5d12, 0x5d23, 0x5d1f, 0x5d2e, 0x5e3e, 0x5e34, 0x5eb1,
+ 0x5eb4, 0x5eb9, 0x5eb2, 0x5eb3, 0x5f36, 0x5f38, 0x5f9b, 0x5f96,
+ 0x5f9f, 0x608a, 0x6090, 0x6086, 0x60be, 0x60b0, 0x60ba, 0x60d3,
+ 0x60d4, 0x60cf, 0x60e4, 0x60d9, 0x60dd, 0x60c8, 0x60b1, 0x60db,
+ 0x60b7, 0x60ca, 0x60bf, 0x60c3, 0x60cd, 0x60c0, 0x6332, 0x6365,
+ 0x638a, 0x6382, 0x637d, 0x63bd, 0x639e, 0x63ad, 0x639d, 0x6397,
+ 0x63ab, 0x638e, 0x636f, 0x6387, 0x6390, 0x636e, 0x63af, 0x6375,
+ 0x639c, 0x636d, 0x63ae, 0x637c, 0x63a4, 0x633b, 0x639f, 0x6378,
+ 0x6385, 0x6381, 0x6391, 0x638d, 0x6370, 0x6553, 0x65cd, 0x6665,
+ 0x6661, 0x665b, 0x6659, 0x665c, 0x6662, 0x6718, 0x6879, 0x6887,
+ 0x6890, 0x689c, 0x686d, 0x686e, 0x68ae, 0x68ab, 0x6956, 0x686f,
+ 0x68a3, 0x68ac, 0x68a9, 0x6875, 0x6874, 0x68b2, 0x688f, 0x6877,
+ 0x6892, 0x687c, 0x686b, 0x6872, 0x68aa, 0x6880, 0x6871, 0x687e,
+ 0x689b, 0x6896, 0x688b, 0x68a0, 0x6889, 0x68a4, 0x6878, 0x687b,
+ 0x6891, 0x688c, 0x688a, 0x687d, 0x6b36, 0x6b33, 0x6b37, 0x6b38,
+ 0x6b91, 0x6b8f, 0x6b8d, 0x6b8e, 0x6b8c, 0x6c2a, 0x6dc0, 0x6dab,
+ 0x6db4, 0x6db3, 0x6e74, 0x6dac, 0x6de9, 0x6de2, 0x6db7, 0x6df6,
+ 0x6dd4, 0x6e00, 0x6dc8, 0x6de0, 0x6ddf, 0x6dd6, 0x6dbe, 0x6de5,
+ 0x6ddc, 0x6ddd, 0x6ddb, 0x6df4, 0x6dca, 0x6dbd, 0x6ded, 0x6df0,
+ 0x6dba, 0x6dd5, 0x6dc2, 0x6dcf, 0x6dc9,
+ /* 0xd6 */
+ 0x6dd0, 0x6df2, 0x6dd3, 0x6dfd, 0x6dd7, 0x6dcd, 0x6de3, 0x6dbb,
+ 0x70fa, 0x710d, 0x70f7, 0x7117, 0x70f4, 0x710c, 0x70f0, 0x7104,
+ 0x70f3, 0x7110, 0x70fc, 0x70ff, 0x7106, 0x7113, 0x7100, 0x70f8,
+ 0x70f6, 0x710b, 0x7102, 0x710e, 0x727e, 0x727b, 0x727c, 0x727f,
+ 0x731d, 0x7317, 0x7307, 0x7311, 0x7318, 0x730a, 0x7308, 0x72ff,
+ 0x730f, 0x731e, 0x7388, 0x73f6, 0x73f8, 0x73f5, 0x7404, 0x7401,
+ 0x73fd, 0x7407, 0x7400, 0x73fa, 0x73fc, 0x73ff, 0x740c, 0x740b,
+ 0x73f4, 0x7408, 0x7564, 0x7563, 0x75ce, 0x75d2, 0x75cf, 0x75cb,
+ 0x75cc, 0x75d1, 0x75d0, 0x768f, 0x7689, 0x76d3, 0x7739, 0x772f,
+ 0x772d, 0x7731, 0x7732, 0x7734, 0x7733, 0x773d, 0x7725, 0x773b,
+ 0x7735, 0x7848, 0x7852, 0x7849, 0x784d, 0x784a, 0x784c, 0x7826,
+ 0x7845, 0x7850, 0x7964, 0x7967, 0x7969, 0x796a, 0x7963, 0x796b,
+ 0x7961, 0x79bb, 0x79fa, 0x79f8, 0x79f6, 0x79f7, 0x7a8f, 0x7a94,
+ 0x7a90, 0x7b35, 0x7b47, 0x7b34, 0x7b25, 0x7b30, 0x7b22, 0x7b24,
+ 0x7b33, 0x7b18, 0x7b2a, 0x7b1d, 0x7b31, 0x7b2b, 0x7b2d, 0x7b2f,
+ 0x7b32, 0x7b38, 0x7b1a, 0x7b23, 0x7c94, 0x7c98, 0x7c96, 0x7ca3,
+ 0x7d35, 0x7d3d, 0x7d38, 0x7d36, 0x7d3a, 0x7d45, 0x7d2c, 0x7d29,
+ 0x7d41, 0x7d47, 0x7d3e, 0x7d3f, 0x7d4a, 0x7d3b, 0x7d28, 0x7f63,
+ 0x7f95, 0x7f9c, 0x7f9d, 0x7f9b, 0x7fca, 0x7fcb, 0x7fcd, 0x7fd0,
+ 0x7fd1, 0x7fc7, 0x7fcf, 0x7fc9, 0x801f,
+ /* 0xd7 */
+ 0x801e, 0x801b, 0x8047, 0x8043, 0x8048, 0x8118, 0x8125, 0x8119,
+ 0x811b, 0x812d, 0x811f, 0x812c, 0x811e, 0x8121, 0x8115, 0x8127,
+ 0x811d, 0x8122, 0x8211, 0x8238, 0x8233, 0x823a, 0x8234, 0x8232,
+ 0x8274, 0x8390, 0x83a3, 0x83a8, 0x838d, 0x837a, 0x8373, 0x83a4,
+ 0x8374, 0x838f, 0x8381, 0x8395, 0x8399, 0x8375, 0x8394, 0x83a9,
+ 0x837d, 0x8383, 0x838c, 0x839d, 0x839b, 0x83aa, 0x838b, 0x837e,
+ 0x83a5, 0x83af, 0x8388, 0x8397, 0x83b0, 0x837f, 0x83a6, 0x8387,
+ 0x83ae, 0x8376, 0x839a, 0x8659, 0x8656, 0x86bf, 0x86b7, 0x86c2,
+ 0x86c1, 0x86c5, 0x86ba, 0x86b0, 0x86c8, 0x86b9, 0x86b3, 0x86b8,
+ 0x86cc, 0x86b4, 0x86bb, 0x86bc, 0x86c3, 0x86bd, 0x86be, 0x8852,
+ 0x8889, 0x8895, 0x88a8, 0x88a2, 0x88aa, 0x889a, 0x8891, 0x88a1,
+ 0x889f, 0x8898, 0x88a7, 0x8899, 0x889b, 0x8897, 0x88a4, 0x88ac,
+ 0x888c, 0x8893, 0x888e, 0x8982, 0x89d6, 0x89d9, 0x89d5, 0x8a30,
+ 0x8a27, 0x8a2c, 0x8a1e, 0x8c39, 0x8c3b, 0x8c5c, 0x8c5d, 0x8c7d,
+ 0x8ca5, 0x8d7d, 0x8d7b, 0x8d79, 0x8dbc, 0x8dc2, 0x8db9, 0x8dbf,
+ 0x8dc1, 0x8ed8, 0x8ede, 0x8edd, 0x8edc, 0x8ed7, 0x8ee0, 0x8ee1,
+ 0x9024, 0x900b, 0x9011, 0x901c, 0x900c, 0x9021, 0x90ef, 0x90ea,
+ 0x90f0, 0x90f4, 0x90f2, 0x90f3, 0x90d4, 0x90eb, 0x90ec, 0x90e9,
+ 0x9156, 0x9158, 0x915a, 0x9153, 0x9155, 0x91ec, 0x91f4, 0x91f1,
+ 0x91f3, 0x91f8, 0x91e4, 0x91f9, 0x91ea,
+ /* 0xd8 */
+ 0x91eb, 0x91f7, 0x91e8, 0x91ee, 0x957a, 0x9586, 0x9588, 0x967c,
+ 0x966d, 0x966b, 0x9671, 0x966f, 0x96bf, 0x976a, 0x9804, 0x98e5,
+ 0x9997, 0x509b, 0x5095, 0x5094, 0x509e, 0x508b, 0x50a3, 0x5083,
+ 0x508c, 0x508e, 0x509d, 0x5068, 0x509c, 0x5092, 0x5082, 0x5087,
+ 0x515f, 0x51d4, 0x5312, 0x5311, 0x53a4, 0x53a7, 0x5591, 0x55a8,
+ 0x55a5, 0x55ad, 0x5577, 0x5645, 0x55a2, 0x5593, 0x5588, 0x558f,
+ 0x55b5, 0x5581, 0x55a3, 0x5592, 0x55a4, 0x557d, 0x558c, 0x55a6,
+ 0x557f, 0x5595, 0x55a1, 0x558e, 0x570c, 0x5829, 0x5837, 0x5819,
+ 0x581e, 0x5827, 0x5823, 0x5828, 0x57f5, 0x5848, 0x5825, 0x581c,
+ 0x581b, 0x5833, 0x583f, 0x5836, 0x582e, 0x5839, 0x5838, 0x582d,
+ 0x582c, 0x583b, 0x5961, 0x5aaf, 0x5a94, 0x5a9f, 0x5a7a, 0x5aa2,
+ 0x5a9e, 0x5a78, 0x5aa6, 0x5a7c, 0x5aa5, 0x5aac, 0x5a95, 0x5aae,
+ 0x5a37, 0x5a84, 0x5a8a, 0x5a97, 0x5a83, 0x5a8b, 0x5aa9, 0x5a7b,
+ 0x5a7d, 0x5a8c, 0x5a9c, 0x5a8f, 0x5a93, 0x5a9d, 0x5bea, 0x5bcd,
+ 0x5bcb, 0x5bd4, 0x5bd1, 0x5bca, 0x5bce, 0x5c0c, 0x5c30, 0x5d37,
+ 0x5d43, 0x5d6b, 0x5d41, 0x5d4b, 0x5d3f, 0x5d35, 0x5d51, 0x5d4e,
+ 0x5d55, 0x5d33, 0x5d3a, 0x5d52, 0x5d3d, 0x5d31, 0x5d59, 0x5d42,
+ 0x5d39, 0x5d49, 0x5d38, 0x5d3c, 0x5d32, 0x5d36, 0x5d40, 0x5d45,
+ 0x5e44, 0x5e41, 0x5f58, 0x5fa6, 0x5fa5, 0x5fab, 0x60c9, 0x60b9,
+ 0x60cc, 0x60e2, 0x60ce, 0x60c4, 0x6114,
+ /* 0xd9 */
+ 0x60f2, 0x610a, 0x6116, 0x6105, 0x60f5, 0x6113, 0x60f8, 0x60fc,
+ 0x60fe, 0x60c1, 0x6103, 0x6118, 0x611d, 0x6110, 0x60ff, 0x6104,
+ 0x610b, 0x624a, 0x6394, 0x63b1, 0x63b0, 0x63ce, 0x63e5, 0x63e8,
+ 0x63ef, 0x63c3, 0x649d, 0x63f3, 0x63ca, 0x63e0, 0x63f6, 0x63d5,
+ 0x63f2, 0x63f5, 0x6461, 0x63df, 0x63be, 0x63dd, 0x63dc, 0x63c4,
+ 0x63d8, 0x63d3, 0x63c2, 0x63c7, 0x63cc, 0x63cb, 0x63c8, 0x63f0,
+ 0x63d7, 0x63d9, 0x6532, 0x6567, 0x656a, 0x6564, 0x655c, 0x6568,
+ 0x6565, 0x658c, 0x659d, 0x659e, 0x65ae, 0x65d0, 0x65d2, 0x667c,
+ 0x666c, 0x667b, 0x6680, 0x6671, 0x6679, 0x666a, 0x6672, 0x6701,
+ 0x690c, 0x68d3, 0x6904, 0x68dc, 0x692a, 0x68ec, 0x68ea, 0x68f1,
+ 0x690f, 0x68d6, 0x68f7, 0x68eb, 0x68e4, 0x68f6, 0x6913, 0x6910,
+ 0x68f3, 0x68e1, 0x6907, 0x68cc, 0x6908, 0x6970, 0x68b4, 0x6911,
+ 0x68ef, 0x68c6, 0x6914, 0x68f8, 0x68d0, 0x68fd, 0x68fc, 0x68e8,
+ 0x690b, 0x690a, 0x6917, 0x68ce, 0x68c8, 0x68dd, 0x68de, 0x68e6,
+ 0x68f4, 0x68d1, 0x6906, 0x68d4, 0x68e9, 0x6915, 0x6925, 0x68c7,
+ 0x6b39, 0x6b3b, 0x6b3f, 0x6b3c, 0x6b94, 0x6b97, 0x6b99, 0x6b95,
+ 0x6bbd, 0x6bf0, 0x6bf2, 0x6bf3, 0x6c30, 0x6dfc, 0x6e46, 0x6e47,
+ 0x6e1f, 0x6e49, 0x6e88, 0x6e3c, 0x6e3d, 0x6e45, 0x6e62, 0x6e2b,
+ 0x6e3f, 0x6e41, 0x6e5d, 0x6e73, 0x6e1c, 0x6e33, 0x6e4b, 0x6e40,
+ 0x6e51, 0x6e3b, 0x6e03, 0x6e2e, 0x6e5e,
+ /* 0xda */
+ 0x6e68, 0x6e5c, 0x6e61, 0x6e31, 0x6e28, 0x6e60, 0x6e71, 0x6e6b,
+ 0x6e39, 0x6e22, 0x6e30, 0x6e53, 0x6e65, 0x6e27, 0x6e78, 0x6e64,
+ 0x6e77, 0x6e55, 0x6e79, 0x6e52, 0x6e66, 0x6e35, 0x6e36, 0x6e5a,
+ 0x7120, 0x711e, 0x712f, 0x70fb, 0x712e, 0x7131, 0x7123, 0x7125,
+ 0x7122, 0x7132, 0x711f, 0x7128, 0x713a, 0x711b, 0x724b, 0x725a,
+ 0x7288, 0x7289, 0x7286, 0x7285, 0x728b, 0x7312, 0x730b, 0x7330,
+ 0x7322, 0x7331, 0x7333, 0x7327, 0x7332, 0x732d, 0x7326, 0x7323,
+ 0x7335, 0x730c, 0x742e, 0x742c, 0x7430, 0x742b, 0x7416, 0x741a,
+ 0x7421, 0x742d, 0x7431, 0x7424, 0x7423, 0x741d, 0x7429, 0x7420,
+ 0x7432, 0x74fb, 0x752f, 0x756f, 0x756c, 0x75e7, 0x75da, 0x75e1,
+ 0x75e6, 0x75dd, 0x75df, 0x75e4, 0x75d7, 0x7695, 0x7692, 0x76da,
+ 0x7746, 0x7747, 0x7744, 0x774d, 0x7745, 0x774a, 0x774e, 0x774b,
+ 0x774c, 0x77de, 0x77ec, 0x7860, 0x7864, 0x7865, 0x785c, 0x786d,
+ 0x7871, 0x786a, 0x786e, 0x7870, 0x7869, 0x7868, 0x785e, 0x7862,
+ 0x7974, 0x7973, 0x7972, 0x7970, 0x7a02, 0x7a0a, 0x7a03, 0x7a0c,
+ 0x7a04, 0x7a99, 0x7ae6, 0x7ae4, 0x7b4a, 0x7b3b, 0x7b44, 0x7b48,
+ 0x7b4c, 0x7b4e, 0x7b40, 0x7b58, 0x7b45, 0x7ca2, 0x7c9e, 0x7ca8,
+ 0x7ca1, 0x7d58, 0x7d6f, 0x7d63, 0x7d53, 0x7d56, 0x7d67, 0x7d6a,
+ 0x7d4f, 0x7d6d, 0x7d5c, 0x7d6b, 0x7d52, 0x7d54, 0x7d69, 0x7d51,
+ 0x7d5f, 0x7d4e, 0x7f3e, 0x7f3f, 0x7f65,
+ /* 0xdb */
+ 0x7f66, 0x7fa2, 0x7fa0, 0x7fa1, 0x7fd7, 0x8051, 0x804f, 0x8050,
+ 0x80fe, 0x80d4, 0x8143, 0x814a, 0x8152, 0x814f, 0x8147, 0x813d,
+ 0x814d, 0x813a, 0x81e6, 0x81ee, 0x81f7, 0x81f8, 0x81f9, 0x8204,
+ 0x823c, 0x823d, 0x823f, 0x8275, 0x833b, 0x83cf, 0x83f9, 0x8423,
+ 0x83c0, 0x83e8, 0x8412, 0x83e7, 0x83e4, 0x83fc, 0x83f6, 0x8410,
+ 0x83c6, 0x83c8, 0x83eb, 0x83e3, 0x83bf, 0x8401, 0x83dd, 0x83e5,
+ 0x83d8, 0x83ff, 0x83e1, 0x83cb, 0x83ce, 0x83d6, 0x83f5, 0x83c9,
+ 0x8409, 0x840f, 0x83de, 0x8411, 0x8406, 0x83c2, 0x83f3, 0x83d5,
+ 0x83fa, 0x83c7, 0x83d1, 0x83ea, 0x8413, 0x83c3, 0x83ec, 0x83ee,
+ 0x83c4, 0x83fb, 0x83d7, 0x83e2, 0x841b, 0x83db, 0x83fe, 0x86d8,
+ 0x86e2, 0x86e6, 0x86d3, 0x86e3, 0x86da, 0x86ea, 0x86dd, 0x86eb,
+ 0x86dc, 0x86ec, 0x86e9, 0x86d7, 0x86e8, 0x86d1, 0x8848, 0x8856,
+ 0x8855, 0x88ba, 0x88d7, 0x88b9, 0x88b8, 0x88c0, 0x88be, 0x88b6,
+ 0x88bc, 0x88b7, 0x88bd, 0x88b2, 0x8901, 0x88c9, 0x8995, 0x8998,
+ 0x8997, 0x89dd, 0x89da, 0x89db, 0x8a4e, 0x8a4d, 0x8a39, 0x8a59,
+ 0x8a40, 0x8a57, 0x8a58, 0x8a44, 0x8a45, 0x8a52, 0x8a48, 0x8a51,
+ 0x8a4a, 0x8a4c, 0x8a4f, 0x8c5f, 0x8c81, 0x8c80, 0x8cba, 0x8cbe,
+ 0x8cb0, 0x8cb9, 0x8cb5, 0x8d84, 0x8d80, 0x8d89, 0x8dd8, 0x8dd3,
+ 0x8dcd, 0x8dc7, 0x8dd6, 0x8ddc, 0x8dcf, 0x8dd5, 0x8dd9, 0x8dc8,
+ 0x8dd7, 0x8dc5, 0x8eef, 0x8ef7, 0x8efa,
+ /* 0xdc */
+ 0x8ef9, 0x8ee6, 0x8eee, 0x8ee5, 0x8ef5, 0x8ee7, 0x8ee8, 0x8ef6,
+ 0x8eeb, 0x8ef1, 0x8eec, 0x8ef4, 0x8ee9, 0x902d, 0x9034, 0x902f,
+ 0x9106, 0x912c, 0x9104, 0x90ff, 0x90fc, 0x9108, 0x90f9, 0x90fb,
+ 0x9101, 0x9100, 0x9107, 0x9105, 0x9103, 0x9161, 0x9164, 0x915f,
+ 0x9162, 0x9160, 0x9201, 0x920a, 0x9225, 0x9203, 0x921a, 0x9226,
+ 0x920f, 0x920c, 0x9200, 0x9212, 0x91ff, 0x91fd, 0x9206, 0x9204,
+ 0x9227, 0x9202, 0x921c, 0x9224, 0x9219, 0x9217, 0x9205, 0x9216,
+ 0x957b, 0x958d, 0x958c, 0x9590, 0x9687, 0x967e, 0x9688, 0x9689,
+ 0x9683, 0x9680, 0x96c2, 0x96c8, 0x96c3, 0x96f1, 0x96f0, 0x976c,
+ 0x9770, 0x976e, 0x9807, 0x98a9, 0x98eb, 0x9ce6, 0x9ef9, 0x4e83,
+ 0x4e84, 0x4eb6, 0x50bd, 0x50bf, 0x50c6, 0x50ae, 0x50c4, 0x50ca,
+ 0x50b4, 0x50c8, 0x50c2, 0x50b0, 0x50c1, 0x50ba, 0x50b1, 0x50cb,
+ 0x50c9, 0x50b6, 0x50b8, 0x51d7, 0x527a, 0x5278, 0x527b, 0x527c,
+ 0x55c3, 0x55db, 0x55cc, 0x55d0, 0x55cb, 0x55ca, 0x55dd, 0x55c0,
+ 0x55d4, 0x55c4, 0x55e9, 0x55bf, 0x55d2, 0x558d, 0x55cf, 0x55d5,
+ 0x55e2, 0x55d6, 0x55c8, 0x55f2, 0x55cd, 0x55d9, 0x55c2, 0x5714,
+ 0x5853, 0x5868, 0x5864, 0x584f, 0x584d, 0x5849, 0x586f, 0x5855,
+ 0x584e, 0x585d, 0x5859, 0x5865, 0x585b, 0x583d, 0x5863, 0x5871,
+ 0x58fc, 0x5ac7, 0x5ac4, 0x5acb, 0x5aba, 0x5ab8, 0x5ab1, 0x5ab5,
+ 0x5ab0, 0x5abf, 0x5ac8, 0x5abb, 0x5ac6,
+ /* 0xdd */
+ 0x5ab7, 0x5ac0, 0x5aca, 0x5ab4, 0x5ab6, 0x5acd, 0x5ab9, 0x5a90,
+ 0x5bd6, 0x5bd8, 0x5bd9, 0x5c1f, 0x5c33, 0x5d71, 0x5d63, 0x5d4a,
+ 0x5d65, 0x5d72, 0x5d6c, 0x5d5e, 0x5d68, 0x5d67, 0x5d62, 0x5df0,
+ 0x5e4f, 0x5e4e, 0x5e4a, 0x5e4d, 0x5e4b, 0x5ec5, 0x5ecc, 0x5ec6,
+ 0x5ecb, 0x5ec7, 0x5f40, 0x5faf, 0x5fad, 0x60f7, 0x6149, 0x614a,
+ 0x612b, 0x6145, 0x6136, 0x6132, 0x612e, 0x6146, 0x612f, 0x614f,
+ 0x6129, 0x6140, 0x6220, 0x9168, 0x6223, 0x6225, 0x6224, 0x63c5,
+ 0x63f1, 0x63eb, 0x6410, 0x6412, 0x6409, 0x6420, 0x6424, 0x6433,
+ 0x6443, 0x641f, 0x6415, 0x6418, 0x6439, 0x6437, 0x6422, 0x6423,
+ 0x640c, 0x6426, 0x6430, 0x6428, 0x6441, 0x6435, 0x642f, 0x640a,
+ 0x641a, 0x6440, 0x6425, 0x6427, 0x640b, 0x63e7, 0x641b, 0x642e,
+ 0x6421, 0x640e, 0x656f, 0x6592, 0x65d3, 0x6686, 0x668c, 0x6695,
+ 0x6690, 0x668b, 0x668a, 0x6699, 0x6694, 0x6678, 0x6720, 0x6966,
+ 0x695f, 0x6938, 0x694e, 0x6962, 0x6971, 0x693f, 0x6945, 0x696a,
+ 0x6939, 0x6942, 0x6957, 0x6959, 0x697a, 0x6948, 0x6949, 0x6935,
+ 0x696c, 0x6933, 0x693d, 0x6965, 0x68f0, 0x6978, 0x6934, 0x6969,
+ 0x6940, 0x696f, 0x6944, 0x6976, 0x6958, 0x6941, 0x6974, 0x694c,
+ 0x693b, 0x694b, 0x6937, 0x695c, 0x694f, 0x6951, 0x6932, 0x6952,
+ 0x692f, 0x697b, 0x693c, 0x6b46, 0x6b45, 0x6b43, 0x6b42, 0x6b48,
+ 0x6b41, 0x6b9b, 0xfa0d, 0x6bfb, 0x6bfc,
+ /* 0xde */
+ 0x6bf9, 0x6bf7, 0x6bf8, 0x6e9b, 0x6ed6, 0x6ec8, 0x6e8f, 0x6ec0,
+ 0x6e9f, 0x6e93, 0x6e94, 0x6ea0, 0x6eb1, 0x6eb9, 0x6ec6, 0x6ed2,
+ 0x6ebd, 0x6ec1, 0x6e9e, 0x6ec9, 0x6eb7, 0x6eb0, 0x6ecd, 0x6ea6,
+ 0x6ecf, 0x6eb2, 0x6ebe, 0x6ec3, 0x6edc, 0x6ed8, 0x6e99, 0x6e92,
+ 0x6e8e, 0x6e8d, 0x6ea4, 0x6ea1, 0x6ebf, 0x6eb3, 0x6ed0, 0x6eca,
+ 0x6e97, 0x6eae, 0x6ea3, 0x7147, 0x7154, 0x7152, 0x7163, 0x7160,
+ 0x7141, 0x715d, 0x7162, 0x7172, 0x7178, 0x716a, 0x7161, 0x7142,
+ 0x7158, 0x7143, 0x714b, 0x7170, 0x715f, 0x7150, 0x7153, 0x7144,
+ 0x714d, 0x715a, 0x724f, 0x728d, 0x728c, 0x7291, 0x7290, 0x728e,
+ 0x733c, 0x7342, 0x733b, 0x733a, 0x7340, 0x734a, 0x7349, 0x7444,
+ 0x744a, 0x744b, 0x7452, 0x7451, 0x7457, 0x7440, 0x744f, 0x7450,
+ 0x744e, 0x7442, 0x7446, 0x744d, 0x7454, 0x74e1, 0x74ff, 0x74fe,
+ 0x74fd, 0x751d, 0x7579, 0x7577, 0x6983, 0x75ef, 0x760f, 0x7603,
+ 0x75f7, 0x75fe, 0x75fc, 0x75f9, 0x75f8, 0x7610, 0x75fb, 0x75f6,
+ 0x75ed, 0x75f5, 0x75fd, 0x7699, 0x76b5, 0x76dd, 0x7755, 0x775f,
+ 0x7760, 0x7752, 0x7756, 0x775a, 0x7769, 0x7767, 0x7754, 0x7759,
+ 0x776d, 0x77e0, 0x7887, 0x789a, 0x7894, 0x788f, 0x7884, 0x7895,
+ 0x7885, 0x7886, 0x78a1, 0x7883, 0x7879, 0x7899, 0x7880, 0x7896,
+ 0x787b, 0x797c, 0x7982, 0x797d, 0x7979, 0x7a11, 0x7a18, 0x7a19,
+ 0x7a12, 0x7a17, 0x7a15, 0x7a22, 0x7a13,
+ /* 0xdf */
+ 0x7a1b, 0x7a10, 0x7aa3, 0x7aa2, 0x7a9e, 0x7aeb, 0x7b66, 0x7b64,
+ 0x7b6d, 0x7b74, 0x7b69, 0x7b72, 0x7b65, 0x7b73, 0x7b71, 0x7b70,
+ 0x7b61, 0x7b78, 0x7b76, 0x7b63, 0x7cb2, 0x7cb4, 0x7caf, 0x7d88,
+ 0x7d86, 0x7d80, 0x7d8d, 0x7d7f, 0x7d85, 0x7d7a, 0x7d8e, 0x7d7b,
+ 0x7d83, 0x7d7c, 0x7d8c, 0x7d94, 0x7d84, 0x7d7d, 0x7d92, 0x7f6d,
+ 0x7f6b, 0x7f67, 0x7f68, 0x7f6c, 0x7fa6, 0x7fa5, 0x7fa7, 0x7fdb,
+ 0x7fdc, 0x8021, 0x8164, 0x8160, 0x8177, 0x815c, 0x8169, 0x815b,
+ 0x8162, 0x8172, 0x6721, 0x815e, 0x8176, 0x8167, 0x816f, 0x8144,
+ 0x8161, 0x821d, 0x8249, 0x8244, 0x8240, 0x8242, 0x8245, 0x84f1,
+ 0x843f, 0x8456, 0x8476, 0x8479, 0x848f, 0x848d, 0x8465, 0x8451,
+ 0x8440, 0x8486, 0x8467, 0x8430, 0x844d, 0x847d, 0x845a, 0x8459,
+ 0x8474, 0x8473, 0x845d, 0x8507, 0x845e, 0x8437, 0x843a, 0x8434,
+ 0x847a, 0x8443, 0x8478, 0x8432, 0x8445, 0x8429, 0x83d9, 0x844b,
+ 0x842f, 0x8442, 0x842d, 0x845f, 0x8470, 0x8439, 0x844e, 0x844c,
+ 0x8452, 0x846f, 0x84c5, 0x848e, 0x843b, 0x8447, 0x8436, 0x8433,
+ 0x8468, 0x847e, 0x8444, 0x842b, 0x8460, 0x8454, 0x846e, 0x8450,
+ 0x870b, 0x8704, 0x86f7, 0x870c, 0x86fa, 0x86d6, 0x86f5, 0x874d,
+ 0x86f8, 0x870e, 0x8709, 0x8701, 0x86f6, 0x870d, 0x8705, 0x88d6,
+ 0x88cb, 0x88cd, 0x88ce, 0x88de, 0x88db, 0x88da, 0x88cc, 0x88d0,
+ 0x8985, 0x899b, 0x89df, 0x89e5, 0x89e4,
+ /* 0xe0 */
+ 0x89e1, 0x89e0, 0x89e2, 0x89dc, 0x89e6, 0x8a76, 0x8a86, 0x8a7f,
+ 0x8a61, 0x8a3f, 0x8a77, 0x8a82, 0x8a84, 0x8a75, 0x8a83, 0x8a81,
+ 0x8a74, 0x8a7a, 0x8c3c, 0x8c4b, 0x8c4a, 0x8c65, 0x8c64, 0x8c66,
+ 0x8c86, 0x8c84, 0x8c85, 0x8ccc, 0x8d68, 0x8d69, 0x8d91, 0x8d8c,
+ 0x8d8e, 0x8d8f, 0x8d8d, 0x8d93, 0x8d94, 0x8d90, 0x8d92, 0x8df0,
+ 0x8de0, 0x8dec, 0x8df1, 0x8dee, 0x8dd0, 0x8de9, 0x8de3, 0x8de2,
+ 0x8de7, 0x8df2, 0x8deb, 0x8df4, 0x8f06, 0x8eff, 0x8f01, 0x8f00,
+ 0x8f05, 0x8f07, 0x8f08, 0x8f02, 0x8f0b, 0x9052, 0x903f, 0x9044,
+ 0x9049, 0x903d, 0x9110, 0x910d, 0x910f, 0x9111, 0x9116, 0x9114,
+ 0x910b, 0x910e, 0x916e, 0x916f, 0x9248, 0x9252, 0x9230, 0x923a,
+ 0x9266, 0x9233, 0x9265, 0x925e, 0x9283, 0x922e, 0x924a, 0x9246,
+ 0x926d, 0x926c, 0x924f, 0x9260, 0x9267, 0x926f, 0x9236, 0x9261,
+ 0x9270, 0x9231, 0x9254, 0x9263, 0x9250, 0x9272, 0x924e, 0x9253,
+ 0x924c, 0x9256, 0x9232, 0x959f, 0x959c, 0x959e, 0x959b, 0x9692,
+ 0x9693, 0x9691, 0x9697, 0x96ce, 0x96fa, 0x96fd, 0x96f8, 0x96f5,
+ 0x9773, 0x9777, 0x9778, 0x9772, 0x980f, 0x980d, 0x980e, 0x98ac,
+ 0x98f6, 0x98f9, 0x99af, 0x99b2, 0x99b0, 0x99b5, 0x9aad, 0x9aab,
+ 0x9b5b, 0x9cea, 0x9ced, 0x9ce7, 0x9e80, 0x9efd, 0x50e6, 0x50d4,
+ 0x50d7, 0x50e8, 0x50f3, 0x50db, 0x50ea, 0x50dd, 0x50e4, 0x50d3,
+ 0x50ec, 0x50f0, 0x50ef, 0x50e3, 0x50e0,
+ /* 0xe1 */
+ 0x51d8, 0x5280, 0x5281, 0x52e9, 0x52eb, 0x5330, 0x53ac, 0x5627,
+ 0x5615, 0x560c, 0x5612, 0x55fc, 0x560f, 0x561c, 0x5601, 0x5613,
+ 0x5602, 0x55fa, 0x561d, 0x5604, 0x55ff, 0x55f9, 0x5889, 0x587c,
+ 0x5890, 0x5898, 0x5886, 0x5881, 0x587f, 0x5874, 0x588b, 0x587a,
+ 0x5887, 0x5891, 0x588e, 0x5876, 0x5882, 0x5888, 0x587b, 0x5894,
+ 0x588f, 0x58fe, 0x596b, 0x5adc, 0x5aee, 0x5ae5, 0x5ad5, 0x5aea,
+ 0x5ada, 0x5aed, 0x5aeb, 0x5af3, 0x5ae2, 0x5ae0, 0x5adb, 0x5aec,
+ 0x5ade, 0x5add, 0x5ad9, 0x5ae8, 0x5adf, 0x5b77, 0x5be0, 0x5be3,
+ 0x5c63, 0x5d82, 0x5d80, 0x5d7d, 0x5d86, 0x5d7a, 0x5d81, 0x5d77,
+ 0x5d8a, 0x5d89, 0x5d88, 0x5d7e, 0x5d7c, 0x5d8d, 0x5d79, 0x5d7f,
+ 0x5e58, 0x5e59, 0x5e53, 0x5ed8, 0x5ed1, 0x5ed7, 0x5ece, 0x5edc,
+ 0x5ed5, 0x5ed9, 0x5ed2, 0x5ed4, 0x5f44, 0x5f43, 0x5f6f, 0x5fb6,
+ 0x612c, 0x6128, 0x6141, 0x615e, 0x6171, 0x6173, 0x6152, 0x6153,
+ 0x6172, 0x616c, 0x6180, 0x6174, 0x6154, 0x617a, 0x615b, 0x6165,
+ 0x613b, 0x616a, 0x6161, 0x6156, 0x6229, 0x6227, 0x622b, 0x642b,
+ 0x644d, 0x645b, 0x645d, 0x6474, 0x6476, 0x6472, 0x6473, 0x647d,
+ 0x6475, 0x6466, 0x64a6, 0x644e, 0x6482, 0x645e, 0x645c, 0x644b,
+ 0x6453, 0x6460, 0x6450, 0x647f, 0x643f, 0x646c, 0x646b, 0x6459,
+ 0x6465, 0x6477, 0x6573, 0x65a0, 0x66a1, 0x66a0, 0x669f, 0x6705,
+ 0x6704, 0x6722, 0x69b1, 0x69b6, 0x69c9,
+ /* 0xe2 */
+ 0x69a0, 0x69ce, 0x6996, 0x69b0, 0x69ac, 0x69bc, 0x6991, 0x6999,
+ 0x698e, 0x69a7, 0x698d, 0x69a9, 0x69be, 0x69af, 0x69bf, 0x69c4,
+ 0x69bd, 0x69a4, 0x69d4, 0x69b9, 0x69ca, 0x699a, 0x69cf, 0x69b3,
+ 0x6993, 0x69aa, 0x69a1, 0x699e, 0x69d9, 0x6997, 0x6990, 0x69c2,
+ 0x69b5, 0x69a5, 0x69c6, 0x6b4a, 0x6b4d, 0x6b4b, 0x6b9e, 0x6b9f,
+ 0x6ba0, 0x6bc3, 0x6bc4, 0x6bfe, 0x6ece, 0x6ef5, 0x6ef1, 0x6f03,
+ 0x6f25, 0x6ef8, 0x6f37, 0x6efb, 0x6f2e, 0x6f09, 0x6f4e, 0x6f19,
+ 0x6f1a, 0x6f27, 0x6f18, 0x6f3b, 0x6f12, 0x6eed, 0x6f0a, 0x6f36,
+ 0x6f73, 0x6ef9, 0x6eee, 0x6f2d, 0x6f40, 0x6f30, 0x6f3c, 0x6f35,
+ 0x6eeb, 0x6f07, 0x6f0e, 0x6f43, 0x6f05, 0x6efd, 0x6ef6, 0x6f39,
+ 0x6f1c, 0x6efc, 0x6f3a, 0x6f1f, 0x6f0d, 0x6f1e, 0x6f08, 0x6f21,
+ 0x7187, 0x7190, 0x7189, 0x7180, 0x7185, 0x7182, 0x718f, 0x717b,
+ 0x7186, 0x7181, 0x7197, 0x7244, 0x7253, 0x7297, 0x7295, 0x7293,
+ 0x7343, 0x734d, 0x7351, 0x734c, 0x7462, 0x7473, 0x7471, 0x7475,
+ 0x7472, 0x7467, 0x746e, 0x7500, 0x7502, 0x7503, 0x757d, 0x7590,
+ 0x7616, 0x7608, 0x760c, 0x7615, 0x7611, 0x760a, 0x7614, 0x76b8,
+ 0x7781, 0x777c, 0x7785, 0x7782, 0x776e, 0x7780, 0x776f, 0x777e,
+ 0x7783, 0x78b2, 0x78aa, 0x78b4, 0x78ad, 0x78a8, 0x787e, 0x78ab,
+ 0x789e, 0x78a5, 0x78a0, 0x78ac, 0x78a2, 0x78a4, 0x7998, 0x798a,
+ 0x798b, 0x7996, 0x7995, 0x7994, 0x7993,
+ /* 0xe3 */
+ 0x7997, 0x7988, 0x7992, 0x7990, 0x7a2b, 0x7a4a, 0x7a30, 0x7a2f,
+ 0x7a28, 0x7a26, 0x7aa8, 0x7aab, 0x7aac, 0x7aee, 0x7b88, 0x7b9c,
+ 0x7b8a, 0x7b91, 0x7b90, 0x7b96, 0x7b8d, 0x7b8c, 0x7b9b, 0x7b8e,
+ 0x7b85, 0x7b98, 0x5284, 0x7b99, 0x7ba4, 0x7b82, 0x7cbb, 0x7cbf,
+ 0x7cbc, 0x7cba, 0x7da7, 0x7db7, 0x7dc2, 0x7da3, 0x7daa, 0x7dc1,
+ 0x7dc0, 0x7dc5, 0x7d9d, 0x7dce, 0x7dc4, 0x7dc6, 0x7dcb, 0x7dcc,
+ 0x7daf, 0x7db9, 0x7d96, 0x7dbc, 0x7d9f, 0x7da6, 0x7dae, 0x7da9,
+ 0x7da1, 0x7dc9, 0x7f73, 0x7fe2, 0x7fe3, 0x7fe5, 0x7fde, 0x8024,
+ 0x805d, 0x805c, 0x8189, 0x8186, 0x8183, 0x8187, 0x818d, 0x818c,
+ 0x818b, 0x8215, 0x8497, 0x84a4, 0x84a1, 0x849f, 0x84ba, 0x84ce,
+ 0x84c2, 0x84ac, 0x84ae, 0x84ab, 0x84b9, 0x84b4, 0x84c1, 0x84cd,
+ 0x84aa, 0x849a, 0x84b1, 0x84d0, 0x849d, 0x84a7, 0x84bb, 0x84a2,
+ 0x8494, 0x84c7, 0x84cc, 0x849b, 0x84a9, 0x84af, 0x84a8, 0x84d6,
+ 0x8498, 0x84b6, 0x84cf, 0x84a0, 0x84d7, 0x84d4, 0x84d2, 0x84db,
+ 0x84b0, 0x8491, 0x8661, 0x8733, 0x8723, 0x8728, 0x876b, 0x8740,
+ 0x872e, 0x871e, 0x8721, 0x8719, 0x871b, 0x8743, 0x872c, 0x8741,
+ 0x873e, 0x8746, 0x8720, 0x8732, 0x872a, 0x872d, 0x873c, 0x8712,
+ 0x873a, 0x8731, 0x8735, 0x8742, 0x8726, 0x8727, 0x8738, 0x8724,
+ 0x871a, 0x8730, 0x8711, 0x88f7, 0x88e7, 0x88f1, 0x88f2, 0x88fa,
+ 0x88fe, 0x88ee, 0x88fc, 0x88f6, 0x88fb,
+ /* 0xe4 */
+ 0x88f0, 0x88ec, 0x88eb, 0x899d, 0x89a1, 0x899f, 0x899e, 0x89e9,
+ 0x89eb, 0x89e8, 0x8aab, 0x8a99, 0x8a8b, 0x8a92, 0x8a8f, 0x8a96,
+ 0x8c3d, 0x8c68, 0x8c69, 0x8cd5, 0x8ccf, 0x8cd7, 0x8d96, 0x8e09,
+ 0x8e02, 0x8dff, 0x8e0d, 0x8dfd, 0x8e0a, 0x8e03, 0x8e07, 0x8e06,
+ 0x8e05, 0x8dfe, 0x8e00, 0x8e04, 0x8f10, 0x8f11, 0x8f0e, 0x8f0d,
+ 0x9123, 0x911c, 0x9120, 0x9122, 0x911f, 0x911d, 0x911a, 0x9124,
+ 0x9121, 0x911b, 0x917a, 0x9172, 0x9179, 0x9173, 0x92a5, 0x92a4,
+ 0x9276, 0x929b, 0x927a, 0x92a0, 0x9294, 0x92aa, 0x928d, 0x92a6,
+ 0x929a, 0x92ab, 0x9279, 0x9297, 0x927f, 0x92a3, 0x92ee, 0x928e,
+ 0x9282, 0x9295, 0x92a2, 0x927d, 0x9288, 0x92a1, 0x928a, 0x9286,
+ 0x928c, 0x9299, 0x92a7, 0x927e, 0x9287, 0x92a9, 0x929d, 0x928b,
+ 0x922d, 0x969e, 0x96a1, 0x96ff, 0x9758, 0x977d, 0x977a, 0x977e,
+ 0x9783, 0x9780, 0x9782, 0x977b, 0x9784, 0x9781, 0x977f, 0x97ce,
+ 0x97cd, 0x9816, 0x98ad, 0x98ae, 0x9902, 0x9900, 0x9907, 0x999d,
+ 0x999c, 0x99c3, 0x99b9, 0x99bb, 0x99ba, 0x99c2, 0x99bd, 0x99c7,
+ 0x9ab1, 0x9ae3, 0x9ae7, 0x9b3e, 0x9b3f, 0x9b60, 0x9b61, 0x9b5f,
+ 0x9cf1, 0x9cf2, 0x9cf5, 0x9ea7, 0x50ff, 0x5103, 0x5130, 0x50f8,
+ 0x5106, 0x5107, 0x50f6, 0x50fe, 0x510b, 0x510c, 0x50fd, 0x510a,
+ 0x528b, 0x528c, 0x52f1, 0x52ef, 0x5648, 0x5642, 0x564c, 0x5635,
+ 0x5641, 0x564a, 0x5649, 0x5646, 0x5658,
+ /* 0xe5 */
+ 0x565a, 0x5640, 0x5633, 0x563d, 0x562c, 0x563e, 0x5638, 0x562a,
+ 0x563a, 0x571a, 0x58ab, 0x589d, 0x58b1, 0x58a0, 0x58a3, 0x58af,
+ 0x58ac, 0x58a5, 0x58a1, 0x58ff, 0x5aff, 0x5af4, 0x5afd, 0x5af7,
+ 0x5af6, 0x5b03, 0x5af8, 0x5b02, 0x5af9, 0x5b01, 0x5b07, 0x5b05,
+ 0x5b0f, 0x5c67, 0x5d99, 0x5d97, 0x5d9f, 0x5d92, 0x5da2, 0x5d93,
+ 0x5d95, 0x5da0, 0x5d9c, 0x5da1, 0x5d9a, 0x5d9e, 0x5e69, 0x5e5d,
+ 0x5e60, 0x5e5c, 0x7df3, 0x5edb, 0x5ede, 0x5ee1, 0x5f49, 0x5fb2,
+ 0x618b, 0x6183, 0x6179, 0x61b1, 0x61b0, 0x61a2, 0x6189, 0x619b,
+ 0x6193, 0x61af, 0x61ad, 0x619f, 0x6192, 0x61aa, 0x61a1, 0x618d,
+ 0x6166, 0x61b3, 0x622d, 0x646e, 0x6470, 0x6496, 0x64a0, 0x6485,
+ 0x6497, 0x649c, 0x648f, 0x648b, 0x648a, 0x648c, 0x64a3, 0x649f,
+ 0x6468, 0x64b1, 0x6498, 0x6576, 0x657a, 0x6579, 0x657b, 0x65b2,
+ 0x65b3, 0x66b5, 0x66b0, 0x66a9, 0x66b2, 0x66b7, 0x66aa, 0x66af,
+ 0x6a00, 0x6a06, 0x6a17, 0x69e5, 0x69f8, 0x6a15, 0x69f1, 0x69e4,
+ 0x6a20, 0x69ff, 0x69ec, 0x69e2, 0x6a1b, 0x6a1d, 0x69fe, 0x6a27,
+ 0x69f2, 0x69ee, 0x6a14, 0x69f7, 0x69e7, 0x6a40, 0x6a08, 0x69e6,
+ 0x69fb, 0x6a0d, 0x69fc, 0x69eb, 0x6a09, 0x6a04, 0x6a18, 0x6a25,
+ 0x6a0f, 0x69f6, 0x6a26, 0x6a07, 0x69f4, 0x6a16, 0x6b51, 0x6ba5,
+ 0x6ba3, 0x6ba2, 0x6ba6, 0x6c01, 0x6c00, 0x6bff, 0x6c02, 0x6f41,
+ 0x6f26, 0x6f7e, 0x6f87, 0x6fc6, 0x6f92,
+ /* 0xe6 */
+ 0x6f8d, 0x6f89, 0x6f8c, 0x6f62, 0x6f4f, 0x6f85, 0x6f5a, 0x6f96,
+ 0x6f76, 0x6f6c, 0x6f82, 0x6f55, 0x6f72, 0x6f52, 0x6f50, 0x6f57,
+ 0x6f94, 0x6f93, 0x6f5d, 0x6f00, 0x6f61, 0x6f6b, 0x6f7d, 0x6f67,
+ 0x6f90, 0x6f53, 0x6f8b, 0x6f69, 0x6f7f, 0x6f95, 0x6f63, 0x6f77,
+ 0x6f6a, 0x6f7b, 0x71b2, 0x71af, 0x719b, 0x71b0, 0x71a0, 0x719a,
+ 0x71a9, 0x71b5, 0x719d, 0x71a5, 0x719e, 0x71a4, 0x71a1, 0x71aa,
+ 0x719c, 0x71a7, 0x71b3, 0x7298, 0x729a, 0x7358, 0x7352, 0x735e,
+ 0x735f, 0x7360, 0x735d, 0x735b, 0x7361, 0x735a, 0x7359, 0x7362,
+ 0x7487, 0x7489, 0x748a, 0x7486, 0x7481, 0x747d, 0x7485, 0x7488,
+ 0x747c, 0x7479, 0x7508, 0x7507, 0x757e, 0x7625, 0x761e, 0x7619,
+ 0x761d, 0x761c, 0x7623, 0x761a, 0x7628, 0x761b, 0x769c, 0x769d,
+ 0x769e, 0x769b, 0x778d, 0x778f, 0x7789, 0x7788, 0x78cd, 0x78bb,
+ 0x78cf, 0x78cc, 0x78d1, 0x78ce, 0x78d4, 0x78c8, 0x78c3, 0x78c4,
+ 0x78c9, 0x799a, 0x79a1, 0x79a0, 0x799c, 0x79a2, 0x799b, 0x6b76,
+ 0x7a39, 0x7ab2, 0x7ab4, 0x7ab3, 0x7bb7, 0x7bcb, 0x7bbe, 0x7bac,
+ 0x7bce, 0x7baf, 0x7bb9, 0x7bca, 0x7bb5, 0x7cc5, 0x7cc8, 0x7ccc,
+ 0x7ccb, 0x7df7, 0x7ddb, 0x7dea, 0x7de7, 0x7dd7, 0x7de1, 0x7e03,
+ 0x7dfa, 0x7de6, 0x7df6, 0x7df1, 0x7df0, 0x7dee, 0x7ddf, 0x7f76,
+ 0x7fac, 0x7fb0, 0x7fad, 0x7fed, 0x7feb, 0x7fea, 0x7fec, 0x7fe6,
+ 0x7fe8, 0x8064, 0x8067, 0x81a3, 0x819f,
+ /* 0xe7 */
+ 0x819e, 0x8195, 0x81a2, 0x8199, 0x8197, 0x8216, 0x824f, 0x8253,
+ 0x8252, 0x8250, 0x824e, 0x8251, 0x8524, 0x853b, 0x850f, 0x8500,
+ 0x8529, 0x850e, 0x8509, 0x850d, 0x851f, 0x850a, 0x8527, 0x851c,
+ 0x84fb, 0x852b, 0x84fa, 0x8508, 0x850c, 0x84f4, 0x852a, 0x84f2,
+ 0x8515, 0x84f7, 0x84eb, 0x84f3, 0x84fc, 0x8512, 0x84ea, 0x84e9,
+ 0x8516, 0x84fe, 0x8528, 0x851d, 0x852e, 0x8502, 0x84fd, 0x851e,
+ 0x84f6, 0x8531, 0x8526, 0x84e7, 0x84e8, 0x84f0, 0x84ef, 0x84f9,
+ 0x8518, 0x8520, 0x8530, 0x850b, 0x8519, 0x852f, 0x8662, 0x8756,
+ 0x8763, 0x8764, 0x8777, 0x87e1, 0x8773, 0x8758, 0x8754, 0x875b,
+ 0x8752, 0x8761, 0x875a, 0x8751, 0x875e, 0x876d, 0x876a, 0x8750,
+ 0x874e, 0x875f, 0x875d, 0x876f, 0x876c, 0x877a, 0x876e, 0x875c,
+ 0x8765, 0x874f, 0x877b, 0x8775, 0x8762, 0x8767, 0x8769, 0x885a,
+ 0x8905, 0x890c, 0x8914, 0x890b, 0x8917, 0x8918, 0x8919, 0x8906,
+ 0x8916, 0x8911, 0x890e, 0x8909, 0x89a2, 0x89a4, 0x89a3, 0x89ed,
+ 0x89f0, 0x89ec, 0x8acf, 0x8ac6, 0x8ab8, 0x8ad3, 0x8ad1, 0x8ad4,
+ 0x8ad5, 0x8abb, 0x8ad7, 0x8abe, 0x8ac0, 0x8ac5, 0x8ad8, 0x8ac3,
+ 0x8aba, 0x8abd, 0x8ad9, 0x8c3e, 0x8c4d, 0x8c8f, 0x8ce5, 0x8cdf,
+ 0x8cd9, 0x8ce8, 0x8cda, 0x8cdd, 0x8ce7, 0x8da0, 0x8d9c, 0x8da1,
+ 0x8d9b, 0x8e20, 0x8e23, 0x8e25, 0x8e24, 0x8e2e, 0x8e15, 0x8e1b,
+ 0x8e16, 0x8e11, 0x8e19, 0x8e26, 0x8e27,
+ /* 0xe8 */
+ 0x8e14, 0x8e12, 0x8e18, 0x8e13, 0x8e1c, 0x8e17, 0x8e1a, 0x8f2c,
+ 0x8f24, 0x8f18, 0x8f1a, 0x8f20, 0x8f23, 0x8f16, 0x8f17, 0x9073,
+ 0x9070, 0x906f, 0x9067, 0x906b, 0x912f, 0x912b, 0x9129, 0x912a,
+ 0x9132, 0x9126, 0x912e, 0x9185, 0x9186, 0x918a, 0x9181, 0x9182,
+ 0x9184, 0x9180, 0x92d0, 0x92c3, 0x92c4, 0x92c0, 0x92d9, 0x92b6,
+ 0x92cf, 0x92f1, 0x92df, 0x92d8, 0x92e9, 0x92d7, 0x92dd, 0x92cc,
+ 0x92ef, 0x92c2, 0x92e8, 0x92ca, 0x92c8, 0x92ce, 0x92e6, 0x92cd,
+ 0x92d5, 0x92c9, 0x92e0, 0x92de, 0x92e7, 0x92d1, 0x92d3, 0x92b5,
+ 0x92e1, 0x92c6, 0x92b4, 0x957c, 0x95ac, 0x95ab, 0x95ae, 0x95b0,
+ 0x96a4, 0x96a2, 0x96d3, 0x9705, 0x9708, 0x9702, 0x975a, 0x978a,
+ 0x978e, 0x9788, 0x97d0, 0x97cf, 0x981e, 0x981d, 0x9826, 0x9829,
+ 0x9828, 0x9820, 0x981b, 0x9827, 0x98b2, 0x9908, 0x98fa, 0x9911,
+ 0x9914, 0x9916, 0x9917, 0x9915, 0x99dc, 0x99cd, 0x99cf, 0x99d3,
+ 0x99d4, 0x99ce, 0x99c9, 0x99d6, 0x99d8, 0x99cb, 0x99d7, 0x99cc,
+ 0x9ab3, 0x9aec, 0x9aeb, 0x9af3, 0x9af2, 0x9af1, 0x9b46, 0x9b43,
+ 0x9b67, 0x9b74, 0x9b71, 0x9b66, 0x9b76, 0x9b75, 0x9b70, 0x9b68,
+ 0x9b64, 0x9b6c, 0x9cfc, 0x9cfa, 0x9cfd, 0x9cff, 0x9cf7, 0x9d07,
+ 0x9d00, 0x9cf9, 0x9cfb, 0x9d08, 0x9d05, 0x9d04, 0x9e83, 0x9ed3,
+ 0x9f0f, 0x9f10, 0x511c, 0x5113, 0x5117, 0x511a, 0x5111, 0x51de,
+ 0x5334, 0x53e1, 0x5670, 0x5660, 0x566e,
+ /* 0xe9 */
+ 0x5673, 0x5666, 0x5663, 0x566d, 0x5672, 0x565e, 0x5677, 0x571c,
+ 0x571b, 0x58c8, 0x58bd, 0x58c9, 0x58bf, 0x58ba, 0x58c2, 0x58bc,
+ 0x58c6, 0x5b17, 0x5b19, 0x5b1b, 0x5b21, 0x5b14, 0x5b13, 0x5b10,
+ 0x5b16, 0x5b28, 0x5b1a, 0x5b20, 0x5b1e, 0x5bef, 0x5dac, 0x5db1,
+ 0x5da9, 0x5da7, 0x5db5, 0x5db0, 0x5dae, 0x5daa, 0x5da8, 0x5db2,
+ 0x5dad, 0x5daf, 0x5db4, 0x5e67, 0x5e68, 0x5e66, 0x5e6f, 0x5ee9,
+ 0x5ee7, 0x5ee6, 0x5ee8, 0x5ee5, 0x5f4b, 0x5fbc, 0x619d, 0x61a8,
+ 0x6196, 0x61c5, 0x61b4, 0x61c6, 0x61c1, 0x61cc, 0x61ba, 0x61bf,
+ 0x61b8, 0x618c, 0x64d7, 0x64d6, 0x64d0, 0x64cf, 0x64c9, 0x64bd,
+ 0x6489, 0x64c3, 0x64db, 0x64f3, 0x64d9, 0x6533, 0x657f, 0x657c,
+ 0x65a2, 0x66c8, 0x66be, 0x66c0, 0x66ca, 0x66cb, 0x66cf, 0x66bd,
+ 0x66bb, 0x66ba, 0x66cc, 0x6723, 0x6a34, 0x6a66, 0x6a49, 0x6a67,
+ 0x6a32, 0x6a68, 0x6a3e, 0x6a5d, 0x6a6d, 0x6a76, 0x6a5b, 0x6a51,
+ 0x6a28, 0x6a5a, 0x6a3b, 0x6a3f, 0x6a41, 0x6a6a, 0x6a64, 0x6a50,
+ 0x6a4f, 0x6a54, 0x6a6f, 0x6a69, 0x6a60, 0x6a3c, 0x6a5e, 0x6a56,
+ 0x6a55, 0x6a4d, 0x6a4e, 0x6a46, 0x6b55, 0x6b54, 0x6b56, 0x6ba7,
+ 0x6baa, 0x6bab, 0x6bc8, 0x6bc7, 0x6c04, 0x6c03, 0x6c06, 0x6fad,
+ 0x6fcb, 0x6fa3, 0x6fc7, 0x6fbc, 0x6fce, 0x6fc8, 0x6f5e, 0x6fc4,
+ 0x6fbd, 0x6f9e, 0x6fca, 0x6fa8, 0x7004, 0x6fa5, 0x6fae, 0x6fba,
+ 0x6fac, 0x6faa, 0x6fcf, 0x6fbf, 0x6fb8,
+ /* 0xea */
+ 0x6fa2, 0x6fc9, 0x6fab, 0x6fcd, 0x6faf, 0x6fb2, 0x6fb0, 0x71c5,
+ 0x71c2, 0x71bf, 0x71b8, 0x71d6, 0x71c0, 0x71c1, 0x71cb, 0x71d4,
+ 0x71ca, 0x71c7, 0x71cf, 0x71bd, 0x71d8, 0x71bc, 0x71c6, 0x71da,
+ 0x71db, 0x729d, 0x729e, 0x7369, 0x7366, 0x7367, 0x736c, 0x7365,
+ 0x736b, 0x736a, 0x747f, 0x749a, 0x74a0, 0x7494, 0x7492, 0x7495,
+ 0x74a1, 0x750b, 0x7580, 0x762f, 0x762d, 0x7631, 0x763d, 0x7633,
+ 0x763c, 0x7635, 0x7632, 0x7630, 0x76bb, 0x76e6, 0x779a, 0x779d,
+ 0x77a1, 0x779c, 0x779b, 0x77a2, 0x77a3, 0x7795, 0x7799, 0x7797,
+ 0x78dd, 0x78e9, 0x78e5, 0x78ea, 0x78de, 0x78e3, 0x78db, 0x78e1,
+ 0x78e2, 0x78ed, 0x78df, 0x78e0, 0x79a4, 0x7a44, 0x7a48, 0x7a47,
+ 0x7ab6, 0x7ab8, 0x7ab5, 0x7ab1, 0x7ab7, 0x7bde, 0x7be3, 0x7be7,
+ 0x7bdd, 0x7bd5, 0x7be5, 0x7bda, 0x7be8, 0x7bf9, 0x7bd4, 0x7bea,
+ 0x7be2, 0x7bdc, 0x7beb, 0x7bd8, 0x7bdf, 0x7cd2, 0x7cd4, 0x7cd7,
+ 0x7cd0, 0x7cd1, 0x7e12, 0x7e21, 0x7e17, 0x7e0c, 0x7e1f, 0x7e20,
+ 0x7e13, 0x7e0e, 0x7e1c, 0x7e15, 0x7e1a, 0x7e22, 0x7e0b, 0x7e0f,
+ 0x7e16, 0x7e0d, 0x7e14, 0x7e25, 0x7e24, 0x7f43, 0x7f7b, 0x7f7c,
+ 0x7f7a, 0x7fb1, 0x7fef, 0x802a, 0x8029, 0x806c, 0x81b1, 0x81a6,
+ 0x81ae, 0x81b9, 0x81b5, 0x81ab, 0x81b0, 0x81ac, 0x81b4, 0x81b2,
+ 0x81b7, 0x81a7, 0x81f2, 0x8255, 0x8256, 0x8257, 0x8556, 0x8545,
+ 0x856b, 0x854d, 0x8553, 0x8561, 0x8558,
+ /* 0xeb */
+ 0x8540, 0x8546, 0x8564, 0x8541, 0x8562, 0x8544, 0x8551, 0x8547,
+ 0x8563, 0x853e, 0x855b, 0x8571, 0x854e, 0x856e, 0x8575, 0x8555,
+ 0x8567, 0x8560, 0x858c, 0x8566, 0x855d, 0x8554, 0x8565, 0x856c,
+ 0x8663, 0x8665, 0x8664, 0x879b, 0x878f, 0x8797, 0x8793, 0x8792,
+ 0x8788, 0x8781, 0x8796, 0x8798, 0x8779, 0x8787, 0x87a3, 0x8785,
+ 0x8790, 0x8791, 0x879d, 0x8784, 0x8794, 0x879c, 0x879a, 0x8789,
+ 0x891e, 0x8926, 0x8930, 0x892d, 0x892e, 0x8927, 0x8931, 0x8922,
+ 0x8929, 0x8923, 0x892f, 0x892c, 0x891f, 0x89f1, 0x8ae0, 0x8ae2,
+ 0x8af2, 0x8af4, 0x8af5, 0x8add, 0x8b14, 0x8ae4, 0x8adf, 0x8af0,
+ 0x8ac8, 0x8ade, 0x8ae1, 0x8ae8, 0x8aff, 0x8aef, 0x8afb, 0x8c91,
+ 0x8c92, 0x8c90, 0x8cf5, 0x8cee, 0x8cf1, 0x8cf0, 0x8cf3, 0x8d6c,
+ 0x8d6e, 0x8da5, 0x8da7, 0x8e33, 0x8e3e, 0x8e38, 0x8e40, 0x8e45,
+ 0x8e36, 0x8e3c, 0x8e3d, 0x8e41, 0x8e30, 0x8e3f, 0x8ebd, 0x8f36,
+ 0x8f2e, 0x8f35, 0x8f32, 0x8f39, 0x8f37, 0x8f34, 0x9076, 0x9079,
+ 0x907b, 0x9086, 0x90fa, 0x9133, 0x9135, 0x9136, 0x9193, 0x9190,
+ 0x9191, 0x918d, 0x918f, 0x9327, 0x931e, 0x9308, 0x931f, 0x9306,
+ 0x930f, 0x937a, 0x9338, 0x933c, 0x931b, 0x9323, 0x9312, 0x9301,
+ 0x9346, 0x932d, 0x930e, 0x930d, 0x92cb, 0x931d, 0x92fa, 0x9325,
+ 0x9313, 0x92f9, 0x92f7, 0x9334, 0x9302, 0x9324, 0x92ff, 0x9329,
+ 0x9339, 0x9335, 0x932a, 0x9314, 0x930c,
+ /* 0xec */
+ 0x930b, 0x92fe, 0x9309, 0x9300, 0x92fb, 0x9316, 0x95bc, 0x95cd,
+ 0x95be, 0x95b9, 0x95ba, 0x95b6, 0x95bf, 0x95b5, 0x95bd, 0x96a9,
+ 0x96d4, 0x970b, 0x9712, 0x9710, 0x9799, 0x9797, 0x9794, 0x97f0,
+ 0x97f8, 0x9835, 0x982f, 0x9832, 0x9924, 0x991f, 0x9927, 0x9929,
+ 0x999e, 0x99ee, 0x99ec, 0x99e5, 0x99e4, 0x99f0, 0x99e3, 0x99ea,
+ 0x99e9, 0x99e7, 0x9ab9, 0x9abf, 0x9ab4, 0x9abb, 0x9af6, 0x9afa,
+ 0x9af9, 0x9af7, 0x9b33, 0x9b80, 0x9b85, 0x9b87, 0x9b7c, 0x9b7e,
+ 0x9b7b, 0x9b82, 0x9b93, 0x9b92, 0x9b90, 0x9b7a, 0x9b95, 0x9b7d,
+ 0x9b88, 0x9d25, 0x9d17, 0x9d20, 0x9d1e, 0x9d14, 0x9d29, 0x9d1d,
+ 0x9d18, 0x9d22, 0x9d10, 0x9d19, 0x9d1f, 0x9e88, 0x9e86, 0x9e87,
+ 0x9eae, 0x9ead, 0x9ed5, 0x9ed6, 0x9efa, 0x9f12, 0x9f3d, 0x5126,
+ 0x5125, 0x5122, 0x5124, 0x5120, 0x5129, 0x52f4, 0x5693, 0x568c,
+ 0x568d, 0x5686, 0x5684, 0x5683, 0x567e, 0x5682, 0x567f, 0x5681,
+ 0x58d6, 0x58d4, 0x58cf, 0x58d2, 0x5b2d, 0x5b25, 0x5b32, 0x5b23,
+ 0x5b2c, 0x5b27, 0x5b26, 0x5b2f, 0x5b2e, 0x5b7b, 0x5bf1, 0x5bf2,
+ 0x5db7, 0x5e6c, 0x5e6a, 0x5fbe, 0x5fbb, 0x61c3, 0x61b5, 0x61bc,
+ 0x61e7, 0x61e0, 0x61e5, 0x61e4, 0x61e8, 0x61de, 0x64ef, 0x64e9,
+ 0x64e3, 0x64eb, 0x64e4, 0x64e8, 0x6581, 0x6580, 0x65b6, 0x65da,
+ 0x66d2, 0x6a8d, 0x6a96, 0x6a81, 0x6aa5, 0x6a89, 0x6a9f, 0x6a9b,
+ 0x6aa1, 0x6a9e, 0x6a87, 0x6a93, 0x6a8e,
+ /* 0xed */
+ 0x6a95, 0x6a83, 0x6aa8, 0x6aa4, 0x6a91, 0x6a7f, 0x6aa6, 0x6a9a,
+ 0x6a85, 0x6a8c, 0x6a92, 0x6b5b, 0x6bad, 0x6c09, 0x6fcc, 0x6fa9,
+ 0x6ff4, 0x6fd4, 0x6fe3, 0x6fdc, 0x6fed, 0x6fe7, 0x6fe6, 0x6fde,
+ 0x6ff2, 0x6fdd, 0x6fe2, 0x6fe8, 0x71e1, 0x71f1, 0x71e8, 0x71f2,
+ 0x71e4, 0x71f0, 0x71e2, 0x7373, 0x736e, 0x736f, 0x7497, 0x74b2,
+ 0x74ab, 0x7490, 0x74aa, 0x74ad, 0x74b1, 0x74a5, 0x74af, 0x7510,
+ 0x7511, 0x7512, 0x750f, 0x7584, 0x7643, 0x7648, 0x7649, 0x7647,
+ 0x76a4, 0x76e9, 0x77b5, 0x77ab, 0x77b2, 0x77b7, 0x77b6, 0x77b4,
+ 0x77b1, 0x77a8, 0x77f0, 0x78f3, 0x78fd, 0x7902, 0x78fb, 0x78fc,
+ 0x78f2, 0x7905, 0x78f9, 0x78fe, 0x7904, 0x79ab, 0x79a8, 0x7a5c,
+ 0x7a5b, 0x7a56, 0x7a58, 0x7a54, 0x7a5a, 0x7abe, 0x7ac0, 0x7ac1,
+ 0x7c05, 0x7c0f, 0x7bf2, 0x7c00, 0x7bff, 0x7bfb, 0x7c0e, 0x7bf4,
+ 0x7c0b, 0x7bf3, 0x7c02, 0x7c09, 0x7c03, 0x7c01, 0x7bf8, 0x7bfd,
+ 0x7c06, 0x7bf0, 0x7bf1, 0x7c10, 0x7c0a, 0x7ce8, 0x7e2d, 0x7e3c,
+ 0x7e42, 0x7e33, 0x9848, 0x7e38, 0x7e2a, 0x7e49, 0x7e40, 0x7e47,
+ 0x7e29, 0x7e4c, 0x7e30, 0x7e3b, 0x7e36, 0x7e44, 0x7e3a, 0x7f45,
+ 0x7f7f, 0x7f7e, 0x7f7d, 0x7ff4, 0x7ff2, 0x802c, 0x81bb, 0x81c4,
+ 0x81cc, 0x81ca, 0x81c5, 0x81c7, 0x81bc, 0x81e9, 0x825b, 0x825a,
+ 0x825c, 0x8583, 0x8580, 0x858f, 0x85a7, 0x8595, 0x85a0, 0x858b,
+ 0x85a3, 0x857b, 0x85a4, 0x859a, 0x859e,
+ /* 0xee */
+ 0x8577, 0x857c, 0x8589, 0x85a1, 0x857a, 0x8578, 0x8557, 0x858e,
+ 0x8596, 0x8586, 0x858d, 0x8599, 0x859d, 0x8581, 0x85a2, 0x8582,
+ 0x8588, 0x8585, 0x8579, 0x8576, 0x8598, 0x8590, 0x859f, 0x8668,
+ 0x87be, 0x87aa, 0x87ad, 0x87c5, 0x87b0, 0x87ac, 0x87b9, 0x87b5,
+ 0x87bc, 0x87ae, 0x87c9, 0x87c3, 0x87c2, 0x87cc, 0x87b7, 0x87af,
+ 0x87c4, 0x87ca, 0x87b4, 0x87b6, 0x87bf, 0x87b8, 0x87bd, 0x87de,
+ 0x87b2, 0x8935, 0x8933, 0x893c, 0x893e, 0x8941, 0x8952, 0x8937,
+ 0x8942, 0x89ad, 0x89af, 0x89ae, 0x89f2, 0x89f3, 0x8b1e, 0x8b18,
+ 0x8b16, 0x8b11, 0x8b05, 0x8b0b, 0x8b22, 0x8b0f, 0x8b12, 0x8b15,
+ 0x8b07, 0x8b0d, 0x8b08, 0x8b06, 0x8b1c, 0x8b13, 0x8b1a, 0x8c4f,
+ 0x8c70, 0x8c72, 0x8c71, 0x8c6f, 0x8c95, 0x8c94, 0x8cf9, 0x8d6f,
+ 0x8e4e, 0x8e4d, 0x8e53, 0x8e50, 0x8e4c, 0x8e47, 0x8f43, 0x8f40,
+ 0x9085, 0x907e, 0x9138, 0x919a, 0x91a2, 0x919b, 0x9199, 0x919f,
+ 0x91a1, 0x919d, 0x91a0, 0x93a1, 0x9383, 0x93af, 0x9364, 0x9356,
+ 0x9347, 0x937c, 0x9358, 0x935c, 0x9376, 0x9349, 0x9350, 0x9351,
+ 0x9360, 0x936d, 0x938f, 0x934c, 0x936a, 0x9379, 0x9357, 0x9355,
+ 0x9352, 0x934f, 0x9371, 0x9377, 0x937b, 0x9361, 0x935e, 0x9363,
+ 0x9367, 0x9380, 0x934e, 0x9359, 0x95c7, 0x95c0, 0x95c9, 0x95c3,
+ 0x95c5, 0x95b7, 0x96ae, 0x96b0, 0x96ac, 0x9720, 0x971f, 0x9718,
+ 0x971d, 0x9719, 0x979a, 0x97a1, 0x979c,
+ /* 0xef */
+ 0x979e, 0x979d, 0x97d5, 0x97d4, 0x97f1, 0x9841, 0x9844, 0x984a,
+ 0x9849, 0x9845, 0x9843, 0x9925, 0x992b, 0x992c, 0x992a, 0x9933,
+ 0x9932, 0x992f, 0x992d, 0x9931, 0x9930, 0x9998, 0x99a3, 0x99a1,
+ 0x9a02, 0x99fa, 0x99f4, 0x99f7, 0x99f9, 0x99f8, 0x99f6, 0x99fb,
+ 0x99fd, 0x99fe, 0x99fc, 0x9a03, 0x9abe, 0x9afe, 0x9afd, 0x9b01,
+ 0x9afc, 0x9b48, 0x9b9a, 0x9ba8, 0x9b9e, 0x9b9b, 0x9ba6, 0x9ba1,
+ 0x9ba5, 0x9ba4, 0x9b86, 0x9ba2, 0x9ba0, 0x9baf, 0x9d33, 0x9d41,
+ 0x9d67, 0x9d36, 0x9d2e, 0x9d2f, 0x9d31, 0x9d38, 0x9d30, 0x9d45,
+ 0x9d42, 0x9d43, 0x9d3e, 0x9d37, 0x9d40, 0x9d3d, 0x7ff5, 0x9d2d,
+ 0x9e8a, 0x9e89, 0x9e8d, 0x9eb0, 0x9ec8, 0x9eda, 0x9efb, 0x9eff,
+ 0x9f24, 0x9f23, 0x9f22, 0x9f54, 0x9fa0, 0x5131, 0x512d, 0x512e,
+ 0x5698, 0x569c, 0x5697, 0x569a, 0x569d, 0x5699, 0x5970, 0x5b3c,
+ 0x5c69, 0x5c6a, 0x5dc0, 0x5e6d, 0x5e6e, 0x61d8, 0x61df, 0x61ed,
+ 0x61ee, 0x61f1, 0x61ea, 0x61f0, 0x61eb, 0x61d6, 0x61e9, 0x64ff,
+ 0x6504, 0x64fd, 0x64f8, 0x6501, 0x6503, 0x64fc, 0x6594, 0x65db,
+ 0x66da, 0x66db, 0x66d8, 0x6ac5, 0x6ab9, 0x6abd, 0x6ae1, 0x6ac6,
+ 0x6aba, 0x6ab6, 0x6ab7, 0x6ac7, 0x6ab4, 0x6aad, 0x6b5e, 0x6bc9,
+ 0x6c0b, 0x7007, 0x700c, 0x700d, 0x7001, 0x7005, 0x7014, 0x700e,
+ 0x6fff, 0x7000, 0x6ffb, 0x7026, 0x6ffc, 0x6ff7, 0x700a, 0x7201,
+ 0x71ff, 0x71f9, 0x7203, 0x71fd, 0x7376,
+ /* 0xf0 */
+ 0x74b8, 0x74c0, 0x74b5, 0x74c1, 0x74be, 0x74b6, 0x74bb, 0x74c2,
+ 0x7514, 0x7513, 0x765c, 0x7664, 0x7659, 0x7650, 0x7653, 0x7657,
+ 0x765a, 0x76a6, 0x76bd, 0x76ec, 0x77c2, 0x77ba, 0x78ff, 0x790c,
+ 0x7913, 0x7914, 0x7909, 0x7910, 0x7912, 0x7911, 0x79ad, 0x79ac,
+ 0x7a5f, 0x7c1c, 0x7c29, 0x7c19, 0x7c20, 0x7c1f, 0x7c2d, 0x7c1d,
+ 0x7c26, 0x7c28, 0x7c22, 0x7c25, 0x7c30, 0x7e5c, 0x7e50, 0x7e56,
+ 0x7e63, 0x7e58, 0x7e62, 0x7e5f, 0x7e51, 0x7e60, 0x7e57, 0x7e53,
+ 0x7fb5, 0x7fb3, 0x7ff7, 0x7ff8, 0x8075, 0x81d1, 0x81d2, 0x81d0,
+ 0x825f, 0x825e, 0x85b4, 0x85c6, 0x85c0, 0x85c3, 0x85c2, 0x85b3,
+ 0x85b5, 0x85bd, 0x85c7, 0x85c4, 0x85bf, 0x85cb, 0x85ce, 0x85c8,
+ 0x85c5, 0x85b1, 0x85b6, 0x85d2, 0x8624, 0x85b8, 0x85b7, 0x85be,
+ 0x8669, 0x87e7, 0x87e6, 0x87e2, 0x87db, 0x87eb, 0x87ea, 0x87e5,
+ 0x87df, 0x87f3, 0x87e4, 0x87d4, 0x87dc, 0x87d3, 0x87ed, 0x87d8,
+ 0x87e3, 0x87a4, 0x87d7, 0x87d9, 0x8801, 0x87f4, 0x87e8, 0x87dd,
+ 0x8953, 0x894b, 0x894f, 0x894c, 0x8946, 0x8950, 0x8951, 0x8949,
+ 0x8b2a, 0x8b27, 0x8b23, 0x8b33, 0x8b30, 0x8b35, 0x8b47, 0x8b2f,
+ 0x8b3c, 0x8b3e, 0x8b31, 0x8b25, 0x8b37, 0x8b26, 0x8b36, 0x8b2e,
+ 0x8b24, 0x8b3b, 0x8b3d, 0x8b3a, 0x8c42, 0x8c75, 0x8c99, 0x8c98,
+ 0x8c97, 0x8cfe, 0x8d04, 0x8d02, 0x8d00, 0x8e5c, 0x8e62, 0x8e60,
+ 0x8e57, 0x8e56, 0x8e5e, 0x8e65, 0x8e67,
+ /* 0xf1 */
+ 0x8e5b, 0x8e5a, 0x8e61, 0x8e5d, 0x8e69, 0x8e54, 0x8f46, 0x8f47,
+ 0x8f48, 0x8f4b, 0x9128, 0x913a, 0x913b, 0x913e, 0x91a8, 0x91a5,
+ 0x91a7, 0x91af, 0x91aa, 0x93b5, 0x938c, 0x9392, 0x93b7, 0x939b,
+ 0x939d, 0x9389, 0x93a7, 0x938e, 0x93aa, 0x939e, 0x93a6, 0x9395,
+ 0x9388, 0x9399, 0x939f, 0x938d, 0x93b1, 0x9391, 0x93b2, 0x93a4,
+ 0x93a8, 0x93b4, 0x93a3, 0x93a5, 0x95d2, 0x95d3, 0x95d1, 0x96b3,
+ 0x96d7, 0x96da, 0x5dc2, 0x96df, 0x96d8, 0x96dd, 0x9723, 0x9722,
+ 0x9725, 0x97ac, 0x97ae, 0x97a8, 0x97ab, 0x97a4, 0x97aa, 0x97a2,
+ 0x97a5, 0x97d7, 0x97d9, 0x97d6, 0x97d8, 0x97fa, 0x9850, 0x9851,
+ 0x9852, 0x98b8, 0x9941, 0x993c, 0x993a, 0x9a0f, 0x9a0b, 0x9a09,
+ 0x9a0d, 0x9a04, 0x9a11, 0x9a0a, 0x9a05, 0x9a07, 0x9a06, 0x9ac0,
+ 0x9adc, 0x9b08, 0x9b04, 0x9b05, 0x9b29, 0x9b35, 0x9b4a, 0x9b4c,
+ 0x9b4b, 0x9bc7, 0x9bc6, 0x9bc3, 0x9bbf, 0x9bc1, 0x9bb5, 0x9bb8,
+ 0x9bd3, 0x9bb6, 0x9bc4, 0x9bb9, 0x9bbd, 0x9d5c, 0x9d53, 0x9d4f,
+ 0x9d4a, 0x9d5b, 0x9d4b, 0x9d59, 0x9d56, 0x9d4c, 0x9d57, 0x9d52,
+ 0x9d54, 0x9d5f, 0x9d58, 0x9d5a, 0x9e8e, 0x9e8c, 0x9edf, 0x9f01,
+ 0x9f00, 0x9f16, 0x9f25, 0x9f2b, 0x9f2a, 0x9f29, 0x9f28, 0x9f4c,
+ 0x9f55, 0x5134, 0x5135, 0x5296, 0x52f7, 0x53b4, 0x56ab, 0x56ad,
+ 0x56a6, 0x56a7, 0x56aa, 0x56ac, 0x58da, 0x58dd, 0x58db, 0x5912,
+ 0x5b3d, 0x5b3e, 0x5b3f, 0x5dc3, 0x5e70,
+ /* 0xf2 */
+ 0x5fbf, 0x61fb, 0x6507, 0x6510, 0x650d, 0x6509, 0x650c, 0x650e,
+ 0x6584, 0x65de, 0x65dd, 0x66de, 0x6ae7, 0x6ae0, 0x6acc, 0x6ad1,
+ 0x6ad9, 0x6acb, 0x6adf, 0x6adc, 0x6ad0, 0x6aeb, 0x6acf, 0x6acd,
+ 0x6ade, 0x6b60, 0x6bb0, 0x6c0c, 0x7019, 0x7027, 0x7020, 0x7016,
+ 0x702b, 0x7021, 0x7022, 0x7023, 0x7029, 0x7017, 0x7024, 0x701c,
+ 0x702a, 0x720c, 0x720a, 0x7207, 0x7202, 0x7205, 0x72a5, 0x72a6,
+ 0x72a4, 0x72a3, 0x72a1, 0x74cb, 0x74c5, 0x74b7, 0x74c3, 0x7516,
+ 0x7660, 0x77c9, 0x77ca, 0x77c4, 0x77f1, 0x791d, 0x791b, 0x7921,
+ 0x791c, 0x7917, 0x791e, 0x79b0, 0x7a67, 0x7a68, 0x7c33, 0x7c3c,
+ 0x7c39, 0x7c2c, 0x7c3b, 0x7cec, 0x7cea, 0x7e76, 0x7e75, 0x7e78,
+ 0x7e70, 0x7e77, 0x7e6f, 0x7e7a, 0x7e72, 0x7e74, 0x7e68, 0x7f4b,
+ 0x7f4a, 0x7f83, 0x7f86, 0x7fb7, 0x7ffd, 0x7ffe, 0x8078, 0x81d7,
+ 0x81d5, 0x8264, 0x8261, 0x8263, 0x85eb, 0x85f1, 0x85ed, 0x85d9,
+ 0x85e1, 0x85e8, 0x85da, 0x85d7, 0x85ec, 0x85f2, 0x85f8, 0x85d8,
+ 0x85df, 0x85e3, 0x85dc, 0x85d1, 0x85f0, 0x85e6, 0x85ef, 0x85de,
+ 0x85e2, 0x8800, 0x87fa, 0x8803, 0x87f6, 0x87f7, 0x8809, 0x880c,
+ 0x880b, 0x8806, 0x87fc, 0x8808, 0x87ff, 0x880a, 0x8802, 0x8962,
+ 0x895a, 0x895b, 0x8957, 0x8961, 0x895c, 0x8958, 0x895d, 0x8959,
+ 0x8988, 0x89b7, 0x89b6, 0x89f6, 0x8b50, 0x8b48, 0x8b4a, 0x8b40,
+ 0x8b53, 0x8b56, 0x8b54, 0x8b4b, 0x8b55,
+ /* 0xf3 */
+ 0x8b51, 0x8b42, 0x8b52, 0x8b57, 0x8c43, 0x8c77, 0x8c76, 0x8c9a,
+ 0x8d06, 0x8d07, 0x8d09, 0x8dac, 0x8daa, 0x8dad, 0x8dab, 0x8e6d,
+ 0x8e78, 0x8e73, 0x8e6a, 0x8e6f, 0x8e7b, 0x8ec2, 0x8f52, 0x8f51,
+ 0x8f4f, 0x8f50, 0x8f53, 0x8fb4, 0x9140, 0x913f, 0x91b0, 0x91ad,
+ 0x93de, 0x93c7, 0x93cf, 0x93c2, 0x93da, 0x93d0, 0x93f9, 0x93ec,
+ 0x93cc, 0x93d9, 0x93a9, 0x93e6, 0x93ca, 0x93d4, 0x93ee, 0x93e3,
+ 0x93d5, 0x93c4, 0x93ce, 0x93c0, 0x93d2, 0x93e7, 0x957d, 0x95da,
+ 0x95db, 0x96e1, 0x9729, 0x972b, 0x972c, 0x9728, 0x9726, 0x97b3,
+ 0x97b7, 0x97b6, 0x97dd, 0x97de, 0x97df, 0x985c, 0x9859, 0x985d,
+ 0x9857, 0x98bf, 0x98bd, 0x98bb, 0x98be, 0x9948, 0x9947, 0x9943,
+ 0x99a6, 0x99a7, 0x9a1a, 0x9a15, 0x9a25, 0x9a1d, 0x9a24, 0x9a1b,
+ 0x9a22, 0x9a20, 0x9a27, 0x9a23, 0x9a1e, 0x9a1c, 0x9a14, 0x9ac2,
+ 0x9b0b, 0x9b0a, 0x9b0e, 0x9b0c, 0x9b37, 0x9bea, 0x9beb, 0x9be0,
+ 0x9bde, 0x9be4, 0x9be6, 0x9be2, 0x9bf0, 0x9bd4, 0x9bd7, 0x9bec,
+ 0x9bdc, 0x9bd9, 0x9be5, 0x9bd5, 0x9be1, 0x9bda, 0x9d77, 0x9d81,
+ 0x9d8a, 0x9d84, 0x9d88, 0x9d71, 0x9d80, 0x9d78, 0x9d86, 0x9d8b,
+ 0x9d8c, 0x9d7d, 0x9d6b, 0x9d74, 0x9d75, 0x9d70, 0x9d69, 0x9d85,
+ 0x9d73, 0x9d7b, 0x9d82, 0x9d6f, 0x9d79, 0x9d7f, 0x9d87, 0x9d68,
+ 0x9e94, 0x9e91, 0x9ec0, 0x9efc, 0x9f2d, 0x9f40, 0x9f41, 0x9f4d,
+ 0x9f56, 0x9f57, 0x9f58, 0x5337, 0x56b2,
+ /* 0xf4 */
+ 0x56b5, 0x56b3, 0x58e3, 0x5b45, 0x5dc6, 0x5dc7, 0x5eee, 0x5eef,
+ 0x5fc0, 0x5fc1, 0x61f9, 0x6517, 0x6516, 0x6515, 0x6513, 0x65df,
+ 0x66e8, 0x66e3, 0x66e4, 0x6af3, 0x6af0, 0x6aea, 0x6ae8, 0x6af9,
+ 0x6af1, 0x6aee, 0x6aef, 0x703c, 0x7035, 0x702f, 0x7037, 0x7034,
+ 0x7031, 0x7042, 0x7038, 0x703f, 0x703a, 0x7039, 0x7040, 0x703b,
+ 0x7033, 0x7041, 0x7213, 0x7214, 0x72a8, 0x737d, 0x737c, 0x74ba,
+ 0x76ab, 0x76aa, 0x76be, 0x76ed, 0x77cc, 0x77ce, 0x77cf, 0x77cd,
+ 0x77f2, 0x7925, 0x7923, 0x7927, 0x7928, 0x7924, 0x7929, 0x79b2,
+ 0x7a6e, 0x7a6c, 0x7a6d, 0x7af7, 0x7c49, 0x7c48, 0x7c4a, 0x7c47,
+ 0x7c45, 0x7cee, 0x7e7b, 0x7e7e, 0x7e81, 0x7e80, 0x7fba, 0x7fff,
+ 0x8079, 0x81db, 0x81d9, 0x820b, 0x8268, 0x8269, 0x8622, 0x85ff,
+ 0x8601, 0x85fe, 0x861b, 0x8600, 0x85f6, 0x8604, 0x8609, 0x8605,
+ 0x860c, 0x85fd, 0x8819, 0x8810, 0x8811, 0x8817, 0x8813, 0x8816,
+ 0x8963, 0x8966, 0x89b9, 0x89f7, 0x8b60, 0x8b6a, 0x8b5d, 0x8b68,
+ 0x8b63, 0x8b65, 0x8b67, 0x8b6d, 0x8dae, 0x8e86, 0x8e88, 0x8e84,
+ 0x8f59, 0x8f56, 0x8f57, 0x8f55, 0x8f58, 0x8f5a, 0x908d, 0x9143,
+ 0x9141, 0x91b7, 0x91b5, 0x91b2, 0x91b3, 0x940b, 0x9413, 0x93fb,
+ 0x9420, 0x940f, 0x9414, 0x93fe, 0x9415, 0x9410, 0x9428, 0x9419,
+ 0x940d, 0x93f5, 0x9400, 0x93f7, 0x9407, 0x940e, 0x9416, 0x9412,
+ 0x93fa, 0x9409, 0x93f8, 0x940a, 0x93ff,
+ /* 0xf5 */
+ 0x93fc, 0x940c, 0x93f6, 0x9411, 0x9406, 0x95de, 0x95e0, 0x95df,
+ 0x972e, 0x972f, 0x97b9, 0x97bb, 0x97fd, 0x97fe, 0x9860, 0x9862,
+ 0x9863, 0x985f, 0x98c1, 0x98c2, 0x9950, 0x994e, 0x9959, 0x994c,
+ 0x994b, 0x9953, 0x9a32, 0x9a34, 0x9a31, 0x9a2c, 0x9a2a, 0x9a36,
+ 0x9a29, 0x9a2e, 0x9a38, 0x9a2d, 0x9ac7, 0x9aca, 0x9ac6, 0x9b10,
+ 0x9b12, 0x9b11, 0x9c0b, 0x9c08, 0x9bf7, 0x9c05, 0x9c12, 0x9bf8,
+ 0x9c40, 0x9c07, 0x9c0e, 0x9c06, 0x9c17, 0x9c14, 0x9c09, 0x9d9f,
+ 0x9d99, 0x9da4, 0x9d9d, 0x9d92, 0x9d98, 0x9d90, 0x9d9b, 0x9da0,
+ 0x9d94, 0x9d9c, 0x9daa, 0x9d97, 0x9da1, 0x9d9a, 0x9da2, 0x9da8,
+ 0x9d9e, 0x9da3, 0x9dbf, 0x9da9, 0x9d96, 0x9da6, 0x9da7, 0x9e99,
+ 0x9e9b, 0x9e9a, 0x9ee5, 0x9ee4, 0x9ee7, 0x9ee6, 0x9f30, 0x9f2e,
+ 0x9f5b, 0x9f60, 0x9f5e, 0x9f5d, 0x9f59, 0x9f91, 0x513a, 0x5139,
+ 0x5298, 0x5297, 0x56c3, 0x56bd, 0x56be, 0x5b48, 0x5b47, 0x5dcb,
+ 0x5dcf, 0x5ef1, 0x61fd, 0x651b, 0x6b02, 0x6afc, 0x6b03, 0x6af8,
+ 0x6b00, 0x7043, 0x7044, 0x704a, 0x7048, 0x7049, 0x7045, 0x7046,
+ 0x721d, 0x721a, 0x7219, 0x737e, 0x7517, 0x766a, 0x77d0, 0x792d,
+ 0x7931, 0x792f, 0x7c54, 0x7c53, 0x7cf2, 0x7e8a, 0x7e87, 0x7e88,
+ 0x7e8b, 0x7e86, 0x7e8d, 0x7f4d, 0x7fbb, 0x8030, 0x81dd, 0x8618,
+ 0x862a, 0x8626, 0x861f, 0x8623, 0x861c, 0x8619, 0x8627, 0x862e,
+ 0x8621, 0x8620, 0x8629, 0x861e, 0x8625,
+ /* 0xf6 */
+ 0x8829, 0x881d, 0x881b, 0x8820, 0x8824, 0x881c, 0x882b, 0x884a,
+ 0x896d, 0x8969, 0x896e, 0x896b, 0x89fa, 0x8b79, 0x8b78, 0x8b45,
+ 0x8b7a, 0x8b7b, 0x8d10, 0x8d14, 0x8daf, 0x8e8e, 0x8e8c, 0x8f5e,
+ 0x8f5b, 0x8f5d, 0x9146, 0x9144, 0x9145, 0x91b9, 0x943f, 0x943b,
+ 0x9436, 0x9429, 0x943d, 0x943c, 0x9430, 0x9439, 0x942a, 0x9437,
+ 0x942c, 0x9440, 0x9431, 0x95e5, 0x95e4, 0x95e3, 0x9735, 0x973a,
+ 0x97bf, 0x97e1, 0x9864, 0x98c9, 0x98c6, 0x98c0, 0x9958, 0x9956,
+ 0x9a39, 0x9a3d, 0x9a46, 0x9a44, 0x9a42, 0x9a41, 0x9a3a, 0x9a3f,
+ 0x9acd, 0x9b15, 0x9b17, 0x9b18, 0x9b16, 0x9b3a, 0x9b52, 0x9c2b,
+ 0x9c1d, 0x9c1c, 0x9c2c, 0x9c23, 0x9c28, 0x9c29, 0x9c24, 0x9c21,
+ 0x9db7, 0x9db6, 0x9dbc, 0x9dc1, 0x9dc7, 0x9dca, 0x9dcf, 0x9dbe,
+ 0x9dc5, 0x9dc3, 0x9dbb, 0x9db5, 0x9dce, 0x9db9, 0x9dba, 0x9dac,
+ 0x9dc8, 0x9db1, 0x9dad, 0x9dcc, 0x9db3, 0x9dcd, 0x9db2, 0x9e7a,
+ 0x9e9c, 0x9eeb, 0x9eee, 0x9eed, 0x9f1b, 0x9f18, 0x9f1a, 0x9f31,
+ 0x9f4e, 0x9f65, 0x9f64, 0x9f92, 0x4eb9, 0x56c6, 0x56c5, 0x56cb,
+ 0x5971, 0x5b4b, 0x5b4c, 0x5dd5, 0x5dd1, 0x5ef2, 0x6521, 0x6520,
+ 0x6526, 0x6522, 0x6b0b, 0x6b08, 0x6b09, 0x6c0d, 0x7055, 0x7056,
+ 0x7057, 0x7052, 0x721e, 0x721f, 0x72a9, 0x737f, 0x74d8, 0x74d5,
+ 0x74d9, 0x74d7, 0x766d, 0x76ad, 0x7935, 0x79b4, 0x7a70, 0x7a71,
+ 0x7c57, 0x7c5c, 0x7c59, 0x7c5b, 0x7c5a,
+ /* 0xf7 */
+ 0x7cf4, 0x7cf1, 0x7e91, 0x7f4f, 0x7f87, 0x81de, 0x826b, 0x8634,
+ 0x8635, 0x8633, 0x862c, 0x8632, 0x8636, 0x882c, 0x8828, 0x8826,
+ 0x882a, 0x8825, 0x8971, 0x89bf, 0x89be, 0x89fb, 0x8b7e, 0x8b84,
+ 0x8b82, 0x8b86, 0x8b85, 0x8b7f, 0x8d15, 0x8e95, 0x8e94, 0x8e9a,
+ 0x8e92, 0x8e90, 0x8e96, 0x8e97, 0x8f60, 0x8f62, 0x9147, 0x944c,
+ 0x9450, 0x944a, 0x944b, 0x944f, 0x9447, 0x9445, 0x9448, 0x9449,
+ 0x9446, 0x973f, 0x97e3, 0x986a, 0x9869, 0x98cb, 0x9954, 0x995b,
+ 0x9a4e, 0x9a53, 0x9a54, 0x9a4c, 0x9a4f, 0x9a48, 0x9a4a, 0x9a49,
+ 0x9a52, 0x9a50, 0x9ad0, 0x9b19, 0x9b2b, 0x9b3b, 0x9b56, 0x9b55,
+ 0x9c46, 0x9c48, 0x9c3f, 0x9c44, 0x9c39, 0x9c33, 0x9c41, 0x9c3c,
+ 0x9c37, 0x9c34, 0x9c32, 0x9c3d, 0x9c36, 0x9ddb, 0x9dd2, 0x9dde,
+ 0x9dda, 0x9dcb, 0x9dd0, 0x9ddc, 0x9dd1, 0x9ddf, 0x9de9, 0x9dd9,
+ 0x9dd8, 0x9dd6, 0x9df5, 0x9dd5, 0x9ddd, 0x9eb6, 0x9ef0, 0x9f35,
+ 0x9f33, 0x9f32, 0x9f42, 0x9f6b, 0x9f95, 0x9fa2, 0x513d, 0x5299,
+ 0x58e8, 0x58e7, 0x5972, 0x5b4d, 0x5dd8, 0x882f, 0x5f4f, 0x6201,
+ 0x6203, 0x6204, 0x6529, 0x6525, 0x6596, 0x66eb, 0x6b11, 0x6b12,
+ 0x6b0f, 0x6bca, 0x705b, 0x705a, 0x7222, 0x7382, 0x7381, 0x7383,
+ 0x7670, 0x77d4, 0x7c67, 0x7c66, 0x7e95, 0x826c, 0x863a, 0x8640,
+ 0x8639, 0x863c, 0x8631, 0x863b, 0x863e, 0x8830, 0x8832, 0x882e,
+ 0x8833, 0x8976, 0x8974, 0x8973, 0x89fe,
+ /* 0xf8 */
+ 0x8b8c, 0x8b8e, 0x8b8b, 0x8b88, 0x8c45, 0x8d19, 0x8e98, 0x8f64,
+ 0x8f63, 0x91bc, 0x9462, 0x9455, 0x945d, 0x9457, 0x945e, 0x97c4,
+ 0x97c5, 0x9800, 0x9a56, 0x9a59, 0x9b1e, 0x9b1f, 0x9b20, 0x9c52,
+ 0x9c58, 0x9c50, 0x9c4a, 0x9c4d, 0x9c4b, 0x9c55, 0x9c59, 0x9c4c,
+ 0x9c4e, 0x9dfb, 0x9df7, 0x9def, 0x9de3, 0x9deb, 0x9df8, 0x9de4,
+ 0x9df6, 0x9de1, 0x9dee, 0x9de6, 0x9df2, 0x9df0, 0x9de2, 0x9dec,
+ 0x9df4, 0x9df3, 0x9de8, 0x9ded, 0x9ec2, 0x9ed0, 0x9ef2, 0x9ef3,
+ 0x9f06, 0x9f1c, 0x9f38, 0x9f37, 0x9f36, 0x9f43, 0x9f4f, 0x9f71,
+ 0x9f70, 0x9f6e, 0x9f6f, 0x56d3, 0x56cd, 0x5b4e, 0x5c6d, 0x652d,
+ 0x66ed, 0x66ee, 0x6b13, 0x705f, 0x7061, 0x705d, 0x7060, 0x7223,
+ 0x74db, 0x74e5, 0x77d5, 0x7938, 0x79b7, 0x79b6, 0x7c6a, 0x7e97,
+ 0x7f89, 0x826d, 0x8643, 0x8838, 0x8837, 0x8835, 0x884b, 0x8b94,
+ 0x8b95, 0x8e9e, 0x8e9f, 0x8ea0, 0x8e9d, 0x91be, 0x91bd, 0x91c2,
+ 0x946b, 0x9468, 0x9469, 0x96e5, 0x9746, 0x9743, 0x9747, 0x97c7,
+ 0x97e5, 0x9a5e, 0x9ad5, 0x9b59, 0x9c63, 0x9c67, 0x9c66, 0x9c62,
+ 0x9c5e, 0x9c60, 0x9e02, 0x9dfe, 0x9e07, 0x9e03, 0x9e06, 0x9e05,
+ 0x9e00, 0x9e01, 0x9e09, 0x9dff, 0x9dfd, 0x9e04, 0x9ea0, 0x9f1e,
+ 0x9f46, 0x9f74, 0x9f75, 0x9f76, 0x56d4, 0x652e, 0x65b8, 0x6b18,
+ 0x6b19, 0x6b17, 0x6b1a, 0x7062, 0x7226, 0x72aa, 0x77d8, 0x77d9,
+ 0x7939, 0x7c69, 0x7c6b, 0x7cf6, 0x7e9a,
+ /* 0xf9 */
+ 0x7e98, 0x7e9b, 0x7e99, 0x81e0, 0x81e1, 0x8646, 0x8647, 0x8648,
+ 0x8979, 0x897a, 0x897c, 0x897b, 0x89ff, 0x8b98, 0x8b99, 0x8ea5,
+ 0x8ea4, 0x8ea3, 0x946e, 0x946d, 0x946f, 0x9471, 0x9473, 0x9749,
+ 0x9872, 0x995f, 0x9c68, 0x9c6e, 0x9c6d, 0x9e0b, 0x9e0d, 0x9e10,
+ 0x9e0f, 0x9e12, 0x9e11, 0x9ea1, 0x9ef5, 0x9f09, 0x9f47, 0x9f78,
+ 0x9f7b, 0x9f7a, 0x9f79, 0x571e, 0x7066, 0x7c6f, 0x883c, 0x8db2,
+ 0x8ea6, 0x91c3, 0x9474, 0x9478, 0x9476, 0x9475, 0x9a60, 0x9c74,
+ 0x9c73, 0x9c71, 0x9c75, 0x9e14, 0x9e13, 0x9ef6, 0x9f0a, 0x9fa4,
+ 0x7068, 0x7065, 0x7cf7, 0x866a, 0x883e, 0x883d, 0x883f, 0x8b9e,
+ 0x8c9c, 0x8ea9, 0x8ec9, 0x974b, 0x9873, 0x9874, 0x98cc, 0x9961,
+ 0x99ab, 0x9a64, 0x9a66, 0x9a67, 0x9b24, 0x9e15, 0x9e17, 0x9f48,
+ 0x6207, 0x6b1e, 0x7227, 0x864c, 0x8ea8, 0x9482, 0x9480, 0x9481,
+ 0x9a69, 0x9a68, 0x9b2e, 0x9e19, 0x7229, 0x864b, 0x8b9f, 0x9483,
+ 0x9c79, 0x9eb7, 0x7675, 0x9a6b, 0x9c7a, 0x9e1d, 0x7069, 0x706a,
+ 0x9ea4, 0x9f7e, 0x9f49, 0x9f98,
+};
+
+/* HKSCS table */
+
+static const unsigned short hkscs_2uni_page88[627] = {
+ /* 0x88 */
+ 0x7e43, 0x7e44, 0x7e45, 0x7e46, 0x7e47, 0x7e48, 0x7e49, 0x7e4a,
+ 0x7e4b, 0x7e4c, 0x7e4d, 0x7e4e, 0x7e4f, 0x7e50, 0x7e51, 0x7e52,
+ 0x7e53, 0x7e54, 0x7e55, 0x7e56, 0x7e57, 0x7e58, 0x0080, 0x0041,
+ 0x010d, 0x0040, 0x0092, 0x0049, 0x009a, 0x0048, 0x00cc, 0x0053,
+ 0x0111, 0x0052, 0x7e65, 0x02be, 0x7e67, 0x02c0, 0x004a, 0x0081,
+ 0x0061, 0x010e, 0x0060, 0x0151, 0x0093, 0x0069, 0x009b, 0x0068,
+ 0x00ab, 0x006d, 0x0110, 0x006c, 0x00cd, 0x0073, 0x0112, 0x0072,
+ 0x00eb, 0x007a, 0x0114, 0x0079, 0x0116, 0x0118, 0x011a, 0x011c,
+ 0x007c, 0x7e84, 0x02bf, 0x7e86, 0x02c1, 0x006a, 0x0161, 0x7e8a,
+ 0x7e8b, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ /* 0x89 */
+ 0xea69, 0x7ee1, 0x81bd, 0x36ca, 0x81bd, 0x81bd, 0x1ffd, 0x405d,
+ 0x6d8e, 0x629f, 0x81bd, 0x81bd, 0xd3b5, 0x3651, 0x20da, 0x20e8,
+ 0x2168, 0x2316, 0x2334, 0x235c, 0x23a4, 0x2461, 0x2468, 0x24fb,
+ 0x250e, 0x2591, 0x2598, 0x28a2, 0x2ab0, 0x2ac4, 0x2ac7, 0x2af2,
+ 0x2af4, 0x2d26, 0x2d5e, 0x2d5f, 0x2e5a, 0x3046, 0x31fb, 0x3749,
+ 0x39be, 0x39c4, 0x3a25, 0x3f0e, 0x423c, 0x46b5, 0x5024, 0x502c,
+ 0x503a, 0x5047, 0x504f, 0x505f, 0x5086, 0x50b7, 0x53fa, 0x544f,
+ 0x54ef, 0x5b06, 0x5cfe, 0x5d22, 0x6066, 0x6067, 0x606e, 0x4591,
+ 0x4e7c, 0x4f4d, 0x3b06, 0x4c49, 0x23e7, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x624c, 0x4a38, 0x621e, 0x523c, 0x81bd, 0x5e0b, 0x5276,
+ 0x7f30, 0x81bd, 0x81bd, 0x521f, 0x6f07, 0x1f0d, 0x6e09, 0x6e4c,
+ 0x1e7e, 0x7f39, 0xcfce, 0x6e4a, 0x7f3c, 0x0881, 0x81bd, 0x401a,
+ 0x53be, 0x4699, 0x81bd, 0x1b91, 0x6b2c, 0x6b4f, 0x6fd9, 0x4b07,
+ 0x7f48, 0x970a, 0x86d0, 0x7f4b, 0x1fe4, 0x2041, 0x2040, 0x2047,
+ 0x207f, 0x20ab, 0x20f7, 0x070c, 0x217d, 0x10c8, 0x21c3, 0x2248,
+ 0x073d, 0x0753, 0x0765, 0x2346, 0x2ac5, 0x239b, 0x23bc, 0x23c5,
+ 0x2049, 0x2439, 0x2450, 0x24e7, 0x0887, 0x2569, 0x0811, 0x2570,
+ 0x0813, 0x2582, 0x25e3, 0x082d, 0x0832, 0x0941, 0x2653, 0x2663,
+ 0x2674, 0x2679, 0x2690, 0x26af, 0x26d8, 0x26e3, 0x26e8, 0x0858,
+ 0x26ff, 0x0865, 0x087f, 0x2797, 0x0885,
+ /* 0x8a */
+ 0x7f7d, 0x26e5, 0x81bd, 0x8a42, 0x7f81, 0x7f82, 0x2750, 0xa186,
+ 0x0cac, 0x8481, 0x5f46, 0xb8f8, 0x7f89, 0x12d3, 0xd87e, 0x48fa,
+ 0x7f8d, 0x0cf4, 0x1a55, 0x7f90, 0xca72, 0xb92a, 0x369d, 0x7f94,
+ 0x8cf4, 0x8ad5, 0x8e34, 0x364d, 0x5f7e, 0x7f9a, 0x7f9b, 0x7f9c,
+ 0x7f9d, 0xd996, 0xb293, 0x81bd, 0x8b06, 0x7fa2, 0xd8a9, 0x1a74,
+ 0x7fa5, 0x7fa6, 0x6b72, 0x0d27, 0x7fa9, 0x126d, 0x07c6, 0xbb87,
+ 0x7fad, 0x7fae, 0x7faf, 0x6dae, 0x68d5, 0x81bd, 0x1659, 0xc465,
+ 0x3674, 0x26a3, 0x7fb7, 0x7fb8, 0x8db7, 0x0cbb, 0x8daf, 0x7fbc,
+ 0x7fbd, 0x7fbe, 0x36aa, 0x7fc0, 0x8a43, 0x5f68, 0x99e1, 0xdf0c,
+ 0x7fc5, 0x81bd, 0x1a8b, 0x7fc8, 0x127a, 0x2a33, 0x7fcb, 0x81bd,
+ 0x7fcd, 0x863c, 0x7fcf, 0x7fd0, 0x7fd1, 0x2739, 0x133b, 0x163a,
+ 0x81bd, 0x1cf4, 0x7fd7, 0x7fd8, 0x532a, 0x69b5, 0x7fdb, 0x3539,
+ 0x0cbe, 0x9db5, 0x5ec0, 0x2861, 0x363c, 0x10c3, 0x81bd, 0x7fe4,
+ 0x8b89, 0x9fcf, 0x7fe7, 0x81bd, 0x8e08, 0x7fea, 0x0c52, 0x0cc6,
+ 0x7fed, 0x0838, 0x7fef, 0x9907, 0x2812, 0x8cb1, 0x7ff3, 0x7ff4,
+ 0x077c, 0x3dfd, 0x7ff7, 0x81bd, 0x81bd, 0x7ffa, 0x7ffb, 0x7ffc,
+ 0x7ffd, 0xe00d, 0x8bfa, 0x8000, 0x8001, 0x5113, 0x8003, 0x9e03,
+ 0x9f39, 0x08bb, 0xbb23, 0x8008, 0x8ccd, 0x8c2a, 0x1213, 0x8cb0,
+ 0x8b07, 0x800e, 0x800f, 0x81bd, 0x8c2b, 0x8012, 0x8b08, 0x8e00,
+ 0x8e7d, 0x1279, 0x9cd6, 0x35f2, 0x8ced,
+ /* 0x8b */
+ 0xa674, 0xd2f9, 0xa08e, 0x8b3e, 0x8b3f, 0xa111, 0xa115, 0x0cd8,
+ 0x8022, 0x8e07, 0x8cae, 0x8025, 0xcb50, 0x8027, 0x8028, 0x8029,
+ 0x666a, 0x268c, 0x5444, 0x2779, 0x81bd, 0xe783, 0x6ce6, 0x6b76,
+ 0xd3de, 0x8033, 0x42c0, 0x52ed, 0x526c, 0x2ddc, 0xc772, 0x52b4,
+ 0x0a57, 0x251f, 0xd87d, 0x6276, 0x8c7a, 0x8b8f, 0x8bf7, 0x8c7b,
+ 0x089d, 0xb92b, 0x08c9, 0x8ad6, 0x286f, 0x9df5, 0x8e09, 0x8b90,
+ 0x8bf8, 0x8db8, 0x8e88, 0xd947, 0x90d5, 0x8bf9, 0xb950, 0xa264,
+ 0x2c14, 0x8d5d, 0x8d5e, 0x8e35, 0x8e36, 0x295c, 0x8b91, 0xd354,
+ 0xd9cd, 0x8cf5, 0x8bfb, 0xbafe, 0x09c3, 0x8cf6, 0x8ec0, 0xbb98,
+ 0x8062, 0x8063, 0x93fa, 0x8065, 0x8066, 0x2a59, 0x2428, 0x08da,
+ 0x806a, 0x4d32, 0x2d28, 0x1a80, 0x1d6c, 0x6f67, 0x1c67, 0x6cdf,
+ 0x6c4d, 0xc0b4, 0xa43d, 0x27bb, 0x08b2, 0x2849, 0x1fe8, 0x2ac2,
+ 0x807a, 0x807b, 0x6811, 0x807d, 0x201b, 0x207b, 0x07fe, 0x2de3,
+ 0x3111, 0x3184, 0x0bba, 0x340c, 0x36f5, 0x3d3a, 0x3df5, 0x3dfa,
+ 0x41ec, 0x43ab, 0x1fec, 0x442d, 0x808e, 0x50d2, 0x4abb, 0x4e79,
+ 0x50d3, 0x8093, 0x0781, 0x81bd, 0x8096, 0x5182, 0x5200, 0x8099,
+ 0x809a, 0x251d, 0x59a4, 0x5b01, 0x809e, 0x5ce0, 0x5e1d, 0x6545,
+ 0x6638, 0x663f, 0x66a8, 0x80a5, 0x68a6, 0x6935, 0x698e, 0x699e,
+ 0x6a23, 0x80ab, 0x6d3c, 0x6e5f, 0x6f04, 0x3d2f, 0x6fdc, 0x1ff7,
+ 0x80b2, 0x66dd, 0x33f7, 0x6562,
+};
+static const unsigned short hkscs_2uni_page8d[3140] = {
+ /* 0x8d */
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x2efe, 0x2f08, 0x2f16, 0x107c, 0x0acf, 0x2f64, 0x2f79, 0x0ae0,
+ 0x0af8, 0x3002, 0x307d, 0x30e5, 0x3143, 0x0bc8, 0x0bd4, 0x0bff,
+ 0x0c0d, 0x3297, 0x32fd, 0x2ea5, 0x0c49, 0x3377, 0x3379, 0x338f,
+ 0x0c78, 0x33ec, 0x3450, 0x34a5, 0x34d8, 0x0cb8, 0x2871, 0x0cc3,
+ 0x35a2, 0x35bb, 0x35c7, 0x361a, 0x0d0b, 0x3680, 0x2ed5, 0x27e1,
+ 0x6fdf, 0x0d57, 0x3746, 0x0d7d, 0x37bf, 0x3813, 0x0db2, 0x3852,
+ 0x0de2, 0x38d6, 0x0e02, 0x3964, 0x39c0, 0x0e18, 0x3a0a, 0x3a44,
+ 0x0e32, 0x0e31, 0x0e3b, 0x3ac9, 0x3b03, 0x43dc, 0x3b24, 0x3b5f,
+ 0x3b45, 0x0e7c, 0x3b96, 0x0e9d, 0x3c25, 0x3c34, 0x3c31, 0x3c42,
+ 0x0eac, 0x3c59, 0x0eb2, 0x3c6b, 0x3c75, 0x3c94, 0x3cb6, 0x3d41,
+ 0x3d81, 0x3daa, 0x3e35, 0x3e6a, 0x0f4b, 0x3ec2, 0x3ec6, 0x3ee6,
+ 0x3f41, 0x0f6f, 0x3f64, 0x3f71, 0x3f95, 0x3f98, 0x3fa9, 0x4006,
+ 0xdd80, 0x403b, 0x4062, 0x405a, 0x6fbf, 0x4068, 0x4069, 0x40a4,
+ 0x40b4, 0x0fc6, 0xad01, 0x4101, 0x413e, 0x0fea, 0x0ff5, 0x4337,
+ 0x2e59, 0x100a, 0x41ac, 0x1011, 0x41d0, 0x41d4, 0x41ef, 0x41ff,
+ 0x4209, 0x8465, 0x1641, 0x08b1, 0x80f0,
+ /* 0x8e */
+ 0x7311, 0x297e, 0xce93, 0x42be, 0xbee0, 0x090e, 0x3b62, 0xdfa9,
+ 0x2d34, 0x4bc9, 0xbf61, 0xe359, 0x4be5, 0x4bfd, 0xbfec, 0x4c3b,
+ 0x4c30, 0x4c42, 0x4c43, 0x4351, 0x7325, 0x144a, 0x4c5a, 0x4c5d,
+ 0x4c6a, 0x146f, 0x2672, 0xc141, 0x4c8b, 0x4cd5, 0x4ca9, 0x7330,
+ 0xc1fe, 0x4d22, 0x4cef, 0x551c, 0xc0f4, 0xcc7f, 0x4d50, 0x55a1,
+ 0x4d12, 0x81bd, 0xadb0, 0x102d, 0xc1a5, 0x5612, 0x4d7a, 0x81bd,
+ 0x4db5, 0xc1c1, 0x4dc4, 0x4e03, 0x7345, 0x4e26, 0x383d, 0xb338,
+ 0x4e49, 0x4e47, 0x4e66, 0x4df4, 0x4e73, 0x4e75, 0x81bd, 0x4fe7,
+ 0x179d, 0xce04, 0x4edd, 0xce96, 0x460d, 0x4f09, 0x4f2b, 0x42b5,
+ 0x4f33, 0x81bd, 0xae17, 0xc3e9, 0x4f64, 0x0f93, 0x4f75, 0x93b9,
+ 0x4f65, 0x7362, 0x81bd, 0xc4a1, 0xc4da, 0x4fee, 0x5012, 0x15ab,
+ 0x652c, 0x4fa7, 0x50c0, 0x50c1, 0x50c7, 0x4ab6, 0xc5d0, 0x6aa1,
+ 0x5117, 0xc611, 0x5123, 0x9221, 0x8228, 0x17dc, 0xa9a6, 0x1783,
+ 0xda3a, 0x517a, 0xc6c9, 0x81bd, 0x5188, 0x519d, 0x81bd, 0x51af,
+ 0x7381, 0x7382, 0x51bb, 0x51bc, 0x51e1, 0x7386, 0x1c09, 0xc7e6,
+ 0x7389, 0xc868, 0x38e5, 0x5227, 0xde08, 0x5287, 0x529a, 0x2a70,
+ 0x9d36, 0x3e3f, 0xc6d8, 0x7394, 0x36a7, 0x7396, 0x5398, 0x941e,
+ 0x3c13, 0xb6a5, 0xb6d5, 0x16fa, 0x53a9, 0x739e, 0xcad2, 0x73a0,
+ 0x21b9, 0x917d, 0x5662, 0x54e2, 0xcb0a, 0xb5e7, 0xa770, 0x9333,
+ 0xabf8, 0x542a, 0x3adb, 0xebd4, 0x145b,
+ /* 0x8f */
+ 0x56cb, 0x5450, 0x549a, 0x8b96, 0x9374, 0x0981, 0x73b4, 0xa79a,
+ 0x53fb, 0x5462, 0x5498, 0xac4b, 0xcd63, 0x73bb, 0xcb97, 0xa80e,
+ 0x103f, 0x549d, 0x27ac, 0x5505, 0x178b, 0xcd65, 0x552c, 0x81bd,
+ 0x5553, 0x073e, 0xce94, 0x3c17, 0x56da, 0x0756, 0xce02, 0x73cd,
+ 0x55d8, 0x73cf, 0x55f1, 0x1053, 0x1764, 0x3c67, 0x55ca, 0x73d5,
+ 0x4ad8, 0x81bd, 0xcb96, 0xce37, 0xce03, 0x565e, 0x81bd, 0x5511,
+ 0x1720, 0x5613, 0x5664, 0x73e1, 0x14c0, 0xc1c0, 0x17c3, 0x56b4,
+ 0x2cb2, 0x73e7, 0x17a7, 0x56f3, 0x1796, 0x397f, 0x5756, 0xdbe5,
+ 0xdbfb, 0x5701, 0x73f0, 0x5742, 0x73f2, 0xd08d, 0x73f4, 0x17ea,
+ 0x5768, 0x0908, 0x9462, 0x25b7, 0xd1da, 0x57be, 0x58b1, 0xe878,
+ 0x592e, 0xa0e7, 0x58f1, 0x591a, 0x594f, 0x2821, 0x57ac, 0x3a16,
+ 0x188f, 0x5985, 0x5986, 0xd2a0, 0xabb9, 0xd2a4, 0x599e, 0x59dc,
+ 0x18db, 0x59f4, 0x59f5, 0x3581, 0x5a05, 0x48f7, 0xd38f, 0x5ac7,
+ 0x5aca, 0x81bd, 0x81bd, 0x5ae7, 0x5afc, 0xdde5, 0x5b27, 0xd4a4,
+ 0xd5bd, 0x5bdc, 0x4913, 0x62be, 0x5bd0, 0xd559, 0x4c69, 0xd63a,
+ 0x7426, 0x1993, 0xd638, 0x42fc, 0x5c4c, 0x5c5f, 0xbc30, 0xbca5,
+ 0x5c7f, 0x5c8c, 0x5c8d, 0x5be9, 0xb6ba, 0x5cd0, 0x5cdb, 0x5bef,
+ 0x7436, 0x1895, 0x598f, 0x5d9b, 0xd714, 0xd74f, 0xec14, 0x09e5,
+ 0xd713, 0x5dd6, 0xd758, 0xd77d, 0x5e12, 0x5e03, 0x94d0, 0x5ddb,
+ 0x41dc, 0x5e11, 0x7448, 0x1150, 0x81bd,
+ /* 0x90 */
+ 0x5ea9, 0xd802, 0x744d, 0xb5ca, 0x0e3c, 0x7450, 0xd0cc, 0x4c67,
+ 0x5fad, 0x5fb6, 0x5fc3, 0x6394, 0x6019, 0x602d, 0xda65, 0xda92,
+ 0x60a5, 0x63c3, 0xe9df, 0x8910, 0x60b3, 0x1baa, 0xdd9e, 0xdb3d,
+ 0xabbb, 0x30b8, 0xa522, 0x60f9, 0x7467, 0x7468, 0x7469, 0x9aa5,
+ 0x0c40, 0xce97, 0x6137, 0xdb3c, 0xd5be, 0x6161, 0xdb6c, 0xdbcb,
+ 0x61a8, 0x7474, 0x61c4, 0xdc66, 0x61ae, 0x81bd, 0x6227, 0x0db0,
+ 0x6269, 0x6284, 0x4e2c, 0xdcf3, 0x9789, 0x62ce, 0x3e5f, 0x6301,
+ 0x6322, 0xbcf9, 0x81bd, 0xde86, 0xaadb, 0xdecc, 0xbd1b, 0x748a,
+ 0x63ec, 0x642b, 0xdea1, 0xdfab, 0x420f, 0x2c83, 0xdea2, 0xdea5,
+ 0x1be5, 0x6304, 0xdfac, 0xdff9, 0xdfbf, 0x6433, 0x651b, 0x5fbc,
+ 0x6645, 0x6666, 0x64e6, 0x6660, 0x4176, 0x1539, 0x74a1, 0xdc58,
+ 0x8f7c, 0xac2e, 0x1c5f, 0x3ddc, 0x673b, 0x6756, 0x13ec, 0x6763,
+ 0xce95, 0x339a, 0x6776, 0x4a75, 0xdea0, 0x677d, 0x258c, 0x1c21,
+ 0xccb8, 0x83b4, 0xc690, 0xe1af, 0xe1e5, 0xb711, 0x94d5, 0xa5ca,
+ 0x67f1, 0x5782, 0x67f6, 0x1c8f, 0x17bd, 0x1805, 0x74c1, 0x41f5,
+ 0x2d01, 0x67db, 0x81bd, 0x74c6, 0x6817, 0x2d0a, 0xe2ab, 0x681f,
+ 0x64e5, 0x2290, 0xa3b7, 0xa3bc, 0x6849, 0x685f, 0x6871, 0x687e,
+ 0x6880, 0x6892, 0x68a0, 0xbc6c, 0x68ae, 0x459c, 0xe2f3, 0x81bd,
+ 0x68b5, 0xe2dd, 0x74dd, 0x1d11, 0x68f4, 0x68f3, 0x690b, 0x6926,
+ 0x0dce, 0xd135, 0x0fd1, 0x8730, 0xaf1c,
+ /* 0x91 */
+ 0xbe46, 0x698a, 0x6977, 0x6988, 0x6987, 0x1d3f, 0xcd27, 0x9293,
+ 0x2770, 0x69a1, 0x69a6, 0x69ac, 0x6438, 0x69f9, 0xb669, 0x1db2,
+ 0xe417, 0xe4c5, 0x6ab5, 0x6acc, 0x6afb, 0x6ad0, 0x6b18, 0xbe65,
+ 0x0984, 0xe1b1, 0xe5d5, 0x6ba0, 0x6ba2, 0xe585, 0x6bb4, 0x1e4e,
+ 0x6bd4, 0x6bed, 0xdbc0, 0x21f4, 0x6bf4, 0xca28, 0x0b83, 0xa37d,
+ 0x6c10, 0x6c00, 0xe67e, 0x2c05, 0x9423, 0x6c4e, 0xb00b, 0x6cc2,
+ 0x6cbf, 0x6ccc, 0xe728, 0x6e14, 0xe837, 0xe912, 0x751e, 0xe861,
+ 0xe8a3, 0xe95f, 0x6dbe, 0x6dc3, 0x7524, 0x6e4e, 0x3a48, 0x6e04,
+ 0x7528, 0xe913, 0xe9a0, 0x94fb, 0xe9b3, 0x6d79, 0x752e, 0x752f,
+ 0x6ed0, 0x6ed5, 0x6ede, 0x6ee2, 0x1f74, 0x6eea, 0x6eef, 0xb124,
+ 0x6f01, 0x0e20, 0x0ca5, 0x0f9d, 0x20f2, 0x0a7e, 0xdfeb, 0x6f42,
+ 0x6f48, 0x1dd6, 0x64e4, 0xcd62, 0x6f57, 0x81bd, 0x6f79, 0x285f,
+ 0x284a, 0x6f85, 0x6a78, 0xe18b, 0x68b2, 0x55ff, 0x6fa2, 0x6fa9,
+ 0x4c5c, 0x6fce, 0x4396, 0x1dfe, 0xb5b5, 0xb5fb, 0x42f7, 0xb638,
+ 0xb108, 0xb691, 0x451e, 0xdf9a, 0x94ba, 0x4b1f, 0xdd3e, 0xe0b6,
+ 0x6429, 0x64b3, 0xde04, 0x63ac, 0x6441, 0x648b, 0xdd2c, 0xb279,
+ 0x4397, 0x116b, 0x48f2, 0x4bc3, 0x4250, 0x756d, 0xb1b8, 0x42fe,
+ 0x7570, 0x4223, 0x947e, 0xa7d9, 0x1147, 0x9445, 0xbc2f, 0x93b8,
+ 0x09e2, 0x92bb, 0x757a, 0x09a1, 0x9334, 0x757d, 0xc34b, 0x09e3,
+ 0x9280, 0x291b, 0xb665, 0x90be, 0x7584,
+ /* 0x92 */
+ 0x9086, 0x9136, 0x5683, 0xa8e6, 0x81bd, 0x55d5, 0x758b, 0xd125,
+ 0xac31, 0xbc9c, 0xacbb, 0xd012, 0x1774, 0xa92e, 0xe55d, 0xcee6,
+ 0x39b9, 0x09f3, 0x0ed5, 0x1067, 0x2a2c, 0x759a, 0x39d0, 0x12d7,
+ 0xa97f, 0x759e, 0xae4b, 0x75a0, 0xcc21, 0x268b, 0x285e, 0xc831,
+ 0x2852, 0x75a6, 0x89a8, 0x8b8d, 0x6486, 0x75aa, 0x645c, 0x20b8,
+ 0x22eb, 0x0ad9, 0xb1f6, 0x207c, 0x85a5, 0x84bf, 0x210b, 0x214a,
+ 0xbd91, 0x2c28, 0x82eb, 0x850b, 0x0c59, 0x844a, 0x8554, 0x06f5,
+ 0x20e9, 0x8400, 0xe133, 0x83b5, 0x5c1a, 0x75c2, 0x2058, 0x228d,
+ 0x22cd, 0x2162, 0x20c3, 0x75c8, 0xac4a, 0x2102, 0x21ee, 0x222c,
+ 0x2241, 0x218c, 0x21a5, 0x2218, 0x22bc, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x3ff6, 0xa7d5, 0x75d8, 0xac7f, 0x3f32, 0x9444, 0xac49,
+ 0x2368, 0x2383, 0x86e0, 0x175d, 0x85e3, 0x85d2, 0x85d1, 0x5e7a,
+ 0xde5c, 0x874e, 0x2419, 0x2464, 0x8833, 0x24a1, 0x81bd, 0x18fa,
+ 0x430c, 0xb14c, 0x8a20, 0xb5ec, 0x75f1, 0x3b91, 0x8b9d, 0x81bd,
+ 0x115e, 0x4619, 0x4594, 0x45d6, 0x4518, 0x1dce, 0xb6fc, 0xae4d,
+ 0x2590, 0x0844, 0x438f, 0xae89, 0x2774, 0x8485, 0x268d, 0x89c6,
+ 0x28dd, 0x631d, 0x67b4, 0x6426, 0x299d, 0x294d, 0x293f, 0x08fe,
+ 0x2a8b, 0x2c59, 0xde06, 0x92ba, 0x932f, 0x92d0, 0x2bec, 0x2b78,
+ 0x634f, 0x2c3e, 0x2c8f, 0x2bd2, 0x7619, 0x95b3, 0x9421, 0x761c,
+ 0x09b5, 0x3ec5, 0x45c3, 0x2be1, 0xc2c3,
+ /* 0x93 */
+ 0x2c41, 0xdf97, 0x8553, 0x64a0, 0x460c, 0x9003, 0x4285, 0x1bf2,
+ 0x64c8, 0xddbb, 0x647d, 0x0a60, 0x2dde, 0x2e5e, 0x301e, 0x3008,
+ 0x9556, 0x953c, 0xaa6e, 0x308d, 0x2d0f, 0x94c3, 0x94c4, 0x09c1,
+ 0x9460, 0x099d, 0x92be, 0x0993, 0x52aa, 0xde07, 0x96fa, 0xa6f2,
+ 0xdd68, 0x30cc, 0x30ce, 0x94e7, 0x7646, 0x2c2b, 0x92fb, 0x2d04,
+ 0x5754, 0xd2bd, 0x59a0, 0x323e, 0x9e60, 0x9c6b, 0x319b, 0x1138,
+ 0x9c2f, 0x9c3e, 0x7654, 0xcf33, 0x3380, 0x81fe, 0x8206, 0x9c5b,
+ 0x3359, 0x3358, 0x3235, 0xa15b, 0xa1c7, 0xb414, 0x7660, 0x3631,
+ 0xb3a5, 0xa06a, 0x0ce9, 0xa022, 0xa6d0, 0xe4aa, 0xa2f8, 0x34f7,
+ 0x766a, 0x3676, 0x34f1, 0x3591, 0xb623, 0xa227, 0x3464, 0xa161,
+ 0x35fb, 0x372b, 0x3b32, 0x0eb4, 0xa38e, 0xa56d, 0xb5c9, 0xa56b,
+ 0x26cd, 0xa5a0, 0x9499, 0x767d, 0x388e, 0xa549, 0x7680, 0x0da0,
+ 0x1410, 0xbcc4, 0xdee2, 0xbccf, 0x92bc, 0xbc9b, 0xbc25, 0x4a6e,
+ 0xa403, 0x93ea, 0xa4f4, 0x0724, 0x768e, 0xa442, 0xb089, 0x384e,
+ 0xcd24, 0x382b, 0x1dd3, 0x37f0, 0xd470, 0x7697, 0x3823, 0xa592,
+ 0xa5a1, 0x37de, 0xbf32, 0x0b91, 0x769e, 0xa9fc, 0x0e59, 0xa9e2,
+ 0xa67e, 0x4650, 0x0e56, 0x394f, 0xb36a, 0x3a76, 0x39de, 0x0e84,
+ 0x3c7e, 0x0b23, 0xaa15, 0xb247, 0x3bf3, 0x3c12, 0x3c89, 0x3cc5,
+ 0x94d2, 0x36d1, 0x3a58, 0x3c0c, 0x0e97, 0x3c3a, 0x3d17, 0xad80,
+ 0xaada, 0x6460, 0x63b2, 0xdfaa, 0xde8b,
+ /* 0x94 */
+ 0x6349, 0x76c0, 0xdd9c, 0x6527, 0x3f65, 0x408b, 0x76c5, 0x81bd,
+ 0xad3f, 0x100f, 0x3f84, 0xadfc, 0x2bfd, 0x3f8a, 0x2a07, 0x3ee4,
+ 0x49c2, 0x42bb, 0xb0da, 0xb036, 0x4271, 0x43d0, 0x4407, 0x4414,
+ 0xb48f, 0xb465, 0x2339, 0xb6e4, 0x86eb, 0x45fa, 0xacb8, 0x76de,
+ 0x76df, 0xb557, 0xc3a1, 0x1186, 0x1131, 0xb71f, 0xdfe3, 0xacf5,
+ 0x3267, 0x1173, 0x464c, 0x45bc, 0x6447, 0x45b7, 0x171f, 0xcdaa,
+ 0x17d1, 0x4703, 0x11e3, 0xb859, 0xb886, 0x11d8, 0x46d5, 0x47f3,
+ 0xea86, 0x0dd9, 0x45e8, 0xde8c, 0xb5eb, 0xb5ce, 0x0dbb, 0x104d,
+ 0xb68e, 0x117f, 0x7701, 0xb533, 0x62ba, 0x28f2, 0x6402, 0xdea3,
+ 0x9424, 0x229f, 0xbb61, 0xbb27, 0x48f8, 0xa4f2, 0x488e, 0x488f,
+ 0x48fb, 0xb3d7, 0xa9c1, 0x0d1e, 0x7713, 0x45b8, 0x461b, 0x113f,
+ 0xb6fa, 0xb707, 0x1348, 0xb6d6, 0xc52e, 0x63c7, 0xbcc1, 0x499e,
+ 0x4a0d, 0x4a08, 0x4a52, 0x4550, 0x4ad9, 0xd3c1, 0x7725, 0x138e,
+ 0x81bd, 0x5616, 0x4b25, 0x3bed, 0xacba, 0x4bba, 0x4b74, 0x13ee,
+ 0x92a6, 0x13b2, 0x62f5, 0x4b71, 0x8b0c, 0xb5cc, 0x83d9, 0xabba,
+ 0x932e, 0x0857, 0x272b, 0x0830, 0x096a, 0x8314, 0x773d, 0x4c62,
+ 0x2c19, 0x9d35, 0x7741, 0xc01c, 0x2bcd, 0x839b, 0x4a70, 0x2bea,
+ 0xc106, 0x4c7e, 0x1479, 0x4ddd, 0x4ded, 0x1491, 0xc0f3, 0xc2fc,
+ 0xc2e6, 0x4e4d, 0xb639, 0x7752, 0x4e0e, 0x4dfc, 0x4e2e, 0x3c72,
+ 0x4f5c, 0x4f87, 0x4f53, 0x50ce, 0xc5a1,
+ /* 0x95 */
+ 0xc4dc, 0x775d, 0x4f17, 0xc2c2, 0x14ea, 0x7761, 0x8856, 0x3996,
+ 0x820e, 0xa80f, 0x2984, 0xc692, 0x7768, 0xb5a2, 0x515d, 0x4ca7,
+ 0x87ec, 0xc069, 0xc243, 0x4c8c, 0xc28e, 0x6aa6, 0x5785, 0x6b23,
+ 0x3bdc, 0x7775, 0x0ca2, 0xb637, 0xc7ad, 0x6adf, 0x777a, 0x5600,
+ 0xd0e7, 0x777d, 0x176a, 0x52b7, 0x1682, 0x5246, 0x5289, 0x52c2,
+ 0xc8f4, 0x6983, 0xcac2, 0x53e2, 0x53e5, 0xcad1, 0x55d3, 0xcd67,
+ 0x5750, 0xd15b, 0x2c46, 0x13ff, 0x7790, 0x2ceb, 0x9461, 0x2ca4,
+ 0x9498, 0x57e0, 0x5868, 0x7797, 0x596d, 0xd222, 0x2bc2, 0x59ae,
+ 0x2105, 0x59c7, 0x59ff, 0x5a26, 0x5aa5, 0x5a8d, 0xbdc3, 0x5a94,
+ 0xd405, 0xd404, 0x77a6, 0xdf99, 0xdf5c, 0xddb9, 0x112d, 0x5623,
+ 0x1975, 0x194f, 0x0ab2, 0x5b7d, 0x5b5c, 0xe308, 0x310d, 0x62eb,
+ 0x77b4, 0x3794, 0x42a9, 0x4244, 0x9405, 0x6dad, 0x5d9f, 0x5de9,
+ 0xd79c, 0x2b5a, 0x4943, 0x2bb0, 0x15ee, 0x0994, 0x5f2a, 0x5fa7,
+ 0xb7c9, 0x6030, 0x604a, 0x1574, 0x3e18, 0x413b, 0x9aa1, 0x1b1b,
+ 0x40f9, 0x400b, 0x939a, 0x6ca9, 0x0975, 0xb56f, 0x61bb, 0x81bd,
+ 0x2731, 0x1b86, 0x627b, 0x64c4, 0xde0b, 0x12e2, 0x77da, 0x64e7,
+ 0xdfdd, 0x77dd, 0x5665, 0x5b6b, 0x6659, 0x6667, 0x6657, 0x6656,
+ 0xe074, 0x45c5, 0x1142, 0xb53f, 0x77e8, 0x77e9, 0x1167, 0xa4e5,
+ 0x674f, 0x77ed, 0xe0e6, 0xe0e5, 0x114c, 0x77f1, 0xb6b8, 0xadae,
+ 0x4592, 0x45eb, 0x117c, 0x6801, 0xe1b0,
+ /* 0x96 */
+ 0x3a07, 0x1c9d, 0x77fb, 0x77fc, 0x81bd, 0x6428, 0xdd49, 0x7800,
+ 0xdeef, 0xc67e, 0x637a, 0x2cd1, 0x5ca9, 0x1bbc, 0x4579, 0xafdb,
+ 0x685b, 0x6831, 0x69f8, 0x780c, 0x2f81, 0xdf85, 0xb6f2, 0x68df,
+ 0xe35a, 0x63b6, 0x7813, 0x62a5, 0x1740, 0xdf10, 0xb6a7, 0xdf24,
+ 0x699c, 0xde05, 0x1180, 0x62ea, 0x1ba5, 0x5594, 0x69fb, 0x6a0d,
+ 0x7821, 0x107d, 0x6a5b, 0x1daf, 0x6a6a, 0x6b1c, 0xdf25, 0x7828,
+ 0x3c4f, 0x6ae1, 0x2cbe, 0x6aef, 0x782d, 0x1dd0, 0x782f, 0x6a7c,
+ 0x1dfd, 0x1dd7, 0x643d, 0x2a32, 0x9002, 0x29e2, 0xb5f8, 0x9168,
+ 0x49c4, 0x9d5f, 0xabb8, 0x3a85, 0x0ffd, 0x6518, 0x0be7, 0x3310,
+ 0x9dc1, 0x9f6b, 0x32c7, 0x6d0f, 0x6d13, 0x6d3b, 0x6cf5, 0x6cd0,
+ 0x6c3f, 0x6c8f, 0xe6ed, 0x6c5f, 0x784d, 0xe87e, 0x6d61, 0x1eee,
+ 0xaec4, 0x6e58, 0x1ef0, 0x6d4c, 0x7855, 0x7856, 0xe873, 0xe4ef,
+ 0x6de5, 0x563d, 0x785b, 0xcf9f, 0x785d, 0x573c, 0x17b3, 0xcd64,
+ 0xce44, 0xcdb0, 0x55a0, 0x572e, 0x7865, 0xaa17, 0xc424, 0x4b62,
+ 0xa7dc, 0xa880, 0x1bad, 0xb61e, 0x0fe2, 0x649b, 0x637e, 0x6408,
+ 0x83ff, 0x4a39, 0x6337, 0x650d, 0x21a4, 0x0700, 0x6164, 0xbc9d,
+ 0x49bd, 0x49d4, 0x4a36, 0x49cb, 0x9317, 0xa489, 0xb581, 0x095a,
+ 0x2132, 0x415a, 0x4159, 0x81bd, 0x419e, 0x25d4, 0x7887, 0x297b,
+ 0x2ab3, 0x294a, 0x6d56, 0x2997, 0x42b4, 0x076f, 0x788f, 0x436b,
+ 0x7891, 0xba17, 0x81bd, 0x9375, 0xde09,
+ /* 0x97 */
+ 0x32cc, 0x2c8e, 0x2bcb, 0x153c, 0xb248, 0x09ec, 0x1dbb, 0xddbc,
+ 0x647b, 0x6478, 0x9496, 0x78a1, 0x55f2, 0xccc0, 0x78a4, 0xb0ba,
+ 0xa0e6, 0xb181, 0x2b54, 0xabb7, 0xc881, 0x4f28, 0xc4db, 0xc464,
+ 0xb5f9, 0xb5cb, 0xddba, 0x63a5, 0x4562, 0x1169, 0x4634, 0xdf23,
+ 0x945f, 0x1161, 0xb6f3, 0x3c98, 0x4573, 0x457b, 0x1156, 0xb67e,
+ 0xb6d4, 0x9399, 0xb6a6, 0x84e7, 0x78c2, 0x78c3, 0x45c8, 0xb556,
+ 0x4225, 0xb5b6, 0x6344, 0x4566, 0x641f, 0x863e, 0x63f1, 0x78cd,
+ 0xddd6, 0x6446, 0xdfa7, 0xbd15, 0x1bb5, 0xde42, 0x42eb, 0x78d5,
+ 0x78d6, 0x2864, 0x871a, 0x78d9, 0x78da, 0x26c2, 0x4b44, 0x93ba,
+ 0x4f7e, 0x9282, 0xb690, 0x78e1, 0x17ae, 0x64c1, 0x09ca, 0x78e5,
+ 0xb5ed, 0x2b70, 0x947f, 0x9443, 0xd244, 0x2c61, 0x09a2, 0xab5b,
+ 0x0970, 0x631f, 0x2c39, 0xde41, 0x9422, 0x6434, 0x0f4d, 0x8974,
+ 0x1cd6, 0x0c4a, 0x22b4, 0x0fe9, 0x0fcc, 0x905c, 0x42f5, 0x157b,
+ 0x78fe, 0x3f8f, 0xe1e4, 0x176b, 0x3f17, 0xd7cf, 0x41e7, 0x3e6f,
+ 0x0f56, 0xadad, 0xac2d, 0x3f82, 0x408c, 0x0fef, 0x8535, 0x46d1,
+ 0x097c, 0x0788, 0x1900, 0x115a, 0x1af1, 0x2b84, 0x632e, 0x1bbe,
+ 0x6041, 0x7917, 0x7918, 0x29d2, 0x2988, 0x0996, 0x90d2, 0x427e,
+ 0xb122, 0x791f, 0xa323, 0x8fb0, 0x9afd, 0x3a79, 0x3b27, 0x7925,
+ 0xa725, 0xd674, 0xa91f, 0xde43, 0xaa16, 0x792b, 0xb81f, 0x3bda,
+ 0xa8ed, 0xccb7, 0x55be, 0x175f, 0x174e,
+ /* 0x98 */
+ 0xcd26, 0x7934, 0xcc82, 0xcf9e, 0x4097, 0xd0c9, 0x54bd, 0x92fa,
+ 0x556d, 0xcc80, 0xd013, 0x939b, 0x2b49, 0x2c42, 0x9373, 0x2c21,
+ 0x2c31, 0x94c5, 0xafbc, 0x09ed, 0x2baf, 0x92fc, 0x0987, 0x430e,
+ 0x6450, 0x385a, 0xb065, 0x2c2e, 0x2beb, 0x7950, 0x3beb, 0xacb9,
+ 0xd3b6, 0xb21b, 0xb08a, 0x429d, 0xb019, 0xdda1, 0x2170, 0xcd28,
+ 0x2e82, 0xb28e, 0xd7cd, 0xb17d, 0x3bcc, 0xb016, 0x9004, 0x4226,
+ 0x42b3, 0xb1a9, 0x1025, 0x3e9f, 0x7967, 0xb68f, 0x4fe5, 0x2bab,
+ 0x2eef, 0x1073, 0x311c, 0x796e, 0x796f, 0x4f24, 0x55a6, 0x2645,
+ 0x7973, 0xa5c0, 0x8354, 0x293e, 0x7977, 0x8719, 0x1265, 0x797a,
+ 0x797b, 0x4183, 0x797d, 0x2f30, 0x450f, 0x4e53, 0xde19, 0x7982,
+ 0x2188, 0x5167, 0x444d, 0x4490, 0xd5f4, 0x44b8, 0x44b9, 0xbe36,
+ 0x44c1, 0x44c8, 0x1129, 0xd618, 0x616c, 0x4375, 0x7991, 0x4561,
+ 0x5376, 0x114a, 0x488c, 0x1151, 0x3e62, 0x28bd, 0x4599, 0x459e,
+ 0x459f, 0x1162, 0x1170, 0x1174, 0x117a, 0x4653, 0x118e, 0x11d3,
+ 0x46c2, 0x46ed, 0x46f2, 0x470d, 0x11fc, 0x4748, 0x475c, 0x1240,
+ 0x47cd, 0x1257, 0x47f4, 0x125c, 0x47fa, 0xb9dc, 0x4308, 0x27e3,
+ 0x5ac0, 0x2a29, 0x129d, 0x48c3, 0x12b9, 0x3921, 0x12c5, 0x089b,
+ 0x4918, 0x12ea, 0x12ef, 0x2e1e, 0x493e, 0x494b, 0x2ab2, 0x4998,
+ 0x4239, 0x499c, 0x1328, 0x49b9, 0x49c7, 0x49d1, 0x49e6, 0x55c8,
+ 0x79cb, 0x4ab3, 0x39c3, 0x4ab2, 0x1383,
+ /* 0x99 */
+ 0x1389, 0x4b11, 0x4b19, 0x60bb, 0x4b86, 0x60bc, 0x13e7, 0x4c11,
+ 0x1432, 0x4c3c, 0x53f9, 0x1444, 0x4c4f, 0x4c5b, 0x144f, 0x1fe1,
+ 0x4ce2, 0x4cec, 0x4cfb, 0x4d92, 0x4d9b, 0x14e0, 0x14fa, 0x4dfb,
+ 0x4e1c, 0x150c, 0x4e38, 0x1514, 0x4e6d, 0x6093, 0x4240, 0x8acf,
+ 0x4f4f, 0x4f54, 0x4f50, 0x4f7d, 0x512e, 0x5134, 0x441f, 0x1617,
+ 0x51a0, 0x51a5, 0x4cb9, 0x51ae, 0x51b1, 0x51d4, 0x104c, 0x2974,
+ 0x4220, 0x5237, 0x5269, 0x166d, 0x528c, 0x44aa, 0x528e, 0x5292,
+ 0x46e0, 0x5294, 0x1681, 0x0df9, 0x52d6, 0x52d9, 0x52da, 0x1693,
+ 0x29fa, 0x52fc, 0x5304, 0x16a5, 0x5313, 0x16ad, 0x5325, 0x29af,
+ 0x5341, 0x5364, 0x53d4, 0x170f, 0x5426, 0x53f6, 0x544a, 0x5458,
+ 0x547f, 0x1730, 0x54d7, 0x6729, 0x3b4a, 0x5585, 0x4275, 0x55e4,
+ 0x32a3, 0x5608, 0x1784, 0x563e, 0x5661, 0x5678, 0x5690, 0x56b8,
+ 0x56d2, 0x17bb, 0x56ef, 0x56f0, 0x5720, 0x17f7, 0x57b2, 0x57d2,
+ 0x57f2, 0x582f, 0x6705, 0x58cb, 0x1886, 0x1897, 0x59ee, 0x5a3f,
+ 0x5a64, 0x5a87, 0x5ad1, 0xd4e7, 0x5b69, 0x5b78, 0x5bd4, 0x5bf4,
+ 0x5d51, 0x5dd4, 0x5df2, 0x5e1c, 0x1a18, 0x2a1f, 0x5ec3, 0x1a6d,
+ 0x20ae, 0x5f3a, 0x2798, 0x2914, 0x5f71, 0x27b5, 0x5fb0, 0x1ab7,
+ 0x5fce, 0x5fe2, 0x5fe4, 0x5fed, 0x5ff2, 0x60b7, 0x60c1, 0x60ca,
+ 0x60cc, 0x6133, 0x6a84, 0x1b2d, 0x69a0, 0x62d3, 0x1b9e, 0x62e8,
+ 0x6318, 0x632b, 0x6371, 0x636e, 0x637f,
+ /* 0x9a */
+ 0x63a3, 0x63ab, 0x63b3, 0x63b4, 0x63bd, 0x6403, 0x6444, 0x646d,
+ 0x1bc5, 0x1bd1, 0x6eff, 0x64d7, 0x24c1, 0x64dd, 0x64ed, 0x64fe,
+ 0x1bea, 0x6514, 0x6539, 0x65ed, 0x6662, 0x1c27, 0x66b4, 0x66f3,
+ 0x1c65, 0x3960, 0x1ca4, 0x6800, 0x1cb5, 0x6872, 0x6882, 0x2814,
+ 0x1d24, 0x32a8, 0x6979, 0x1d59, 0x69b1, 0x2a04, 0x69ce, 0x69d9,
+ 0x2374, 0x69dc, 0x69f7, 0x6a02, 0x6a1d, 0x6a22, 0x1db0, 0x6a85,
+ 0x1ddd, 0x6afc, 0x6bcf, 0x4c03, 0x6c29, 0x6c41, 0x6c9d, 0x6cb1,
+ 0x6cb4, 0x1ead, 0x6ce0, 0x0a2f, 0x7a29, 0x6d89, 0x6cfa, 0x6f3e,
+ 0x2810, 0x6dd3, 0x6dfd, 0x6e00, 0x6e3c, 0x65b6, 0x60b6, 0x6ebb,
+ 0x6eec, 0x6ef1, 0x6efd, 0x6f06, 0x659c, 0x6f22, 0x6f31, 0x6f38,
+ 0x4c48, 0x6f84, 0x7a3f, 0x7a40, 0x7a41, 0x3ada, 0x6583, 0x2b6c,
+ 0x7a45, 0x2a00, 0x6581, 0x0a79, 0x7a49, 0x7a4a, 0x7a4b, 0x7a4c,
+ 0x2917, 0x42f3, 0x7a4f, 0x7a50, 0x7a51, 0x262a, 0x7a53, 0x7a54,
+ 0x265e, 0x7a56, 0x7a57, 0x8a53, 0x7a59, 0x7a5a, 0x32a7, 0x7a5c,
+ 0x283a, 0x7a5e, 0x7a5f, 0x7a60, 0x7a61, 0x7a62, 0x7a63, 0x3b15,
+ 0x6cef, 0x58e5, 0x7a67, 0x8b8e, 0x7a69, 0x7a6a, 0x8cad, 0x7a6c,
+ 0x2de0, 0x7a6e, 0x2fcb, 0x7a70, 0x7a71, 0x8db6, 0x38de, 0x8dbb,
+ 0x7a75, 0x7a76, 0x0907, 0x7a78, 0x7a79, 0x7a7a, 0x7a7b, 0x2524,
+ 0x562d, 0x8fe3, 0x7a7f, 0x7a80, 0x5cc1, 0x7a82, 0x7a83, 0x7a84,
+ 0x7a85, 0x2038, 0x423b, 0x7a88, 0x7a89,
+ /* 0x9b */
+ 0x7a8a, 0x7a8b, 0x7a8c, 0x7a8d, 0x7a8e, 0x7a8f, 0x3483, 0x97d5,
+ 0x7a92, 0x4318, 0x3a15, 0x7a95, 0x3ba9, 0x0988, 0x9a7c, 0x7a99,
+ 0x7a9a, 0x7a9b, 0x7a9c, 0x7a9d, 0x547d, 0x7a9f, 0x7aa0, 0x9fd5,
+ 0x5ae5, 0x7aa3, 0x60a0, 0x7aa5, 0x6878, 0x7aa7, 0x6907, 0x6b7d,
+ 0x7aaa, 0x81bd, 0x7aac, 0x7aad, 0x7aae, 0xa1c8, 0x7ab0, 0x7ab1,
+ 0x7ab2, 0x7ab3, 0x7ab4, 0x7ab5, 0x7ab6, 0x7ab7, 0x7ab8, 0x7ab9,
+ 0x3171, 0x3808, 0x387f, 0x7abd, 0x7abe, 0x7abf, 0x81bd, 0xb5fa,
+ 0x81bd, 0x7ac3, 0x7ac4, 0x81bd, 0x8486, 0x2a75, 0x38ce, 0x3ad8,
+ 0x7aca, 0xd317, 0xc3a2, 0x7acd, 0x7ace, 0xd2be, 0x98da, 0x1b50,
+ 0x1cf8, 0x7ad3, 0xde5a, 0x7ad5, 0x7ad6, 0xadfb, 0x7ad8, 0xb156,
+ 0x7ada, 0x7adb, 0x2392, 0x8711, 0x2b5f, 0x97a8, 0x0e7e, 0xab3f,
+ 0x7ae2, 0x7ae3, 0x2948, 0x7ae5, 0x0c5b, 0x7ae7, 0x7ae8, 0x7ae9,
+ 0x0a22, 0x9a03, 0x5c9e, 0xdf0e, 0x81bd, 0x7aef, 0x7af0, 0x7af1,
+ 0x4389, 0x7af3, 0x8a78, 0x2b25, 0x7af6, 0x7af7, 0x87b9, 0x5fda,
+ 0x7afa, 0x244f, 0x28ff, 0x42f1, 0x7afe, 0x7aff, 0x7b00, 0xb6e7,
+ 0x277c, 0x7b03, 0xbc6e, 0xcb52, 0x81bd, 0x0733, 0x7b08, 0xd2f2,
+ 0x7b0a, 0x1998, 0x7b0c, 0xbca6, 0xbec7, 0xb57f, 0x7b10, 0x2226,
+ 0x07bb, 0x7b13, 0x81bd, 0x7b15, 0x19fc, 0xdd08, 0xc02e, 0x7b19,
+ 0xc146, 0x7b1b, 0x2961, 0x42d1, 0x81bd, 0x7b1f, 0xd692, 0x6156,
+ 0x7b22, 0xba1a, 0x5ca2, 0x7b25, 0x7b26,
+ /* 0x9c */
+ 0x2f1b, 0xcbf7, 0x81bd, 0x7b2a, 0x7b2b, 0x5c2a, 0xb636, 0x7b2e,
+ 0xadaf, 0xc712, 0x1e00, 0x7b32, 0x7b33, 0x9d5b, 0x6525, 0xbee1,
+ 0x3355, 0x2be7, 0xeb8d, 0x81bd, 0x2879, 0xb2e1, 0x7b3d, 0x202a,
+ 0x7b3f, 0x6716, 0x3f4f, 0xccbd, 0x08d8, 0x5ab7, 0x7b45, 0xc96e,
+ 0xc691, 0xc95e, 0x81bd, 0x7b4a, 0x4cc2, 0x7b4c, 0x88d1, 0x7b4e,
+ 0x81bd, 0x7b50, 0x4bc5, 0x81bd, 0xca7a, 0x6ae6, 0x7b55, 0x091f,
+ 0x7b57, 0x7b58, 0x4b03, 0x7b5a, 0x7b5b, 0x2eec, 0x7b5d, 0x81bd,
+ 0x7b5f, 0x1950, 0x7b61, 0x46bb, 0x59a5, 0x7b64, 0x2a76, 0x09dc,
+ 0x9c0d, 0x7b68, 0x7b69, 0x0f14, 0x7b6b, 0x7b6c, 0x6341, 0x99ba,
+ 0x7b6f, 0x63f0, 0xd1a6, 0x7b72, 0x3df9, 0x655f, 0x7b75, 0x8c78,
+ 0x5967, 0x5a35, 0x7b79, 0x7b7a, 0x9371, 0x4038, 0xb66a, 0x7b7e,
+ 0x0c64, 0x0979, 0x81bd, 0x81bd, 0x17bf, 0x3876, 0xe62d, 0xe464,
+ 0x5a83, 0x7b88, 0x7b89, 0x2896, 0x135f, 0x91ca, 0x0c61, 0xa96f,
+ 0x7b8f, 0x9085, 0x432d, 0x54e6, 0x7b93, 0xe268, 0x81bd, 0x1ef7,
+ 0xd06f, 0xdd6b, 0x7b99, 0x7b9a, 0x7b9b, 0x7b9c, 0xaf3a, 0x4cc3,
+ 0x4afe, 0xd809, 0x4135, 0xea1f, 0x3bc3, 0x7ba4, 0x2562, 0x7ba6,
+ 0x647f, 0x39f6, 0x681d, 0xd92f, 0x7bab, 0xca35, 0x90ad, 0xa4ef,
+ 0x7baf, 0x2f45, 0xdff0, 0x7bb2, 0x28d5, 0x68e3, 0xdd09, 0x2f6b,
+ 0xb5c8, 0x377e, 0x3b95, 0x2592, 0xb6e5, 0xad41, 0x0ed1, 0x38f6,
+ 0x7bbf, 0xd8b4, 0xd8ee, 0x9861, 0x7bc3,
+ /* 0x9d */
+ 0x7bc4, 0x7bc5, 0x7bc6, 0x7bc7, 0x7bc8, 0x7bc9, 0x088a, 0x7bcb,
+ 0xdc2a, 0x1b7a, 0x35a6, 0x7bcf, 0x4988, 0x6315, 0x7bd2, 0x1672,
+ 0x7bd4, 0x165f, 0x7bd6, 0x7bd7, 0x7bd8, 0x2bb8, 0x7bda, 0x81bd,
+ 0x7bdc, 0x7bdd, 0x81bd, 0xe210, 0x7be0, 0x1077, 0x7be2, 0x7be3,
+ 0x60d0, 0x440f, 0x284b, 0x7be7, 0xe3e9, 0x7be9, 0x7bea, 0x7beb,
+ 0x7bec, 0x7bed, 0xe52a, 0x7bef, 0x7bf0, 0xe58e, 0x7bf2, 0x7bf3,
+ 0x501f, 0x7bf5, 0xe7e3, 0x1ee4, 0x6607, 0x7bf9, 0x4322, 0x7bfb,
+ 0x1f91, 0x6112, 0x7bfe, 0x1f9c, 0x8a9c, 0x60be, 0x2781, 0x60ba,
+ 0x7c04, 0x60b9, 0xb6d3, 0x1789, 0x4fff, 0x40d6, 0x3c71, 0x20aa,
+ 0x07a4, 0xdeec, 0x7c0e, 0x09fa, 0x5f80, 0x93b5, 0x7c12, 0xdf2c,
+ 0xdf59, 0x7c15, 0xc82f, 0x106b, 0xd315, 0xaaf7, 0xbd75, 0xbf96,
+ 0x205a, 0xc2c1, 0xc598, 0x287f, 0x8bed, 0x5f0e, 0x2d2d, 0xac48,
+ 0xb81e, 0x359e, 0x81bd, 0x93b6, 0x943b, 0x36f0, 0x27ed, 0xc18a,
+ 0x25da, 0xbbd1, 0x1046, 0x7c2f, 0x1ebd, 0x27e2, 0x27de, 0x50c9,
+ 0xc318, 0x2b35, 0x7c36, 0x58b0, 0x1fdc, 0x8d2a, 0x8b09, 0xa8fa,
+ 0x5297, 0x6d9e, 0x5e18, 0x47bb, 0x6d05, 0x47ce, 0x4939, 0x6405,
+ 0x25f2, 0x52c8, 0x5477, 0x27e5, 0x52b2, 0x5598, 0x523d, 0x27aa,
+ 0x4ae2, 0x2803, 0x25d6, 0x7c4f, 0x088e, 0x27c5, 0x27b1, 0x38b1,
+ 0xd9e2, 0x08ed, 0x46b4, 0x27b0, 0x277a, 0x2657, 0x2732, 0x8a41,
+ 0x7c5c, 0x3090, 0xbac8, 0x8bf6, 0x7c60,
+ /* 0x9e */
+ 0x7c61, 0x6eeb, 0x4eda, 0x279e, 0x8db5, 0x345d, 0x682d, 0x2654,
+ 0x5dcd, 0x4376, 0x6236, 0x35bc, 0x3579, 0x35be, 0x2729, 0x7c70,
+ 0x6d32, 0x7c72, 0x235a, 0x079f, 0x8b67, 0x2367, 0x260d, 0x26de,
+ 0x26d3, 0x47e6, 0x5f2d, 0x7c7c, 0x4731, 0x5236, 0x5944, 0x58c6,
+ 0x5a07, 0x5336, 0x559c, 0x8e01, 0x176c, 0x4484, 0xb446, 0x2d50,
+ 0x548b, 0xc993, 0x283b, 0x9d34, 0xd6ef, 0xaf63, 0xd733, 0xce90,
+ 0x7c91, 0x6230, 0x8f19, 0x62c8, 0xab3c, 0xeae9, 0x8c2c, 0x8c79,
+ 0x43e6, 0x9662, 0x19ce, 0xba42, 0x7c9d, 0x8d2b, 0x137a, 0x6d1d,
+ 0x36df, 0xa260, 0x1b73, 0x7ca4, 0xe6bc, 0x8d2c, 0x8b8a, 0x81bd,
+ 0x7ca9, 0x8d2d, 0x81bd, 0x7cac, 0x8ec7, 0x4323, 0x500e, 0x6d90,
+ 0x1fda, 0x1fc4, 0x0837, 0x2ccd, 0x3e72, 0x2527, 0x096c, 0x0c9c,
+ 0x253d, 0x0965, 0x7cbb, 0x2a5a, 0xb76e, 0x53ad, 0x260b, 0x296a,
+ 0x7cc1, 0x88b9, 0x81bd, 0x0d12, 0x9b65, 0x44f4, 0xe76c, 0x1f49,
+ 0x6cad, 0xab3e, 0xe7f0, 0x1e9b, 0xba29, 0xe39e, 0x7ccf, 0x55dc,
+ 0xabb6, 0x7cd2, 0xc8f3, 0xa960, 0x34ee, 0x4ea5, 0xacb7, 0xac2c,
+ 0x0cea, 0x6108, 0x248c, 0x10f4, 0x093a, 0x1869, 0x7cdf, 0x47c0,
+ 0x2cb0, 0x8c36, 0x49fa, 0x1a36, 0x2a67, 0x133f, 0x283c, 0x6c4b,
+ 0x2f34, 0x47d4, 0x7ceb, 0x6ec5, 0x1f21, 0x81bd, 0x0abb, 0x32d9,
+ 0xa3da, 0xb1b2, 0x81bd, 0x281d, 0x8fa9, 0x2967, 0xb5a3, 0x7cf8,
+ 0x23f4, 0xd06e, 0x086d, 0x81bd, 0x6dbc,
+ /* 0x9f */
+ 0x4dd6, 0x6bf9, 0x299e, 0x932c, 0x2e13, 0x3693, 0x7d04, 0x7d05,
+ 0xd124, 0x57ed, 0x7d08, 0xcd22, 0xb722, 0x7d0b, 0x81bd, 0x23be,
+ 0x7d0e, 0x2f4e, 0x67c3, 0x9711, 0x6ec1, 0x614c, 0x4c9f, 0x6bc2,
+ 0x2e91, 0x4d23, 0x3428, 0x34f5, 0x6bbf, 0x4d4f, 0x6bea, 0x4dfe,
+ 0x81bd, 0x4dc2, 0x4e06, 0x6cd5, 0x4d7c, 0x6bc9, 0x81bd, 0x6cdb,
+ 0xb57e, 0x6f9a, 0x2733, 0x2d83, 0x21bd, 0x6ed8, 0x21b2, 0x2420,
+ 0x1086, 0x2491, 0x2927, 0x2216, 0x2b77, 0x2fd2, 0x6888, 0x6deb,
+ 0x605c, 0x2629, 0x6874, 0x6a00, 0x687a, 0x24ec, 0x32f0, 0x3aec,
+ 0x259a, 0x6cca, 0x6d42, 0x1e7b, 0x6701, 0x3b40, 0x2266, 0x46c6,
+ 0x932d, 0x6a9a, 0x2433, 0x81bd, 0x6219, 0x6741, 0x621c, 0x81bd,
+ 0x6211, 0x7d4f, 0x353f, 0xcd23, 0x3c8a, 0x27d1, 0x624e, 0x46fa,
+ 0x3445, 0x853c, 0x44cf, 0x4df0, 0x7d5a, 0xab3d, 0x81bd, 0xb559,
+ 0x4856, 0x6c5d, 0x1fea, 0x8ad4, 0x553e, 0x5982, 0x81bd, 0x2e0a,
+ 0x3b80, 0x81bd, 0x293a, 0x23df, 0x2fb5, 0x208e, 0x3df1, 0x7d6d,
+ 0x20f9, 0x265c, 0x269a, 0x245a, 0x5e82, 0x08be, 0x81bd, 0x08b3,
+ 0x81bd, 0x3d12, 0x623c, 0x6fe5, 0x6c57, 0x68ee, 0x6974, 0x6b7a,
+ 0x6ee8, 0x6ec4, 0x42fa, 0x4c94, 0x81bd, 0x3dba, 0x5958, 0x50f8,
+ 0x81bd, 0x27e0, 0x7d88, 0x5f77, 0x6f93, 0x81bd, 0x5ed4, 0x5f4f,
+ 0x6e5c, 0x5f01, 0x3442, 0xda7d, 0x5f28, 0x5f75, 0x4c53, 0xb6b7,
+ 0x4bbe, 0x4a58, 0x3eaa, 0x5ba7, 0x4787,
+ /* 0xa0 */
+ 0xde1a, 0x6f66, 0x3e8e, 0x5916, 0x4743, 0xe9f2, 0x49d3, 0xeb00,
+ 0x5e0c, 0x4462, 0x44f1, 0x5c6d, 0x4482, 0x4671, 0x5deb, 0xb6fb,
+ 0x576f, 0x317a, 0x59e0, 0x1737, 0x81bd, 0x93fb, 0xcdc5, 0x81bd,
+ 0x5bbe, 0x9bdb, 0x81bd, 0x32bd, 0x47e7, 0x6b97, 0x6d84, 0x642e,
+ 0x6c4f, 0x5935, 0x81bd, 0x81bd, 0x5df7, 0x44ac, 0x67e1, 0x6c70,
+ 0x0896, 0x4432, 0x1e47, 0x4dd1, 0x6a0a, 0xc4d9, 0x3319, 0x1e44,
+ 0x6ed6, 0x333d, 0x81bd, 0x291f, 0x332f, 0x3466, 0x33f9, 0x81bd,
+ 0x0d1c, 0x33a2, 0x256a, 0xa675, 0x3524, 0x39c2, 0x0892, 0x2f17,
+ 0xdf82, 0x60da, 0x7ddd, 0x81bd, 0x2299, 0x9686, 0x4a86, 0x24f2,
+ 0x66f8, 0x8cbb, 0x12e5, 0x81bd, 0x497e, 0x81bd, 0x4e42, 0x7dea,
+ 0x4e5a, 0x4bad, 0x51e6, 0x51e3, 0x4ecd, 0x4685, 0x4672, 0x5ad4,
+ 0x539a, 0x38cc, 0x51e2, 0xd246, 0x51db, 0x4670, 0x5283, 0x48a4,
+ 0x5ac9, 0xc90c, 0x46d3, 0xce91, 0x58e9, 0x590e, 0x5348, 0x58cc,
+ 0x5b89, 0x5dad, 0x5c83, 0x48ab, 0x4678, 0x565a, 0x08f5, 0x3b72,
+ 0x5ea6, 0x81bd, 0x5ae9, 0x81bd, 0x3f79, 0x5901, 0xadd1, 0x4667,
+ 0x105b, 0x42f6, 0x3264, 0x335c, 0x0f51, 0x81bd, 0x3237, 0x81bd,
+ 0x50f1, 0xdeed, 0x81bd, 0x32a9, 0x1dbe, 0x23e0, 0x0ed8, 0xab07,
+ 0xc317, 0xd316, 0x7e25, 0x9504, 0x8ffe, 0xe4c3, 0xcd9c, 0xd06d,
+ 0x2e81, 0xc52d, 0xddcf, 0xa8b7, 0x826e, 0x7e30, 0xb98e, 0x17e2,
+ 0x2cdf, 0x7e34, 0x6f90, 0x6ee6, 0x7e37,
+};
+static const unsigned short hkscs_2uni_pagec6[471] = {
+ /* 0xc6 */
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x0420,
+ 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
+ 0x0429, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a,
+ 0x043b, 0x043c, 0x043d, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x1ff6, 0x1fff, 0x2045,
+ 0x2060, 0x2342, 0x2356, 0x236b, 0x24b9, 0x24f8, 0x2529, 0x2576,
+ 0x2aca, 0x2d40, 0x2f9b, 0x0573, 0x303f, 0x81bd, 0x3110, 0x3121,
+ 0x36f4, 0x81bd, 0x4712, 0x81bd, 0x60b5, 0x81bd, 0x0028, 0x01c6,
+ 0x067d, 0x067e, 0x061d, 0x061e, 0x81bd, 0x81bd, 0x0585, 0x0586,
+ 0x0587, 0x067c, 0x817b, 0x817d, 0x04bd, 0x05c1, 0x05c2, 0x05c3,
+ 0x05c4, 0x05c5, 0x05c6, 0x05c7, 0x05c8, 0x05c9, 0x05ca, 0x05cb,
+ 0x05cc, 0x05cd, 0x05ce, 0x05cf, 0x05d0, 0x05d1, 0x05d2, 0x05d3,
+ 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8,
+ /* 0xc7 */
+ 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 0x05e0,
+ 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8,
+ 0x05e9, 0x05ea, 0x05eb, 0x05ec, 0x05ed, 0x05ee, 0x05ef, 0x05f0,
+ 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x05f5, 0x05f6, 0x05f7, 0x05f8,
+ 0x05f9, 0x05fa, 0x05fb, 0x05fc, 0x05fd, 0x05fe, 0x05ff, 0x0600,
+ 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607, 0x0608,
+ 0x0609, 0x060a, 0x060b, 0x060c, 0x060d, 0x060e, 0x060f, 0x0610,
+ 0x0611, 0x0612, 0x0613, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625,
+ 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d,
+ 0x062e, 0x062f, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
+ 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x063b, 0x063c, 0x063d,
+ 0x063e, 0x063f, 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645,
+ 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d,
+ 0x064e, 0x064f, 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655,
+ 0x0656, 0x0657, 0x0658, 0x0659, 0x065a, 0x065b, 0x065c, 0x065d,
+ 0x065e, 0x065f, 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665,
+ 0x0666, 0x0667, 0x0668, 0x0669, 0x066a, 0x066b, 0x066c, 0x066d,
+ 0x066e, 0x066f, 0x0670, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675,
+ 0x0676, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0201,
+ 0x0216, 0x0217, 0x0218, 0x0219, 0x021a,
+ /* 0xc8 */
+ 0x021b, 0x021c, 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222,
+ 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a,
+ 0x022b, 0x022c, 0x022d, 0x022e, 0x022f, 0x0230, 0x0231, 0x0232,
+ 0x0233, 0x0234, 0x0235, 0x0251, 0x0236, 0x0237, 0x0238, 0x0239,
+ 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f, 0x0240, 0x0241,
+ 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249,
+ 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, 0x03e7, 0x03b8,
+ 0x03b9, 0x8125, 0x8126, 0x201a, 0x8128, 0x23c2, 0x812a, 0x812b,
+ 0x2348, 0x812d, 0x812e, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81a2, 0x81a4, 0x8147, 0x8142, 0x06b1,
+ 0x0316, 0x0321, 0x061b, 0x061c, 0x04c0, 0x04c4, 0x04c6, 0x04c7,
+ 0x04c8, 0x04ca, 0x04cc, 0x04cd, 0x04d5, 0x04dc, 0x04dd, 0x04e5,
+ 0x04e7, 0x04ea, 0x04ec, 0x04ee, 0x04f6, 0x04fc, 0x04fe, 0x0506,
+ 0x050a, 0x050c, 0x050d, 0x050f, 0x0516, 0x0517, 0x051e, 0x0523,
+ 0x81bd, 0x81bd, 0x81bd, 0x0183, 0x0150, 0x015b, 0x0154, 0x0175,
+ 0x00d3, 0x0078, 0x00cb, 0x018a, 0x016a,
+};
+static const unsigned short hkscs_2uni_pagef9[942] = {
+ /* 0xf9 */
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x81bd,
+ 0x81bd, 0x81bd, 0x81bd, 0x81bd, 0x4a01, 0x6379, 0x5a0f, 0x2a7b,
+ 0x3212, 0x4e27, 0x2cba, 0x0454, 0x0466, 0x0457, 0x0460, 0x046c,
+ 0x0463, 0x045a, 0x0469, 0x045d, 0x0452, 0x0464, 0x0455, 0x045e,
+ 0x046a, 0x0461, 0x0458, 0x0467, 0x045b, 0x0453, 0x0465, 0x0456,
+ 0x045f, 0x046b, 0x0462, 0x0459, 0x0468, 0x045c, 0x0451, 0x0450,
+ 0x046d, 0x046e, 0x0470, 0x046f, 0x81ad,
+ /* 0xfa */
+ 0x8647, 0x639b, 0x86df, 0x7003, 0x56cc, 0x1535, 0x456f, 0x2375,
+ 0x0909, 0xb582, 0xdda4, 0x6404, 0x959b, 0x546e, 0xab08, 0x49bc,
+ 0x3904, 0x349f, 0xb573, 0xdd6a, 0x83e0, 0xcbb3, 0x9005, 0x216b,
+ 0x7018, 0x21c8, 0xcd29, 0x701b, 0xa840, 0xb6f1, 0x9bd3, 0x81bd,
+ 0x84be, 0x3164, 0x84c0, 0x8487, 0x405b, 0x855f, 0x81bd, 0x22c1,
+ 0x073a, 0x22ce, 0x692c, 0x0a03, 0x5596, 0x702d, 0x85c7, 0x2320,
+ 0xa634, 0x232a, 0x89ff, 0x993c, 0x8425, 0x9bf0, 0x868e, 0xa4f3,
+ 0x7038, 0x2d42, 0x58bd, 0x86b3, 0xaad9, 0x2372, 0x2378, 0x6d74,
+ 0x2389, 0x238f, 0x2391, 0x0f5c, 0x2393, 0xb6e6, 0x2373, 0x23a2,
+ 0x2502, 0x23ad, 0x554d, 0x3afe, 0x704c, 0x313b, 0x23cb, 0x23e6,
+ 0x23fc, 0x2475, 0x2417, 0x2454, 0x2479, 0x2485, 0x4d95, 0x56c2,
+ 0x24a0, 0x574d, 0x705a, 0x81bd, 0xde9e, 0x2709, 0x4059, 0xad40,
+ 0x8894, 0xadac, 0x24f3, 0x81bd, 0x89e2, 0x3e8b, 0x92e6, 0x39db,
+ 0x4555, 0x320a, 0x112a, 0x0b8c, 0x92a8, 0x435d, 0x1722, 0x252d,
+ 0x2534, 0xdc2b, 0x253e, 0x81bd, 0x9196, 0x91d3, 0x4966, 0x2553,
+ 0xde5b, 0x2560, 0x256b, 0x256e, 0x4527, 0xbeb2, 0x11d9, 0x451c,
+ 0x2581, 0x2585, 0x3e09, 0x2009, 0x29be, 0x2599, 0x0d6b, 0x898f,
+ 0x25a0, 0xadab, 0xa263, 0x25b6, 0x8a77, 0x25d3, 0x41f9, 0x26eb,
+ 0x3817, 0x3f1b, 0x262d, 0xcb53, 0x7094, 0x271d, 0x264f, 0x2664,
+ 0x1a26, 0x7099, 0x709a, 0x1034, 0x8b0d,
+ /* 0xfb */
+ 0xdd7c, 0x9cd8, 0x2707, 0x1f2d, 0x25ef, 0x4597, 0x2746, 0x2769,
+ 0x81bd, 0x9497, 0xadfa, 0x17d2, 0xb1f5, 0x3873, 0x8df4, 0x27f7,
+ 0x388d, 0xa54a, 0x3864, 0x386d, 0x280d, 0x280f, 0x4a71, 0x28b1,
+ 0x6847, 0x25be, 0x28c0, 0x28af, 0x28ad, 0xdf26, 0x08e3, 0x8f4f,
+ 0x2906, 0xaf65, 0x3e2e, 0x420b, 0x2902, 0x0971, 0xcc7e, 0x29a6,
+ 0x70c5, 0x29c3, 0x90d4, 0xb123, 0x29e6, 0xb7b5, 0x2a1c, 0x2a6a,
+ 0x0821, 0x2aa0, 0x2a9c, 0x70d0, 0x2abb, 0x2dbf, 0x2903, 0xe8d0,
+ 0xb038, 0x6493, 0x0861, 0x2adf, 0x3a66, 0x0983, 0x3fd9, 0x91fe,
+ 0x2be4, 0x2713, 0x9252, 0x5685, 0x2b89, 0x8b0e, 0xcc81, 0xcd2a,
+ 0x939c, 0x2b99, 0x93bb, 0x9372, 0xcd66, 0x3f31, 0x93e8, 0x9295,
+ 0x2bb9, 0xce05, 0x2c6b, 0x2c23, 0x09a6, 0x70f2, 0x81bd, 0x09c8,
+ 0x2c56, 0x45e5, 0x2c93, 0xcf61, 0x70f9, 0x1005, 0x94d1, 0x09f2,
+ 0x70fd, 0x3043, 0x2490, 0x2d36, 0x3748, 0x2d3c, 0xd50e, 0x1284,
+ 0x1add, 0x7106, 0x2d95, 0x3320, 0x7109, 0x710a, 0x86a5, 0x2db3,
+ 0x2d5d, 0x1f50, 0x2dc5, 0x9604, 0x2dd3, 0x454e, 0x2dd4, 0x9665,
+ 0xcb28, 0x2e09, 0x1b5d, 0x2e45, 0x2ea9, 0x2eaf, 0x2f4b, 0x9739,
+ 0x9777, 0x2ed0, 0x2ed8, 0x2f06, 0x97a4, 0x2e7a, 0x2f97, 0x547c,
+ 0x0aed, 0xb541, 0x9889, 0x99b3, 0x5407, 0x0af6, 0x0e82, 0x2fee,
+ 0x3c4a, 0x81bd, 0x303a, 0x7130, 0x8ad3, 0x2566, 0x2077, 0x81bd,
+ 0x2568, 0x9331, 0x2fc9, 0x30b4, 0xdac2,
+ /* 0xfc */
+ 0x30b9, 0x30bb, 0x0b60, 0x30bc, 0x39fe, 0x64db, 0x30cd, 0x8301,
+ 0xeb54, 0x0d9e, 0x1b2e, 0x903a, 0x30fa, 0xc988, 0x9b10, 0x81bd,
+ 0x9b71, 0x3123, 0x687d, 0xce2e, 0x3132, 0x6400, 0x7150, 0x3167,
+ 0x2f76, 0x0fdf, 0x7154, 0x982a, 0xd0b8, 0x9ca8, 0x6296, 0x83de,
+ 0xdde9, 0x31f1, 0x3845, 0x715d, 0x0c23, 0x1047, 0x08f9, 0x2950,
+ 0x9df4, 0x4af1, 0x10c0, 0x325e, 0x81bd, 0x3273, 0x7168, 0xb5cf,
+ 0x716a, 0x4624, 0x22a1, 0x2c60, 0x3324, 0x55a4, 0x3302, 0x7171,
+ 0xce92, 0x3341, 0x23b4, 0x7175, 0x3347, 0x2d6a, 0xad77, 0x9e5f,
+ 0x3393, 0xdf5d, 0xe51d, 0x3390, 0x0bf2, 0x9f80, 0x9ec1, 0x31e3,
+ 0x331c, 0x36de, 0x354b, 0x8298, 0x3485, 0x9330, 0x3495, 0xa28d,
+ 0x352c, 0xb61f, 0x0cd7, 0x35f8, 0x35b8, 0x718f, 0x93bc, 0x81bd,
+ 0x410a, 0xa2b6, 0x68d4, 0xae4c, 0xbe5d, 0x36a1, 0x36a5, 0x653b,
+ 0x0d26, 0x35fa, 0x0d17, 0x370d, 0x4096, 0xb668, 0xb663, 0x3745,
+ 0x372d, 0x371f, 0xa37e, 0x3775, 0xb580, 0x1d77, 0x3791, 0x1358,
+ 0x93e9, 0x37a0, 0x37a3, 0x319f, 0xa680, 0x37d8, 0xa4b7, 0xa4b8,
+ 0x3804, 0xa464, 0xa465, 0x380b, 0x8bf5, 0x3827, 0xbb26, 0x3833,
+ 0x81bd, 0x71bb, 0xa4f1, 0xdbb4, 0xa488, 0xbbd3, 0x4945, 0x9ef7,
+ 0x6a64, 0x38c2, 0xb15c, 0xb661, 0x0deb, 0x3bba, 0xaa02, 0x81bd,
+ 0x3927, 0x3922, 0x71cc, 0x71cd, 0x3997, 0x1769, 0x39e2, 0x3fd0,
+ 0x62fc, 0x39c1, 0xa666, 0xcd60, 0x3a1d,
+ /* 0xfd */
+ 0x71d7, 0x3ba1, 0x3bcb, 0xde9f, 0x3b33, 0x3a83, 0xa80d, 0x3ac1,
+ 0x3ac0, 0x0fb2, 0x0cc1, 0xa87c, 0x0e40, 0x396c, 0x3b21, 0xde0a,
+ 0x157c, 0x3af6, 0x3b58, 0x0e61, 0x8509, 0x54e3, 0x2250, 0x3bb9,
+ 0x71ef, 0x996a, 0x3c05, 0x71f2, 0x3c5d, 0x0eb3, 0x3971, 0x3c88,
+ 0xe25c, 0x0ecd, 0x3cdd, 0x71fa, 0x329e, 0x3cf5, 0x3d34, 0x71fe,
+ 0x4035, 0xaa5b, 0x84f5, 0x7202, 0x0a00, 0x25e1, 0xaa9a, 0x3da1,
+ 0xacbc, 0x3d9c, 0x3df7, 0x9b8b, 0x720b, 0xcb51, 0x3e1a, 0x53a6,
+ 0x3e39, 0xabbc, 0x1745, 0xabbd, 0xaf64, 0xb54c, 0xb540, 0xab09,
+ 0x09a5, 0x0f6b, 0x7219, 0x6c43, 0xa4b9, 0x721c, 0x510f, 0x39f7,
+ 0xcd25, 0xcd61, 0xcdab, 0x3f56, 0x3f1c, 0x3ffc, 0x4084, 0xb5bf,
+ 0x7227, 0xce32, 0x56b3, 0xcf34, 0x2387, 0x81bd, 0x81bd, 0x55ae,
+ 0xdee1, 0x81bd, 0xac2f, 0x45d3, 0xad42, 0x4b4c, 0x3fcf, 0x2c51,
+ 0xa34b, 0x4178, 0x09cd, 0x411d, 0xac30, 0x407a, 0x9117, 0xadfd,
+ 0x17d5, 0x64b0, 0x40c4, 0x40dc, 0x0fce, 0x40f4, 0x7245, 0x0fbb,
+ 0x411f, 0xaf04, 0x4153, 0x724a, 0xaf15, 0xadf9, 0xc220, 0x724e,
+ 0xaeff, 0x239f, 0xaf16, 0xaf17, 0xaf00, 0xc55d, 0x41cb, 0x41fe,
+ 0x4227, 0x4201, 0x424c, 0x4255, 0x4256, 0x425f, 0x1384, 0x1068,
+ 0x4334, 0x4316, 0xb037, 0x42ab, 0x42c5, 0x2c48, 0x42ca, 0x81bd,
+ 0x2e5c, 0xb125, 0x42cf, 0x6422, 0x726b, 0x42ac, 0xb21a, 0xb667,
+ 0xb662, 0x433a, 0xdfa8, 0x423d, 0x438e,
+ /* 0xfe */
+ 0x6502, 0x4395, 0x2ad1, 0x6503, 0x43a4, 0x6401, 0x727a, 0x43ae,
+ 0x43c0, 0xb5b4, 0x3a7d, 0x43d5, 0x43d7, 0x10d5, 0x7282, 0x39cd,
+ 0x40bd, 0x4402, 0x81bd, 0x44ab, 0xb4e3, 0xdcab, 0x1b6d, 0xdc84,
+ 0x44a8, 0x44ae, 0x454f, 0x452a, 0x7290, 0xcaae, 0x4549, 0x45c9,
+ 0xafa2, 0x92a7, 0xb664, 0x37e3, 0x0985, 0xb5f7, 0xb5cd, 0x729b,
+ 0x4577, 0x4595, 0x3ac3, 0xb666, 0x45b9, 0x72a1, 0x1157, 0x81bd,
+ 0x9ead, 0x45e0, 0xe132, 0x45c7, 0x4564, 0x45f6, 0x5539, 0x45ec,
+ 0x09f0, 0x45f4, 0x64b1, 0x3bec, 0x4602, 0x1bd3, 0x72b2, 0xaf1f,
+ 0xb6b9, 0xdf4f, 0x2d06, 0x72b7, 0x945e, 0x4648, 0x9548, 0x468e,
+ 0x81bd, 0x469e, 0xe159, 0x95cb, 0x2d97, 0x72c1, 0x6445, 0x46cd,
+ 0x46ca, 0x46e7, 0x46ee, 0xba02, 0x1184, 0x72c9, 0x470e, 0x45dd,
+ 0x471e, 0x4734, 0x4782, 0x47ac, 0x47d1, 0x47cf, 0x47ef, 0x47f6,
+ 0x72d4, 0x4810, 0x536f, 0x0ab8, 0xc9d1, 0xc9ce, 0x4821, 0x4825,
+ 0x4837, 0x484c, 0xcf5f, 0x55e2, 0xba9d, 0xbafd, 0x72e2, 0x489e,
+ 0x48a6, 0x48c0, 0x366f, 0xbb60, 0x48d8, 0xa56c, 0x492f, 0x72eb,
+ 0x72ec, 0x9281, 0x4974, 0x81bd, 0x72f0, 0x72f1, 0x3a8a, 0x4a2f,
+ 0x4a47, 0x4a53, 0x6765, 0x4aae, 0xbd20, 0x4a57, 0x4ab4, 0x4a31,
+ 0xd2cc, 0x60b8, 0x59c4, 0xdeeb, 0x7300, 0x9c5c, 0x4b06, 0x5a40,
+ 0x3ac2, 0x4b00, 0xbf17, 0x4b1d, 0xd639, 0x4abc, 0x4b29, 0x3faa,
+ 0xd0e6, 0x1128, 0x4b46, 0xe20d, 0x4b54,
+};
+
+static const ucs4_t hkscs_2uni_upages[945] = {
+ 0x00080, 0x000c0, 0x00100, 0x00140, 0x001c0, 0x00240, 0x00280, 0x002c0,
+ 0x00400, 0x00440, 0x01e80, 0x01ec0, 0x02100, 0x02140, 0x02180, 0x021c0,
+ 0x02440, 0x02540, 0x02700, 0x02e80, 0x02ec0, 0x02f00, 0x03000, 0x03040,
+ 0x03080, 0x030c0, 0x03200, 0x03400, 0x03440, 0x03480, 0x034c0, 0x03500,
+ 0x03540, 0x03580, 0x035c0, 0x03600, 0x03640, 0x03680, 0x036c0, 0x03700,
+ 0x03740, 0x03780, 0x037c0, 0x03800, 0x03840, 0x03880, 0x038c0, 0x03900,
+ 0x03940, 0x03980, 0x039c0, 0x03a00, 0x03a40, 0x03a80, 0x03ac0, 0x03b00,
+ 0x03b40, 0x03b80, 0x03bc0, 0x03c00, 0x03c40, 0x03cc0, 0x03d00, 0x03d40,
+ 0x03d80, 0x03dc0, 0x03e00, 0x03e40, 0x03e80, 0x03ec0, 0x03f00, 0x03f40,
+ 0x03f80, 0x03fc0, 0x04000, 0x04040, 0x04080, 0x040c0, 0x04100, 0x04140,
+ 0x04180, 0x041c0, 0x04200, 0x04240, 0x04280, 0x042c0, 0x04300, 0x04340,
+ 0x04380, 0x043c0, 0x04400, 0x04440, 0x04480, 0x044c0, 0x04500, 0x04540,
+ 0x04580, 0x045c0, 0x04600, 0x04640, 0x04680, 0x046c0, 0x04700, 0x04740,
+ 0x04780, 0x047c0, 0x04800, 0x04840, 0x04880, 0x048c0, 0x04900, 0x04940,
+ 0x04980, 0x049c0, 0x04a00, 0x04a80, 0x04ac0, 0x04b00, 0x04b40, 0x04b80,
+ 0x04bc0, 0x04c00, 0x04c40, 0x04c80, 0x04cc0, 0x04d00, 0x04d80, 0x04e00,
+ 0x04e40, 0x04e80, 0x04ec0, 0x04f00, 0x04f40, 0x04f80, 0x04fc0, 0x05000,
+ 0x05040, 0x05080, 0x050c0, 0x05100, 0x05140, 0x05180, 0x051c0, 0x05200,
+ 0x05240, 0x05280, 0x052c0, 0x05300, 0x05340, 0x05380, 0x053c0, 0x05400,
+ 0x05440, 0x05480, 0x054c0, 0x05500, 0x05540, 0x05580, 0x055c0, 0x05600,
+ 0x05640, 0x05680, 0x056c0, 0x05700, 0x05740, 0x05780, 0x057c0, 0x05800,
+ 0x05840, 0x05880, 0x058c0, 0x05900, 0x05940, 0x05980, 0x059c0, 0x05a00,
+ 0x05a40, 0x05a80, 0x05ac0, 0x05b00, 0x05b40, 0x05b80, 0x05bc0, 0x05c00,
+ 0x05c40, 0x05c80, 0x05cc0, 0x05d00, 0x05d40, 0x05d80, 0x05dc0, 0x05e00,
+ 0x05e40, 0x05e80, 0x05ec0, 0x05f00, 0x05f40, 0x05f80, 0x05fc0, 0x06000,
+ 0x06040, 0x06080, 0x060c0, 0x06100, 0x06140, 0x06180, 0x061c0, 0x06200,
+ 0x06240, 0x06280, 0x062c0, 0x06300, 0x06340, 0x06380, 0x063c0, 0x06400,
+ 0x06440, 0x06480, 0x064c0, 0x06500, 0x06540, 0x06580, 0x065c0, 0x06600,
+ 0x06640, 0x06680, 0x066c0, 0x06700, 0x06740, 0x06780, 0x067c0, 0x06800,
+ 0x06840, 0x06880, 0x068c0, 0x06900, 0x06940, 0x06980, 0x069c0, 0x06a00,
+ 0x06a40, 0x06a80, 0x06ac0, 0x06b00, 0x06b40, 0x06b80, 0x06bc0, 0x06c00,
+ 0x06c40, 0x06c80, 0x06cc0, 0x06d00, 0x06d40, 0x06d80, 0x06e00, 0x06e40,
+ 0x06e80, 0x06ec0, 0x06f00, 0x06f40, 0x06f80, 0x06fc0, 0x07000, 0x07040,
+ 0x07080, 0x070c0, 0x07100, 0x07140, 0x07180, 0x071c0, 0x07200, 0x07240,
+ 0x07280, 0x072c0, 0x07300, 0x07340, 0x07380, 0x073c0, 0x07400, 0x07440,
+ 0x07480, 0x074c0, 0x07500, 0x07540, 0x07580, 0x075c0, 0x07600, 0x07640,
+ 0x07680, 0x076c0, 0x07700, 0x07740, 0x07780, 0x077c0, 0x07800, 0x07840,
+ 0x07880, 0x078c0, 0x07900, 0x07940, 0x07980, 0x079c0, 0x07a00, 0x07a40,
+ 0x07a80, 0x07ac0, 0x07b00, 0x07b40, 0x07b80, 0x07bc0, 0x07c00, 0x07c40,
+ 0x07c80, 0x07cc0, 0x07d00, 0x07d40, 0x07d80, 0x07dc0, 0x07e00, 0x07e40,
+ 0x07e80, 0x07ec0, 0x07f00, 0x07f40, 0x07f80, 0x07fc0, 0x08000, 0x08040,
+ 0x08080, 0x080c0, 0x08100, 0x08140, 0x08180, 0x081c0, 0x08200, 0x08240,
+ 0x08280, 0x082c0, 0x08300, 0x08340, 0x08380, 0x083c0, 0x08400, 0x08440,
+ 0x08480, 0x084c0, 0x08500, 0x08540, 0x085c0, 0x08600, 0x08640, 0x08680,
+ 0x086c0, 0x08700, 0x08740, 0x08780, 0x087c0, 0x08800, 0x08840, 0x08880,
+ 0x088c0, 0x08900, 0x08940, 0x08980, 0x089c0, 0x08a00, 0x08a40, 0x08a80,
+ 0x08ac0, 0x08b00, 0x08b40, 0x08b80, 0x08bc0, 0x08c40, 0x08c80, 0x08cc0,
+ 0x08d00, 0x08d40, 0x08d80, 0x08dc0, 0x08e00, 0x08e40, 0x08e80, 0x08ec0,
+ 0x08f00, 0x08f40, 0x08f80, 0x08fc0, 0x09000, 0x09040, 0x09080, 0x090c0,
+ 0x09140, 0x09180, 0x091c0, 0x09200, 0x09240, 0x09280, 0x092c0, 0x09300,
+ 0x09340, 0x09380, 0x093c0, 0x09400, 0x09440, 0x09480, 0x094c0, 0x09500,
+ 0x09540, 0x09580, 0x095c0, 0x09600, 0x09640, 0x09680, 0x096c0, 0x09700,
+ 0x09740, 0x09780, 0x097c0, 0x09800, 0x09840, 0x09880, 0x098c0, 0x09900,
+ 0x09940, 0x09980, 0x099c0, 0x09a00, 0x09a40, 0x09a80, 0x09ac0, 0x09b00,
+ 0x09b40, 0x09b80, 0x09bc0, 0x09c00, 0x09c40, 0x09d00, 0x09d40, 0x09d80,
+ 0x09dc0, 0x09e00, 0x09e40, 0x09e80, 0x09ec0, 0x09f00, 0x09f40, 0x09f80,
+ 0x0e000, 0x0e040, 0x0e080, 0x0e0c0, 0x0e100, 0x0e140, 0x0e180, 0x0e1c0,
+ 0x0e200, 0x0e240, 0x0e280, 0x0e2c0, 0x0e300, 0x0e340, 0x0e380, 0x0e3c0,
+ 0x0e400, 0x0e440, 0x0e480, 0x0e4c0, 0x0e500, 0x0e540, 0x0e580, 0x0e5c0,
+ 0x0e600, 0x0e640, 0x0e680, 0x0e6c0, 0x0e700, 0x0e740, 0x0e780, 0x0e7c0,
+ 0x0e800, 0x0e840, 0x0e880, 0x0e8c0, 0x0e900, 0x0e940, 0x0e980, 0x0e9c0,
+ 0x0ea80, 0x0eac0, 0x0eb00, 0x0eb40, 0x0eb80, 0x0ebc0, 0x0ec00, 0x0ec40,
+ 0x0ec80, 0x0ecc0, 0x0ed00, 0x0ed40, 0x0ed80, 0x0edc0, 0x0ee00, 0x0ee40,
+ 0x0ee80, 0x0f300, 0x0f340, 0x0f380, 0x0f3c0, 0x0f400, 0x0f440, 0x0f480,
+ 0x0f4c0, 0x0f500, 0x0f540, 0x0f680, 0x0f7c0, 0x0ff00, 0x0ffc0, 0x20000,
+ 0x20040, 0x200c0, 0x20100, 0x20180, 0x201c0, 0x20200, 0x20240, 0x20280,
+ 0x202c0, 0x20300, 0x20340, 0x20380, 0x203c0, 0x20400, 0x20440, 0x20480,
+ 0x204c0, 0x20540, 0x20580, 0x205c0, 0x20600, 0x20700, 0x20740, 0x20800,
+ 0x20840, 0x20900, 0x20940, 0x20a00, 0x20a40, 0x20a80, 0x20b80, 0x20bc0,
+ 0x20c00, 0x20c40, 0x20c80, 0x20cc0, 0x20d40, 0x20d80, 0x20e00, 0x20e40,
+ 0x20e80, 0x20ec0, 0x20f00, 0x20f80, 0x20fc0, 0x21000, 0x21040, 0x21080,
+ 0x210c0, 0x21100, 0x21140, 0x21180, 0x211c0, 0x21240, 0x21280, 0x212c0,
+ 0x21300, 0x21380, 0x213c0, 0x21440, 0x21480, 0x214c0, 0x21580, 0x21600,
+ 0x21640, 0x21680, 0x216c0, 0x21700, 0x21740, 0x21780, 0x217c0, 0x21800,
+ 0x21840, 0x21880, 0x218c0, 0x21900, 0x21940, 0x21980, 0x219c0, 0x21a40,
+ 0x21b40, 0x21c80, 0x21d40, 0x21d80, 0x21dc0, 0x21e00, 0x21e80, 0x21ec0,
+ 0x21f40, 0x21f80, 0x22040, 0x22080, 0x220c0, 0x22100, 0x22140, 0x22180,
+ 0x221c0, 0x22240, 0x22300, 0x22380, 0x223c0, 0x22440, 0x22480, 0x22500,
+ 0x22580, 0x22600, 0x22640, 0x22680, 0x226c0, 0x22700, 0x22740, 0x22780,
+ 0x22800, 0x22840, 0x22880, 0x228c0, 0x22900, 0x22940, 0x22980, 0x22ac0,
+ 0x22b00, 0x22b40, 0x22bc0, 0x22c00, 0x22c40, 0x22c80, 0x22cc0, 0x22d00,
+ 0x22d40, 0x22d80, 0x22e00, 0x22e40, 0x22fc0, 0x23040, 0x23080, 0x230c0,
+ 0x23100, 0x23180, 0x231c0, 0x23200, 0x23240, 0x23280, 0x232c0, 0x23300,
+ 0x23380, 0x233c0, 0x23400, 0x23440, 0x234c0, 0x23500, 0x23540, 0x23580,
+ 0x235c0, 0x23600, 0x23640, 0x23680, 0x236c0, 0x23700, 0x23740, 0x23780,
+ 0x237c0, 0x23ac0, 0x23b40, 0x23c80, 0x23cc0, 0x23d40, 0x23d80, 0x23dc0,
+ 0x23e00, 0x23e80, 0x23ec0, 0x23f00, 0x23f40, 0x23f80, 0x23fc0, 0x24000,
+ 0x24040, 0x24080, 0x240c0, 0x24100, 0x24140, 0x24180, 0x241c0, 0x24200,
+ 0x24240, 0x24280, 0x242c0, 0x24300, 0x24340, 0x24380, 0x243c0, 0x24400,
+ 0x24440, 0x24480, 0x244c0, 0x24500, 0x24540, 0x24600, 0x24640, 0x24680,
+ 0x246c0, 0x24700, 0x24780, 0x24800, 0x248c0, 0x24900, 0x24940, 0x24980,
+ 0x249c0, 0x24a00, 0x24a40, 0x24a80, 0x24ac0, 0x24b40, 0x24bc0, 0x24c00,
+ 0x24c80, 0x24cc0, 0x24d00, 0x24d80, 0x24dc0, 0x24e40, 0x24f00, 0x24f40,
+ 0x24f80, 0x24fc0, 0x25080, 0x25140, 0x251c0, 0x25200, 0x252c0, 0x25300,
+ 0x25400, 0x25440, 0x25540, 0x25580, 0x255c0, 0x25600, 0x25640, 0x25680,
+ 0x256c0, 0x25700, 0x25740, 0x257c0, 0x25840, 0x258c0, 0x25940, 0x25980,
+ 0x25a80, 0x25ac0, 0x25b40, 0x25b80, 0x25bc0, 0x25c00, 0x25c40, 0x25cc0,
+ 0x25d00, 0x25d40, 0x25e00, 0x25e80, 0x25ec0, 0x25f40, 0x25fc0, 0x26000,
+ 0x26040, 0x26080, 0x26100, 0x26140, 0x26180, 0x261c0, 0x26240, 0x262c0,
+ 0x26340, 0x26380, 0x26400, 0x26480, 0x26500, 0x26540, 0x26580, 0x26600,
+ 0x26680, 0x266c0, 0x26740, 0x26780, 0x267c0, 0x26840, 0x26880, 0x26900,
+ 0x26980, 0x269c0, 0x26a00, 0x26a40, 0x26b00, 0x26b40, 0x26b80, 0x26bc0,
+ 0x26c00, 0x26c40, 0x26c80, 0x26cc0, 0x26d00, 0x26d80, 0x26dc0, 0x26e00,
+ 0x26e40, 0x26e80, 0x26ec0, 0x26f00, 0x26f40, 0x26f80, 0x26fc0, 0x27000,
+ 0x27040, 0x27080, 0x270c0, 0x27100, 0x27140, 0x27200, 0x272c0, 0x27380,
+ 0x27400, 0x27480, 0x275c0, 0x27600, 0x27640, 0x27680, 0x27700, 0x27740,
+ 0x27780, 0x27840, 0x27900, 0x27940, 0x27a00, 0x27a40, 0x27a80, 0x27ac0,
+ 0x27b00, 0x27bc0, 0x27c00, 0x27d00, 0x27d40, 0x27d80, 0x27dc0, 0x27e40,
+ 0x28000, 0x28080, 0x280c0, 0x28100, 0x28140, 0x28200, 0x28240, 0x282c0,
+ 0x28300, 0x28340, 0x28400, 0x28480, 0x28500, 0x28540, 0x285c0, 0x28600,
+ 0x28680, 0x286c0, 0x28800, 0x28900, 0x28940, 0x28980, 0x289c0, 0x28a00,
+ 0x28a40, 0x28a80, 0x28ac0, 0x28b00, 0x28b40, 0x28b80, 0x28bc0, 0x28c00,
+ 0x28cc0, 0x28d00, 0x28e00, 0x28e40, 0x28e80, 0x28ec0, 0x29080, 0x290c0,
+ 0x29100, 0x29180, 0x291c0, 0x29400, 0x29440, 0x294c0, 0x29580, 0x295c0,
+ 0x29840, 0x29880, 0x298c0, 0x29900, 0x29940, 0x29980, 0x29b00, 0x29bc0,
+ 0x29c80, 0x29d00, 0x29d40, 0x29e00, 0x29e40, 0x29e80, 0x29ec0, 0x29f00,
+ 0x29f80, 0x2a0c0, 0x2a100, 0x2a140, 0x2a180, 0x2a1c0, 0x2a200, 0x2a280,
+ 0x2a2c0, 0x2a380, 0x2a5c0, 0x2a680, 0x2f840, 0x2f880, 0x2f8c0, 0x2f980,
+ 0x2f9c0,
+};
+
+/* SJIS table */
+static const unsigned short jisx0213_to_ucs_combining[][2] = {
+ {0x304b, 0x309a},
+ {0x304d, 0x309a},
+ {0x304f, 0x309a},
+ {0x3051, 0x309a},
+ {0x3053, 0x309a},
+ {0x30ab, 0x309a},
+ {0x30ad, 0x309a},
+ {0x30af, 0x309a},
+ {0x30b1, 0x309a},
+ {0x30b3, 0x309a},
+ {0x30bb, 0x309a},
+ {0x30c4, 0x309a},
+ {0x30c8, 0x309a},
+ {0x31f7, 0x309a},
+ {0x00e6, 0x0300},
+ {0x0254, 0x0300},
+ {0x0254, 0x0301},
+ {0x028c, 0x0300},
+ {0x028c, 0x0301},
+ {0x0259, 0x0300},
+ {0x0259, 0x0301},
+ {0x025a, 0x0300},
+ {0x025a, 0x0301},
+ {0x02e9, 0x02e5},
+ {0x02e5, 0x02e9},
+};
+
+static const unsigned short jisx0213_to_ucs_main[120 * 94] = {
+ /* 0x12121..0x1217E */
+ 0x1000, 0x1001, 0x1002, 0x830c, 0x830e, 0x10fb, 0x831a, 0x831b,
+ 0x831f, 0x8301, 0x109b, 0x109c, 0x00b4, 0x8340, 0x00a8, 0x833e,
+ 0x83e3, 0x833f, 0x10fd, 0x10fe, 0x109d, 0x109e, 0x1003, 0x2edd,
+ 0x1005, 0x1006, 0x1007, 0x10fc, 0x0715, 0x0710, 0x830f, 0x833c,
+ 0x101c, 0x0716, 0x835c, 0x0726, 0x0725, 0x0718, 0x0719, 0x071c,
+ 0x071d, 0x8308, 0x8309, 0x1014, 0x1015, 0x833b, 0x833d, 0x835b,
+ 0x835d, 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e,
+ 0x100f, 0x1010, 0x1011, 0x830b, 0x0912, 0x00b1, 0x00d7, 0x00f7,
+ 0x831d, 0x0960, 0x831c, 0x831e, 0x0966, 0x0967, 0x091e, 0x0934,
+ 0x0d42, 0x0d40, 0x00b0, 0x0732, 0x0733, 0x0803, 0x83e5, 0x8304,
+ 0x00a2, 0x00a3, 0x8305, 0x8303, 0x8306, 0x830a, 0x8320, 0x00a7,
+ 0x0d06, 0x0d05, 0x0ccb, 0x0ccf, 0x0cce, 0x0cc7,
+ /* 0x12221..0x1227E */
+ 0x0cc6, 0x0ca1, 0x0ca0, 0x0cb3, 0x0cb2, 0x0cbd, 0x0cbc, 0x073b,
+ 0x1012, 0x0892, 0x0890, 0x0891, 0x0893, 0x1013, 0x8307, 0x8302,
+ 0x830d, 0x835e, 0x1033, 0x1034, 0x1035, 0x103b, 0x103c, 0x10ff,
+ 0x109f, 0x0908, 0x090b, 0x0986, 0x0987, 0x0982, 0x0983, 0x092a,
+ 0x0929, 0x0984, 0x0985, 0x098a, 0x098b, 0x0909, 0x0905, 0x0a05,
+ 0x0a06, 0x0927, 0x0928, 0x00ac, 0x08d2, 0x08d4, 0x0900, 0x0903,
+ 0x0995, 0x0996, 0x0997, 0x0925, 0x0926, 0x835f, 0x8360, 0x1018,
+ 0x1019, 0x1016, 0x1017, 0x0920, 0x09a5, 0x0a12, 0x0902, 0x0907,
+ 0x0961, 0x0952, 0x096a, 0x096b, 0x091a, 0x093d, 0x091d, 0x0935,
+ 0x092b, 0x092c, 0x0962, 0x0943, 0x0945, 0x0948, 0x0976, 0x0977,
+ 0x0894, 0x082b, 0x0730, 0x0d6f, 0x0d6d, 0x0d6a, 0x0720, 0x0721,
+ 0x00b6, 0x0d6e, 0x0d6b, 0x0d6c, 0x0d69, 0x0cef,
+ /* 0x12321..0x1237E */
+ 0x0cb7, 0x0cb6, 0x0cc1, 0x0cc0, 0x0897, 0x0898, 0x0896, 0x0899,
+ 0x08c4, 0x08e8, 0x08e6, 0x08e7, 0x08e9, 0x0f34, 0x0f35, 0x8310,
+ 0x8311, 0x8312, 0x8313, 0x8314, 0x8315, 0x8316, 0x8317, 0x8318,
+ 0x8319, 0x0999, 0x0cc9, 0x103d, 0x8246, 0x8245, 0x0ce6, 0x0722,
+ 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326, 0x8327, 0x8328,
+ 0x8329, 0x832a, 0x832b, 0x832c, 0x832d, 0x832e, 0x832f, 0x8330,
+ 0x8331, 0x8332, 0x8333, 0x8334, 0x8335, 0x8336, 0x8337, 0x8338,
+ 0x8339, 0x833a, 0x0913, 0x0835, 0x080f, 0x13cb, 0x0813, 0x0827,
+ 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348,
+ 0x8349, 0x834a, 0x834b, 0x834c, 0x834d, 0x834e, 0x834f, 0x8350,
+ 0x8351, 0x8352, 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358,
+ 0x8359, 0x835a, 0x10a0, 0x0713, 0x0ffa, 0x0ffb,
+ /* 0x12421..0x1247E */
+ 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048,
+ 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f, 0x1050,
+ 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058,
+ 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f, 0x1060,
+ 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, 0x1068,
+ 0x1069, 0x106a, 0x106b, 0x106c, 0x106d, 0x106e, 0x106f, 0x1070,
+ 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077, 0x1078,
+ 0x1079, 0x107a, 0x107b, 0x107c, 0x107d, 0x107e, 0x107f, 0x1080,
+ 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088,
+ 0x1089, 0x108a, 0x108b, 0x108c, 0x108d, 0x108e, 0x108f, 0x1090,
+ 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x0001, 0x0002,
+ 0x0003, 0x0004, 0x0005, 0x0000, 0x0000, 0x0000,
+ /* 0x12521..0x1257E */
+ 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8,
+ 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0,
+ 0x10b1, 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8,
+ 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0,
+ 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5, 0x10c6, 0x10c7, 0x10c8,
+ 0x10c9, 0x10ca, 0x10cb, 0x10cc, 0x10cd, 0x10ce, 0x10cf, 0x10d0,
+ 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, 0x10d8,
+ 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, 0x10e0,
+ 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, 0x10e8,
+ 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, 0x10f0,
+ 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d,
+ /* 0x12621..0x1267E */
+ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
+ 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0,
+ 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9,
+ 0x0d64, 0x0d60, 0x0d62, 0x0d66, 0x0d61, 0x0d65, 0x0d67, 0x0d63,
+ 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8,
+ 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0,
+ 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9,
+ 0x03c2, 0x0bf5, 0x0bf6, 0x0bf7, 0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb,
+ 0x0bfc, 0x0bfd, 0x0bfe, 0x0d16, 0x0d17, 0x1020, 0x0d0e, 0x0d00,
+ 0x0d01, 0x0d02, 0x0d03, 0x0d68, 0x0cb1, 0x11f0, 0x11f1, 0x11f2,
+ 0x11f3, 0x11f4, 0x11f5, 0x11f6, 0x11f7, 0x11f8, 0x11f9, 0x000e,
+ 0x11fa, 0x11fb, 0x11fc, 0x11fd, 0x11fe, 0x11ff,
+ /* 0x12721..0x1277E */
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416,
+ 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426,
+ 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e,
+ 0x042f, 0x0abe, 0x0abf, 0x0ac0, 0x0ac1, 0x0ac2, 0x0ac3, 0x0ac4,
+ 0x0ac5, 0x0ac6, 0x0ac7, 0x0ac8, 0x0ac9, 0x0aca, 0x0acb, 0x0acc,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436,
+ 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
+ 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446,
+ 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e,
+ 0x044f, 0x10f7, 0x10f8, 0x10f9, 0x10fa, 0x09da, 0x09db, 0x0853,
+ 0x0854, 0x0855, 0x0e13, 0x0a18, 0x0b23, 0x0ace,
+ /* 0x12821..0x1287E */
+ 0x0c00, 0x0c02, 0x0c0c, 0x0c10, 0x0c18, 0x0c14, 0x0c1c, 0x0c2c,
+ 0x0c24, 0x0c34, 0x0c3c, 0x0c01, 0x0c03, 0x0c0f, 0x0c13, 0x0c1b,
+ 0x0c17, 0x0c23, 0x0c33, 0x0c2b, 0x0c3b, 0x0c4b, 0x0c20, 0x0c2f,
+ 0x0c28, 0x0c37, 0x0c3f, 0x0c1d, 0x0c30, 0x0c25, 0x0c38, 0x0c42,
+ 0x1251, 0x1252, 0x1253, 0x1254, 0x1255, 0x1256, 0x1257, 0x1258,
+ 0x1259, 0x125a, 0x125b, 0x125c, 0x125d, 0x125e, 0x125f, 0x12b1,
+ 0x12b2, 0x12b3, 0x12b4, 0x12b5, 0x12b6, 0x12b7, 0x12b8, 0x12b9,
+ 0x12ba, 0x12bb, 0x12bc, 0x12bd, 0x12be, 0x12bf, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0cd0, 0x0cd1,
+ 0x0cd2, 0x0cd3, 0x073c, 0x0747, 0x0748, 0x0749, 0x01cd, 0x01ce,
+ 0x01d0, 0x053e, 0x053f, 0x01f8, 0x01f9, 0x01d1, 0x01d2, 0x01d4,
+ 0x01d6, 0x01d8, 0x01da, 0x01dc, 0x0000, 0x0000,
+ /* 0x12921..0x1297E */
+ 0x07ac, 0x00a0, 0x00a1, 0x00a4, 0x00a6, 0x00a9, 0x00aa, 0x00ab,
+ 0x00ad, 0x00ae, 0x00af, 0x00b2, 0x00b3, 0x00b7, 0x00b8, 0x00b9,
+ 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1,
+ 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9,
+ 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1,
+ 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d8, 0x00d9, 0x00da,
+ 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2,
+ 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
+ 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
+ 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
+ 0x00fc, 0x00fd, 0x00fe, 0x00ff, 0x0100, 0x012a, 0x016a, 0x0112,
+ 0x014c, 0x0101, 0x012b, 0x016b, 0x0113, 0x014d,
+ /* 0x12A21..0x12A7E */
+ 0x0104, 0x02d8, 0x0141, 0x013d, 0x015a, 0x0160, 0x015e, 0x0164,
+ 0x0179, 0x017d, 0x017b, 0x0105, 0x02db, 0x0142, 0x013e, 0x015b,
+ 0x02c7, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
+ 0x0154, 0x0102, 0x0139, 0x0106, 0x010c, 0x0118, 0x011a, 0x010e,
+ 0x0143, 0x0147, 0x0150, 0x0158, 0x016e, 0x0170, 0x0162, 0x0155,
+ 0x0103, 0x013a, 0x0107, 0x010d, 0x0119, 0x011b, 0x010f, 0x0111,
+ 0x0144, 0x0148, 0x0151, 0x0159, 0x016f, 0x0171, 0x0163, 0x02d9,
+ 0x0108, 0x011c, 0x0124, 0x0134, 0x015c, 0x016c, 0x0109, 0x011d,
+ 0x0125, 0x0135, 0x015d, 0x016d, 0x0271, 0x028b, 0x027e, 0x0283,
+ 0x0292, 0x026c, 0x026e, 0x0279, 0x0288, 0x0256, 0x0273, 0x027d,
+ 0x0282, 0x0290, 0x027b, 0x026d, 0x025f, 0x0272, 0x029d, 0x028e,
+ 0x0261, 0x014b, 0x0270, 0x0281, 0x0127, 0x0295,
+ /* 0x12B21..0x12B7E */
+ 0x0294, 0x0266, 0x0298, 0x01c2, 0x0253, 0x0257, 0x0284, 0x0260,
+ 0x0193, 0x0153, 0x0152, 0x0268, 0x0289, 0x0258, 0x0275, 0x0259,
+ 0x025c, 0x025e, 0x0250, 0x026f, 0x028a, 0x0264, 0x028c, 0x0254,
+ 0x0251, 0x0252, 0x028d, 0x0265, 0x02a2, 0x02a1, 0x0255, 0x0291,
+ 0x027a, 0x0267, 0x025a, 0x000f, 0x01fd, 0x0670, 0x0671, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0672,
+ 0x0673, 0x0361, 0x02c8, 0x02cc, 0x02d0, 0x02d1, 0x0306, 0x073f,
+ 0x030b, 0x0301, 0x0304, 0x0300, 0x030f, 0x030c, 0x0302, 0x02e5,
+ 0x02e6, 0x02e7, 0x02e8, 0x02e9, 0x0018, 0x0019, 0x0325, 0x032c,
+ 0x0339, 0x031c, 0x031f, 0x0320, 0x0308, 0x033d, 0x0329, 0x032f,
+ 0x02de, 0x0324, 0x0330, 0x033c, 0x0334, 0x031d, 0x031e, 0x0318,
+ 0x0319, 0x032a, 0x033a, 0x033b, 0x0303, 0x031a,
+ /* 0x12C21..0x12C7E */
+ 0x0e76, 0x0e77, 0x0e78, 0x0e79, 0x0e7a, 0x0e7b, 0x0e7c, 0x0e7d,
+ 0x0e7e, 0x0e7f, 0x0beb, 0x0bec, 0x0bed, 0x0bee, 0x0bef, 0x0bf0,
+ 0x0bf1, 0x0bf2, 0x0bf3, 0x0bf4, 0x0870, 0x0871, 0x0872, 0x0873,
+ 0x0874, 0x0875, 0x0876, 0x0877, 0x0878, 0x0879, 0x087a, 0x087b,
+ 0x0bd0, 0x0bd1, 0x0bd2, 0x0bd3, 0x0bd4, 0x0bd5, 0x0bd6, 0x0bd7,
+ 0x0bd8, 0x0bd9, 0x0bda, 0x0bdb, 0x0bdc, 0x0bdd, 0x0bde, 0x0bdf,
+ 0x0be0, 0x0be1, 0x0be2, 0x0be3, 0x0be4, 0x0be5, 0x0be6, 0x0be7,
+ 0x0be8, 0x0be9, 0x12d0, 0x12d1, 0x12d2, 0x12d3, 0x12d4, 0x12d5,
+ 0x12d6, 0x12d7, 0x12d8, 0x12d9, 0x12da, 0x12db, 0x12dc, 0x12dd,
+ 0x12de, 0x12df, 0x12e0, 0x12e1, 0x12e2, 0x12e3, 0x12fa, 0x12e9,
+ 0x12e5, 0x12ed, 0x12ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0751, 0x0742,
+ /* 0x12D21..0x12D7E */
+ 0x0b60, 0x0b61, 0x0b62, 0x0b63, 0x0b64, 0x0b65, 0x0b66, 0x0b67,
+ 0x0b68, 0x0b69, 0x0b6a, 0x0b6b, 0x0b6c, 0x0b6d, 0x0b6e, 0x0b6f,
+ 0x0b70, 0x0b71, 0x0b72, 0x0b73, 0x0860, 0x0861, 0x0862, 0x0863,
+ 0x0864, 0x0865, 0x0866, 0x0867, 0x0868, 0x0869, 0x086a, 0x1349,
+ 0x1314, 0x1322, 0x134d, 0x1318, 0x1327, 0x1303, 0x1336, 0x1351,
+ 0x1357, 0x130d, 0x1326, 0x1323, 0x132b, 0x134a, 0x133b, 0x139c,
+ 0x139d, 0x139e, 0x138e, 0x138f, 0x13c4, 0x13a1, 0x086b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x137b, 0x101d,
+ 0x101f, 0x0816, 0x13cd, 0x0821, 0x12a4, 0x12a5, 0x12a6, 0x12a7,
+ 0x12a8, 0x1231, 0x1232, 0x1239, 0x137e, 0x137d, 0x137c, 0x0000,
+ 0x0000, 0x0000, 0x092e, 0x0000, 0x0000, 0x0000, 0x0000, 0x091f,
+ 0x09bf, 0x0000, 0x0000, 0x0000, 0x0e56, 0x0d1e,
+ /* 0x12E21..0x12E7E */
+ 0x0000, 0x840b, 0x1402, 0x2e28, 0x2e2f, 0x2e30, 0x2e8d, 0x2ee1,
+ 0x2efd, 0x2eff, 0x2f03, 0x2f0b, 0x2f60, 0x2f48, 0x2f49, 0x2f56,
+ 0x2f5f, 0x2f6a, 0x2f6c, 0x2f7e, 0x2f8a, 0x2f94, 0x2f97, 0x8130,
+ 0x2fc9, 0x2fe0, 0x3001, 0x3002, 0x300e, 0x3018, 0x3027, 0x302e,
+ 0x3040, 0x303b, 0x3041, 0x3094, 0x30cc, 0x30f2, 0x30d0, 0x30e6,
+ 0x8131, 0x3106, 0x3103, 0x310b, 0x311e, 0x3135, 0x314a, 0x8132,
+ 0x3155, 0x3157, 0x14b5, 0x319d, 0x31c3, 0x31ca, 0x31de, 0x31e2,
+ 0x31ee, 0x3201, 0x14db, 0x3213, 0x3215, 0x3249, 0x3257, 0x3261,
+ 0x3293, 0x32c8, 0x8133, 0x32cc, 0x32d0, 0x32d6, 0x32db, 0x8134,
+ 0x32f0, 0x32fb, 0x3300, 0x3307, 0x331c, 0x8135, 0x3361, 0x3363,
+ 0x337d, 0x3393, 0x339d, 0x33b2, 0x3412, 0x3427, 0x344d, 0x349c,
+ 0x346b, 0x3474, 0x347f, 0x3488, 0x3496, 0x34a1,
+ /* 0x12F21..0x12F7E */
+ 0x34a9, 0x34c6, 0x34ff, 0x350e, 0x352b, 0x3535, 0x3550, 0x355e,
+ 0x3581, 0x3586, 0x358e, 0x8136, 0x35ad, 0x35ce, 0x8137, 0x3608,
+ 0x360e, 0x363b, 0x3649, 0x3676, 0x3666, 0x8138, 0x366f, 0x3671,
+ 0x3672, 0x3699, 0x369e, 0x36a9, 0x36ac, 0x36b3, 0x36c9, 0x36ca,
+ 0x370a, 0x913d, 0x3721, 0x372f, 0x3733, 0x3734, 0x3770, 0x3777,
+ 0x377c, 0x379c, 0x810f, 0x921b, 0x37b8, 0x37c7, 0x37c8, 0x37cf,
+ 0x37e4, 0x37ed, 0x37f5, 0x37f6, 0x37ff, 0x3809, 0x8110, 0x3861,
+ 0x3864, 0x8139, 0x387c, 0x3889, 0x389e, 0x813a, 0x38a9, 0x936e,
+ 0x38d2, 0x38ce, 0x38d4, 0x38da, 0x38e0, 0x38e9, 0x390c, 0x6641,
+ 0x395d, 0x396d, 0x398b, 0x3992, 0x39a4, 0x39c3, 0x39d2, 0x39dd,
+ 0x3a13, 0x3a23, 0x3a67, 0x3a6d, 0x3a77, 0x3a7e, 0x3a84, 0x3a9e,
+ 0x3aa7, 0x3ac4, 0x97bd, 0x3b19, 0x3b25, 0x0000,
+ /* 0x13021..0x1307E */
+ 0x2e9c, 0x3516, 0x3a03, 0x763f, 0x34c0, 0x411b, 0x4328, 0x39f6,
+ 0x7022, 0x6475, 0x631c, 0x5a50, 0x40aa, 0x43e1, 0x4e25, 0x45ed,
+ 0x6466, 0x62a6, 0x7bf5, 0x4893, 0x3727, 0x45a1, 0x4271, 0x3b9b,
+ 0x39d0, 0x667b, 0x78f4, 0x5d62, 0x5dbe, 0x7b8e, 0x4216, 0x5c9f,
+ 0x68b7, 0x3b89, 0x3eb5, 0x4309, 0x4697, 0x4848, 0x75c7, 0x778d,
+ 0x474f, 0x2ee5, 0x2f0a, 0x2f4d, 0x2f9d, 0x3049, 0x36f2, 0x3937,
+ 0x39d4, 0x3a01, 0x3c09, 0x40df, 0x410f, 0x4170, 0x4613, 0x4905,
+ 0x50ba, 0x554f, 0x5570, 0x59fb, 0x5dad, 0x5def, 0x60c3, 0x640e,
+ 0x6863, 0x6b02, 0x7055, 0x707a, 0x333b, 0x2e95, 0x2ea5, 0x37df,
+ 0x60b2, 0x70c1, 0x58ef, 0x2e00, 0x38f1, 0x4ea2, 0x7038, 0x5a32,
+ 0x6328, 0x628b, 0x7c2f, 0x3141, 0x3370, 0x34bd, 0x34e1, 0x36e0,
+ 0x39fb, 0x3f15, 0x78f2, 0x4deb, 0x60e4, 0x652d,
+ /* 0x13121..0x1317E */
+ 0x7662, 0x7670, 0x76a0, 0x77fb, 0x340b, 0x33f3, 0x3b87, 0x50cf,
+ 0x5fbd, 0x6fc2, 0x76e8, 0x336f, 0x7d5c, 0x5aba, 0x2e11, 0x5893,
+ 0x61fc, 0x4e26, 0x3618, 0x3504, 0x4b1d, 0x651a, 0x7c3b, 0x39e5,
+ 0x33a9, 0x4d66, 0x54dc, 0x758f, 0x3642, 0x2e91, 0x704b, 0x76f2,
+ 0x634f, 0x790c, 0x33e1, 0x35b6, 0x3b30, 0x3f71, 0x4620, 0x46f3,
+ 0x4804, 0x4c38, 0x4cf3, 0x4d29, 0x545b, 0x56c8, 0x5a4e, 0x7834,
+ 0x62f1, 0x685b, 0x6a60, 0x72ed, 0x4db2, 0x55ab, 0x56ca, 0x79c5,
+ 0x40a6, 0x6b01, 0x6d8a, 0x75b2, 0x498e, 0x33ad, 0x3186, 0x3712,
+ 0x3830, 0x3944, 0x3bb4, 0x3ef6, 0x4028, 0x43a9, 0x43f4, 0x4cbf,
+ 0x4f14, 0x508e, 0x5114, 0x5159, 0x51d5, 0x533f, 0x5e01, 0x6276,
+ 0x62d1, 0x6597, 0x7060, 0x725b, 0x7d1b, 0x3869, 0x45bc, 0x4c5a,
+ 0x5525, 0x31f9, 0x392e, 0x3965, 0x3f80, 0x3fdc,
+ /* 0x13221..0x1327E */
+ 0x42bc, 0x45fa, 0x4a2a, 0x4b27, 0x4bb4, 0x538b, 0x5fc1, 0x6956,
+ 0x7d2c, 0x7d0e, 0x7ec4, 0x3ca1, 0x4c96, 0x637b, 0x3104, 0x3c4b,
+ 0x41b6, 0x61c6, 0x4876, 0x5261, 0x2e59, 0x2ffa, 0x3378, 0x4069,
+ 0x4e29, 0x5a4f, 0x77f3, 0x2e0b, 0x3316, 0x2eee, 0x2f55, 0x2f3d,
+ 0x2fa1, 0x2f73, 0x32a0, 0x33ef, 0x3609, 0x390f, 0x3ac1, 0x3bb6,
+ 0x3be1, 0x59d1, 0x4687, 0x479c, 0x47b6, 0x4b4c, 0x4cb3, 0x506b,
+ 0x53c2, 0x598d, 0x59be, 0x5a3c, 0x5b87, 0x62b1, 0x62db, 0x6304,
+ 0x6377, 0x63ef, 0x63d3, 0x6766, 0x6ab2, 0x3629, 0x6ca8, 0x6fe6,
+ 0x704e, 0x771e, 0x668a, 0x2fc4, 0x3ce8, 0x4211, 0x5259, 0x553b,
+ 0x61e5, 0x62bd, 0x66fe, 0x6cc0, 0x76c5, 0x7913, 0x79d5, 0x2ecb,
+ 0x2f1a, 0x69e3, 0x36de, 0x384a, 0x38ca, 0x3efb, 0x3feb, 0x402a,
+ 0x4094, 0x4062, 0x41d0, 0x4212, 0x42d0, 0x4539,
+ /* 0x13321..0x1337E */
+ 0x7b41, 0x4666, 0x48b0, 0x4d77, 0x5070, 0x554c, 0x5686, 0x5d75,
+ 0x62a5, 0x67f9, 0x758b, 0x768e, 0x6c9d, 0x31f1, 0x32be, 0x3916,
+ 0x34b3, 0x3bb3, 0x3d16, 0x4168, 0x4982, 0x4daf, 0x588d, 0x64cb,
+ 0x6857, 0x6a72, 0x73a7, 0x7ab8, 0x4d6c, 0x79a8, 0x66d9, 0x37a3,
+ 0x47ff, 0x66ce, 0x720e, 0x3283, 0x3687, 0x3404, 0x3ed3, 0x42e1,
+ 0x44b9, 0x483c, 0x4838, 0x4bbb, 0x5372, 0x58ba, 0x5a6b, 0x699a,
+ 0x69d2, 0x6d6b, 0x6f03, 0x70ed, 0x75a3, 0x7694, 0x7769, 0x3b66,
+ 0x3cb3, 0x497d, 0x784d, 0x784e, 0x439b, 0x5b20, 0x4a2b, 0x4a7f,
+ 0x48b6, 0x7c0d, 0x4f5f, 0x3272, 0x359d, 0x4070, 0x42ec, 0x4d3b,
+ 0x4e07, 0x4ed1, 0x645b, 0x6910, 0x6f44, 0x2e14, 0x7c39, 0x33f6,
+ 0x491b, 0x4a3a, 0x7784, 0x482a, 0x315c, 0x5ac3, 0x64b2, 0x71dc,
+ 0x738c, 0x365b, 0x7d28, 0x4822, 0x6305, 0x6431,
+ /* 0x13421..0x1347E */
+ 0x5ca5, 0x3208, 0x62c5, 0x54e6, 0x2e7e, 0x2f83, 0x31a0, 0x3bd2,
+ 0x320a, 0x32d8, 0x32e7, 0x3dfb, 0x359a, 0x382a, 0x39e6, 0x3b8c,
+ 0x3b98, 0x3bdb, 0x3e72, 0x3e79, 0x40a3, 0x411f, 0x4163, 0x41be,
+ 0x43db, 0x4562, 0x47d1, 0x4853, 0x48fa, 0x4b3e, 0x4b53, 0x4c57,
+ 0x4f22, 0x4f97, 0x4f45, 0x54b0, 0x5518, 0x56e3, 0x570b, 0x5aff,
+ 0x5ba1, 0x5c21, 0x5de9, 0x5f36, 0x5ff0, 0x609d, 0x6266, 0x639e,
+ 0x69b3, 0x6acc, 0x6cab, 0x7084, 0x7451, 0x7593, 0x7591, 0x75a2,
+ 0x7665, 0x77d3, 0x7928, 0x6218, 0x2e38, 0x342b, 0x3cb8, 0x3dcc,
+ 0x53a9, 0x564c, 0x573c, 0x3ca9, 0x5feb, 0x6d0b, 0x76c1, 0x7811,
+ 0x7854, 0x7858, 0x2f01, 0x2f0e, 0x3371, 0x359c, 0x3668, 0x37fa,
+ 0x3947, 0x3b09, 0x3bc4, 0x3c90, 0x3e0c, 0x3e7e, 0x3fcc, 0x43ee,
+ 0x473a, 0x45d7, 0x45e2, 0x471f, 0x48cb, 0x48c4,
+ /* 0x13521..0x1357E */
+ 0x4a5f, 0x3e30, 0x4bc5, 0x4c17, 0x4c7d, 0x557f, 0x5948, 0x3b63,
+ 0x5a00, 0x5d00, 0x3fbd, 0x698f, 0x6a18, 0x6cb4, 0x6d77, 0x6ecc,
+ 0x6f1d, 0x78e2, 0x7a0e, 0x7b3c, 0x2e80, 0x307d, 0x3100, 0x3993,
+ 0x3b9c, 0x422f, 0x4280, 0x44ec, 0x4b3a, 0x52a0, 0x5591, 0x5947,
+ 0x5fa9, 0x67fb, 0x6abc, 0x6b70, 0x43ac, 0x63ca, 0x77a0, 0x3409,
+ 0x3403, 0x35ab, 0x4854, 0x4a58, 0x6a70, 0x5827, 0x4775, 0x7ecd,
+ 0x3374, 0x3ba2, 0x611a, 0x6650, 0x7006, 0x2e18, 0x2e45, 0x2ec7,
+ 0x2f11, 0x33ca, 0x3438, 0x3bae, 0x3f13, 0x4025, 0x4551, 0x473d,
+ 0x4c42, 0x4c72, 0x4ce3, 0x5078, 0x5403, 0x5a76, 0x5aae, 0x5b08,
+ 0x5d1a, 0x5cfe, 0x5d66, 0x45e7, 0x525b, 0x33bb, 0x3c45, 0x3de8,
+ 0x42d2, 0x42e0, 0x4319, 0x4e20, 0x665a, 0x6a31, 0x6ddd, 0x72f8,
+ 0x4f01, 0x59a6, 0x7b5a, 0x2ea8, 0x2eab, 0x2eac,
+ /* 0x13621..0x1367E */
+ 0x2f9b, 0x2fa0, 0x30d1, 0x3147, 0x5af6, 0x3171, 0x31f6, 0x3354,
+ 0x3321, 0x337f, 0x33eb, 0x35ac, 0x3883, 0x3ce1, 0x3f37, 0x3f4a,
+ 0x402f, 0x4050, 0x406d, 0x431f, 0x4559, 0x4a4b, 0x4cc1, 0x52c2,
+ 0x52ed, 0x57ef, 0x60f8, 0x6105, 0x6208, 0x654e, 0x70f7, 0x73e1,
+ 0x77ff, 0x7957, 0x7a5a, 0x2ef0, 0x31dd, 0x3c2d, 0x4681, 0x496d,
+ 0x3c40, 0x46f2, 0x4975, 0x5389, 0x4850, 0x5c81, 0x30c5, 0x32e4,
+ 0x3747, 0x3dfe, 0x7326, 0x45a4, 0x4b23, 0x4b3d, 0x5434, 0x5981,
+ 0x59bd, 0x5b4b, 0x5dca, 0x62b9, 0x63cc, 0x687f, 0x695f, 0x6b39,
+ 0x6fd1, 0x71d1, 0x341f, 0x7280, 0x2e5d, 0x3036, 0x33e5, 0x333a,
+ 0x52d7, 0x5396, 0x57e9, 0x62e6, 0x6eaf, 0x79c6, 0x79c8, 0x79d2,
+ 0x3177, 0x411a, 0x665e, 0x35b0, 0x5a7a, 0x3076, 0x3bd3, 0x7047,
+ 0x7685, 0x2e32, 0x4adb, 0x71e7, 0x3c51, 0x3c48,
+ /* 0x13721..0x1377E */
+ 0x4398, 0x5a9f, 0x4c93, 0x7774, 0x6f61, 0x5aaa, 0x518a, 0x7688,
+ 0x5c82, 0x4817, 0x5e70, 0x4851, 0x736c, 0x32f2, 0x341b, 0x65ab,
+ 0x6a13, 0x5fa4, 0x6ecd, 0x70e1, 0x3366, 0x6888, 0x5941, 0x2fc2,
+ 0x30be, 0x3211, 0x3144, 0x3553, 0x372d, 0x53ea, 0x378b, 0x3951,
+ 0x3f62, 0x3f84, 0x4075, 0x4176, 0x4167, 0x41a9, 0x43b2, 0x443a,
+ 0x456c, 0x466f, 0x4842, 0x4e13, 0x5566, 0x5a3d, 0x5cfb, 0x5d4c,
+ 0x5d99, 0x5e4b, 0x5f6b, 0x630e, 0x634a, 0x66cd, 0x6a08, 0x6a63,
+ 0x6b66, 0x6efd, 0x781a, 0x7d8f, 0x62b8, 0x6fce, 0x7be8, 0x3287,
+ 0x421f, 0x4483, 0x4fc0, 0x7699, 0x4841, 0x3091, 0x4b20, 0x4c7a,
+ 0x4f54, 0x5a74, 0x5d50, 0x6840, 0x6a23, 0x4708, 0x2ef6, 0x3039,
+ 0x3026, 0x3065, 0x317c, 0x3238, 0x3263, 0x35a7, 0x370f, 0x3805,
+ 0x3acc, 0x3efa, 0x41b2, 0x41f8, 0x42f3, 0x4372,
+ /* 0x13821..0x1387E */
+ 0x491c, 0x4a29, 0x527d, 0x52ac, 0x532e, 0x5814, 0x586f, 0x5d79,
+ 0x570c, 0x60a9, 0x698b, 0x6b19, 0x6ce2, 0x6ed2, 0x7063, 0x7375,
+ 0x767a, 0x7855, 0x7a13, 0x7e78, 0x3143, 0x339f, 0x33b3, 0x3e7b,
+ 0x3f26, 0x4e1b, 0x4e90, 0x5384, 0x53fe, 0x5d43, 0x6237, 0x6a00,
+ 0x6afa, 0x7650, 0x2e4e, 0x300b, 0x33e4, 0x347c, 0x36fa, 0x39d1,
+ 0x3b64, 0x3df1, 0x3eab, 0x3f27, 0x4238, 0x4545, 0x47af, 0x4e56,
+ 0x52d0, 0x5cca, 0x68b4, 0x60a1, 0x60e1, 0x63f0, 0x664e, 0x6a87,
+ 0x6de8, 0x7237, 0x76c7, 0x7867, 0x7f13, 0x2e94, 0x2e92, 0x2f0d,
+ 0x3348, 0x3449, 0x343e, 0x3a2f, 0x3f8c, 0x3fa1, 0x409f, 0x48a7,
+ 0x4a8e, 0x545a, 0x5881, 0x6a9e, 0x6aa4, 0x6b77, 0x7190, 0x2e5e,
+ 0x7bc9, 0x2ea4, 0x2f7c, 0x2faf, 0x3019, 0x3016, 0x3149, 0x316c,
+ 0x329f, 0x32b9, 0x32fe, 0x339a, 0x33e3, 0x3411,
+ /* 0x13921..0x1397E */
+ 0x340e, 0x3589, 0x3751, 0x37a2, 0x397d, 0x3b54, 0x3b5d, 0x3b8f,
+ 0x3de5, 0x3de7, 0x3df7, 0x3e78, 0x3e83, 0x3e9a, 0x3eb7, 0x3f18,
+ 0x4052, 0x414c, 0x4297, 0x42d8, 0x43a7, 0x453b, 0x4602, 0x4643,
+ 0x46f4, 0x476d, 0x4821, 0x4897, 0x49cb, 0x4c5f, 0x4d2a, 0x4d69,
+ 0x4e2f, 0x4e9d, 0x5532, 0x5687, 0x586c, 0x5a3f, 0x5ce0, 0x5d05,
+ 0x5d18, 0x5d5e, 0x5db1, 0x6015, 0x6003, 0x60af, 0x60b1, 0x6154,
+ 0x618f, 0x622a, 0x6352, 0x684c, 0x6861, 0x6b1b, 0x6ca2, 0x6cfc,
+ 0x70ca, 0x7175, 0x7271, 0x583f, 0x72fc, 0x75a4, 0x764d, 0x7805,
+ 0x7999, 0x7ad8, 0x7d3b, 0x325b, 0x32ab, 0x33f7, 0x3408, 0x38d5,
+ 0x42f7, 0x4fe0, 0x6c6a, 0x6f5f, 0x7eb9, 0x314b, 0x323b, 0x344a,
+ 0x36fd, 0x5a40, 0x7177, 0x7d60, 0x7ed2, 0x5344, 0x4f09, 0x6170,
+ 0x5511, 0x3ffd, 0x40da, 0x7aa8, 0x52db, 0x6fbc,
+ /* 0x13A21..0x13A7E */
+ 0x4b64, 0x7803, 0x2eca, 0x36f0, 0x3764, 0x38be, 0x3a5a, 0x4068,
+ 0x41c7, 0x460f, 0x4606, 0x4839, 0x48b1, 0x4df7, 0x55d5, 0x5d3a,
+ 0x626e, 0x7b42, 0x2e9b, 0x2f50, 0x33c9, 0x3506, 0x3d6f, 0x3de6,
+ 0x3dee, 0x47fb, 0x4c99, 0x5473, 0x5802, 0x6a50, 0x7396, 0x68df,
+ 0x3750, 0x3ea7, 0x432b, 0x30b5, 0x30ac, 0x318d, 0x4700, 0x34c9,
+ 0x385e, 0x39bb, 0x3bb0, 0x3f69, 0x424d, 0x43a1, 0x483d, 0x4b73,
+ 0x4e08, 0x507d, 0x71c7, 0x5280, 0x5815, 0x5826, 0x596d, 0x458e,
+ 0x5d30, 0x63dc, 0x68c1, 0x6f09, 0x769b, 0x3264, 0x3728, 0x4750,
+ 0x5f6a, 0x6ca1, 0x31b4, 0x3742, 0x762a, 0x383a, 0x498a, 0x60b4,
+ 0x34b2, 0x3d0e, 0x37fc, 0x5895, 0x7dfa, 0x2f5c, 0x324a, 0x348b,
+ 0x443e, 0x4628, 0x4714, 0x47f5, 0x5a84, 0x5b56, 0x5d22, 0x732f,
+ 0x485c, 0x7bad, 0x5b39, 0x3319, 0x318a, 0x3237,
+ /* 0x13B21..0x13B7E */
+ 0x3bdf, 0x42f6, 0x44ae, 0x44e6, 0x472d, 0x4bba, 0x65a9, 0x76d1,
+ 0x5690, 0x7bd6, 0x434c, 0x7306, 0x7bab, 0x56bf, 0x4652, 0x2e09,
+ 0x3098, 0x33c2, 0x3c71, 0x40e8, 0x4492, 0x4563, 0x485f, 0x51e6,
+ 0x53ca, 0x5523, 0x5b97, 0x5e82, 0x6695, 0x6b83, 0x6cdb, 0x7178,
+ 0x7910, 0x45ac, 0x46ab, 0x4b8b, 0x2ed5, 0x2ed4, 0x2f3a, 0x2f7f,
+ 0x323a, 0x33f8, 0x33f2, 0x35e3, 0x36db, 0x38eb, 0x39cb, 0x39c9,
+ 0x39ff, 0x3b50, 0x3c4d, 0x3e02, 0x3e2b, 0x3fd7, 0x401d, 0x4307,
+ 0x452f, 0x3b5c, 0x45af, 0x45bd, 0x45e8, 0x479d, 0x4b62, 0x4b7b,
+ 0x4c0f, 0x5345, 0x5949, 0x59c1, 0x5cf8, 0x5d19, 0x5d2b, 0x60a2,
+ 0x6102, 0x61f3, 0x6996, 0x6a5e, 0x6a69, 0x6a66, 0x6a8c, 0x6aee,
+ 0x6cc7, 0x6cdc, 0x76cc, 0x78fc, 0x4b6f, 0x2e8b, 0x2f3c, 0x2f8d,
+ 0x3150, 0x3b57, 0x3bfa, 0x4148, 0x4301, 0x4642,
+ /* 0x13C21..0x13C7E */
+ 0x4b21, 0x4ecb, 0x4cbb, 0x523e, 0x54bd, 0x55d4, 0x58c1, 0x593a,
+ 0x600c, 0x6033, 0x61ea, 0x6494, 0x6f9e, 0x4c50, 0x7e7f, 0x3f0f,
+ 0x6b58, 0x7d2b, 0x5afa, 0x6ef8, 0x3b8d, 0x76eb, 0x2e03, 0x33f1,
+ 0x37f7, 0x3931, 0x3ac9, 0x3ba4, 0x4089, 0x4e7f, 0x4f06, 0x55be,
+ 0x6cea, 0x3b9f, 0x6500, 0x5be0, 0x3072, 0x47f4, 0x629d, 0x3c61,
+ 0x654a, 0x5e1e, 0x620e, 0x3199, 0x3c04, 0x4368, 0x6d66, 0x459c,
+ 0x516e, 0x593e, 0x5d17, 0x6005, 0x6b1d, 0x6eca, 0x706e, 0x66c7,
+ 0x70aa, 0x301f, 0x32fa, 0x3c3a, 0x4753, 0x507c, 0x5235, 0x714c,
+ 0x71c8, 0x732b, 0x62e5, 0x3bc2, 0x3f31, 0x40f9, 0x2e3b, 0x33d6,
+ 0x3b88, 0x424b, 0x4731, 0x4b8a, 0x52e9, 0x53e0, 0x5a2e, 0x616b,
+ 0x6da3, 0x7152, 0x7996, 0x3112, 0x33d7, 0x346a, 0x3bff, 0x4388,
+ 0x4a39, 0x5dac, 0x7700, 0x36da, 0x33ce, 0x3468,
+ /* 0x13D21..0x13D7E */
+ 0x3b97, 0x3c31, 0x3dde, 0x2fee, 0x4101, 0x42fe, 0x4d32, 0x59c0,
+ 0x59cb, 0x5d42, 0x5e4d, 0x5fd2, 0x61ed, 0x621f, 0x6490, 0x6846,
+ 0x6972, 0x6b90, 0x6e74, 0x6f2f, 0x7031, 0x714b, 0x716c, 0x76c6,
+ 0x719c, 0x2ec0, 0x2f4f, 0x3145, 0x3341, 0x3f93, 0x420e, 0x47d4,
+ 0x4c41, 0x4e0b, 0x5363, 0x5e26, 0x71cd, 0x7283, 0x33d4, 0x3919,
+ 0x3bbf, 0x4dd1, 0x595d, 0x5e2e, 0x5c9b, 0x387e, 0x519f, 0x31fa,
+ 0x6853, 0x6ff0, 0x2fca, 0x3cfb, 0x4625, 0x57ac, 0x5ae3, 0x621c,
+ 0x79ff, 0x31c6, 0x3faa, 0x45ec, 0x496f, 0x4b89, 0x4df3, 0x4e96,
+ 0x4f64, 0x56fe, 0x5d14, 0x3de1, 0x7075, 0x7187, 0x7806, 0x31e6,
+ 0x321d, 0x4240, 0x4691, 0x46d9, 0x4e1a, 0x3eb6, 0x5dd2, 0x5f72,
+ 0x46f8, 0x65af, 0x65f7, 0x6af8, 0x32a9, 0x33d9, 0x3973, 0x3e8f,
+ 0x3f90, 0x4055, 0x72e4, 0x7664, 0x30b7, 0x311f,
+ /* 0x13E21..0x13E7E */
+ 0x32dd, 0x3320, 0x3347, 0x33ec, 0x34e8, 0x3546, 0x3531, 0x3617,
+ 0x3968, 0x39be, 0x3a3c, 0x3bb5, 0x3c06, 0x3c0f, 0x3c11, 0x3c1a,
+ 0x3e84, 0x3e8a, 0x3ee0, 0x3f70, 0x427f, 0x4284, 0x42db, 0x438c,
+ 0x4377, 0x4607, 0x460c, 0x462d, 0x4676, 0x477e, 0x48a2, 0x4a1f,
+ 0x4a35, 0x4cbc, 0x4d88, 0x4e09, 0x4e58, 0x513c, 0x5126, 0x5167,
+ 0x55c7, 0x5701, 0x585d, 0x5901, 0x5965, 0x59f0, 0x5ae0, 0x5b11,
+ 0x5ca7, 0x5d39, 0x6096, 0x63d6, 0x648b, 0x6549, 0x685d, 0x68f3,
+ 0x6a1f, 0x6a3c, 0x6a54, 0x6a73, 0x6c61, 0x6cde, 0x71a4, 0x7266,
+ 0x737e, 0x7418, 0x769c, 0x7798, 0x2e0a, 0x2e08, 0x2e1e, 0x2e57,
+ 0x3197, 0x3270, 0x37ce, 0x3834, 0x38cc, 0x3b22, 0x3e38, 0x40c5,
+ 0x44fe, 0x4761, 0x4756, 0x4d44, 0x52b6, 0x5573, 0x5a63, 0x64b8,
+ 0x6b72, 0x71b8, 0x7320, 0x3631, 0x37f4, 0x78fe,
+ /* 0x13F21..0x13F7E */
+ 0x42ed, 0x490d, 0x4b96, 0x51ed, 0x5e54, 0x6077, 0x6272, 0x69e6,
+ 0x78df, 0x6755, 0x6fb1, 0x3c3b, 0x2f38, 0x2fe1, 0x2fb5, 0x3507,
+ 0x3a20, 0x3bdd, 0x3be9, 0x3fc3, 0x414e, 0x432f, 0x45b0, 0x464b,
+ 0x48ee, 0x499b, 0x4d78, 0x4df1, 0x5533, 0x55b9, 0x571f, 0x595e,
+ 0x59e6, 0x5d33, 0x61e3, 0x62af, 0x65aa, 0x69aa, 0x6a3a, 0x6eab,
+ 0x6f9b, 0x7032, 0x71dd, 0x7707, 0x2eba, 0x2ec1, 0x3203, 0x3875,
+ 0x38ec, 0x3c0b, 0x551a, 0x3c3d, 0x614e, 0x6a0a, 0x6fc5, 0x7663,
+ 0x776d, 0x5b25, 0x6acf, 0x7808, 0x7162, 0x36f3, 0x33a8, 0x7017,
+ 0x3439, 0x3782, 0x3e25, 0x43a8, 0x4c34, 0x508a, 0x5761, 0x5c8b,
+ 0x5fe0, 0x6870, 0x7042, 0x7154, 0x7310, 0x7318, 0x768f, 0x545e,
+ 0x7ac4, 0x3d07, 0x3d69, 0x4570, 0x47a2, 0x6da8, 0x76db, 0x436e,
+ 0x4749, 0x4919, 0x63c5, 0x7817, 0x76c0, 0x68fe,
+ /* 0x14021..0x1407E */
+ 0x4f84, 0x447a, 0x3bf8, 0x2e16, 0x502c, 0x555d, 0x462f, 0x31c4,
+ 0x3236, 0x32e2, 0x39d3, 0x3f81, 0x4027, 0x4210, 0x453f, 0x4574,
+ 0x461f, 0x4674, 0x48f2, 0x4816, 0x4b63, 0x4e05, 0x5272, 0x551f,
+ 0x56db, 0x5cbe, 0x6056, 0x38f0, 0x68fd, 0x697f, 0x6aa0, 0x6a93,
+ 0x6acb, 0x701d, 0x7192, 0x7752, 0x7759, 0x4589, 0x5a0e, 0x6106,
+ 0x76bb, 0x3e2d, 0x40dc, 0x421a, 0x45a5, 0x4614, 0x4790, 0x57f3,
+ 0x5a4d, 0x5c4d, 0x5e3e, 0x610a, 0x6cac, 0x6d64, 0x6de1, 0x6e5f,
+ 0x58a9, 0x3207, 0x42d9, 0x43a5, 0x4442, 0x4298, 0x6a2d, 0x5a83,
+ 0x5bc0, 0x6aac, 0x76ea, 0x5d76, 0x620c, 0x6749, 0x2ed9, 0x3148,
+ 0x3343, 0x3360, 0x3ba3, 0x3c02, 0x3c16, 0x3ddd, 0x4226, 0x4247,
+ 0x44b0, 0x4813, 0x4834, 0x4cc9, 0x4d45, 0x4d17, 0x47d3, 0x4f5c,
+ 0x514e, 0x517d, 0x45cb, 0x5a7f, 0x5bad, 0x5dda,
+ /* 0x14121..0x1417E */
+ 0x5e4a, 0x5fa8, 0x617a, 0x621b, 0x6239, 0x65a6, 0x6a6e, 0x6cce,
+ 0x6df5, 0x7078, 0x7077, 0x72ad, 0x7291, 0x7583, 0x7bae, 0x324d,
+ 0x3584, 0x4f38, 0x5136, 0x3168, 0x5985, 0x5e55, 0x61b3, 0x5cce,
+ 0x364c, 0x3851, 0x3ca8, 0x43aa, 0x46fe, 0x46fd, 0x495a, 0x52d9,
+ 0x558f, 0x558e, 0x590e, 0x5956, 0x59df, 0x5c97, 0x5d20, 0x5d44,
+ 0x6607, 0x6a34, 0x763b, 0x7061, 0x7f20, 0x30e7, 0x3275, 0x33cc,
+ 0x33e2, 0x3009, 0x35aa, 0x38ee, 0x394f, 0x523d, 0x3b8b, 0x3c64,
+ 0x331d, 0x40e3, 0x40f3, 0x435c, 0x4383, 0x433f, 0x43bb, 0x44cd,
+ 0x45e9, 0x46f9, 0x3de3, 0x49cd, 0x49fd, 0x4f15, 0x51e5, 0x2e89,
+ 0x55e9, 0x56f8, 0x5a93, 0x5cdf, 0x5dcf, 0x5d9c, 0x6061, 0x6349,
+ 0x6358, 0x646c, 0x64bc, 0x65fb, 0x68c5, 0x6d70, 0x7001, 0x706d,
+ 0x7397, 0x771c, 0x7a12, 0x30cf, 0x3897, 0x418e,
+ /* 0x14221..0x1427E */
+ 0x61d3, 0x6535, 0x6d08, 0x7020, 0x2fc3, 0x3074, 0x3247, 0x3373,
+ 0x406f, 0x4349, 0x475f, 0x4e2c, 0x6db3, 0x701f, 0x2fd7, 0x3c5e,
+ 0x6cca, 0x45cf, 0x5d9a, 0x3352, 0x6896, 0x3176, 0x43c3, 0x3b58,
+ 0x3b6b, 0x3c0a, 0x440d, 0x4751, 0x705c, 0x2ed6, 0x391a, 0x392a,
+ 0x4c70, 0x6a51, 0x353e, 0x3815, 0x39a5, 0x40f0, 0x4253, 0x47c1,
+ 0x6235, 0x4955, 0x7640, 0x79c4, 0x7a28, 0x2f53, 0x3806, 0x3bfe,
+ 0x6010, 0x3cb1, 0x3e2f, 0x3f85, 0x4020, 0x414b, 0x4234, 0x46ff,
+ 0x4cf0, 0x4ede, 0x60ce, 0x617f, 0x62d4, 0x688b, 0x6cb8, 0x7000,
+ 0x702e, 0x768a, 0x7edb, 0x7bdb, 0x2ee3, 0x33f0, 0x3927, 0x5b2c,
+ 0x718d, 0x784c, 0x7df9, 0x4edd, 0x5027, 0x3353, 0x3544, 0x3b85,
+ 0x4258, 0x429e, 0x42d3, 0x4ca2, 0x4fef, 0x5422, 0x6a17, 0x7438,
+ 0x4fc1, 0x6afe, 0x6338, 0x31e7, 0x66f8, 0x33ea,
+ /* 0x14321..0x1437E */
+ 0x33e9, 0x2f46, 0x7054, 0x6fb0, 0x396a, 0x6131, 0x3dfd, 0x5aea,
+ 0x6fbf, 0x48da, 0x6c37, 0x52f8, 0x7c48, 0x4a3d, 0x6ab0, 0x2e39,
+ 0x3358, 0x3606, 0x3766, 0x42c5, 0x43a2, 0x45e6, 0x4b4e, 0x4de1,
+ 0x4e5b, 0x50ad, 0x57ed, 0x5aef, 0x5baa, 0x5dbb, 0x603d, 0x60c6,
+ 0x66cb, 0x6a95, 0x735b, 0x36e3, 0x38c7, 0x3f3e, 0x45ad, 0x4696,
+ 0x4a80, 0x4bb5, 0x5537, 0x6ac7, 0x3024, 0x57e5, 0x3730, 0x3f1b,
+ 0x4065, 0x467a, 0x4c60, 0x55f4, 0x5a1a, 0x5f6e, 0x61f4, 0x6718,
+ 0x7045, 0x79b3, 0x5bc9, 0x555c, 0x5af9, 0x5b51, 0x64c4, 0x7010,
+ 0x59e9, 0x5a92, 0x6336, 0x3ae1, 0x5740, 0x2e2d, 0x2ef2, 0x3b99,
+ 0x3fe0, 0x42bd, 0x463c, 0x47f1, 0x4ce8, 0x666b, 0x6877, 0x6a3b,
+ 0x714e, 0x72f3, 0x79d0, 0x4a17, 0x5026, 0x532a, 0x62e7, 0x6457,
+ 0x6caf, 0x2e01, 0x3146, 0x31cb, 0x358b, 0x3bf5,
+ /* 0x14421..0x1447E */
+ 0x3e16, 0x3e33, 0x3e81, 0x3f14, 0x3f35, 0x3f6b, 0x3fb4, 0x41f2,
+ 0x4311, 0x46a2, 0x471d, 0x4f6e, 0x5252, 0x553a, 0x573a, 0x6074,
+ 0x6139, 0x6178, 0x6776, 0x6abf, 0x6adc, 0x6d85, 0x6df3, 0x729a,
+ 0x7577, 0x7802, 0x7ce5, 0x32c5, 0x4357, 0x56f4, 0x4715, 0x4c88,
+ 0x53cd, 0x6cc3, 0x73ae, 0x7673, 0x4d25, 0x389c, 0x490e, 0x49cc,
+ 0x6ffd, 0x739a, 0x55db, 0x701a, 0x385a, 0x4802, 0x43b4, 0x49fb,
+ 0x2f43, 0x4f2c, 0x47d8, 0x6fbb, 0x6526, 0x5db4, 0x7354, 0x493f,
+ 0x4f70, 0x376a, 0x38f7, 0x3b2c, 0x5d2c, 0x522a, 0x340a, 0x71e3,
+ 0x7db4, 0x2ead, 0x2f4e, 0x305c, 0x3075, 0x3243, 0x6c9e, 0x3448,
+ 0x3824, 0x3b9a, 0x3e1d, 0x3e95, 0x3ead, 0x3ef7, 0x3f1f, 0x408c,
+ 0x42b5, 0x433a, 0x43d0, 0x48af, 0x4c40, 0x5887, 0x598e, 0x5a0b,
+ 0x5de0, 0x6247, 0x6a02, 0x6ae6, 0x6e44, 0x7013,
+ /* 0x14521..0x1457E */
+ 0x70b8, 0x712d, 0x71d8, 0x7f0e, 0x4ce5, 0x4458, 0x44e2, 0x4575,
+ 0x4ef4, 0x5684, 0x5b1b, 0x7069, 0x73d1, 0x4eba, 0x34f2, 0x3fb9,
+ 0x44a4, 0x6f4d, 0x6fed, 0x7244, 0x3178, 0x386b, 0x3929, 0x3c55,
+ 0x3e97, 0x4dfb, 0x5e8f, 0x551c, 0x6cbc, 0x6ee2, 0x785b, 0x50b9,
+ 0x2f1d, 0x4bbf, 0x4fb1, 0x5530, 0x76fb, 0x314e, 0x3410, 0x3835,
+ 0x3857, 0x39ac, 0x3c60, 0x3f92, 0x4597, 0x475c, 0x4e21, 0x567b,
+ 0x63df, 0x6ced, 0x7014, 0x70fd, 0x734d, 0x5825, 0x583a, 0x32aa,
+ 0x3ea6, 0x371f, 0x3974, 0x4012, 0x3012, 0x315a, 0x31ac, 0x31cd,
+ 0x3200, 0x3510, 0x3854, 0x3858, 0x3957, 0x3b95, 0x3cf6, 0x3d8b,
+ 0x40bc, 0x4295, 0x442d, 0x4771, 0x4843, 0x48bc, 0x48df, 0x56d7,
+ 0x4dd8, 0x4e6f, 0x4d9b, 0x506f, 0x51c8, 0x3f53, 0x55d8, 0x5977,
+ 0x5b49, 0x5b54, 0x5b52, 0x5cd6, 0x5d71, 0x3230,
+ /* 0x14621..0x1467E */
+ 0x6463, 0x6569, 0x65e4, 0x6a0e, 0x6b04, 0x6c46, 0x6e0f, 0x7003,
+ 0x700f, 0x7419, 0x7676, 0x782d, 0x7a30, 0x75d8, 0x30cd, 0x32d5,
+ 0x340c, 0x3802, 0x3c0e, 0x41a7, 0x449e, 0x4d1e, 0x57b3, 0x5ae5,
+ 0x60f4, 0x6404, 0x7053, 0x7285, 0x3ce0, 0x7d07, 0x333f, 0x3f97,
+ 0x3fb3, 0x4d9c, 0x5279, 0x5763, 0x59bf, 0x5be4, 0x4bd2, 0x52ec,
+ 0x6aad, 0x4803, 0x4a61, 0x31f8, 0x5a81, 0x4934, 0x3c4a, 0x7cf6,
+ 0x62eb, 0x3bc5, 0x7149, 0x501e, 0x3678, 0x3c6f, 0x40c7, 0x4566,
+ 0x4c8c, 0x6c5a, 0x7041, 0x7813, 0x3451, 0x46c7, 0x720d, 0x3948,
+ 0x70a3, 0x3185, 0x2e4d, 0x31ea, 0x6599, 0x6b0e, 0x5058, 0x437a,
+ 0x734b, 0x4962, 0x79b4, 0x5e04, 0x5577, 0x3357, 0x4960, 0x6edf,
+ 0x76e3, 0x4c5d, 0x2e8c, 0x3c3c, 0x3f10, 0x6fe9, 0x3302, 0x6cd1,
+ 0x6089, 0x6679, 0x3eff, 0x45e5, 0x2e73, 0x3165,
+ /* 0x14721..0x1477E */
+ 0x3982, 0x3c3f, 0x77ee, 0x2efb, 0x398a, 0x3fcd, 0x6a8d, 0x4fe1,
+ 0x59b0, 0x5962, 0x3be7, 0x6471, 0x532b, 0x51b1, 0x3e74, 0x3ff5,
+ 0x437b, 0x449a, 0x51c3, 0x5c98, 0x2e43, 0x3efc, 0x2e4b, 0x37dc,
+ 0x36a2, 0x40a9, 0x4fc3, 0x5d0d, 0x60fd, 0x6133, 0x61bf, 0x6fb2,
+ 0x6997, 0x66a4, 0x3df4, 0x428a, 0x44ad, 0x6987, 0x4777, 0x4ce2,
+ 0x4d3e, 0x5436, 0x5834, 0x3a46, 0x5f75, 0x62ad, 0x79ac, 0x2ff3,
+ 0x3ec3, 0x42dd, 0x4392, 0x4557, 0x476f, 0x56c3, 0x524c, 0x60cc,
+ 0x60ba, 0x6f29, 0x714d, 0x300d, 0x37f9, 0x3a92, 0x4885, 0x4973,
+ 0x5164, 0x52fd, 0x6cb7, 0x38f2, 0x6ce0, 0x766a, 0x7019, 0x677f,
+ 0x59e4, 0x57e7, 0x6429, 0x2f2f, 0x3265, 0x335a, 0x42cd, 0x47cf,
+ 0x4cca, 0x567d, 0x5b94, 0x5c95, 0x6236, 0x6584, 0x6feb, 0x46dd,
+ 0x4f20, 0x5206, 0x5e1b, 0x63ab, 0x79c1, 0x7ea6,
+ /* 0x14821..0x1487E */
+ 0x31fd, 0x5bb1, 0x5872, 0x5bb8, 0x6087, 0x5b48, 0x4ae8, 0x3e61,
+ 0x608c, 0x5551, 0x5560, 0x316b, 0x7262, 0x4e8c, 0x567a, 0x7197,
+ 0x7aea, 0x2f10, 0x5f70, 0x429c, 0x5b4f, 0x75a5, 0x7ce9, 0x367a,
+ 0x3859, 0x66e4, 0x76bc, 0x2f34, 0x3224, 0x334a, 0x33cd, 0x33db,
+ 0x3e06, 0x442c, 0x4591, 0x477f, 0x4c3e, 0x4c4e, 0x5248, 0x52af,
+ 0x53ed, 0x5554, 0x5e41, 0x622c, 0x65e9, 0x6ca9, 0x5bc4, 0x71c6,
+ 0x5169, 0x7812, 0x78ef, 0x433d, 0x4669, 0x556a, 0x56e4, 0x58d0,
+ 0x6543, 0x66ee, 0x332a, 0x3351, 0x3426, 0x3983, 0x3e87, 0x3f7c,
+ 0x40b2, 0x4249, 0x4279, 0x42ab, 0x4590, 0x4bd4, 0x4ccc, 0x55b2,
+ 0x56ae, 0x5891, 0x59d8, 0x5dcb, 0x5f77, 0x60a5, 0x68ab, 0x6ab9,
+ 0x6cbb, 0x707f, 0x775e, 0x78db, 0x4a0b, 0x5c38, 0x3099, 0x3c3e,
+ 0x3fae, 0x4787, 0x4bd8, 0x5435, 0x5709, 0x5f8e,
+ /* 0x14921..0x1497E */
+ 0x7f3b, 0x47ca, 0x5a17, 0x3339, 0x558b, 0x7aed, 0x3f66, 0x619d,
+ 0x63f1, 0x6098, 0x3f3c, 0x3fc5, 0x5562, 0x5b46, 0x703c, 0x4867,
+ 0x39eb, 0x3a9b, 0x5d10, 0x567e, 0x6b2c, 0x2ff5, 0x3f6a, 0x4a19,
+ 0x4c37, 0x4f02, 0x54e2, 0x5968, 0x6868, 0x6a55, 0x6c79, 0x3edf,
+ 0x43cf, 0x55c5, 0x59d2, 0x62d7, 0x7328, 0x72f2, 0x649c, 0x66ed,
+ 0x7c2d, 0x34c1, 0x3f6c, 0x458c, 0x4d5c, 0x5015, 0x6ca7, 0x6cd3,
+ 0x783b, 0x454f, 0x54f6, 0x2e0d, 0x2ed8, 0x37e0, 0x392b, 0x3a66,
+ 0x3bcc, 0x31a8, 0x3e03, 0x3e9c, 0x4016, 0x4276, 0x4577, 0x45a7,
+ 0x466e, 0x4d6e, 0x5236, 0x5b26, 0x6150, 0x619a, 0x6299, 0x6b5c,
+ 0x6ca0, 0x6ce6, 0x6d74, 0x761c, 0x7644, 0x2fae, 0x44ab, 0x4b66,
+ 0x621e, 0x6461, 0x656a, 0x70e8, 0x3c01, 0x4953, 0x78a8, 0x647a,
+ 0x6557, 0x2f0f, 0x326f, 0x3fa9, 0x3e45, 0x470d,
+ /* 0x14A21..0x14A7E */
+ 0x598f, 0x6179, 0x6907, 0x6986, 0x4df5, 0x3f17, 0x4255, 0x4cb8,
+ 0x2ecf, 0x5269, 0x7b92, 0x3206, 0x343b, 0x3674, 0x38b3, 0x41a4,
+ 0x426e, 0x511a, 0x396e, 0x5c89, 0x5cde, 0x5d1b, 0x76f0, 0x4587,
+ 0x605e, 0x2e19, 0x2f75, 0x3175, 0x3840, 0x3e63, 0x3e73, 0x3f0a,
+ 0x47c4, 0x2e26, 0x653d, 0x7589, 0x765b, 0x5c73, 0x7801, 0x30fb,
+ 0x38c1, 0x5656, 0x58a7, 0x3225, 0x57a5, 0x6511, 0x5b86, 0x304f,
+ 0x3909, 0x5247, 0x5bc7, 0x5de8, 0x6fba, 0x6fd4, 0x704d, 0x2fbf,
+ 0x32c9, 0x3a29, 0x3f01, 0x77ad, 0x2fdd, 0x6217, 0x72ea, 0x3703,
+ 0x4355, 0x4b69, 0x552b, 0x68dc, 0x6f14, 0x5a42, 0x32df, 0x3893,
+ 0x4155, 0x420a, 0x46ae, 0x4bcd, 0x5c3f, 0x63e9, 0x3023, 0x2ff8,
+ 0x3305, 0x3446, 0x3831, 0x3949, 0x3b9d, 0x3cf0, 0x3cef, 0x3d29,
+ 0x3e96, 0x42b1, 0x4367, 0x453e, 0x45b9, 0x470b,
+ /* 0x14B21..0x14B7E */
+ 0x4cd5, 0x4ce1, 0x50f9, 0x5832, 0x5e2b, 0x60de, 0x62b3, 0x640c,
+ 0x64ec, 0x6702, 0x6912, 0x6a2a, 0x6c4a, 0x70a6, 0x72d2, 0x78fd,
+ 0x7cf3, 0x7d6c, 0x2e4f, 0x2ea1, 0x308d, 0x3256, 0x374a, 0x39a8,
+ 0x3e3d, 0x3fd8, 0x3fd9, 0x423f, 0x46b4, 0x471b, 0x47d0, 0x48d2,
+ 0x3192, 0x5d21, 0x60aa, 0x61a8, 0x6b00, 0x6c8c, 0x6cbf, 0x727e,
+ 0x7632, 0x3420, 0x782c, 0x3317, 0x30d5, 0x335c, 0x38a8, 0x44b2,
+ 0x4734, 0x5267, 0x5766, 0x5a46, 0x71e6, 0x32c3, 0x4ca1, 0x4b86,
+ 0x3800, 0x3e4c, 0x3954, 0x472c, 0x5ffb, 0x31e1, 0x56c6, 0x4469,
+ 0x58e8, 0x7b54, 0x7ebb, 0x37cb, 0x39b9, 0x4627, 0x479a, 0x4bce,
+ 0x34e9, 0x49d9, 0x3e55, 0x619c, 0x4795, 0x7baa, 0x47fe, 0x7c52,
+ 0x485d, 0x2ea6, 0x2fe3, 0x33c8, 0x42b9, 0x472b, 0x4cab, 0x6fc4,
+ 0x2fad, 0x5e6d, 0x7ebf, 0x2e07, 0x4162, 0x4e80,
+ /* 0x14C21..0x14C7E */
+ 0x4f2b, 0x6513, 0x3473, 0x472a, 0x7b45, 0x3df3, 0x5b95, 0x3cac,
+ 0x3bc6, 0x671c, 0x4e4a, 0x64d1, 0x5a14, 0x6108, 0x3999, 0x5c8d,
+ 0x4c11, 0x5720, 0x32d9, 0x3922, 0x5121, 0x525f, 0x57db, 0x7727,
+ 0x7d61, 0x490b, 0x3a7f, 0x3a18, 0x31a5, 0x340d, 0x347d, 0x460e,
+ 0x56df, 0x6ff7, 0x7298, 0x7cf4, 0x39ea, 0x525d, 0x4ec5, 0x314d,
+ 0x48c9, 0x5dbf, 0x5dec, 0x7762, 0x7eba, 0x4478, 0x4a21, 0x6302,
+ 0x3984, 0x3b5f, 0x4bdb, 0x531b, 0x56f2, 0x5db2, 0x6017, 0x6499,
+ 0x3132, 0x4728, 0x7ed9, 0x56ee, 0x4762, 0x32ff, 0x7905, 0x3c24,
+ 0x423b, 0x5c7e, 0x6cb0, 0x354f, 0x40b6, 0x5d0b, 0x7580, 0x3301,
+ 0x2e5f, 0x31b6, 0x391c, 0x523a, 0x6036, 0x71ce, 0x3f25, 0x57e2,
+ 0x3384, 0x3f79, 0x5d04, 0x65ac, 0x6a33, 0x6e8d, 0x7756, 0x47f3,
+ 0x65ae, 0x7453, 0x4109, 0x4108, 0x4cb9, 0x5652,
+ /* 0x14D21..0x14D7E */
+ 0x6aed, 0x6f38, 0x352f, 0x2f51, 0x312a, 0x32c7, 0x33cb, 0x3ba5,
+ 0x3e7d, 0x40a0, 0x4182, 0x43d6, 0x4709, 0x47da, 0x4e67, 0x4d8c,
+ 0x5336, 0x5337, 0x5531, 0x5950, 0x68d5, 0x6a98, 0x704a, 0x7091,
+ 0x70f5, 0x76c4, 0x678d, 0x3915, 0x2e88, 0x2f59, 0x2e0e, 0x6a89,
+ 0x6f3f, 0x7810, 0x30ad, 0x3e7c, 0x3996, 0x3bb9, 0x3eb8, 0x43da,
+ 0x43fa, 0x44c1, 0x46dc, 0x494a, 0x49d8, 0x4d0b, 0x4eb6, 0x5194,
+ 0x5528, 0x5aaf, 0x5f8a, 0x6000, 0x6449, 0x64c9, 0x6981, 0x6b21,
+ 0x6e0a, 0x7065, 0x767d, 0x790a, 0x417e, 0x4291, 0x4b32, 0x4c83,
+ 0x4d74, 0x5fcc, 0x5ffc, 0x4dc0, 0x5f85, 0x67ba, 0x68f8, 0x4765,
+ 0x63b1, 0x783c, 0x76f7, 0x4d1b, 0x5d61, 0x643d, 0x716a, 0x2e71,
+ 0x3375, 0x3d50, 0x4b04, 0x4feb, 0x65cd, 0x662d, 0x69a7, 0x3229,
+ 0x340f, 0x3c65, 0x474e, 0x48a8, 0x5406, 0x5483,
+ /* 0x14E21..0x14E7E */
+ 0x55e2, 0x68cf, 0x68e1, 0x71cc, 0x76e2, 0x7678, 0x3f8b, 0x5387,
+ 0x5acb, 0x644e, 0x43a0, 0x5565, 0x3289, 0x4d41, 0x4e9c, 0x5409,
+ 0x5559, 0x586b, 0x5c92, 0x7686, 0x5adc, 0x7f8d, 0x2fb6, 0x416e,
+ 0x45c5, 0x665c, 0x2e86, 0x2eae, 0x30da, 0x2e21, 0x31cc, 0x3bee,
+ 0x4599, 0x4881, 0x4dbc, 0x531f, 0x5642, 0x57ad, 0x5a1c, 0x5ce7,
+ 0x626f, 0x6ad2, 0x707c, 0x71cf, 0x7675, 0x7818, 0x329b, 0x5dd1,
+ 0x302b, 0x3398, 0x4797, 0x4dcb, 0x51d0, 0x5433, 0x61e8, 0x6f2a,
+ 0x76a3, 0x7c57, 0x7e9f, 0x5460, 0x3841, 0x4d99, 0x5d2f, 0x785e,
+ 0x2ee4, 0x2f36, 0x2f8b, 0x31b7, 0x32b1, 0x3dba, 0x401c, 0x53b2,
+ 0x593c, 0x62d3, 0x7234, 0x76b7, 0x76f6, 0x770a, 0x7e97, 0x7f62,
+ 0x46a6, 0x4b74, 0x3217, 0x32a3, 0x50c8, 0x68c2, 0x3ec9, 0x404b,
+ 0x4190, 0x4f23, 0x5149, 0x5c3e, 0x5df4, 0x606f,
+ /* 0x14F21..0x14F7E */
+ 0x64ee, 0x7023, 0x732c, 0x3442, 0x7b6f, 0x4ad3, 0x5089, 0x6cc2,
+ 0x6def, 0x7732, 0x32b4, 0x3a41, 0x3eca, 0x3f04, 0x4717, 0x497c,
+ 0x4994, 0x4d6a, 0x4f0f, 0x5262, 0x52fc, 0x5bed, 0x6001, 0x607e,
+ 0x674b, 0x70ce, 0x316d, 0x7e93, 0x5984, 0x608b, 0x7332, 0x6ad6,
+ 0x302d, 0x348c, 0x6a71, 0x4b6a, 0x6cc4, 0x6107, 0x40d1, 0x47a0,
+ 0x7df2, 0x2e99, 0x2e98, 0x7c10, 0x6a6b, 0x65c1, 0x6568, 0x4900,
+ 0x4e7e, 0x5897, 0x6155, 0x0000, 0x3b41, 0x3b56, 0x3b7d, 0x3b93,
+ 0x3bd8, 0x3bec, 0x3c12, 0x3c1e, 0x3c23, 0x3c2b, 0x178d, 0x3c62,
+ 0x813b, 0x813c, 0x95b4, 0x3c7a, 0x3c8f, 0x3c9f, 0x3ca3, 0x3caa,
+ 0x3cba, 0x3ccb, 0x3cd0, 0x3cd2, 0x3cf4, 0x9b34, 0x17e2, 0x3d0d,
+ 0x3d27, 0x8111, 0x3d46, 0x3d47, 0x3d53, 0x3d4a, 0x3d6d, 0x3d81,
+ 0x3da0, 0x3da4, 0x3da7, 0x3db8, 0x3dcb, 0x0000,
+ /* 0x15021..0x1507E */
+ 0x3f0c, 0x2e10, 0x2e15, 0x2e2a, 0x2e31, 0x2e36, 0x2e3c, 0x2e3f,
+ 0x2e42, 0x2e56, 0x2e58, 0x2e82, 0x2e85, 0x6c6b, 0x2e8a, 0x6212,
+ 0x3f0d, 0x2e8e, 0x2e9e, 0x2e9f, 0x2ea0, 0x2ea2, 0x2eb0, 0x2eb3,
+ 0x2eb6, 0x2ece, 0x2ecd, 0x2ec4, 0x2ec6, 0x2ec2, 0x2ed7, 0x2ede,
+ 0x2eed, 0x2edf, 0x2ef7, 0x2f09, 0x2f5a, 0x2f30, 0x2f5b, 0x2f5d,
+ 0x2f57, 0x2f47, 0x2f76, 0x2f88, 0x2f8f, 0x2f98, 0x2f7b, 0x2f69,
+ 0x2f70, 0x2f91, 0x2f6f, 0x2f86, 0x2f96, 0x3118, 0x2fd4, 0x2fdf,
+ 0x2fce, 0x2fd8, 0x2fdb, 0x2fd1, 0x2fda, 0x2fd0, 0x2fe4, 0x2fe5,
+ 0x301a, 0x3028, 0x3014, 0x302a, 0x3025, 0x3005, 0x2f1c, 0x2ff6,
+ 0x3021, 0x3029, 0x302c, 0x2ffe, 0x2fef, 0x3011, 0x3006, 0x3043,
+ 0x3047, 0x4703, 0x3055, 0x3050, 0x3048, 0x305a, 0x3056, 0x306c,
+ 0x3078, 0x3080, 0x309a, 0x3085, 0x30b4, 0x30b2,
+ /* 0x15121..0x1517E */
+ 0x30c9, 0x30ca, 0x30b3, 0x30c2, 0x30d6, 0x30de, 0x30e5, 0x30ed,
+ 0x30e3, 0x30ee, 0x30f9, 0x30f5, 0x3109, 0x3101, 0x3102, 0x3116,
+ 0x3115, 0x3114, 0x311a, 0x3121, 0x313a, 0x3137, 0x313c, 0x313b,
+ 0x313f, 0x3140, 0x3152, 0x314c, 0x3154, 0x3162, 0x5af8, 0x3169,
+ 0x316a, 0x316e, 0x3180, 0x3182, 0x36d8, 0x318c, 0x3189, 0x318f,
+ 0x3191, 0x3193, 0x3195, 0x3196, 0x31a4, 0x31a6, 0x31a2, 0x31a9,
+ 0x31aa, 0x31ab, 0x31b3, 0x31b1, 0x31b2, 0x31b0, 0x31b5, 0x31bd,
+ 0x31c5, 0x31c9, 0x31db, 0x31e0, 0x6655, 0x31e9, 0x31ed, 0x31f0,
+ 0x31f5, 0x31fe, 0x3204, 0x320b, 0x3214, 0x320e, 0x3227, 0x322a,
+ 0x322e, 0x3233, 0x3239, 0x324f, 0x3244, 0x324b, 0x324c, 0x325e,
+ 0x3254, 0x326a, 0x3274, 0x3269, 0x3273, 0x327f, 0x327d, 0x328d,
+ 0x3294, 0x3292, 0x3271, 0x3288, 0x3291, 0x6fa8,
+ /* 0x15221..0x1527E */
+ 0x6fa7, 0x32ac, 0x32ad, 0x32bc, 0x32b5, 0x32c1, 0x32cd, 0x32d7,
+ 0x32de, 0x32e3, 0x32e6, 0x78ed, 0x32e0, 0x32f3, 0x32f5, 0x32f8,
+ 0x32f9, 0x3306, 0x3308, 0x5538, 0x330d, 0x3310, 0x330f, 0x3315,
+ 0x331a, 0x3323, 0x332f, 0x3331, 0x3333, 0x3338, 0x3340, 0x3346,
+ 0x3345, 0x2e17, 0x3349, 0x334d, 0x31d6, 0x335e, 0x3369, 0x336e,
+ 0x3918, 0x337b, 0x3377, 0x3382, 0x3396, 0x33a0, 0x33a6, 0x33a5,
+ 0x33ae, 0x33b0, 0x33b6, 0x33c3, 0x5c12, 0x76d9, 0x33df, 0x46fc,
+ 0x51ee, 0x33ee, 0x33e8, 0x33ed, 0x33fa, 0x3401, 0x343d, 0x3440,
+ 0x342c, 0x342d, 0x343c, 0x342e, 0x3436, 0x3429, 0x341d, 0x344e,
+ 0x348f, 0x3475, 0x348e, 0x345f, 0x3471, 0x3477, 0x3470, 0x3492,
+ 0x347b, 0x3480, 0x3476, 0x3484, 0x3490, 0x3486, 0x34c7, 0x34a2,
+ 0x34b8, 0x34a5, 0x34ac, 0x34c4, 0x34c8, 0x34a8,
+ /* 0x15321..0x1537E */
+ 0x34ab, 0x34c2, 0x34a4, 0x34be, 0x34bc, 0x34d8, 0x34e5, 0x34e6,
+ 0x350f, 0x3514, 0x34fd, 0x34ee, 0x34ed, 0x34fa, 0x34e2, 0x3539,
+ 0x3540, 0x3563, 0x354c, 0x352e, 0x355c, 0x3545, 0x3556, 0x3557,
+ 0x3538, 0x3533, 0x355d, 0x3599, 0x3580, 0x34af, 0x358a, 0x359f,
+ 0x357b, 0x357e, 0x3598, 0x359e, 0x35ae, 0x357c, 0x3583, 0x35a9,
+ 0x3587, 0x35a8, 0x35da, 0x35c5, 0x35df, 0x35c4, 0x35dc, 0x35e4,
+ 0x35d4, 0x3614, 0x35f7, 0x3616, 0x35fe, 0x35fd, 0x361b, 0x35f9,
+ 0x364e, 0x3650, 0x51df, 0x3634, 0x3636, 0x3632, 0x3638, 0x366b,
+ 0x3664, 0x362f, 0x366c, 0x366a, 0x3686, 0x3680, 0x368a, 0x36a0,
+ 0x3694, 0x368f, 0x36a5, 0x36ae, 0x36b6, 0x36b4, 0x36c2, 0x36bc,
+ 0x36c1, 0x36c3, 0x36c0, 0x36c8, 0x36ce, 0x36d1, 0x36d3, 0x36d7,
+ 0x36ee, 0x36f9, 0x3700, 0x36ff, 0x3704, 0x3709,
+ /* 0x15421..0x1547E */
+ 0x3708, 0x370b, 0x370d, 0x3713, 0x3718, 0x3716, 0x35c7, 0x371c,
+ 0x3726, 0x3737, 0x3738, 0x374e, 0x373b, 0x3740, 0x374f, 0x3769,
+ 0x37c0, 0x3788, 0x3761, 0x377f, 0x3789, 0x3793, 0x37a0, 0x37b3,
+ 0x37a4, 0x37aa, 0x37b0, 0x37c3, 0x37c6, 0x37d4, 0x37d2, 0x37d3,
+ 0x380a, 0x37d6, 0x37e3, 0x380b, 0x3819, 0x381d, 0x3872, 0x3821,
+ 0x3862, 0x384b, 0x3870, 0x4bc0, 0x3852, 0x383d, 0x3879, 0x3885,
+ 0x38b9, 0x389f, 0x38ab, 0x38ba, 0x38de, 0x38bb, 0x38b8, 0x38ae,
+ 0x38c5, 0x38d3, 0x38d1, 0x38d7, 0x38d9, 0x38d8, 0x38e5, 0x38dc,
+ 0x38e4, 0x38df, 0x38ef, 0x38fa, 0x38f9, 0x38fb, 0x38fc, 0x38fd,
+ 0x3902, 0x390a, 0x3910, 0x391b, 0x48a6, 0x3925, 0x392c, 0x392d,
+ 0x3932, 0x3938, 0x393e, 0x5ad2, 0x3955, 0x3950, 0x394e, 0x395a,
+ 0x3958, 0x3962, 0x3960, 0x3967, 0x396c, 0x3969,
+ /* 0x15521..0x1557E */
+ 0x3978, 0x3981, 0x399d, 0x2f5e, 0x2fab, 0x39a3, 0x39b2, 0x39c6,
+ 0x39e8, 0x39dc, 0x398d, 0x39d9, 0x39da, 0x3a25, 0x3a1f, 0x3a11,
+ 0x3a1c, 0x3a09, 0x3a1a, 0x3a40, 0x3a6c, 0x3a49, 0x3a35, 0x3a36,
+ 0x3a62, 0x3a6a, 0x3a9a, 0x3abc, 0x3abe, 0x3acb, 0x3ac2, 0x3abd,
+ 0x3ae3, 0x3ad7, 0x3ae6, 0x3ae9, 0x3ad6, 0x3afa, 0x3afb, 0x3b0c,
+ 0x3b0b, 0x3b16, 0x3b32, 0x3ad0, 0x3b2a, 0x3b36, 0x3b3e, 0x3b43,
+ 0x3b45, 0x3b40, 0x3b51, 0x3b55, 0x3b5a, 0x3b5b, 0x3b65, 0x3b69,
+ 0x3b70, 0x3b73, 0x3b75, 0x3b78, 0x4588, 0x3b7a, 0x3b80, 0x3b83,
+ 0x3ba6, 0x3bb8, 0x3bc3, 0x3bc7, 0x3bc9, 0x3bd4, 0x3bd0, 0x3be4,
+ 0x3be6, 0x3be2, 0x3bde, 0x3be5, 0x3beb, 0x3bf0, 0x3bf6, 0x3bf3,
+ 0x3c05, 0x3c07, 0x3c08, 0x3c0d, 0x3c13, 0x3c20, 0x3c22, 0x3c28,
+ 0x3c38, 0x3c39, 0x3c41, 0x3c46, 0x3c4e, 0x3c53,
+ /* 0x15621..0x1567E */
+ 0x3c50, 0x3c4f, 0x3b71, 0x3c6c, 0x3c6e, 0x2e62, 0x3c76, 0x3c79,
+ 0x3c8c, 0x3c91, 0x3c94, 0x399b, 0x3cab, 0x3cbb, 0x3cb6, 0x3cbc,
+ 0x3cb7, 0x3cc5, 0x3cbe, 0x3cc7, 0x3cd9, 0x3ce9, 0x3cfd, 0x3cfa,
+ 0x3ced, 0x3d8c, 0x3cea, 0x3d0b, 0x3d15, 0x3d17, 0x3d5c, 0x3d1f,
+ 0x3d1b, 0x3d11, 0x3d14, 0x3d22, 0x3d1a, 0x3d19, 0x3d18, 0x3d4c,
+ 0x3d52, 0x3d4e, 0x3d4b, 0x3d6c, 0x3d73, 0x3d76, 0x3d87, 0x3d84,
+ 0x3d82, 0x3da2, 0x3d9d, 0x3dac, 0x3dae, 0x3dbd, 0x3d90, 0x3db7,
+ 0x3dbc, 0x3dc9, 0x3dcd, 0x3dd3, 0x3dd2, 0x3dd6, 0x3ddb, 0x3deb,
+ 0x3df2, 0x3df5, 0x3e0b, 0x3e1a, 0x3e19, 0x3e11, 0x3e1b, 0x3e36,
+ 0x3e37, 0x3e44, 0x3e43, 0x3e40, 0x3e4e, 0x3e57, 0x3e54, 0x3e5f,
+ 0x3e62, 0x3e64, 0x3e47, 0x3e75, 0x3e76, 0x3e7a, 0x7ebc, 0x3e7f,
+ 0x3ea0, 0x3ec1, 0x3ec2, 0x3ec8, 0x3ed0, 0x3ecf,
+ /* 0x15721..0x1577E */
+ 0x3ed6, 0x3ee3, 0x3edd, 0x3eda, 0x3edb, 0x3ee2, 0x3ee1, 0x3ee8,
+ 0x3ee9, 0x3eec, 0x3ef1, 0x3ef3, 0x3ef0, 0x3ef4, 0x3ef8, 0x3efe,
+ 0x3f03, 0x3f09, 0x3f5d, 0x3f5c, 0x3f0b, 0x3f11, 0x3f16, 0x3f29,
+ 0x3f2d, 0x3f38, 0x3f41, 0x3f48, 0x3f4c, 0x3f4e, 0x3f2f, 0x3f51,
+ 0x3f56, 0x3f57, 0x3f59, 0x3f61, 0x3f6d, 0x3f73, 0x3f77, 0x3f83,
+ 0x3f82, 0x3f7f, 0x3f8a, 0x3f88, 0x3f91, 0x3f87, 0x3f9e, 0x3f99,
+ 0x3f98, 0x3fa0, 0x3fa8, 0x3fad, 0x3fbc, 0x3fd6, 0x3ffb, 0x3fe4,
+ 0x3ff8, 0x3ff1, 0x3fdd, 0x40b3, 0x3fff, 0x4021, 0x4060, 0x4019,
+ 0x4010, 0x4029, 0x400e, 0x4031, 0x401b, 0x4015, 0x402b, 0x4026,
+ 0x400f, 0x403a, 0x405a, 0x4041, 0x406a, 0x4077, 0x405f, 0x404a,
+ 0x4046, 0x404d, 0x4063, 0x4043, 0x4064, 0x4042, 0x406c, 0x406b,
+ 0x4059, 0x4081, 0x408d, 0x40e7, 0x4083, 0x409a,
+ /* 0x15821..0x1587E */
+ 0x4084, 0x409b, 0x4096, 0x4097, 0x4092, 0x40a7, 0x408b, 0x40e1,
+ 0x40b8, 0x40e0, 0x40d3, 0x40b4, 0x3ff0, 0x40bd, 0x40c6, 0x40b5,
+ 0x40d8, 0x414d, 0x4115, 0x4106, 0x40f6, 0x40f7, 0x4100, 0x40f4,
+ 0x40fa, 0x4103, 0x4121, 0x40fb, 0x40f1, 0x410d, 0x410e, 0x4147,
+ 0x413e, 0x4128, 0x4127, 0x414a, 0x413f, 0x413c, 0x412c, 0x4134,
+ 0x413d, 0x4142, 0x4144, 0x4173, 0x4177, 0x4158, 0x4159, 0x415a,
+ 0x416b, 0x4174, 0x416f, 0x4165, 0x4171, 0x415f, 0x415d, 0x4153,
+ 0x4175, 0x4199, 0x4196, 0x4187, 0x41ac, 0x4194, 0x419a, 0x418a,
+ 0x4191, 0x41ab, 0x41ae, 0x41cc, 0x41ca, 0x41c9, 0x41f7, 0x41c8,
+ 0x41c3, 0x41c6, 0x41ba, 0x41cb, 0x5f79, 0x41cd, 0x41e6, 0x41e3,
+ 0x41f6, 0x41fa, 0x41f4, 0x41ff, 0x41fd, 0x41fc, 0x41fe, 0x4200,
+ 0x4208, 0x4209, 0x420d, 0x420c, 0x4214, 0x421b,
+ /* 0x15921..0x1597E */
+ 0x421e, 0x4221, 0x422a, 0x422e, 0x4230, 0x4232, 0x4233, 0x4241,
+ 0x424e, 0x425e, 0x4263, 0x425b, 0x4260, 0x4268, 0x427c, 0x4282,
+ 0x4289, 0x427e, 0x4292, 0x4293, 0x4296, 0x42d4, 0x4283, 0x4294,
+ 0x42d7, 0x42d1, 0x42bb, 0x42cf, 0x42ff, 0x42c6, 0x44d4, 0x42c8,
+ 0x42dc, 0x42cc, 0x42ca, 0x42c2, 0x42c7, 0x429b, 0x42c9, 0x430c,
+ 0x42ee, 0x42f1, 0x4327, 0x4302, 0x4308, 0x42ef, 0x42f5, 0x4350,
+ 0x433e, 0x434d, 0x441c, 0x434f, 0x4396, 0x438e, 0x4380, 0x43ab,
+ 0x4376, 0x43a3, 0x438f, 0x4389, 0x439f, 0x43b5, 0x436b, 0x4369,
+ 0x43be, 0x43e9, 0x43c0, 0x43c6, 0x43e3, 0x43c9, 0x43d2, 0x43f6,
+ 0x43c4, 0x4416, 0x4434, 0x4406, 0x4413, 0x4426, 0x4436, 0x451d,
+ 0x4417, 0x4428, 0x440f, 0x4467, 0x446f, 0x4476, 0x444e, 0x452a,
+ 0x4495, 0x4493, 0x44a5, 0x44a9, 0x4488, 0x44bc,
+ /* 0x15A21..0x15A7E */
+ 0x44da, 0x44d2, 0x44c5, 0x44c7, 0x44bb, 0x44d8, 0x44c2, 0x44f1,
+ 0x44e7, 0x6209, 0x44e0, 0x44e1, 0x42ac, 0x44e3, 0x44ef, 0x452c,
+ 0x44f6, 0x44f4, 0x44f2, 0x44fa, 0x4500, 0x44fd, 0x4518, 0x451c,
+ 0x4505, 0x4524, 0x4523, 0x452b, 0x4534, 0x4535, 0x4537, 0x4536,
+ 0x4538, 0x554b, 0x4548, 0x4556, 0x4555, 0x454d, 0x4558, 0x455e,
+ 0x455d, 0x4572, 0x4578, 0x4582, 0x4583, 0x6b8a, 0x459b, 0x459f,
+ 0x45ab, 0x45b7, 0x45c3, 0x45c6, 0x45c1, 0x45c4, 0x45cc, 0x45d2,
+ 0x45db, 0x45d9, 0x45e0, 0x45e1, 0x45f1, 0x4772, 0x460a, 0x4603,
+ 0x45fb, 0x4773, 0x4635, 0x4636, 0x4634, 0x461c, 0x464f, 0x4644,
+ 0x4649, 0x4641, 0x465e, 0x465d, 0x4664, 0x4667, 0x4668, 0x465f,
+ 0x4662, 0x4670, 0x4683, 0x4688, 0x468e, 0x4689, 0x4684, 0x4698,
+ 0x469d, 0x46c1, 0x46b9, 0x46c9, 0x46be, 0x46bc,
+ /* 0x15B21..0x15B7E */
+ 0x46c4, 0x46b8, 0x46d6, 0x46da, 0x46e0, 0x463f, 0x46e6, 0x46e9,
+ 0x46f0, 0x46f5, 0x46f7, 0x470f, 0x4716, 0x471e, 0x4726, 0x4727,
+ 0x7738, 0x472e, 0x473f, 0x4736, 0x4741, 0x4738, 0x4737, 0x4746,
+ 0x475e, 0x4760, 0x4759, 0x4763, 0x4764, 0x4789, 0x4770, 0x47a9,
+ 0x477c, 0x476a, 0x478c, 0x478b, 0x47a6, 0x47a1, 0x4785, 0x47b7,
+ 0x47ef, 0x47b4, 0x47ec, 0x47b3, 0x47e9, 0x47b8, 0x47e4, 0x47de,
+ 0x47dd, 0x47e2, 0x47ee, 0x47b9, 0x47ce, 0x47c6, 0x47e7, 0x4a9c,
+ 0x481e, 0x4846, 0x4829, 0x4840, 0x484d, 0x4832, 0x484e, 0x48b3,
+ 0x482b, 0x4859, 0x4863, 0x4877, 0x487f, 0x489f, 0x488f, 0x48ad,
+ 0x4894, 0x489d, 0x489b, 0x4883, 0x4aae, 0x48b9, 0x4874, 0x48b5,
+ 0x48a0, 0x48ba, 0x490f, 0x488d, 0x487e, 0x4901, 0x48ca, 0x4908,
+ 0x48d8, 0x4922, 0x4926, 0x48e1, 0x490c, 0x48cd,
+ /* 0x15C21..0x15C7E */
+ 0x48d4, 0x48e7, 0x48d5, 0x4936, 0x4912, 0x4904, 0x48d7, 0x48e3,
+ 0x4925, 0x48f9, 0x48e0, 0x48ef, 0x4928, 0x492a, 0x491a, 0x4923,
+ 0x4921, 0x48c6, 0x4979, 0x4977, 0x495c, 0x4978, 0x496b, 0x4954,
+ 0x497e, 0x496e, 0x4939, 0x4974, 0x493d, 0x4959, 0x4930, 0x4961,
+ 0x495e, 0x495d, 0x4981, 0x496a, 0x49b2, 0x49ae, 0x49d0, 0x49bf,
+ 0x49c1, 0x49d3, 0x49be, 0x49ce, 0x3be8, 0x49ca, 0x49dd, 0x49bb,
+ 0x49c3, 0x49a7, 0x4a2e, 0x4991, 0x49a0, 0x499c, 0x4995, 0x49b4,
+ 0x49de, 0x49e8, 0x4a02, 0x4a1b, 0x49ff, 0x4b0a, 0x49f9, 0x49f2,
+ 0x49e7, 0x4a05, 0x49b1, 0x4a1e, 0x49ed, 0x4a14, 0x49eb, 0x4a0a,
+ 0x4a12, 0x4ac1, 0x4a23, 0x4a13, 0x4a44, 0x4a0c, 0x4a72, 0x4a36,
+ 0x4a78, 0x4a47, 0x4a62, 0x4a59, 0x4a66, 0x4a48, 0x4a38, 0x4a22,
+ 0x4a90, 0x4a8d, 0x4aa0, 0x4a84, 0x4aa2, 0x4aa3,
+ /* 0x15D21..0x15D7E */
+ 0x4a97, 0x6617, 0x4abb, 0x4ac3, 0x4ac2, 0x4ab8, 0x4ab3, 0x4aac,
+ 0x4ade, 0x4ad1, 0x4adf, 0x4aaa, 0x4ada, 0x4aea, 0x4afb, 0x4b05,
+ 0x6616, 0x4afa, 0x4b12, 0x4b16, 0x7b31, 0x4b1f, 0x4b38, 0x4b37,
+ 0x56dc, 0x4b39, 0x78ee, 0x4b47, 0x4b43, 0x4b49, 0x4b50, 0x4b59,
+ 0x4b54, 0x4b5b, 0x4b5f, 0x4b61, 0x4b78, 0x4b79, 0x4b7f, 0x4b80,
+ 0x4b84, 0x4b83, 0x4b8d, 0x4b98, 0x4b95, 0x4b9e, 0x4ba4, 0x4baa,
+ 0x4bab, 0x4baf, 0x4bb2, 0x4bb1, 0x4bb3, 0x4bb7, 0x4bbc, 0x4bc6,
+ 0x4bcb, 0x4bd3, 0x4bdf, 0x4bec, 0x4beb, 0x4bf3, 0x4bef, 0x7ebe,
+ 0x4c08, 0x4c13, 0x4c14, 0x4c1b, 0x4c24, 0x4c23, 0x4c5e, 0x4c55,
+ 0x4c62, 0x4c6a, 0x4c82, 0x4c8d, 0x4c9a, 0x4c81, 0x4c9b, 0x4c7e,
+ 0x4c68, 0x4c73, 0x4c92, 0x4c90, 0x4cc4, 0x4cf1, 0x4cd3, 0x4cbd,
+ 0x4cd7, 0x4cc5, 0x4cdd, 0x4cae, 0x4cb1, 0x4cbe,
+ /* 0x15E21..0x15E7E */
+ 0x4cba, 0x4cdb, 0x4cef, 0x4cd9, 0x4cea, 0x4d1f, 0x684d, 0x4d36,
+ 0x4d2b, 0x4d3d, 0x4d38, 0x4d19, 0x4d35, 0x4d33, 0x4d12, 0x4d0c,
+ 0x4d63, 0x4d93, 0x4d64, 0x4d5a, 0x4d79, 0x4d59, 0x4d8e, 0x4d95,
+ 0x4fe4, 0x4d85, 0x4df9, 0x4e15, 0x4e0a, 0x4db5, 0x4dc7, 0x4de6,
+ 0x4db8, 0x4dc6, 0x4dec, 0x4dde, 0x4dcc, 0x4de8, 0x4dd2, 0x4dc5,
+ 0x4dfa, 0x4dd9, 0x4de4, 0x4dd5, 0x4dea, 0x4dee, 0x4e2d, 0x4e6e,
+ 0x4e2e, 0x4e19, 0x4e72, 0x4e5f, 0x4e3e, 0x4e23, 0x4e6b, 0x4e2b,
+ 0x4e76, 0x4e4d, 0x4e1f, 0x4e43, 0x4e3a, 0x4e4e, 0x4e24, 0x4eff,
+ 0x4e1d, 0x4e38, 0x4e82, 0x4eaa, 0x4e98, 0x4ec9, 0x4eb7, 0x4ed3,
+ 0x4ebd, 0x4eaf, 0x4ec4, 0x4eb2, 0x4ed4, 0x4ed5, 0x4e8f, 0x4ea5,
+ 0x4ec2, 0x4e9f, 0x4f41, 0x4f11, 0x504c, 0x4eec, 0x4ef8, 0x4efe,
+ 0x4f3f, 0x4ef2, 0x4f31, 0x4eef, 0x4f32, 0x4ecc,
+ /* 0x15F21..0x15F7E */
+ 0x4f3e, 0x4f13, 0x4ef7, 0x4f86, 0x4f7a, 0x4f78, 0x4f81, 0x4f80,
+ 0x4f6f, 0x4f5b, 0x4ff3, 0x4f6d, 0x4f82, 0x4f7c, 0x4f58, 0x4f8e,
+ 0x4f91, 0x4fc2, 0x4f66, 0x4fb3, 0x4fa3, 0x4fa1, 0x4fa4, 0x4fb9,
+ 0x4fc6, 0x4faa, 0x4fdf, 0x4fd5, 0x4fec, 0x4fd4, 0x4fd8, 0x4ff1,
+ 0x4fee, 0x4fdb, 0x5009, 0x500b, 0x4ffa, 0x5011, 0x5001, 0x500f,
+ 0x4ffe, 0x501b, 0x501a, 0x4f74, 0x501d, 0x5018, 0x501f, 0x5030,
+ 0x503e, 0x5032, 0x5051, 0x5063, 0x5099, 0x5092, 0x50af, 0x50f1,
+ 0x50ac, 0x50b8, 0x50b3, 0x50ae, 0x50df, 0x50cb, 0x50dd, 0x50d9,
+ 0x5109, 0x50fd, 0x511c, 0x5119, 0x5165, 0x5155, 0x5188, 0x5166,
+ 0x5162, 0x514c, 0x5156, 0x516c, 0x518f, 0x51fb, 0x5184, 0x5195,
+ 0x51a8, 0x51ac, 0x51d7, 0x51b9, 0x51be, 0x51d2, 0x51c9, 0x51d4,
+ 0x51ce, 0x51e0, 0x51ec, 0x51e7, 0x51f5, 0x51fc,
+ /* 0x16021..0x1607E */
+ 0x51f9, 0x51ff, 0x520d, 0x5210, 0x521b, 0x5228, 0x522d, 0x522c,
+ 0x5230, 0x5232, 0x523b, 0x523c, 0x523f, 0x5240, 0x5246, 0x524b,
+ 0x5258, 0x5274, 0x527e, 0x5282, 0x5281, 0x5287, 0x5292, 0x5296,
+ 0x52a2, 0x52a7, 0x52b9, 0x52b2, 0x52c3, 0x52c6, 0x52c4, 0x52ce,
+ 0x52d2, 0x52e2, 0x52e0, 0x52e1, 0x52f9, 0x52f7, 0x300f, 0x5317,
+ 0x530a, 0x531c, 0x5316, 0x531d, 0x5334, 0x532f, 0x5329, 0x5325,
+ 0x533e, 0x534e, 0x534f, 0x7ed8, 0x5357, 0x536a, 0x5368, 0x5370,
+ 0x5378, 0x5375, 0x537b, 0x537a, 0x53c8, 0x53b3, 0x53ce, 0x53bb,
+ 0x53c0, 0x53e5, 0x53ee, 0x53de, 0x54a2, 0x5405, 0x546f, 0x5425,
+ 0x53f8, 0x5432, 0x543a, 0x5455, 0x543f, 0x545f, 0x5459, 0x5441,
+ 0x545c, 0x5469, 0x5470, 0x5463, 0x546a, 0x5476, 0x547e, 0x548b,
+ 0x549e, 0x54a7, 0x54ca, 0x54cf, 0x54d4, 0x53f1,
+ /* 0x16121..0x1617E */
+ 0x54e0, 0x54e3, 0x54e7, 0x54e9, 0x54ee, 0x54f2, 0x54f0, 0x54f1,
+ 0x54f8, 0x54f7, 0x5504, 0x5503, 0x5505, 0x550c, 0x550e, 0x550d,
+ 0x5515, 0x5513, 0x551e, 0x5526, 0x552c, 0x553c, 0x5544, 0x554d,
+ 0x554a, 0x5549, 0x555b, 0x5546, 0x555a, 0x5569, 0x5564, 0x5567,
+ 0x556b, 0x556d, 0x5578, 0x5576, 0x5586, 0x5587, 0x5574, 0x558a,
+ 0x5589, 0x5582, 0x5594, 0x559a, 0x559d, 0x55a5, 0x55a3, 0x55c2,
+ 0x55b3, 0x55c3, 0x55b5, 0x55bd, 0x55b8, 0x55bc, 0x55b1, 0x55cd,
+ 0x55ca, 0x55d2, 0x55d9, 0x55e3, 0x55de, 0x55fe, 0x55ff, 0x55fc,
+ 0x5601, 0x55f0, 0x55fa, 0x55f2, 0x55f3, 0x560b, 0x560d, 0x5609,
+ 0x561f, 0x5627, 0x5620, 0x5621, 0x5622, 0x5624, 0x5634, 0x5630,
+ 0x563b, 0x5647, 0x5648, 0x5646, 0x565c, 0x5658, 0x5661, 0x5662,
+ 0x5668, 0x5669, 0x566a, 0x5667, 0x566c, 0x5670,
+ /* 0x16221..0x1627E */
+ 0x5672, 0x5676, 0x5678, 0x567c, 0x5680, 0x5683, 0x5688, 0x568b,
+ 0x568e, 0x5696, 0x5693, 0x5699, 0x569a, 0x56b0, 0x56b4, 0x56b8,
+ 0x56b9, 0x56ba, 0x56c2, 0x56cd, 0x56d6, 0x56d2, 0x56de, 0x56e1,
+ 0x56e5, 0x56e7, 0x56ea, 0x662f, 0x56fb, 0x5708, 0x5707, 0x5704,
+ 0x5729, 0x5724, 0x571e, 0x5725, 0x5726, 0x571b, 0x5737, 0x5738,
+ 0x5747, 0x575a, 0x5768, 0x576b, 0x575b, 0x5765, 0x577f, 0x577e,
+ 0x5779, 0x578e, 0x578b, 0x5791, 0x57a0, 0x579e, 0x57b0, 0x57b6,
+ 0x57b9, 0x57bf, 0x57bc, 0x57bd, 0x57bb, 0x57c7, 0x57cd, 0x57d7,
+ 0x57da, 0x57dc, 0x57e3, 0x57ee, 0x57fc, 0x580c, 0x5812, 0x5926,
+ 0x5820, 0x592a, 0x5845, 0x588e, 0x5874, 0x5886, 0x587c, 0x589a,
+ 0x588c, 0x58a3, 0x58b5, 0x58aa, 0x58af, 0x58d1, 0x58c6, 0x58cb,
+ 0x58d4, 0x58be, 0x58bc, 0x58c5, 0x58ca, 0x58ec,
+ /* 0x16321..0x1637E */
+ 0x58e7, 0x58da, 0x58fd, 0x58f4, 0x5907, 0x5912, 0x5911, 0x5919,
+ 0x592c, 0x592b, 0x5940, 0x5960, 0x5957, 0x595f, 0x595a, 0x5955,
+ 0x5953, 0x597a, 0x597f, 0x598a, 0x599d, 0x59a7, 0x7f4b, 0x59aa,
+ 0x59ae, 0x59b3, 0x59b9, 0x59ba, 0x59c9, 0x59d5, 0x59e7, 0x59ec,
+ 0x59e1, 0x59e3, 0x5a08, 0x5a0d, 0x5a18, 0x5a19, 0x5a20, 0x5a1f,
+ 0x5980, 0x5a31, 0x5a3b, 0x5a3e, 0x5a37, 0x5a43, 0x5a57, 0x5a49,
+ 0x5a61, 0x5a62, 0x5a69, 0x7f9d, 0x5a70, 0x5a79, 0x5a7d, 0x5a88,
+ 0x5a97, 0x5a95, 0x5a98, 0x5a96, 0x5aa9, 0x5ac8, 0x5ab0, 0x5ab6,
+ 0x5ac5, 0x5ac4, 0x5abf, 0x7083, 0x5ac7, 0x5aca, 0x5acd, 0x5acf,
+ 0x5ad5, 0x5ad3, 0x5ad9, 0x5ada, 0x5add, 0x5ae1, 0x5ae2, 0x5ae6,
+ 0x5aed, 0x5af0, 0x5b02, 0x5b0f, 0x5b0a, 0x5b06, 0x5b33, 0x5b18,
+ 0x5b19, 0x5b1e, 0x5b35, 0x5b28, 0x5b36, 0x5b50,
+ /* 0x16421..0x1647E */
+ 0x5b7a, 0x5b04, 0x5b4d, 0x5b0b, 0x5b4c, 0x5b45, 0x5b75, 0x5b65,
+ 0x5b74, 0x5b67, 0x5b70, 0x5b71, 0x5b6c, 0x5b6e, 0x5b9d, 0x5b98,
+ 0x5b9f, 0x5b8d, 0x5b9c, 0x5b9a, 0x5b8b, 0x5b92, 0x5b8f, 0x5b5d,
+ 0x5b99, 0x5bcb, 0x5bc1, 0x5bcc, 0x5bcf, 0x5bb4, 0x5bc6, 0x5bdd,
+ 0x5be9, 0x5c11, 0x5c14, 0x5be6, 0x5be5, 0x5c60, 0x5c00, 0x5c07,
+ 0x5c13, 0x5bf3, 0x5bf7, 0x5c17, 0x5c0d, 0x5bf6, 0x5c23, 0x5c27,
+ 0x5c2a, 0x5c1f, 0x5c37, 0x5c2b, 0x5c3d, 0x5c4c, 0x5c43, 0x5c54,
+ 0x5c4f, 0x5c40, 0x5c50, 0x5c58, 0x5c5f, 0x5c64, 0x5c56, 0x5c65,
+ 0x5c6c, 0x5c75, 0x5c83, 0x5c90, 0x5ca4, 0x5cad, 0x5ca2, 0x5cab,
+ 0x5ca1, 0x5ca8, 0x5cb3, 0x5cb2, 0x5cb1, 0x5cae, 0x5cb9, 0x5cbd,
+ 0x5cc0, 0x5cc5, 0x5cc2, 0x5cd8, 0x5cd2, 0x5cdc, 0x5ce2, 0x7b3b,
+ 0x5cef, 0x5cf2, 0x5cf4, 0x5cf6, 0x5cfa, 0x5d06,
+ /* 0x16521..0x1657E */
+ 0x5d02, 0x5d1c, 0x5d15, 0x5d0a, 0x5d45, 0x5d4b, 0x5d2e, 0x5d32,
+ 0x5d3f, 0x5d35, 0x5d46, 0x5d73, 0x5d56, 0x5d4e, 0x5d72, 0x5d68,
+ 0x5d6e, 0x5d4f, 0x5d63, 0x5d93, 0x5d89, 0x5d5b, 0x5d8f, 0x5d7d,
+ 0x5d9b, 0x5dba, 0x5dae, 0x5da3, 0x5db5, 0x5dc7, 0x5dbd, 0x5dab,
+ 0x5e3d, 0x5da2, 0x5daf, 0x5ddc, 0x5db8, 0x5d9f, 0x5db0, 0x5dd8,
+ 0x5ddd, 0x5de4, 0x5dde, 0x5dfb, 0x5df2, 0x5de1, 0x5e05, 0x5e0a,
+ 0x5e23, 0x5e21, 0x5e12, 0x5e31, 0x5e1f, 0x5e09, 0x5e0b, 0x5e22,
+ 0x5e46, 0x5e66, 0x5e3b, 0x5e35, 0x5e39, 0x5e43, 0x5e37, 0x5e32,
+ 0x5e3a, 0x5e67, 0x5e5d, 0x5e56, 0x5e5e, 0x5e59, 0x5e5a, 0x5e79,
+ 0x5e6a, 0x5e69, 0x5e7c, 0x5e7b, 0x5e83, 0x5dd5, 0x5e7d, 0x6fae,
+ 0x5e7f, 0x5e88, 0x5e89, 0x5e8c, 0x5e92, 0x5e90, 0x5e93, 0x5e94,
+ 0x5e96, 0x5e8e, 0x5e9b, 0x5e9c, 0x5f38, 0x5f3a,
+ /* 0x16621..0x1667E */
+ 0x5f45, 0x5f4c, 0x5f4d, 0x5f4e, 0x5f50, 0x5f51, 0x5f55, 0x5f54,
+ 0x5f58, 0x5f5f, 0x5f60, 0x5f68, 0x5f69, 0x5f67, 0x5f78, 0x5f82,
+ 0x5f86, 0x5f83, 0x5f88, 0x5f87, 0x5f8c, 0x5f94, 0x5f9e, 0x5f9d,
+ 0x5f9a, 0x5fa3, 0x5faf, 0x5fb2, 0x5fb9, 0x5fae, 0x5fb6, 0x5fb8,
+ 0x6b71, 0x5fc5, 0x5fc6, 0x5fca, 0x5fd5, 0x5fd4, 0x5fe1, 0x5fe6,
+ 0x5fe9, 0x5ff3, 0x5ff9, 0x78dc, 0x6006, 0x6004, 0x600b, 0x6012,
+ 0x6018, 0x6019, 0x601c, 0x6021, 0x6028, 0x603f, 0x603b, 0x604a,
+ 0x6046, 0x6052, 0x6058, 0x605a, 0x605f, 0x6062, 0x6068, 0x6073,
+ 0x6072, 0x6070, 0x6076, 0x6079, 0x607d, 0x607f, 0x6084, 0x6086,
+ 0x6085, 0x609b, 0x6093, 0x609a, 0x60ad, 0x3190, 0x60ac, 0x60db,
+ 0x60e5, 0x60d9, 0x60dd, 0x60c4, 0x60da, 0x60d6, 0x6109, 0x60ef,
+ 0x60f1, 0x611b, 0x6129, 0x6123, 0x612f, 0x614b,
+ /* 0x16721..0x1677E */
+ 0x768b, 0x6146, 0x613e, 0x6153, 0x6151, 0x60fc, 0x6171, 0x616e,
+ 0x6165, 0x6166, 0x6174, 0x6183, 0x6188, 0x618a, 0x6180, 0x6182,
+ 0x61a0, 0x6195, 0x61a4, 0x61a3, 0x615f, 0x6193, 0x61a9, 0x61b0,
+ 0x61b5, 0x61be, 0x61b8, 0x61bd, 0x61c0, 0x61c2, 0x61ba, 0x61c9,
+ 0x61cd, 0x61d1, 0x61d9, 0x61d8, 0x61c8, 0x61da, 0x61df, 0x61e0,
+ 0x61e7, 0x61fa, 0x61fb, 0x61fe, 0x6201, 0x6202, 0x6205, 0x6207,
+ 0x620a, 0x620d, 0x6210, 0x6216, 0x6229, 0x622b, 0x6238, 0x6233,
+ 0x6240, 0x6259, 0x6258, 0x625d, 0x625a, 0x625f, 0x6264, 0x6262,
+ 0x6268, 0x626a, 0x626b, 0x622e, 0x6271, 0x6277, 0x6278, 0x627e,
+ 0x628d, 0x6292, 0x62ab, 0x629f, 0x62bb, 0x62ac, 0x62e1, 0x62e3,
+ 0x62df, 0x62d2, 0x62f4, 0x62f3, 0x62fa, 0x6393, 0x6303, 0x62fb,
+ 0x62f9, 0x62de, 0x6306, 0x62dc, 0x6309, 0x62d9,
+ /* 0x16821..0x1687E */
+ 0x6335, 0x6334, 0x6316, 0x6332, 0x6331, 0x6340, 0x6339, 0x6350,
+ 0x6345, 0x632f, 0x632b, 0x6317, 0x6318, 0x6385, 0x639a, 0x63aa,
+ 0x639f, 0x63a2, 0x6396, 0x6323, 0x638e, 0x6387, 0x638a, 0x637c,
+ 0x63b5, 0x6373, 0x6375, 0x63a0, 0x6389, 0x63a8, 0x63f4, 0x6413,
+ 0x63eb, 0x63ce, 0x63fd, 0x6403, 0x63d8, 0x640b, 0x63c1, 0x63f7,
+ 0x6407, 0x63e0, 0x63f2, 0x640d, 0x6422, 0x6420, 0x63bd, 0x6438,
+ 0x6506, 0x63fb, 0x646d, 0x642a, 0x643c, 0x655a, 0x6484, 0x6477,
+ 0x646b, 0x64ad, 0x646e, 0x6482, 0x6469, 0x6446, 0x642c, 0x646f,
+ 0x6479, 0x6435, 0x64ca, 0x6462, 0x64b9, 0x64bf, 0x649f, 0x64d9,
+ 0x64cd, 0x64bb, 0x64da, 0x64d0, 0x64c1, 0x64c6, 0x64d6, 0x64a1,
+ 0x6521, 0x64ff, 0x64f4, 0x6517, 0x6518, 0x652c, 0x651f, 0x6515,
+ 0x6514, 0x64fc, 0x6540, 0x6563, 0x6558, 0x6548,
+ /* 0x16921..0x1697E */
+ 0x6541, 0x6602, 0x654b, 0x6555, 0x6580, 0x65a4, 0x6588, 0x6591,
+ 0x658a, 0x65a8, 0x656d, 0x6594, 0x659b, 0x65ea, 0x6587, 0x659c,
+ 0x6577, 0x657e, 0x6590, 0x65c9, 0x65ba, 0x65cf, 0x65b9, 0x65d0,
+ 0x65d5, 0x65dd, 0x65e5, 0x65dc, 0x65f9, 0x660a, 0x6613, 0x660b,
+ 0x65fe, 0x65fa, 0x6606, 0x6622, 0x661a, 0x6630, 0x663f, 0x664d,
+ 0x2e55, 0x6654, 0x665f, 0x6667, 0x6671, 0x6693, 0x66a3, 0x66a9,
+ 0x66aa, 0x668b, 0x668c, 0x66b6, 0x66af, 0x66c4, 0x66c6, 0x66b0,
+ 0x66c9, 0x6823, 0x66ab, 0x66d4, 0x66de, 0x66e9, 0x66ec, 0x66df,
+ 0x66db, 0x66ef, 0x6712, 0x6706, 0x6708, 0x6700, 0x6703, 0x66fb,
+ 0x6711, 0x6709, 0x670d, 0x66f9, 0x670a, 0x6734, 0x673f, 0x6737,
+ 0x673b, 0x6725, 0x6729, 0x671a, 0x6760, 0x675f, 0x6778, 0x674c,
+ 0x674e, 0x6774, 0x6757, 0x6768, 0x676e, 0x6759,
+ /* 0x16A21..0x16A7E */
+ 0x6753, 0x6763, 0x676a, 0x6805, 0x67a2, 0x679f, 0x6782, 0x67af,
+ 0x67cb, 0x67bd, 0x67c0, 0x67d0, 0x76d6, 0x67ab, 0x67c4, 0x67b3,
+ 0x67c7, 0x67c6, 0x67bb, 0x67ef, 0x67f2, 0x67e0, 0x680f, 0x680d,
+ 0x67fe, 0x67f6, 0x67f7, 0x680e, 0x67d2, 0x6811, 0x6816, 0x6815,
+ 0x6822, 0x6821, 0x6831, 0x6836, 0x6839, 0x6827, 0x683b, 0x6844,
+ 0x6842, 0x6852, 0x6859, 0x685e, 0x6862, 0x686b, 0x6881, 0x687e,
+ 0x689e, 0x6875, 0x687d, 0x68b5, 0x6872, 0x6882, 0x6897, 0x6892,
+ 0x68ae, 0x6899, 0x68a2, 0x688d, 0x68a4, 0x68b0, 0x68bf, 0x68b1,
+ 0x68c3, 0x68c4, 0x68d4, 0x68d8, 0x68d9, 0x68dd, 0x68f9, 0x6902,
+ 0x68fc, 0x68f4, 0x68e8, 0x68f2, 0x6904, 0x690c, 0x690a, 0x6913,
+ 0x6943, 0x691e, 0x6925, 0x692a, 0x692b, 0x6941, 0x6944, 0x693b,
+ 0x6936, 0x6938, 0x694c, 0x691d, 0x6960, 0x695e,
+ /* 0x16B21..0x16B7E */
+ 0x6966, 0x6964, 0x696d, 0x696a, 0x696f, 0x6974, 0x6977, 0x697e,
+ 0x6983, 0x6988, 0x698a, 0x6993, 0x6998, 0x69a1, 0x69a9, 0x69a6,
+ 0x69ac, 0x69af, 0x69b2, 0x69ba, 0x69bd, 0x69bf, 0x69c0, 0x69da,
+ 0x69dc, 0x69dd, 0x69e7, 0x69f4, 0x69f8, 0x6a03, 0x6a16, 0x6a10,
+ 0x6a0c, 0x6a1b, 0x6a1d, 0x6a25, 0x6a36, 0x6a41, 0x6a5b, 0x6a52,
+ 0x6a46, 0x6a48, 0x6a7c, 0x6a6d, 0x6a6c, 0x6a62, 0x6a85, 0x6a82,
+ 0x6a84, 0x6aa8, 0x6aa1, 0x6a91, 0x6aa5, 0x6aa6, 0x6a9a, 0x6aa3,
+ 0x6ac4, 0x6acd, 0x6ac2, 0x6ada, 0x6aeb, 0x6af3, 0x6ae7, 0x6ae4,
+ 0x6af1, 0x6b14, 0x6ae0, 0x6ae2, 0x6af7, 0x6ade, 0x6adb, 0x6b0c,
+ 0x6b07, 0x6b1a, 0x6ae1, 0x6b16, 0x6b10, 0x6b17, 0x6b20, 0x6b33,
+ 0x77ab, 0x6b26, 0x6b2b, 0x6b3e, 0x6b28, 0x6b41, 0x6b4c, 0x6b4f,
+ 0x6b4e, 0x6b49, 0x6b56, 0x6b5b, 0x6b5a, 0x6b6b,
+ /* 0x16C21..0x16C7E */
+ 0x6b5f, 0x6b6c, 0x6b6f, 0x6b74, 0x6b7d, 0x6b80, 0x6b8c, 0x6b8e,
+ 0x6b92, 0x6b93, 0x6b96, 0x6b99, 0x6b9a, 0x6c3a, 0x6c41, 0x6c3f,
+ 0x6c48, 0x6c4c, 0x6c4e, 0x6c50, 0x6c55, 0x6c62, 0x6c6c, 0x6c78,
+ 0x6c7a, 0x6c82, 0x6c89, 0x6c85, 0x6c8a, 0x6c8d, 0x6c8e, 0x6c94,
+ 0x6c7c, 0x6c98, 0x421d, 0x6cad, 0x6caa, 0x6cbd, 0x6cb2, 0x6cb3,
+ 0x6cae, 0x6cb6, 0x6cc8, 0x6cc1, 0x6ce4, 0x6ce3, 0x6cda, 0x6cfd,
+ 0x6cfa, 0x6cfb, 0x6d04, 0x6d05, 0x6d0a, 0x6d07, 0x6d0f, 0x6d0d,
+ 0x6d10, 0x7f4e, 0x6d13, 0x6ccd, 0x6d14, 0x6d16, 0x6d67, 0x6d6d,
+ 0x6d71, 0x6d73, 0x6d81, 0x6d99, 0x6dc2, 0x6dbe, 0x6dba, 0x6dcf,
+ 0x6dda, 0x6dd6, 0x6dcc, 0x6ddb, 0x6dcb, 0x6dea, 0x6deb, 0x6ddf,
+ 0x6de3, 0x6dfc, 0x6e08, 0x6e09, 0x6dff, 0x6e1d, 0x6e1e, 0x6e10,
+ 0x6e1f, 0x6e42, 0x6e35, 0x6e30, 0x6e34, 0x6e4a,
+ /* 0x16D21..0x16D7E */
+ 0x6e47, 0x6e49, 0x6e4c, 0x6e50, 0x6e48, 0x6e59, 0x6e64, 0x6e60,
+ 0x6e2a, 0x6e63, 0x6e55, 0x6e76, 0x6e72, 0x6e7c, 0x6e81, 0x6e87,
+ 0x6e85, 0x6e84, 0x6e8b, 0x6e8a, 0x6e93, 0x6e91, 0x6e94, 0x6e99,
+ 0x6eaa, 0x6ea1, 0x6eac, 0x6eb0, 0x6ec6, 0x6eb1, 0x6ebe, 0x6ec5,
+ 0x6ec8, 0x6ecb, 0x6edb, 0x6ee3, 0x6efc, 0x6efb, 0x6eeb, 0x6efe,
+ 0x6f0a, 0x6f05, 0x6f15, 0x6f12, 0x6f19, 0x6f13, 0x6f1c, 0x6f1f,
+ 0x6f1b, 0x6f0c, 0x6f26, 0x6f33, 0x6f3b, 0x6f39, 0x6f45, 0x6f42,
+ 0x6f3e, 0x6f4c, 0x6f49, 0x6f46, 0x6f4e, 0x6f57, 0x6f5c, 0x6f62,
+ 0x6f63, 0x6f64, 0x6f9c, 0x6f9f, 0x6fa3, 0x6fad, 0x6faf, 0x6fb7,
+ 0x6fda, 0x6fe5, 0x6fe2, 0x6fea, 0x6fef, 0x7087, 0x6ff4, 0x7005,
+ 0x6ff9, 0x6ffa, 0x7011, 0x7015, 0x7021, 0x700d, 0x701e, 0x7016,
+ 0x700b, 0x7027, 0x7036, 0x7035, 0x7039, 0x6ff8,
+ /* 0x16E21..0x16E7E */
+ 0x704f, 0x7050, 0x7051, 0x7052, 0x700e, 0x7049, 0x703e, 0x7056,
+ 0x7058, 0x705e, 0x7068, 0x706f, 0x7076, 0x76a8, 0x7072, 0x7082,
+ 0x707d, 0x7081, 0x7080, 0x708a, 0x7089, 0x708f, 0x70a8, 0x70af,
+ 0x70b1, 0x70b5, 0x70e2, 0x70e4, 0x4248, 0x70db, 0x7102, 0x7112,
+ 0x7119, 0x7132, 0x7130, 0x714a, 0x7156, 0x7158, 0x7163, 0x7165,
+ 0x7169, 0x7173, 0x7172, 0x718b, 0x7189, 0x7182, 0x71a2, 0x71ab,
+ 0x71af, 0x71aa, 0x71b5, 0x71b4, 0x71ba, 0x71c0, 0x71c1, 0x71c9,
+ 0x71cb, 0x71d0, 0x71d6, 0x71df, 0x71e1, 0x71db, 0x71fc, 0x71f5,
+ 0x71f6, 0x721e, 0x71ff, 0x7214, 0x722c, 0x7215, 0x7211, 0x725e,
+ 0x7257, 0x7245, 0x7249, 0x7264, 0x7248, 0x7295, 0x723f, 0x724b,
+ 0x7250, 0x729c, 0x7296, 0x7293, 0x729b, 0x725a, 0x72cf, 0x72b9,
+ 0x72b7, 0x72e9, 0x730f, 0x72fa, 0x7344, 0x732e,
+ /* 0x16F21..0x16F7E */
+ 0x7319, 0x7322, 0x731a, 0x7323, 0x733a, 0x7335, 0x733b, 0x735c,
+ 0x7360, 0x737c, 0x736e, 0x7356, 0x73b0, 0x73ac, 0x73ad, 0x7394,
+ 0x73b9, 0x73d6, 0x73d7, 0x73e8, 0x73e5, 0x73d8, 0x73c3, 0x73dd,
+ 0x73d0, 0x73c8, 0x73e4, 0x741a, 0x7414, 0x7413, 0x7403, 0x7407,
+ 0x7410, 0x7436, 0x742b, 0x7435, 0x7421, 0x743a, 0x7441, 0x7452,
+ 0x7444, 0x745b, 0x7460, 0x7462, 0x745e, 0x746a, 0x7229, 0x7470,
+ 0x7475, 0x7477, 0x747d, 0x745a, 0x747c, 0x747e, 0x7481, 0x747f,
+ 0x7582, 0x7587, 0x758a, 0x7594, 0x7596, 0x7598, 0x7599, 0x75a0,
+ 0x75a8, 0x75a7, 0x75ad, 0x75bc, 0x75bb, 0x75b9, 0x75be, 0x75ca,
+ 0x4ff6, 0x75c3, 0x75cd, 0x75cc, 0x75d5, 0x75d4, 0x75d6, 0x75dc,
+ 0x75e1, 0x75e5, 0x75e2, 0x7621, 0x7628, 0x762e, 0x762f, 0x7642,
+ 0x764c, 0x764f, 0x764b, 0x7677, 0x765c, 0x765e,
+ /* 0x17021..0x1707E */
+ 0x765d, 0x765f, 0x7666, 0x7672, 0x766c, 0x768d, 0x7698, 0x7695,
+ 0x7697, 0x76aa, 0x76a7, 0x76b1, 0x76b2, 0x76b0, 0x76b4, 0x76b6,
+ 0x76b8, 0x76b9, 0x76ce, 0x76cb, 0x76c9, 0x76cd, 0x694d, 0x76dc,
+ 0x770d, 0x76d5, 0x76f9, 0x7704, 0x7706, 0x7708, 0x7713, 0x770e,
+ 0x7711, 0x770f, 0x7716, 0x7719, 0x7724, 0x772a, 0x7730, 0x7739,
+ 0x773d, 0x773e, 0x7744, 0x7746, 0x7748, 0x7742, 0x7749, 0x775c,
+ 0x7760, 0x7764, 0x7766, 0x7768, 0x32d2, 0x776b, 0x7771, 0x7779,
+ 0x7785, 0x777c, 0x7781, 0x777a, 0x7786, 0x778b, 0x778f, 0x7790,
+ 0x779c, 0x77a8, 0x77a6, 0x77a3, 0x77b3, 0x77b4, 0x77c3, 0x77c6,
+ 0x77c8, 0x77cb, 0x77dc, 0x77ed, 0x7f4f, 0x77f2, 0x5adf, 0x77f6,
+ 0x77f5, 0x780f, 0x780c, 0x7838, 0x7824, 0x7821, 0x7837, 0x783d,
+ 0x7846, 0x784f, 0x784b, 0x786b, 0x786f, 0x7870,
+ /* 0x17121..0x1717E */
+ 0x7871, 0x7874, 0x7873, 0x78aa, 0x78af, 0x78b1, 0x78b6, 0x78c4,
+ 0x78c3, 0x78c6, 0x78e9, 0x78eb, 0x7903, 0x7909, 0x7912, 0x7914,
+ 0x7918, 0x7921, 0x791d, 0x791e, 0x7924, 0x7920, 0x792c, 0x792e,
+ 0x793d, 0x793e, 0x7942, 0x7949, 0x7945, 0x7950, 0x794b, 0x7951,
+ 0x7952, 0x794c, 0x7955, 0x7997, 0x7998, 0x79a5, 0x79ad, 0x79ae,
+ 0x79bc, 0x79df, 0x79db, 0x79dd, 0x79d8, 0x79d1, 0x79ed, 0x79ee,
+ 0x79f1, 0x79f2, 0x79fb, 0x79f8, 0x7a01, 0x7a0f, 0x7a05, 0x79e2,
+ 0x7a19, 0x7a2b, 0x7a37, 0x7a45, 0x7a42, 0x7a40, 0x7a43, 0x7a3e,
+ 0x7a55, 0x7a4d, 0x7a5b, 0x7a57, 0x7a5f, 0x7a62, 0x7a65, 0x7a64,
+ 0x7a69, 0x7a6b, 0x7a6a, 0x7aad, 0x7ab0, 0x7abc, 0x7ac0, 0x7acf,
+ 0x7ad1, 0x7ad3, 0x7ad4, 0x7ade, 0x7adf, 0x7ae2, 0x7ae3, 0x7ae6,
+ 0x7aef, 0x7aeb, 0x7aee, 0x7af4, 0x7af1, 0x7af7,
+ /* 0x17221..0x1727E */
+ 0x7afb, 0x7b06, 0x7b18, 0x7b1a, 0x7b1f, 0x7b22, 0x7b23, 0x7b25,
+ 0x7b27, 0x7b28, 0x7b29, 0x7b2a, 0x7b2e, 0x7b2f, 0x7b32, 0x7b44,
+ 0x7b43, 0x7b4f, 0x7b4d, 0x7b4e, 0x7b51, 0x7b58, 0x7b74, 0x7b93,
+ 0x7b83, 0x7b91, 0x7b96, 0x7b97, 0x7b9f, 0x7ba0, 0x7ba8, 0x7bb4,
+ 0x7bc0, 0x7bca, 0x7bb9, 0x7bc6, 0x7bcf, 0x7bd1, 0x7bd2, 0x7be3,
+ 0x7be2, 0x7be4, 0x7bd4, 0x7be1, 0x7c3a, 0x7bf2, 0x7bf1, 0x7bf0,
+ 0x7c15, 0x7c14, 0x7c09, 0x7c13, 0x7c0c, 0x7c06, 0x7c08, 0x7c12,
+ 0x7c0a, 0x7c04, 0x7c2e, 0x7c1b, 0x7c25, 0x7c24, 0x7c21, 0x7c30,
+ 0x7c47, 0x7c32, 0x7c46, 0x7c3e, 0x7c5a, 0x7c60, 0x7c67, 0x7c76,
+ 0x7c78, 0x7ce7, 0x7cec, 0x7cf0, 0x7d09, 0x7d08, 0x7ceb, 0x7d03,
+ 0x7d06, 0x7d2a, 0x7d26, 0x7daf, 0x7d23, 0x7d1f, 0x7d44, 0x7d15,
+ 0x7d12, 0x7d41, 0x7d3f, 0x7d3e, 0x7d46, 0x7d48,
+ /* 0x17321..0x1737E */
+ 0x7d5d, 0x7d5e, 0x7d64, 0x7d51, 0x7d50, 0x7d59, 0x7d72, 0x7d89,
+ 0x7d87, 0x7dab, 0x7d6f, 0x7d7a, 0x7d9a, 0x7da4, 0x7da9, 0x7db2,
+ 0x7dc4, 0x7dc1, 0x7dbb, 0x7db8, 0x7dba, 0x7dc6, 0x7dcf, 0x7dc2,
+ 0x7dd9, 0x7dd3, 0x7df8, 0x7de6, 0x7ded, 0x7def, 0x7dfd, 0x7e1a,
+ 0x7e1b, 0x7e1e, 0x7e75, 0x7e79, 0x7e7d, 0x7e81, 0x7e88, 0x7e8b,
+ 0x7e8c, 0x7e92, 0x7e95, 0x7e91, 0x7e9d, 0x7ea5, 0x7ea9, 0x7eb8,
+ 0x7eaa, 0x7ead, 0x7761, 0x7ecc, 0x7ece, 0x7ecf, 0x7ed0, 0x7ed4,
+ 0x7edc, 0x7ede, 0x7edd, 0x7ee0, 0x7ee5, 0x7ee8, 0x7eef, 0x7ef4,
+ 0x7ef6, 0x7ef7, 0x7ef9, 0x7efb, 0x7efc, 0x7efd, 0x7f07, 0x7f08,
+ 0x56b7, 0x7f15, 0x7f21, 0x7f2c, 0x7f3e, 0x7f4a, 0x7f52, 0x7f54,
+ 0x7f63, 0x7f5f, 0x7f60, 0x7f61, 0x7f66, 0x7f67, 0x7f6c, 0x7f6a,
+ 0x7f77, 0x7f72, 0x7f76, 0x7f95, 0x7f9c, 0x7fa0,
+ /* 0x17421..0x1747E */
+ 0x382f, 0x49c7, 0x7059, 0x5464, 0x31dc, 0x5199, 0x0000, 0x3de2,
+ 0x3e14, 0x3e18, 0x3e58, 0x3e5e, 0x3ebe, 0x8028, 0x3ecb, 0x3ef9,
+ 0x3f00, 0x3f02, 0x3f07, 0x3f1d, 0x3f23, 0x3f34, 0x3f36, 0x3f3d,
+ 0x3f40, 0x3f45, 0x3f54, 0x3f58, 0x3f64, 0x3f67, 0x3f7d, 0x3f89,
+ 0x3f9c, 0x3fa7, 0x3faf, 0x3fb5, 0x3fb7, 0x3fc9, 0x3fde, 0x3fe1,
+ 0x3fe9, 0x400d, 0x4014, 0x4018, 0x4033, 0x4035, 0x4047, 0x813d,
+ 0x409d, 0x409e, 0x40cb, 0x40d4, 0x40d5, 0x40dd, 0x40f8, 0x411c,
+ 0x412b, 0x4130, 0x4137, 0x813e, 0x418d, 0x813f, 0x41bc, 0x41b9,
+ 0x8140, 0x4222, 0x423e, 0x4243, 0x4256, 0x425a, 0x426f, 0x4285,
+ 0x42c4, 0x42d6, 0x42fc, 0x430a, 0x4318, 0x4339, 0x4343, 0x4365,
+ 0x437c, 0x43e5, 0x43ed, 0x43f5, 0x4410, 0x4414, 0x4422, 0x4479,
+ 0x4451, 0x4460, 0x446d, 0x44ce, 0x44be, 0x44bf,
+ /* 0x17521..0x1757E */
+ 0x44c4, 0x44ca, 0x44d0, 0x44f7, 0x44fb, 0x4522, 0x4529, 0x8141,
+ 0x4567, 0x459d, 0x8142, 0x4600, 0x4609, 0x4615, 0x461e, 0x463a,
+ 0x4622, 0x4624, 0x462b, 0x4630, 0x4631, 0x4633, 0x46fb, 0x4648,
+ 0x464c, 0xa7c4, 0x4659, 0x465a, 0x4661, 0x4665, 0x4673, 0x4677,
+ 0x4678, 0x468d, 0x8143, 0x46a0, 0x46b2, 0x46bb, 0x46c6, 0x46c8,
+ 0x1b22, 0x46db, 0x46e8, 0x46fa, 0x4713, 0x8029, 0x4733, 0x4766,
+ 0x4747, 0x4748, 0x477b, 0x4781, 0x4793, 0x4798, 0x479b, 0x47bb,
+ 0x47f9, 0x47c0, 0x47d7, 0x47fc, 0x4801, 0x4852, 0x481d, 0x482c,
+ 0x4831, 0x485b, 0x4872, 0x4875, 0x8144, 0x48a3, 0x48a5, 0x48b2,
+ 0x48c8, 0x48d0, 0x48e8, 0x48ed, 0x48f0, 0x48f1, 0x48fc, 0x490a,
+ 0x4949, 0xaac4, 0x4935, 0x4942, 0x4957, 0x4963, 0x4964, 0x4968,
+ 0x4980, 0x8114, 0x49a5, 0x49ad, 0x49cf, 0x1bb6,
+ /* 0x17621..0x1767E */
+ 0x1bc3, 0x49e2, 0x49e9, 0x49ea, 0x49f5, 0x49f6, 0x4a0f, 0x4a15,
+ 0xac3f, 0x4a3b, 0x4a3e, 0x4a45, 0x4a50, 0x4a56, 0x4a5b, 0x4a6b,
+ 0x4a73, 0xac63, 0x4a89, 0x4a94, 0x4a9d, 0x4a9e, 0x4aa5, 0x4ae4,
+ 0x4ae7, 0x1c0f, 0x801d, 0x4b1b, 0x4b1e, 0x4b2c, 0x4b35, 0x4b46,
+ 0x4b56, 0x4b60, 0x4b65, 0x4b67, 0x4b77, 0x4b82, 0x4ba9, 0x4bad,
+ 0x8070, 0x4bcf, 0x4bd6, 0x4bd7, 0x4bff, 0x4c05, 0x4c10, 0x4c33,
+ 0x4c59, 0x4c5c, 0x4caa, 0x4c74, 0x4c76, 0x4c85, 0x4c86, 0x4c98,
+ 0x4c9c, 0x4cfb, 0x4cc6, 0x4cd4, 0x4ce0, 0x4ceb, 0x4cee, 0xaffe,
+ 0x4d04, 0x4d0e, 0x4d2e, 0x4d31, 0x4d39, 0x4d3f, 0x4d58, 0x4d65,
+ 0x8145, 0x4d82, 0x4d87, 0x4d89, 0x4d94, 0x4daa, 0x4dac, 0x4dbf,
+ 0x4dc4, 0x4dd6, 0x4dda, 0x4ddb, 0x4ddd, 0x4dfc, 0x8146, 0x4e34,
+ 0x4e44, 0x4e5c, 0x4e5e, 0x4eab, 0x4eb1, 0x4ec1,
+ /* 0x17721..0x1777E */
+ 0x4ec7, 0x4ece, 0x4f10, 0x4f1a, 0x8147, 0x4f2a, 0x4f2f, 0x4f33,
+ 0x4f51, 0x4f59, 0x4f5e, 0x4f61, 0x4f62, 0x4f7e, 0x4f88, 0x4f8c,
+ 0x4f8d, 0x4f94, 0x4fa0, 0x4fa7, 0x4fb6, 0x4fbc, 0x4fc7, 0x4fca,
+ 0x4ff9, 0x4ff0, 0x4ff5, 0x5005, 0x5006, 0x5028, 0x504a, 0x505d,
+ 0x505e, 0x504e, 0x5064, 0x5075, 0x5085, 0x50a4, 0x50ab, 0x50b7,
+ 0x50d4, 0x50d8, 0x50e4, 0x510f, 0x512b, 0x511e, 0x5120, 0x512e,
+ 0x5130, 0x5146, 0x5147, 0x5151, 0x8148, 0x5152, 0x515c, 0x5160,
+ 0x5168, 0x8115, 0x5185, 0x5187, 0x5192, 0x51c1, 0x51ba, 0x51c4,
+ 0x51fe, 0x5200, 0x5215, 0x5255, 0x5256, 0x1e3f, 0x528d, 0x529b,
+ 0x52be, 0x52c0, 0x52fb, 0xb6f1, 0x5327, 0x5328, 0x8116, 0x5350,
+ 0x5366, 0x537c, 0x5395, 0x539f, 0x53a0, 0x53a2, 0x53a6, 0x53ab,
+ 0x53c9, 0x53cf, 0x53d6, 0x53d9, 0x53e3, 0x53e9,
+ /* 0x17821..0x1787E */
+ 0x5407, 0x540a, 0x541a, 0x541b, 0x814a, 0x5426, 0x5428, 0x542a,
+ 0x542b, 0x542c, 0x542e, 0x542f, 0x5430, 0x5444, 0x5446, 0x5447,
+ 0x544b, 0x5457, 0x5462, 0x546b, 0x546d, 0x5486, 0x5487, 0x5489,
+ 0x5498, 0x549c, 0x549f, 0x54a3, 0x5490, 0x54a6, 0x54a8, 0x54a9,
+ 0x54b5, 0x54bf, 0x54c8, 0x54c9, 0x54da, 0x54ff, 0x5501, 0x5517,
+ 0x552f, 0x556f, 0x5579, 0x5592, 0x1f72, 0x55ce, 0x55e4, 0x5600,
+ 0x5602, 0x5608, 0x5615, 0x5616, 0x5619, 0x561e, 0x562d, 0x5635,
+ 0x5643, 0x564b, 0x5664, 0x5665, 0x566d, 0x566f, 0x5671, 0x5681,
+ 0x569b, 0x569d, 0x569e, 0x56a6, 0x56aa, 0x56b6, 0x56c5, 0x56cc,
+ 0x56ce, 0x56d4, 0x56e6, 0x56f1, 0x56fc, 0x570a, 0x5719, 0x5734,
+ 0x5736, 0x5746, 0x574d, 0x574e, 0x575c, 0x575f, 0x5762, 0x577a,
+ 0x5780, 0x5794, 0x57aa, 0x57e0, 0x582d, 0xc08e,
+ /* 0x17921..0x1797E */
+ 0x5843, 0x584e, 0x584f, 0x5851, 0x5868, 0x586e, 0x814b, 0x58b0,
+ 0xc10e, 0x58ad, 0x58e4, 0x58f2, 0x5900, 0x58f7, 0x591c, 0x592e,
+ 0x5931, 0x5934, 0x814c, 0x814d, 0x5945, 0x5946, 0x814e, 0x814f,
+ 0x8150, 0x595c, 0x8151, 0x8119, 0x811a, 0x5979, 0x8152, 0x8153,
+ 0x811b, 0x5998, 0x59b1, 0x59b8, 0x59c8, 0x59ca, 0xc271, 0x59d4,
+ 0x59de, 0x59eb, 0x59ed, 0x5a03, 0x8154, 0x5a39, 0x5a5d, 0x5a6d,
+ 0x8155, 0x5a85, 0x5aa0, 0xc3c4, 0x5ab3, 0x5abb, 0x5ace, 0x5aeb,
+ 0x5afd, 0x5b12, 0x5b2d, 0x5b3b, 0x5b47, 0x5b4e, 0x5b60, 0x5b6d,
+ 0x5b6f, 0x5b72, 0x5b9e, 0x8156, 0x5bd7, 0x5bd9, 0x5c01, 0x5c31,
+ 0x5c1e, 0x5c20, 0x5c33, 0x5c36, 0x2264, 0xc6a1, 0x5c59, 0x5c6d,
+ 0x5c79, 0x5c8f, 0x5c94, 0x5ca0, 0x5cbc, 0x5cd5, 0x5cd9, 0x5cdd,
+ 0x5d07, 0x5d08, 0x5d13, 0x5d1d, 0x5d23, 0x5d31,
+ /* 0x17A21..0x17A7E */
+ 0x5d41, 0x5d48, 0x5d53, 0x5d5c, 0x5d7a, 0x5d83, 0x5d8b, 0x5da0,
+ 0x5da6, 0x5dc2, 0x5dcc, 0x5dd6, 0x5de3, 0x8157, 0x5e28, 0x5e08,
+ 0x5e11, 0x5e15, 0x8159, 0x5e47, 0x5e52, 0x5e61, 0x5e8a, 0x5e8d,
+ 0x5f47, 0x815a, 0x5f91, 0x5f97, 0x5fbf, 0x5fce, 0x5fdb, 0x5fdf,
+ 0x5fec, 0x5fee, 0x5ffa, 0x815b, 0x6014, 0x6026, 0x6035, 0x6037,
+ 0x603c, 0x60ca, 0x60d7, 0x60e0, 0x60f3, 0x6118, 0x614a, 0x6160,
+ 0x6167, 0x6168, 0x616d, 0x61bb, 0x61ca, 0x61cf, 0x61d7, 0x815c,
+ 0x2453, 0x245b, 0x6260, 0x6274, 0xd1ff, 0x628e, 0x62a1, 0x62a3,
+ 0x62a4, 0x62a9, 0x62ae, 0x62b7, 0x62be, 0x62bf, 0x62c6, 0x62d5,
+ 0x62fd, 0x62fe, 0x6300, 0x6301, 0x6362, 0x6322, 0x632d, 0x633a,
+ 0x6343, 0x6347, 0x6351, 0x6355, 0x637d, 0x6386, 0x6392, 0x6398,
+ 0x63a7, 0x63a9, 0x63bf, 0x63c0, 0x63c7, 0x63cf,
+ /* 0x17B21..0x17B7E */
+ 0x63d1, 0x63e1, 0x63ea, 0x6401, 0x6406, 0x640a, 0x815f, 0x6448,
+ 0x645f, 0x6470, 0x6473, 0x6485, 0x649e, 0x64af, 0x64b4, 0x64ba,
+ 0x64c0, 0x64c2, 0xd340, 0x6532, 0x651e, 0x6523, 0x652f, 0x6559,
+ 0x6564, 0x811f, 0x65ad, 0x657a, 0x658c, 0x658f, 0x65a2, 0x65b0,
+ 0x65cb, 0x65ce, 0x65ed, 0x6612, 0x65ff, 0x6604, 0x6605, 0x6610,
+ 0xd574, 0x6618, 0x6629, 0x6638, 0x6657, 0x665b, 0x8036, 0x6662,
+ 0x259d, 0x666c, 0x6675, 0x6698, 0x66b8, 0x66fa, 0x66fc, 0x66fd,
+ 0x670b, 0x6771, 0x6787, 0x6788, 0x67ac, 0x67ad, 0x67b5, 0x25ea,
+ 0x67d6, 0x67ec, 0x6806, 0x680a, 0x6810, 0x6814, 0x681f, 0x6898,
+ 0x68aa, 0x68ca, 0x68ce, 0xd784, 0x68f5, 0x691c, 0x8160, 0x6918,
+ 0x6919, 0x691a, 0x6927, 0x6930, 0x6932, 0x6939, 0x6940, 0x6994,
+ 0x8161, 0x69d4, 0x69e5, 0x69f6, 0x6a12, 0x6a15,
+ /* 0x17C21..0x17C7E */
+ 0x6a22, 0x6a37, 0x6a47, 0x6a4e, 0x6a5d, 0x6a61, 0x6a75, 0x6a79,
+ 0x6aa7, 0x6ad0, 0x6adf, 0x6af4, 0x6af6, 0x8122, 0x8162, 0x8163,
+ 0x6b46, 0x6b54, 0x6b59, 0x6b69, 0x6b9d, 0x6c49, 0x6c68, 0x8164,
+ 0x6ce1, 0x6cf4, 0x6cf8, 0x6cfe, 0x8165, 0x6d12, 0x6d1b, 0x6daf,
+ 0x6dce, 0x6dd1, 0x6dd7, 0x6e20, 0x6e23, 0x6e3d, 0x6e70, 0x6e7b,
+ 0xe077, 0x6ec0, 0x2844, 0x6efa, 0x6f1e, 0x6f2d, 0x6f36, 0x6f54,
+ 0xe14d, 0x6fa6, 0x6fb5, 0x6fe4, 0x6fe8, 0x6fee, 0x7008, 0x702d,
+ 0x8167, 0x7088, 0x7095, 0x7097, 0x7099, 0x709b, 0x70a2, 0x70b3,
+ 0x70be, 0x70c4, 0x70c5, 0x70c7, 0x70d7, 0x70dd, 0x70de, 0x70ef,
+ 0x70f4, 0x8126, 0x7114, 0x7115, 0x7116, 0x7122, 0x7123, 0x7127,
+ 0x712f, 0x7131, 0x7134, 0x713d, 0x7148, 0x715b, 0x7183, 0x719e,
+ 0x71ac, 0x71b1, 0x71bc, 0x71d7, 0x71fb, 0x71e4,
+ /* 0x17D21..0x17D7E */
+ 0x71e5, 0x71ed, 0x71f1, 0x7207, 0x7210, 0x7238, 0x7239, 0x723a,
+ 0x723c, 0x7240, 0x7243, 0x724f, 0x7278, 0x7288, 0x72c2, 0x72cb,
+ 0x72cc, 0x72d3, 0x72e0, 0x72ff, 0x7304, 0x731f, 0x7321, 0x7325,
+ 0x7348, 0x7349, 0x734a, 0x7364, 0x7365, 0x736a, 0x7370, 0x739b,
+ 0x73a3, 0x73ba, 0x73c6, 0x73de, 0x73df, 0x7404, 0x73fd, 0x7433,
+ 0x744a, 0x7463, 0x746b, 0x7471, 0x7472, 0x758e, 0x759f, 0x75a6,
+ 0x75a9, 0x75ac, 0x75b6, 0x75bd, 0x75cb, 0x75d0, 0x75d3, 0x29b0,
+ 0x75da, 0x75de, 0x7658, 0x7684, 0x80dc, 0x769d, 0x76a4, 0x76a5,
+ 0x76d2, 0x76de, 0x8168, 0x76e9, 0x76ef, 0x7733, 0x773b, 0x774d,
+ 0x774e, 0x774f, 0x775a, 0x776e, 0x7773, 0x7795, 0x77ae, 0x77ba,
+ 0x77c1, 0x77c9, 0x77de, 0x77db, 0x77f4, 0x8169, 0x780a, 0x781e,
+ 0x782b, 0x7830, 0x816a, 0x7852, 0x7853, 0x7856,
+ /* 0x17E21..0x17E7E */
+ 0x7857, 0x7859, 0x785a, 0x80d0, 0x7865, 0x786c, 0x78ba, 0x78c8,
+ 0x78e7, 0x7958, 0x799e, 0x7a02, 0x7a03, 0x7a24, 0x7a2d, 0x7a2e,
+ 0x7a38, 0x7a4a, 0x7a4e, 0x7a52, 0x7ab6, 0x7ac1, 0x7ac3, 0x7ace,
+ 0x7ad6, 0x7af9, 0x7b02, 0x7b08, 0x7b20, 0x2c17, 0x7b2d, 0x7b5e,
+ 0x7b79, 0x7b66, 0x7b72, 0x7b75, 0x7b84, 0x7b8a, 0x7b8f, 0x7b9e,
+ 0x7ba7, 0x7bc1, 0x7bce, 0x7be5, 0x7bf8, 0x7bfd, 0x7c00, 0x7c23,
+ 0x7c41, 0x7c4f, 0x7c50, 0x7c53, 0x7c63, 0x7c65, 0x7c77, 0x7d1d,
+ 0x7d1e, 0x7d43, 0x7d47, 0x7d52, 0x7d63, 0x7d70, 0x7d7c, 0x7d8a,
+ 0x7d96, 0x7dc0, 0x7dac, 0x7dbc, 0x7dd7, 0xf590, 0x7de7, 0x7e07,
+ 0x7e15, 0x7e7c, 0x7e9e, 0x7ea4, 0x7eac, 0x7eaf, 0x7eb4, 0x7eb5,
+ 0x7ec3, 0x7ed1, 0x7f10, 0x7f39, 0x7f57, 0x7f90, 0x7f94, 0x7f97,
+ 0x7fa2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x22121..0x2217E */
+ 0x8489, 0x2e02, 0x2e0f, 0x2e12, 0x2e29, 0x2e2b, 0x2e2e, 0x2e40,
+ 0x2e47, 0x2e48, 0x84a2, 0x2e51, 0x1406, 0x84a4, 0x2e5a, 0x2e69,
+ 0x2e9d, 0x142c, 0x142e, 0x2eb9, 0x2ebb, 0x8522, 0x2ebc, 0x2ec3,
+ 0x2ec8, 0x2ed0, 0x2eeb, 0x2eda, 0x2ef1, 0x2ef5, 0x2f00, 0x2f16,
+ 0x2f64, 0x2f37, 0x2f3e, 0x2f54, 0x2f58, 0x8593, 0x2f77, 0x2f78,
+ 0x2f7a, 0x2f7d, 0x2f82, 0x2f85, 0x2f92, 0x2f9a, 0x2fe6, 0x2fb2,
+ 0x2fbe, 0x2fc5, 0x2fcb, 0x2fcf, 0x2fd2, 0x146a, 0x2ff2, 0x3000,
+ 0x3010, 0x3013, 0x301c, 0x301e, 0x3022, 0x1468, 0x3042, 0x3046,
+ 0x304e, 0x3053, 0x3057, 0x3063, 0x3066, 0x306a, 0x3070, 0x30a3,
+ 0x3088, 0x3092, 0x3093, 0x3095, 0x3096, 0x309c, 0x30aa, 0x862b,
+ 0x30b1, 0x30ba, 0x30bb, 0x30c4, 0x30c7, 0x30f3, 0x8681, 0x30ce,
+ 0x8671, 0x30d4, 0x30d9, 0x30e1, 0x30e9, 0x1492,
+ /* 0x22321..0x2237E */
+ 0x3108, 0x86f9, 0x3117, 0x311b, 0x874a, 0x3160, 0x8809, 0x3173,
+ 0x3183, 0x318b, 0x14bc, 0x3198, 0x31a3, 0x31ad, 0x14c7, 0x31bc,
+ 0x88d6, 0x8928, 0x31f3, 0x31f4, 0x3202, 0x3212, 0x3216, 0x8a4f,
+ 0x3255, 0x325c, 0x326c, 0x3277, 0x3284, 0x3282, 0x8b07, 0x3298,
+ 0x8b3a, 0x32a4, 0x32a6, 0x32af, 0x32ba, 0x32bb, 0x32ca, 0x151f,
+ 0x32d1, 0x8bb9, 0x32f7, 0x330a, 0x330b, 0x3324, 0x3335, 0x333e,
+ 0x3342, 0x8c7c, 0x8c9d, 0x3367, 0x336c, 0x337a, 0x33a4, 0x33b4,
+ 0x8d53, 0x33b7, 0x33c0, 0x8d9d, 0x155d, 0x155e, 0x33d5, 0x33da,
+ 0x1563, 0x33f4, 0x33f5, 0x3455, 0x3424, 0x3428, 0x156e, 0x3443,
+ 0x3462, 0x3466, 0x346c, 0x348a, 0x348d, 0x3495, 0x34a0, 0x34a6,
+ 0x34ad, 0x34ae, 0x34b7, 0x34ba, 0x34bf, 0x34c3, 0x8e45, 0x34ec,
+ 0x34ef, 0x34f1, 0x34f3, 0x3500, 0x3501, 0x3509,
+ /* 0x22421..0x2247E */
+ 0x353c, 0x3541, 0x15a6, 0x3547, 0x354a, 0x15a8, 0x3560, 0x3561,
+ 0x3564, 0x8ee1, 0x357d, 0x3582, 0x3588, 0x3591, 0x15c5, 0x35d2,
+ 0x8f95, 0x8f6d, 0x35bf, 0x35c9, 0x35cc, 0x35d1, 0x35dd, 0x15da,
+ 0x35e2, 0x8f64, 0x35e9, 0x3628, 0x905f, 0x3607, 0x3610, 0x3630,
+ 0x3637, 0x15f4, 0x363d, 0x363f, 0x3640, 0x3647, 0x365e, 0x3660,
+ 0x366d, 0x1605, 0x3688, 0x368c, 0x3695, 0x369a, 0x369d, 0x36a8,
+ 0x36ad, 0x36b2, 0x36c5, 0x36cd, 0x36df, 0x36e8, 0x36f6, 0x36f7,
+ 0x9101, 0x3715, 0x3723, 0x9155, 0x3729, 0x917b, 0x3745, 0x3746,
+ 0x374c, 0x374d, 0x9174, 0x3768, 0x376f, 0x3773, 0x3774, 0x3775,
+ 0x377b, 0x91e4, 0x91d7, 0x37ac, 0x379a, 0x379d, 0x379e, 0x37a8,
+ 0x37d7, 0x91fd, 0x37cc, 0x9236, 0x9244, 0x37de, 0x37e6, 0x37f0,
+ 0x164a, 0x37f8, 0x37fb, 0x37fd, 0x3804, 0x381e,
+ /* 0x22521..0x2257E */
+ 0x3820, 0x3827, 0x3832, 0x3839, 0x92c4, 0x3849, 0x384c, 0x3867,
+ 0x388a, 0x388b, 0x388d, 0x388f, 0x3890, 0x3894, 0x389d, 0x38aa,
+ 0x38b1, 0x936d, 0x38c3, 0x38cd, 0x38e2, 0x38f3, 0x38f4, 0x3905,
+ 0x3906, 0x390b, 0x390d, 0x3914, 0x3924, 0x94d7, 0x1691, 0x393d,
+ 0x1699, 0x3946, 0x1696, 0xd229, 0x395b, 0x395f, 0x9547, 0x3975,
+ 0x3976, 0x397c, 0x399f, 0x39ae, 0x39bc, 0x39c8, 0x39cd, 0x39de,
+ 0x39e3, 0x39e4, 0x39e7, 0x39ee, 0x9606, 0x9642, 0x16cf, 0x3a0c,
+ 0x3a0d, 0x3a17, 0x3a27, 0x3a2d, 0x3a55, 0x3a65, 0x3a7a, 0x3a8b,
+ 0x3a9c, 0x3a9f, 0x3aa0, 0x3aa2, 0x3ab1, 0x3ab3, 0x3ab5, 0x3aba,
+ 0x3abf, 0x3ada, 0x3adc, 0x3ae0, 0x3ae5, 0x3af0, 0x3aee, 0x3af5,
+ 0x3b00, 0x3b08, 0x3b17, 0x3b34, 0x3b2d, 0x3b4c, 0x3b52, 0x3b68,
+ 0x3b6f, 0x3b7c, 0x3b7f, 0x3b81, 0x3b84, 0x98c3,
+ /* 0x22821..0x2287E */
+ 0x3b96, 0x3bac, 0x1761, 0x3bc0, 0x1762, 0x3bce, 0x3bd6, 0x176c,
+ 0x176b, 0x3bf1, 0x3bfd, 0x1775, 0x3c03, 0x3c29, 0x3c30, 0x9956,
+ 0x3c5f, 0x3c63, 0x3c67, 0x3c68, 0x3c69, 0x3c70, 0x9a2d, 0x9a45,
+ 0x3c7c, 0x9a78, 0x9a62, 0x3c88, 0x3c8a, 0x17c1, 0x9aa1, 0x9a9c,
+ 0x3ca0, 0x3ca2, 0x3ca6, 0x3ca7, 0x9a92, 0x3cad, 0x3cb5, 0x9ab7,
+ 0x3cc9, 0x9ae0, 0x9b33, 0x3d06, 0x3d10, 0x3d2b, 0x3d1d, 0x3d20,
+ 0x3d24, 0x3d26, 0x3d31, 0x3d39, 0x3d42, 0x17e8, 0x3d61, 0x3d6a,
+ 0x17f4, 0x3d70, 0x9c1e, 0x17fd, 0x3d88, 0x1800, 0x3d92, 0x3d94,
+ 0x3d97, 0x3d99, 0x3db0, 0x3db2, 0x3db4, 0x9c76, 0x3db9, 0x3dd1,
+ 0x3dd7, 0x3dd8, 0x3de0, 0x9cfa, 0x3de4, 0x3de9, 0x182f, 0x3e00,
+ 0x1836, 0x3e12, 0x3e15, 0x1840, 0x3e1f, 0x3e2e, 0x3e3e, 0x3e49,
+ 0x185c, 0x3e56, 0x1861, 0x3e6b, 0x3e6c, 0x3e6d,
+ /* 0x22C21..0x22C7E */
+ 0x3e6e, 0x9d7b, 0x3ea5, 0x3eaa, 0x3eac, 0x3eb9, 0x3ebf, 0x3ec6,
+ 0x3ed2, 0x3ed9, 0x9f1e, 0x3efd, 0x3f08, 0x3f0e, 0x3f1c, 0x9fad,
+ 0x3f1e, 0x3f47, 0x3f63, 0x3f72, 0x3f7e, 0x3f8f, 0x3fa2, 0x3fa4,
+ 0x3fb8, 0x3fc4, 0x18fa, 0x3fc7, 0x3fcb, 0x3fd2, 0x3fd3, 0x3fd4,
+ 0x3fe2, 0x3fee, 0x3fef, 0x3ff3, 0x3ffc, 0x1917, 0x4017, 0x4022,
+ 0x4024, 0x191a, 0x404c, 0x407f, 0x408a, 0x4095, 0x40a8, 0xa0f3,
+ 0x40b0, 0x40b1, 0x40be, 0x40c8, 0x40d9, 0x40db, 0x40ee, 0x40f2,
+ 0x40f5, 0x4110, 0x4112, 0x4113, 0x4119, 0x411e, 0x413a, 0x196f,
+ 0x4141, 0x4146, 0x4160, 0x417c, 0xa15b, 0x4192, 0x4193, 0x4197,
+ 0x4198, 0x41a5, 0x41a8, 0x41ad, 0xa1ab, 0x41d5, 0x41dd, 0x41df,
+ 0x41f5, 0xa28f, 0x4215, 0x4223, 0x4229, 0x4246, 0x424c, 0x4251,
+ 0x4252, 0x4261, 0x4264, 0x427b, 0x426d, 0x4273,
+ /* 0x22D21..0x22D7E */
+ 0x4299, 0x42a6, 0x42d5, 0xa3b8, 0x42fd, 0x4303, 0x430d, 0x4310,
+ 0xa44f, 0xa450, 0x4332, 0x4335, 0x433b, 0x433c, 0x4341, 0x4344,
+ 0x434e, 0xa446, 0x4359, 0xa51d, 0xa4a6, 0x436c, 0x4384, 0x4399,
+ 0xa524, 0x4394, 0x43bd, 0x43f7, 0x43d4, 0x43d5, 0x43dc, 0x43e0,
+ 0x43eb, 0x43ec, 0x43f2, 0x4409, 0x441e, 0x4425, 0x4429, 0x442f,
+ 0x445a, 0x445b, 0x445d, 0x4473, 0x447d, 0x4487, 0x4491, 0x449d,
+ 0x449f, 0x44cb, 0x44cc, 0x44d5, 0x44d7, 0xa6e1, 0x44e4, 0x44e5,
+ 0x44ff, 0x4504, 0x1a6e, 0x450f, 0x4514, 0x4516, 0x1a73, 0x451e,
+ 0x4532, 0x4544, 0x4554, 0x456b, 0x457a, 0x4581, 0x4584, 0x4585,
+ 0x458a, 0x45b2, 0x45b5, 0x45b8, 0x45bf, 0x45c2, 0x45c9, 0x45d4,
+ 0x1ad6, 0x45f2, 0x45f9, 0x45fc, 0x4604, 0x4608, 0x4621, 0x462a,
+ 0x4645, 0x4651, 0x464e, 0x1aea, 0xa7c3, 0x4657,
+ /* 0x22E21..0x22E7E */
+ 0x465b, 0x4663, 0xa7f5, 0xa7b6, 0x466a, 0x466b, 0x466c, 0x466d,
+ 0x467b, 0x4680, 0x4690, 0x4692, 0x4699, 0x1b0e, 0x46ad, 0x46b1,
+ 0x46b5, 0x1b1a, 0x46bf, 0x1b1c, 0x46ec, 0x1ad7, 0x4701, 0x4705,
+ 0x4712, 0xa872, 0x4719, 0xa8d3, 0xa8d2, 0x474c, 0x474d, 0x4754,
+ 0x475d, 0xa8d0, 0xa8e4, 0xa8d5, 0x4774, 0x4776, 0xa8da, 0x4792,
+ 0xa8df, 0x6363, 0x4810, 0x47b0, 0x47b2, 0x47c3, 0x47c8, 0x47d2,
+ 0x47d9, 0x47db, 0x47f0, 0x47f7, 0xa94a, 0xa951, 0xa94b, 0x4818,
+ 0x481f, 0x482d, 0xa965, 0x4833, 0x483b, 0x483e, 0x4844, 0x4845,
+ 0x4849, 0x484c, 0x4855, 0x4857, 0x1b77, 0x486b, 0x486e, 0x487a,
+ 0x487c, 0x4882, 0x4890, 0x4896, 0x1b6d, 0x4898, 0x4899, 0x489a,
+ 0x489c, 0x48aa, 0x48ab, 0x48b4, 0x48bb, 0x48fb, 0xa9e4, 0xaa5a,
+ 0x8113, 0x48c3, 0x48c5, 0x48cc, 0x48cf, 0x48d6,
+ /* 0x22F21..0x22F7E */
+ 0x48d9, 0x48e4, 0x48e5, 0x48ec, 0x48f7, 0x4903, 0x4907, 0x1b87,
+ 0x1b88, 0xaa94, 0x493b, 0x1b8d, 0x4946, 0x4969, 0x496c, 0x4972,
+ 0x497a, 0x497f, 0x4992, 0x1ba4, 0x4996, 0x4998, 0x49a6, 0x49b0,
+ 0x49b7, 0x49ba, 0x49bc, 0x49c0, 0x49d1, 0x49d6, 0xab39, 0xab47,
+ 0x4a30, 0xab38, 0xab3a, 0x49e3, 0x49ee, 0x49ef, 0x49f3, 0x1bcd,
+ 0x49f4, 0x49fe, 0x4a11, 0x4a1a, 0x4a1d, 0xac1c, 0x4a32, 0x4a33,
+ 0x4a34, 0x4a3f, 0x4a46, 0x4a49, 0x4a7a, 0x4a4e, 0x4a52, 0x4a64,
+ 0xac0c, 0x4a7e, 0x4a83, 0x4a8b, 0x1bf0, 0x4a91, 0x4a9f, 0x4aa1,
+ 0xac64, 0x4aab, 0x4abd, 0x4ac6, 0x4ad4, 0x4ad0, 0x4adc, 0x4add,
+ 0xacff, 0xace7, 0x4aec, 0x4af1, 0x4af2, 0x4af3, 0x4afd, 0xad24,
+ 0x4b0b, 0x4b0f, 0x4b10, 0x4b11, 0xad3d, 0x4b17, 0x1c26, 0x4b2f,
+ 0x4b4a, 0x4b58, 0x4b6c, 0x4b75, 0x4b7a, 0x4b81,
+ /* 0x26E21..0x26E7E */
+ 0x4b9b, 0x4bae, 0xae98, 0x4bbd, 0x4bbe, 0x4bc7, 0x4bc8, 0x4bc9,
+ 0x4bda, 0x4be6, 0x4be7, 0x4bee, 0x4bf1, 0x4c02, 0x4c0a, 0x4c0e,
+ 0x4c35, 0x4c36, 0x4c3a, 0xaf7f, 0x4c3f, 0x4c4d, 0x4c5b, 0x4c6d,
+ 0x4c84, 0x4c89, 0x1cc3, 0x4c94, 0x4c95, 0x4c97, 0x4cad, 0x4cc2,
+ 0x4cd0, 0x1cd2, 0x4cd6, 0x4cda, 0x4cdc, 0x4ce9, 0x4cec, 0x4ced,
+ 0xb000, 0x4d00, 0x4d0a, 0x4d24, 0x4d26, 0x4d27, 0x4c67, 0x4d2f,
+ 0x4d3c, 0x4d5b, 0x4d5e, 0x4d60, 0x4d70, 0x4d80, 0x4d81, 0x4d8a,
+ 0x4d8d, 0x4d91, 0x4d98, 0xb040, 0x4e17, 0xb0fa, 0xb0f9, 0xb0d3,
+ 0x4dab, 0x4dae, 0x4db4, 0x4dc2, 0x4d34, 0x4dc8, 0x4dce, 0x4dcf,
+ 0x4dd0, 0x4ddf, 0x4de9, 0x4df6, 0x4e36, 0x4e1e, 0x4e22, 0x4e27,
+ 0x1d11, 0x4e32, 0x4e3c, 0x4e48, 0x4e49, 0x4e4b, 0x4e4c, 0x4e4f,
+ 0x4e51, 0x4e53, 0x4e54, 0x4e57, 0x4e63, 0x1d1e,
+ /* 0x26F21..0x26F7E */
+ 0x4e93, 0x4ea7, 0x4eb4, 0x4ebf, 0x4ec3, 0x4eca, 0x4ed9, 0x4f35,
+ 0x4eeb, 0x4ef9, 0x4efb, 0x4f0a, 0x4f0c, 0x4f18, 0x4f25, 0x4f36,
+ 0x4f3c, 0xb17e, 0x4f52, 0x4f57, 0x4f5a, 0x4f60, 0x4f68, 0x4f98,
+ 0x4f7d, 0x4f90, 0x4f96, 0x4fbe, 0x4f9f, 0x4fa5, 0x4faf, 0x1d64,
+ 0x4fb5, 0x4fc8, 0x4fc9, 0x4fda, 0x4fde, 0x4fe9, 0xb296, 0x4ffc,
+ 0x5000, 0x5007, 0x500a, 0x5023, 0xb303, 0x5039, 0x503a, 0x503c,
+ 0x5043, 0x5047, 0x504b, 0x1d9a, 0x5054, 0x5065, 0x5069, 0x506c,
+ 0x506e, 0x5076, 0x507e, 0x5081, 0x5086, 0x5095, 0x5097, 0x50bb,
+ 0xb3c6, 0x509f, 0x50b1, 0xb3fe, 0x50ec, 0x50ca, 0x50d1, 0x50d3,
+ 0x50dc, 0x5103, 0x5104, 0x5106, 0x5107, 0x5108, 0x510c, 0x1dc0,
+ 0x512f, 0x5131, 0x5150, 0x514a, 0x5153, 0x515e, 0x1dd4, 0x5196,
+ 0x5180, 0x519b, 0x51a0, 0x51a2, 0x51ae, 0x51af,
+ /* 0x27021..0x2707E */
+ 0x51b3, 0xb4bc, 0x51cb, 0x51d3, 0x51d9, 0x51dc, 0x5207, 0x1e05,
+ 0x8149, 0x522b, 0x5234, 0x5238, 0x5239, 0x2e2c, 0x5242, 0x5253,
+ 0x5257, 0x5263, 0xb529, 0x526e, 0x526f, 0x5278, 0x527f, 0x528e,
+ 0xb5a5, 0x52ad, 0x52ae, 0x52b0, 0x52b1, 0x52c1, 0x1e60, 0x52cc,
+ 0x1e66, 0x1e68, 0x52f3, 0x52fa, 0x5307, 0x5312, 0x5318, 0x5319,
+ 0x1e83, 0x5339, 0x532c, 0x5331, 0x5333, 0x533d, 0x5352, 0x1e94,
+ 0x536b, 0x536c, 0xb796, 0x536e, 0x536f, 0x5371, 0x5377, 0x5381,
+ 0x5385, 0x538a, 0x5394, 0x5398, 0x539c, 0x539e, 0x53a5, 0x53a8,
+ 0x53b5, 0x53b7, 0x53b9, 0x53bc, 0x53bf, 0x53c5, 0x53cb, 0x53e1,
+ 0x53e7, 0x53f9, 0x5413, 0x53fa, 0x5401, 0x5424, 0x5431, 0x5439,
+ 0x5453, 0x5440, 0x5443, 0x544d, 0x5452, 0x545d, 0x5471, 0x5481,
+ 0x5485, 0x5488, 0xb84d, 0x5492, 0x5497, 0x5499,
+ /* 0x27121..0x2717E */
+ 0x54a0, 0x54a1, 0x54a5, 0x54aa, 0x54ab, 0x54b9, 0x54bb, 0x54ba,
+ 0x54d6, 0x54d8, 0x54de, 0x54ef, 0x54eb, 0xb956, 0x54fa, 0xb96f,
+ 0x5520, 0x5524, 0x552a, 0x1f57, 0xba16, 0x553d, 0x553e, 0x5540,
+ 0x5548, 0x554e, 0x5550, 0x5552, 0x556c, 0x5572, 0x5571, 0x557a,
+ 0x557d, 0x557e, 0x5581, 0xbb14, 0x558c, 0x1f75, 0x55a2, 0x1f77,
+ 0x55b0, 0x55b7, 0x55bf, 0x55c0, 0x55c6, 0x55cf, 0x55d3, 0x55dd,
+ 0x55df, 0x55e0, 0x55e7, 0x55ec, 0x55ee, 0x55f1, 0x55f9, 0x5603,
+ 0x5618, 0x5607, 0x560f, 0x1fae, 0xbc0e, 0x5613, 0x561b, 0x561c,
+ 0xbc37, 0x5625, 0x5628, 0x563c, 0x5633, 0xbc6a, 0x1fc9, 0x5641,
+ 0xbc8b, 0x5649, 0x5655, 0x1fd7, 0x566e, 0x5695, 0x569c, 0x56a1,
+ 0x56a0, 0x56a7, 0x56a8, 0x56af, 0xbd4a, 0x56c9, 0xbd55, 0x56e8,
+ 0x56ec, 0xbe22, 0x5717, 0x571a, 0x572d, 0x5735,
+ /* 0x27221..0x2727E */
+ 0xbea9, 0x2039, 0xbee5, 0xbecd, 0x5758, 0x5760, 0x576a, 0xbf1e,
+ 0x5772, 0x577c, 0x577d, 0xbf4c, 0x2058, 0x579a, 0x579f, 0x57a2,
+ 0x57a4, 0x57a9, 0x57de, 0x57df, 0x57e4, 0x57e6, 0x57ea, 0x57ec,
+ 0x2093, 0x57f0, 0x57f4, 0x57fb, 0xc02e, 0x5805, 0x5806, 0x5809,
+ 0x580d, 0x5819, 0x5821, 0x582c, 0x5847, 0x5864, 0x586a, 0xc0d9,
+ 0x588a, 0x5894, 0x58a4, 0x589d, 0x589e, 0x589f, 0x58bb, 0x58c8,
+ 0x58cc, 0x58ce, 0x58d5, 0x58e0, 0x58e1, 0x58e6, 0x58f9, 0x58fa,
+ 0x58fb, 0x58fe, 0xc1a7, 0x5910, 0x591b, 0x5930, 0x5925, 0x593b,
+ 0x594a, 0x5958, 0x595b, 0x2105, 0x5967, 0x5972, 0x5994, 0x5995,
+ 0x5996, 0x599b, 0x59a1, 0x59a9, 0x59b4, 0x59bb, 0x59c2, 0x59c7,
+ 0x59cc, 0x59cd, 0x59d6, 0x2148, 0xc2a9, 0xc2b4, 0x214f, 0x5a0a,
+ 0x5a11, 0x5a15, 0x5a1b, 0x5a1e, 0x2163, 0x5a2d,
+ /* 0x27321..0x2737E */
+ 0x5a38, 0x5a47, 0x5a4c, 0x5a56, 0x5a59, 0x5a5c, 0x5a5f, 0x5a60,
+ 0x5a67, 0x5a6a, 0x5a75, 0x5a78, 0x5a82, 0x5a8a, 0x5a90, 0x5aa3,
+ 0x5aac, 0xc3d4, 0x21b4, 0x5ab9, 0x5abc, 0x5abe, 0x21bf, 0x5acc,
+ 0x5ad1, 0x5ae7, 0x5ae8, 0x5af4, 0xc4e4, 0xc4e3, 0x5b07, 0xc4f1,
+ 0x5b3d, 0x5b27, 0x5b2a, 0x5b2e, 0x5b2f, 0x5b31, 0x21e6, 0x21f3,
+ 0x5b7f, 0x5b41, 0x21ee, 0x5b55, 0x5b79, 0x5b64, 0x5b66, 0x5b69,
+ 0x5b73, 0xc532, 0x2207, 0x5b90, 0x5b91, 0x5b9b, 0x220e, 0x5baf,
+ 0x5bb5, 0x5bbc, 0x5bc5, 0x5bca, 0xc5cb, 0xc5e4, 0x5bd4, 0x5bd6,
+ 0x5bda, 0x5bea, 0x5bf0, 0x5c03, 0x5c0b, 0x5c0e, 0x5c0f, 0x5c26,
+ 0x5c45, 0x5c4a, 0x5c51, 0x5c57, 0x5c5e, 0x5c61, 0x5c69, 0x5c6e,
+ 0x5c6f, 0x5c70, 0xc72e, 0xc756, 0xc765, 0x5ca6, 0xc762, 0x5cb6,
+ 0x5cb7, 0x5cbf, 0xc7d8, 0x5cc4, 0xc7c2, 0x5cc8,
+ /* 0x27421..0x2747E */
+ 0x5ccd, 0xc7e8, 0x5cd7, 0xc823, 0x5ce6, 0x5ceb, 0xc85c, 0x5cf5,
+ 0x5d03, 0x5d09, 0x22c6, 0x5d12, 0x5d1e, 0xc8e0, 0xc8d4, 0x5d3d,
+ 0x5d3e, 0x5d40, 0x5d47, 0xc90c, 0xc8fb, 0x22d6, 0x5d59, 0x5d5a,
+ 0x5d6a, 0x5d70, 0x22dd, 0x5d7f, 0xc917, 0x5d86, 0x5d88, 0x5d8c,
+ 0x5d97, 0xc960, 0x5d9d, 0x5da7, 0x5daa, 0x5db6, 0x5db7, 0x5dc0,
+ 0x5dd7, 0x5dd9, 0x5de6, 0x5df1, 0x5df9, 0x2302, 0xc9ed, 0x8158,
+ 0x5e10, 0x5e17, 0x5e1d, 0x5e20, 0x5e27, 0x5e2c, 0x5e45, 0x5e73,
+ 0x5e75, 0x5e7e, 0x5e86, 0x5e87, 0x232b, 0x5e91, 0x5e98, 0x5e9a,
+ 0x2343, 0x5f3c, 0x5f3b, 0x5f3e, 0x5f43, 0x5f44, 0x5f4f, 0x14c1,
+ 0xca70, 0x5f52, 0xca86, 0x5f61, 0x5f63, 0x5f64, 0x5f6d, 0x5f7d,
+ 0x5f7e, 0xcb4c, 0x5f90, 0x317b, 0xb00e, 0x5f96, 0x5f9c, 0x5fad,
+ 0xcc02, 0x5fc3, 0x5fcf, 0x5fe3, 0x5fe5, 0x5fef,
+ /* 0x27521..0x2757E */
+ 0x5ff2, 0x6002, 0x600a, 0x6008, 0x600e, 0x6011, 0x6016, 0x6024,
+ 0x602c, 0x6030, 0x6043, 0x6066, 0x6071, 0x6075, 0x607b, 0x6099,
+ 0x609c, 0x60a4, 0x60a7, 0x60b8, 0xcd7e, 0x60c5, 0x60d5, 0x60d8,
+ 0x60e6, 0xcdb0, 0x610d, 0x60f5, 0x60fb, 0x23ee, 0x6135, 0x6116,
+ 0x611e, 0x23f0, 0x6124, 0x6127, 0x612c, 0xce1d, 0x613d, 0x2408,
+ 0x6169, 0x2417, 0x6181, 0x241c, 0x6184, 0x6185, 0x2422, 0x6198,
+ 0x61b2, 0x61c1, 0x61c3, 0x61d6, 0x61db, 0xcfdd, 0x61e4, 0xcfea,
+ 0x61ec, 0xd051, 0x61fd, 0x61ff, 0xd06f, 0x6204, 0xd0dd, 0x6219,
+ 0x6221, 0x6222, 0xd11e, 0x6232, 0x6234, 0x623c, 0x6246, 0x6249,
+ 0x6245, 0xd158, 0x624b, 0x2476, 0x624f, 0x247a, 0x6257, 0xd18c,
+ 0x625c, 0x6263, 0xd1b7, 0x815d, 0x815e, 0x6279, 0x2491, 0x627d,
+ 0x627f, 0x6283, 0x628a, 0x6293, 0x62a7, 0x62a8,
+ /* 0x27621..0x2767E */
+ 0x62b2, 0x62b4, 0x62ba, 0x62bc, 0x62e2, 0x62e8, 0x62f7, 0x6307,
+ 0x6308, 0x630c, 0x6354, 0x631b, 0x631d, 0x6330, 0x633c, 0x6344,
+ 0x6357, 0x24be, 0x637f, 0x24d4, 0x24b3, 0x638d, 0x6394, 0x6395,
+ 0x639b, 0x639d, 0x63c9, 0x63d0, 0x63d4, 0x63dd, 0x63e5, 0x63f9,
+ 0x640f, 0x6411, 0x6415, 0xd273, 0x6417, 0x6439, 0x644a, 0x644f,
+ 0x6451, 0x6452, 0x6459, 0x645a, 0x645c, 0xd2dd, 0x6465, 0x6476,
+ 0x6478, 0x647c, 0x6481, 0x250d, 0x64dc, 0x6497, 0x64a6, 0x64be,
+ 0x2508, 0x64ce, 0x64cf, 0x64d3, 0xd365, 0x64e7, 0x64ea, 0x64ef,
+ 0x64f0, 0x64f1, 0x64fa, 0x64fd, 0x650c, 0x651b, 0x6524, 0x6525,
+ 0x652b, 0x6534, 0x654f, 0x656f, 0x2525, 0x2543, 0x653e, 0x6551,
+ 0x6553, 0x655e, 0x6561, 0x6562, 0xd494, 0x657b, 0x657d, 0x657f,
+ 0x6581, 0x6586, 0x6593, 0x659d, 0x659f, 0xd4f8,
+ /* 0x27721..0x2777E */
+ 0xd4f6, 0xd4f7, 0x65b7, 0x65bc, 0x65c7, 0x65ca, 0x65d8, 0x65d9,
+ 0x65df, 0x65e1, 0x65e6, 0x65f6, 0x6600, 0x6611, 0x661e, 0x6621,
+ 0x6624, 0x6627, 0xd58d, 0x6639, 0x663c, 0xd5b9, 0x6640, 0x8120,
+ 0x6653, 0x6656, 0x666f, 0x6677, 0x667a, 0x6687, 0x6689, 0x668d,
+ 0x6691, 0x669c, 0x669d, 0x66a8, 0x8121, 0x66b1, 0x66b3, 0x66c1,
+ 0x66c3, 0x66d1, 0x66d5, 0x66d7, 0x66e3, 0x66e6, 0x25b8, 0x6705,
+ 0x6707, 0x670e, 0x6710, 0x6713, 0x6719, 0x671f, 0x6721, 0x6723,
+ 0x6731, 0x673a, 0x673e, 0x6740, 0x6743, 0x6751, 0x6758, 0x6764,
+ 0x6765, 0x6772, 0x677c, 0xd65b, 0xd65a, 0x67a7, 0x6789, 0x678b,
+ 0x6793, 0x67a0, 0xd67e, 0x25e5, 0x67be, 0xd690, 0x67c1, 0x67ce,
+ 0x67f5, 0x67df, 0xd6c9, 0x67e3, 0x67e5, 0x67e6, 0x67ea, 0x67eb,
+ 0x67ed, 0x6801, 0x6803, 0x680b, 0x6813, 0x6828,
+ /* 0x27821..0x2787E */
+ 0x682e, 0x6832, 0x683c, 0x260f, 0x684a, 0x6858, 0x685f, 0x6864,
+ 0xd715, 0xd714, 0x6869, 0xd731, 0x686f, 0x68a0, 0x68bc, 0x68bd,
+ 0x68be, 0x68c0, 0x68d2, 0xd793, 0x68d1, 0x68d3, 0x68db, 0x68f0,
+ 0x68f1, 0x2641, 0x6901, 0xd80e, 0x6937, 0xd823, 0x6942, 0x6945,
+ 0x6949, 0xd852, 0x2665, 0x6962, 0x6980, 0x6989, 0x6990, 0x699f,
+ 0x69b0, 0x69b7, 0x69d6, 0x69d8, 0x69eb, 0x26a1, 0x69f1, 0x69f3,
+ 0x69fd, 0x69ff, 0x26af, 0x6a11, 0x6a14, 0xd985, 0x6a21, 0x6a35,
+ 0x6a3e, 0x6a45, 0x6a4d, 0x6a58, 0x6aae, 0x6a90, 0x6ab7, 0x6abe,
+ 0x6ad7, 0x6afc, 0xda84, 0x6b0a, 0x6b05, 0x6b0d, 0x6b1c, 0x6b1f,
+ 0x6b2d, 0x6b43, 0x270c, 0x6b51, 0x6b5e, 0x6b76, 0x6b7f, 0x6b81,
+ 0x6b8b, 0x6b94, 0x6b95, 0x6b9c, 0x6b9e, 0x6c39, 0xdbb3, 0x6c3d,
+ 0xdbbe, 0xdbc7, 0x6c45, 0x6c47, 0x6c4f, 0x6c54,
+ /* 0x27921..0x2797E */
+ 0x6c57, 0x6c69, 0x6c6d, 0x6c73, 0xdcb8, 0x6c93, 0x6c92, 0x6c99,
+ 0x2764, 0x6c9b, 0x6ca4, 0x6cd6, 0x6cd5, 0x6cd9, 0xdd20, 0x6cf0,
+ 0x6cf1, 0xdd90, 0x6d09, 0x6d0e, 0x6d6c, 0x6d84, 0x6d95, 0x6da6,
+ 0xdeb7, 0x6dc6, 0x6dc8, 0x6dd9, 0x6dec, 0x6e0c, 0x27fd, 0x6dfd,
+ 0x6e06, 0xdf8a, 0x6e14, 0x6e16, 0x6e21, 0x6e22, 0x6e27, 0xdfbb,
+ 0x2816, 0x6e36, 0x6e39, 0x6e4b, 0x6e54, 0x6e62, 0x6e6c, 0x6e6d,
+ 0x6e6f, 0x6e98, 0x6e9e, 0x6eae, 0x6eb3, 0x6eb5, 0x6eb6, 0x6ebb,
+ 0xe082, 0x6ed1, 0x6ed4, 0x284e, 0x6ef9, 0xe0f3, 0x6f00, 0x6f08,
+ 0x6f17, 0x6f2b, 0x6f40, 0x6f4a, 0x6f58, 0xe18c, 0x6fa4, 0x6fb4,
+ 0x8166, 0x6fb6, 0xe1d5, 0x6fc1, 0x6fc6, 0x8124, 0x6fca, 0x6fcd,
+ 0x6fd3, 0x6fd5, 0x6fe0, 0x6ff1, 0x6ff5, 0x6ffb, 0x7002, 0x700c,
+ 0x7037, 0xe26b, 0x7043, 0x7044, 0x705d, 0xe2c8,
+ /* 0x27A21..0x27A7E */
+ 0xe2c9, 0x7085, 0x708c, 0x7090, 0x761d, 0x70a1, 0x28b5, 0x70b0,
+ 0x70b6, 0x70c3, 0x70c8, 0xe3d7, 0x70dc, 0x70df, 0xe3fa, 0x70f6,
+ 0x70f2, 0x7100, 0x70eb, 0x70fe, 0x70ff, 0x7104, 0x7106, 0x7118,
+ 0x711c, 0x711e, 0x7137, 0x7139, 0x713a, 0x7146, 0x7147, 0x7157,
+ 0x7159, 0x7161, 0x7164, 0x7174, 0x7179, 0x7185, 0x718e, 0x71a8,
+ 0x71ae, 0x71b3, 0x71b6, 0x71c3, 0x71c4, 0x71da, 0xe449, 0xe446,
+ 0x71ec, 0x71ee, 0x7201, 0x720a, 0x7216, 0x7217, 0xe46b, 0x7233,
+ 0x7242, 0x7247, 0x724a, 0x724e, 0x7251, 0x7256, 0x7259, 0x7260,
+ 0x7261, 0x7265, 0x7267, 0x7268, 0xe487, 0xe488, 0x727c, 0x727d,
+ 0x727f, 0x7289, 0x728d, 0x7297, 0x7299, 0x729f, 0x72a7, 0x72ab,
+ 0xe4ba, 0xe4bb, 0x72b2, 0x72bf, 0x72c0, 0x72c6, 0x72ce, 0x72d0,
+ 0x72d7, 0x72d9, 0x72e5, 0x72e7, 0x7311, 0xe51e,
+ /* 0x27B21..0x27B7E */
+ 0xe529, 0x72f7, 0x72f9, 0x72fb, 0x7302, 0x730d, 0x7315, 0x731d,
+ 0x731e, 0x7327, 0x7329, 0xe571, 0xe543, 0x7347, 0x7351, 0x7357,
+ 0x735a, 0x736b, 0x7371, 0x7373, 0x73a1, 0xe599, 0xe5cd, 0x7388,
+ 0x738b, 0x738f, 0x739e, 0x73f5, 0xe5e4, 0xe5dd, 0x73f1, 0x73c1,
+ 0x73c7, 0x73dc, 0x73e2, 0x73e7, 0x7409, 0x740f, 0x7416, 0x7417,
+ 0x73fb, 0x7432, 0x7434, 0x743b, 0x7445, 0xe6c1, 0xe6ef, 0x746d,
+ 0x746f, 0x7578, 0x7579, 0x7586, 0x758c, 0x758d, 0xe710, 0x75ab,
+ 0x75b4, 0xe771, 0x75c8, 0xe7fb, 0xe81f, 0x762c, 0x7633, 0x7634,
+ 0xe836, 0x763c, 0x7641, 0x7661, 0xe889, 0x7682, 0xe8eb, 0x769a,
+ 0xe932, 0x29e7, 0x76a9, 0x76af, 0x76b3, 0x76ba, 0x76bd, 0x29fa,
+ 0xe9f8, 0x76d8, 0x76da, 0x76dd, 0x2a04, 0x7714, 0x7723, 0x2a29,
+ 0x7736, 0x7741, 0x7747, 0x7755, 0x7757, 0x775b,
+ /* 0x27C21..0x27C7E */
+ 0x776a, 0xeaa0, 0xeab1, 0x7796, 0x779a, 0x779e, 0x77a2, 0x77b1,
+ 0x77b2, 0x77be, 0x77cc, 0x77d1, 0x77d4, 0x77d8, 0x77d9, 0x77e1,
+ 0x77f1, 0x7804, 0x780d, 0x780e, 0x7814, 0x7816, 0x2abc, 0xeb90,
+ 0x7823, 0x7832, 0x7833, 0x7825, 0x7847, 0x7866, 0x78ab, 0x78ad,
+ 0x78b0, 0xeccf, 0x78b7, 0x78b8, 0x78bb, 0x78bc, 0x78bf, 0x78c2,
+ 0x78c7, 0x78cb, 0x78e0, 0xed7f, 0x78e1, 0x78e3, 0x78e5, 0x78ea,
+ 0x78f0, 0x78f1, 0x78f3, 0x7908, 0x2b3b, 0xedf0, 0x7916, 0x7917,
+ 0xee19, 0x791a, 0x791b, 0x791c, 0xee50, 0x7931, 0x7932, 0x7933,
+ 0x793a, 0x793b, 0x793c, 0x7940, 0x7941, 0x7946, 0x794d, 0x794e,
+ 0x795c, 0x795f, 0x7960, 0x79a3, 0x79a6, 0x79b9, 0x79bd, 0x79bf,
+ 0x79c3, 0x79c9, 0x79d4, 0x79d9, 0x79de, 0xefc6, 0x79f0, 0x79f9,
+ 0x79fc, 0x7a0a, 0x7a11, 0x7a16, 0x7a1a, 0x7a20,
+ /* 0x27D21..0x27D7E */
+ 0x7a31, 0x7a36, 0x7a44, 0x7a4c, 0x7a58, 0x2bc2, 0x7aaf, 0x2bca,
+ 0x7ab7, 0x2bd2, 0x7ab9, 0xf072, 0x7ac6, 0x7ad0, 0x7ad2, 0x7ad5,
+ 0x2be8, 0x7adc, 0x7ae0, 0x7ae5, 0x7ae9, 0x7b03, 0x7b0c, 0x7b10,
+ 0x7b12, 0x7b16, 0x7b1c, 0x7b2b, 0x7b33, 0x7b3d, 0x2c20, 0x7b4b,
+ 0x7b63, 0x7b65, 0x7b6b, 0x7b6c, 0x7b73, 0x7b76, 0x7b77, 0x7ba6,
+ 0x7bac, 0x7bb1, 0xf1db, 0xf23d, 0x7bb2, 0x7bb8, 0x7bbe, 0x7bc7,
+ 0x7bf3, 0x7bd8, 0x7bdd, 0x7be7, 0x7bea, 0x7beb, 0x7bef, 0x7bee,
+ 0xf215, 0x7bfa, 0xf28a, 0x7bf7, 0xf249, 0x7c16, 0x7c18, 0x7c19,
+ 0x7c1a, 0x7c1d, 0x7c22, 0x7c27, 0x7c29, 0x7c2a, 0xf2c4, 0x7c31,
+ 0x7c36, 0x7c37, 0x7c45, 0x7c5c, 0xf2e9, 0x7c49, 0x7c4a, 0xf2db,
+ 0x7c54, 0x7c58, 0x7c5b, 0x7c5d, 0x7c5f, 0x7c69, 0x7c6a, 0x7c6b,
+ 0x7c6d, 0x7c6e, 0x7c70, 0x7c72, 0x7c75, 0x7c7a,
+ /* 0x27E21..0x27E7E */
+ 0x7ce6, 0x7cf2, 0x7d0b, 0x7d02, 0xf3ce, 0x7d11, 0x7d17, 0x7d18,
+ 0xf42f, 0x2cc4, 0xf41a, 0x7d32, 0x2cd1, 0x7d42, 0x7d4a, 0x7d5f,
+ 0x7d62, 0xf4f9, 0x7d69, 0x7d6b, 0xf482, 0x7d73, 0x7d76, 0x7d77,
+ 0x7d7e, 0x7d84, 0x7d8d, 0x7d99, 0x7da1, 0x7dbf, 0x7db5, 0x7db9,
+ 0x7dbd, 0x7dc3, 0x7dc7, 0x7dc9, 0x7dd6, 0x7dda, 0x7ddf, 0x7de0,
+ 0x7de3, 0x7df4, 0x2d07, 0x7e0a, 0x7e02, 0x7e0d, 0x7e19, 0x7e1c,
+ 0x7e1d, 0x7e7b, 0x9e18, 0x7e80, 0x7e85, 0x7e9b, 0x7ea8, 0xf60c,
+ 0x7ebd, 0xf6b7, 0x7edf, 0x7ee7, 0x7eee, 0x7eff, 0x7f02, 0x2d77,
+ 0x7f03, 0x7f17, 0x7f19, 0x7f2f, 0x7f37, 0x7f3a, 0x7f3d, 0x7f41,
+ 0x7f45, 0x7f46, 0x7f53, 0x7f55, 0x7f58, 0xf7f1, 0x7f5d, 0xf802,
+ 0x7f69, 0xf81a, 0x7f6d, 0x7f70, 0x7f75, 0xf8b2, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const ucs4_t jisx0213_to_ucs_pagestart[] = {
+ 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x1e00, 0x1f00, 0x2000,
+ 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2900,
+ 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700,
+ 0x3800, 0x3900, 0x3a00, 0x3b00, 0x3c00, 0x3d00, 0x3e00, 0x3f00,
+ 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700,
+ 0x4800, 0x4900, 0x4a00, 0x4b00, 0x4c00, 0x4d00, 0x4e00, 0x4f00,
+ 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700,
+ 0x5800, 0x5900, 0x5a00, 0x5b00, 0x5c00, 0x5d00, 0x5e00, 0x5f00,
+ 0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700,
+ 0x6800, 0x6900, 0x6a00, 0x6b00, 0x6c00, 0x6d00, 0x6e00, 0x6f00,
+ 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700,
+ 0x7800, 0x7900, 0x7a00, 0x7b00, 0x7c00, 0x7d00, 0x7e00, 0x7f00,
+ 0x8000, 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700,
+ 0x8800, 0x8900, 0x8a00, 0x8b00, 0x8c00, 0x8d00, 0x8e00, 0x8f00,
+ 0x9000, 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700,
+ 0x9800, 0x9900, 0x9a00, 0x9b00, 0x9c00, 0x9d00, 0x9e00, 0x9f00,
+ 0xf900, 0xfa00, 0xfe00, 0xff00, 0x20000, 0x20180, 0x20300, 0x20400,
+ 0x20500, 0x20600, 0x20700, 0x20800, 0x20900, 0x20a80, 0x20d00, 0x20e00,
+ 0x20f00, 0x21200, 0x21300, 0x21400, 0x21500, 0x21600, 0x21700, 0x21800,
+ 0x21900, 0x21c00, 0x21d00, 0x21e00, 0x21f00, 0x22100, 0x22200, 0x22300,
+ 0x22600, 0x22800, 0x22900, 0x22a00, 0x22b00, 0x22c00, 0x22d00, 0x23100,
+ 0x23300, 0x23400, 0x23500, 0x23600, 0x23700, 0x23800, 0x23a00, 0x23c00,
+ 0x23d00, 0x23f00, 0x24000, 0x24100, 0x24300, 0x24600, 0x24700, 0x24800,
+ 0x24a00, 0x24b00, 0x24c00, 0x24d00, 0x24e00, 0x25000, 0x25100, 0x25200,
+ 0x25400, 0x25500, 0x25700, 0x25900, 0x25a00, 0x25b80, 0x25d00, 0x25e00,
+ 0x25f00, 0x26000, 0x26200, 0x26300, 0x26400, 0x26600, 0x26700, 0x26800,
+ 0x26900, 0x26a00, 0x26c00, 0x26e00, 0x26f00, 0x27080, 0x27380, 0x27600,
+ 0x27700, 0x27900, 0x27a00, 0x27b00, 0x27c00, 0x27d80, 0x27f00, 0x28000,
+ 0x28200, 0x28380, 0x28500, 0x28600, 0x28900, 0x28a00, 0x28b00, 0x28d00,
+ 0x28e00, 0x28f00, 0x29200, 0x29400, 0x29500, 0x29600, 0x29700, 0x29800,
+ 0x29a00, 0x29d00, 0x29e00, 0x29f00, 0x2a000, 0x2a100, 0x2a380, 0x2a500,
+ 0x2a600,
+};
+
+static const short jisx0213_from_ucs_level1[2715] = {
+ -1, -1, 0, 1, 2, 3, 4, 5,
+ -1, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 15, -1, -1, -1, -1, 16, -1, -1,
+ 17, 18, 19, -1, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, -1, 29, 30,
+ 31, 32, -1, 33, 34, 35, 36, 37,
+ 38, 39, -1, -1, 40, 41, -1, -1,
+ -1, -1, -1, -1, 42, -1, -1, 43,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 44, 45, 46, 47, -1, -1, -1, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, -1, 69, 70, 71,
+ 72, 73, -1, 74, 75, 76, -1, -1,
+ -1, 77, -1, 78, 79, 80, 81, 82,
+ 83, -1, -1, 84, 85, 86, 87, 88,
+ 89, 90, 91, -1, -1, 92, 93, 94,
+ 95, 96, 97, -1, 98, 99, 100, 101,
+ 102, 103, -1, 104, 105, 106, -1, 107,
+ 108, 109, 110, 111, 112, 113, 114, 115,
+ 116, 117, 118, -1, 119, 120, -1, 121,
+ 122, 123, 124, -1, -1, -1, 125, 126,
+ 127, -1, 128, -1, 129, -1, -1, 130,
+ 131, -1, -1, 132, 133, 134, -1, -1,
+ 135, 136, 137, 138, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 181, 182,
+ 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206,
+ 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 220, 221, 222,
+ 223, 224, 225, 226, 227, 228, 229, 230,
+ 231, 232, 233, 234, 235, 236, 237, 238,
+ 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254,
+ 255, 256, 257, 258, 259, 260, 261, 262,
+ 263, 264, 265, 266, 267, 268, 269, 270,
+ 271, 272, 273, 274, 275, 276, 277, 278,
+ 279, 280, 281, 282, 283, 284, 285, 286,
+ 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302,
+ 303, 304, 305, 306, 307, 308, 309, 310,
+ 311, 312, 313, 314, 315, 316, 317, 318,
+ 319, 320, 321, 322, 323, 324, 325, 326,
+ 327, 328, 329, -1, 330, 331, 332, 333,
+ 334, 335, 336, 337, 338, 339, 340, 341,
+ 342, 343, 344, 345, 346, 347, 348, 349,
+ 350, 351, 352, 353, 354, 355, 356, 357,
+ 358, 359, 360, 361, 362, 363, 364, 365,
+ 366, 367, 368, 369, 370, 371, 372, 373,
+ 374, 375, 376, 377, 378, 379, 380, -1,
+ 381, 382, 383, 384, 385, 386, 387, 388,
+ 389, 390, 391, 392, 393, 394, 395, 396,
+ 397, 398, 399, 400, 401, 402, 403, 404,
+ 405, 406, 407, 408, 409, 410, 411, 412,
+ 413, 414, 415, -1, -1, 416, 417, 418,
+ 419, 420, 421, 422, 423, 424, 425, 426,
+ 427, 428, 429, 430, 431, 432, 433, 434,
+ 435, 436, 437, 438, 439, 440, 441, 442,
+ 443, 444, -1, 445, 446, 447, 448, 449,
+ 450, 451, 452, 453, 454, 455, 456, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 457, 458, -1, 459,
+ 460, 461, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 462, -1, -1, 463, 464, -1, 465,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 466, -1, 467, -1, -1, -1, 468, -1,
+ 469, -1, -1, -1, 470, 471, 472, 473,
+ -1, 474, -1, -1, 475, -1, -1, 476,
+ 477, -1, -1, -1, -1, 478, -1, -1,
+ 479, -1, 480, -1, -1, 481, 482, -1,
+ -1, -1, -1, 483, 484, -1, -1, -1,
+ -1, -1, -1, -1, -1, 485, -1, 486,
+ -1, 487, 488, -1, -1, 489, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 490, 491, -1, 492, 493, 494, -1, 495,
+ -1, 496, -1, -1, -1, -1, -1, 497,
+ -1, 498, 499, -1, 500, 501, -1, -1,
+ -1, -1, 502, -1, -1, -1, -1, 503,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 504, -1, -1, 505, 506, 507, 508,
+ 509, -1, -1, -1, 510, 511, -1, 512,
+ -1, -1, -1, -1, -1, 513, -1, -1,
+ 514, -1, -1, -1, 515, -1, 516, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 517, -1, -1, -1, -1,
+ -1, 518, 519, -1, -1, -1, 520, -1,
+ -1, -1, 521, -1, -1, 522, 523, -1,
+ 524, -1, -1, -1, -1, -1, -1, 525,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 526, 527,
+ -1, -1, -1, -1, -1, 528, -1, 529,
+ -1, 530, -1, 531, -1, 532, 533, 534,
+ 535, 536, -1, -1, 537, 538, -1, 539,
+ 540, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 541, -1, -1, -1, -1, -1,
+ -1, 542, -1, 543, 544, 545, -1, 546,
+ -1, -1, -1, -1, -1, 547, -1, -1,
+ -1, -1, 548, -1, 549, -1, -1, 550,
+ -1, -1, -1, -1, -1, -1, 551, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 552, -1, 553, -1, -1, -1, -1, 554,
+ -1, -1, 555, -1, -1, -1, -1, -1,
+ -1, 556, -1, -1, -1, 557, -1, -1,
+ 558, -1, -1, -1, 559, -1, -1, -1,
+ 560, 561, 562, -1, -1, -1, -1, -1,
+ -1, 563, -1, -1, 564, -1, 565, 566,
+ 567, 568, -1, -1, -1, -1, -1, -1,
+ 569, -1, 570, 571, 572, -1, 573, -1,
+ -1, -1, -1, -1, -1, 574, 575, -1,
+ -1, -1, -1, -1, -1, -1, -1, 576,
+ -1, -1, -1, 577, -1, -1, 578, -1,
+ -1, 579, -1, -1, -1, -1, 580, -1,
+ 581, 582, -1, 583, 584, 585, -1, 586,
+ 587, 588, -1, 589, -1, -1, -1, -1,
+ -1, 590, 591, -1, -1, 592, -1, -1,
+ 593, -1, -1, -1, -1, -1, -1, -1,
+ -1, 594, 595, -1, 596, -1, -1, -1,
+ -1, -1, -1, 597, -1, 598, -1, 599,
+ 600, 601, 602, 603, -1, -1, -1, -1,
+ 604, 605, -1, 606, -1, -1, -1, -1,
+ -1, 607, -1, -1, -1, -1, 608, 609,
+ -1, -1, -1, 610, 611, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 612,
+ 613, 614, -1, -1, -1, -1, -1, -1,
+ 615, -1, 616, -1, 617, 618, -1, -1,
+ -1, -1, -1, -1, -1, -1, 619, -1,
+ -1, -1, 620, -1, -1, -1, 621, 622,
+ -1, -1, 623, -1, -1, -1, 624, -1,
+ 625, -1, -1, -1, -1, -1, 626, -1,
+ -1, -1, 627, -1, -1, -1, -1, -1,
+ -1, 628, 629, 630, -1, -1, -1, 631,
+ 632, 633, -1, -1, -1, 634, -1, 635,
+ -1, -1, -1, 636, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 637, 638, -1,
+ 639, 640, 641, 642, -1, -1, -1, 643,
+ -1, -1, -1, -1, 644, 645, -1, 646,
+ 647, -1, 648, 649, 650, -1, -1, 651,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 652, -1, -1, -1, -1, -1,
+ -1, -1, 653, -1, -1, -1, -1, 654,
+ -1, 655, -1, 656, 657, 658, -1, -1,
+ -1, -1, -1, 659, -1, -1, -1, -1,
+ -1, 660, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 661,
+ 662, 663, 664, 665, -1, -1, -1, 666,
+ 667, -1, 668, 669, -1, -1, 670, -1,
+ -1, -1, -1, -1, -1, -1, 671, -1,
+ 672, -1, -1, -1, -1, -1, -1, 673,
+ 674, -1, 675,
+};
+
+static const unsigned short gbkext1_2uni_page81[6080] = {
+ /* 0x81 */
+ 0x4e02, 0x4e04, 0x4e05, 0x4e06, 0x4e0f, 0x4e12, 0x4e17, 0x4e1f,
+ 0x4e20, 0x4e21, 0x4e23, 0x4e26, 0x4e29, 0x4e2e, 0x4e2f, 0x4e31,
+ 0x4e33, 0x4e35, 0x4e37, 0x4e3c, 0x4e40, 0x4e41, 0x4e42, 0x4e44,
+ 0x4e46, 0x4e4a, 0x4e51, 0x4e55, 0x4e57, 0x4e5a, 0x4e5b, 0x4e62,
+ 0x4e63, 0x4e64, 0x4e65, 0x4e67, 0x4e68, 0x4e6a, 0x4e6b, 0x4e6c,
+ 0x4e6d, 0x4e6e, 0x4e6f, 0x4e72, 0x4e74, 0x4e75, 0x4e76, 0x4e77,
+ 0x4e78, 0x4e79, 0x4e7a, 0x4e7b, 0x4e7c, 0x4e7d, 0x4e7f, 0x4e80,
+ 0x4e81, 0x4e82, 0x4e83, 0x4e84, 0x4e85, 0x4e87, 0x4e8a, 0x4e90,
+ 0x4e96, 0x4e97, 0x4e99, 0x4e9c, 0x4e9d, 0x4e9e, 0x4ea3, 0x4eaa,
+ 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb4, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9,
+ 0x4ebc, 0x4ebd, 0x4ebe, 0x4ec8, 0x4ecc, 0x4ecf, 0x4ed0, 0x4ed2,
+ 0x4eda, 0x4edb, 0x4edc, 0x4ee0, 0x4ee2, 0x4ee6, 0x4ee7, 0x4ee9,
+ 0x4eed, 0x4eee, 0x4eef, 0x4ef1, 0x4ef4, 0x4ef8, 0x4ef9, 0x4efa,
+ 0x4efc, 0x4efe, 0x4f00, 0x4f02, 0x4f03, 0x4f04, 0x4f05, 0x4f06,
+ 0x4f07, 0x4f08, 0x4f0b, 0x4f0c, 0x4f12, 0x4f13, 0x4f14, 0x4f15,
+ 0x4f16, 0x4f1c, 0x4f1d, 0x4f21, 0x4f23, 0x4f28, 0x4f29, 0x4f2c,
+ 0x4f2d, 0x4f2e, 0x4f31, 0x4f33, 0x4f35, 0x4f37, 0x4f39, 0x4f3b,
+ 0x4f3e, 0x4f3f, 0x4f40, 0x4f41, 0x4f42, 0x4f44, 0x4f45, 0x4f47,
+ 0x4f48, 0x4f49, 0x4f4a, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56,
+ 0x4f61, 0x4f62, 0x4f66, 0x4f68, 0x4f6a, 0x4f6b, 0x4f6d, 0x4f6e,
+ 0x4f71, 0x4f72, 0x4f75, 0x4f77, 0x4f78, 0x4f79, 0x4f7a, 0x4f7d,
+ 0x4f80, 0x4f81, 0x4f82, 0x4f85, 0x4f86, 0x4f87, 0x4f8a, 0x4f8c,
+ 0x4f8e, 0x4f90, 0x4f92, 0x4f93, 0x4f95, 0x4f96, 0x4f98, 0x4f99,
+ 0x4f9a, 0x4f9c, 0x4f9e, 0x4f9f, 0x4fa1, 0x4fa2,
+ /* 0x82 */
+ 0x4fa4, 0x4fab, 0x4fad, 0x4fb0, 0x4fb1, 0x4fb2, 0x4fb3, 0x4fb4,
+ 0x4fb6, 0x4fb7, 0x4fb8, 0x4fb9, 0x4fba, 0x4fbb, 0x4fbc, 0x4fbd,
+ 0x4fbe, 0x4fc0, 0x4fc1, 0x4fc2, 0x4fc6, 0x4fc7, 0x4fc8, 0x4fc9,
+ 0x4fcb, 0x4fcc, 0x4fcd, 0x4fd2, 0x4fd3, 0x4fd4, 0x4fd5, 0x4fd6,
+ 0x4fd9, 0x4fdb, 0x4fe0, 0x4fe2, 0x4fe4, 0x4fe5, 0x4fe7, 0x4feb,
+ 0x4fec, 0x4ff0, 0x4ff2, 0x4ff4, 0x4ff5, 0x4ff6, 0x4ff7, 0x4ff9,
+ 0x4ffb, 0x4ffc, 0x4ffd, 0x4fff, 0x5000, 0x5001, 0x5002, 0x5003,
+ 0x5004, 0x5005, 0x5006, 0x5007, 0x5008, 0x5009, 0x500a, 0x500b,
+ 0x500e, 0x5010, 0x5011, 0x5013, 0x5015, 0x5016, 0x5017, 0x501b,
+ 0x501d, 0x501e, 0x5020, 0x5022, 0x5023, 0x5024, 0x5027, 0x502b,
+ 0x502f, 0x5030, 0x5031, 0x5032, 0x5033, 0x5034, 0x5035, 0x5036,
+ 0x5037, 0x5038, 0x5039, 0x503b, 0x503d, 0x503f, 0x5040, 0x5041,
+ 0x5042, 0x5044, 0x5045, 0x5046, 0x5049, 0x504a, 0x504b, 0x504d,
+ 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5056, 0x5057, 0x5058,
+ 0x5059, 0x505b, 0x505d, 0x505e, 0x505f, 0x5060, 0x5061, 0x5062,
+ 0x5063, 0x5064, 0x5066, 0x5067, 0x5068, 0x5069, 0x506a, 0x506b,
+ 0x506d, 0x506e, 0x506f, 0x5070, 0x5071, 0x5072, 0x5073, 0x5074,
+ 0x5075, 0x5078, 0x5079, 0x507a, 0x507c, 0x507d, 0x5081, 0x5082,
+ 0x5083, 0x5084, 0x5086, 0x5087, 0x5089, 0x508a, 0x508b, 0x508c,
+ 0x508e, 0x508f, 0x5090, 0x5091, 0x5092, 0x5093, 0x5094, 0x5095,
+ 0x5096, 0x5097, 0x5098, 0x5099, 0x509a, 0x509b, 0x509c, 0x509d,
+ 0x509e, 0x509f, 0x50a0, 0x50a1, 0x50a2, 0x50a4, 0x50a6, 0x50aa,
+ 0x50ab, 0x50ad, 0x50ae, 0x50af, 0x50b0, 0x50b1, 0x50b3, 0x50b4,
+ 0x50b5, 0x50b6, 0x50b7, 0x50b8, 0x50b9, 0x50bc,
+ /* 0x83 */
+ 0x50bd, 0x50be, 0x50bf, 0x50c0, 0x50c1, 0x50c2, 0x50c3, 0x50c4,
+ 0x50c5, 0x50c6, 0x50c7, 0x50c8, 0x50c9, 0x50ca, 0x50cb, 0x50cc,
+ 0x50cd, 0x50ce, 0x50d0, 0x50d1, 0x50d2, 0x50d3, 0x50d4, 0x50d5,
+ 0x50d7, 0x50d8, 0x50d9, 0x50db, 0x50dc, 0x50dd, 0x50de, 0x50df,
+ 0x50e0, 0x50e1, 0x50e2, 0x50e3, 0x50e4, 0x50e5, 0x50e8, 0x50e9,
+ 0x50ea, 0x50eb, 0x50ef, 0x50f0, 0x50f1, 0x50f2, 0x50f4, 0x50f6,
+ 0x50f7, 0x50f8, 0x50f9, 0x50fa, 0x50fc, 0x50fd, 0x50fe, 0x50ff,
+ 0x5100, 0x5101, 0x5102, 0x5103, 0x5104, 0x5105, 0x5108, 0x5109,
+ 0x510a, 0x510c, 0x510d, 0x510e, 0x510f, 0x5110, 0x5111, 0x5113,
+ 0x5114, 0x5115, 0x5116, 0x5117, 0x5118, 0x5119, 0x511a, 0x511b,
+ 0x511c, 0x511d, 0x511e, 0x511f, 0x5120, 0x5122, 0x5123, 0x5124,
+ 0x5125, 0x5126, 0x5127, 0x5128, 0x5129, 0x512a, 0x512b, 0x512c,
+ 0x512d, 0x512e, 0x512f, 0x5130, 0x5131, 0x5132, 0x5133, 0x5134,
+ 0x5135, 0x5136, 0x5137, 0x5138, 0x5139, 0x513a, 0x513b, 0x513c,
+ 0x513d, 0x513e, 0x5142, 0x5147, 0x514a, 0x514c, 0x514e, 0x514f,
+ 0x5150, 0x5152, 0x5153, 0x5157, 0x5158, 0x5159, 0x515b, 0x515d,
+ 0x515e, 0x515f, 0x5160, 0x5161, 0x5163, 0x5164, 0x5166, 0x5167,
+ 0x5169, 0x516a, 0x516f, 0x5172, 0x517a, 0x517e, 0x517f, 0x5183,
+ 0x5184, 0x5186, 0x5187, 0x518a, 0x518b, 0x518e, 0x518f, 0x5190,
+ 0x5191, 0x5193, 0x5194, 0x5198, 0x519a, 0x519d, 0x519e, 0x519f,
+ 0x51a1, 0x51a3, 0x51a6, 0x51a7, 0x51a8, 0x51a9, 0x51aa, 0x51ad,
+ 0x51ae, 0x51b4, 0x51b8, 0x51b9, 0x51ba, 0x51be, 0x51bf, 0x51c1,
+ 0x51c2, 0x51c3, 0x51c5, 0x51c8, 0x51ca, 0x51cd, 0x51ce, 0x51d0,
+ 0x51d2, 0x51d3, 0x51d4, 0x51d5, 0x51d6, 0x51d7,
+ /* 0x84 */
+ 0x51d8, 0x51d9, 0x51da, 0x51dc, 0x51de, 0x51df, 0x51e2, 0x51e3,
+ 0x51e5, 0x51e6, 0x51e7, 0x51e8, 0x51e9, 0x51ea, 0x51ec, 0x51ee,
+ 0x51f1, 0x51f2, 0x51f4, 0x51f7, 0x51fe, 0x5204, 0x5205, 0x5209,
+ 0x520b, 0x520c, 0x520f, 0x5210, 0x5213, 0x5214, 0x5215, 0x521c,
+ 0x521e, 0x521f, 0x5221, 0x5222, 0x5223, 0x5225, 0x5226, 0x5227,
+ 0x522a, 0x522c, 0x522f, 0x5231, 0x5232, 0x5234, 0x5235, 0x523c,
+ 0x523e, 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524b,
+ 0x524e, 0x524f, 0x5252, 0x5253, 0x5255, 0x5257, 0x5258, 0x5259,
+ 0x525a, 0x525b, 0x525d, 0x525f, 0x5260, 0x5262, 0x5263, 0x5264,
+ 0x5266, 0x5268, 0x526b, 0x526c, 0x526d, 0x526e, 0x5270, 0x5271,
+ 0x5273, 0x5274, 0x5275, 0x5276, 0x5277, 0x5278, 0x5279, 0x527a,
+ 0x527b, 0x527c, 0x527e, 0x5280, 0x5283, 0x5284, 0x5285, 0x5286,
+ 0x5287, 0x5289, 0x528a, 0x528b, 0x528c, 0x528d, 0x528e, 0x528f,
+ 0x5291, 0x5292, 0x5294, 0x5295, 0x5296, 0x5297, 0x5298, 0x5299,
+ 0x529a, 0x529c, 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52ae, 0x52af,
+ 0x52b0, 0x52b4, 0x52b5, 0x52b6, 0x52b7, 0x52b8, 0x52b9, 0x52ba,
+ 0x52bb, 0x52bc, 0x52bd, 0x52c0, 0x52c1, 0x52c2, 0x52c4, 0x52c5,
+ 0x52c6, 0x52c8, 0x52ca, 0x52cc, 0x52cd, 0x52ce, 0x52cf, 0x52d1,
+ 0x52d3, 0x52d4, 0x52d5, 0x52d7, 0x52d9, 0x52da, 0x52db, 0x52dc,
+ 0x52dd, 0x52de, 0x52e0, 0x52e1, 0x52e2, 0x52e3, 0x52e5, 0x52e6,
+ 0x52e7, 0x52e8, 0x52e9, 0x52ea, 0x52eb, 0x52ec, 0x52ed, 0x52ee,
+ 0x52ef, 0x52f1, 0x52f2, 0x52f3, 0x52f4, 0x52f5, 0x52f6, 0x52f7,
+ 0x52f8, 0x52fb, 0x52fc, 0x52fd, 0x5301, 0x5302, 0x5303, 0x5304,
+ 0x5307, 0x5309, 0x530a, 0x530b, 0x530c, 0x530e,
+ /* 0x85 */
+ 0x5311, 0x5312, 0x5313, 0x5314, 0x5318, 0x531b, 0x531c, 0x531e,
+ 0x531f, 0x5322, 0x5324, 0x5325, 0x5327, 0x5328, 0x5329, 0x532b,
+ 0x532c, 0x532d, 0x532f, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334,
+ 0x5335, 0x5336, 0x5337, 0x5338, 0x533c, 0x533d, 0x5340, 0x5342,
+ 0x5344, 0x5346, 0x534b, 0x534c, 0x534d, 0x5350, 0x5354, 0x5358,
+ 0x5359, 0x535b, 0x535d, 0x5365, 0x5368, 0x536a, 0x536c, 0x536d,
+ 0x5372, 0x5376, 0x5379, 0x537b, 0x537c, 0x537d, 0x537e, 0x5380,
+ 0x5381, 0x5383, 0x5387, 0x5388, 0x538a, 0x538e, 0x538f, 0x5390,
+ 0x5391, 0x5392, 0x5393, 0x5394, 0x5396, 0x5397, 0x5399, 0x539b,
+ 0x539c, 0x539e, 0x53a0, 0x53a1, 0x53a4, 0x53a7, 0x53aa, 0x53ab,
+ 0x53ac, 0x53ad, 0x53af, 0x53b0, 0x53b1, 0x53b2, 0x53b3, 0x53b4,
+ 0x53b5, 0x53b7, 0x53b8, 0x53b9, 0x53ba, 0x53bc, 0x53bd, 0x53be,
+ 0x53c0, 0x53c3, 0x53c4, 0x53c5, 0x53c6, 0x53c7, 0x53ce, 0x53cf,
+ 0x53d0, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dc, 0x53dd, 0x53de,
+ 0x53e1, 0x53e2, 0x53e7, 0x53f4, 0x53fa, 0x53fe, 0x53ff, 0x5400,
+ 0x5402, 0x5405, 0x5407, 0x540b, 0x5414, 0x5418, 0x5419, 0x541a,
+ 0x541c, 0x5422, 0x5424, 0x5425, 0x542a, 0x5430, 0x5433, 0x5436,
+ 0x5437, 0x543a, 0x543d, 0x543f, 0x5441, 0x5442, 0x5444, 0x5445,
+ 0x5447, 0x5449, 0x544c, 0x544d, 0x544e, 0x544f, 0x5451, 0x545a,
+ 0x545d, 0x545e, 0x545f, 0x5460, 0x5461, 0x5463, 0x5465, 0x5467,
+ 0x5469, 0x546a, 0x546b, 0x546c, 0x546d, 0x546e, 0x546f, 0x5470,
+ 0x5474, 0x5479, 0x547a, 0x547e, 0x547f, 0x5481, 0x5483, 0x5485,
+ 0x5487, 0x5488, 0x5489, 0x548a, 0x548d, 0x5491, 0x5493, 0x5497,
+ 0x5498, 0x549c, 0x549e, 0x549f, 0x54a0, 0x54a1,
+ /* 0x86 */
+ 0x54a2, 0x54a5, 0x54ae, 0x54b0, 0x54b2, 0x54b5, 0x54b6, 0x54b7,
+ 0x54b9, 0x54ba, 0x54bc, 0x54be, 0x54c3, 0x54c5, 0x54ca, 0x54cb,
+ 0x54d6, 0x54d8, 0x54db, 0x54e0, 0x54e1, 0x54e2, 0x54e3, 0x54e4,
+ 0x54eb, 0x54ec, 0x54ef, 0x54f0, 0x54f1, 0x54f4, 0x54f5, 0x54f6,
+ 0x54f7, 0x54f8, 0x54f9, 0x54fb, 0x54fe, 0x5500, 0x5502, 0x5503,
+ 0x5504, 0x5505, 0x5508, 0x550a, 0x550b, 0x550c, 0x550d, 0x550e,
+ 0x5512, 0x5513, 0x5515, 0x5516, 0x5517, 0x5518, 0x5519, 0x551a,
+ 0x551c, 0x551d, 0x551e, 0x551f, 0x5521, 0x5525, 0x5526, 0x5528,
+ 0x5529, 0x552b, 0x552d, 0x5532, 0x5534, 0x5535, 0x5536, 0x5538,
+ 0x5539, 0x553a, 0x553b, 0x553d, 0x5540, 0x5542, 0x5545, 0x5547,
+ 0x5548, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 0x5551, 0x5552,
+ 0x5553, 0x5554, 0x5557, 0x5558, 0x5559, 0x555a, 0x555b, 0x555d,
+ 0x555e, 0x555f, 0x5560, 0x5562, 0x5563, 0x5568, 0x5569, 0x556b,
+ 0x556f, 0x5570, 0x5571, 0x5572, 0x5573, 0x5574, 0x5579, 0x557a,
+ 0x557d, 0x557f, 0x5585, 0x5586, 0x558c, 0x558d, 0x558e, 0x5590,
+ 0x5592, 0x5593, 0x5595, 0x5596, 0x5597, 0x559a, 0x559b, 0x559e,
+ 0x55a0, 0x55a1, 0x55a2, 0x55a3, 0x55a4, 0x55a5, 0x55a6, 0x55a8,
+ 0x55a9, 0x55aa, 0x55ab, 0x55ac, 0x55ad, 0x55ae, 0x55af, 0x55b0,
+ 0x55b2, 0x55b4, 0x55b6, 0x55b8, 0x55ba, 0x55bc, 0x55bf, 0x55c0,
+ 0x55c1, 0x55c2, 0x55c3, 0x55c6, 0x55c7, 0x55c8, 0x55ca, 0x55cb,
+ 0x55ce, 0x55cf, 0x55d0, 0x55d5, 0x55d7, 0x55d8, 0x55d9, 0x55da,
+ 0x55db, 0x55de, 0x55e0, 0x55e2, 0x55e7, 0x55e9, 0x55ed, 0x55ee,
+ 0x55f0, 0x55f1, 0x55f4, 0x55f6, 0x55f8, 0x55f9, 0x55fa, 0x55fb,
+ 0x55fc, 0x55ff, 0x5602, 0x5603, 0x5604, 0x5605,
+ /* 0x87 */
+ 0x5606, 0x5607, 0x560a, 0x560b, 0x560d, 0x5610, 0x5611, 0x5612,
+ 0x5613, 0x5614, 0x5615, 0x5616, 0x5617, 0x5619, 0x561a, 0x561c,
+ 0x561d, 0x5620, 0x5621, 0x5622, 0x5625, 0x5626, 0x5628, 0x5629,
+ 0x562a, 0x562b, 0x562e, 0x562f, 0x5630, 0x5633, 0x5635, 0x5637,
+ 0x5638, 0x563a, 0x563c, 0x563d, 0x563e, 0x5640, 0x5641, 0x5642,
+ 0x5643, 0x5644, 0x5645, 0x5646, 0x5647, 0x5648, 0x5649, 0x564a,
+ 0x564b, 0x564f, 0x5650, 0x5651, 0x5652, 0x5653, 0x5655, 0x5656,
+ 0x565a, 0x565b, 0x565d, 0x565e, 0x565f, 0x5660, 0x5661, 0x5663,
+ 0x5665, 0x5666, 0x5667, 0x566d, 0x566e, 0x566f, 0x5670, 0x5672,
+ 0x5673, 0x5674, 0x5675, 0x5677, 0x5678, 0x5679, 0x567a, 0x567d,
+ 0x567e, 0x567f, 0x5680, 0x5681, 0x5682, 0x5683, 0x5684, 0x5687,
+ 0x5688, 0x5689, 0x568a, 0x568b, 0x568c, 0x568d, 0x5690, 0x5691,
+ 0x5692, 0x5694, 0x5695, 0x5696, 0x5697, 0x5698, 0x5699, 0x569a,
+ 0x569b, 0x569c, 0x569d, 0x569e, 0x569f, 0x56a0, 0x56a1, 0x56a2,
+ 0x56a4, 0x56a5, 0x56a6, 0x56a7, 0x56a8, 0x56a9, 0x56aa, 0x56ab,
+ 0x56ac, 0x56ad, 0x56ae, 0x56b0, 0x56b1, 0x56b2, 0x56b3, 0x56b4,
+ 0x56b5, 0x56b6, 0x56b8, 0x56b9, 0x56ba, 0x56bb, 0x56bd, 0x56be,
+ 0x56bf, 0x56c0, 0x56c1, 0x56c2, 0x56c3, 0x56c4, 0x56c5, 0x56c6,
+ 0x56c7, 0x56c8, 0x56c9, 0x56cb, 0x56cc, 0x56cd, 0x56ce, 0x56cf,
+ 0x56d0, 0x56d1, 0x56d2, 0x56d3, 0x56d5, 0x56d6, 0x56d8, 0x56d9,
+ 0x56dc, 0x56e3, 0x56e5, 0x56e6, 0x56e7, 0x56e8, 0x56e9, 0x56ea,
+ 0x56ec, 0x56ee, 0x56ef, 0x56f2, 0x56f3, 0x56f6, 0x56f7, 0x56f8,
+ 0x56fb, 0x56fc, 0x5700, 0x5701, 0x5702, 0x5705, 0x5707, 0x570b,
+ 0x570c, 0x570d, 0x570e, 0x570f, 0x5710, 0x5711,
+ /* 0x88 */
+ 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718, 0x5719,
+ 0x571a, 0x571b, 0x571d, 0x571e, 0x5720, 0x5721, 0x5722, 0x5724,
+ 0x5725, 0x5726, 0x5727, 0x572b, 0x5731, 0x5732, 0x5734, 0x5735,
+ 0x5736, 0x5737, 0x5738, 0x573c, 0x573d, 0x573f, 0x5741, 0x5743,
+ 0x5744, 0x5745, 0x5746, 0x5748, 0x5749, 0x574b, 0x5752, 0x5753,
+ 0x5754, 0x5755, 0x5756, 0x5758, 0x5759, 0x5762, 0x5763, 0x5765,
+ 0x5767, 0x576c, 0x576e, 0x5770, 0x5771, 0x5772, 0x5774, 0x5775,
+ 0x5778, 0x5779, 0x577a, 0x577d, 0x577e, 0x577f, 0x5780, 0x5781,
+ 0x5787, 0x5788, 0x5789, 0x578a, 0x578d, 0x578e, 0x578f, 0x5790,
+ 0x5791, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799, 0x579a,
+ 0x579c, 0x579d, 0x579e, 0x579f, 0x57a5, 0x57a8, 0x57aa, 0x57ac,
+ 0x57af, 0x57b0, 0x57b1, 0x57b3, 0x57b5, 0x57b6, 0x57b7, 0x57b9,
+ 0x57ba, 0x57bb, 0x57bc, 0x57bd, 0x57be, 0x57bf, 0x57c0, 0x57c1,
+ 0x57c4, 0x57c5, 0x57c6, 0x57c7, 0x57c8, 0x57c9, 0x57ca, 0x57cc,
+ 0x57cd, 0x57d0, 0x57d1, 0x57d3, 0x57d6, 0x57d7, 0x57db, 0x57dc,
+ 0x57de, 0x57e1, 0x57e2, 0x57e3, 0x57e5, 0x57e6, 0x57e7, 0x57e8,
+ 0x57e9, 0x57ea, 0x57eb, 0x57ec, 0x57ee, 0x57f0, 0x57f1, 0x57f2,
+ 0x57f3, 0x57f5, 0x57f6, 0x57f7, 0x57fb, 0x57fc, 0x57fe, 0x57ff,
+ 0x5801, 0x5803, 0x5804, 0x5805, 0x5808, 0x5809, 0x580a, 0x580c,
+ 0x580e, 0x580f, 0x5810, 0x5812, 0x5813, 0x5814, 0x5816, 0x5817,
+ 0x5818, 0x581a, 0x581b, 0x581c, 0x581d, 0x581f, 0x5822, 0x5823,
+ 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x582b, 0x582c, 0x582d,
+ 0x582e, 0x582f, 0x5831, 0x5832, 0x5833, 0x5834, 0x5836, 0x5837,
+ 0x5838, 0x5839, 0x583a, 0x583b, 0x583c, 0x583d,
+ /* 0x89 */
+ 0x583e, 0x583f, 0x5840, 0x5841, 0x5842, 0x5843, 0x5845, 0x5846,
+ 0x5847, 0x5848, 0x5849, 0x584a, 0x584b, 0x584e, 0x584f, 0x5850,
+ 0x5852, 0x5853, 0x5855, 0x5856, 0x5857, 0x5859, 0x585a, 0x585b,
+ 0x585c, 0x585d, 0x585f, 0x5860, 0x5861, 0x5862, 0x5863, 0x5864,
+ 0x5866, 0x5867, 0x5868, 0x5869, 0x586a, 0x586d, 0x586e, 0x586f,
+ 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877,
+ 0x5878, 0x5879, 0x587a, 0x587b, 0x587c, 0x587d, 0x587f, 0x5882,
+ 0x5884, 0x5886, 0x5887, 0x5888, 0x588a, 0x588b, 0x588c, 0x588d,
+ 0x588e, 0x588f, 0x5890, 0x5891, 0x5894, 0x5895, 0x5896, 0x5897,
+ 0x5898, 0x589b, 0x589c, 0x589d, 0x58a0, 0x58a1, 0x58a2, 0x58a3,
+ 0x58a4, 0x58a5, 0x58a6, 0x58a7, 0x58aa, 0x58ab, 0x58ac, 0x58ad,
+ 0x58ae, 0x58af, 0x58b0, 0x58b1, 0x58b2, 0x58b3, 0x58b4, 0x58b5,
+ 0x58b6, 0x58b7, 0x58b8, 0x58b9, 0x58ba, 0x58bb, 0x58bd, 0x58be,
+ 0x58bf, 0x58c0, 0x58c2, 0x58c3, 0x58c4, 0x58c6, 0x58c7, 0x58c8,
+ 0x58c9, 0x58ca, 0x58cb, 0x58cc, 0x58cd, 0x58ce, 0x58cf, 0x58d0,
+ 0x58d2, 0x58d3, 0x58d4, 0x58d6, 0x58d7, 0x58d8, 0x58d9, 0x58da,
+ 0x58db, 0x58dc, 0x58dd, 0x58de, 0x58df, 0x58e0, 0x58e1, 0x58e2,
+ 0x58e3, 0x58e5, 0x58e6, 0x58e7, 0x58e8, 0x58e9, 0x58ea, 0x58ed,
+ 0x58ef, 0x58f1, 0x58f2, 0x58f4, 0x58f5, 0x58f7, 0x58f8, 0x58fa,
+ 0x58fb, 0x58fc, 0x58fd, 0x58fe, 0x58ff, 0x5900, 0x5901, 0x5903,
+ 0x5905, 0x5906, 0x5908, 0x5909, 0x590a, 0x590b, 0x590c, 0x590e,
+ 0x5910, 0x5911, 0x5912, 0x5913, 0x5917, 0x5918, 0x591b, 0x591d,
+ 0x591e, 0x5920, 0x5921, 0x5922, 0x5923, 0x5926, 0x5928, 0x592c,
+ 0x5930, 0x5932, 0x5933, 0x5935, 0x5936, 0x593b,
+ /* 0x8a */
+ 0x593d, 0x593e, 0x593f, 0x5940, 0x5943, 0x5945, 0x5946, 0x594a,
+ 0x594c, 0x594d, 0x5950, 0x5952, 0x5953, 0x5959, 0x595b, 0x595c,
+ 0x595d, 0x595e, 0x595f, 0x5961, 0x5963, 0x5964, 0x5966, 0x5967,
+ 0x5968, 0x5969, 0x596a, 0x596b, 0x596c, 0x596d, 0x596e, 0x596f,
+ 0x5970, 0x5971, 0x5972, 0x5975, 0x5977, 0x597a, 0x597b, 0x597c,
+ 0x597e, 0x597f, 0x5980, 0x5985, 0x5989, 0x598b, 0x598c, 0x598e,
+ 0x598f, 0x5990, 0x5991, 0x5994, 0x5995, 0x5998, 0x599a, 0x599b,
+ 0x599c, 0x599d, 0x599f, 0x59a0, 0x59a1, 0x59a2, 0x59a6, 0x59a7,
+ 0x59ac, 0x59ad, 0x59b0, 0x59b1, 0x59b3, 0x59b4, 0x59b5, 0x59b6,
+ 0x59b7, 0x59b8, 0x59ba, 0x59bc, 0x59bd, 0x59bf, 0x59c0, 0x59c1,
+ 0x59c2, 0x59c3, 0x59c4, 0x59c5, 0x59c7, 0x59c8, 0x59c9, 0x59cc,
+ 0x59cd, 0x59ce, 0x59cf, 0x59d5, 0x59d6, 0x59d9, 0x59db, 0x59de,
+ 0x59df, 0x59e0, 0x59e1, 0x59e2, 0x59e4, 0x59e6, 0x59e7, 0x59e9,
+ 0x59ea, 0x59eb, 0x59ed, 0x59ee, 0x59ef, 0x59f0, 0x59f1, 0x59f2,
+ 0x59f3, 0x59f4, 0x59f5, 0x59f6, 0x59f7, 0x59f8, 0x59fa, 0x59fc,
+ 0x59fd, 0x59fe, 0x5a00, 0x5a02, 0x5a0a, 0x5a0b, 0x5a0d, 0x5a0e,
+ 0x5a0f, 0x5a10, 0x5a12, 0x5a14, 0x5a15, 0x5a16, 0x5a17, 0x5a19,
+ 0x5a1a, 0x5a1b, 0x5a1d, 0x5a1e, 0x5a21, 0x5a22, 0x5a24, 0x5a26,
+ 0x5a27, 0x5a28, 0x5a2a, 0x5a2b, 0x5a2c, 0x5a2d, 0x5a2e, 0x5a2f,
+ 0x5a30, 0x5a33, 0x5a35, 0x5a37, 0x5a38, 0x5a39, 0x5a3a, 0x5a3b,
+ 0x5a3d, 0x5a3e, 0x5a3f, 0x5a41, 0x5a42, 0x5a43, 0x5a44, 0x5a45,
+ 0x5a47, 0x5a48, 0x5a4b, 0x5a4c, 0x5a4d, 0x5a4e, 0x5a4f, 0x5a50,
+ 0x5a51, 0x5a52, 0x5a53, 0x5a54, 0x5a56, 0x5a57, 0x5a58, 0x5a59,
+ 0x5a5b, 0x5a5c, 0x5a5d, 0x5a5e, 0x5a5f, 0x5a60,
+ /* 0x8b */
+ 0x5a61, 0x5a63, 0x5a64, 0x5a65, 0x5a66, 0x5a68, 0x5a69, 0x5a6b,
+ 0x5a6c, 0x5a6d, 0x5a6e, 0x5a6f, 0x5a70, 0x5a71, 0x5a72, 0x5a73,
+ 0x5a78, 0x5a79, 0x5a7b, 0x5a7c, 0x5a7d, 0x5a7e, 0x5a80, 0x5a81,
+ 0x5a82, 0x5a83, 0x5a84, 0x5a85, 0x5a86, 0x5a87, 0x5a88, 0x5a89,
+ 0x5a8a, 0x5a8b, 0x5a8c, 0x5a8d, 0x5a8e, 0x5a8f, 0x5a90, 0x5a91,
+ 0x5a93, 0x5a94, 0x5a95, 0x5a96, 0x5a97, 0x5a98, 0x5a99, 0x5a9c,
+ 0x5a9d, 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa1, 0x5aa2, 0x5aa3, 0x5aa4,
+ 0x5aa5, 0x5aa6, 0x5aa7, 0x5aa8, 0x5aa9, 0x5aab, 0x5aac, 0x5aad,
+ 0x5aae, 0x5aaf, 0x5ab0, 0x5ab1, 0x5ab4, 0x5ab6, 0x5ab7, 0x5ab9,
+ 0x5aba, 0x5abb, 0x5abc, 0x5abd, 0x5abf, 0x5ac0, 0x5ac3, 0x5ac4,
+ 0x5ac5, 0x5ac6, 0x5ac7, 0x5ac8, 0x5aca, 0x5acb, 0x5acd, 0x5ace,
+ 0x5acf, 0x5ad0, 0x5ad1, 0x5ad3, 0x5ad5, 0x5ad7, 0x5ad9, 0x5ada,
+ 0x5adb, 0x5add, 0x5ade, 0x5adf, 0x5ae2, 0x5ae4, 0x5ae5, 0x5ae7,
+ 0x5ae8, 0x5aea, 0x5aec, 0x5aed, 0x5aee, 0x5aef, 0x5af0, 0x5af2,
+ 0x5af3, 0x5af4, 0x5af5, 0x5af6, 0x5af7, 0x5af8, 0x5af9, 0x5afa,
+ 0x5afb, 0x5afc, 0x5afd, 0x5afe, 0x5aff, 0x5b00, 0x5b01, 0x5b02,
+ 0x5b03, 0x5b04, 0x5b05, 0x5b06, 0x5b07, 0x5b08, 0x5b0a, 0x5b0b,
+ 0x5b0c, 0x5b0d, 0x5b0e, 0x5b0f, 0x5b10, 0x5b11, 0x5b12, 0x5b13,
+ 0x5b14, 0x5b15, 0x5b18, 0x5b19, 0x5b1a, 0x5b1b, 0x5b1c, 0x5b1d,
+ 0x5b1e, 0x5b1f, 0x5b20, 0x5b21, 0x5b22, 0x5b23, 0x5b24, 0x5b25,
+ 0x5b26, 0x5b27, 0x5b28, 0x5b29, 0x5b2a, 0x5b2b, 0x5b2c, 0x5b2d,
+ 0x5b2e, 0x5b2f, 0x5b30, 0x5b31, 0x5b33, 0x5b35, 0x5b36, 0x5b38,
+ 0x5b39, 0x5b3a, 0x5b3b, 0x5b3c, 0x5b3d, 0x5b3e, 0x5b3f, 0x5b41,
+ 0x5b42, 0x5b43, 0x5b44, 0x5b45, 0x5b46, 0x5b47,
+ /* 0x8c */
+ 0x5b48, 0x5b49, 0x5b4a, 0x5b4b, 0x5b4c, 0x5b4d, 0x5b4e, 0x5b4f,
+ 0x5b52, 0x5b56, 0x5b5e, 0x5b60, 0x5b61, 0x5b67, 0x5b68, 0x5b6b,
+ 0x5b6d, 0x5b6e, 0x5b6f, 0x5b72, 0x5b74, 0x5b76, 0x5b77, 0x5b78,
+ 0x5b79, 0x5b7b, 0x5b7c, 0x5b7e, 0x5b7f, 0x5b82, 0x5b86, 0x5b8a,
+ 0x5b8d, 0x5b8e, 0x5b90, 0x5b91, 0x5b92, 0x5b94, 0x5b96, 0x5b9f,
+ 0x5ba7, 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5bae, 0x5baf, 0x5bb1,
+ 0x5bb2, 0x5bb7, 0x5bba, 0x5bbb, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bc3,
+ 0x5bc8, 0x5bc9, 0x5bca, 0x5bcb, 0x5bcd, 0x5bce, 0x5bcf, 0x5bd1,
+ 0x5bd4, 0x5bd5, 0x5bd6, 0x5bd7, 0x5bd8, 0x5bd9, 0x5bda, 0x5bdb,
+ 0x5bdc, 0x5be0, 0x5be2, 0x5be3, 0x5be6, 0x5be7, 0x5be9, 0x5bea,
+ 0x5beb, 0x5bec, 0x5bed, 0x5bef, 0x5bf1, 0x5bf2, 0x5bf3, 0x5bf4,
+ 0x5bf5, 0x5bf6, 0x5bf7, 0x5bfd, 0x5bfe, 0x5c00, 0x5c02, 0x5c03,
+ 0x5c05, 0x5c07, 0x5c08, 0x5c0b, 0x5c0c, 0x5c0d, 0x5c0e, 0x5c10,
+ 0x5c12, 0x5c13, 0x5c17, 0x5c19, 0x5c1b, 0x5c1e, 0x5c1f, 0x5c20,
+ 0x5c21, 0x5c23, 0x5c26, 0x5c28, 0x5c29, 0x5c2a, 0x5c2b, 0x5c2d,
+ 0x5c2e, 0x5c2f, 0x5c30, 0x5c32, 0x5c33, 0x5c35, 0x5c36, 0x5c37,
+ 0x5c43, 0x5c44, 0x5c46, 0x5c47, 0x5c4c, 0x5c4d, 0x5c52, 0x5c53,
+ 0x5c54, 0x5c56, 0x5c57, 0x5c58, 0x5c5a, 0x5c5b, 0x5c5c, 0x5c5d,
+ 0x5c5f, 0x5c62, 0x5c64, 0x5c67, 0x5c68, 0x5c69, 0x5c6a, 0x5c6b,
+ 0x5c6c, 0x5c6d, 0x5c70, 0x5c72, 0x5c73, 0x5c74, 0x5c75, 0x5c76,
+ 0x5c77, 0x5c78, 0x5c7b, 0x5c7c, 0x5c7d, 0x5c7e, 0x5c80, 0x5c83,
+ 0x5c84, 0x5c85, 0x5c86, 0x5c87, 0x5c89, 0x5c8a, 0x5c8b, 0x5c8e,
+ 0x5c8f, 0x5c92, 0x5c93, 0x5c95, 0x5c9d, 0x5c9e, 0x5c9f, 0x5ca0,
+ 0x5ca1, 0x5ca4, 0x5ca5, 0x5ca6, 0x5ca7, 0x5ca8,
+ /* 0x8d */
+ 0x5caa, 0x5cae, 0x5caf, 0x5cb0, 0x5cb2, 0x5cb4, 0x5cb6, 0x5cb9,
+ 0x5cba, 0x5cbb, 0x5cbc, 0x5cbe, 0x5cc0, 0x5cc2, 0x5cc3, 0x5cc5,
+ 0x5cc6, 0x5cc7, 0x5cc8, 0x5cc9, 0x5cca, 0x5ccc, 0x5ccd, 0x5cce,
+ 0x5ccf, 0x5cd0, 0x5cd1, 0x5cd3, 0x5cd4, 0x5cd5, 0x5cd6, 0x5cd7,
+ 0x5cd8, 0x5cda, 0x5cdb, 0x5cdc, 0x5cdd, 0x5cde, 0x5cdf, 0x5ce0,
+ 0x5ce2, 0x5ce3, 0x5ce7, 0x5ce9, 0x5ceb, 0x5cec, 0x5cee, 0x5cef,
+ 0x5cf1, 0x5cf2, 0x5cf3, 0x5cf4, 0x5cf5, 0x5cf6, 0x5cf7, 0x5cf8,
+ 0x5cf9, 0x5cfa, 0x5cfc, 0x5cfd, 0x5cfe, 0x5cff, 0x5d00, 0x5d01,
+ 0x5d04, 0x5d05, 0x5d08, 0x5d09, 0x5d0a, 0x5d0b, 0x5d0c, 0x5d0d,
+ 0x5d0f, 0x5d10, 0x5d11, 0x5d12, 0x5d13, 0x5d15, 0x5d17, 0x5d18,
+ 0x5d19, 0x5d1a, 0x5d1c, 0x5d1d, 0x5d1f, 0x5d20, 0x5d21, 0x5d22,
+ 0x5d23, 0x5d25, 0x5d28, 0x5d2a, 0x5d2b, 0x5d2c, 0x5d2f, 0x5d30,
+ 0x5d31, 0x5d32, 0x5d33, 0x5d35, 0x5d36, 0x5d37, 0x5d38, 0x5d39,
+ 0x5d3a, 0x5d3b, 0x5d3c, 0x5d3f, 0x5d40, 0x5d41, 0x5d42, 0x5d43,
+ 0x5d44, 0x5d45, 0x5d46, 0x5d48, 0x5d49, 0x5d4d, 0x5d4e, 0x5d4f,
+ 0x5d50, 0x5d51, 0x5d52, 0x5d53, 0x5d54, 0x5d55, 0x5d56, 0x5d57,
+ 0x5d59, 0x5d5a, 0x5d5c, 0x5d5e, 0x5d5f, 0x5d60, 0x5d61, 0x5d62,
+ 0x5d63, 0x5d64, 0x5d65, 0x5d66, 0x5d67, 0x5d68, 0x5d6a, 0x5d6d,
+ 0x5d6e, 0x5d70, 0x5d71, 0x5d72, 0x5d73, 0x5d75, 0x5d76, 0x5d77,
+ 0x5d78, 0x5d79, 0x5d7a, 0x5d7b, 0x5d7c, 0x5d7d, 0x5d7e, 0x5d7f,
+ 0x5d80, 0x5d81, 0x5d83, 0x5d84, 0x5d85, 0x5d86, 0x5d87, 0x5d88,
+ 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, 0x5d8d, 0x5d8e, 0x5d8f, 0x5d90,
+ 0x5d91, 0x5d92, 0x5d93, 0x5d94, 0x5d95, 0x5d96, 0x5d97, 0x5d98,
+ 0x5d9a, 0x5d9b, 0x5d9c, 0x5d9e, 0x5d9f, 0x5da0,
+ /* 0x8e */
+ 0x5da1, 0x5da2, 0x5da3, 0x5da4, 0x5da5, 0x5da6, 0x5da7, 0x5da8,
+ 0x5da9, 0x5daa, 0x5dab, 0x5dac, 0x5dad, 0x5dae, 0x5daf, 0x5db0,
+ 0x5db1, 0x5db2, 0x5db3, 0x5db4, 0x5db5, 0x5db6, 0x5db8, 0x5db9,
+ 0x5dba, 0x5dbb, 0x5dbc, 0x5dbd, 0x5dbe, 0x5dbf, 0x5dc0, 0x5dc1,
+ 0x5dc2, 0x5dc3, 0x5dc4, 0x5dc6, 0x5dc7, 0x5dc8, 0x5dc9, 0x5dca,
+ 0x5dcb, 0x5dcc, 0x5dce, 0x5dcf, 0x5dd0, 0x5dd1, 0x5dd2, 0x5dd3,
+ 0x5dd4, 0x5dd5, 0x5dd6, 0x5dd7, 0x5dd8, 0x5dd9, 0x5dda, 0x5ddc,
+ 0x5ddf, 0x5de0, 0x5de3, 0x5de4, 0x5dea, 0x5dec, 0x5ded, 0x5df0,
+ 0x5df5, 0x5df6, 0x5df8, 0x5df9, 0x5dfa, 0x5dfb, 0x5dfc, 0x5dff,
+ 0x5e00, 0x5e04, 0x5e07, 0x5e09, 0x5e0a, 0x5e0b, 0x5e0d, 0x5e0e,
+ 0x5e12, 0x5e13, 0x5e17, 0x5e1e, 0x5e1f, 0x5e20, 0x5e21, 0x5e22,
+ 0x5e23, 0x5e24, 0x5e25, 0x5e28, 0x5e29, 0x5e2a, 0x5e2b, 0x5e2c,
+ 0x5e2f, 0x5e30, 0x5e32, 0x5e33, 0x5e34, 0x5e35, 0x5e36, 0x5e39,
+ 0x5e3a, 0x5e3e, 0x5e3f, 0x5e40, 0x5e41, 0x5e43, 0x5e46, 0x5e47,
+ 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50,
+ 0x5e51, 0x5e52, 0x5e53, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a,
+ 0x5e5c, 0x5e5d, 0x5e5f, 0x5e60, 0x5e63, 0x5e64, 0x5e65, 0x5e66,
+ 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e,
+ 0x5e6f, 0x5e70, 0x5e71, 0x5e75, 0x5e77, 0x5e79, 0x5e7e, 0x5e81,
+ 0x5e82, 0x5e83, 0x5e85, 0x5e88, 0x5e89, 0x5e8c, 0x5e8d, 0x5e8e,
+ 0x5e92, 0x5e98, 0x5e9b, 0x5e9d, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4,
+ 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, 0x5eae, 0x5eaf, 0x5eb0,
+ 0x5eb1, 0x5eb2, 0x5eb4, 0x5eba, 0x5ebb, 0x5ebc, 0x5ebd, 0x5ebf,
+ 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, 0x5ec5,
+ /* 0x8f */
+ 0x5ec6, 0x5ec7, 0x5ec8, 0x5ecb, 0x5ecc, 0x5ecd, 0x5ece, 0x5ecf,
+ 0x5ed0, 0x5ed4, 0x5ed5, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edc,
+ 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4,
+ 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee9, 0x5eeb, 0x5eec, 0x5eed, 0x5eee,
+ 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef5, 0x5ef8, 0x5ef9,
+ 0x5efb, 0x5efc, 0x5efd, 0x5f05, 0x5f06, 0x5f07, 0x5f09, 0x5f0c,
+ 0x5f0d, 0x5f0e, 0x5f10, 0x5f12, 0x5f14, 0x5f16, 0x5f19, 0x5f1a,
+ 0x5f1c, 0x5f1d, 0x5f1e, 0x5f21, 0x5f22, 0x5f23, 0x5f24, 0x5f28,
+ 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f32, 0x5f33, 0x5f34, 0x5f35,
+ 0x5f36, 0x5f37, 0x5f38, 0x5f3b, 0x5f3d, 0x5f3e, 0x5f3f, 0x5f41,
+ 0x5f42, 0x5f43, 0x5f44, 0x5f45, 0x5f46, 0x5f47, 0x5f48, 0x5f49,
+ 0x5f4a, 0x5f4b, 0x5f4c, 0x5f4d, 0x5f4e, 0x5f4f, 0x5f51, 0x5f54,
+ 0x5f59, 0x5f5a, 0x5f5b, 0x5f5c, 0x5f5e, 0x5f5f, 0x5f60, 0x5f63,
+ 0x5f65, 0x5f67, 0x5f68, 0x5f6b, 0x5f6e, 0x5f6f, 0x5f72, 0x5f74,
+ 0x5f75, 0x5f76, 0x5f78, 0x5f7a, 0x5f7d, 0x5f7e, 0x5f7f, 0x5f83,
+ 0x5f86, 0x5f8d, 0x5f8e, 0x5f8f, 0x5f91, 0x5f93, 0x5f94, 0x5f96,
+ 0x5f9a, 0x5f9b, 0x5f9d, 0x5f9e, 0x5f9f, 0x5fa0, 0x5fa2, 0x5fa3,
+ 0x5fa4, 0x5fa5, 0x5fa6, 0x5fa7, 0x5fa9, 0x5fab, 0x5fac, 0x5faf,
+ 0x5fb0, 0x5fb1, 0x5fb2, 0x5fb3, 0x5fb4, 0x5fb6, 0x5fb8, 0x5fb9,
+ 0x5fba, 0x5fbb, 0x5fbe, 0x5fbf, 0x5fc0, 0x5fc1, 0x5fc2, 0x5fc7,
+ 0x5fc8, 0x5fca, 0x5fcb, 0x5fce, 0x5fd3, 0x5fd4, 0x5fd5, 0x5fda,
+ 0x5fdb, 0x5fdc, 0x5fde, 0x5fdf, 0x5fe2, 0x5fe3, 0x5fe5, 0x5fe6,
+ 0x5fe8, 0x5fe9, 0x5fec, 0x5fef, 0x5ff0, 0x5ff2, 0x5ff3, 0x5ff4,
+ 0x5ff6, 0x5ff7, 0x5ff9, 0x5ffa, 0x5ffc, 0x6007,
+ /* 0x90 */
+ 0x6008, 0x6009, 0x600b, 0x600c, 0x6010, 0x6011, 0x6013, 0x6017,
+ 0x6018, 0x601a, 0x601e, 0x601f, 0x6022, 0x6023, 0x6024, 0x602c,
+ 0x602d, 0x602e, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6036,
+ 0x6037, 0x6038, 0x6039, 0x603a, 0x603d, 0x603e, 0x6040, 0x6044,
+ 0x6045, 0x6046, 0x6047, 0x6048, 0x6049, 0x604a, 0x604c, 0x604e,
+ 0x604f, 0x6051, 0x6053, 0x6054, 0x6056, 0x6057, 0x6058, 0x605b,
+ 0x605c, 0x605e, 0x605f, 0x6060, 0x6061, 0x6065, 0x6066, 0x606e,
+ 0x6071, 0x6072, 0x6074, 0x6075, 0x6077, 0x607e, 0x6080, 0x6081,
+ 0x6082, 0x6085, 0x6086, 0x6087, 0x6088, 0x608a, 0x608b, 0x608e,
+ 0x608f, 0x6090, 0x6091, 0x6093, 0x6095, 0x6097, 0x6098, 0x6099,
+ 0x609c, 0x609e, 0x60a1, 0x60a2, 0x60a4, 0x60a5, 0x60a7, 0x60a9,
+ 0x60aa, 0x60ae, 0x60b0, 0x60b3, 0x60b5, 0x60b6, 0x60b7, 0x60b9,
+ 0x60ba, 0x60bd, 0x60be, 0x60bf, 0x60c0, 0x60c1, 0x60c2, 0x60c3,
+ 0x60c4, 0x60c7, 0x60c8, 0x60c9, 0x60cc, 0x60cd, 0x60ce, 0x60cf,
+ 0x60d0, 0x60d2, 0x60d3, 0x60d4, 0x60d6, 0x60d7, 0x60d9, 0x60db,
+ 0x60de, 0x60e1, 0x60e2, 0x60e3, 0x60e4, 0x60e5, 0x60ea, 0x60f1,
+ 0x60f2, 0x60f5, 0x60f7, 0x60f8, 0x60fb, 0x60fc, 0x60fd, 0x60fe,
+ 0x60ff, 0x6102, 0x6103, 0x6104, 0x6105, 0x6107, 0x610a, 0x610b,
+ 0x610c, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, 0x6116, 0x6117,
+ 0x6118, 0x6119, 0x611b, 0x611c, 0x611d, 0x611e, 0x6121, 0x6122,
+ 0x6125, 0x6128, 0x6129, 0x612a, 0x612c, 0x612d, 0x612e, 0x612f,
+ 0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137,
+ 0x6138, 0x6139, 0x613a, 0x613b, 0x613c, 0x613d, 0x613e, 0x6140,
+ 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146,
+ /* 0x91 */
+ 0x6147, 0x6149, 0x614b, 0x614d, 0x614f, 0x6150, 0x6152, 0x6153,
+ 0x6154, 0x6156, 0x6157, 0x6158, 0x6159, 0x615a, 0x615b, 0x615c,
+ 0x615e, 0x615f, 0x6160, 0x6161, 0x6163, 0x6164, 0x6165, 0x6166,
+ 0x6169, 0x616a, 0x616b, 0x616c, 0x616d, 0x616e, 0x616f, 0x6171,
+ 0x6172, 0x6173, 0x6174, 0x6176, 0x6178, 0x6179, 0x617a, 0x617b,
+ 0x617c, 0x617d, 0x617e, 0x617f, 0x6180, 0x6181, 0x6182, 0x6183,
+ 0x6184, 0x6185, 0x6186, 0x6187, 0x6188, 0x6189, 0x618a, 0x618c,
+ 0x618d, 0x618f, 0x6190, 0x6191, 0x6192, 0x6193, 0x6195, 0x6196,
+ 0x6197, 0x6198, 0x6199, 0x619a, 0x619b, 0x619c, 0x619e, 0x619f,
+ 0x61a0, 0x61a1, 0x61a2, 0x61a3, 0x61a4, 0x61a5, 0x61a6, 0x61aa,
+ 0x61ab, 0x61ad, 0x61ae, 0x61af, 0x61b0, 0x61b1, 0x61b2, 0x61b3,
+ 0x61b4, 0x61b5, 0x61b6, 0x61b8, 0x61b9, 0x61ba, 0x61bb, 0x61bc,
+ 0x61bd, 0x61bf, 0x61c0, 0x61c1, 0x61c3, 0x61c4, 0x61c5, 0x61c6,
+ 0x61c7, 0x61c9, 0x61cc, 0x61cd, 0x61ce, 0x61cf, 0x61d0, 0x61d3,
+ 0x61d5, 0x61d6, 0x61d7, 0x61d8, 0x61d9, 0x61da, 0x61db, 0x61dc,
+ 0x61dd, 0x61de, 0x61df, 0x61e0, 0x61e1, 0x61e2, 0x61e3, 0x61e4,
+ 0x61e5, 0x61e7, 0x61e8, 0x61e9, 0x61ea, 0x61eb, 0x61ec, 0x61ed,
+ 0x61ee, 0x61ef, 0x61f0, 0x61f1, 0x61f2, 0x61f3, 0x61f4, 0x61f6,
+ 0x61f7, 0x61f8, 0x61f9, 0x61fa, 0x61fb, 0x61fc, 0x61fd, 0x61fe,
+ 0x6200, 0x6201, 0x6202, 0x6203, 0x6204, 0x6205, 0x6207, 0x6209,
+ 0x6213, 0x6214, 0x6219, 0x621c, 0x621d, 0x621e, 0x6220, 0x6223,
+ 0x6226, 0x6227, 0x6228, 0x6229, 0x622b, 0x622d, 0x622f, 0x6230,
+ 0x6231, 0x6232, 0x6235, 0x6236, 0x6238, 0x6239, 0x623a, 0x623b,
+ 0x623c, 0x6242, 0x6244, 0x6245, 0x6246, 0x624a,
+ /* 0x92 */
+ 0x624f, 0x6250, 0x6255, 0x6256, 0x6257, 0x6259, 0x625a, 0x625c,
+ 0x625d, 0x625e, 0x625f, 0x6260, 0x6261, 0x6262, 0x6264, 0x6265,
+ 0x6268, 0x6271, 0x6272, 0x6274, 0x6275, 0x6277, 0x6278, 0x627a,
+ 0x627b, 0x627d, 0x6281, 0x6282, 0x6283, 0x6285, 0x6286, 0x6287,
+ 0x6288, 0x628b, 0x628c, 0x628d, 0x628e, 0x628f, 0x6290, 0x6294,
+ 0x6299, 0x629c, 0x629d, 0x629e, 0x62a3, 0x62a6, 0x62a7, 0x62a9,
+ 0x62aa, 0x62ad, 0x62ae, 0x62af, 0x62b0, 0x62b2, 0x62b3, 0x62b4,
+ 0x62b6, 0x62b7, 0x62b8, 0x62ba, 0x62be, 0x62c0, 0x62c1, 0x62c3,
+ 0x62cb, 0x62cf, 0x62d1, 0x62d5, 0x62dd, 0x62de, 0x62e0, 0x62e1,
+ 0x62e4, 0x62ea, 0x62eb, 0x62f0, 0x62f2, 0x62f5, 0x62f8, 0x62f9,
+ 0x62fa, 0x62fb, 0x6300, 0x6303, 0x6304, 0x6305, 0x6306, 0x630a,
+ 0x630b, 0x630c, 0x630d, 0x630f, 0x6310, 0x6312, 0x6313, 0x6314,
+ 0x6315, 0x6317, 0x6318, 0x6319, 0x631c, 0x6326, 0x6327, 0x6329,
+ 0x632c, 0x632d, 0x632e, 0x6330, 0x6331, 0x6333, 0x6334, 0x6335,
+ 0x6336, 0x6337, 0x6338, 0x633b, 0x633c, 0x633e, 0x633f, 0x6340,
+ 0x6341, 0x6344, 0x6347, 0x6348, 0x634a, 0x6351, 0x6352, 0x6353,
+ 0x6354, 0x6356, 0x6357, 0x6358, 0x6359, 0x635a, 0x635b, 0x635c,
+ 0x635d, 0x6360, 0x6364, 0x6365, 0x6366, 0x6368, 0x636a, 0x636b,
+ 0x636c, 0x636f, 0x6370, 0x6372, 0x6373, 0x6374, 0x6375, 0x6378,
+ 0x6379, 0x637c, 0x637d, 0x637e, 0x637f, 0x6381, 0x6383, 0x6384,
+ 0x6385, 0x6386, 0x638b, 0x638d, 0x6391, 0x6393, 0x6394, 0x6395,
+ 0x6397, 0x6399, 0x639a, 0x639b, 0x639c, 0x639d, 0x639e, 0x639f,
+ 0x63a1, 0x63a4, 0x63a6, 0x63ab, 0x63af, 0x63b1, 0x63b2, 0x63b5,
+ 0x63b6, 0x63b9, 0x63bb, 0x63bd, 0x63bf, 0x63c0,
+ /* 0x93 */
+ 0x63c1, 0x63c2, 0x63c3, 0x63c5, 0x63c7, 0x63c8, 0x63ca, 0x63cb,
+ 0x63cc, 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63d7, 0x63d8, 0x63d9,
+ 0x63da, 0x63db, 0x63dc, 0x63dd, 0x63df, 0x63e2, 0x63e4, 0x63e5,
+ 0x63e6, 0x63e7, 0x63e8, 0x63eb, 0x63ec, 0x63ee, 0x63ef, 0x63f0,
+ 0x63f1, 0x63f3, 0x63f5, 0x63f7, 0x63f9, 0x63fa, 0x63fb, 0x63fc,
+ 0x63fe, 0x6403, 0x6404, 0x6406, 0x6407, 0x6408, 0x6409, 0x640a,
+ 0x640d, 0x640e, 0x6411, 0x6412, 0x6415, 0x6416, 0x6417, 0x6418,
+ 0x6419, 0x641a, 0x641d, 0x641f, 0x6422, 0x6423, 0x6424, 0x6425,
+ 0x6427, 0x6428, 0x6429, 0x642b, 0x642e, 0x642f, 0x6430, 0x6431,
+ 0x6432, 0x6433, 0x6435, 0x6436, 0x6437, 0x6438, 0x6439, 0x643b,
+ 0x643c, 0x643e, 0x6440, 0x6442, 0x6443, 0x6449, 0x644b, 0x644c,
+ 0x644d, 0x644e, 0x644f, 0x6450, 0x6451, 0x6453, 0x6455, 0x6456,
+ 0x6457, 0x6459, 0x645a, 0x645b, 0x645c, 0x645d, 0x645f, 0x6460,
+ 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, 0x6468, 0x646a,
+ 0x646b, 0x646c, 0x646e, 0x646f, 0x6470, 0x6471, 0x6472, 0x6473,
+ 0x6474, 0x6475, 0x6476, 0x6477, 0x647b, 0x647c, 0x647d, 0x647e,
+ 0x647f, 0x6480, 0x6481, 0x6483, 0x6486, 0x6488, 0x6489, 0x648a,
+ 0x648b, 0x648c, 0x648d, 0x648e, 0x648f, 0x6490, 0x6493, 0x6494,
+ 0x6497, 0x6498, 0x649a, 0x649b, 0x649c, 0x649d, 0x649f, 0x64a0,
+ 0x64a1, 0x64a2, 0x64a3, 0x64a5, 0x64a6, 0x64a7, 0x64a8, 0x64aa,
+ 0x64ab, 0x64af, 0x64b1, 0x64b2, 0x64b3, 0x64b4, 0x64b6, 0x64b9,
+ 0x64bb, 0x64bd, 0x64be, 0x64bf, 0x64c1, 0x64c3, 0x64c4, 0x64c6,
+ 0x64c7, 0x64c8, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64cf, 0x64d1,
+ 0x64d3, 0x64d4, 0x64d5, 0x64d6, 0x64d9, 0x64da,
+ /* 0x94 */
+ 0x64db, 0x64dc, 0x64dd, 0x64df, 0x64e0, 0x64e1, 0x64e3, 0x64e5,
+ 0x64e7, 0x64e8, 0x64e9, 0x64ea, 0x64eb, 0x64ec, 0x64ed, 0x64ee,
+ 0x64ef, 0x64f0, 0x64f1, 0x64f2, 0x64f3, 0x64f4, 0x64f5, 0x64f6,
+ 0x64f7, 0x64f8, 0x64f9, 0x64fa, 0x64fb, 0x64fc, 0x64fd, 0x64fe,
+ 0x64ff, 0x6501, 0x6502, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507,
+ 0x6508, 0x650a, 0x650b, 0x650c, 0x650d, 0x650e, 0x650f, 0x6510,
+ 0x6511, 0x6513, 0x6514, 0x6515, 0x6516, 0x6517, 0x6519, 0x651a,
+ 0x651b, 0x651c, 0x651d, 0x651e, 0x651f, 0x6520, 0x6521, 0x6522,
+ 0x6523, 0x6524, 0x6526, 0x6527, 0x6528, 0x6529, 0x652a, 0x652c,
+ 0x652d, 0x6530, 0x6531, 0x6532, 0x6533, 0x6537, 0x653a, 0x653c,
+ 0x653d, 0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6546, 0x6547,
+ 0x654a, 0x654b, 0x654d, 0x654e, 0x6550, 0x6552, 0x6553, 0x6554,
+ 0x6557, 0x6558, 0x655a, 0x655c, 0x655f, 0x6560, 0x6561, 0x6564,
+ 0x6565, 0x6567, 0x6568, 0x6569, 0x656a, 0x656d, 0x656e, 0x656f,
+ 0x6571, 0x6573, 0x6575, 0x6576, 0x6578, 0x6579, 0x657a, 0x657b,
+ 0x657c, 0x657d, 0x657e, 0x657f, 0x6580, 0x6581, 0x6582, 0x6583,
+ 0x6584, 0x6585, 0x6586, 0x6588, 0x6589, 0x658a, 0x658d, 0x658e,
+ 0x658f, 0x6592, 0x6594, 0x6595, 0x6596, 0x6598, 0x659a, 0x659d,
+ 0x659e, 0x65a0, 0x65a2, 0x65a3, 0x65a6, 0x65a8, 0x65aa, 0x65ac,
+ 0x65ae, 0x65b1, 0x65b2, 0x65b3, 0x65b4, 0x65b5, 0x65b6, 0x65b7,
+ 0x65b8, 0x65ba, 0x65bb, 0x65be, 0x65bf, 0x65c0, 0x65c2, 0x65c7,
+ 0x65c8, 0x65c9, 0x65ca, 0x65cd, 0x65d0, 0x65d1, 0x65d3, 0x65d4,
+ 0x65d5, 0x65d8, 0x65d9, 0x65da, 0x65db, 0x65dc, 0x65dd, 0x65de,
+ 0x65df, 0x65e1, 0x65e3, 0x65e4, 0x65ea, 0x65eb,
+ /* 0x95 */
+ 0x65f2, 0x65f3, 0x65f4, 0x65f5, 0x65f8, 0x65f9, 0x65fb, 0x65fc,
+ 0x65fd, 0x65fe, 0x65ff, 0x6601, 0x6604, 0x6605, 0x6607, 0x6608,
+ 0x6609, 0x660b, 0x660d, 0x6610, 0x6611, 0x6612, 0x6616, 0x6617,
+ 0x6618, 0x661a, 0x661b, 0x661c, 0x661e, 0x6621, 0x6622, 0x6623,
+ 0x6624, 0x6626, 0x6629, 0x662a, 0x662b, 0x662c, 0x662e, 0x6630,
+ 0x6632, 0x6633, 0x6637, 0x6638, 0x6639, 0x663a, 0x663b, 0x663d,
+ 0x663f, 0x6640, 0x6642, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648,
+ 0x6649, 0x664a, 0x664d, 0x664e, 0x6650, 0x6651, 0x6658, 0x6659,
+ 0x665b, 0x665c, 0x665d, 0x665e, 0x6660, 0x6662, 0x6663, 0x6665,
+ 0x6667, 0x6669, 0x666a, 0x666b, 0x666c, 0x666d, 0x6671, 0x6672,
+ 0x6673, 0x6675, 0x6678, 0x6679, 0x667b, 0x667c, 0x667d, 0x667f,
+ 0x6680, 0x6681, 0x6683, 0x6685, 0x6686, 0x6688, 0x6689, 0x668a,
+ 0x668b, 0x668d, 0x668e, 0x668f, 0x6690, 0x6692, 0x6693, 0x6694,
+ 0x6695, 0x6698, 0x6699, 0x669a, 0x669b, 0x669c, 0x669e, 0x669f,
+ 0x66a0, 0x66a1, 0x66a2, 0x66a3, 0x66a4, 0x66a5, 0x66a6, 0x66a9,
+ 0x66aa, 0x66ab, 0x66ac, 0x66ad, 0x66af, 0x66b0, 0x66b1, 0x66b2,
+ 0x66b3, 0x66b5, 0x66b6, 0x66b7, 0x66b8, 0x66ba, 0x66bb, 0x66bc,
+ 0x66bd, 0x66bf, 0x66c0, 0x66c1, 0x66c2, 0x66c3, 0x66c4, 0x66c5,
+ 0x66c6, 0x66c7, 0x66c8, 0x66c9, 0x66ca, 0x66cb, 0x66cc, 0x66cd,
+ 0x66ce, 0x66cf, 0x66d0, 0x66d1, 0x66d2, 0x66d3, 0x66d4, 0x66d5,
+ 0x66d6, 0x66d7, 0x66d8, 0x66da, 0x66de, 0x66df, 0x66e0, 0x66e1,
+ 0x66e2, 0x66e3, 0x66e4, 0x66e5, 0x66e7, 0x66e8, 0x66ea, 0x66eb,
+ 0x66ec, 0x66ed, 0x66ee, 0x66ef, 0x66f1, 0x66f5, 0x66f6, 0x66f8,
+ 0x66fa, 0x66fb, 0x66fd, 0x6701, 0x6702, 0x6703,
+ /* 0x96 */
+ 0x6704, 0x6705, 0x6706, 0x6707, 0x670c, 0x670e, 0x670f, 0x6711,
+ 0x6712, 0x6713, 0x6716, 0x6718, 0x6719, 0x671a, 0x671c, 0x671e,
+ 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6727, 0x6729,
+ 0x672e, 0x6730, 0x6732, 0x6733, 0x6736, 0x6737, 0x6738, 0x6739,
+ 0x673b, 0x673c, 0x673e, 0x673f, 0x6741, 0x6744, 0x6745, 0x6747,
+ 0x674a, 0x674b, 0x674d, 0x6752, 0x6754, 0x6755, 0x6757, 0x6758,
+ 0x6759, 0x675a, 0x675b, 0x675d, 0x6762, 0x6763, 0x6764, 0x6766,
+ 0x6767, 0x676b, 0x676c, 0x676e, 0x6771, 0x6774, 0x6776, 0x6778,
+ 0x6779, 0x677a, 0x677b, 0x677d, 0x6780, 0x6782, 0x6783, 0x6785,
+ 0x6786, 0x6788, 0x678a, 0x678c, 0x678d, 0x678e, 0x678f, 0x6791,
+ 0x6792, 0x6793, 0x6794, 0x6796, 0x6799, 0x679b, 0x679f, 0x67a0,
+ 0x67a1, 0x67a4, 0x67a6, 0x67a9, 0x67ac, 0x67ae, 0x67b1, 0x67b2,
+ 0x67b4, 0x67b9, 0x67ba, 0x67bb, 0x67bc, 0x67bd, 0x67be, 0x67bf,
+ 0x67c0, 0x67c2, 0x67c5, 0x67c6, 0x67c7, 0x67c8, 0x67c9, 0x67ca,
+ 0x67cb, 0x67cc, 0x67cd, 0x67ce, 0x67d5, 0x67d6, 0x67d7, 0x67db,
+ 0x67df, 0x67e1, 0x67e3, 0x67e4, 0x67e6, 0x67e7, 0x67e8, 0x67ea,
+ 0x67eb, 0x67ed, 0x67ee, 0x67f2, 0x67f5, 0x67f6, 0x67f7, 0x67f8,
+ 0x67f9, 0x67fa, 0x67fb, 0x67fc, 0x67fe, 0x6801, 0x6802, 0x6803,
+ 0x6804, 0x6806, 0x680d, 0x6810, 0x6812, 0x6814, 0x6815, 0x6818,
+ 0x6819, 0x681a, 0x681b, 0x681c, 0x681e, 0x681f, 0x6820, 0x6822,
+ 0x6823, 0x6824, 0x6825, 0x6826, 0x6827, 0x6828, 0x682b, 0x682c,
+ 0x682d, 0x682e, 0x682f, 0x6830, 0x6831, 0x6834, 0x6835, 0x6836,
+ 0x683a, 0x683b, 0x683f, 0x6847, 0x684b, 0x684d, 0x684f, 0x6852,
+ 0x6856, 0x6857, 0x6858, 0x6859, 0x685a, 0x685b,
+ /* 0x97 */
+ 0x685c, 0x685d, 0x685e, 0x685f, 0x686a, 0x686c, 0x686d, 0x686e,
+ 0x686f, 0x6870, 0x6871, 0x6872, 0x6873, 0x6875, 0x6878, 0x6879,
+ 0x687a, 0x687b, 0x687c, 0x687d, 0x687e, 0x687f, 0x6880, 0x6882,
+ 0x6884, 0x6887, 0x6888, 0x6889, 0x688a, 0x688b, 0x688c, 0x688d,
+ 0x688e, 0x6890, 0x6891, 0x6892, 0x6894, 0x6895, 0x6896, 0x6898,
+ 0x6899, 0x689a, 0x689b, 0x689c, 0x689d, 0x689e, 0x689f, 0x68a0,
+ 0x68a1, 0x68a3, 0x68a4, 0x68a5, 0x68a9, 0x68aa, 0x68ab, 0x68ac,
+ 0x68ae, 0x68b1, 0x68b2, 0x68b4, 0x68b6, 0x68b7, 0x68b8, 0x68b9,
+ 0x68ba, 0x68bb, 0x68bc, 0x68bd, 0x68be, 0x68bf, 0x68c1, 0x68c3,
+ 0x68c4, 0x68c5, 0x68c6, 0x68c7, 0x68c8, 0x68ca, 0x68cc, 0x68ce,
+ 0x68cf, 0x68d0, 0x68d1, 0x68d3, 0x68d4, 0x68d6, 0x68d7, 0x68d9,
+ 0x68db, 0x68dc, 0x68dd, 0x68de, 0x68df, 0x68e1, 0x68e2, 0x68e4,
+ 0x68e5, 0x68e6, 0x68e7, 0x68e8, 0x68e9, 0x68ea, 0x68eb, 0x68ec,
+ 0x68ed, 0x68ef, 0x68f2, 0x68f3, 0x68f4, 0x68f6, 0x68f7, 0x68f8,
+ 0x68fb, 0x68fd, 0x68fe, 0x68ff, 0x6900, 0x6902, 0x6903, 0x6904,
+ 0x6906, 0x6907, 0x6908, 0x6909, 0x690a, 0x690c, 0x690f, 0x6911,
+ 0x6913, 0x6914, 0x6915, 0x6916, 0x6917, 0x6918, 0x6919, 0x691a,
+ 0x691b, 0x691c, 0x691d, 0x691e, 0x6921, 0x6922, 0x6923, 0x6925,
+ 0x6926, 0x6927, 0x6928, 0x6929, 0x692a, 0x692b, 0x692c, 0x692e,
+ 0x692f, 0x6931, 0x6932, 0x6933, 0x6935, 0x6936, 0x6937, 0x6938,
+ 0x693a, 0x693b, 0x693c, 0x693e, 0x6940, 0x6941, 0x6943, 0x6944,
+ 0x6945, 0x6946, 0x6947, 0x6948, 0x6949, 0x694a, 0x694b, 0x694c,
+ 0x694d, 0x694e, 0x694f, 0x6950, 0x6951, 0x6952, 0x6953, 0x6955,
+ 0x6956, 0x6958, 0x6959, 0x695b, 0x695c, 0x695f,
+ /* 0x98 */
+ 0x6961, 0x6962, 0x6964, 0x6965, 0x6967, 0x6968, 0x6969, 0x696a,
+ 0x696c, 0x696d, 0x696f, 0x6970, 0x6972, 0x6973, 0x6974, 0x6975,
+ 0x6976, 0x697a, 0x697b, 0x697d, 0x697e, 0x697f, 0x6981, 0x6983,
+ 0x6985, 0x698a, 0x698b, 0x698c, 0x698e, 0x698f, 0x6990, 0x6991,
+ 0x6992, 0x6993, 0x6996, 0x6997, 0x6999, 0x699a, 0x699d, 0x699e,
+ 0x699f, 0x69a0, 0x69a1, 0x69a2, 0x69a3, 0x69a4, 0x69a5, 0x69a6,
+ 0x69a9, 0x69aa, 0x69ac, 0x69ae, 0x69af, 0x69b0, 0x69b2, 0x69b3,
+ 0x69b5, 0x69b6, 0x69b8, 0x69b9, 0x69ba, 0x69bc, 0x69bd, 0x69be,
+ 0x69bf, 0x69c0, 0x69c2, 0x69c3, 0x69c4, 0x69c5, 0x69c6, 0x69c7,
+ 0x69c8, 0x69c9, 0x69cb, 0x69cd, 0x69cf, 0x69d1, 0x69d2, 0x69d3,
+ 0x69d5, 0x69d6, 0x69d7, 0x69d8, 0x69d9, 0x69da, 0x69dc, 0x69dd,
+ 0x69de, 0x69e1, 0x69e2, 0x69e3, 0x69e4, 0x69e5, 0x69e6, 0x69e7,
+ 0x69e8, 0x69e9, 0x69ea, 0x69eb, 0x69ec, 0x69ee, 0x69ef, 0x69f0,
+ 0x69f1, 0x69f3, 0x69f4, 0x69f5, 0x69f6, 0x69f7, 0x69f8, 0x69f9,
+ 0x69fa, 0x69fb, 0x69fc, 0x69fe, 0x6a00, 0x6a01, 0x6a02, 0x6a03,
+ 0x6a04, 0x6a05, 0x6a06, 0x6a07, 0x6a08, 0x6a09, 0x6a0b, 0x6a0c,
+ 0x6a0d, 0x6a0e, 0x6a0f, 0x6a10, 0x6a11, 0x6a12, 0x6a13, 0x6a14,
+ 0x6a15, 0x6a16, 0x6a19, 0x6a1a, 0x6a1b, 0x6a1c, 0x6a1d, 0x6a1e,
+ 0x6a20, 0x6a22, 0x6a23, 0x6a24, 0x6a25, 0x6a26, 0x6a27, 0x6a29,
+ 0x6a2b, 0x6a2c, 0x6a2d, 0x6a2e, 0x6a30, 0x6a32, 0x6a33, 0x6a34,
+ 0x6a36, 0x6a37, 0x6a38, 0x6a39, 0x6a3a, 0x6a3b, 0x6a3c, 0x6a3f,
+ 0x6a40, 0x6a41, 0x6a42, 0x6a43, 0x6a45, 0x6a46, 0x6a48, 0x6a49,
+ 0x6a4a, 0x6a4b, 0x6a4c, 0x6a4d, 0x6a4e, 0x6a4f, 0x6a51, 0x6a52,
+ 0x6a53, 0x6a54, 0x6a55, 0x6a56, 0x6a57, 0x6a5a,
+ /* 0x99 */
+ 0x6a5c, 0x6a5d, 0x6a5e, 0x6a5f, 0x6a60, 0x6a62, 0x6a63, 0x6a64,
+ 0x6a66, 0x6a67, 0x6a68, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d,
+ 0x6a6e, 0x6a6f, 0x6a70, 0x6a72, 0x6a73, 0x6a74, 0x6a75, 0x6a76,
+ 0x6a77, 0x6a78, 0x6a7a, 0x6a7b, 0x6a7d, 0x6a7e, 0x6a7f, 0x6a81,
+ 0x6a82, 0x6a83, 0x6a85, 0x6a86, 0x6a87, 0x6a88, 0x6a89, 0x6a8a,
+ 0x6a8b, 0x6a8c, 0x6a8d, 0x6a8f, 0x6a92, 0x6a93, 0x6a94, 0x6a95,
+ 0x6a96, 0x6a98, 0x6a99, 0x6a9a, 0x6a9b, 0x6a9c, 0x6a9d, 0x6a9e,
+ 0x6a9f, 0x6aa1, 0x6aa2, 0x6aa3, 0x6aa4, 0x6aa5, 0x6aa6, 0x6aa7,
+ 0x6aa8, 0x6aaa, 0x6aad, 0x6aae, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab2,
+ 0x6ab3, 0x6ab4, 0x6ab5, 0x6ab6, 0x6ab7, 0x6ab8, 0x6ab9, 0x6aba,
+ 0x6abb, 0x6abc, 0x6abd, 0x6abe, 0x6abf, 0x6ac0, 0x6ac1, 0x6ac2,
+ 0x6ac3, 0x6ac4, 0x6ac5, 0x6ac6, 0x6ac7, 0x6ac8, 0x6ac9, 0x6aca,
+ 0x6acb, 0x6acc, 0x6acd, 0x6ace, 0x6acf, 0x6ad0, 0x6ad1, 0x6ad2,
+ 0x6ad3, 0x6ad4, 0x6ad5, 0x6ad6, 0x6ad7, 0x6ad8, 0x6ad9, 0x6ada,
+ 0x6adb, 0x6adc, 0x6add, 0x6ade, 0x6adf, 0x6ae0, 0x6ae1, 0x6ae2,
+ 0x6ae3, 0x6ae4, 0x6ae5, 0x6ae6, 0x6ae7, 0x6ae8, 0x6ae9, 0x6aea,
+ 0x6aeb, 0x6aec, 0x6aed, 0x6aee, 0x6aef, 0x6af0, 0x6af1, 0x6af2,
+ 0x6af3, 0x6af4, 0x6af5, 0x6af6, 0x6af7, 0x6af8, 0x6af9, 0x6afa,
+ 0x6afb, 0x6afc, 0x6afd, 0x6afe, 0x6aff, 0x6b00, 0x6b01, 0x6b02,
+ 0x6b03, 0x6b04, 0x6b05, 0x6b06, 0x6b07, 0x6b08, 0x6b09, 0x6b0a,
+ 0x6b0b, 0x6b0c, 0x6b0d, 0x6b0e, 0x6b0f, 0x6b10, 0x6b11, 0x6b12,
+ 0x6b13, 0x6b14, 0x6b15, 0x6b16, 0x6b17, 0x6b18, 0x6b19, 0x6b1a,
+ 0x6b1b, 0x6b1c, 0x6b1d, 0x6b1e, 0x6b1f, 0x6b25, 0x6b26, 0x6b28,
+ 0x6b29, 0x6b2a, 0x6b2b, 0x6b2c, 0x6b2d, 0x6b2e,
+ /* 0x9a */
+ 0x6b2f, 0x6b30, 0x6b31, 0x6b33, 0x6b34, 0x6b35, 0x6b36, 0x6b38,
+ 0x6b3b, 0x6b3c, 0x6b3d, 0x6b3f, 0x6b40, 0x6b41, 0x6b42, 0x6b44,
+ 0x6b45, 0x6b48, 0x6b4a, 0x6b4b, 0x6b4d, 0x6b4e, 0x6b4f, 0x6b50,
+ 0x6b51, 0x6b52, 0x6b53, 0x6b54, 0x6b55, 0x6b56, 0x6b57, 0x6b58,
+ 0x6b5a, 0x6b5b, 0x6b5c, 0x6b5d, 0x6b5e, 0x6b5f, 0x6b60, 0x6b61,
+ 0x6b68, 0x6b69, 0x6b6b, 0x6b6c, 0x6b6d, 0x6b6e, 0x6b6f, 0x6b70,
+ 0x6b71, 0x6b72, 0x6b73, 0x6b74, 0x6b75, 0x6b76, 0x6b77, 0x6b78,
+ 0x6b7a, 0x6b7d, 0x6b7e, 0x6b7f, 0x6b80, 0x6b85, 0x6b88, 0x6b8c,
+ 0x6b8e, 0x6b8f, 0x6b90, 0x6b91, 0x6b94, 0x6b95, 0x6b97, 0x6b98,
+ 0x6b99, 0x6b9c, 0x6b9d, 0x6b9e, 0x6b9f, 0x6ba0, 0x6ba2, 0x6ba3,
+ 0x6ba4, 0x6ba5, 0x6ba6, 0x6ba7, 0x6ba8, 0x6ba9, 0x6bab, 0x6bac,
+ 0x6bad, 0x6bae, 0x6baf, 0x6bb0, 0x6bb1, 0x6bb2, 0x6bb6, 0x6bb8,
+ 0x6bb9, 0x6bba, 0x6bbb, 0x6bbc, 0x6bbd, 0x6bbe, 0x6bc0, 0x6bc3,
+ 0x6bc4, 0x6bc6, 0x6bc7, 0x6bc8, 0x6bc9, 0x6bca, 0x6bcc, 0x6bce,
+ 0x6bd0, 0x6bd1, 0x6bd8, 0x6bda, 0x6bdc, 0x6bdd, 0x6bde, 0x6bdf,
+ 0x6be0, 0x6be2, 0x6be3, 0x6be4, 0x6be5, 0x6be6, 0x6be7, 0x6be8,
+ 0x6be9, 0x6bec, 0x6bed, 0x6bee, 0x6bf0, 0x6bf1, 0x6bf2, 0x6bf4,
+ 0x6bf6, 0x6bf7, 0x6bf8, 0x6bfa, 0x6bfb, 0x6bfc, 0x6bfe, 0x6bff,
+ 0x6c00, 0x6c01, 0x6c02, 0x6c03, 0x6c04, 0x6c08, 0x6c09, 0x6c0a,
+ 0x6c0b, 0x6c0c, 0x6c0e, 0x6c12, 0x6c17, 0x6c1c, 0x6c1d, 0x6c1e,
+ 0x6c20, 0x6c23, 0x6c25, 0x6c2b, 0x6c2c, 0x6c2d, 0x6c31, 0x6c33,
+ 0x6c36, 0x6c37, 0x6c39, 0x6c3a, 0x6c3b, 0x6c3c, 0x6c3e, 0x6c3f,
+ 0x6c43, 0x6c44, 0x6c45, 0x6c48, 0x6c4b, 0x6c4c, 0x6c4d, 0x6c4e,
+ 0x6c4f, 0x6c51, 0x6c52, 0x6c53, 0x6c56, 0x6c58,
+ /* 0x9b */
+ 0x6c59, 0x6c5a, 0x6c62, 0x6c63, 0x6c65, 0x6c66, 0x6c67, 0x6c6b,
+ 0x6c6c, 0x6c6d, 0x6c6e, 0x6c6f, 0x6c71, 0x6c73, 0x6c75, 0x6c77,
+ 0x6c78, 0x6c7a, 0x6c7b, 0x6c7c, 0x6c7f, 0x6c80, 0x6c84, 0x6c87,
+ 0x6c8a, 0x6c8b, 0x6c8d, 0x6c8e, 0x6c91, 0x6c92, 0x6c95, 0x6c96,
+ 0x6c97, 0x6c98, 0x6c9a, 0x6c9c, 0x6c9d, 0x6c9e, 0x6ca0, 0x6ca2,
+ 0x6ca8, 0x6cac, 0x6caf, 0x6cb0, 0x6cb4, 0x6cb5, 0x6cb6, 0x6cb7,
+ 0x6cba, 0x6cc0, 0x6cc1, 0x6cc2, 0x6cc3, 0x6cc6, 0x6cc7, 0x6cc8,
+ 0x6ccb, 0x6ccd, 0x6cce, 0x6ccf, 0x6cd1, 0x6cd2, 0x6cd8, 0x6cd9,
+ 0x6cda, 0x6cdc, 0x6cdd, 0x6cdf, 0x6ce4, 0x6ce6, 0x6ce7, 0x6ce9,
+ 0x6cec, 0x6ced, 0x6cf2, 0x6cf4, 0x6cf9, 0x6cff, 0x6d00, 0x6d02,
+ 0x6d03, 0x6d05, 0x6d06, 0x6d08, 0x6d09, 0x6d0a, 0x6d0d, 0x6d0f,
+ 0x6d10, 0x6d11, 0x6d13, 0x6d14, 0x6d15, 0x6d16, 0x6d18, 0x6d1c,
+ 0x6d1d, 0x6d1f, 0x6d20, 0x6d21, 0x6d22, 0x6d23, 0x6d24, 0x6d26,
+ 0x6d28, 0x6d29, 0x6d2c, 0x6d2d, 0x6d2f, 0x6d30, 0x6d34, 0x6d36,
+ 0x6d37, 0x6d38, 0x6d3a, 0x6d3f, 0x6d40, 0x6d42, 0x6d44, 0x6d49,
+ 0x6d4c, 0x6d50, 0x6d55, 0x6d56, 0x6d57, 0x6d58, 0x6d5b, 0x6d5d,
+ 0x6d5f, 0x6d61, 0x6d62, 0x6d64, 0x6d65, 0x6d67, 0x6d68, 0x6d6b,
+ 0x6d6c, 0x6d6d, 0x6d70, 0x6d71, 0x6d72, 0x6d73, 0x6d75, 0x6d76,
+ 0x6d79, 0x6d7a, 0x6d7b, 0x6d7d, 0x6d7e, 0x6d7f, 0x6d80, 0x6d81,
+ 0x6d83, 0x6d84, 0x6d86, 0x6d87, 0x6d8a, 0x6d8b, 0x6d8d, 0x6d8f,
+ 0x6d90, 0x6d92, 0x6d96, 0x6d97, 0x6d98, 0x6d99, 0x6d9a, 0x6d9c,
+ 0x6da2, 0x6da5, 0x6dac, 0x6dad, 0x6db0, 0x6db1, 0x6db3, 0x6db4,
+ 0x6db6, 0x6db7, 0x6db9, 0x6dba, 0x6dbb, 0x6dbc, 0x6dbd, 0x6dbe,
+ 0x6dc1, 0x6dc2, 0x6dc3, 0x6dc8, 0x6dc9, 0x6dca,
+ /* 0x9c */
+ 0x6dcd, 0x6dce, 0x6dcf, 0x6dd0, 0x6dd2, 0x6dd3, 0x6dd4, 0x6dd5,
+ 0x6dd7, 0x6dda, 0x6ddb, 0x6ddc, 0x6ddf, 0x6de2, 0x6de3, 0x6de5,
+ 0x6de7, 0x6de8, 0x6de9, 0x6dea, 0x6ded, 0x6def, 0x6df0, 0x6df2,
+ 0x6df4, 0x6df5, 0x6df6, 0x6df8, 0x6dfa, 0x6dfd, 0x6dfe, 0x6dff,
+ 0x6e00, 0x6e01, 0x6e02, 0x6e03, 0x6e04, 0x6e06, 0x6e07, 0x6e08,
+ 0x6e09, 0x6e0b, 0x6e0f, 0x6e12, 0x6e13, 0x6e15, 0x6e18, 0x6e19,
+ 0x6e1b, 0x6e1c, 0x6e1e, 0x6e1f, 0x6e22, 0x6e26, 0x6e27, 0x6e28,
+ 0x6e2a, 0x6e2c, 0x6e2e, 0x6e30, 0x6e31, 0x6e33, 0x6e35, 0x6e36,
+ 0x6e37, 0x6e39, 0x6e3b, 0x6e3c, 0x6e3d, 0x6e3e, 0x6e3f, 0x6e40,
+ 0x6e41, 0x6e42, 0x6e45, 0x6e46, 0x6e47, 0x6e48, 0x6e49, 0x6e4a,
+ 0x6e4b, 0x6e4c, 0x6e4f, 0x6e50, 0x6e51, 0x6e52, 0x6e55, 0x6e57,
+ 0x6e59, 0x6e5a, 0x6e5c, 0x6e5d, 0x6e5e, 0x6e60, 0x6e61, 0x6e62,
+ 0x6e63, 0x6e64, 0x6e65, 0x6e66, 0x6e67, 0x6e68, 0x6e69, 0x6e6a,
+ 0x6e6c, 0x6e6d, 0x6e6f, 0x6e70, 0x6e71, 0x6e72, 0x6e73, 0x6e74,
+ 0x6e75, 0x6e76, 0x6e77, 0x6e78, 0x6e79, 0x6e7a, 0x6e7b, 0x6e7c,
+ 0x6e7d, 0x6e80, 0x6e81, 0x6e82, 0x6e84, 0x6e87, 0x6e88, 0x6e8a,
+ 0x6e8b, 0x6e8c, 0x6e8d, 0x6e8e, 0x6e91, 0x6e92, 0x6e93, 0x6e94,
+ 0x6e95, 0x6e96, 0x6e97, 0x6e99, 0x6e9a, 0x6e9b, 0x6e9d, 0x6e9e,
+ 0x6ea0, 0x6ea1, 0x6ea3, 0x6ea4, 0x6ea6, 0x6ea8, 0x6ea9, 0x6eab,
+ 0x6eac, 0x6ead, 0x6eae, 0x6eb0, 0x6eb3, 0x6eb5, 0x6eb8, 0x6eb9,
+ 0x6ebc, 0x6ebe, 0x6ebf, 0x6ec0, 0x6ec3, 0x6ec4, 0x6ec5, 0x6ec6,
+ 0x6ec8, 0x6ec9, 0x6eca, 0x6ecc, 0x6ecd, 0x6ece, 0x6ed0, 0x6ed2,
+ 0x6ed6, 0x6ed8, 0x6ed9, 0x6edb, 0x6edc, 0x6edd, 0x6ee3, 0x6ee7,
+ 0x6eea, 0x6eeb, 0x6eec, 0x6eed, 0x6eee, 0x6eef,
+ /* 0x9d */
+ 0x6ef0, 0x6ef1, 0x6ef2, 0x6ef3, 0x6ef5, 0x6ef6, 0x6ef7, 0x6ef8,
+ 0x6efa, 0x6efb, 0x6efc, 0x6efd, 0x6efe, 0x6eff, 0x6f00, 0x6f01,
+ 0x6f03, 0x6f04, 0x6f05, 0x6f07, 0x6f08, 0x6f0a, 0x6f0b, 0x6f0c,
+ 0x6f0d, 0x6f0e, 0x6f10, 0x6f11, 0x6f12, 0x6f16, 0x6f17, 0x6f18,
+ 0x6f19, 0x6f1a, 0x6f1b, 0x6f1c, 0x6f1d, 0x6f1e, 0x6f1f, 0x6f21,
+ 0x6f22, 0x6f23, 0x6f25, 0x6f26, 0x6f27, 0x6f28, 0x6f2c, 0x6f2e,
+ 0x6f30, 0x6f32, 0x6f34, 0x6f35, 0x6f37, 0x6f38, 0x6f39, 0x6f3a,
+ 0x6f3b, 0x6f3c, 0x6f3d, 0x6f3f, 0x6f40, 0x6f41, 0x6f42, 0x6f43,
+ 0x6f44, 0x6f45, 0x6f48, 0x6f49, 0x6f4a, 0x6f4c, 0x6f4e, 0x6f4f,
+ 0x6f50, 0x6f51, 0x6f52, 0x6f53, 0x6f54, 0x6f55, 0x6f56, 0x6f57,
+ 0x6f59, 0x6f5a, 0x6f5b, 0x6f5d, 0x6f5f, 0x6f60, 0x6f61, 0x6f63,
+ 0x6f64, 0x6f65, 0x6f67, 0x6f68, 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c,
+ 0x6f6f, 0x6f70, 0x6f71, 0x6f73, 0x6f75, 0x6f76, 0x6f77, 0x6f79,
+ 0x6f7b, 0x6f7d, 0x6f7e, 0x6f7f, 0x6f80, 0x6f81, 0x6f82, 0x6f83,
+ 0x6f85, 0x6f86, 0x6f87, 0x6f8a, 0x6f8b, 0x6f8f, 0x6f90, 0x6f91,
+ 0x6f92, 0x6f93, 0x6f94, 0x6f95, 0x6f96, 0x6f97, 0x6f98, 0x6f99,
+ 0x6f9a, 0x6f9b, 0x6f9d, 0x6f9e, 0x6f9f, 0x6fa0, 0x6fa2, 0x6fa3,
+ 0x6fa4, 0x6fa5, 0x6fa6, 0x6fa8, 0x6fa9, 0x6faa, 0x6fab, 0x6fac,
+ 0x6fad, 0x6fae, 0x6faf, 0x6fb0, 0x6fb1, 0x6fb2, 0x6fb4, 0x6fb5,
+ 0x6fb7, 0x6fb8, 0x6fba, 0x6fbb, 0x6fbc, 0x6fbd, 0x6fbe, 0x6fbf,
+ 0x6fc1, 0x6fc3, 0x6fc4, 0x6fc5, 0x6fc6, 0x6fc7, 0x6fc8, 0x6fca,
+ 0x6fcb, 0x6fcc, 0x6fcd, 0x6fce, 0x6fcf, 0x6fd0, 0x6fd3, 0x6fd4,
+ 0x6fd5, 0x6fd6, 0x6fd7, 0x6fd8, 0x6fd9, 0x6fda, 0x6fdb, 0x6fdc,
+ 0x6fdd, 0x6fdf, 0x6fe2, 0x6fe3, 0x6fe4, 0x6fe5,
+ /* 0x9e */
+ 0x6fe6, 0x6fe7, 0x6fe8, 0x6fe9, 0x6fea, 0x6feb, 0x6fec, 0x6fed,
+ 0x6ff0, 0x6ff1, 0x6ff2, 0x6ff3, 0x6ff4, 0x6ff5, 0x6ff6, 0x6ff7,
+ 0x6ff8, 0x6ff9, 0x6ffa, 0x6ffb, 0x6ffc, 0x6ffd, 0x6ffe, 0x6fff,
+ 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007,
+ 0x7008, 0x7009, 0x700a, 0x700b, 0x700c, 0x700d, 0x700e, 0x700f,
+ 0x7010, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017, 0x7018,
+ 0x7019, 0x701c, 0x701d, 0x701e, 0x701f, 0x7020, 0x7021, 0x7022,
+ 0x7024, 0x7025, 0x7026, 0x7027, 0x7028, 0x7029, 0x702a, 0x702b,
+ 0x702c, 0x702d, 0x702e, 0x702f, 0x7030, 0x7031, 0x7032, 0x7033,
+ 0x7034, 0x7036, 0x7037, 0x7038, 0x703a, 0x703b, 0x703c, 0x703d,
+ 0x703e, 0x703f, 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045,
+ 0x7046, 0x7047, 0x7048, 0x7049, 0x704a, 0x704b, 0x704d, 0x704e,
+ 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x7057,
+ 0x7058, 0x7059, 0x705a, 0x705b, 0x705c, 0x705d, 0x705f, 0x7060,
+ 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067, 0x7068,
+ 0x7069, 0x706a, 0x706e, 0x7071, 0x7072, 0x7073, 0x7074, 0x7077,
+ 0x7079, 0x707a, 0x707b, 0x707d, 0x7081, 0x7082, 0x7083, 0x7084,
+ 0x7086, 0x7087, 0x7088, 0x708b, 0x708c, 0x708d, 0x708f, 0x7090,
+ 0x7091, 0x7093, 0x7097, 0x7098, 0x709a, 0x709b, 0x709e, 0x709f,
+ 0x70a0, 0x70a1, 0x70a2, 0x70a3, 0x70a4, 0x70a5, 0x70a6, 0x70a7,
+ 0x70a8, 0x70a9, 0x70aa, 0x70b0, 0x70b2, 0x70b4, 0x70b5, 0x70b6,
+ 0x70ba, 0x70be, 0x70bf, 0x70c4, 0x70c5, 0x70c6, 0x70c7, 0x70c9,
+ 0x70cb, 0x70cc, 0x70cd, 0x70ce, 0x70cf, 0x70d0, 0x70d1, 0x70d2,
+ 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d7, 0x70da,
+ /* 0x9f */
+ 0x70dc, 0x70dd, 0x70de, 0x70e0, 0x70e1, 0x70e2, 0x70e3, 0x70e5,
+ 0x70ea, 0x70ee, 0x70f0, 0x70f1, 0x70f2, 0x70f3, 0x70f4, 0x70f5,
+ 0x70f6, 0x70f8, 0x70fa, 0x70fb, 0x70fc, 0x70fe, 0x70ff, 0x7100,
+ 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x7108,
+ 0x710b, 0x710c, 0x710d, 0x710e, 0x710f, 0x7111, 0x7112, 0x7114,
+ 0x7117, 0x711b, 0x711c, 0x711d, 0x711e, 0x711f, 0x7120, 0x7121,
+ 0x7122, 0x7123, 0x7124, 0x7125, 0x7127, 0x7128, 0x7129, 0x712a,
+ 0x712b, 0x712c, 0x712d, 0x712e, 0x7132, 0x7133, 0x7134, 0x7135,
+ 0x7137, 0x7138, 0x7139, 0x713a, 0x713b, 0x713c, 0x713d, 0x713e,
+ 0x713f, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7146, 0x7147,
+ 0x7148, 0x7149, 0x714b, 0x714d, 0x714f, 0x7150, 0x7151, 0x7152,
+ 0x7153, 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159, 0x715a,
+ 0x715b, 0x715d, 0x715f, 0x7160, 0x7161, 0x7162, 0x7163, 0x7165,
+ 0x7169, 0x716a, 0x716b, 0x716c, 0x716d, 0x716f, 0x7170, 0x7171,
+ 0x7174, 0x7175, 0x7176, 0x7177, 0x7179, 0x717b, 0x717c, 0x717e,
+ 0x717f, 0x7180, 0x7181, 0x7182, 0x7183, 0x7185, 0x7186, 0x7187,
+ 0x7188, 0x7189, 0x718b, 0x718c, 0x718d, 0x718e, 0x7190, 0x7191,
+ 0x7192, 0x7193, 0x7195, 0x7196, 0x7197, 0x719a, 0x719b, 0x719c,
+ 0x719d, 0x719e, 0x71a1, 0x71a2, 0x71a3, 0x71a4, 0x71a5, 0x71a6,
+ 0x71a7, 0x71a9, 0x71aa, 0x71ab, 0x71ad, 0x71ae, 0x71af, 0x71b0,
+ 0x71b1, 0x71b2, 0x71b4, 0x71b6, 0x71b7, 0x71b8, 0x71ba, 0x71bb,
+ 0x71bc, 0x71bd, 0x71be, 0x71bf, 0x71c0, 0x71c1, 0x71c2, 0x71c4,
+ 0x71c5, 0x71c6, 0x71c7, 0x71c8, 0x71c9, 0x71ca, 0x71cb, 0x71cc,
+ 0x71cd, 0x71cf, 0x71d0, 0x71d1, 0x71d2, 0x71d3,
+ /* 0xa0 */
+ 0x71d6, 0x71d7, 0x71d8, 0x71d9, 0x71da, 0x71db, 0x71dc, 0x71dd,
+ 0x71de, 0x71df, 0x71e1, 0x71e2, 0x71e3, 0x71e4, 0x71e6, 0x71e8,
+ 0x71e9, 0x71ea, 0x71eb, 0x71ec, 0x71ed, 0x71ef, 0x71f0, 0x71f1,
+ 0x71f2, 0x71f3, 0x71f4, 0x71f5, 0x71f6, 0x71f7, 0x71f8, 0x71fa,
+ 0x71fb, 0x71fc, 0x71fd, 0x71fe, 0x71ff, 0x7200, 0x7201, 0x7202,
+ 0x7203, 0x7204, 0x7205, 0x7207, 0x7208, 0x7209, 0x720a, 0x720b,
+ 0x720c, 0x720d, 0x720e, 0x720f, 0x7210, 0x7211, 0x7212, 0x7213,
+ 0x7214, 0x7215, 0x7216, 0x7217, 0x7218, 0x7219, 0x721a, 0x721b,
+ 0x721c, 0x721e, 0x721f, 0x7220, 0x7221, 0x7222, 0x7223, 0x7224,
+ 0x7225, 0x7226, 0x7227, 0x7229, 0x722b, 0x722d, 0x722e, 0x722f,
+ 0x7232, 0x7233, 0x7234, 0x723a, 0x723c, 0x723e, 0x7240, 0x7241,
+ 0x7242, 0x7243, 0x7244, 0x7245, 0x7246, 0x7249, 0x724a, 0x724b,
+ 0x724e, 0x724f, 0x7250, 0x7251, 0x7253, 0x7254, 0x7255, 0x7257,
+ 0x7258, 0x725a, 0x725c, 0x725e, 0x7260, 0x7263, 0x7264, 0x7265,
+ 0x7268, 0x726a, 0x726b, 0x726c, 0x726d, 0x7270, 0x7271, 0x7273,
+ 0x7274, 0x7276, 0x7277, 0x7278, 0x727b, 0x727c, 0x727d, 0x7282,
+ 0x7283, 0x7285, 0x7286, 0x7287, 0x7288, 0x7289, 0x728c, 0x728e,
+ 0x7290, 0x7291, 0x7293, 0x7294, 0x7295, 0x7296, 0x7297, 0x7298,
+ 0x7299, 0x729a, 0x729b, 0x729c, 0x729d, 0x729e, 0x72a0, 0x72a1,
+ 0x72a2, 0x72a3, 0x72a4, 0x72a5, 0x72a6, 0x72a7, 0x72a8, 0x72a9,
+ 0x72aa, 0x72ab, 0x72ae, 0x72b1, 0x72b2, 0x72b3, 0x72b5, 0x72ba,
+ 0x72bb, 0x72bc, 0x72bd, 0x72be, 0x72bf, 0x72c0, 0x72c5, 0x72c6,
+ 0x72c7, 0x72c9, 0x72ca, 0x72cb, 0x72cc, 0x72cf, 0x72d1, 0x72d3,
+ 0x72d4, 0x72d5, 0x72d6, 0x72d8, 0x72da, 0x72db,
+};
+
+static const unsigned short gbkext2_2uni_pagea8[8272] = {
+ /* 0xa8 */
+ 0x02ca, 0x02cb, 0x02d9, 0x2013, 0x2015, 0x2025, 0x2035, 0x2105,
+ 0x2109, 0x2196, 0x2197, 0x2198, 0x2199, 0x2215, 0x221f, 0x2223,
+ 0x2252, 0x2266, 0x2267, 0x22bf, 0x2550, 0x2551, 0x2552, 0x2553,
+ 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b,
+ 0x255c, 0x255d, 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2563,
+ 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b,
+ 0x256c, 0x256d, 0x256e, 0x256f, 0x2570, 0x2571, 0x2572, 0x2573,
+ 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, 0x2588,
+ 0x2589, 0x258a, 0x258b, 0x258c, 0x258d, 0x258e, 0x258f, 0x2593,
+ 0x2594, 0x2595, 0x25bc, 0x25bd, 0x25e2, 0x25e3, 0x25e4, 0x25e5,
+ 0x2609, 0x2295, 0x3012, 0x301d, 0x301e, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0xa9 */
+ 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028,
+ 0x3029, 0x32a3, 0x338e, 0x338f, 0x339c, 0x339d, 0x339e, 0x33a1,
+ 0x33c4, 0x33ce, 0x33d1, 0x33d2, 0x33d5, 0xfe30, 0xffe2, 0xffe4,
+ 0xfffd, 0x2121, 0x3231, 0xfffd, 0x2010, 0xfffd, 0xfffd, 0xfffd,
+ 0x30fc, 0x309b, 0x309c, 0x30fd, 0x30fe, 0x3006, 0x309d, 0x309e,
+ 0xfe49, 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 0xfe50,
+ 0xfe51, 0xfe52, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xfe59, 0xfe5a,
+ 0xfe5b, 0xfe5c, 0xfe5d, 0xfe5e, 0xfe5f, 0xfe60, 0xfe61, 0xfe62,
+ 0xfe63, 0xfe64, 0xfe65, 0xfe66, 0xfe68, 0xfe69, 0xfe6a, 0xfe6b,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3007, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0xaa */
+ 0x72dc, 0x72dd, 0x72df, 0x72e2, 0x72e3, 0x72e4, 0x72e5, 0x72e6,
+ 0x72e7, 0x72ea, 0x72eb, 0x72f5, 0x72f6, 0x72f9, 0x72fd, 0x72fe,
+ 0x72ff, 0x7300, 0x7302, 0x7304, 0x7305, 0x7306, 0x7307, 0x7308,
+ 0x7309, 0x730b, 0x730c, 0x730d, 0x730f, 0x7310, 0x7311, 0x7312,
+ 0x7314, 0x7318, 0x7319, 0x731a, 0x731f, 0x7320, 0x7323, 0x7324,
+ 0x7326, 0x7327, 0x7328, 0x732d, 0x732f, 0x7330, 0x7332, 0x7333,
+ 0x7335, 0x7336, 0x733a, 0x733b, 0x733c, 0x733d, 0x7340, 0x7341,
+ 0x7342, 0x7343, 0x7344, 0x7345, 0x7346, 0x7347, 0x7348, 0x7349,
+ 0x734a, 0x734b, 0x734c, 0x734e, 0x734f, 0x7351, 0x7353, 0x7354,
+ 0x7355, 0x7356, 0x7358, 0x7359, 0x735a, 0x735b, 0x735c, 0x735d,
+ 0x735e, 0x735f, 0x7361, 0x7362, 0x7363, 0x7364, 0x7365, 0x7366,
+ 0x7367, 0x7368, 0x7369, 0x736a, 0x736b, 0x736e, 0x7370, 0x7371,
+ /* 0xab */
+ 0x7372, 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 0x7378, 0x7379,
+ 0x737a, 0x737b, 0x737c, 0x737d, 0x737f, 0x7380, 0x7381, 0x7382,
+ 0x7383, 0x7385, 0x7386, 0x7388, 0x738a, 0x738c, 0x738d, 0x738f,
+ 0x7390, 0x7392, 0x7393, 0x7394, 0x7395, 0x7397, 0x7398, 0x7399,
+ 0x739a, 0x739c, 0x739d, 0x739e, 0x73a0, 0x73a1, 0x73a3, 0x73a4,
+ 0x73a5, 0x73a6, 0x73a7, 0x73a8, 0x73aa, 0x73ac, 0x73ad, 0x73b1,
+ 0x73b4, 0x73b5, 0x73b6, 0x73b8, 0x73b9, 0x73bc, 0x73bd, 0x73be,
+ 0x73bf, 0x73c1, 0x73c3, 0x73c4, 0x73c5, 0x73c6, 0x73c7, 0x73cb,
+ 0x73cc, 0x73ce, 0x73d2, 0x73d3, 0x73d4, 0x73d5, 0x73d6, 0x73d7,
+ 0x73d8, 0x73da, 0x73db, 0x73dc, 0x73dd, 0x73df, 0x73e1, 0x73e2,
+ 0x73e3, 0x73e4, 0x73e6, 0x73e8, 0x73ea, 0x73eb, 0x73ec, 0x73ee,
+ 0x73ef, 0x73f0, 0x73f1, 0x73f3, 0x73f4, 0x73f5, 0x73f6, 0x73f7,
+ /* 0xac */
+ 0x73f8, 0x73f9, 0x73fa, 0x73fb, 0x73fc, 0x73fd, 0x73fe, 0x73ff,
+ 0x7400, 0x7401, 0x7402, 0x7404, 0x7407, 0x7408, 0x740b, 0x740c,
+ 0x740d, 0x740e, 0x7411, 0x7412, 0x7413, 0x7414, 0x7415, 0x7416,
+ 0x7417, 0x7418, 0x7419, 0x741c, 0x741d, 0x741e, 0x741f, 0x7420,
+ 0x7421, 0x7423, 0x7424, 0x7427, 0x7429, 0x742b, 0x742d, 0x742f,
+ 0x7431, 0x7432, 0x7437, 0x7438, 0x7439, 0x743a, 0x743b, 0x743d,
+ 0x743e, 0x743f, 0x7440, 0x7442, 0x7443, 0x7444, 0x7445, 0x7446,
+ 0x7447, 0x7448, 0x7449, 0x744a, 0x744b, 0x744c, 0x744d, 0x744e,
+ 0x744f, 0x7450, 0x7451, 0x7452, 0x7453, 0x7454, 0x7456, 0x7458,
+ 0x745d, 0x7460, 0x7461, 0x7462, 0x7463, 0x7464, 0x7465, 0x7466,
+ 0x7467, 0x7468, 0x7469, 0x746a, 0x746b, 0x746c, 0x746e, 0x746f,
+ 0x7471, 0x7472, 0x7473, 0x7474, 0x7475, 0x7478, 0x7479, 0x747a,
+ /* 0xad */
+ 0x747b, 0x747c, 0x747d, 0x747f, 0x7482, 0x7484, 0x7485, 0x7486,
+ 0x7488, 0x7489, 0x748a, 0x748c, 0x748d, 0x748f, 0x7491, 0x7492,
+ 0x7493, 0x7494, 0x7495, 0x7496, 0x7497, 0x7498, 0x7499, 0x749a,
+ 0x749b, 0x749d, 0x749f, 0x74a0, 0x74a1, 0x74a2, 0x74a3, 0x74a4,
+ 0x74a5, 0x74a6, 0x74aa, 0x74ab, 0x74ac, 0x74ad, 0x74ae, 0x74af,
+ 0x74b0, 0x74b1, 0x74b2, 0x74b3, 0x74b4, 0x74b5, 0x74b6, 0x74b7,
+ 0x74b8, 0x74b9, 0x74bb, 0x74bc, 0x74bd, 0x74be, 0x74bf, 0x74c0,
+ 0x74c1, 0x74c2, 0x74c3, 0x74c4, 0x74c5, 0x74c6, 0x74c7, 0x74c8,
+ 0x74c9, 0x74ca, 0x74cb, 0x74cc, 0x74cd, 0x74ce, 0x74cf, 0x74d0,
+ 0x74d1, 0x74d3, 0x74d4, 0x74d5, 0x74d6, 0x74d7, 0x74d8, 0x74d9,
+ 0x74da, 0x74db, 0x74dd, 0x74df, 0x74e1, 0x74e5, 0x74e7, 0x74e8,
+ 0x74e9, 0x74ea, 0x74eb, 0x74ec, 0x74ed, 0x74f0, 0x74f1, 0x74f2,
+ /* 0xae */
+ 0x74f3, 0x74f5, 0x74f8, 0x74f9, 0x74fa, 0x74fb, 0x74fc, 0x74fd,
+ 0x74fe, 0x7500, 0x7501, 0x7502, 0x7503, 0x7505, 0x7506, 0x7507,
+ 0x7508, 0x7509, 0x750a, 0x750b, 0x750c, 0x750e, 0x7510, 0x7512,
+ 0x7514, 0x7515, 0x7516, 0x7517, 0x751b, 0x751d, 0x751e, 0x7520,
+ 0x7521, 0x7522, 0x7523, 0x7524, 0x7526, 0x7527, 0x752a, 0x752e,
+ 0x7534, 0x7536, 0x7539, 0x753c, 0x753d, 0x753f, 0x7541, 0x7542,
+ 0x7543, 0x7544, 0x7546, 0x7547, 0x7549, 0x754a, 0x754d, 0x7550,
+ 0x7551, 0x7552, 0x7553, 0x7555, 0x7556, 0x7557, 0x7558, 0x755d,
+ 0x755e, 0x755f, 0x7560, 0x7561, 0x7562, 0x7563, 0x7564, 0x7567,
+ 0x7568, 0x7569, 0x756b, 0x756c, 0x756d, 0x756e, 0x756f, 0x7570,
+ 0x7571, 0x7573, 0x7575, 0x7576, 0x7577, 0x757a, 0x757b, 0x757c,
+ 0x757d, 0x757e, 0x7580, 0x7581, 0x7582, 0x7584, 0x7585, 0x7587,
+ /* 0xaf */
+ 0x7588, 0x7589, 0x758a, 0x758c, 0x758d, 0x758e, 0x7590, 0x7593,
+ 0x7595, 0x7598, 0x759b, 0x759c, 0x759e, 0x75a2, 0x75a6, 0x75a7,
+ 0x75a8, 0x75a9, 0x75aa, 0x75ad, 0x75b6, 0x75b7, 0x75ba, 0x75bb,
+ 0x75bf, 0x75c0, 0x75c1, 0x75c6, 0x75cb, 0x75cc, 0x75ce, 0x75cf,
+ 0x75d0, 0x75d1, 0x75d3, 0x75d7, 0x75d9, 0x75da, 0x75dc, 0x75dd,
+ 0x75df, 0x75e0, 0x75e1, 0x75e5, 0x75e9, 0x75ec, 0x75ed, 0x75ee,
+ 0x75ef, 0x75f2, 0x75f3, 0x75f5, 0x75f6, 0x75f7, 0x75f8, 0x75fa,
+ 0x75fb, 0x75fd, 0x75fe, 0x7602, 0x7604, 0x7606, 0x7607, 0x7608,
+ 0x7609, 0x760b, 0x760d, 0x760e, 0x760f, 0x7611, 0x7612, 0x7613,
+ 0x7614, 0x7616, 0x761a, 0x761c, 0x761d, 0x761e, 0x7621, 0x7623,
+ 0x7627, 0x7628, 0x762c, 0x762e, 0x762f, 0x7631, 0x7632, 0x7636,
+ 0x7637, 0x7639, 0x763a, 0x763b, 0x763d, 0x7641, 0x7642, 0x7644,
+ /* 0xb0 */
+ 0x7645, 0x7646, 0x7647, 0x7648, 0x7649, 0x764a, 0x764b, 0x764e,
+ 0x764f, 0x7650, 0x7651, 0x7652, 0x7653, 0x7655, 0x7657, 0x7658,
+ 0x7659, 0x765a, 0x765b, 0x765d, 0x765f, 0x7660, 0x7661, 0x7662,
+ 0x7664, 0x7665, 0x7666, 0x7667, 0x7668, 0x7669, 0x766a, 0x766c,
+ 0x766d, 0x766e, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x7675,
+ 0x7676, 0x7677, 0x7679, 0x767a, 0x767c, 0x767f, 0x7680, 0x7681,
+ 0x7683, 0x7685, 0x7689, 0x768a, 0x768c, 0x768d, 0x768f, 0x7690,
+ 0x7692, 0x7694, 0x7695, 0x7697, 0x7698, 0x769a, 0x769b, 0x769c,
+ 0x769d, 0x769e, 0x769f, 0x76a0, 0x76a1, 0x76a2, 0x76a3, 0x76a5,
+ 0x76a6, 0x76a7, 0x76a8, 0x76a9, 0x76aa, 0x76ab, 0x76ac, 0x76ad,
+ 0x76af, 0x76b0, 0x76b3, 0x76b5, 0x76b6, 0x76b7, 0x76b8, 0x76b9,
+ 0x76ba, 0x76bb, 0x76bc, 0x76bd, 0x76be, 0x76c0, 0x76c1, 0x76c3,
+ /* 0xb1 */
+ 0x76c4, 0x76c7, 0x76c9, 0x76cb, 0x76cc, 0x76d3, 0x76d5, 0x76d9,
+ 0x76da, 0x76dc, 0x76dd, 0x76de, 0x76e0, 0x76e1, 0x76e2, 0x76e3,
+ 0x76e4, 0x76e6, 0x76e7, 0x76e8, 0x76e9, 0x76ea, 0x76eb, 0x76ec,
+ 0x76ed, 0x76f0, 0x76f3, 0x76f5, 0x76f6, 0x76f7, 0x76fa, 0x76fb,
+ 0x76fd, 0x76ff, 0x7700, 0x7702, 0x7703, 0x7705, 0x7706, 0x770a,
+ 0x770c, 0x770e, 0x770f, 0x7710, 0x7711, 0x7712, 0x7713, 0x7714,
+ 0x7715, 0x7716, 0x7717, 0x7718, 0x771b, 0x771c, 0x771d, 0x771e,
+ 0x7721, 0x7723, 0x7724, 0x7725, 0x7727, 0x772a, 0x772b, 0x772c,
+ 0x772e, 0x7730, 0x7731, 0x7732, 0x7733, 0x7734, 0x7739, 0x773b,
+ 0x773d, 0x773e, 0x773f, 0x7742, 0x7744, 0x7745, 0x7746, 0x7748,
+ 0x7749, 0x774a, 0x774b, 0x774c, 0x774d, 0x774e, 0x774f, 0x7752,
+ 0x7753, 0x7754, 0x7755, 0x7756, 0x7757, 0x7758, 0x7759, 0x775c,
+ /* 0xb2 */
+ 0x775d, 0x775e, 0x775f, 0x7760, 0x7764, 0x7767, 0x7769, 0x776a,
+ 0x776d, 0x776e, 0x776f, 0x7770, 0x7771, 0x7772, 0x7773, 0x7774,
+ 0x7775, 0x7776, 0x7777, 0x7778, 0x777a, 0x777b, 0x777c, 0x7781,
+ 0x7782, 0x7783, 0x7786, 0x7787, 0x7788, 0x7789, 0x778a, 0x778b,
+ 0x778f, 0x7790, 0x7793, 0x7794, 0x7795, 0x7796, 0x7797, 0x7798,
+ 0x7799, 0x779a, 0x779b, 0x779c, 0x779d, 0x779e, 0x77a1, 0x77a3,
+ 0x77a4, 0x77a6, 0x77a8, 0x77ab, 0x77ad, 0x77ae, 0x77af, 0x77b1,
+ 0x77b2, 0x77b4, 0x77b6, 0x77b7, 0x77b8, 0x77b9, 0x77ba, 0x77bc,
+ 0x77be, 0x77c0, 0x77c1, 0x77c2, 0x77c3, 0x77c4, 0x77c5, 0x77c6,
+ 0x77c7, 0x77c8, 0x77c9, 0x77ca, 0x77cb, 0x77cc, 0x77ce, 0x77cf,
+ 0x77d0, 0x77d1, 0x77d2, 0x77d3, 0x77d4, 0x77d5, 0x77d6, 0x77d8,
+ 0x77d9, 0x77da, 0x77dd, 0x77de, 0x77df, 0x77e0, 0x77e1, 0x77e4,
+ /* 0xb3 */
+ 0x77e6, 0x77e8, 0x77ea, 0x77ef, 0x77f0, 0x77f1, 0x77f2, 0x77f4,
+ 0x77f5, 0x77f7, 0x77f9, 0x77fa, 0x77fb, 0x77fc, 0x7803, 0x7804,
+ 0x7805, 0x7806, 0x7807, 0x7808, 0x780a, 0x780b, 0x780e, 0x780f,
+ 0x7810, 0x7813, 0x7815, 0x7819, 0x781b, 0x781e, 0x7820, 0x7821,
+ 0x7822, 0x7824, 0x7828, 0x782a, 0x782b, 0x782e, 0x782f, 0x7831,
+ 0x7832, 0x7833, 0x7835, 0x7836, 0x783d, 0x783f, 0x7841, 0x7842,
+ 0x7843, 0x7844, 0x7846, 0x7848, 0x7849, 0x784a, 0x784b, 0x784d,
+ 0x784f, 0x7851, 0x7853, 0x7854, 0x7858, 0x7859, 0x785a, 0x785b,
+ 0x785c, 0x785e, 0x785f, 0x7860, 0x7861, 0x7862, 0x7863, 0x7864,
+ 0x7865, 0x7866, 0x7867, 0x7868, 0x7869, 0x786f, 0x7870, 0x7871,
+ 0x7872, 0x7873, 0x7874, 0x7875, 0x7876, 0x7878, 0x7879, 0x787a,
+ 0x787b, 0x787d, 0x787e, 0x787f, 0x7880, 0x7881, 0x7882, 0x7883,
+ /* 0xb4 */
+ 0x7884, 0x7885, 0x7886, 0x7888, 0x788a, 0x788b, 0x788f, 0x7890,
+ 0x7892, 0x7894, 0x7895, 0x7896, 0x7899, 0x789d, 0x789e, 0x78a0,
+ 0x78a2, 0x78a4, 0x78a6, 0x78a8, 0x78a9, 0x78aa, 0x78ab, 0x78ac,
+ 0x78ad, 0x78ae, 0x78af, 0x78b5, 0x78b6, 0x78b7, 0x78b8, 0x78ba,
+ 0x78bb, 0x78bc, 0x78bd, 0x78bf, 0x78c0, 0x78c2, 0x78c3, 0x78c4,
+ 0x78c6, 0x78c7, 0x78c8, 0x78cc, 0x78cd, 0x78ce, 0x78cf, 0x78d1,
+ 0x78d2, 0x78d3, 0x78d6, 0x78d7, 0x78d8, 0x78da, 0x78db, 0x78dc,
+ 0x78dd, 0x78de, 0x78df, 0x78e0, 0x78e1, 0x78e2, 0x78e3, 0x78e4,
+ 0x78e5, 0x78e6, 0x78e7, 0x78e9, 0x78ea, 0x78eb, 0x78ed, 0x78ee,
+ 0x78ef, 0x78f0, 0x78f1, 0x78f3, 0x78f5, 0x78f6, 0x78f8, 0x78f9,
+ 0x78fb, 0x78fc, 0x78fd, 0x78fe, 0x78ff, 0x7900, 0x7902, 0x7903,
+ 0x7904, 0x7906, 0x7907, 0x7908, 0x7909, 0x790a, 0x790b, 0x790c,
+ /* 0xb5 */
+ 0x790d, 0x790e, 0x790f, 0x7910, 0x7911, 0x7912, 0x7914, 0x7915,
+ 0x7916, 0x7917, 0x7918, 0x7919, 0x791a, 0x791b, 0x791c, 0x791d,
+ 0x791f, 0x7920, 0x7921, 0x7922, 0x7923, 0x7925, 0x7926, 0x7927,
+ 0x7928, 0x7929, 0x792a, 0x792b, 0x792c, 0x792d, 0x792e, 0x792f,
+ 0x7930, 0x7931, 0x7932, 0x7933, 0x7935, 0x7936, 0x7937, 0x7938,
+ 0x7939, 0x793d, 0x793f, 0x7942, 0x7943, 0x7944, 0x7945, 0x7947,
+ 0x794a, 0x794b, 0x794c, 0x794d, 0x794e, 0x794f, 0x7950, 0x7951,
+ 0x7952, 0x7954, 0x7955, 0x7958, 0x7959, 0x7961, 0x7963, 0x7964,
+ 0x7966, 0x7969, 0x796a, 0x796b, 0x796c, 0x796e, 0x7970, 0x7971,
+ 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7979, 0x797b, 0x797c,
+ 0x797d, 0x797e, 0x797f, 0x7982, 0x7983, 0x7986, 0x7987, 0x7988,
+ 0x7989, 0x798b, 0x798c, 0x798d, 0x798e, 0x7990, 0x7991, 0x7992,
+ /* 0xb6 */
+ 0x7993, 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x799b,
+ 0x799c, 0x799d, 0x799e, 0x799f, 0x79a0, 0x79a1, 0x79a2, 0x79a3,
+ 0x79a4, 0x79a5, 0x79a6, 0x79a8, 0x79a9, 0x79aa, 0x79ab, 0x79ac,
+ 0x79ad, 0x79ae, 0x79af, 0x79b0, 0x79b1, 0x79b2, 0x79b4, 0x79b5,
+ 0x79b6, 0x79b7, 0x79b8, 0x79bc, 0x79bf, 0x79c2, 0x79c4, 0x79c5,
+ 0x79c7, 0x79c8, 0x79ca, 0x79cc, 0x79ce, 0x79cf, 0x79d0, 0x79d3,
+ 0x79d4, 0x79d6, 0x79d7, 0x79d9, 0x79da, 0x79db, 0x79dc, 0x79dd,
+ 0x79de, 0x79e0, 0x79e1, 0x79e2, 0x79e5, 0x79e8, 0x79ea, 0x79ec,
+ 0x79ee, 0x79f1, 0x79f2, 0x79f3, 0x79f4, 0x79f5, 0x79f6, 0x79f7,
+ 0x79f9, 0x79fa, 0x79fc, 0x79fe, 0x79ff, 0x7a01, 0x7a04, 0x7a05,
+ 0x7a07, 0x7a08, 0x7a09, 0x7a0a, 0x7a0c, 0x7a0f, 0x7a10, 0x7a11,
+ 0x7a12, 0x7a13, 0x7a15, 0x7a16, 0x7a18, 0x7a19, 0x7a1b, 0x7a1c,
+ /* 0xb7 */
+ 0x7a1d, 0x7a1f, 0x7a21, 0x7a22, 0x7a24, 0x7a25, 0x7a26, 0x7a27,
+ 0x7a28, 0x7a29, 0x7a2a, 0x7a2b, 0x7a2c, 0x7a2d, 0x7a2e, 0x7a2f,
+ 0x7a30, 0x7a31, 0x7a32, 0x7a34, 0x7a35, 0x7a36, 0x7a38, 0x7a3a,
+ 0x7a3e, 0x7a40, 0x7a41, 0x7a42, 0x7a43, 0x7a44, 0x7a45, 0x7a47,
+ 0x7a48, 0x7a49, 0x7a4a, 0x7a4b, 0x7a4c, 0x7a4d, 0x7a4e, 0x7a4f,
+ 0x7a50, 0x7a52, 0x7a53, 0x7a54, 0x7a55, 0x7a56, 0x7a58, 0x7a59,
+ 0x7a5a, 0x7a5b, 0x7a5c, 0x7a5d, 0x7a5e, 0x7a5f, 0x7a60, 0x7a61,
+ 0x7a62, 0x7a63, 0x7a64, 0x7a65, 0x7a66, 0x7a67, 0x7a68, 0x7a69,
+ 0x7a6a, 0x7a6b, 0x7a6c, 0x7a6d, 0x7a6e, 0x7a6f, 0x7a71, 0x7a72,
+ 0x7a73, 0x7a75, 0x7a7b, 0x7a7c, 0x7a7d, 0x7a7e, 0x7a82, 0x7a85,
+ 0x7a87, 0x7a89, 0x7a8a, 0x7a8b, 0x7a8c, 0x7a8e, 0x7a8f, 0x7a90,
+ 0x7a93, 0x7a94, 0x7a99, 0x7a9a, 0x7a9b, 0x7a9e, 0x7aa1, 0x7aa2,
+ /* 0xb8 */
+ 0x7aa3, 0x7aa4, 0x7aa7, 0x7aa9, 0x7aaa, 0x7aab, 0x7aae, 0x7aaf,
+ 0x7ab0, 0x7ab1, 0x7ab2, 0x7ab4, 0x7ab5, 0x7ab6, 0x7ab7, 0x7ab8,
+ 0x7ab9, 0x7aba, 0x7abb, 0x7abc, 0x7abd, 0x7abe, 0x7ac0, 0x7ac1,
+ 0x7ac2, 0x7ac3, 0x7ac4, 0x7ac5, 0x7ac6, 0x7ac7, 0x7ac8, 0x7ac9,
+ 0x7aca, 0x7acc, 0x7acd, 0x7ace, 0x7acf, 0x7ad0, 0x7ad1, 0x7ad2,
+ 0x7ad3, 0x7ad4, 0x7ad5, 0x7ad7, 0x7ad8, 0x7ada, 0x7adb, 0x7adc,
+ 0x7add, 0x7ae1, 0x7ae2, 0x7ae4, 0x7ae7, 0x7ae8, 0x7ae9, 0x7aea,
+ 0x7aeb, 0x7aec, 0x7aee, 0x7af0, 0x7af1, 0x7af2, 0x7af3, 0x7af4,
+ 0x7af5, 0x7af6, 0x7af7, 0x7af8, 0x7afb, 0x7afc, 0x7afe, 0x7b00,
+ 0x7b01, 0x7b02, 0x7b05, 0x7b07, 0x7b09, 0x7b0c, 0x7b0d, 0x7b0e,
+ 0x7b10, 0x7b12, 0x7b13, 0x7b16, 0x7b17, 0x7b18, 0x7b1a, 0x7b1c,
+ 0x7b1d, 0x7b1f, 0x7b21, 0x7b22, 0x7b23, 0x7b27, 0x7b29, 0x7b2d,
+ /* 0xb9 */
+ 0x7b2f, 0x7b30, 0x7b32, 0x7b34, 0x7b35, 0x7b36, 0x7b37, 0x7b39,
+ 0x7b3b, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b42, 0x7b43, 0x7b44,
+ 0x7b46, 0x7b48, 0x7b4a, 0x7b4d, 0x7b4e, 0x7b53, 0x7b55, 0x7b57,
+ 0x7b59, 0x7b5c, 0x7b5e, 0x7b5f, 0x7b61, 0x7b63, 0x7b64, 0x7b65,
+ 0x7b66, 0x7b67, 0x7b68, 0x7b69, 0x7b6a, 0x7b6b, 0x7b6c, 0x7b6d,
+ 0x7b6f, 0x7b70, 0x7b73, 0x7b74, 0x7b76, 0x7b78, 0x7b7a, 0x7b7c,
+ 0x7b7d, 0x7b7f, 0x7b81, 0x7b82, 0x7b83, 0x7b84, 0x7b86, 0x7b87,
+ 0x7b88, 0x7b89, 0x7b8a, 0x7b8b, 0x7b8c, 0x7b8e, 0x7b8f, 0x7b91,
+ 0x7b92, 0x7b93, 0x7b96, 0x7b98, 0x7b99, 0x7b9a, 0x7b9b, 0x7b9e,
+ 0x7b9f, 0x7ba0, 0x7ba3, 0x7ba4, 0x7ba5, 0x7bae, 0x7baf, 0x7bb0,
+ 0x7bb2, 0x7bb3, 0x7bb5, 0x7bb6, 0x7bb7, 0x7bb9, 0x7bba, 0x7bbb,
+ 0x7bbc, 0x7bbd, 0x7bbe, 0x7bbf, 0x7bc0, 0x7bc2, 0x7bc3, 0x7bc4,
+ /* 0xba */
+ 0x7bc5, 0x7bc8, 0x7bc9, 0x7bca, 0x7bcb, 0x7bcd, 0x7bce, 0x7bcf,
+ 0x7bd0, 0x7bd2, 0x7bd4, 0x7bd5, 0x7bd6, 0x7bd7, 0x7bd8, 0x7bdb,
+ 0x7bdc, 0x7bde, 0x7bdf, 0x7be0, 0x7be2, 0x7be3, 0x7be4, 0x7be7,
+ 0x7be8, 0x7be9, 0x7beb, 0x7bec, 0x7bed, 0x7bef, 0x7bf0, 0x7bf2,
+ 0x7bf3, 0x7bf4, 0x7bf5, 0x7bf6, 0x7bf8, 0x7bf9, 0x7bfa, 0x7bfb,
+ 0x7bfd, 0x7bff, 0x7c00, 0x7c01, 0x7c02, 0x7c03, 0x7c04, 0x7c05,
+ 0x7c06, 0x7c08, 0x7c09, 0x7c0a, 0x7c0d, 0x7c0e, 0x7c10, 0x7c11,
+ 0x7c12, 0x7c13, 0x7c14, 0x7c15, 0x7c17, 0x7c18, 0x7c19, 0x7c1a,
+ 0x7c1b, 0x7c1c, 0x7c1d, 0x7c1e, 0x7c20, 0x7c21, 0x7c22, 0x7c23,
+ 0x7c24, 0x7c25, 0x7c28, 0x7c29, 0x7c2b, 0x7c2c, 0x7c2d, 0x7c2e,
+ 0x7c2f, 0x7c30, 0x7c31, 0x7c32, 0x7c33, 0x7c34, 0x7c35, 0x7c36,
+ 0x7c37, 0x7c39, 0x7c3a, 0x7c3b, 0x7c3c, 0x7c3d, 0x7c3e, 0x7c42,
+ /* 0xbb */
+ 0x7c43, 0x7c44, 0x7c45, 0x7c46, 0x7c47, 0x7c48, 0x7c49, 0x7c4a,
+ 0x7c4b, 0x7c4c, 0x7c4e, 0x7c4f, 0x7c50, 0x7c51, 0x7c52, 0x7c53,
+ 0x7c54, 0x7c55, 0x7c56, 0x7c57, 0x7c58, 0x7c59, 0x7c5a, 0x7c5b,
+ 0x7c5c, 0x7c5d, 0x7c5e, 0x7c5f, 0x7c60, 0x7c61, 0x7c62, 0x7c63,
+ 0x7c64, 0x7c65, 0x7c66, 0x7c67, 0x7c68, 0x7c69, 0x7c6a, 0x7c6b,
+ 0x7c6c, 0x7c6d, 0x7c6e, 0x7c6f, 0x7c70, 0x7c71, 0x7c72, 0x7c75,
+ 0x7c76, 0x7c77, 0x7c78, 0x7c79, 0x7c7a, 0x7c7e, 0x7c7f, 0x7c80,
+ 0x7c81, 0x7c82, 0x7c83, 0x7c84, 0x7c85, 0x7c86, 0x7c87, 0x7c88,
+ 0x7c8a, 0x7c8b, 0x7c8c, 0x7c8d, 0x7c8e, 0x7c8f, 0x7c90, 0x7c93,
+ 0x7c94, 0x7c96, 0x7c99, 0x7c9a, 0x7c9b, 0x7ca0, 0x7ca1, 0x7ca3,
+ 0x7ca6, 0x7ca7, 0x7ca8, 0x7ca9, 0x7cab, 0x7cac, 0x7cad, 0x7caf,
+ 0x7cb0, 0x7cb4, 0x7cb5, 0x7cb6, 0x7cb7, 0x7cb8, 0x7cba, 0x7cbb,
+ /* 0xbc */
+ 0x7cbf, 0x7cc0, 0x7cc2, 0x7cc3, 0x7cc4, 0x7cc6, 0x7cc9, 0x7ccb,
+ 0x7cce, 0x7ccf, 0x7cd0, 0x7cd1, 0x7cd2, 0x7cd3, 0x7cd4, 0x7cd8,
+ 0x7cda, 0x7cdb, 0x7cdd, 0x7cde, 0x7ce1, 0x7ce2, 0x7ce3, 0x7ce4,
+ 0x7ce5, 0x7ce6, 0x7ce7, 0x7ce9, 0x7cea, 0x7ceb, 0x7cec, 0x7ced,
+ 0x7cee, 0x7cf0, 0x7cf1, 0x7cf2, 0x7cf3, 0x7cf4, 0x7cf5, 0x7cf6,
+ 0x7cf7, 0x7cf9, 0x7cfa, 0x7cfc, 0x7cfd, 0x7cfe, 0x7cff, 0x7d00,
+ 0x7d01, 0x7d02, 0x7d03, 0x7d04, 0x7d05, 0x7d06, 0x7d07, 0x7d08,
+ 0x7d09, 0x7d0b, 0x7d0c, 0x7d0d, 0x7d0e, 0x7d0f, 0x7d10, 0x7d11,
+ 0x7d12, 0x7d13, 0x7d14, 0x7d15, 0x7d16, 0x7d17, 0x7d18, 0x7d19,
+ 0x7d1a, 0x7d1b, 0x7d1c, 0x7d1d, 0x7d1e, 0x7d1f, 0x7d21, 0x7d23,
+ 0x7d24, 0x7d25, 0x7d26, 0x7d28, 0x7d29, 0x7d2a, 0x7d2c, 0x7d2d,
+ 0x7d2e, 0x7d30, 0x7d31, 0x7d32, 0x7d33, 0x7d34, 0x7d35, 0x7d36,
+ /* 0xbd */
+ 0x7d37, 0x7d38, 0x7d39, 0x7d3a, 0x7d3b, 0x7d3c, 0x7d3d, 0x7d3e,
+ 0x7d3f, 0x7d40, 0x7d41, 0x7d42, 0x7d43, 0x7d44, 0x7d45, 0x7d46,
+ 0x7d47, 0x7d48, 0x7d49, 0x7d4a, 0x7d4b, 0x7d4c, 0x7d4d, 0x7d4e,
+ 0x7d4f, 0x7d50, 0x7d51, 0x7d52, 0x7d53, 0x7d54, 0x7d55, 0x7d56,
+ 0x7d57, 0x7d58, 0x7d59, 0x7d5a, 0x7d5b, 0x7d5c, 0x7d5d, 0x7d5e,
+ 0x7d5f, 0x7d60, 0x7d61, 0x7d62, 0x7d63, 0x7d64, 0x7d65, 0x7d66,
+ 0x7d67, 0x7d68, 0x7d69, 0x7d6a, 0x7d6b, 0x7d6c, 0x7d6d, 0x7d6f,
+ 0x7d70, 0x7d71, 0x7d72, 0x7d73, 0x7d74, 0x7d75, 0x7d76, 0x7d78,
+ 0x7d79, 0x7d7a, 0x7d7b, 0x7d7c, 0x7d7d, 0x7d7e, 0x7d7f, 0x7d80,
+ 0x7d81, 0x7d82, 0x7d83, 0x7d84, 0x7d85, 0x7d86, 0x7d87, 0x7d88,
+ 0x7d89, 0x7d8a, 0x7d8b, 0x7d8c, 0x7d8d, 0x7d8e, 0x7d8f, 0x7d90,
+ 0x7d91, 0x7d92, 0x7d93, 0x7d94, 0x7d95, 0x7d96, 0x7d97, 0x7d98,
+ /* 0xbe */
+ 0x7d99, 0x7d9a, 0x7d9b, 0x7d9c, 0x7d9d, 0x7d9e, 0x7d9f, 0x7da0,
+ 0x7da1, 0x7da2, 0x7da3, 0x7da4, 0x7da5, 0x7da7, 0x7da8, 0x7da9,
+ 0x7daa, 0x7dab, 0x7dac, 0x7dad, 0x7daf, 0x7db0, 0x7db1, 0x7db2,
+ 0x7db3, 0x7db4, 0x7db5, 0x7db6, 0x7db7, 0x7db8, 0x7db9, 0x7dba,
+ 0x7dbb, 0x7dbc, 0x7dbd, 0x7dbe, 0x7dbf, 0x7dc0, 0x7dc1, 0x7dc2,
+ 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dc7, 0x7dc8, 0x7dc9, 0x7dca,
+ 0x7dcb, 0x7dcc, 0x7dcd, 0x7dce, 0x7dcf, 0x7dd0, 0x7dd1, 0x7dd2,
+ 0x7dd3, 0x7dd4, 0x7dd5, 0x7dd6, 0x7dd7, 0x7dd8, 0x7dd9, 0x7dda,
+ 0x7ddb, 0x7ddc, 0x7ddd, 0x7dde, 0x7ddf, 0x7de0, 0x7de1, 0x7de2,
+ 0x7de3, 0x7de4, 0x7de5, 0x7de6, 0x7de7, 0x7de8, 0x7de9, 0x7dea,
+ 0x7deb, 0x7dec, 0x7ded, 0x7dee, 0x7def, 0x7df0, 0x7df1, 0x7df2,
+ 0x7df3, 0x7df4, 0x7df5, 0x7df6, 0x7df7, 0x7df8, 0x7df9, 0x7dfa,
+ /* 0xbf */
+ 0x7dfb, 0x7dfc, 0x7dfd, 0x7dfe, 0x7dff, 0x7e00, 0x7e01, 0x7e02,
+ 0x7e03, 0x7e04, 0x7e05, 0x7e06, 0x7e07, 0x7e08, 0x7e09, 0x7e0a,
+ 0x7e0b, 0x7e0c, 0x7e0d, 0x7e0e, 0x7e0f, 0x7e10, 0x7e11, 0x7e12,
+ 0x7e13, 0x7e14, 0x7e15, 0x7e16, 0x7e17, 0x7e18, 0x7e19, 0x7e1a,
+ 0x7e1b, 0x7e1c, 0x7e1d, 0x7e1e, 0x7e1f, 0x7e20, 0x7e21, 0x7e22,
+ 0x7e23, 0x7e24, 0x7e25, 0x7e26, 0x7e27, 0x7e28, 0x7e29, 0x7e2a,
+ 0x7e2b, 0x7e2c, 0x7e2d, 0x7e2e, 0x7e2f, 0x7e30, 0x7e31, 0x7e32,
+ 0x7e33, 0x7e34, 0x7e35, 0x7e36, 0x7e37, 0x7e38, 0x7e39, 0x7e3a,
+ 0x7e3c, 0x7e3d, 0x7e3e, 0x7e3f, 0x7e40, 0x7e42, 0x7e43, 0x7e44,
+ 0x7e45, 0x7e46, 0x7e48, 0x7e49, 0x7e4a, 0x7e4b, 0x7e4c, 0x7e4d,
+ 0x7e4e, 0x7e4f, 0x7e50, 0x7e51, 0x7e52, 0x7e53, 0x7e54, 0x7e55,
+ 0x7e56, 0x7e57, 0x7e58, 0x7e59, 0x7e5a, 0x7e5b, 0x7e5c, 0x7e5d,
+ /* 0xc0 */
+ 0x7e5e, 0x7e5f, 0x7e60, 0x7e61, 0x7e62, 0x7e63, 0x7e64, 0x7e65,
+ 0x7e66, 0x7e67, 0x7e68, 0x7e69, 0x7e6a, 0x7e6b, 0x7e6c, 0x7e6d,
+ 0x7e6e, 0x7e6f, 0x7e70, 0x7e71, 0x7e72, 0x7e73, 0x7e74, 0x7e75,
+ 0x7e76, 0x7e77, 0x7e78, 0x7e79, 0x7e7a, 0x7e7b, 0x7e7c, 0x7e7d,
+ 0x7e7e, 0x7e7f, 0x7e80, 0x7e81, 0x7e83, 0x7e84, 0x7e85, 0x7e86,
+ 0x7e87, 0x7e88, 0x7e89, 0x7e8a, 0x7e8b, 0x7e8c, 0x7e8d, 0x7e8e,
+ 0x7e8f, 0x7e90, 0x7e91, 0x7e92, 0x7e93, 0x7e94, 0x7e95, 0x7e96,
+ 0x7e97, 0x7e98, 0x7e99, 0x7e9a, 0x7e9c, 0x7e9d, 0x7e9e, 0x7eae,
+ 0x7eb4, 0x7ebb, 0x7ebc, 0x7ed6, 0x7ee4, 0x7eec, 0x7ef9, 0x7f0a,
+ 0x7f10, 0x7f1e, 0x7f37, 0x7f39, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e,
+ 0x7f3f, 0x7f40, 0x7f41, 0x7f43, 0x7f46, 0x7f47, 0x7f48, 0x7f49,
+ 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, 0x7f52, 0x7f53,
+ /* 0xc1 */
+ 0x7f56, 0x7f59, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f60, 0x7f63,
+ 0x7f64, 0x7f65, 0x7f66, 0x7f67, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6f,
+ 0x7f70, 0x7f73, 0x7f75, 0x7f76, 0x7f77, 0x7f78, 0x7f7a, 0x7f7b,
+ 0x7f7c, 0x7f7d, 0x7f7f, 0x7f80, 0x7f82, 0x7f83, 0x7f84, 0x7f85,
+ 0x7f86, 0x7f87, 0x7f88, 0x7f89, 0x7f8b, 0x7f8d, 0x7f8f, 0x7f90,
+ 0x7f91, 0x7f92, 0x7f93, 0x7f95, 0x7f96, 0x7f97, 0x7f98, 0x7f99,
+ 0x7f9b, 0x7f9c, 0x7fa0, 0x7fa2, 0x7fa3, 0x7fa5, 0x7fa6, 0x7fa8,
+ 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7fb1, 0x7fb3,
+ 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, 0x7fba, 0x7fbb, 0x7fbe, 0x7fc0,
+ 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc6, 0x7fc7, 0x7fc8, 0x7fc9, 0x7fcb,
+ 0x7fcd, 0x7fcf, 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd6, 0x7fd7,
+ 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fe2, 0x7fe3,
+ /* 0xc2 */
+ 0x7fe4, 0x7fe7, 0x7fe8, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fef,
+ 0x7ff2, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffa,
+ 0x7ffd, 0x7ffe, 0x7fff, 0x8002, 0x8007, 0x8008, 0x8009, 0x800a,
+ 0x800e, 0x800f, 0x8011, 0x8013, 0x801a, 0x801b, 0x801d, 0x801e,
+ 0x801f, 0x8021, 0x8023, 0x8024, 0x802b, 0x802c, 0x802d, 0x802e,
+ 0x802f, 0x8030, 0x8032, 0x8034, 0x8039, 0x803a, 0x803c, 0x803e,
+ 0x8040, 0x8041, 0x8044, 0x8045, 0x8047, 0x8048, 0x8049, 0x804e,
+ 0x804f, 0x8050, 0x8051, 0x8053, 0x8055, 0x8056, 0x8057, 0x8059,
+ 0x805b, 0x805c, 0x805d, 0x805e, 0x805f, 0x8060, 0x8061, 0x8062,
+ 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 0x8068, 0x806b, 0x806c,
+ 0x806d, 0x806e, 0x806f, 0x8070, 0x8072, 0x8073, 0x8074, 0x8075,
+ 0x8076, 0x8077, 0x8078, 0x8079, 0x807a, 0x807b, 0x807c, 0x807d,
+ /* 0xc3 */
+ 0x807e, 0x8081, 0x8082, 0x8085, 0x8088, 0x808a, 0x808d, 0x808e,
+ 0x808f, 0x8090, 0x8091, 0x8092, 0x8094, 0x8095, 0x8097, 0x8099,
+ 0x809e, 0x80a3, 0x80a6, 0x80a7, 0x80a8, 0x80ac, 0x80b0, 0x80b3,
+ 0x80b5, 0x80b6, 0x80b8, 0x80b9, 0x80bb, 0x80c5, 0x80c7, 0x80c8,
+ 0x80c9, 0x80ca, 0x80cb, 0x80cf, 0x80d0, 0x80d1, 0x80d2, 0x80d3,
+ 0x80d4, 0x80d5, 0x80d8, 0x80df, 0x80e0, 0x80e2, 0x80e3, 0x80e6,
+ 0x80ee, 0x80f5, 0x80f7, 0x80f9, 0x80fb, 0x80fe, 0x80ff, 0x8100,
+ 0x8101, 0x8103, 0x8104, 0x8105, 0x8107, 0x8108, 0x810b, 0x810c,
+ 0x8115, 0x8117, 0x8119, 0x811b, 0x811c, 0x811d, 0x811f, 0x8120,
+ 0x8121, 0x8122, 0x8123, 0x8124, 0x8125, 0x8126, 0x8127, 0x8128,
+ 0x8129, 0x812a, 0x812b, 0x812d, 0x812e, 0x8130, 0x8133, 0x8134,
+ 0x8135, 0x8137, 0x8139, 0x813a, 0x813b, 0x813c, 0x813d, 0x813f,
+ /* 0xc4 */
+ 0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8147, 0x8149,
+ 0x814d, 0x814e, 0x814f, 0x8152, 0x8156, 0x8157, 0x8158, 0x815b,
+ 0x815c, 0x815d, 0x815e, 0x815f, 0x8161, 0x8162, 0x8163, 0x8164,
+ 0x8166, 0x8168, 0x816a, 0x816b, 0x816c, 0x816f, 0x8172, 0x8173,
+ 0x8175, 0x8176, 0x8177, 0x8178, 0x8181, 0x8183, 0x8184, 0x8185,
+ 0x8186, 0x8187, 0x8189, 0x818b, 0x818c, 0x818d, 0x818e, 0x8190,
+ 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8199, 0x819a,
+ 0x819e, 0x819f, 0x81a0, 0x81a1, 0x81a2, 0x81a4, 0x81a5, 0x81a7,
+ 0x81a9, 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1,
+ 0x81b2, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81bc,
+ 0x81bd, 0x81be, 0x81bf, 0x81c4, 0x81c5, 0x81c7, 0x81c8, 0x81c9,
+ 0x81cb, 0x81cd, 0x81ce, 0x81cf, 0x81d0, 0x81d1, 0x81d2, 0x81d3,
+ /* 0xc5 */
+ 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 0x81d9, 0x81da, 0x81db,
+ 0x81dc, 0x81dd, 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2, 0x81e4,
+ 0x81e5, 0x81e6, 0x81e8, 0x81e9, 0x81eb, 0x81ee, 0x81ef, 0x81f0,
+ 0x81f1, 0x81f2, 0x81f5, 0x81f6, 0x81f7, 0x81f8, 0x81f9, 0x81fa,
+ 0x81fd, 0x81ff, 0x8203, 0x8207, 0x8208, 0x8209, 0x820a, 0x820b,
+ 0x820e, 0x820f, 0x8211, 0x8213, 0x8215, 0x8216, 0x8217, 0x8218,
+ 0x8219, 0x821a, 0x821d, 0x8220, 0x8224, 0x8225, 0x8226, 0x8227,
+ 0x8229, 0x822e, 0x8232, 0x823a, 0x823c, 0x823d, 0x823f, 0x8240,
+ 0x8241, 0x8242, 0x8243, 0x8245, 0x8246, 0x8248, 0x824a, 0x824c,
+ 0x824d, 0x824e, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255,
+ 0x8256, 0x8257, 0x8259, 0x825b, 0x825c, 0x825d, 0x825e, 0x8260,
+ 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8269,
+ /* 0xc6 */
+ 0x826a, 0x826b, 0x826c, 0x826d, 0x8271, 0x8275, 0x8276, 0x8277,
+ 0x8278, 0x827b, 0x827c, 0x8280, 0x8281, 0x8283, 0x8285, 0x8286,
+ 0x8287, 0x8289, 0x828c, 0x8290, 0x8293, 0x8294, 0x8295, 0x8296,
+ 0x829a, 0x829b, 0x829e, 0x82a0, 0x82a2, 0x82a3, 0x82a7, 0x82b2,
+ 0x82b5, 0x82b6, 0x82ba, 0x82bb, 0x82bc, 0x82bf, 0x82c0, 0x82c2,
+ 0x82c3, 0x82c5, 0x82c6, 0x82c9, 0x82d0, 0x82d6, 0x82d9, 0x82da,
+ 0x82dd, 0x82e2, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82ec, 0x82ed,
+ 0x82ee, 0x82f0, 0x82f2, 0x82f3, 0x82f5, 0x82f6, 0x82f8, 0x82fa,
+ 0x82fc, 0x82fd, 0x82fe, 0x82ff, 0x8300, 0x830a, 0x830b, 0x830d,
+ 0x8310, 0x8312, 0x8313, 0x8316, 0x8318, 0x8319, 0x831d, 0x831e,
+ 0x831f, 0x8320, 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326,
+ 0x8329, 0x832a, 0x832e, 0x8330, 0x8332, 0x8337, 0x833b, 0x833d,
+ /* 0xc7 */
+ 0x833e, 0x833f, 0x8341, 0x8342, 0x8344, 0x8345, 0x8348, 0x834a,
+ 0x834b, 0x834c, 0x834d, 0x834e, 0x8353, 0x8355, 0x8356, 0x8357,
+ 0x8358, 0x8359, 0x835d, 0x8362, 0x8370, 0x8371, 0x8372, 0x8373,
+ 0x8374, 0x8375, 0x8376, 0x8379, 0x837a, 0x837e, 0x837f, 0x8380,
+ 0x8381, 0x8382, 0x8383, 0x8384, 0x8387, 0x8388, 0x838a, 0x838b,
+ 0x838c, 0x838d, 0x838f, 0x8390, 0x8391, 0x8394, 0x8395, 0x8396,
+ 0x8397, 0x8399, 0x839a, 0x839d, 0x839f, 0x83a1, 0x83a2, 0x83a3,
+ 0x83a4, 0x83a5, 0x83a6, 0x83a7, 0x83ac, 0x83ad, 0x83ae, 0x83af,
+ 0x83b5, 0x83bb, 0x83be, 0x83bf, 0x83c2, 0x83c3, 0x83c4, 0x83c6,
+ 0x83c8, 0x83c9, 0x83cb, 0x83cd, 0x83ce, 0x83d0, 0x83d1, 0x83d2,
+ 0x83d3, 0x83d5, 0x83d7, 0x83d9, 0x83da, 0x83db, 0x83de, 0x83e2,
+ 0x83e3, 0x83e4, 0x83e6, 0x83e7, 0x83e8, 0x83eb, 0x83ec, 0x83ed,
+ /* 0xc8 */
+ 0x83ee, 0x83ef, 0x83f3, 0x83f4, 0x83f5, 0x83f6, 0x83f7, 0x83fa,
+ 0x83fb, 0x83fc, 0x83fe, 0x83ff, 0x8400, 0x8402, 0x8405, 0x8407,
+ 0x8408, 0x8409, 0x840a, 0x8410, 0x8412, 0x8413, 0x8414, 0x8415,
+ 0x8416, 0x8417, 0x8419, 0x841a, 0x841b, 0x841e, 0x841f, 0x8420,
+ 0x8421, 0x8422, 0x8423, 0x8429, 0x842a, 0x842b, 0x842c, 0x842d,
+ 0x842e, 0x842f, 0x8430, 0x8432, 0x8433, 0x8434, 0x8435, 0x8436,
+ 0x8437, 0x8439, 0x843a, 0x843b, 0x843e, 0x843f, 0x8440, 0x8441,
+ 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, 0x8449, 0x844a,
+ 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 0x8450, 0x8452, 0x8453,
+ 0x8454, 0x8455, 0x8456, 0x8458, 0x845d, 0x845e, 0x845f, 0x8460,
+ 0x8462, 0x8464, 0x8465, 0x8466, 0x8467, 0x8468, 0x846a, 0x846e,
+ 0x846f, 0x8470, 0x8472, 0x8474, 0x8477, 0x8479, 0x847b, 0x847c,
+ /* 0xc9 */
+ 0x847d, 0x847e, 0x847f, 0x8480, 0x8481, 0x8483, 0x8484, 0x8485,
+ 0x8486, 0x848a, 0x848d, 0x848f, 0x8490, 0x8491, 0x8492, 0x8493,
+ 0x8494, 0x8495, 0x8496, 0x8498, 0x849a, 0x849b, 0x849d, 0x849e,
+ 0x849f, 0x84a0, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7,
+ 0x84a8, 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84b0,
+ 0x84b1, 0x84b3, 0x84b5, 0x84b6, 0x84b7, 0x84bb, 0x84bc, 0x84be,
+ 0x84c0, 0x84c2, 0x84c3, 0x84c5, 0x84c6, 0x84c7, 0x84c8, 0x84cb,
+ 0x84cc, 0x84ce, 0x84cf, 0x84d2, 0x84d4, 0x84d5, 0x84d7, 0x84d8,
+ 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84de, 0x84e1, 0x84e2, 0x84e4,
+ 0x84e7, 0x84e8, 0x84e9, 0x84ea, 0x84eb, 0x84ed, 0x84ee, 0x84ef,
+ 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 0x84f8,
+ 0x84f9, 0x84fa, 0x84fb, 0x84fd, 0x84fe, 0x8500, 0x8501, 0x8502,
+ /* 0xca */
+ 0x8503, 0x8504, 0x8505, 0x8506, 0x8507, 0x8508, 0x8509, 0x850a,
+ 0x850b, 0x850d, 0x850e, 0x850f, 0x8510, 0x8512, 0x8514, 0x8515,
+ 0x8516, 0x8518, 0x8519, 0x851b, 0x851c, 0x851d, 0x851e, 0x8520,
+ 0x8522, 0x8523, 0x8524, 0x8525, 0x8526, 0x8527, 0x8528, 0x8529,
+ 0x852a, 0x852d, 0x852e, 0x852f, 0x8530, 0x8531, 0x8532, 0x8533,
+ 0x8534, 0x8535, 0x8536, 0x853e, 0x853f, 0x8540, 0x8541, 0x8542,
+ 0x8544, 0x8545, 0x8546, 0x8547, 0x854b, 0x854c, 0x854d, 0x854e,
+ 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8554, 0x8555, 0x8557,
+ 0x8558, 0x855a, 0x855b, 0x855c, 0x855d, 0x855f, 0x8560, 0x8561,
+ 0x8562, 0x8563, 0x8565, 0x8566, 0x8567, 0x8569, 0x856a, 0x856b,
+ 0x856c, 0x856d, 0x856e, 0x856f, 0x8570, 0x8571, 0x8573, 0x8575,
+ 0x8576, 0x8577, 0x8578, 0x857c, 0x857d, 0x857f, 0x8580, 0x8581,
+ /* 0xcb */
+ 0x8582, 0x8583, 0x8586, 0x8588, 0x8589, 0x858a, 0x858b, 0x858c,
+ 0x858d, 0x858e, 0x8590, 0x8591, 0x8592, 0x8593, 0x8594, 0x8595,
+ 0x8596, 0x8597, 0x8598, 0x8599, 0x859a, 0x859d, 0x859e, 0x859f,
+ 0x85a0, 0x85a1, 0x85a2, 0x85a3, 0x85a5, 0x85a6, 0x85a7, 0x85a9,
+ 0x85ab, 0x85ac, 0x85ad, 0x85b1, 0x85b2, 0x85b3, 0x85b4, 0x85b5,
+ 0x85b6, 0x85b8, 0x85ba, 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf,
+ 0x85c0, 0x85c2, 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 0x85c8,
+ 0x85ca, 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85d1, 0x85d2, 0x85d4,
+ 0x85d6, 0x85d7, 0x85d8, 0x85d9, 0x85da, 0x85db, 0x85dd, 0x85de,
+ 0x85df, 0x85e0, 0x85e1, 0x85e2, 0x85e3, 0x85e5, 0x85e6, 0x85e7,
+ 0x85e8, 0x85ea, 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 0x85f0,
+ 0x85f1, 0x85f2, 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 0x85f8,
+ /* 0xcc */
+ 0x85f9, 0x85fa, 0x85fc, 0x85fd, 0x85fe, 0x8600, 0x8601, 0x8602,
+ 0x8603, 0x8604, 0x8606, 0x8607, 0x8608, 0x8609, 0x860a, 0x860b,
+ 0x860c, 0x860d, 0x860e, 0x860f, 0x8610, 0x8612, 0x8613, 0x8614,
+ 0x8615, 0x8617, 0x8618, 0x8619, 0x861a, 0x861b, 0x861c, 0x861d,
+ 0x861e, 0x861f, 0x8620, 0x8621, 0x8622, 0x8623, 0x8624, 0x8625,
+ 0x8626, 0x8628, 0x862a, 0x862b, 0x862c, 0x862d, 0x862e, 0x862f,
+ 0x8630, 0x8631, 0x8632, 0x8633, 0x8634, 0x8635, 0x8636, 0x8637,
+ 0x8639, 0x863a, 0x863b, 0x863d, 0x863e, 0x863f, 0x8640, 0x8641,
+ 0x8642, 0x8643, 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649,
+ 0x864a, 0x864b, 0x864c, 0x8652, 0x8653, 0x8655, 0x8656, 0x8657,
+ 0x8658, 0x8659, 0x865b, 0x865c, 0x865d, 0x865f, 0x8660, 0x8661,
+ 0x8663, 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, 0x866a,
+ /* 0xcd */
+ 0x866d, 0x866f, 0x8670, 0x8672, 0x8673, 0x8674, 0x8675, 0x8676,
+ 0x8677, 0x8678, 0x8683, 0x8684, 0x8685, 0x8686, 0x8687, 0x8688,
+ 0x8689, 0x868e, 0x868f, 0x8690, 0x8691, 0x8692, 0x8694, 0x8696,
+ 0x8697, 0x8698, 0x8699, 0x869a, 0x869b, 0x869e, 0x869f, 0x86a0,
+ 0x86a1, 0x86a2, 0x86a5, 0x86a6, 0x86ab, 0x86ad, 0x86ae, 0x86b2,
+ 0x86b3, 0x86b7, 0x86b8, 0x86b9, 0x86bb, 0x86bc, 0x86bd, 0x86be,
+ 0x86bf, 0x86c1, 0x86c2, 0x86c3, 0x86c5, 0x86c8, 0x86cc, 0x86cd,
+ 0x86d2, 0x86d3, 0x86d5, 0x86d6, 0x86d7, 0x86da, 0x86dc, 0x86dd,
+ 0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e5, 0x86e6, 0x86e7, 0x86e8,
+ 0x86ea, 0x86eb, 0x86ec, 0x86ef, 0x86f5, 0x86f6, 0x86f7, 0x86fa,
+ 0x86fb, 0x86fc, 0x86fd, 0x86ff, 0x8701, 0x8704, 0x8705, 0x8706,
+ 0x870b, 0x870c, 0x870e, 0x870f, 0x8710, 0x8711, 0x8714, 0x8716,
+ /* 0xce */
+ 0x8719, 0x871b, 0x871d, 0x871f, 0x8720, 0x8724, 0x8726, 0x8727,
+ 0x8728, 0x872a, 0x872b, 0x872c, 0x872d, 0x872f, 0x8730, 0x8732,
+ 0x8733, 0x8735, 0x8736, 0x8738, 0x8739, 0x873a, 0x873c, 0x873d,
+ 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, 0x8746, 0x874a,
+ 0x874b, 0x874d, 0x874f, 0x8750, 0x8751, 0x8752, 0x8754, 0x8755,
+ 0x8756, 0x8758, 0x875a, 0x875b, 0x875c, 0x875d, 0x875e, 0x875f,
+ 0x8761, 0x8762, 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b,
+ 0x876c, 0x876d, 0x876f, 0x8771, 0x8772, 0x8773, 0x8775, 0x8777,
+ 0x8778, 0x8779, 0x877a, 0x877f, 0x8780, 0x8781, 0x8784, 0x8786,
+ 0x8787, 0x8789, 0x878a, 0x878c, 0x878e, 0x878f, 0x8790, 0x8791,
+ 0x8792, 0x8794, 0x8795, 0x8796, 0x8798, 0x8799, 0x879a, 0x879b,
+ 0x879c, 0x879d, 0x879e, 0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4,
+ /* 0xcf */
+ 0x87a5, 0x87a6, 0x87a7, 0x87a9, 0x87aa, 0x87ae, 0x87b0, 0x87b1,
+ 0x87b2, 0x87b4, 0x87b6, 0x87b7, 0x87b8, 0x87b9, 0x87bb, 0x87bc,
+ 0x87be, 0x87bf, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c7,
+ 0x87c8, 0x87c9, 0x87cc, 0x87cd, 0x87ce, 0x87cf, 0x87d0, 0x87d4,
+ 0x87d5, 0x87d6, 0x87d7, 0x87d8, 0x87d9, 0x87da, 0x87dc, 0x87dd,
+ 0x87de, 0x87df, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e6, 0x87e7,
+ 0x87e8, 0x87e9, 0x87eb, 0x87ec, 0x87ed, 0x87ef, 0x87f0, 0x87f1,
+ 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6, 0x87f7, 0x87f8, 0x87fa,
+ 0x87fb, 0x87fc, 0x87fd, 0x87ff, 0x8800, 0x8801, 0x8802, 0x8804,
+ 0x8805, 0x8806, 0x8807, 0x8808, 0x8809, 0x880b, 0x880c, 0x880d,
+ 0x880e, 0x880f, 0x8810, 0x8811, 0x8812, 0x8814, 0x8817, 0x8818,
+ 0x8819, 0x881a, 0x881c, 0x881d, 0x881e, 0x881f, 0x8820, 0x8823,
+ /* 0xd0 */
+ 0x8824, 0x8825, 0x8826, 0x8827, 0x8828, 0x8829, 0x882a, 0x882b,
+ 0x882c, 0x882d, 0x882e, 0x882f, 0x8830, 0x8831, 0x8833, 0x8834,
+ 0x8835, 0x8836, 0x8837, 0x8838, 0x883a, 0x883b, 0x883d, 0x883e,
+ 0x883f, 0x8841, 0x8842, 0x8843, 0x8846, 0x8847, 0x8848, 0x8849,
+ 0x884a, 0x884b, 0x884e, 0x884f, 0x8850, 0x8851, 0x8852, 0x8853,
+ 0x8855, 0x8856, 0x8858, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e,
+ 0x885f, 0x8860, 0x8866, 0x8867, 0x886a, 0x886d, 0x886f, 0x8871,
+ 0x8873, 0x8874, 0x8875, 0x8876, 0x8878, 0x8879, 0x887a, 0x887b,
+ 0x887c, 0x8880, 0x8883, 0x8886, 0x8887, 0x8889, 0x888a, 0x888c,
+ 0x888e, 0x888f, 0x8890, 0x8891, 0x8893, 0x8894, 0x8895, 0x8897,
+ 0x8898, 0x8899, 0x889a, 0x889b, 0x889d, 0x889e, 0x889f, 0x88a0,
+ 0x88a1, 0x88a3, 0x88a5, 0x88a6, 0x88a7, 0x88a8, 0x88a9, 0x88aa,
+ /* 0xd1 */
+ 0x88ac, 0x88ae, 0x88af, 0x88b0, 0x88b2, 0x88b3, 0x88b4, 0x88b5,
+ 0x88b6, 0x88b8, 0x88b9, 0x88ba, 0x88bb, 0x88bd, 0x88be, 0x88bf,
+ 0x88c0, 0x88c3, 0x88c4, 0x88c7, 0x88c8, 0x88ca, 0x88cb, 0x88cc,
+ 0x88cd, 0x88cf, 0x88d0, 0x88d1, 0x88d3, 0x88d6, 0x88d7, 0x88da,
+ 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88e0, 0x88e1, 0x88e6, 0x88e7,
+ 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f2,
+ 0x88f5, 0x88f6, 0x88f7, 0x88fa, 0x88fb, 0x88fd, 0x88ff, 0x8900,
+ 0x8901, 0x8903, 0x8904, 0x8905, 0x8906, 0x8907, 0x8908, 0x8909,
+ 0x890b, 0x890c, 0x890d, 0x890e, 0x890f, 0x8911, 0x8914, 0x8915,
+ 0x8916, 0x8917, 0x8918, 0x891c, 0x891d, 0x891e, 0x891f, 0x8920,
+ 0x8922, 0x8923, 0x8924, 0x8926, 0x8927, 0x8928, 0x8929, 0x892c,
+ 0x892d, 0x892e, 0x892f, 0x8931, 0x8932, 0x8933, 0x8935, 0x8937,
+ /* 0xd2 */
+ 0x8938, 0x8939, 0x893a, 0x893b, 0x893c, 0x893d, 0x893e, 0x893f,
+ 0x8940, 0x8942, 0x8943, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949,
+ 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951,
+ 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959,
+ 0x895a, 0x895b, 0x895c, 0x895d, 0x8960, 0x8961, 0x8962, 0x8963,
+ 0x8964, 0x8965, 0x8967, 0x8968, 0x8969, 0x896a, 0x896b, 0x896c,
+ 0x896d, 0x896e, 0x896f, 0x8970, 0x8971, 0x8972, 0x8973, 0x8974,
+ 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, 0x897a, 0x897c, 0x897d,
+ 0x897e, 0x8980, 0x8982, 0x8984, 0x8985, 0x8987, 0x8988, 0x8989,
+ 0x898a, 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 0x8990, 0x8991,
+ 0x8992, 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999,
+ 0x899a, 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1,
+ /* 0xd3 */
+ 0x89a2, 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 0x89a8, 0x89a9,
+ 0x89aa, 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 0x89b0, 0x89b1,
+ 0x89b2, 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 0x89b8, 0x89b9,
+ 0x89ba, 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 0x89c0, 0x89c3,
+ 0x89cd, 0x89d3, 0x89d4, 0x89d5, 0x89d7, 0x89d8, 0x89d9, 0x89db,
+ 0x89dd, 0x89df, 0x89e0, 0x89e1, 0x89e2, 0x89e4, 0x89e7, 0x89e8,
+ 0x89e9, 0x89ea, 0x89ec, 0x89ed, 0x89ee, 0x89f0, 0x89f1, 0x89f2,
+ 0x89f4, 0x89f5, 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa, 0x89fb,
+ 0x89fc, 0x89fd, 0x89fe, 0x89ff, 0x8a01, 0x8a02, 0x8a03, 0x8a04,
+ 0x8a05, 0x8a06, 0x8a08, 0x8a09, 0x8a0a, 0x8a0b, 0x8a0c, 0x8a0d,
+ 0x8a0e, 0x8a0f, 0x8a10, 0x8a11, 0x8a12, 0x8a13, 0x8a14, 0x8a15,
+ 0x8a16, 0x8a17, 0x8a18, 0x8a19, 0x8a1a, 0x8a1b, 0x8a1c, 0x8a1d,
+ /* 0xd4 */
+ 0x8a1e, 0x8a1f, 0x8a20, 0x8a21, 0x8a22, 0x8a23, 0x8a24, 0x8a25,
+ 0x8a26, 0x8a27, 0x8a28, 0x8a29, 0x8a2a, 0x8a2b, 0x8a2c, 0x8a2d,
+ 0x8a2e, 0x8a2f, 0x8a30, 0x8a31, 0x8a32, 0x8a33, 0x8a34, 0x8a35,
+ 0x8a36, 0x8a37, 0x8a38, 0x8a39, 0x8a3a, 0x8a3b, 0x8a3c, 0x8a3d,
+ 0x8a3f, 0x8a40, 0x8a41, 0x8a42, 0x8a43, 0x8a44, 0x8a45, 0x8a46,
+ 0x8a47, 0x8a49, 0x8a4a, 0x8a4b, 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f,
+ 0x8a50, 0x8a51, 0x8a52, 0x8a53, 0x8a54, 0x8a55, 0x8a56, 0x8a57,
+ 0x8a58, 0x8a59, 0x8a5a, 0x8a5b, 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f,
+ 0x8a60, 0x8a61, 0x8a62, 0x8a63, 0x8a64, 0x8a65, 0x8a66, 0x8a67,
+ 0x8a68, 0x8a69, 0x8a6a, 0x8a6b, 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f,
+ 0x8a70, 0x8a71, 0x8a72, 0x8a73, 0x8a74, 0x8a75, 0x8a76, 0x8a77,
+ 0x8a78, 0x8a7a, 0x8a7b, 0x8a7c, 0x8a7d, 0x8a7e, 0x8a7f, 0x8a80,
+ /* 0xd5 */
+ 0x8a81, 0x8a82, 0x8a83, 0x8a84, 0x8a85, 0x8a86, 0x8a87, 0x8a88,
+ 0x8a8b, 0x8a8c, 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91, 0x8a92,
+ 0x8a94, 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b,
+ 0x8a9c, 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3,
+ 0x8aa4, 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab,
+ 0x8aac, 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3,
+ 0x8ab4, 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9, 0x8aba, 0x8abb,
+ 0x8abc, 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3,
+ 0x8ac4, 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9, 0x8aca, 0x8acb,
+ 0x8acc, 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3,
+ 0x8ad4, 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9, 0x8ada, 0x8adb,
+ 0x8adc, 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3,
+ /* 0xd6 */
+ 0x8ae4, 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9, 0x8aea, 0x8aeb,
+ 0x8aec, 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1, 0x8af2, 0x8af3,
+ 0x8af4, 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9, 0x8afa, 0x8afb,
+ 0x8afc, 0x8afd, 0x8afe, 0x8aff, 0x8b00, 0x8b01, 0x8b02, 0x8b03,
+ 0x8b04, 0x8b05, 0x8b06, 0x8b08, 0x8b09, 0x8b0a, 0x8b0b, 0x8b0c,
+ 0x8b0d, 0x8b0e, 0x8b0f, 0x8b10, 0x8b11, 0x8b12, 0x8b13, 0x8b14,
+ 0x8b15, 0x8b16, 0x8b17, 0x8b18, 0x8b19, 0x8b1a, 0x8b1b, 0x8b1c,
+ 0x8b1d, 0x8b1e, 0x8b1f, 0x8b20, 0x8b21, 0x8b22, 0x8b23, 0x8b24,
+ 0x8b25, 0x8b27, 0x8b28, 0x8b29, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b2d,
+ 0x8b2e, 0x8b2f, 0x8b30, 0x8b31, 0x8b32, 0x8b33, 0x8b34, 0x8b35,
+ 0x8b36, 0x8b37, 0x8b38, 0x8b39, 0x8b3a, 0x8b3b, 0x8b3c, 0x8b3d,
+ 0x8b3e, 0x8b3f, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45,
+ /* 0xd7 */
+ 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d,
+ 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55,
+ 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d,
+ 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65,
+ 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6d, 0x8b6e, 0x8b6f,
+ 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75, 0x8b76, 0x8b77,
+ 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d, 0x8b7e, 0x8b7f,
+ 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86, 0x8b87,
+ 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e, 0x8b8f,
+ 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96, 0x8b97,
+ 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e, 0x8b9f,
+ 0x8bac, 0x8bb1, 0x8bbb, 0x8bc7, 0x8bd0, 0x8bea, 0x8c09, 0x8c1e,
+ /* 0xd8 */
+ 0x8c38, 0x8c39, 0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d, 0x8c3e, 0x8c3f,
+ 0x8c40, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c48, 0x8c4a, 0x8c4b,
+ 0x8c4d, 0x8c4e, 0x8c4f, 0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54,
+ 0x8c56, 0x8c57, 0x8c58, 0x8c59, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e,
+ 0x8c5f, 0x8c60, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67, 0x8c68,
+ 0x8c69, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f, 0x8c70, 0x8c71, 0x8c72,
+ 0x8c74, 0x8c75, 0x8c76, 0x8c77, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e,
+ 0x8c7f, 0x8c80, 0x8c81, 0x8c83, 0x8c84, 0x8c86, 0x8c87, 0x8c88,
+ 0x8c8b, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90, 0x8c91, 0x8c92, 0x8c93,
+ 0x8c95, 0x8c96, 0x8c97, 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d,
+ 0x8c9e, 0x8c9f, 0x8ca0, 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5,
+ 0x8ca6, 0x8ca7, 0x8ca8, 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad,
+ /* 0xd9 */
+ 0x8cae, 0x8caf, 0x8cb0, 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5,
+ 0x8cb6, 0x8cb7, 0x8cb8, 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd,
+ 0x8cbe, 0x8cbf, 0x8cc0, 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5,
+ 0x8cc6, 0x8cc7, 0x8cc8, 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd,
+ 0x8cce, 0x8ccf, 0x8cd0, 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5,
+ 0x8cd6, 0x8cd7, 0x8cd8, 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd,
+ 0x8cde, 0x8cdf, 0x8ce0, 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5,
+ 0x8ce6, 0x8ce7, 0x8ce8, 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced,
+ 0x8cee, 0x8cef, 0x8cf0, 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5,
+ 0x8cf6, 0x8cf7, 0x8cf8, 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd,
+ 0x8cfe, 0x8cff, 0x8d00, 0x8d01, 0x8d02, 0x8d03, 0x8d04, 0x8d05,
+ 0x8d06, 0x8d07, 0x8d08, 0x8d09, 0x8d0a, 0x8d0b, 0x8d0c, 0x8d0d,
+ /* 0xda */
+ 0x8d0e, 0x8d0f, 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15,
+ 0x8d16, 0x8d17, 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d20,
+ 0x8d51, 0x8d52, 0x8d57, 0x8d5f, 0x8d65, 0x8d68, 0x8d69, 0x8d6a,
+ 0x8d6c, 0x8d6e, 0x8d6f, 0x8d71, 0x8d72, 0x8d78, 0x8d79, 0x8d7a,
+ 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d7f, 0x8d80, 0x8d82, 0x8d83,
+ 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f,
+ 0x8d90, 0x8d92, 0x8d93, 0x8d95, 0x8d96, 0x8d97, 0x8d98, 0x8d99,
+ 0x8d9a, 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8da0, 0x8da1, 0x8da2,
+ 0x8da4, 0x8da5, 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa, 0x8dab,
+ 0x8dac, 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db2, 0x8db6, 0x8db7,
+ 0x8db9, 0x8dbb, 0x8dbd, 0x8dc0, 0x8dc1, 0x8dc2, 0x8dc5, 0x8dc7,
+ 0x8dc8, 0x8dc9, 0x8dca, 0x8dcd, 0x8dd0, 0x8dd2, 0x8dd3, 0x8dd4,
+ /* 0xdb */
+ 0x8dd5, 0x8dd8, 0x8dd9, 0x8ddc, 0x8de0, 0x8de1, 0x8de2, 0x8de5,
+ 0x8de6, 0x8de7, 0x8de9, 0x8ded, 0x8dee, 0x8df0, 0x8df1, 0x8df2,
+ 0x8df4, 0x8df6, 0x8dfc, 0x8dfe, 0x8dff, 0x8e00, 0x8e01, 0x8e02,
+ 0x8e03, 0x8e04, 0x8e06, 0x8e07, 0x8e08, 0x8e0b, 0x8e0d, 0x8e0e,
+ 0x8e10, 0x8e11, 0x8e12, 0x8e13, 0x8e15, 0x8e16, 0x8e17, 0x8e18,
+ 0x8e19, 0x8e1a, 0x8e1b, 0x8e1c, 0x8e20, 0x8e21, 0x8e24, 0x8e25,
+ 0x8e26, 0x8e27, 0x8e28, 0x8e2b, 0x8e2d, 0x8e30, 0x8e32, 0x8e33,
+ 0x8e34, 0x8e36, 0x8e37, 0x8e38, 0x8e3b, 0x8e3c, 0x8e3e, 0x8e3f,
+ 0x8e43, 0x8e45, 0x8e46, 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50,
+ 0x8e53, 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58, 0x8e5a, 0x8e5b,
+ 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0x8e63,
+ 0x8e64, 0x8e65, 0x8e67, 0x8e68, 0x8e6a, 0x8e6b, 0x8e6e, 0x8e71,
+ /* 0xdc */
+ 0x8e73, 0x8e75, 0x8e77, 0x8e78, 0x8e79, 0x8e7a, 0x8e7b, 0x8e7d,
+ 0x8e7e, 0x8e80, 0x8e82, 0x8e83, 0x8e84, 0x8e86, 0x8e88, 0x8e89,
+ 0x8e8a, 0x8e8b, 0x8e8c, 0x8e8d, 0x8e8e, 0x8e91, 0x8e92, 0x8e93,
+ 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9d,
+ 0x8e9f, 0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4, 0x8ea5, 0x8ea6,
+ 0x8ea7, 0x8ea8, 0x8ea9, 0x8eaa, 0x8ead, 0x8eae, 0x8eb0, 0x8eb1,
+ 0x8eb3, 0x8eb4, 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9, 0x8ebb,
+ 0x8ebc, 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3,
+ 0x8ec4, 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, 0x8eca, 0x8ecb,
+ 0x8ecc, 0x8ecd, 0x8ecf, 0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4,
+ 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc,
+ 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4,
+ /* 0xdd */
+ 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec,
+ 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4,
+ 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc,
+ 0x8efd, 0x8efe, 0x8eff, 0x8f00, 0x8f01, 0x8f02, 0x8f03, 0x8f04,
+ 0x8f05, 0x8f06, 0x8f07, 0x8f08, 0x8f09, 0x8f0a, 0x8f0b, 0x8f0c,
+ 0x8f0d, 0x8f0e, 0x8f0f, 0x8f10, 0x8f11, 0x8f12, 0x8f13, 0x8f14,
+ 0x8f15, 0x8f16, 0x8f17, 0x8f18, 0x8f19, 0x8f1a, 0x8f1b, 0x8f1c,
+ 0x8f1d, 0x8f1e, 0x8f1f, 0x8f20, 0x8f21, 0x8f22, 0x8f23, 0x8f24,
+ 0x8f25, 0x8f26, 0x8f27, 0x8f28, 0x8f29, 0x8f2a, 0x8f2b, 0x8f2c,
+ 0x8f2d, 0x8f2e, 0x8f2f, 0x8f30, 0x8f31, 0x8f32, 0x8f33, 0x8f34,
+ 0x8f35, 0x8f36, 0x8f37, 0x8f38, 0x8f39, 0x8f3a, 0x8f3b, 0x8f3c,
+ 0x8f3d, 0x8f3e, 0x8f3f, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44,
+ /* 0xde */
+ 0x8f45, 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c,
+ 0x8f4d, 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54,
+ 0x8f55, 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c,
+ 0x8f5d, 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64,
+ 0x8f65, 0x8f6a, 0x8f80, 0x8f8c, 0x8f92, 0x8f9d, 0x8fa0, 0x8fa1,
+ 0x8fa2, 0x8fa4, 0x8fa5, 0x8fa6, 0x8fa7, 0x8faa, 0x8fac, 0x8fad,
+ 0x8fae, 0x8faf, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb7, 0x8fb8,
+ 0x8fba, 0x8fbb, 0x8fbc, 0x8fbf, 0x8fc0, 0x8fc3, 0x8fc6, 0x8fc9,
+ 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fcf, 0x8fd2, 0x8fd6, 0x8fd7,
+ 0x8fda, 0x8fe0, 0x8fe1, 0x8fe3, 0x8fe7, 0x8fec, 0x8fef, 0x8ff1,
+ 0x8ff2, 0x8ff4, 0x8ff5, 0x8ff6, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffe,
+ 0x8fff, 0x9007, 0x9008, 0x900c, 0x900e, 0x9013, 0x9015, 0x9018,
+ /* 0xdf */
+ 0x9019, 0x901c, 0x9023, 0x9024, 0x9025, 0x9027, 0x9028, 0x9029,
+ 0x902a, 0x902b, 0x902c, 0x9030, 0x9031, 0x9032, 0x9033, 0x9034,
+ 0x9037, 0x9039, 0x903a, 0x903d, 0x903f, 0x9040, 0x9043, 0x9045,
+ 0x9046, 0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904e, 0x9054,
+ 0x9055, 0x9056, 0x9059, 0x905a, 0x905c, 0x905d, 0x905e, 0x905f,
+ 0x9060, 0x9061, 0x9064, 0x9066, 0x9067, 0x9069, 0x906a, 0x906b,
+ 0x906c, 0x906f, 0x9070, 0x9071, 0x9072, 0x9073, 0x9076, 0x9077,
+ 0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907e, 0x9081, 0x9084,
+ 0x9085, 0x9086, 0x9087, 0x9089, 0x908a, 0x908c, 0x908d, 0x908e,
+ 0x908f, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909a, 0x909c,
+ 0x909e, 0x909f, 0x90a0, 0x90a4, 0x90a5, 0x90a7, 0x90a8, 0x90a9,
+ 0x90ab, 0x90ad, 0x90b2, 0x90b7, 0x90bc, 0x90bd, 0x90bf, 0x90c0,
+ /* 0xe0 */
+ 0x90c2, 0x90c3, 0x90c6, 0x90c8, 0x90c9, 0x90cb, 0x90cc, 0x90cd,
+ 0x90d2, 0x90d4, 0x90d5, 0x90d6, 0x90d8, 0x90d9, 0x90da, 0x90de,
+ 0x90df, 0x90e0, 0x90e3, 0x90e4, 0x90e5, 0x90e9, 0x90ea, 0x90ec,
+ 0x90ee, 0x90f0, 0x90f1, 0x90f2, 0x90f3, 0x90f5, 0x90f6, 0x90f7,
+ 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90ff, 0x9100, 0x9101, 0x9103,
+ 0x9105, 0x9106, 0x9107, 0x9108, 0x9109, 0x910a, 0x910b, 0x910c,
+ 0x910d, 0x910e, 0x910f, 0x9110, 0x9111, 0x9112, 0x9113, 0x9114,
+ 0x9115, 0x9116, 0x9117, 0x9118, 0x911a, 0x911b, 0x911c, 0x911d,
+ 0x911f, 0x9120, 0x9121, 0x9124, 0x9125, 0x9126, 0x9127, 0x9128,
+ 0x9129, 0x912a, 0x912b, 0x912c, 0x912d, 0x912e, 0x9130, 0x9132,
+ 0x9133, 0x9134, 0x9135, 0x9136, 0x9137, 0x9138, 0x913a, 0x913b,
+ 0x913c, 0x913d, 0x913e, 0x913f, 0x9140, 0x9141, 0x9142, 0x9144,
+ /* 0xe1 */
+ 0x9145, 0x9147, 0x9148, 0x9151, 0x9153, 0x9154, 0x9155, 0x9156,
+ 0x9158, 0x9159, 0x915b, 0x915c, 0x915f, 0x9160, 0x9166, 0x9167,
+ 0x9168, 0x916b, 0x916d, 0x9173, 0x917a, 0x917b, 0x917c, 0x9180,
+ 0x9181, 0x9182, 0x9183, 0x9184, 0x9186, 0x9188, 0x918a, 0x918e,
+ 0x918f, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199,
+ 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a4, 0x91a5,
+ 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91ab, 0x91ac, 0x91b0, 0x91b1,
+ 0x91b2, 0x91b3, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91bb, 0x91bc,
+ 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2, 0x91c3, 0x91c4,
+ 0x91c5, 0x91c6, 0x91c8, 0x91cb, 0x91d0, 0x91d2, 0x91d3, 0x91d4,
+ 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da, 0x91db, 0x91dd,
+ 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2, 0x91e3, 0x91e4, 0x91e5,
+ /* 0xe2 */
+ 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea, 0x91eb, 0x91ec, 0x91ed,
+ 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2, 0x91f3, 0x91f4, 0x91f5,
+ 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa, 0x91fb, 0x91fc, 0x91fd,
+ 0x91fe, 0x91ff, 0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205,
+ 0x9206, 0x9207, 0x9208, 0x9209, 0x920a, 0x920b, 0x920c, 0x920d,
+ 0x920e, 0x920f, 0x9210, 0x9211, 0x9212, 0x9213, 0x9214, 0x9215,
+ 0x9216, 0x9217, 0x9218, 0x9219, 0x921a, 0x921b, 0x921c, 0x921d,
+ 0x921e, 0x921f, 0x9220, 0x9221, 0x9222, 0x9223, 0x9224, 0x9225,
+ 0x9226, 0x9227, 0x9228, 0x9229, 0x922a, 0x922b, 0x922c, 0x922d,
+ 0x922e, 0x922f, 0x9230, 0x9231, 0x9232, 0x9233, 0x9234, 0x9235,
+ 0x9236, 0x9237, 0x9238, 0x9239, 0x923a, 0x923b, 0x923c, 0x923d,
+ 0x923e, 0x923f, 0x9240, 0x9241, 0x9242, 0x9243, 0x9244, 0x9245,
+ /* 0xe3 */
+ 0x9246, 0x9247, 0x9248, 0x9249, 0x924a, 0x924b, 0x924c, 0x924d,
+ 0x924e, 0x924f, 0x9250, 0x9251, 0x9252, 0x9253, 0x9254, 0x9255,
+ 0x9256, 0x9257, 0x9258, 0x9259, 0x925a, 0x925b, 0x925c, 0x925d,
+ 0x925e, 0x925f, 0x9260, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265,
+ 0x9266, 0x9267, 0x9268, 0x9269, 0x926a, 0x926b, 0x926c, 0x926d,
+ 0x926e, 0x926f, 0x9270, 0x9271, 0x9272, 0x9273, 0x9275, 0x9276,
+ 0x9277, 0x9278, 0x9279, 0x927a, 0x927b, 0x927c, 0x927d, 0x927e,
+ 0x927f, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284, 0x9285, 0x9286,
+ 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c, 0x928d, 0x928f,
+ 0x9290, 0x9291, 0x9292, 0x9293, 0x9294, 0x9295, 0x9296, 0x9297,
+ 0x9298, 0x9299, 0x929a, 0x929b, 0x929c, 0x929d, 0x929e, 0x929f,
+ 0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4, 0x92a5, 0x92a6, 0x92a7,
+ /* 0xe4 */
+ 0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac, 0x92ad, 0x92af, 0x92b0,
+ 0x92b1, 0x92b2, 0x92b3, 0x92b4, 0x92b5, 0x92b6, 0x92b7, 0x92b8,
+ 0x92b9, 0x92ba, 0x92bb, 0x92bc, 0x92bd, 0x92be, 0x92bf, 0x92c0,
+ 0x92c1, 0x92c2, 0x92c3, 0x92c4, 0x92c5, 0x92c6, 0x92c7, 0x92c9,
+ 0x92ca, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1,
+ 0x92d2, 0x92d3, 0x92d4, 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9,
+ 0x92da, 0x92db, 0x92dc, 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1,
+ 0x92e2, 0x92e3, 0x92e4, 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9,
+ 0x92ea, 0x92eb, 0x92ec, 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1,
+ 0x92f2, 0x92f3, 0x92f4, 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9,
+ 0x92fa, 0x92fb, 0x92fc, 0x92fd, 0x92fe, 0x92ff, 0x9300, 0x9301,
+ 0x9302, 0x9303, 0x9304, 0x9305, 0x9306, 0x9307, 0x9308, 0x9309,
+ /* 0xe5 */
+ 0x930a, 0x930b, 0x930c, 0x930d, 0x930e, 0x930f, 0x9310, 0x9311,
+ 0x9312, 0x9313, 0x9314, 0x9315, 0x9316, 0x9317, 0x9318, 0x9319,
+ 0x931a, 0x931b, 0x931c, 0x931d, 0x931e, 0x931f, 0x9320, 0x9321,
+ 0x9322, 0x9323, 0x9324, 0x9325, 0x9326, 0x9327, 0x9328, 0x9329,
+ 0x932a, 0x932b, 0x932c, 0x932d, 0x932e, 0x932f, 0x9330, 0x9331,
+ 0x9332, 0x9333, 0x9334, 0x9335, 0x9336, 0x9337, 0x9338, 0x9339,
+ 0x933a, 0x933b, 0x933c, 0x933d, 0x933f, 0x9340, 0x9341, 0x9342,
+ 0x9343, 0x9344, 0x9345, 0x9346, 0x9347, 0x9348, 0x9349, 0x934a,
+ 0x934b, 0x934c, 0x934d, 0x934e, 0x934f, 0x9350, 0x9351, 0x9352,
+ 0x9353, 0x9354, 0x9355, 0x9356, 0x9357, 0x9358, 0x9359, 0x935a,
+ 0x935b, 0x935c, 0x935d, 0x935e, 0x935f, 0x9360, 0x9361, 0x9362,
+ 0x9363, 0x9364, 0x9365, 0x9366, 0x9367, 0x9368, 0x9369, 0x936b,
+ /* 0xe6 */
+ 0x936c, 0x936d, 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373,
+ 0x9374, 0x9375, 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b,
+ 0x937c, 0x937d, 0x937e, 0x937f, 0x9380, 0x9381, 0x9382, 0x9383,
+ 0x9384, 0x9385, 0x9386, 0x9387, 0x9388, 0x9389, 0x938a, 0x938b,
+ 0x938c, 0x938d, 0x938e, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394,
+ 0x9395, 0x9396, 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c,
+ 0x939d, 0x939e, 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4,
+ 0x93a5, 0x93a6, 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac,
+ 0x93ad, 0x93ae, 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4,
+ 0x93b5, 0x93b6, 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc,
+ 0x93bd, 0x93be, 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4,
+ 0x93c5, 0x93c6, 0x93c7, 0x93c8, 0x93c9, 0x93cb, 0x93cc, 0x93cd,
+ /* 0xe7 */
+ 0x93ce, 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5,
+ 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de,
+ 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6,
+ 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee,
+ 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6,
+ 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe,
+ 0x93ff, 0x9400, 0x9401, 0x9402, 0x9403, 0x9404, 0x9405, 0x9406,
+ 0x9407, 0x9408, 0x9409, 0x940a, 0x940b, 0x940c, 0x940d, 0x940e,
+ 0x940f, 0x9410, 0x9411, 0x9412, 0x9413, 0x9414, 0x9415, 0x9416,
+ 0x9417, 0x9418, 0x9419, 0x941a, 0x941b, 0x941c, 0x941d, 0x941e,
+ 0x941f, 0x9420, 0x9421, 0x9422, 0x9423, 0x9424, 0x9425, 0x9426,
+ 0x9427, 0x9428, 0x9429, 0x942a, 0x942b, 0x942c, 0x942d, 0x942e,
+ /* 0xe8 */
+ 0x942f, 0x9430, 0x9431, 0x9432, 0x9433, 0x9434, 0x9435, 0x9436,
+ 0x9437, 0x9438, 0x9439, 0x943a, 0x943b, 0x943c, 0x943d, 0x943f,
+ 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447,
+ 0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f,
+ 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457,
+ 0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f,
+ 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467,
+ 0x9468, 0x9469, 0x946a, 0x946c, 0x946d, 0x946e, 0x946f, 0x9470,
+ 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, 0x9478,
+ 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x947f, 0x9480,
+ 0x9481, 0x9482, 0x9483, 0x9484, 0x9491, 0x9496, 0x9498, 0x94c7,
+ 0x94cf, 0x94d3, 0x94d4, 0x94da, 0x94e6, 0x94fb, 0x951c, 0x9520,
+ /* 0xe9 */
+ 0x9527, 0x9533, 0x953d, 0x9543, 0x9548, 0x954b, 0x9555, 0x955a,
+ 0x9560, 0x956e, 0x9574, 0x9575, 0x9577, 0x9578, 0x9579, 0x957a,
+ 0x957b, 0x957c, 0x957d, 0x957e, 0x9580, 0x9581, 0x9582, 0x9583,
+ 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958a, 0x958b,
+ 0x958c, 0x958d, 0x958e, 0x958f, 0x9590, 0x9591, 0x9592, 0x9593,
+ 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959a, 0x959b,
+ 0x959c, 0x959d, 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2, 0x95a3,
+ 0x95a4, 0x95a5, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa, 0x95ab,
+ 0x95ac, 0x95ad, 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2, 0x95b3,
+ 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba, 0x95bb,
+ 0x95bc, 0x95bd, 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2, 0x95c3,
+ 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca, 0x95cb,
+ /* 0xea */
+ 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2, 0x95d3,
+ 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da, 0x95db,
+ 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, 0x95e3,
+ 0x95e4, 0x95e5, 0x95e6, 0x95e7, 0x95ec, 0x95ff, 0x9607, 0x9613,
+ 0x9618, 0x961b, 0x961e, 0x9620, 0x9623, 0x9624, 0x9625, 0x9626,
+ 0x9627, 0x9628, 0x9629, 0x962b, 0x962c, 0x962d, 0x962f, 0x9630,
+ 0x9637, 0x9638, 0x9639, 0x963a, 0x963e, 0x9641, 0x9643, 0x964a,
+ 0x964e, 0x964f, 0x9651, 0x9652, 0x9653, 0x9656, 0x9657, 0x9658,
+ 0x9659, 0x965a, 0x965c, 0x965d, 0x965e, 0x9660, 0x9663, 0x9665,
+ 0x9666, 0x966b, 0x966d, 0x966e, 0x966f, 0x9670, 0x9671, 0x9673,
+ 0x9678, 0x9679, 0x967a, 0x967b, 0x967c, 0x967d, 0x967e, 0x967f,
+ 0x9680, 0x9681, 0x9682, 0x9683, 0x9684, 0x9687, 0x9689, 0x968a,
+ /* 0xeb */
+ 0x968c, 0x968e, 0x9691, 0x9692, 0x9693, 0x9695, 0x9696, 0x969a,
+ 0x969b, 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1, 0x96a2, 0x96a3,
+ 0x96a4, 0x96a5, 0x96a6, 0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac,
+ 0x96ad, 0x96ae, 0x96af, 0x96b1, 0x96b2, 0x96b4, 0x96b5, 0x96b7,
+ 0x96b8, 0x96ba, 0x96bb, 0x96bf, 0x96c2, 0x96c3, 0x96c8, 0x96ca,
+ 0x96cb, 0x96d0, 0x96d1, 0x96d3, 0x96d4, 0x96d6, 0x96d7, 0x96d8,
+ 0x96d9, 0x96da, 0x96db, 0x96dc, 0x96dd, 0x96de, 0x96df, 0x96e1,
+ 0x96e2, 0x96e3, 0x96e4, 0x96e5, 0x96e6, 0x96e7, 0x96eb, 0x96ec,
+ 0x96ed, 0x96ee, 0x96f0, 0x96f1, 0x96f2, 0x96f4, 0x96f5, 0x96f8,
+ 0x96fa, 0x96fb, 0x96fc, 0x96fd, 0x96ff, 0x9702, 0x9703, 0x9705,
+ 0x970a, 0x970b, 0x970c, 0x9710, 0x9711, 0x9712, 0x9714, 0x9715,
+ 0x9717, 0x9718, 0x9719, 0x971a, 0x971b, 0x971d, 0x971f, 0x9720,
+ /* 0xec */
+ 0x9721, 0x9722, 0x9723, 0x9724, 0x9725, 0x9726, 0x9727, 0x9728,
+ 0x9729, 0x972b, 0x972c, 0x972e, 0x972f, 0x9731, 0x9733, 0x9734,
+ 0x9735, 0x9736, 0x9737, 0x973a, 0x973b, 0x973c, 0x973d, 0x973f,
+ 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, 0x9746, 0x9747,
+ 0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d, 0x974e, 0x974f,
+ 0x9750, 0x9751, 0x9754, 0x9755, 0x9757, 0x9758, 0x975a, 0x975c,
+ 0x975d, 0x975f, 0x9763, 0x9764, 0x9766, 0x9767, 0x9768, 0x976a,
+ 0x976b, 0x976c, 0x976d, 0x976e, 0x976f, 0x9770, 0x9771, 0x9772,
+ 0x9775, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977d, 0x977e,
+ 0x977f, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9786, 0x9787,
+ 0x9788, 0x9789, 0x978a, 0x978c, 0x978e, 0x978f, 0x9790, 0x9793,
+ 0x9795, 0x9796, 0x9797, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d,
+ /* 0xed */
+ 0x979e, 0x979f, 0x97a1, 0x97a2, 0x97a4, 0x97a5, 0x97a6, 0x97a7,
+ 0x97a8, 0x97a9, 0x97aa, 0x97ac, 0x97ae, 0x97b0, 0x97b1, 0x97b3,
+ 0x97b5, 0x97b6, 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc,
+ 0x97bd, 0x97be, 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4,
+ 0x97c5, 0x97c6, 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc,
+ 0x97cd, 0x97ce, 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4,
+ 0x97d5, 0x97d6, 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc,
+ 0x97dd, 0x97de, 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4,
+ 0x97e5, 0x97e8, 0x97ee, 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f4,
+ 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe,
+ 0x97ff, 0x9800, 0x9801, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806,
+ 0x9807, 0x9808, 0x9809, 0x980a, 0x980b, 0x980c, 0x980d, 0x980e,
+ /* 0xee */
+ 0x980f, 0x9810, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816,
+ 0x9817, 0x9818, 0x9819, 0x981a, 0x981b, 0x981c, 0x981d, 0x981e,
+ 0x981f, 0x9820, 0x9821, 0x9822, 0x9823, 0x9824, 0x9825, 0x9826,
+ 0x9827, 0x9828, 0x9829, 0x982a, 0x982b, 0x982c, 0x982d, 0x982e,
+ 0x982f, 0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 0x9835, 0x9836,
+ 0x9837, 0x9838, 0x9839, 0x983a, 0x983b, 0x983c, 0x983d, 0x983e,
+ 0x983f, 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846,
+ 0x9847, 0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e,
+ 0x984f, 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856,
+ 0x9857, 0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e,
+ 0x985f, 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866,
+ 0x9867, 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e,
+ /* 0xef */
+ 0x986f, 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x988b, 0x988e,
+ 0x9892, 0x9895, 0x9899, 0x98a3, 0x98a8, 0x98a9, 0x98aa, 0x98ab,
+ 0x98ac, 0x98ad, 0x98ae, 0x98af, 0x98b0, 0x98b1, 0x98b2, 0x98b3,
+ 0x98b4, 0x98b5, 0x98b6, 0x98b7, 0x98b8, 0x98b9, 0x98ba, 0x98bb,
+ 0x98bc, 0x98bd, 0x98be, 0x98bf, 0x98c0, 0x98c1, 0x98c2, 0x98c3,
+ 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8, 0x98c9, 0x98ca, 0x98cb,
+ 0x98cc, 0x98cd, 0x98cf, 0x98d0, 0x98d4, 0x98d6, 0x98d7, 0x98db,
+ 0x98dc, 0x98dd, 0x98e0, 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5,
+ 0x98e6, 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef,
+ 0x98f0, 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7,
+ 0x98f8, 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x98ff,
+ 0x9900, 0x9901, 0x9902, 0x9903, 0x9904, 0x9905, 0x9906, 0x9907,
+ /* 0xf0 */
+ 0x9908, 0x9909, 0x990a, 0x990b, 0x990c, 0x990e, 0x990f, 0x9911,
+ 0x9912, 0x9913, 0x9914, 0x9915, 0x9916, 0x9917, 0x9918, 0x9919,
+ 0x991a, 0x991b, 0x991c, 0x991d, 0x991e, 0x991f, 0x9920, 0x9921,
+ 0x9922, 0x9923, 0x9924, 0x9925, 0x9926, 0x9927, 0x9928, 0x9929,
+ 0x992a, 0x992b, 0x992c, 0x992d, 0x992f, 0x9930, 0x9931, 0x9932,
+ 0x9933, 0x9934, 0x9935, 0x9936, 0x9937, 0x9938, 0x9939, 0x993a,
+ 0x993b, 0x993c, 0x993d, 0x993e, 0x993f, 0x9940, 0x9941, 0x9942,
+ 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949, 0x994a,
+ 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951, 0x9952,
+ 0x9953, 0x9956, 0x9957, 0x9958, 0x9959, 0x995a, 0x995b, 0x995c,
+ 0x995d, 0x995e, 0x995f, 0x9960, 0x9961, 0x9962, 0x9964, 0x9966,
+ 0x9973, 0x9978, 0x9979, 0x997b, 0x997e, 0x9982, 0x9983, 0x9989,
+ /* 0xf1 */
+ 0x998c, 0x998e, 0x999a, 0x999b, 0x999c, 0x999d, 0x999e, 0x999f,
+ 0x99a0, 0x99a1, 0x99a2, 0x99a3, 0x99a4, 0x99a6, 0x99a7, 0x99a9,
+ 0x99aa, 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0, 0x99b1,
+ 0x99b2, 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8, 0x99b9,
+ 0x99ba, 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0, 0x99c1,
+ 0x99c2, 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8, 0x99c9,
+ 0x99ca, 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0, 0x99d1,
+ 0x99d2, 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8, 0x99d9,
+ 0x99da, 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0, 0x99e1,
+ 0x99e2, 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8, 0x99e9,
+ 0x99ea, 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0, 0x99f1,
+ 0x99f2, 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8, 0x99f9,
+ /* 0xf2 */
+ 0x99fa, 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x99ff, 0x9a00, 0x9a01,
+ 0x9a02, 0x9a03, 0x9a04, 0x9a05, 0x9a06, 0x9a07, 0x9a08, 0x9a09,
+ 0x9a0a, 0x9a0b, 0x9a0c, 0x9a0d, 0x9a0e, 0x9a0f, 0x9a10, 0x9a11,
+ 0x9a12, 0x9a13, 0x9a14, 0x9a15, 0x9a16, 0x9a17, 0x9a18, 0x9a19,
+ 0x9a1a, 0x9a1b, 0x9a1c, 0x9a1d, 0x9a1e, 0x9a1f, 0x9a20, 0x9a21,
+ 0x9a22, 0x9a23, 0x9a24, 0x9a25, 0x9a26, 0x9a27, 0x9a28, 0x9a29,
+ 0x9a2a, 0x9a2b, 0x9a2c, 0x9a2d, 0x9a2e, 0x9a2f, 0x9a30, 0x9a31,
+ 0x9a32, 0x9a33, 0x9a34, 0x9a35, 0x9a36, 0x9a37, 0x9a38, 0x9a39,
+ 0x9a3a, 0x9a3b, 0x9a3c, 0x9a3d, 0x9a3e, 0x9a3f, 0x9a40, 0x9a41,
+ 0x9a42, 0x9a43, 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49,
+ 0x9a4a, 0x9a4b, 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51,
+ 0x9a52, 0x9a53, 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59,
+ /* 0xf3 */
+ 0x9a5a, 0x9a5b, 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61,
+ 0x9a62, 0x9a63, 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69,
+ 0x9a6a, 0x9a6b, 0x9a72, 0x9a83, 0x9a89, 0x9a8d, 0x9a8e, 0x9a94,
+ 0x9a95, 0x9a99, 0x9aa6, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac, 0x9aad,
+ 0x9aae, 0x9aaf, 0x9ab2, 0x9ab3, 0x9ab4, 0x9ab5, 0x9ab9, 0x9abb,
+ 0x9abd, 0x9abe, 0x9abf, 0x9ac3, 0x9ac4, 0x9ac6, 0x9ac7, 0x9ac8,
+ 0x9ac9, 0x9aca, 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad2, 0x9ad4,
+ 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad9, 0x9ada, 0x9adb, 0x9adc, 0x9add,
+ 0x9ade, 0x9ae0, 0x9ae2, 0x9ae3, 0x9ae4, 0x9ae5, 0x9ae7, 0x9ae8,
+ 0x9ae9, 0x9aea, 0x9aec, 0x9aee, 0x9af0, 0x9af1, 0x9af2, 0x9af3,
+ 0x9af4, 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9afa, 0x9afc, 0x9afd,
+ 0x9afe, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b04, 0x9b05, 0x9b06,
+ /* 0xf4 */
+ 0x9b07, 0x9b09, 0x9b0a, 0x9b0b, 0x9b0c, 0x9b0d, 0x9b0e, 0x9b10,
+ 0x9b11, 0x9b12, 0x9b14, 0x9b15, 0x9b16, 0x9b17, 0x9b18, 0x9b19,
+ 0x9b1a, 0x9b1b, 0x9b1c, 0x9b1d, 0x9b1e, 0x9b20, 0x9b21, 0x9b22,
+ 0x9b24, 0x9b25, 0x9b26, 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2b,
+ 0x9b2c, 0x9b2d, 0x9b2e, 0x9b30, 0x9b31, 0x9b33, 0x9b34, 0x9b35,
+ 0x9b36, 0x9b37, 0x9b38, 0x9b39, 0x9b3a, 0x9b3d, 0x9b3e, 0x9b3f,
+ 0x9b40, 0x9b46, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4e, 0x9b50, 0x9b52,
+ 0x9b53, 0x9b55, 0x9b56, 0x9b57, 0x9b58, 0x9b59, 0x9b5a, 0x9b5b,
+ 0x9b5c, 0x9b5d, 0x9b5e, 0x9b5f, 0x9b60, 0x9b61, 0x9b62, 0x9b63,
+ 0x9b64, 0x9b65, 0x9b66, 0x9b67, 0x9b68, 0x9b69, 0x9b6a, 0x9b6b,
+ 0x9b6c, 0x9b6d, 0x9b6e, 0x9b6f, 0x9b70, 0x9b71, 0x9b72, 0x9b73,
+ 0x9b74, 0x9b75, 0x9b76, 0x9b77, 0x9b78, 0x9b79, 0x9b7a, 0x9b7b,
+ /* 0xf5 */
+ 0x9b7c, 0x9b7d, 0x9b7e, 0x9b7f, 0x9b80, 0x9b81, 0x9b82, 0x9b83,
+ 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b88, 0x9b89, 0x9b8a, 0x9b8b,
+ 0x9b8c, 0x9b8d, 0x9b8e, 0x9b8f, 0x9b90, 0x9b91, 0x9b92, 0x9b93,
+ 0x9b94, 0x9b95, 0x9b96, 0x9b97, 0x9b98, 0x9b99, 0x9b9a, 0x9b9b,
+ 0x9b9c, 0x9b9d, 0x9b9e, 0x9b9f, 0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3,
+ 0x9ba4, 0x9ba5, 0x9ba6, 0x9ba7, 0x9ba8, 0x9ba9, 0x9baa, 0x9bab,
+ 0x9bac, 0x9bad, 0x9bae, 0x9baf, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3,
+ 0x9bb4, 0x9bb5, 0x9bb6, 0x9bb7, 0x9bb8, 0x9bb9, 0x9bba, 0x9bbb,
+ 0x9bbc, 0x9bbd, 0x9bbe, 0x9bbf, 0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3,
+ 0x9bc4, 0x9bc5, 0x9bc6, 0x9bc7, 0x9bc8, 0x9bc9, 0x9bca, 0x9bcb,
+ 0x9bcc, 0x9bcd, 0x9bce, 0x9bcf, 0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3,
+ 0x9bd4, 0x9bd5, 0x9bd6, 0x9bd7, 0x9bd8, 0x9bd9, 0x9bda, 0x9bdb,
+ /* 0xf6 */
+ 0x9bdc, 0x9bdd, 0x9bde, 0x9bdf, 0x9be0, 0x9be1, 0x9be2, 0x9be3,
+ 0x9be4, 0x9be5, 0x9be6, 0x9be7, 0x9be8, 0x9be9, 0x9bea, 0x9beb,
+ 0x9bec, 0x9bed, 0x9bee, 0x9bef, 0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3,
+ 0x9bf4, 0x9bf5, 0x9bf6, 0x9bf7, 0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb,
+ 0x9bfc, 0x9bfd, 0x9bfe, 0x9bff, 0x9c00, 0x9c01, 0x9c02, 0x9c03,
+ 0x9c04, 0x9c05, 0x9c06, 0x9c07, 0x9c08, 0x9c09, 0x9c0a, 0x9c0b,
+ 0x9c0c, 0x9c0d, 0x9c0e, 0x9c0f, 0x9c10, 0x9c11, 0x9c12, 0x9c13,
+ 0x9c14, 0x9c15, 0x9c16, 0x9c17, 0x9c18, 0x9c19, 0x9c1a, 0x9c1b,
+ 0x9c1c, 0x9c1d, 0x9c1e, 0x9c1f, 0x9c20, 0x9c21, 0x9c22, 0x9c23,
+ 0x9c24, 0x9c25, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c2b,
+ 0x9c2c, 0x9c2d, 0x9c2e, 0x9c2f, 0x9c30, 0x9c31, 0x9c32, 0x9c33,
+ 0x9c34, 0x9c35, 0x9c36, 0x9c37, 0x9c38, 0x9c39, 0x9c3a, 0x9c3b,
+ /* 0xf7 */
+ 0x9c3c, 0x9c3d, 0x9c3e, 0x9c3f, 0x9c40, 0x9c41, 0x9c42, 0x9c43,
+ 0x9c44, 0x9c45, 0x9c46, 0x9c47, 0x9c48, 0x9c49, 0x9c4a, 0x9c4b,
+ 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f, 0x9c50, 0x9c51, 0x9c52, 0x9c53,
+ 0x9c54, 0x9c55, 0x9c56, 0x9c57, 0x9c58, 0x9c59, 0x9c5a, 0x9c5b,
+ 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c60, 0x9c61, 0x9c62, 0x9c63,
+ 0x9c64, 0x9c65, 0x9c66, 0x9c67, 0x9c68, 0x9c69, 0x9c6a, 0x9c6b,
+ 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f, 0x9c70, 0x9c71, 0x9c72, 0x9c73,
+ 0x9c74, 0x9c75, 0x9c76, 0x9c77, 0x9c78, 0x9c79, 0x9c7a, 0x9c7b,
+ 0x9c7d, 0x9c7e, 0x9c80, 0x9c83, 0x9c84, 0x9c89, 0x9c8a, 0x9c8c,
+ 0x9c8f, 0x9c93, 0x9c96, 0x9c97, 0x9c98, 0x9c99, 0x9c9d, 0x9caa,
+ 0x9cac, 0x9caf, 0x9cb9, 0x9cbe, 0x9cbf, 0x9cc0, 0x9cc1, 0x9cc2,
+ 0x9cc8, 0x9cc9, 0x9cd1, 0x9cd2, 0x9cda, 0x9cdb, 0x9ce0, 0x9ce1,
+ /* 0xf8 */
+ 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8, 0x9ce9, 0x9cea,
+ 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 0x9cf0, 0x9cf1, 0x9cf2,
+ 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8, 0x9cf9, 0x9cfa,
+ 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9cff, 0x9d00, 0x9d01, 0x9d02,
+ 0x9d03, 0x9d04, 0x9d05, 0x9d06, 0x9d07, 0x9d08, 0x9d09, 0x9d0a,
+ 0x9d0b, 0x9d0c, 0x9d0d, 0x9d0e, 0x9d0f, 0x9d10, 0x9d11, 0x9d12,
+ 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17, 0x9d18, 0x9d19, 0x9d1a,
+ 0x9d1b, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d1f, 0x9d20, 0x9d21, 0x9d22,
+ 0x9d23, 0x9d24, 0x9d25, 0x9d26, 0x9d27, 0x9d28, 0x9d29, 0x9d2a,
+ 0x9d2b, 0x9d2c, 0x9d2d, 0x9d2e, 0x9d2f, 0x9d30, 0x9d31, 0x9d32,
+ 0x9d33, 0x9d34, 0x9d35, 0x9d36, 0x9d37, 0x9d38, 0x9d39, 0x9d3a,
+ 0x9d3b, 0x9d3c, 0x9d3d, 0x9d3e, 0x9d3f, 0x9d40, 0x9d41, 0x9d42,
+ /* 0xf9 */
+ 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 0x9d48, 0x9d49, 0x9d4a,
+ 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 0x9d50, 0x9d51, 0x9d52,
+ 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59, 0x9d5a,
+ 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 0x9d60, 0x9d61, 0x9d62,
+ 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 0x9d68, 0x9d69, 0x9d6a,
+ 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 0x9d70, 0x9d71, 0x9d72,
+ 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79, 0x9d7a,
+ 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d7f, 0x9d80, 0x9d81, 0x9d82,
+ 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88, 0x9d89, 0x9d8a,
+ 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, 0x9d91, 0x9d92,
+ 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9d99, 0x9d9a,
+ 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0x9da1, 0x9da2,
+ /* 0xfa */
+ 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8, 0x9da9, 0x9daa,
+ 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0x9db1, 0x9db2,
+ 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8, 0x9db9, 0x9dba,
+ 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2,
+ 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca,
+ 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2,
+ 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8, 0x9dd9, 0x9dda,
+ 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, 0x9de1, 0x9de2,
+ 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8, 0x9de9, 0x9dea,
+ 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0, 0x9df1, 0x9df2,
+ 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0x9dfa,
+ 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9dff, 0x9e00, 0x9e01, 0x9e02,
+ /* 0xfb */
+ 0x9e03, 0x9e04, 0x9e05, 0x9e06, 0x9e07, 0x9e08, 0x9e09, 0x9e0a,
+ 0x9e0b, 0x9e0c, 0x9e0d, 0x9e0e, 0x9e0f, 0x9e10, 0x9e11, 0x9e12,
+ 0x9e13, 0x9e14, 0x9e15, 0x9e16, 0x9e17, 0x9e18, 0x9e19, 0x9e1a,
+ 0x9e1b, 0x9e1c, 0x9e1d, 0x9e1e, 0x9e24, 0x9e27, 0x9e2e, 0x9e30,
+ 0x9e34, 0x9e3b, 0x9e3c, 0x9e40, 0x9e4d, 0x9e50, 0x9e52, 0x9e53,
+ 0x9e54, 0x9e56, 0x9e59, 0x9e5d, 0x9e5f, 0x9e60, 0x9e61, 0x9e62,
+ 0x9e65, 0x9e6e, 0x9e6f, 0x9e72, 0x9e74, 0x9e75, 0x9e76, 0x9e77,
+ 0x9e78, 0x9e79, 0x9e7a, 0x9e7b, 0x9e7c, 0x9e7d, 0x9e80, 0x9e81,
+ 0x9e83, 0x9e84, 0x9e85, 0x9e86, 0x9e89, 0x9e8a, 0x9e8c, 0x9e8d,
+ 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e94, 0x9e95, 0x9e96, 0x9e97,
+ 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c, 0x9e9e, 0x9ea0, 0x9ea1,
+ 0x9ea2, 0x9ea3, 0x9ea4, 0x9ea5, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa,
+ /* 0xfc */
+ 0x9eab, 0x9eac, 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2,
+ 0x9eb3, 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb9, 0x9eba, 0x9ebc, 0x9ebf,
+ 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8,
+ 0x9eca, 0x9ecb, 0x9ecc, 0x9ed0, 0x9ed2, 0x9ed3, 0x9ed5, 0x9ed6,
+ 0x9ed7, 0x9ed9, 0x9eda, 0x9ede, 0x9ee1, 0x9ee3, 0x9ee4, 0x9ee6,
+ 0x9ee8, 0x9eeb, 0x9eec, 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2,
+ 0x9ef3, 0x9ef4, 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9efa, 0x9efd,
+ 0x9eff, 0x9f00, 0x9f01, 0x9f02, 0x9f03, 0x9f04, 0x9f05, 0x9f06,
+ 0x9f07, 0x9f08, 0x9f09, 0x9f0a, 0x9f0c, 0x9f0f, 0x9f11, 0x9f12,
+ 0x9f14, 0x9f15, 0x9f16, 0x9f18, 0x9f1a, 0x9f1b, 0x9f1c, 0x9f1d,
+ 0x9f1e, 0x9f1f, 0x9f21, 0x9f23, 0x9f24, 0x9f25, 0x9f26, 0x9f27,
+ 0x9f28, 0x9f29, 0x9f2a, 0x9f2b, 0x9f2d, 0x9f2e, 0x9f30, 0x9f31,
+ /* 0xfd */
+ 0x9f32, 0x9f33, 0x9f34, 0x9f35, 0x9f36, 0x9f38, 0x9f3a, 0x9f3c,
+ 0x9f3f, 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f45, 0x9f46, 0x9f47,
+ 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, 0x9f4e, 0x9f4f,
+ 0x9f52, 0x9f53, 0x9f54, 0x9f55, 0x9f56, 0x9f57, 0x9f58, 0x9f59,
+ 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, 0x9f5e, 0x9f5f, 0x9f60, 0x9f61,
+ 0x9f62, 0x9f63, 0x9f64, 0x9f65, 0x9f66, 0x9f67, 0x9f68, 0x9f69,
+ 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, 0x9f6e, 0x9f6f, 0x9f70, 0x9f71,
+ 0x9f72, 0x9f73, 0x9f74, 0x9f75, 0x9f76, 0x9f77, 0x9f78, 0x9f79,
+ 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d, 0x9f7e, 0x9f81, 0x9f82, 0x9f8d,
+ 0x9f8e, 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95,
+ 0x9f96, 0x9f97, 0x9f98, 0x9f9c, 0x9f9d, 0x9f9e, 0x9fa1, 0x9fa2,
+ 0x9fa3, 0x9fa4, 0x9fa5, 0xf92c, 0xf979, 0xf995, 0xf9e7, 0xf9f1,
+ /* 0xfe */
+ 0xfa0c, 0xfa0d, 0xfa0e, 0xfa0f, 0xfa11, 0xfa13, 0xfa14, 0xfa18,
+ 0xfa1f, 0xfa20, 0xfa21, 0xfa23, 0xfa24, 0xfa27, 0xfa28, 0xfa29,
+};
+
+static const unsigned short gbkext_inv_2charset[14313] = {
+ 0xa840, 0xa841, 0xa842, 0xa95c, 0xa843, 0xa844, 0xa845, 0xa846,
+ 0xa847, 0xa848, 0xa959, 0xa849, 0xa84a, 0xa84b, 0xa84c, 0xa84d,
+ 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa892, 0xa853, 0xa854,
+ 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c,
+ 0xa85d, 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864,
+ 0xa865, 0xa866, 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c,
+ 0xa86d, 0xa86e, 0xa86f, 0xa870, 0xa871, 0xa872, 0xa873, 0xa874,
+ 0xa875, 0xa876, 0xa877, 0xa878, 0xa879, 0xa87a, 0xa87b, 0xa87c,
+ 0xa87d, 0xa87e, 0xa880, 0xa881, 0xa882, 0xa883, 0xa884, 0xa885,
+ 0xa886, 0xa887, 0xa888, 0xa889, 0xa88a, 0xa88b, 0xa88c, 0xa88d,
+ 0xa88e, 0xa88f, 0xa890, 0xa891, 0xa965, 0xa996, 0xa893, 0xa894,
+ 0xa895, 0xa940, 0xa941, 0xa942, 0xa943, 0xa944, 0xa945, 0xa946,
+ 0xa947, 0xa948, 0xa961, 0xa962, 0xa966, 0xa967, 0xa960, 0xa963,
+ 0xa964, 0xa95a, 0xa949, 0xa94a, 0xa94b, 0xa94c, 0xa94d, 0xa94e,
+ 0xa94f, 0xa950, 0xa951, 0xa952, 0xa953, 0xa954, 0x8140, 0x8141,
+ 0x8142, 0x8143, 0x8144, 0x8145, 0x8146, 0x8147, 0x8148, 0x8149,
+ 0x814a, 0x814b, 0x814c, 0x814d, 0x814e, 0x814f, 0x8150, 0x8151,
+ 0x8152, 0x8153, 0x8154, 0x8155, 0x8156, 0x8157, 0x8158, 0x8159,
+ 0x815a, 0x815b, 0x815c, 0x815d, 0x815e, 0x815f, 0x8160, 0x8161,
+ 0x8162, 0x8163, 0x8164, 0x8165, 0x8166, 0x8167, 0x8168, 0x8169,
+ 0x816a, 0x816b, 0x816c, 0x816d, 0x816e, 0x816f, 0x8170, 0x8171,
+ 0x8172, 0x8173, 0x8174, 0x8175, 0x8176, 0x8177, 0x8178, 0x8179,
+ 0x817a, 0x817b, 0x817c, 0x817d, 0x817e, 0x8180, 0x8181, 0x8182,
+ 0x8183, 0x8184, 0x8185, 0x8186, 0x8187, 0x8188, 0x8189, 0x818a,
+ 0x818b, 0x818c, 0x818d, 0x818e, 0x818f, 0x8190, 0x8191, 0x8192,
+ 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8198, 0x8199, 0x819a,
+ 0x819b, 0x819c, 0x819d, 0x819e, 0x819f, 0x81a0, 0x81a1, 0x81a2,
+ 0x81a3, 0x81a4, 0x81a5, 0x81a6, 0x81a7, 0x81a8, 0x81a9, 0x81aa,
+ 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, 0x81b2,
+ 0x81b3, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81ba,
+ 0x81bb, 0x81bc, 0x81bd, 0x81be, 0x81bf, 0x81c0, 0x81c1, 0x81c2,
+ 0x81c3, 0x81c4, 0x81c5, 0x81c6, 0x81c7, 0x81c8, 0x81c9, 0x81ca,
+ 0x81cb, 0x81cc, 0x81cd, 0x81ce, 0x81cf, 0x81d0, 0x81d1, 0x81d2,
+ 0x81d3, 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 0x81d9, 0x81da,
+ 0x81db, 0x81dc, 0x81dd, 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2,
+ 0x81e3, 0x81e4, 0x81e5, 0x81e6, 0x81e7, 0x81e8, 0x81e9, 0x81ea,
+ 0x81eb, 0x81ec, 0x81ed, 0x81ee, 0x81ef, 0x81f0, 0x81f1, 0x81f2,
+ 0x81f3, 0x81f4, 0x81f5, 0x81f6, 0x81f7, 0x81f8, 0x81f9, 0x81fa,
+ 0x81fb, 0x81fc, 0x81fd, 0x81fe, 0x8240, 0x8241, 0x8242, 0x8243,
+ 0x8244, 0x8245, 0x8246, 0x8247, 0x8248, 0x8249, 0x824a, 0x824b,
+ 0x824c, 0x824d, 0x824e, 0x824f, 0x8250, 0x8251, 0x8252, 0x8253,
+ 0x8254, 0x8255, 0x8256, 0x8257, 0x8258, 0x8259, 0x825a, 0x825b,
+ 0x825c, 0x825d, 0x825e, 0x825f, 0x8260, 0x8261, 0x8262, 0x8263,
+ 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, 0x8269, 0x826a, 0x826b,
+ 0x826c, 0x826d, 0x826e, 0x826f, 0x8270, 0x8271, 0x8272, 0x8273,
+ 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x827a, 0x827b,
+ 0x827c, 0x827d, 0x827e, 0x8280, 0x8281, 0x8282, 0x8283, 0x8284,
+ 0x8285, 0x8286, 0x8287, 0x8288, 0x8289, 0x828a, 0x828b, 0x828c,
+ 0x828d, 0x828e, 0x828f, 0x8290, 0x8291, 0x8292, 0x8293, 0x8294,
+ 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, 0x829a, 0x829b, 0x829c,
+ 0x829d, 0x829e, 0x829f, 0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4,
+ 0x82a5, 0x82a6, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ab, 0x82ac,
+ 0x82ad, 0x82ae, 0x82af, 0x82b0, 0x82b1, 0x82b2, 0x82b3, 0x82b4,
+ 0x82b5, 0x82b6, 0x82b7, 0x82b8, 0x82b9, 0x82ba, 0x82bb, 0x82bc,
+ 0x82bd, 0x82be, 0x82bf, 0x82c0, 0x82c1, 0x82c2, 0x82c3, 0x82c4,
+ 0x82c5, 0x82c6, 0x82c7, 0x82c8, 0x82c9, 0x82ca, 0x82cb, 0x82cc,
+ 0x82cd, 0x82ce, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0x82d3, 0x82d4,
+ 0x82d5, 0x82d6, 0x82d7, 0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dc,
+ 0x82dd, 0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e2, 0x82e3, 0x82e4,
+ 0x82e5, 0x82e6, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ec,
+ 0x82ed, 0x82ee, 0x82ef, 0x82f0, 0x82f1, 0x82f2, 0x82f3, 0x82f4,
+ 0x82f5, 0x82f6, 0x82f7, 0x82f8, 0x82f9, 0x82fa, 0x82fb, 0x82fc,
+ 0x82fd, 0x82fe, 0x8340, 0x8341, 0x8342, 0x8343, 0x8344, 0x8345,
+ 0x8346, 0x8347, 0x8348, 0x8349, 0x834a, 0x834b, 0x834c, 0x834d,
+ 0x834e, 0x834f, 0x8350, 0x8351, 0x8352, 0x8353, 0x8354, 0x8355,
+ 0x8356, 0x8357, 0x8358, 0x8359, 0x835a, 0x835b, 0x835c, 0x835d,
+ 0x835e, 0x835f, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365,
+ 0x8366, 0x8367, 0x8368, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d,
+ 0x836e, 0x836f, 0x8370, 0x8371, 0x8372, 0x8373, 0x8374, 0x8375,
+ 0x8376, 0x8377, 0x8378, 0x8379, 0x837a, 0x837b, 0x837c, 0x837d,
+ 0x837e, 0x8380, 0x8381, 0x8382, 0x8383, 0x8384, 0x8385, 0x8386,
+ 0x8387, 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838e,
+ 0x838f, 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, 0x8396,
+ 0x8397, 0x8398, 0x8399, 0x839a, 0x839b, 0x839c, 0x839d, 0x839e,
+ 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3, 0x83a4, 0x83a5, 0x83a6,
+ 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab, 0x83ac, 0x83ad, 0x83ae,
+ 0x83af, 0x83b0, 0x83b1, 0x83b2, 0x83b3, 0x83b4, 0x83b5, 0x83b6,
+ 0x83b7, 0x83b8, 0x83b9, 0x83ba, 0x83bb, 0x83bc, 0x83bd, 0x83be,
+ 0x83bf, 0x83c0, 0x83c1, 0x83c2, 0x83c3, 0x83c4, 0x83c5, 0x83c6,
+ 0x83c7, 0x83c8, 0x83c9, 0x83ca, 0x83cb, 0x83cc, 0x83cd, 0x83ce,
+ 0x83cf, 0x83d0, 0x83d1, 0x83d2, 0x83d3, 0x83d4, 0x83d5, 0x83d6,
+ 0x83d7, 0x83d8, 0x83d9, 0x83da, 0x83db, 0x83dc, 0x83dd, 0x83de,
+ 0x83df, 0x83e0, 0x83e1, 0x83e2, 0x83e3, 0x83e4, 0x83e5, 0x83e6,
+ 0x83e7, 0x83e8, 0x83e9, 0x83ea, 0x83eb, 0x83ec, 0x83ed, 0x83ee,
+ 0x83ef, 0x83f0, 0x83f1, 0x83f2, 0x83f3, 0x83f4, 0x83f5, 0x83f6,
+ 0x83f7, 0x83f8, 0x83f9, 0x83fa, 0x83fb, 0x83fc, 0x83fd, 0x83fe,
+ 0x8440, 0x8441, 0x8442, 0x8443, 0x8444, 0x8445, 0x8446, 0x8447,
+ 0x8448, 0x8449, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f,
+ 0x8450, 0x8451, 0x8452, 0x8453, 0x8454, 0x8455, 0x8456, 0x8457,
+ 0x8458, 0x8459, 0x845a, 0x845b, 0x845c, 0x845d, 0x845e, 0x845f,
+ 0x8460, 0x8461, 0x8462, 0x8463, 0x8464, 0x8465, 0x8466, 0x8467,
+ 0x8468, 0x8469, 0x846a, 0x846b, 0x846c, 0x846d, 0x846e, 0x846f,
+ 0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, 0x8476, 0x8477,
+ 0x8478, 0x8479, 0x847a, 0x847b, 0x847c, 0x847d, 0x847e, 0x8480,
+ 0x8481, 0x8482, 0x8483, 0x8484, 0x8485, 0x8486, 0x8487, 0x8488,
+ 0x8489, 0x848a, 0x848b, 0x848c, 0x848d, 0x848e, 0x848f, 0x8490,
+ 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, 0x8496, 0x8497, 0x8498,
+ 0x8499, 0x849a, 0x849b, 0x849c, 0x849d, 0x849e, 0x849f, 0x84a0,
+ 0x84a1, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, 0x84a8,
+ 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84af, 0x84b0,
+ 0x84b1, 0x84b2, 0x84b3, 0x84b4, 0x84b5, 0x84b6, 0x84b7, 0x84b8,
+ 0x84b9, 0x84ba, 0x84bb, 0x84bc, 0x84bd, 0x84be, 0x84bf, 0x84c0,
+ 0x84c1, 0x84c2, 0x84c3, 0x84c4, 0x84c5, 0x84c6, 0x84c7, 0x84c8,
+ 0x84c9, 0x84ca, 0x84cb, 0x84cc, 0x84cd, 0x84ce, 0x84cf, 0x84d0,
+ 0x84d1, 0x84d2, 0x84d3, 0x84d4, 0x84d5, 0x84d6, 0x84d7, 0x84d8,
+ 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84dd, 0x84de, 0x84df, 0x84e0,
+ 0x84e1, 0x84e2, 0x84e3, 0x84e4, 0x84e5, 0x84e6, 0x84e7, 0x84e8,
+ 0x84e9, 0x84ea, 0x84eb, 0x84ec, 0x84ed, 0x84ee, 0x84ef, 0x84f0,
+ 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 0x84f8,
+ 0x84f9, 0x84fa, 0x84fb, 0x84fc, 0x84fd, 0x84fe, 0x8540, 0x8541,
+ 0x8542, 0x8543, 0x8544, 0x8545, 0x8546, 0x8547, 0x8548, 0x8549,
+ 0x854a, 0x854b, 0x854c, 0x854d, 0x854e, 0x854f, 0x8550, 0x8551,
+ 0x8552, 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 0x8558, 0x8559,
+ 0x855a, 0x855b, 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561,
+ 0x8562, 0x8563, 0x8564, 0x8565, 0x8566, 0x8567, 0x8568, 0x8569,
+ 0x856a, 0x856b, 0x856c, 0x856d, 0x856e, 0x856f, 0x8570, 0x8571,
+ 0x8572, 0x8573, 0x8574, 0x8575, 0x8576, 0x8577, 0x8578, 0x8579,
+ 0x857a, 0x857b, 0x857c, 0x857d, 0x857e, 0x8580, 0x8581, 0x8582,
+ 0x8583, 0x8584, 0x8585, 0x8586, 0x8587, 0x8588, 0x8589, 0x858a,
+ 0x858b, 0x858c, 0x858d, 0x858e, 0x858f, 0x8590, 0x8591, 0x8592,
+ 0x8593, 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0x859a,
+ 0x859b, 0x859c, 0x859d, 0x859e, 0x859f, 0x85a0, 0x85a1, 0x85a2,
+ 0x85a3, 0x85a4, 0x85a5, 0x85a6, 0x85a7, 0x85a8, 0x85a9, 0x85aa,
+ 0x85ab, 0x85ac, 0x85ad, 0x85ae, 0x85af, 0x85b0, 0x85b1, 0x85b2,
+ 0x85b3, 0x85b4, 0x85b5, 0x85b6, 0x85b7, 0x85b8, 0x85b9, 0x85ba,
+ 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c0, 0x85c1, 0x85c2,
+ 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 0x85c8, 0x85c9, 0x85ca,
+ 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85cf, 0x85d0, 0x85d1, 0x85d2,
+ 0x85d3, 0x85d4, 0x85d5, 0x85d6, 0x85d7, 0x85d8, 0x85d9, 0x85da,
+ 0x85db, 0x85dc, 0x85dd, 0x85de, 0x85df, 0x85e0, 0x85e1, 0x85e2,
+ 0x85e3, 0x85e4, 0x85e5, 0x85e6, 0x85e7, 0x85e8, 0x85e9, 0x85ea,
+ 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 0x85f0, 0x85f1, 0x85f2,
+ 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 0x85f8, 0x85f9, 0x85fa,
+ 0x85fb, 0x85fc, 0x85fd, 0x85fe, 0x8640, 0x8641, 0x8642, 0x8643,
+ 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649, 0x864a, 0x864b,
+ 0x864c, 0x864d, 0x864e, 0x864f, 0x8650, 0x8651, 0x8652, 0x8653,
+ 0x8654, 0x8655, 0x8656, 0x8657, 0x8658, 0x8659, 0x865a, 0x865b,
+ 0x865c, 0x865d, 0x865e, 0x865f, 0x8660, 0x8661, 0x8662, 0x8663,
+ 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, 0x866a, 0x866b,
+ 0x866c, 0x866d, 0x866e, 0x866f, 0x8670, 0x8671, 0x8672, 0x8673,
+ 0x8674, 0x8675, 0x8676, 0x8677, 0x8678, 0x8679, 0x867a, 0x867b,
+ 0x867c, 0x867d, 0x867e, 0x8680, 0x8681, 0x8682, 0x8683, 0x8684,
+ 0x8685, 0x8686, 0x8687, 0x8688, 0x8689, 0x868a, 0x868b, 0x868c,
+ 0x868d, 0x868e, 0x868f, 0x8690, 0x8691, 0x8692, 0x8693, 0x8694,
+ 0x8695, 0x8696, 0x8697, 0x8698, 0x8699, 0x869a, 0x869b, 0x869c,
+ 0x869d, 0x869e, 0x869f, 0x86a0, 0x86a1, 0x86a2, 0x86a3, 0x86a4,
+ 0x86a5, 0x86a6, 0x86a7, 0x86a8, 0x86a9, 0x86aa, 0x86ab, 0x86ac,
+ 0x86ad, 0x86ae, 0x86af, 0x86b0, 0x86b1, 0x86b2, 0x86b3, 0x86b4,
+ 0x86b5, 0x86b6, 0x86b7, 0x86b8, 0x86b9, 0x86ba, 0x86bb, 0x86bc,
+ 0x86bd, 0x86be, 0x86bf, 0x86c0, 0x86c1, 0x86c2, 0x86c3, 0x86c4,
+ 0x86c5, 0x86c6, 0x86c7, 0x86c8, 0x86c9, 0x86ca, 0x86cb, 0x86cc,
+ 0x86cd, 0x86ce, 0x86cf, 0x86d0, 0x86d1, 0x86d2, 0x86d3, 0x86d4,
+ 0x86d5, 0x86d6, 0x86d7, 0x86d8, 0x86d9, 0x86da, 0x86db, 0x86dc,
+ 0x86dd, 0x86de, 0x86df, 0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e4,
+ 0x86e5, 0x86e6, 0x86e7, 0x86e8, 0x86e9, 0x86ea, 0x86eb, 0x86ec,
+ 0x86ed, 0x86ee, 0x86ef, 0x86f0, 0x86f1, 0x86f2, 0x86f3, 0x86f4,
+ 0x86f5, 0x86f6, 0x86f7, 0x86f8, 0x86f9, 0x86fa, 0x86fb, 0x86fc,
+ 0x86fd, 0x86fe, 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745,
+ 0x8746, 0x8747, 0x8748, 0x8749, 0x874a, 0x874b, 0x874c, 0x874d,
+ 0x874e, 0x874f, 0x8750, 0x8751, 0x8752, 0x8753, 0x8754, 0x8755,
+ 0x8756, 0x8757, 0x8758, 0x8759, 0x875a, 0x875b, 0x875c, 0x875d,
+ 0x875e, 0x875f, 0x8760, 0x8761, 0x8762, 0x8763, 0x8764, 0x8765,
+ 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b, 0x876c, 0x876d,
+ 0x876e, 0x876f, 0x8770, 0x8771, 0x8772, 0x8773, 0x8774, 0x8775,
+ 0x8776, 0x8777, 0x8778, 0x8779, 0x877a, 0x877b, 0x877c, 0x877d,
+ 0x877e, 0x8780, 0x8781, 0x8782, 0x8783, 0x8784, 0x8785, 0x8786,
+ 0x8787, 0x8788, 0x8789, 0x878a, 0x878b, 0x878c, 0x878d, 0x878e,
+ 0x878f, 0x8790, 0x8791, 0x8792, 0x8793, 0x8794, 0x8795, 0x8796,
+ 0x8797, 0x8798, 0x8799, 0x879a, 0x879b, 0x879c, 0x879d, 0x879e,
+ 0x879f, 0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4, 0x87a5, 0x87a6,
+ 0x87a7, 0x87a8, 0x87a9, 0x87aa, 0x87ab, 0x87ac, 0x87ad, 0x87ae,
+ 0x87af, 0x87b0, 0x87b1, 0x87b2, 0x87b3, 0x87b4, 0x87b5, 0x87b6,
+ 0x87b7, 0x87b8, 0x87b9, 0x87ba, 0x87bb, 0x87bc, 0x87bd, 0x87be,
+ 0x87bf, 0x87c0, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c6,
+ 0x87c7, 0x87c8, 0x87c9, 0x87ca, 0x87cb, 0x87cc, 0x87cd, 0x87ce,
+ 0x87cf, 0x87d0, 0x87d1, 0x87d2, 0x87d3, 0x87d4, 0x87d5, 0x87d6,
+ 0x87d7, 0x87d8, 0x87d9, 0x87da, 0x87db, 0x87dc, 0x87dd, 0x87de,
+ 0x87df, 0x87e0, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e5, 0x87e6,
+ 0x87e7, 0x87e8, 0x87e9, 0x87ea, 0x87eb, 0x87ec, 0x87ed, 0x87ee,
+ 0x87ef, 0x87f0, 0x87f1, 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6,
+ 0x87f7, 0x87f8, 0x87f9, 0x87fa, 0x87fb, 0x87fc, 0x87fd, 0x87fe,
+ 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845, 0x8846, 0x8847,
+ 0x8848, 0x8849, 0x884a, 0x884b, 0x884c, 0x884d, 0x884e, 0x884f,
+ 0x8850, 0x8851, 0x8852, 0x8853, 0x8854, 0x8855, 0x8856, 0x8857,
+ 0x8858, 0x8859, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e, 0x885f,
+ 0x8860, 0x8861, 0x8862, 0x8863, 0x8864, 0x8865, 0x8866, 0x8867,
+ 0x8868, 0x8869, 0x886a, 0x886b, 0x886c, 0x886d, 0x886e, 0x886f,
+ 0x8870, 0x8871, 0x8872, 0x8873, 0x8874, 0x8875, 0x8876, 0x8877,
+ 0x8878, 0x8879, 0x887a, 0x887b, 0x887c, 0x887d, 0x887e, 0x8880,
+ 0x8881, 0x8882, 0x8883, 0x8884, 0x8885, 0x8886, 0x8887, 0x8888,
+ 0x8889, 0x888a, 0x888b, 0x888c, 0x888d, 0x888e, 0x888f, 0x8890,
+ 0x8891, 0x8892, 0x8893, 0x8894, 0x8895, 0x8896, 0x8897, 0x8898,
+ 0x8899, 0x889a, 0x889b, 0x889c, 0x889d, 0x889e, 0x889f, 0x88a0,
+ 0x88a1, 0x88a2, 0x88a3, 0x88a4, 0x88a5, 0x88a6, 0x88a7, 0x88a8,
+ 0x88a9, 0x88aa, 0x88ab, 0x88ac, 0x88ad, 0x88ae, 0x88af, 0x88b0,
+ 0x88b1, 0x88b2, 0x88b3, 0x88b4, 0x88b5, 0x88b6, 0x88b7, 0x88b8,
+ 0x88b9, 0x88ba, 0x88bb, 0x88bc, 0x88bd, 0x88be, 0x88bf, 0x88c0,
+ 0x88c1, 0x88c2, 0x88c3, 0x88c4, 0x88c5, 0x88c6, 0x88c7, 0x88c8,
+ 0x88c9, 0x88ca, 0x88cb, 0x88cc, 0x88cd, 0x88ce, 0x88cf, 0x88d0,
+ 0x88d1, 0x88d2, 0x88d3, 0x88d4, 0x88d5, 0x88d6, 0x88d7, 0x88d8,
+ 0x88d9, 0x88da, 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88df, 0x88e0,
+ 0x88e1, 0x88e2, 0x88e3, 0x88e4, 0x88e5, 0x88e6, 0x88e7, 0x88e8,
+ 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f0,
+ 0x88f1, 0x88f2, 0x88f3, 0x88f4, 0x88f5, 0x88f6, 0x88f7, 0x88f8,
+ 0x88f9, 0x88fa, 0x88fb, 0x88fc, 0x88fd, 0x88fe, 0x8940, 0x8941,
+ 0x8942, 0x8943, 0x8944, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949,
+ 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951,
+ 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959,
+ 0x895a, 0x895b, 0x895c, 0x895d, 0x895e, 0x895f, 0x8960, 0x8961,
+ 0x8962, 0x8963, 0x8964, 0x8965, 0x8966, 0x8967, 0x8968, 0x8969,
+ 0x896a, 0x896b, 0x896c, 0x896d, 0x896e, 0x896f, 0x8970, 0x8971,
+ 0x8972, 0x8973, 0x8974, 0x8975, 0x8976, 0x8977, 0x8978, 0x8979,
+ 0x897a, 0x897b, 0x897c, 0x897d, 0x897e, 0x8980, 0x8981, 0x8982,
+ 0x8983, 0x8984, 0x8985, 0x8986, 0x8987, 0x8988, 0x8989, 0x898a,
+ 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 0x8990, 0x8991, 0x8992,
+ 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899a,
+ 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1, 0x89a2,
+ 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 0x89a8, 0x89a9, 0x89aa,
+ 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 0x89b0, 0x89b1, 0x89b2,
+ 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 0x89b8, 0x89b9, 0x89ba,
+ 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 0x89c0, 0x89c1, 0x89c2,
+ 0x89c3, 0x89c4, 0x89c5, 0x89c6, 0x89c7, 0x89c8, 0x89c9, 0x89ca,
+ 0x89cb, 0x89cc, 0x89cd, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x89d2,
+ 0x89d3, 0x89d4, 0x89d5, 0x89d6, 0x89d7, 0x89d8, 0x89d9, 0x89da,
+ 0x89db, 0x89dc, 0x89dd, 0x89de, 0x89df, 0x89e0, 0x89e1, 0x89e2,
+ 0x89e3, 0x89e4, 0x89e5, 0x89e6, 0x89e7, 0x89e8, 0x89e9, 0x89ea,
+ 0x89eb, 0x89ec, 0x89ed, 0x89ee, 0x89ef, 0x89f0, 0x89f1, 0x89f2,
+ 0x89f3, 0x89f4, 0x89f5, 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa,
+ 0x89fb, 0x89fc, 0x89fd, 0x89fe, 0x8a40, 0x8a41, 0x8a42, 0x8a43,
+ 0x8a44, 0x8a45, 0x8a46, 0x8a47, 0x8a48, 0x8a49, 0x8a4a, 0x8a4b,
+ 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, 0x8a50, 0x8a51, 0x8a52, 0x8a53,
+ 0x8a54, 0x8a55, 0x8a56, 0x8a57, 0x8a58, 0x8a59, 0x8a5a, 0x8a5b,
+ 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, 0x8a60, 0x8a61, 0x8a62, 0x8a63,
+ 0x8a64, 0x8a65, 0x8a66, 0x8a67, 0x8a68, 0x8a69, 0x8a6a, 0x8a6b,
+ 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, 0x8a70, 0x8a71, 0x8a72, 0x8a73,
+ 0x8a74, 0x8a75, 0x8a76, 0x8a77, 0x8a78, 0x8a79, 0x8a7a, 0x8a7b,
+ 0x8a7c, 0x8a7d, 0x8a7e, 0x8a80, 0x8a81, 0x8a82, 0x8a83, 0x8a84,
+ 0x8a85, 0x8a86, 0x8a87, 0x8a88, 0x8a89, 0x8a8a, 0x8a8b, 0x8a8c,
+ 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91, 0x8a92, 0x8a93, 0x8a94,
+ 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b, 0x8a9c,
+ 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3, 0x8aa4,
+ 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, 0x8aac,
+ 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, 0x8ab4,
+ 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9, 0x8aba, 0x8abb, 0x8abc,
+ 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3, 0x8ac4,
+ 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9, 0x8aca, 0x8acb, 0x8acc,
+ 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3, 0x8ad4,
+ 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9, 0x8ada, 0x8adb, 0x8adc,
+ 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3, 0x8ae4,
+ 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9, 0x8aea, 0x8aeb, 0x8aec,
+ 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1, 0x8af2, 0x8af3, 0x8af4,
+ 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9, 0x8afa, 0x8afb, 0x8afc,
+ 0x8afd, 0x8afe, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45,
+ 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d,
+ 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55,
+ 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d,
+ 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65,
+ 0x8b66, 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6c, 0x8b6d,
+ 0x8b6e, 0x8b6f, 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75,
+ 0x8b76, 0x8b77, 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d,
+ 0x8b7e, 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86,
+ 0x8b87, 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e,
+ 0x8b8f, 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96,
+ 0x8b97, 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e,
+ 0x8b9f, 0x8ba0, 0x8ba1, 0x8ba2, 0x8ba3, 0x8ba4, 0x8ba5, 0x8ba6,
+ 0x8ba7, 0x8ba8, 0x8ba9, 0x8baa, 0x8bab, 0x8bac, 0x8bad, 0x8bae,
+ 0x8baf, 0x8bb0, 0x8bb1, 0x8bb2, 0x8bb3, 0x8bb4, 0x8bb5, 0x8bb6,
+ 0x8bb7, 0x8bb8, 0x8bb9, 0x8bba, 0x8bbb, 0x8bbc, 0x8bbd, 0x8bbe,
+ 0x8bbf, 0x8bc0, 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5, 0x8bc6,
+ 0x8bc7, 0x8bc8, 0x8bc9, 0x8bca, 0x8bcb, 0x8bcc, 0x8bcd, 0x8bce,
+ 0x8bcf, 0x8bd0, 0x8bd1, 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd5, 0x8bd6,
+ 0x8bd7, 0x8bd8, 0x8bd9, 0x8bda, 0x8bdb, 0x8bdc, 0x8bdd, 0x8bde,
+ 0x8bdf, 0x8be0, 0x8be1, 0x8be2, 0x8be3, 0x8be4, 0x8be5, 0x8be6,
+ 0x8be7, 0x8be8, 0x8be9, 0x8bea, 0x8beb, 0x8bec, 0x8bed, 0x8bee,
+ 0x8bef, 0x8bf0, 0x8bf1, 0x8bf2, 0x8bf3, 0x8bf4, 0x8bf5, 0x8bf6,
+ 0x8bf7, 0x8bf8, 0x8bf9, 0x8bfa, 0x8bfb, 0x8bfc, 0x8bfd, 0x8bfe,
+ 0x8c40, 0x8c41, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c46, 0x8c47,
+ 0x8c48, 0x8c49, 0x8c4a, 0x8c4b, 0x8c4c, 0x8c4d, 0x8c4e, 0x8c4f,
+ 0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54, 0x8c55, 0x8c56, 0x8c57,
+ 0x8c58, 0x8c59, 0x8c5a, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, 0x8c5f,
+ 0x8c60, 0x8c61, 0x8c62, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67,
+ 0x8c68, 0x8c69, 0x8c6a, 0x8c6b, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f,
+ 0x8c70, 0x8c71, 0x8c72, 0x8c73, 0x8c74, 0x8c75, 0x8c76, 0x8c77,
+ 0x8c78, 0x8c79, 0x8c7a, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, 0x8c80,
+ 0x8c81, 0x8c82, 0x8c83, 0x8c84, 0x8c85, 0x8c86, 0x8c87, 0x8c88,
+ 0x8c89, 0x8c8a, 0x8c8b, 0x8c8c, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90,
+ 0x8c91, 0x8c92, 0x8c93, 0x8c94, 0x8c95, 0x8c96, 0x8c97, 0x8c98,
+ 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, 0x8c9e, 0x8c9f, 0x8ca0,
+ 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, 0x8ca6, 0x8ca7, 0x8ca8,
+ 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad, 0x8cae, 0x8caf, 0x8cb0,
+ 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, 0x8cb6, 0x8cb7, 0x8cb8,
+ 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, 0x8cbe, 0x8cbf, 0x8cc0,
+ 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, 0x8cc6, 0x8cc7, 0x8cc8,
+ 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, 0x8cce, 0x8ccf, 0x8cd0,
+ 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, 0x8cd6, 0x8cd7, 0x8cd8,
+ 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, 0x8cde, 0x8cdf, 0x8ce0,
+ 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, 0x8ce6, 0x8ce7, 0x8ce8,
+ 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced, 0x8cee, 0x8cef, 0x8cf0,
+ 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, 0x8cf6, 0x8cf7, 0x8cf8,
+ 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, 0x8cfe, 0x8d40, 0x8d41,
+ 0x8d42, 0x8d43, 0x8d44, 0x8d45, 0x8d46, 0x8d47, 0x8d48, 0x8d49,
+ 0x8d4a, 0x8d4b, 0x8d4c, 0x8d4d, 0x8d4e, 0x8d4f, 0x8d50, 0x8d51,
+ 0x8d52, 0x8d53, 0x8d54, 0x8d55, 0x8d56, 0x8d57, 0x8d58, 0x8d59,
+ 0x8d5a, 0x8d5b, 0x8d5c, 0x8d5d, 0x8d5e, 0x8d5f, 0x8d60, 0x8d61,
+ 0x8d62, 0x8d63, 0x8d64, 0x8d65, 0x8d66, 0x8d67, 0x8d68, 0x8d69,
+ 0x8d6a, 0x8d6b, 0x8d6c, 0x8d6d, 0x8d6e, 0x8d6f, 0x8d70, 0x8d71,
+ 0x8d72, 0x8d73, 0x8d74, 0x8d75, 0x8d76, 0x8d77, 0x8d78, 0x8d79,
+ 0x8d7a, 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d80, 0x8d81, 0x8d82,
+ 0x8d83, 0x8d84, 0x8d85, 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8a,
+ 0x8d8b, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f, 0x8d90, 0x8d91, 0x8d92,
+ 0x8d93, 0x8d94, 0x8d95, 0x8d96, 0x8d97, 0x8d98, 0x8d99, 0x8d9a,
+ 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8d9f, 0x8da0, 0x8da1, 0x8da2,
+ 0x8da3, 0x8da4, 0x8da5, 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa,
+ 0x8dab, 0x8dac, 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db1, 0x8db2,
+ 0x8db3, 0x8db4, 0x8db5, 0x8db6, 0x8db7, 0x8db8, 0x8db9, 0x8dba,
+ 0x8dbb, 0x8dbc, 0x8dbd, 0x8dbe, 0x8dbf, 0x8dc0, 0x8dc1, 0x8dc2,
+ 0x8dc3, 0x8dc4, 0x8dc5, 0x8dc6, 0x8dc7, 0x8dc8, 0x8dc9, 0x8dca,
+ 0x8dcb, 0x8dcc, 0x8dcd, 0x8dce, 0x8dcf, 0x8dd0, 0x8dd1, 0x8dd2,
+ 0x8dd3, 0x8dd4, 0x8dd5, 0x8dd6, 0x8dd7, 0x8dd8, 0x8dd9, 0x8dda,
+ 0x8ddb, 0x8ddc, 0x8ddd, 0x8dde, 0x8ddf, 0x8de0, 0x8de1, 0x8de2,
+ 0x8de3, 0x8de4, 0x8de5, 0x8de6, 0x8de7, 0x8de8, 0x8de9, 0x8dea,
+ 0x8deb, 0x8dec, 0x8ded, 0x8dee, 0x8def, 0x8df0, 0x8df1, 0x8df2,
+ 0x8df3, 0x8df4, 0x8df5, 0x8df6, 0x8df7, 0x8df8, 0x8df9, 0x8dfa,
+ 0x8dfb, 0x8dfc, 0x8dfd, 0x8dfe, 0x8e40, 0x8e41, 0x8e42, 0x8e43,
+ 0x8e44, 0x8e45, 0x8e46, 0x8e47, 0x8e48, 0x8e49, 0x8e4a, 0x8e4b,
+ 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50, 0x8e51, 0x8e52, 0x8e53,
+ 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58, 0x8e59, 0x8e5a, 0x8e5b,
+ 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0x8e63,
+ 0x8e64, 0x8e65, 0x8e66, 0x8e67, 0x8e68, 0x8e69, 0x8e6a, 0x8e6b,
+ 0x8e6c, 0x8e6d, 0x8e6e, 0x8e6f, 0x8e70, 0x8e71, 0x8e72, 0x8e73,
+ 0x8e74, 0x8e75, 0x8e76, 0x8e77, 0x8e78, 0x8e79, 0x8e7a, 0x8e7b,
+ 0x8e7c, 0x8e7d, 0x8e7e, 0x8e80, 0x8e81, 0x8e82, 0x8e83, 0x8e84,
+ 0x8e85, 0x8e86, 0x8e87, 0x8e88, 0x8e89, 0x8e8a, 0x8e8b, 0x8e8c,
+ 0x8e8d, 0x8e8e, 0x8e8f, 0x8e90, 0x8e91, 0x8e92, 0x8e93, 0x8e94,
+ 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9c,
+ 0x8e9d, 0x8e9e, 0x8e9f, 0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4,
+ 0x8ea5, 0x8ea6, 0x8ea7, 0x8ea8, 0x8ea9, 0x8eaa, 0x8eab, 0x8eac,
+ 0x8ead, 0x8eae, 0x8eaf, 0x8eb0, 0x8eb1, 0x8eb2, 0x8eb3, 0x8eb4,
+ 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9, 0x8eba, 0x8ebb, 0x8ebc,
+ 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3, 0x8ec4,
+ 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, 0x8eca, 0x8ecb, 0x8ecc,
+ 0x8ecd, 0x8ece, 0x8ecf, 0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4,
+ 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc,
+ 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4,
+ 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec,
+ 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4,
+ 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc,
+ 0x8efd, 0x8efe, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44, 0x8f45,
+ 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c, 0x8f4d,
+ 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54, 0x8f55,
+ 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c, 0x8f5d,
+ 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64, 0x8f65,
+ 0x8f66, 0x8f67, 0x8f68, 0x8f69, 0x8f6a, 0x8f6b, 0x8f6c, 0x8f6d,
+ 0x8f6e, 0x8f6f, 0x8f70, 0x8f71, 0x8f72, 0x8f73, 0x8f74, 0x8f75,
+ 0x8f76, 0x8f77, 0x8f78, 0x8f79, 0x8f7a, 0x8f7b, 0x8f7c, 0x8f7d,
+ 0x8f7e, 0x8f80, 0x8f81, 0x8f82, 0x8f83, 0x8f84, 0x8f85, 0x8f86,
+ 0x8f87, 0x8f88, 0x8f89, 0x8f8a, 0x8f8b, 0x8f8c, 0x8f8d, 0x8f8e,
+ 0x8f8f, 0x8f90, 0x8f91, 0x8f92, 0x8f93, 0x8f94, 0x8f95, 0x8f96,
+ 0x8f97, 0x8f98, 0x8f99, 0x8f9a, 0x8f9b, 0x8f9c, 0x8f9d, 0x8f9e,
+ 0x8f9f, 0x8fa0, 0x8fa1, 0x8fa2, 0x8fa3, 0x8fa4, 0x8fa5, 0x8fa6,
+ 0x8fa7, 0x8fa8, 0x8fa9, 0x8faa, 0x8fab, 0x8fac, 0x8fad, 0x8fae,
+ 0x8faf, 0x8fb0, 0x8fb1, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb6,
+ 0x8fb7, 0x8fb8, 0x8fb9, 0x8fba, 0x8fbb, 0x8fbc, 0x8fbd, 0x8fbe,
+ 0x8fbf, 0x8fc0, 0x8fc1, 0x8fc2, 0x8fc3, 0x8fc4, 0x8fc5, 0x8fc6,
+ 0x8fc7, 0x8fc8, 0x8fc9, 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fce,
+ 0x8fcf, 0x8fd0, 0x8fd1, 0x8fd2, 0x8fd3, 0x8fd4, 0x8fd5, 0x8fd6,
+ 0x8fd7, 0x8fd8, 0x8fd9, 0x8fda, 0x8fdb, 0x8fdc, 0x8fdd, 0x8fde,
+ 0x8fdf, 0x8fe0, 0x8fe1, 0x8fe2, 0x8fe3, 0x8fe4, 0x8fe5, 0x8fe6,
+ 0x8fe7, 0x8fe8, 0x8fe9, 0x8fea, 0x8feb, 0x8fec, 0x8fed, 0x8fee,
+ 0x8fef, 0x8ff0, 0x8ff1, 0x8ff2, 0x8ff3, 0x8ff4, 0x8ff5, 0x8ff6,
+ 0x8ff7, 0x8ff8, 0x8ff9, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffd, 0x8ffe,
+ 0x9040, 0x9041, 0x9042, 0x9043, 0x9044, 0x9045, 0x9046, 0x9047,
+ 0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904d, 0x904e, 0x904f,
+ 0x9050, 0x9051, 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0x9057,
+ 0x9058, 0x9059, 0x905a, 0x905b, 0x905c, 0x905d, 0x905e, 0x905f,
+ 0x9060, 0x9061, 0x9062, 0x9063, 0x9064, 0x9065, 0x9066, 0x9067,
+ 0x9068, 0x9069, 0x906a, 0x906b, 0x906c, 0x906d, 0x906e, 0x906f,
+ 0x9070, 0x9071, 0x9072, 0x9073, 0x9074, 0x9075, 0x9076, 0x9077,
+ 0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907d, 0x907e, 0x9080,
+ 0x9081, 0x9082, 0x9083, 0x9084, 0x9085, 0x9086, 0x9087, 0x9088,
+ 0x9089, 0x908a, 0x908b, 0x908c, 0x908d, 0x908e, 0x908f, 0x9090,
+ 0x9091, 0x9092, 0x9093, 0x9094, 0x9095, 0x9096, 0x9097, 0x9098,
+ 0x9099, 0x909a, 0x909b, 0x909c, 0x909d, 0x909e, 0x909f, 0x90a0,
+ 0x90a1, 0x90a2, 0x90a3, 0x90a4, 0x90a5, 0x90a6, 0x90a7, 0x90a8,
+ 0x90a9, 0x90aa, 0x90ab, 0x90ac, 0x90ad, 0x90ae, 0x90af, 0x90b0,
+ 0x90b1, 0x90b2, 0x90b3, 0x90b4, 0x90b5, 0x90b6, 0x90b7, 0x90b8,
+ 0x90b9, 0x90ba, 0x90bb, 0x90bc, 0x90bd, 0x90be, 0x90bf, 0x90c0,
+ 0x90c1, 0x90c2, 0x90c3, 0x90c4, 0x90c5, 0x90c6, 0x90c7, 0x90c8,
+ 0x90c9, 0x90ca, 0x90cb, 0x90cc, 0x90cd, 0x90ce, 0x90cf, 0x90d0,
+ 0x90d1, 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x90d6, 0x90d7, 0x90d8,
+ 0x90d9, 0x90da, 0x90db, 0x90dc, 0x90dd, 0x90de, 0x90df, 0x90e0,
+ 0x90e1, 0x90e2, 0x90e3, 0x90e4, 0x90e5, 0x90e6, 0x90e7, 0x90e8,
+ 0x90e9, 0x90ea, 0x90eb, 0x90ec, 0x90ed, 0x90ee, 0x90ef, 0x90f0,
+ 0x90f1, 0x90f2, 0x90f3, 0x90f4, 0x90f5, 0x90f6, 0x90f7, 0x90f8,
+ 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90fd, 0x90fe, 0x9140, 0x9141,
+ 0x9142, 0x9143, 0x9144, 0x9145, 0x9146, 0x9147, 0x9148, 0x9149,
+ 0x914a, 0x914b, 0x914c, 0x914d, 0x914e, 0x914f, 0x9150, 0x9151,
+ 0x9152, 0x9153, 0x9154, 0x9155, 0x9156, 0x9157, 0x9158, 0x9159,
+ 0x915a, 0x915b, 0x915c, 0x915d, 0x915e, 0x915f, 0x9160, 0x9161,
+ 0x9162, 0x9163, 0x9164, 0x9165, 0x9166, 0x9167, 0x9168, 0x9169,
+ 0x916a, 0x916b, 0x916c, 0x916d, 0x916e, 0x916f, 0x9170, 0x9171,
+ 0x9172, 0x9173, 0x9174, 0x9175, 0x9176, 0x9177, 0x9178, 0x9179,
+ 0x917a, 0x917b, 0x917c, 0x917d, 0x917e, 0x9180, 0x9181, 0x9182,
+ 0x9183, 0x9184, 0x9185, 0x9186, 0x9187, 0x9188, 0x9189, 0x918a,
+ 0x918b, 0x918c, 0x918d, 0x918e, 0x918f, 0x9190, 0x9191, 0x9192,
+ 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, 0x919a,
+ 0x919b, 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a2,
+ 0x91a3, 0x91a4, 0x91a5, 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91aa,
+ 0x91ab, 0x91ac, 0x91ad, 0x91ae, 0x91af, 0x91b0, 0x91b1, 0x91b2,
+ 0x91b3, 0x91b4, 0x91b5, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91ba,
+ 0x91bb, 0x91bc, 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2,
+ 0x91c3, 0x91c4, 0x91c5, 0x91c6, 0x91c7, 0x91c8, 0x91c9, 0x91ca,
+ 0x91cb, 0x91cc, 0x91cd, 0x91ce, 0x91cf, 0x91d0, 0x91d1, 0x91d2,
+ 0x91d3, 0x91d4, 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da,
+ 0x91db, 0x91dc, 0x91dd, 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2,
+ 0x91e3, 0x91e4, 0x91e5, 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea,
+ 0x91eb, 0x91ec, 0x91ed, 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2,
+ 0x91f3, 0x91f4, 0x91f5, 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa,
+ 0x91fb, 0x91fc, 0x91fd, 0x91fe, 0x9240, 0x9241, 0x9242, 0x9243,
+ 0x9244, 0x9245, 0x9246, 0x9247, 0x9248, 0x9249, 0x924a, 0x924b,
+ 0x924c, 0x924d, 0x924e, 0x924f, 0x9250, 0x9251, 0x9252, 0x9253,
+ 0x9254, 0x9255, 0x9256, 0x9257, 0x9258, 0x9259, 0x925a, 0x925b,
+ 0x925c, 0x925d, 0x925e, 0x925f, 0x9260, 0x9261, 0x9262, 0x9263,
+ 0x9264, 0x9265, 0x9266, 0x9267, 0x9268, 0x9269, 0x926a, 0x926b,
+ 0x926c, 0x926d, 0x926e, 0x926f, 0x9270, 0x9271, 0x9272, 0x9273,
+ 0x9274, 0x9275, 0x9276, 0x9277, 0x9278, 0x9279, 0x927a, 0x927b,
+ 0x927c, 0x927d, 0x927e, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284,
+ 0x9285, 0x9286, 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c,
+ 0x928d, 0x928e, 0x928f, 0x9290, 0x9291, 0x9292, 0x9293, 0x9294,
+ 0x9295, 0x9296, 0x9297, 0x9298, 0x9299, 0x929a, 0x929b, 0x929c,
+ 0x929d, 0x929e, 0x929f, 0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4,
+ 0x92a5, 0x92a6, 0x92a7, 0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac,
+ 0x92ad, 0x92ae, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92b3, 0x92b4,
+ 0x92b5, 0x92b6, 0x92b7, 0x92b8, 0x92b9, 0x92ba, 0x92bb, 0x92bc,
+ 0x92bd, 0x92be, 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c4,
+ 0x92c5, 0x92c6, 0x92c7, 0x92c8, 0x92c9, 0x92ca, 0x92cb, 0x92cc,
+ 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1, 0x92d2, 0x92d3, 0x92d4,
+ 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9, 0x92da, 0x92db, 0x92dc,
+ 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1, 0x92e2, 0x92e3, 0x92e4,
+ 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9, 0x92ea, 0x92eb, 0x92ec,
+ 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1, 0x92f2, 0x92f3, 0x92f4,
+ 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9, 0x92fa, 0x92fb, 0x92fc,
+ 0x92fd, 0x92fe, 0x9340, 0x9341, 0x9342, 0x9343, 0x9344, 0x9345,
+ 0x9346, 0x9347, 0x9348, 0x9349, 0x934a, 0x934b, 0x934c, 0x934d,
+ 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, 0x9353, 0x9354, 0x9355,
+ 0x9356, 0x9357, 0x9358, 0x9359, 0x935a, 0x935b, 0x935c, 0x935d,
+ 0x935e, 0x935f, 0x9360, 0x9361, 0x9362, 0x9363, 0x9364, 0x9365,
+ 0x9366, 0x9367, 0x9368, 0x9369, 0x936a, 0x936b, 0x936c, 0x936d,
+ 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373, 0x9374, 0x9375,
+ 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b, 0x937c, 0x937d,
+ 0x937e, 0x9380, 0x9381, 0x9382, 0x9383, 0x9384, 0x9385, 0x9386,
+ 0x9387, 0x9388, 0x9389, 0x938a, 0x938b, 0x938c, 0x938d, 0x938e,
+ 0x938f, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, 0x9395, 0x9396,
+ 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c, 0x939d, 0x939e,
+ 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, 0x93a5, 0x93a6,
+ 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, 0x93ad, 0x93ae,
+ 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, 0x93b5, 0x93b6,
+ 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, 0x93bd, 0x93be,
+ 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, 0x93c5, 0x93c6,
+ 0x93c7, 0x93c8, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93ce,
+ 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5, 0x93d6,
+ 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de,
+ 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6,
+ 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee,
+ 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6,
+ 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe,
+ 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447,
+ 0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f,
+ 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457,
+ 0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f,
+ 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467,
+ 0x9468, 0x9469, 0x946a, 0x946b, 0x946c, 0x946d, 0x946e, 0x946f,
+ 0x9470, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477,
+ 0x9478, 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x9480,
+ 0x9481, 0x9482, 0x9483, 0x9484, 0x9485, 0x9486, 0x9487, 0x9488,
+ 0x9489, 0x948a, 0x948b, 0x948c, 0x948d, 0x948e, 0x948f, 0x9490,
+ 0x9491, 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0x9497, 0x9498,
+ 0x9499, 0x949a, 0x949b, 0x949c, 0x949d, 0x949e, 0x949f, 0x94a0,
+ 0x94a1, 0x94a2, 0x94a3, 0x94a4, 0x94a5, 0x94a6, 0x94a7, 0x94a8,
+ 0x94a9, 0x94aa, 0x94ab, 0x94ac, 0x94ad, 0x94ae, 0x94af, 0x94b0,
+ 0x94b1, 0x94b2, 0x94b3, 0x94b4, 0x94b5, 0x94b6, 0x94b7, 0x94b8,
+ 0x94b9, 0x94ba, 0x94bb, 0x94bc, 0x94bd, 0x94be, 0x94bf, 0x94c0,
+ 0x94c1, 0x94c2, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8,
+ 0x94c9, 0x94ca, 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94cf, 0x94d0,
+ 0x94d1, 0x94d2, 0x94d3, 0x94d4, 0x94d5, 0x94d6, 0x94d7, 0x94d8,
+ 0x94d9, 0x94da, 0x94db, 0x94dc, 0x94dd, 0x94de, 0x94df, 0x94e0,
+ 0x94e1, 0x94e2, 0x94e3, 0x94e4, 0x94e5, 0x94e6, 0x94e7, 0x94e8,
+ 0x94e9, 0x94ea, 0x94eb, 0x94ec, 0x94ed, 0x94ee, 0x94ef, 0x94f0,
+ 0x94f1, 0x94f2, 0x94f3, 0x94f4, 0x94f5, 0x94f6, 0x94f7, 0x94f8,
+ 0x94f9, 0x94fa, 0x94fb, 0x94fc, 0x94fd, 0x94fe, 0x9540, 0x9541,
+ 0x9542, 0x9543, 0x9544, 0x9545, 0x9546, 0x9547, 0x9548, 0x9549,
+ 0x954a, 0x954b, 0x954c, 0x954d, 0x954e, 0x954f, 0x9550, 0x9551,
+ 0x9552, 0x9553, 0x9554, 0x9555, 0x9556, 0x9557, 0x9558, 0x9559,
+ 0x955a, 0x955b, 0x955c, 0x955d, 0x955e, 0x955f, 0x9560, 0x9561,
+ 0x9562, 0x9563, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, 0x9569,
+ 0x956a, 0x956b, 0x956c, 0x956d, 0x956e, 0x956f, 0x9570, 0x9571,
+ 0x9572, 0x9573, 0x9574, 0x9575, 0x9576, 0x9577, 0x9578, 0x9579,
+ 0x957a, 0x957b, 0x957c, 0x957d, 0x957e, 0x9580, 0x9581, 0x9582,
+ 0x9583, 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958a,
+ 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9590, 0x9591, 0x9592,
+ 0x9593, 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959a,
+ 0x959b, 0x959c, 0x959d, 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2,
+ 0x95a3, 0x95a4, 0x95a5, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa,
+ 0x95ab, 0x95ac, 0x95ad, 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2,
+ 0x95b3, 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba,
+ 0x95bb, 0x95bc, 0x95bd, 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2,
+ 0x95c3, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca,
+ 0x95cb, 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2,
+ 0x95d3, 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da,
+ 0x95db, 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2,
+ 0x95e3, 0x95e4, 0x95e5, 0x95e6, 0x95e7, 0x95e8, 0x95e9, 0x95ea,
+ 0x95eb, 0x95ec, 0x95ed, 0x95ee, 0x95ef, 0x95f0, 0x95f1, 0x95f2,
+ 0x95f3, 0x95f4, 0x95f5, 0x95f6, 0x95f7, 0x95f8, 0x95f9, 0x95fa,
+ 0x95fb, 0x95fc, 0x95fd, 0x95fe, 0x9640, 0x9641, 0x9642, 0x9643,
+ 0x9644, 0x9645, 0x9646, 0x9647, 0x9648, 0x9649, 0x964a, 0x964b,
+ 0x964c, 0x964d, 0x964e, 0x964f, 0x9650, 0x9651, 0x9652, 0x9653,
+ 0x9654, 0x9655, 0x9656, 0x9657, 0x9658, 0x9659, 0x965a, 0x965b,
+ 0x965c, 0x965d, 0x965e, 0x965f, 0x9660, 0x9661, 0x9662, 0x9663,
+ 0x9664, 0x9665, 0x9666, 0x9667, 0x9668, 0x9669, 0x966a, 0x966b,
+ 0x966c, 0x966d, 0x966e, 0x966f, 0x9670, 0x9671, 0x9672, 0x9673,
+ 0x9674, 0x9675, 0x9676, 0x9677, 0x9678, 0x9679, 0x967a, 0x967b,
+ 0x967c, 0x967d, 0x967e, 0x9680, 0x9681, 0x9682, 0x9683, 0x9684,
+ 0x9685, 0x9686, 0x9687, 0x9688, 0x9689, 0x968a, 0x968b, 0x968c,
+ 0x968d, 0x968e, 0x968f, 0x9690, 0x9691, 0x9692, 0x9693, 0x9694,
+ 0x9695, 0x9696, 0x9697, 0x9698, 0x9699, 0x969a, 0x969b, 0x969c,
+ 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1, 0x96a2, 0x96a3, 0x96a4,
+ 0x96a5, 0x96a6, 0x96a7, 0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac,
+ 0x96ad, 0x96ae, 0x96af, 0x96b0, 0x96b1, 0x96b2, 0x96b3, 0x96b4,
+ 0x96b5, 0x96b6, 0x96b7, 0x96b8, 0x96b9, 0x96ba, 0x96bb, 0x96bc,
+ 0x96bd, 0x96be, 0x96bf, 0x96c0, 0x96c1, 0x96c2, 0x96c3, 0x96c4,
+ 0x96c5, 0x96c6, 0x96c7, 0x96c8, 0x96c9, 0x96ca, 0x96cb, 0x96cc,
+ 0x96cd, 0x96ce, 0x96cf, 0x96d0, 0x96d1, 0x96d2, 0x96d3, 0x96d4,
+ 0x96d5, 0x96d6, 0x96d7, 0x96d8, 0x96d9, 0x96da, 0x96db, 0x96dc,
+ 0x96dd, 0x96de, 0x96df, 0x96e0, 0x96e1, 0x96e2, 0x96e3, 0x96e4,
+ 0x96e5, 0x96e6, 0x96e7, 0x96e8, 0x96e9, 0x96ea, 0x96eb, 0x96ec,
+ 0x96ed, 0x96ee, 0x96ef, 0x96f0, 0x96f1, 0x96f2, 0x96f3, 0x96f4,
+ 0x96f5, 0x96f6, 0x96f7, 0x96f8, 0x96f9, 0x96fa, 0x96fb, 0x96fc,
+ 0x96fd, 0x96fe, 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745,
+ 0x9746, 0x9747, 0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d,
+ 0x974e, 0x974f, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755,
+ 0x9756, 0x9757, 0x9758, 0x9759, 0x975a, 0x975b, 0x975c, 0x975d,
+ 0x975e, 0x975f, 0x9760, 0x9761, 0x9762, 0x9763, 0x9764, 0x9765,
+ 0x9766, 0x9767, 0x9768, 0x9769, 0x976a, 0x976b, 0x976c, 0x976d,
+ 0x976e, 0x976f, 0x9770, 0x9771, 0x9772, 0x9773, 0x9774, 0x9775,
+ 0x9776, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977c, 0x977d,
+ 0x977e, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786,
+ 0x9787, 0x9788, 0x9789, 0x978a, 0x978b, 0x978c, 0x978d, 0x978e,
+ 0x978f, 0x9790, 0x9791, 0x9792, 0x9793, 0x9794, 0x9795, 0x9796,
+ 0x9797, 0x9798, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, 0x979e,
+ 0x979f, 0x97a0, 0x97a1, 0x97a2, 0x97a3, 0x97a4, 0x97a5, 0x97a6,
+ 0x97a7, 0x97a8, 0x97a9, 0x97aa, 0x97ab, 0x97ac, 0x97ad, 0x97ae,
+ 0x97af, 0x97b0, 0x97b1, 0x97b2, 0x97b3, 0x97b4, 0x97b5, 0x97b6,
+ 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, 0x97bd, 0x97be,
+ 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, 0x97c5, 0x97c6,
+ 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, 0x97cd, 0x97ce,
+ 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, 0x97d5, 0x97d6,
+ 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, 0x97dd, 0x97de,
+ 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, 0x97e5, 0x97e6,
+ 0x97e7, 0x97e8, 0x97e9, 0x97ea, 0x97eb, 0x97ec, 0x97ed, 0x97ee,
+ 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f3, 0x97f4, 0x97f5, 0x97f6,
+ 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe,
+ 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, 0x9847,
+ 0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, 0x984f,
+ 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, 0x9857,
+ 0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, 0x985f,
+ 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, 0x9867,
+ 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, 0x986f,
+ 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x9875, 0x9876, 0x9877,
+ 0x9878, 0x9879, 0x987a, 0x987b, 0x987c, 0x987d, 0x987e, 0x9880,
+ 0x9881, 0x9882, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 0x9888,
+ 0x9889, 0x988a, 0x988b, 0x988c, 0x988d, 0x988e, 0x988f, 0x9890,
+ 0x9891, 0x9892, 0x9893, 0x9894, 0x9895, 0x9896, 0x9897, 0x9898,
+ 0x9899, 0x989a, 0x989b, 0x989c, 0x989d, 0x989e, 0x989f, 0x98a0,
+ 0x98a1, 0x98a2, 0x98a3, 0x98a4, 0x98a5, 0x98a6, 0x98a7, 0x98a8,
+ 0x98a9, 0x98aa, 0x98ab, 0x98ac, 0x98ad, 0x98ae, 0x98af, 0x98b0,
+ 0x98b1, 0x98b2, 0x98b3, 0x98b4, 0x98b5, 0x98b6, 0x98b7, 0x98b8,
+ 0x98b9, 0x98ba, 0x98bb, 0x98bc, 0x98bd, 0x98be, 0x98bf, 0x98c0,
+ 0x98c1, 0x98c2, 0x98c3, 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8,
+ 0x98c9, 0x98ca, 0x98cb, 0x98cc, 0x98cd, 0x98ce, 0x98cf, 0x98d0,
+ 0x98d1, 0x98d2, 0x98d3, 0x98d4, 0x98d5, 0x98d6, 0x98d7, 0x98d8,
+ 0x98d9, 0x98da, 0x98db, 0x98dc, 0x98dd, 0x98de, 0x98df, 0x98e0,
+ 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5, 0x98e6, 0x98e7, 0x98e8,
+ 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef, 0x98f0,
+ 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7, 0x98f8,
+ 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x9940, 0x9941,
+ 0x9942, 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949,
+ 0x994a, 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951,
+ 0x9952, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 0x9958, 0x9959,
+ 0x995a, 0x995b, 0x995c, 0x995d, 0x995e, 0x995f, 0x9960, 0x9961,
+ 0x9962, 0x9963, 0x9964, 0x9965, 0x9966, 0x9967, 0x9968, 0x9969,
+ 0x996a, 0x996b, 0x996c, 0x996d, 0x996e, 0x996f, 0x9970, 0x9971,
+ 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 0x9978, 0x9979,
+ 0x997a, 0x997b, 0x997c, 0x997d, 0x997e, 0x9980, 0x9981, 0x9982,
+ 0x9983, 0x9984, 0x9985, 0x9986, 0x9987, 0x9988, 0x9989, 0x998a,
+ 0x998b, 0x998c, 0x998d, 0x998e, 0x998f, 0x9990, 0x9991, 0x9992,
+ 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, 0x9999, 0x999a,
+ 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, 0x99a0, 0x99a1, 0x99a2,
+ 0x99a3, 0x99a4, 0x99a5, 0x99a6, 0x99a7, 0x99a8, 0x99a9, 0x99aa,
+ 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0, 0x99b1, 0x99b2,
+ 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8, 0x99b9, 0x99ba,
+ 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0, 0x99c1, 0x99c2,
+ 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8, 0x99c9, 0x99ca,
+ 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0, 0x99d1, 0x99d2,
+ 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8, 0x99d9, 0x99da,
+ 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0, 0x99e1, 0x99e2,
+ 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8, 0x99e9, 0x99ea,
+ 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0, 0x99f1, 0x99f2,
+ 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8, 0x99f9, 0x99fa,
+ 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x9a40, 0x9a41, 0x9a42, 0x9a43,
+ 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49, 0x9a4a, 0x9a4b,
+ 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51, 0x9a52, 0x9a53,
+ 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59, 0x9a5a, 0x9a5b,
+ 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61, 0x9a62, 0x9a63,
+ 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69, 0x9a6a, 0x9a6b,
+ 0x9a6c, 0x9a6d, 0x9a6e, 0x9a6f, 0x9a70, 0x9a71, 0x9a72, 0x9a73,
+ 0x9a74, 0x9a75, 0x9a76, 0x9a77, 0x9a78, 0x9a79, 0x9a7a, 0x9a7b,
+ 0x9a7c, 0x9a7d, 0x9a7e, 0x9a80, 0x9a81, 0x9a82, 0x9a83, 0x9a84,
+ 0x9a85, 0x9a86, 0x9a87, 0x9a88, 0x9a89, 0x9a8a, 0x9a8b, 0x9a8c,
+ 0x9a8d, 0x9a8e, 0x9a8f, 0x9a90, 0x9a91, 0x9a92, 0x9a93, 0x9a94,
+ 0x9a95, 0x9a96, 0x9a97, 0x9a98, 0x9a99, 0x9a9a, 0x9a9b, 0x9a9c,
+ 0x9a9d, 0x9a9e, 0x9a9f, 0x9aa0, 0x9aa1, 0x9aa2, 0x9aa3, 0x9aa4,
+ 0x9aa5, 0x9aa6, 0x9aa7, 0x9aa8, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac,
+ 0x9aad, 0x9aae, 0x9aaf, 0x9ab0, 0x9ab1, 0x9ab2, 0x9ab3, 0x9ab4,
+ 0x9ab5, 0x9ab6, 0x9ab7, 0x9ab8, 0x9ab9, 0x9aba, 0x9abb, 0x9abc,
+ 0x9abd, 0x9abe, 0x9abf, 0x9ac0, 0x9ac1, 0x9ac2, 0x9ac3, 0x9ac4,
+ 0x9ac5, 0x9ac6, 0x9ac7, 0x9ac8, 0x9ac9, 0x9aca, 0x9acb, 0x9acc,
+ 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad1, 0x9ad2, 0x9ad3, 0x9ad4,
+ 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad8, 0x9ad9, 0x9ada, 0x9adb, 0x9adc,
+ 0x9add, 0x9ade, 0x9adf, 0x9ae0, 0x9ae1, 0x9ae2, 0x9ae3, 0x9ae4,
+ 0x9ae5, 0x9ae6, 0x9ae7, 0x9ae8, 0x9ae9, 0x9aea, 0x9aeb, 0x9aec,
+ 0x9aed, 0x9aee, 0x9aef, 0x9af0, 0x9af1, 0x9af2, 0x9af3, 0x9af4,
+ 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9af9, 0x9afa, 0x9afb, 0x9afc,
+ 0x9afd, 0x9afe, 0x9b40, 0x9b41, 0x9b42, 0x9b43, 0x9b44, 0x9b45,
+ 0x9b46, 0x9b47, 0x9b48, 0x9b49, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4d,
+ 0x9b4e, 0x9b4f, 0x9b50, 0x9b51, 0x9b52, 0x9b53, 0x9b54, 0x9b55,
+ 0x9b56, 0x9b57, 0x9b58, 0x9b59, 0x9b5a, 0x9b5b, 0x9b5c, 0x9b5d,
+ 0x9b5e, 0x9b5f, 0x9b60, 0x9b61, 0x9b62, 0x9b63, 0x9b64, 0x9b65,
+ 0x9b66, 0x9b67, 0x9b68, 0x9b69, 0x9b6a, 0x9b6b, 0x9b6c, 0x9b6d,
+ 0x9b6e, 0x9b6f, 0x9b70, 0x9b71, 0x9b72, 0x9b73, 0x9b74, 0x9b75,
+ 0x9b76, 0x9b77, 0x9b78, 0x9b79, 0x9b7a, 0x9b7b, 0x9b7c, 0x9b7d,
+ 0x9b7e, 0x9b80, 0x9b81, 0x9b82, 0x9b83, 0x9b84, 0x9b85, 0x9b86,
+ 0x9b87, 0x9b88, 0x9b89, 0x9b8a, 0x9b8b, 0x9b8c, 0x9b8d, 0x9b8e,
+ 0x9b8f, 0x9b90, 0x9b91, 0x9b92, 0x9b93, 0x9b94, 0x9b95, 0x9b96,
+ 0x9b97, 0x9b98, 0x9b99, 0x9b9a, 0x9b9b, 0x9b9c, 0x9b9d, 0x9b9e,
+ 0x9b9f, 0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3, 0x9ba4, 0x9ba5, 0x9ba6,
+ 0x9ba7, 0x9ba8, 0x9ba9, 0x9baa, 0x9bab, 0x9bac, 0x9bad, 0x9bae,
+ 0x9baf, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, 0x9bb4, 0x9bb5, 0x9bb6,
+ 0x9bb7, 0x9bb8, 0x9bb9, 0x9bba, 0x9bbb, 0x9bbc, 0x9bbd, 0x9bbe,
+ 0x9bbf, 0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3, 0x9bc4, 0x9bc5, 0x9bc6,
+ 0x9bc7, 0x9bc8, 0x9bc9, 0x9bca, 0x9bcb, 0x9bcc, 0x9bcd, 0x9bce,
+ 0x9bcf, 0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3, 0x9bd4, 0x9bd5, 0x9bd6,
+ 0x9bd7, 0x9bd8, 0x9bd9, 0x9bda, 0x9bdb, 0x9bdc, 0x9bdd, 0x9bde,
+ 0x9bdf, 0x9be0, 0x9be1, 0x9be2, 0x9be3, 0x9be4, 0x9be5, 0x9be6,
+ 0x9be7, 0x9be8, 0x9be9, 0x9bea, 0x9beb, 0x9bec, 0x9bed, 0x9bee,
+ 0x9bef, 0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3, 0x9bf4, 0x9bf5, 0x9bf6,
+ 0x9bf7, 0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb, 0x9bfc, 0x9bfd, 0x9bfe,
+ 0x9c40, 0x9c41, 0x9c42, 0x9c43, 0x9c44, 0x9c45, 0x9c46, 0x9c47,
+ 0x9c48, 0x9c49, 0x9c4a, 0x9c4b, 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f,
+ 0x9c50, 0x9c51, 0x9c52, 0x9c53, 0x9c54, 0x9c55, 0x9c56, 0x9c57,
+ 0x9c58, 0x9c59, 0x9c5a, 0x9c5b, 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f,
+ 0x9c60, 0x9c61, 0x9c62, 0x9c63, 0x9c64, 0x9c65, 0x9c66, 0x9c67,
+ 0x9c68, 0x9c69, 0x9c6a, 0x9c6b, 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f,
+ 0x9c70, 0x9c71, 0x9c72, 0x9c73, 0x9c74, 0x9c75, 0x9c76, 0x9c77,
+ 0x9c78, 0x9c79, 0x9c7a, 0x9c7b, 0x9c7c, 0x9c7d, 0x9c7e, 0x9c80,
+ 0x9c81, 0x9c82, 0x9c83, 0x9c84, 0x9c85, 0x9c86, 0x9c87, 0x9c88,
+ 0x9c89, 0x9c8a, 0x9c8b, 0x9c8c, 0x9c8d, 0x9c8e, 0x9c8f, 0x9c90,
+ 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, 0x9c98,
+ 0x9c99, 0x9c9a, 0x9c9b, 0x9c9c, 0x9c9d, 0x9c9e, 0x9c9f, 0x9ca0,
+ 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca4, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8,
+ 0x9ca9, 0x9caa, 0x9cab, 0x9cac, 0x9cad, 0x9cae, 0x9caf, 0x9cb0,
+ 0x9cb1, 0x9cb2, 0x9cb3, 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cb8,
+ 0x9cb9, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, 0x9cbe, 0x9cbf, 0x9cc0,
+ 0x9cc1, 0x9cc2, 0x9cc3, 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cc8,
+ 0x9cc9, 0x9cca, 0x9ccb, 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0,
+ 0x9cd1, 0x9cd2, 0x9cd3, 0x9cd4, 0x9cd5, 0x9cd6, 0x9cd7, 0x9cd8,
+ 0x9cd9, 0x9cda, 0x9cdb, 0x9cdc, 0x9cdd, 0x9cde, 0x9cdf, 0x9ce0,
+ 0x9ce1, 0x9ce2, 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8,
+ 0x9ce9, 0x9cea, 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 0x9cf0,
+ 0x9cf1, 0x9cf2, 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8,
+ 0x9cf9, 0x9cfa, 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9d40, 0x9d41,
+ 0x9d42, 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 0x9d48, 0x9d49,
+ 0x9d4a, 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 0x9d50, 0x9d51,
+ 0x9d52, 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59,
+ 0x9d5a, 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 0x9d60, 0x9d61,
+ 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 0x9d68, 0x9d69,
+ 0x9d6a, 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 0x9d70, 0x9d71,
+ 0x9d72, 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79,
+ 0x9d7a, 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d80, 0x9d81, 0x9d82,
+ 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88, 0x9d89, 0x9d8a,
+ 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, 0x9d91, 0x9d92,
+ 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9d99, 0x9d9a,
+ 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0x9da1, 0x9da2,
+ 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8, 0x9da9, 0x9daa,
+ 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0x9db1, 0x9db2,
+ 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8, 0x9db9, 0x9dba,
+ 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2,
+ 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca,
+ 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2,
+ 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8, 0x9dd9, 0x9dda,
+ 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, 0x9de1, 0x9de2,
+ 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8, 0x9de9, 0x9dea,
+ 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0, 0x9df1, 0x9df2,
+ 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0x9dfa,
+ 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9e40, 0x9e41, 0x9e42, 0x9e43,
+ 0x9e44, 0x9e45, 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4a, 0x9e4b,
+ 0x9e4c, 0x9e4d, 0x9e4e, 0x9e4f, 0x9e50, 0x9e51, 0x9e52, 0x9e53,
+ 0x9e54, 0x9e55, 0x9e56, 0x9e57, 0x9e58, 0x9e59, 0x9e5a, 0x9e5b,
+ 0x9e5c, 0x9e5d, 0x9e5e, 0x9e5f, 0x9e60, 0x9e61, 0x9e62, 0x9e63,
+ 0x9e64, 0x9e65, 0x9e66, 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b,
+ 0x9e6c, 0x9e6d, 0x9e6e, 0x9e6f, 0x9e70, 0x9e71, 0x9e72, 0x9e73,
+ 0x9e74, 0x9e75, 0x9e76, 0x9e77, 0x9e78, 0x9e79, 0x9e7a, 0x9e7b,
+ 0x9e7c, 0x9e7d, 0x9e7e, 0x9e80, 0x9e81, 0x9e82, 0x9e83, 0x9e84,
+ 0x9e85, 0x9e86, 0x9e87, 0x9e88, 0x9e89, 0x9e8a, 0x9e8b, 0x9e8c,
+ 0x9e8d, 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e92, 0x9e93, 0x9e94,
+ 0x9e95, 0x9e96, 0x9e97, 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c,
+ 0x9e9d, 0x9e9e, 0x9e9f, 0x9ea0, 0x9ea1, 0x9ea2, 0x9ea3, 0x9ea4,
+ 0x9ea5, 0x9ea6, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa, 0x9eab, 0x9eac,
+ 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2, 0x9eb3, 0x9eb4,
+ 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb8, 0x9eb9, 0x9eba, 0x9ebb, 0x9ebc,
+ 0x9ebd, 0x9ebe, 0x9ebf, 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec4,
+ 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, 0x9ec9, 0x9eca, 0x9ecb, 0x9ecc,
+ 0x9ecd, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed1, 0x9ed2, 0x9ed3, 0x9ed4,
+ 0x9ed5, 0x9ed6, 0x9ed7, 0x9ed8, 0x9ed9, 0x9eda, 0x9edb, 0x9edc,
+ 0x9edd, 0x9ede, 0x9edf, 0x9ee0, 0x9ee1, 0x9ee2, 0x9ee3, 0x9ee4,
+ 0x9ee5, 0x9ee6, 0x9ee7, 0x9ee8, 0x9ee9, 0x9eea, 0x9eeb, 0x9eec,
+ 0x9eed, 0x9eee, 0x9eef, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef3, 0x9ef4,
+ 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9ef9, 0x9efa, 0x9efb, 0x9efc,
+ 0x9efd, 0x9efe, 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f44, 0x9f45,
+ 0x9f46, 0x9f47, 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d,
+ 0x9f4e, 0x9f4f, 0x9f50, 0x9f51, 0x9f52, 0x9f53, 0x9f54, 0x9f55,
+ 0x9f56, 0x9f57, 0x9f58, 0x9f59, 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d,
+ 0x9f5e, 0x9f5f, 0x9f60, 0x9f61, 0x9f62, 0x9f63, 0x9f64, 0x9f65,
+ 0x9f66, 0x9f67, 0x9f68, 0x9f69, 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d,
+ 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, 0x9f72, 0x9f73, 0x9f74, 0x9f75,
+ 0x9f76, 0x9f77, 0x9f78, 0x9f79, 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d,
+ 0x9f7e, 0x9f80, 0x9f81, 0x9f82, 0x9f83, 0x9f84, 0x9f85, 0x9f86,
+ 0x9f87, 0x9f88, 0x9f89, 0x9f8a, 0x9f8b, 0x9f8c, 0x9f8d, 0x9f8e,
+ 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, 0x9f96,
+ 0x9f97, 0x9f98, 0x9f99, 0x9f9a, 0x9f9b, 0x9f9c, 0x9f9d, 0x9f9e,
+ 0x9f9f, 0x9fa0, 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa4, 0x9fa5, 0x9fa6,
+ 0x9fa7, 0x9fa8, 0x9fa9, 0x9faa, 0x9fab, 0x9fac, 0x9fad, 0x9fae,
+ 0x9faf, 0x9fb0, 0x9fb1, 0x9fb2, 0x9fb3, 0x9fb4, 0x9fb5, 0x9fb6,
+ 0x9fb7, 0x9fb8, 0x9fb9, 0x9fba, 0x9fbb, 0x9fbc, 0x9fbd, 0x9fbe,
+ 0x9fbf, 0x9fc0, 0x9fc1, 0x9fc2, 0x9fc3, 0x9fc4, 0x9fc5, 0x9fc6,
+ 0x9fc7, 0x9fc8, 0x9fc9, 0x9fca, 0x9fcb, 0x9fcc, 0x9fcd, 0x9fce,
+ 0x9fcf, 0x9fd0, 0x9fd1, 0x9fd2, 0x9fd3, 0x9fd4, 0x9fd5, 0x9fd6,
+ 0x9fd7, 0x9fd8, 0x9fd9, 0x9fda, 0x9fdb, 0x9fdc, 0x9fdd, 0x9fde,
+ 0x9fdf, 0x9fe0, 0x9fe1, 0x9fe2, 0x9fe3, 0x9fe4, 0x9fe5, 0x9fe6,
+ 0x9fe7, 0x9fe8, 0x9fe9, 0x9fea, 0x9feb, 0x9fec, 0x9fed, 0x9fee,
+ 0x9fef, 0x9ff0, 0x9ff1, 0x9ff2, 0x9ff3, 0x9ff4, 0x9ff5, 0x9ff6,
+ 0x9ff7, 0x9ff8, 0x9ff9, 0x9ffa, 0x9ffb, 0x9ffc, 0x9ffd, 0x9ffe,
+ 0xa040, 0xa041, 0xa042, 0xa043, 0xa044, 0xa045, 0xa046, 0xa047,
+ 0xa048, 0xa049, 0xa04a, 0xa04b, 0xa04c, 0xa04d, 0xa04e, 0xa04f,
+ 0xa050, 0xa051, 0xa052, 0xa053, 0xa054, 0xa055, 0xa056, 0xa057,
+ 0xa058, 0xa059, 0xa05a, 0xa05b, 0xa05c, 0xa05d, 0xa05e, 0xa05f,
+ 0xa060, 0xa061, 0xa062, 0xa063, 0xa064, 0xa065, 0xa066, 0xa067,
+ 0xa068, 0xa069, 0xa06a, 0xa06b, 0xa06c, 0xa06d, 0xa06e, 0xa06f,
+ 0xa070, 0xa071, 0xa072, 0xa073, 0xa074, 0xa075, 0xa076, 0xa077,
+ 0xa078, 0xa079, 0xa07a, 0xa07b, 0xa07c, 0xa07d, 0xa07e, 0xa080,
+ 0xa081, 0xa082, 0xa083, 0xa084, 0xa085, 0xa086, 0xa087, 0xa088,
+ 0xa089, 0xa08a, 0xa08b, 0xa08c, 0xa08d, 0xa08e, 0xa08f, 0xa090,
+ 0xa091, 0xa092, 0xa093, 0xa094, 0xa095, 0xa096, 0xa097, 0xa098,
+ 0xa099, 0xa09a, 0xa09b, 0xa09c, 0xa09d, 0xa09e, 0xa09f, 0xa0a0,
+ 0xa0a1, 0xa0a2, 0xa0a3, 0xa0a4, 0xa0a5, 0xa0a6, 0xa0a7, 0xa0a8,
+ 0xa0a9, 0xa0aa, 0xa0ab, 0xa0ac, 0xa0ad, 0xa0ae, 0xa0af, 0xa0b0,
+ 0xa0b1, 0xa0b2, 0xa0b3, 0xa0b4, 0xa0b5, 0xa0b6, 0xa0b7, 0xa0b8,
+ 0xa0b9, 0xa0ba, 0xa0bb, 0xa0bc, 0xa0bd, 0xa0be, 0xa0bf, 0xa0c0,
+ 0xa0c1, 0xa0c2, 0xa0c3, 0xa0c4, 0xa0c5, 0xa0c6, 0xa0c7, 0xa0c8,
+ 0xa0c9, 0xa0ca, 0xa0cb, 0xa0cc, 0xa0cd, 0xa0ce, 0xa0cf, 0xa0d0,
+ 0xa0d1, 0xa0d2, 0xa0d3, 0xa0d4, 0xa0d5, 0xa0d6, 0xa0d7, 0xa0d8,
+ 0xa0d9, 0xa0da, 0xa0db, 0xa0dc, 0xa0dd, 0xa0de, 0xa0df, 0xa0e0,
+ 0xa0e1, 0xa0e2, 0xa0e3, 0xa0e4, 0xa0e5, 0xa0e6, 0xa0e7, 0xa0e8,
+ 0xa0e9, 0xa0ea, 0xa0eb, 0xa0ec, 0xa0ed, 0xa0ee, 0xa0ef, 0xa0f0,
+ 0xa0f1, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f5, 0xa0f6, 0xa0f7, 0xa0f8,
+ 0xa0f9, 0xa0fa, 0xa0fb, 0xa0fc, 0xa0fd, 0xa0fe, 0xaa40, 0xaa41,
+ 0xaa42, 0xaa43, 0xaa44, 0xaa45, 0xaa46, 0xaa47, 0xaa48, 0xaa49,
+ 0xaa4a, 0xaa4b, 0xaa4c, 0xaa4d, 0xaa4e, 0xaa4f, 0xaa50, 0xaa51,
+ 0xaa52, 0xaa53, 0xaa54, 0xaa55, 0xaa56, 0xaa57, 0xaa58, 0xaa59,
+ 0xaa5a, 0xaa5b, 0xaa5c, 0xaa5d, 0xaa5e, 0xaa5f, 0xaa60, 0xaa61,
+ 0xaa62, 0xaa63, 0xaa64, 0xaa65, 0xaa66, 0xaa67, 0xaa68, 0xaa69,
+ 0xaa6a, 0xaa6b, 0xaa6c, 0xaa6d, 0xaa6e, 0xaa6f, 0xaa70, 0xaa71,
+ 0xaa72, 0xaa73, 0xaa74, 0xaa75, 0xaa76, 0xaa77, 0xaa78, 0xaa79,
+ 0xaa7a, 0xaa7b, 0xaa7c, 0xaa7d, 0xaa7e, 0xaa80, 0xaa81, 0xaa82,
+ 0xaa83, 0xaa84, 0xaa85, 0xaa86, 0xaa87, 0xaa88, 0xaa89, 0xaa8a,
+ 0xaa8b, 0xaa8c, 0xaa8d, 0xaa8e, 0xaa8f, 0xaa90, 0xaa91, 0xaa92,
+ 0xaa93, 0xaa94, 0xaa95, 0xaa96, 0xaa97, 0xaa98, 0xaa99, 0xaa9a,
+ 0xaa9b, 0xaa9c, 0xaa9d, 0xaa9e, 0xaa9f, 0xaaa0, 0xab40, 0xab41,
+ 0xab42, 0xab43, 0xab44, 0xab45, 0xab46, 0xab47, 0xab48, 0xab49,
+ 0xab4a, 0xab4b, 0xab4c, 0xab4d, 0xab4e, 0xab4f, 0xab50, 0xab51,
+ 0xab52, 0xab53, 0xab54, 0xab55, 0xab56, 0xab57, 0xab58, 0xab59,
+ 0xab5a, 0xab5b, 0xab5c, 0xab5d, 0xab5e, 0xab5f, 0xab60, 0xab61,
+ 0xab62, 0xab63, 0xab64, 0xab65, 0xab66, 0xab67, 0xab68, 0xab69,
+ 0xab6a, 0xab6b, 0xab6c, 0xab6d, 0xab6e, 0xab6f, 0xab70, 0xab71,
+ 0xab72, 0xab73, 0xab74, 0xab75, 0xab76, 0xab77, 0xab78, 0xab79,
+ 0xab7a, 0xab7b, 0xab7c, 0xab7d, 0xab7e, 0xab80, 0xab81, 0xab82,
+ 0xab83, 0xab84, 0xab85, 0xab86, 0xab87, 0xab88, 0xab89, 0xab8a,
+ 0xab8b, 0xab8c, 0xab8d, 0xab8e, 0xab8f, 0xab90, 0xab91, 0xab92,
+ 0xab93, 0xab94, 0xab95, 0xab96, 0xab97, 0xab98, 0xab99, 0xab9a,
+ 0xab9b, 0xab9c, 0xab9d, 0xab9e, 0xab9f, 0xaba0, 0xac40, 0xac41,
+ 0xac42, 0xac43, 0xac44, 0xac45, 0xac46, 0xac47, 0xac48, 0xac49,
+ 0xac4a, 0xac4b, 0xac4c, 0xac4d, 0xac4e, 0xac4f, 0xac50, 0xac51,
+ 0xac52, 0xac53, 0xac54, 0xac55, 0xac56, 0xac57, 0xac58, 0xac59,
+ 0xac5a, 0xac5b, 0xac5c, 0xac5d, 0xac5e, 0xac5f, 0xac60, 0xac61,
+ 0xac62, 0xac63, 0xac64, 0xac65, 0xac66, 0xac67, 0xac68, 0xac69,
+ 0xac6a, 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xac6f, 0xac70, 0xac71,
+ 0xac72, 0xac73, 0xac74, 0xac75, 0xac76, 0xac77, 0xac78, 0xac79,
+ 0xac7a, 0xac7b, 0xac7c, 0xac7d, 0xac7e, 0xac80, 0xac81, 0xac82,
+ 0xac83, 0xac84, 0xac85, 0xac86, 0xac87, 0xac88, 0xac89, 0xac8a,
+ 0xac8b, 0xac8c, 0xac8d, 0xac8e, 0xac8f, 0xac90, 0xac91, 0xac92,
+ 0xac93, 0xac94, 0xac95, 0xac96, 0xac97, 0xac98, 0xac99, 0xac9a,
+ 0xac9b, 0xac9c, 0xac9d, 0xac9e, 0xac9f, 0xaca0, 0xad40, 0xad41,
+ 0xad42, 0xad43, 0xad44, 0xad45, 0xad46, 0xad47, 0xad48, 0xad49,
+ 0xad4a, 0xad4b, 0xad4c, 0xad4d, 0xad4e, 0xad4f, 0xad50, 0xad51,
+ 0xad52, 0xad53, 0xad54, 0xad55, 0xad56, 0xad57, 0xad58, 0xad59,
+ 0xad5a, 0xad5b, 0xad5c, 0xad5d, 0xad5e, 0xad5f, 0xad60, 0xad61,
+ 0xad62, 0xad63, 0xad64, 0xad65, 0xad66, 0xad67, 0xad68, 0xad69,
+ 0xad6a, 0xad6b, 0xad6c, 0xad6d, 0xad6e, 0xad6f, 0xad70, 0xad71,
+ 0xad72, 0xad73, 0xad74, 0xad75, 0xad76, 0xad77, 0xad78, 0xad79,
+ 0xad7a, 0xad7b, 0xad7c, 0xad7d, 0xad7e, 0xad80, 0xad81, 0xad82,
+ 0xad83, 0xad84, 0xad85, 0xad86, 0xad87, 0xad88, 0xad89, 0xad8a,
+ 0xad8b, 0xad8c, 0xad8d, 0xad8e, 0xad8f, 0xad90, 0xad91, 0xad92,
+ 0xad93, 0xad94, 0xad95, 0xad96, 0xad97, 0xad98, 0xad99, 0xad9a,
+ 0xad9b, 0xad9c, 0xad9d, 0xad9e, 0xad9f, 0xada0, 0xae40, 0xae41,
+ 0xae42, 0xae43, 0xae44, 0xae45, 0xae46, 0xae47, 0xae48, 0xae49,
+ 0xae4a, 0xae4b, 0xae4c, 0xae4d, 0xae4e, 0xae4f, 0xae50, 0xae51,
+ 0xae52, 0xae53, 0xae54, 0xae55, 0xae56, 0xae57, 0xae58, 0xae59,
+ 0xae5a, 0xae5b, 0xae5c, 0xae5d, 0xae5e, 0xae5f, 0xae60, 0xae61,
+ 0xae62, 0xae63, 0xae64, 0xae65, 0xae66, 0xae67, 0xae68, 0xae69,
+ 0xae6a, 0xae6b, 0xae6c, 0xae6d, 0xae6e, 0xae6f, 0xae70, 0xae71,
+ 0xae72, 0xae73, 0xae74, 0xae75, 0xae76, 0xae77, 0xae78, 0xae79,
+ 0xae7a, 0xae7b, 0xae7c, 0xae7d, 0xae7e, 0xae80, 0xae81, 0xae82,
+ 0xae83, 0xae84, 0xae85, 0xae86, 0xae87, 0xae88, 0xae89, 0xae8a,
+ 0xae8b, 0xae8c, 0xae8d, 0xae8e, 0xae8f, 0xae90, 0xae91, 0xae92,
+ 0xae93, 0xae94, 0xae95, 0xae96, 0xae97, 0xae98, 0xae99, 0xae9a,
+ 0xae9b, 0xae9c, 0xae9d, 0xae9e, 0xae9f, 0xaea0, 0xaf40, 0xaf41,
+ 0xaf42, 0xaf43, 0xaf44, 0xaf45, 0xaf46, 0xaf47, 0xaf48, 0xaf49,
+ 0xaf4a, 0xaf4b, 0xaf4c, 0xaf4d, 0xaf4e, 0xaf4f, 0xaf50, 0xaf51,
+ 0xaf52, 0xaf53, 0xaf54, 0xaf55, 0xaf56, 0xaf57, 0xaf58, 0xaf59,
+ 0xaf5a, 0xaf5b, 0xaf5c, 0xaf5d, 0xaf5e, 0xaf5f, 0xaf60, 0xaf61,
+ 0xaf62, 0xaf63, 0xaf64, 0xaf65, 0xaf66, 0xaf67, 0xaf68, 0xaf69,
+ 0xaf6a, 0xaf6b, 0xaf6c, 0xaf6d, 0xaf6e, 0xaf6f, 0xaf70, 0xaf71,
+ 0xaf72, 0xaf73, 0xaf74, 0xaf75, 0xaf76, 0xaf77, 0xaf78, 0xaf79,
+ 0xaf7a, 0xaf7b, 0xaf7c, 0xaf7d, 0xaf7e, 0xaf80, 0xaf81, 0xaf82,
+ 0xaf83, 0xaf84, 0xaf85, 0xaf86, 0xaf87, 0xaf88, 0xaf89, 0xaf8a,
+ 0xaf8b, 0xaf8c, 0xaf8d, 0xaf8e, 0xaf8f, 0xaf90, 0xaf91, 0xaf92,
+ 0xaf93, 0xaf94, 0xaf95, 0xaf96, 0xaf97, 0xaf98, 0xaf99, 0xaf9a,
+ 0xaf9b, 0xaf9c, 0xaf9d, 0xaf9e, 0xaf9f, 0xafa0, 0xb040, 0xb041,
+ 0xb042, 0xb043, 0xb044, 0xb045, 0xb046, 0xb047, 0xb048, 0xb049,
+ 0xb04a, 0xb04b, 0xb04c, 0xb04d, 0xb04e, 0xb04f, 0xb050, 0xb051,
+ 0xb052, 0xb053, 0xb054, 0xb055, 0xb056, 0xb057, 0xb058, 0xb059,
+ 0xb05a, 0xb05b, 0xb05c, 0xb05d, 0xb05e, 0xb05f, 0xb060, 0xb061,
+ 0xb062, 0xb063, 0xb064, 0xb065, 0xb066, 0xb067, 0xb068, 0xb069,
+ 0xb06a, 0xb06b, 0xb06c, 0xb06d, 0xb06e, 0xb06f, 0xb070, 0xb071,
+ 0xb072, 0xb073, 0xb074, 0xb075, 0xb076, 0xb077, 0xb078, 0xb079,
+ 0xb07a, 0xb07b, 0xb07c, 0xb07d, 0xb07e, 0xb080, 0xb081, 0xb082,
+ 0xb083, 0xb084, 0xb085, 0xb086, 0xb087, 0xb088, 0xb089, 0xb08a,
+ 0xb08b, 0xb08c, 0xb08d, 0xb08e, 0xb08f, 0xb090, 0xb091, 0xb092,
+ 0xb093, 0xb094, 0xb095, 0xb096, 0xb097, 0xb098, 0xb099, 0xb09a,
+ 0xb09b, 0xb09c, 0xb09d, 0xb09e, 0xb09f, 0xb0a0, 0xb140, 0xb141,
+ 0xb142, 0xb143, 0xb144, 0xb145, 0xb146, 0xb147, 0xb148, 0xb149,
+ 0xb14a, 0xb14b, 0xb14c, 0xb14d, 0xb14e, 0xb14f, 0xb150, 0xb151,
+ 0xb152, 0xb153, 0xb154, 0xb155, 0xb156, 0xb157, 0xb158, 0xb159,
+ 0xb15a, 0xb15b, 0xb15c, 0xb15d, 0xb15e, 0xb15f, 0xb160, 0xb161,
+ 0xb162, 0xb163, 0xb164, 0xb165, 0xb166, 0xb167, 0xb168, 0xb169,
+ 0xb16a, 0xb16b, 0xb16c, 0xb16d, 0xb16e, 0xb16f, 0xb170, 0xb171,
+ 0xb172, 0xb173, 0xb174, 0xb175, 0xb176, 0xb177, 0xb178, 0xb179,
+ 0xb17a, 0xb17b, 0xb17c, 0xb17d, 0xb17e, 0xb180, 0xb181, 0xb182,
+ 0xb183, 0xb184, 0xb185, 0xb186, 0xb187, 0xb188, 0xb189, 0xb18a,
+ 0xb18b, 0xb18c, 0xb18d, 0xb18e, 0xb18f, 0xb190, 0xb191, 0xb192,
+ 0xb193, 0xb194, 0xb195, 0xb196, 0xb197, 0xb198, 0xb199, 0xb19a,
+ 0xb19b, 0xb19c, 0xb19d, 0xb19e, 0xb19f, 0xb1a0, 0xb240, 0xb241,
+ 0xb242, 0xb243, 0xb244, 0xb245, 0xb246, 0xb247, 0xb248, 0xb249,
+ 0xb24a, 0xb24b, 0xb24c, 0xb24d, 0xb24e, 0xb24f, 0xb250, 0xb251,
+ 0xb252, 0xb253, 0xb254, 0xb255, 0xb256, 0xb257, 0xb258, 0xb259,
+ 0xb25a, 0xb25b, 0xb25c, 0xb25d, 0xb25e, 0xb25f, 0xb260, 0xb261,
+ 0xb262, 0xb263, 0xb264, 0xb265, 0xb266, 0xb267, 0xb268, 0xb269,
+ 0xb26a, 0xb26b, 0xb26c, 0xb26d, 0xb26e, 0xb26f, 0xb270, 0xb271,
+ 0xb272, 0xb273, 0xb274, 0xb275, 0xb276, 0xb277, 0xb278, 0xb279,
+ 0xb27a, 0xb27b, 0xb27c, 0xb27d, 0xb27e, 0xb280, 0xb281, 0xb282,
+ 0xb283, 0xb284, 0xb285, 0xb286, 0xb287, 0xb288, 0xb289, 0xb28a,
+ 0xb28b, 0xb28c, 0xb28d, 0xb28e, 0xb28f, 0xb290, 0xb291, 0xb292,
+ 0xb293, 0xb294, 0xb295, 0xb296, 0xb297, 0xb298, 0xb299, 0xb29a,
+ 0xb29b, 0xb29c, 0xb29d, 0xb29e, 0xb29f, 0xb2a0, 0xb340, 0xb341,
+ 0xb342, 0xb343, 0xb344, 0xb345, 0xb346, 0xb347, 0xb348, 0xb349,
+ 0xb34a, 0xb34b, 0xb34c, 0xb34d, 0xb34e, 0xb34f, 0xb350, 0xb351,
+ 0xb352, 0xb353, 0xb354, 0xb355, 0xb356, 0xb357, 0xb358, 0xb359,
+ 0xb35a, 0xb35b, 0xb35c, 0xb35d, 0xb35e, 0xb35f, 0xb360, 0xb361,
+ 0xb362, 0xb363, 0xb364, 0xb365, 0xb366, 0xb367, 0xb368, 0xb369,
+ 0xb36a, 0xb36b, 0xb36c, 0xb36d, 0xb36e, 0xb36f, 0xb370, 0xb371,
+ 0xb372, 0xb373, 0xb374, 0xb375, 0xb376, 0xb377, 0xb378, 0xb379,
+ 0xb37a, 0xb37b, 0xb37c, 0xb37d, 0xb37e, 0xb380, 0xb381, 0xb382,
+ 0xb383, 0xb384, 0xb385, 0xb386, 0xb387, 0xb388, 0xb389, 0xb38a,
+ 0xb38b, 0xb38c, 0xb38d, 0xb38e, 0xb38f, 0xb390, 0xb391, 0xb392,
+ 0xb393, 0xb394, 0xb395, 0xb396, 0xb397, 0xb398, 0xb399, 0xb39a,
+ 0xb39b, 0xb39c, 0xb39d, 0xb39e, 0xb39f, 0xb3a0, 0xb440, 0xb441,
+ 0xb442, 0xb443, 0xb444, 0xb445, 0xb446, 0xb447, 0xb448, 0xb449,
+ 0xb44a, 0xb44b, 0xb44c, 0xb44d, 0xb44e, 0xb44f, 0xb450, 0xb451,
+ 0xb452, 0xb453, 0xb454, 0xb455, 0xb456, 0xb457, 0xb458, 0xb459,
+ 0xb45a, 0xb45b, 0xb45c, 0xb45d, 0xb45e, 0xb45f, 0xb460, 0xb461,
+ 0xb462, 0xb463, 0xb464, 0xb465, 0xb466, 0xb467, 0xb468, 0xb469,
+ 0xb46a, 0xb46b, 0xb46c, 0xb46d, 0xb46e, 0xb46f, 0xb470, 0xb471,
+ 0xb472, 0xb473, 0xb474, 0xb475, 0xb476, 0xb477, 0xb478, 0xb479,
+ 0xb47a, 0xb47b, 0xb47c, 0xb47d, 0xb47e, 0xb480, 0xb481, 0xb482,
+ 0xb483, 0xb484, 0xb485, 0xb486, 0xb487, 0xb488, 0xb489, 0xb48a,
+ 0xb48b, 0xb48c, 0xb48d, 0xb48e, 0xb48f, 0xb490, 0xb491, 0xb492,
+ 0xb493, 0xb494, 0xb495, 0xb496, 0xb497, 0xb498, 0xb499, 0xb49a,
+ 0xb49b, 0xb49c, 0xb49d, 0xb49e, 0xb49f, 0xb4a0, 0xb540, 0xb541,
+ 0xb542, 0xb543, 0xb544, 0xb545, 0xb546, 0xb547, 0xb548, 0xb549,
+ 0xb54a, 0xb54b, 0xb54c, 0xb54d, 0xb54e, 0xb54f, 0xb550, 0xb551,
+ 0xb552, 0xb553, 0xb554, 0xb555, 0xb556, 0xb557, 0xb558, 0xb559,
+ 0xb55a, 0xb55b, 0xb55c, 0xb55d, 0xb55e, 0xb55f, 0xb560, 0xb561,
+ 0xb562, 0xb563, 0xb564, 0xb565, 0xb566, 0xb567, 0xb568, 0xb569,
+ 0xb56a, 0xb56b, 0xb56c, 0xb56d, 0xb56e, 0xb56f, 0xb570, 0xb571,
+ 0xb572, 0xb573, 0xb574, 0xb575, 0xb576, 0xb577, 0xb578, 0xb579,
+ 0xb57a, 0xb57b, 0xb57c, 0xb57d, 0xb57e, 0xb580, 0xb581, 0xb582,
+ 0xb583, 0xb584, 0xb585, 0xb586, 0xb587, 0xb588, 0xb589, 0xb58a,
+ 0xb58b, 0xb58c, 0xb58d, 0xb58e, 0xb58f, 0xb590, 0xb591, 0xb592,
+ 0xb593, 0xb594, 0xb595, 0xb596, 0xb597, 0xb598, 0xb599, 0xb59a,
+ 0xb59b, 0xb59c, 0xb59d, 0xb59e, 0xb59f, 0xb5a0, 0xb640, 0xb641,
+ 0xb642, 0xb643, 0xb644, 0xb645, 0xb646, 0xb647, 0xb648, 0xb649,
+ 0xb64a, 0xb64b, 0xb64c, 0xb64d, 0xb64e, 0xb64f, 0xb650, 0xb651,
+ 0xb652, 0xb653, 0xb654, 0xb655, 0xb656, 0xb657, 0xb658, 0xb659,
+ 0xb65a, 0xb65b, 0xb65c, 0xb65d, 0xb65e, 0xb65f, 0xb660, 0xb661,
+ 0xb662, 0xb663, 0xb664, 0xb665, 0xb666, 0xb667, 0xb668, 0xb669,
+ 0xb66a, 0xb66b, 0xb66c, 0xb66d, 0xb66e, 0xb66f, 0xb670, 0xb671,
+ 0xb672, 0xb673, 0xb674, 0xb675, 0xb676, 0xb677, 0xb678, 0xb679,
+ 0xb67a, 0xb67b, 0xb67c, 0xb67d, 0xb67e, 0xb680, 0xb681, 0xb682,
+ 0xb683, 0xb684, 0xb685, 0xb686, 0xb687, 0xb688, 0xb689, 0xb68a,
+ 0xb68b, 0xb68c, 0xb68d, 0xb68e, 0xb68f, 0xb690, 0xb691, 0xb692,
+ 0xb693, 0xb694, 0xb695, 0xb696, 0xb697, 0xb698, 0xb699, 0xb69a,
+ 0xb69b, 0xb69c, 0xb69d, 0xb69e, 0xb69f, 0xb6a0, 0xb740, 0xb741,
+ 0xb742, 0xb743, 0xb744, 0xb745, 0xb746, 0xb747, 0xb748, 0xb749,
+ 0xb74a, 0xb74b, 0xb74c, 0xb74d, 0xb74e, 0xb74f, 0xb750, 0xb751,
+ 0xb752, 0xb753, 0xb754, 0xb755, 0xb756, 0xb757, 0xb758, 0xb759,
+ 0xb75a, 0xb75b, 0xb75c, 0xb75d, 0xb75e, 0xb75f, 0xb760, 0xb761,
+ 0xb762, 0xb763, 0xb764, 0xb765, 0xb766, 0xb767, 0xb768, 0xb769,
+ 0xb76a, 0xb76b, 0xb76c, 0xb76d, 0xb76e, 0xb76f, 0xb770, 0xb771,
+ 0xb772, 0xb773, 0xb774, 0xb775, 0xb776, 0xb777, 0xb778, 0xb779,
+ 0xb77a, 0xb77b, 0xb77c, 0xb77d, 0xb77e, 0xb780, 0xb781, 0xb782,
+ 0xb783, 0xb784, 0xb785, 0xb786, 0xb787, 0xb788, 0xb789, 0xb78a,
+ 0xb78b, 0xb78c, 0xb78d, 0xb78e, 0xb78f, 0xb790, 0xb791, 0xb792,
+ 0xb793, 0xb794, 0xb795, 0xb796, 0xb797, 0xb798, 0xb799, 0xb79a,
+ 0xb79b, 0xb79c, 0xb79d, 0xb79e, 0xb79f, 0xb7a0, 0xb840, 0xb841,
+ 0xb842, 0xb843, 0xb844, 0xb845, 0xb846, 0xb847, 0xb848, 0xb849,
+ 0xb84a, 0xb84b, 0xb84c, 0xb84d, 0xb84e, 0xb84f, 0xb850, 0xb851,
+ 0xb852, 0xb853, 0xb854, 0xb855, 0xb856, 0xb857, 0xb858, 0xb859,
+ 0xb85a, 0xb85b, 0xb85c, 0xb85d, 0xb85e, 0xb85f, 0xb860, 0xb861,
+ 0xb862, 0xb863, 0xb864, 0xb865, 0xb866, 0xb867, 0xb868, 0xb869,
+ 0xb86a, 0xb86b, 0xb86c, 0xb86d, 0xb86e, 0xb86f, 0xb870, 0xb871,
+ 0xb872, 0xb873, 0xb874, 0xb875, 0xb876, 0xb877, 0xb878, 0xb879,
+ 0xb87a, 0xb87b, 0xb87c, 0xb87d, 0xb87e, 0xb880, 0xb881, 0xb882,
+ 0xb883, 0xb884, 0xb885, 0xb886, 0xb887, 0xb888, 0xb889, 0xb88a,
+ 0xb88b, 0xb88c, 0xb88d, 0xb88e, 0xb88f, 0xb890, 0xb891, 0xb892,
+ 0xb893, 0xb894, 0xb895, 0xb896, 0xb897, 0xb898, 0xb899, 0xb89a,
+ 0xb89b, 0xb89c, 0xb89d, 0xb89e, 0xb89f, 0xb8a0, 0xb940, 0xb941,
+ 0xb942, 0xb943, 0xb944, 0xb945, 0xb946, 0xb947, 0xb948, 0xb949,
+ 0xb94a, 0xb94b, 0xb94c, 0xb94d, 0xb94e, 0xb94f, 0xb950, 0xb951,
+ 0xb952, 0xb953, 0xb954, 0xb955, 0xb956, 0xb957, 0xb958, 0xb959,
+ 0xb95a, 0xb95b, 0xb95c, 0xb95d, 0xb95e, 0xb95f, 0xb960, 0xb961,
+ 0xb962, 0xb963, 0xb964, 0xb965, 0xb966, 0xb967, 0xb968, 0xb969,
+ 0xb96a, 0xb96b, 0xb96c, 0xb96d, 0xb96e, 0xb96f, 0xb970, 0xb971,
+ 0xb972, 0xb973, 0xb974, 0xb975, 0xb976, 0xb977, 0xb978, 0xb979,
+ 0xb97a, 0xb97b, 0xb97c, 0xb97d, 0xb97e, 0xb980, 0xb981, 0xb982,
+ 0xb983, 0xb984, 0xb985, 0xb986, 0xb987, 0xb988, 0xb989, 0xb98a,
+ 0xb98b, 0xb98c, 0xb98d, 0xb98e, 0xb98f, 0xb990, 0xb991, 0xb992,
+ 0xb993, 0xb994, 0xb995, 0xb996, 0xb997, 0xb998, 0xb999, 0xb99a,
+ 0xb99b, 0xb99c, 0xb99d, 0xb99e, 0xb99f, 0xb9a0, 0xba40, 0xba41,
+ 0xba42, 0xba43, 0xba44, 0xba45, 0xba46, 0xba47, 0xba48, 0xba49,
+ 0xba4a, 0xba4b, 0xba4c, 0xba4d, 0xba4e, 0xba4f, 0xba50, 0xba51,
+ 0xba52, 0xba53, 0xba54, 0xba55, 0xba56, 0xba57, 0xba58, 0xba59,
+ 0xba5a, 0xba5b, 0xba5c, 0xba5d, 0xba5e, 0xba5f, 0xba60, 0xba61,
+ 0xba62, 0xba63, 0xba64, 0xba65, 0xba66, 0xba67, 0xba68, 0xba69,
+ 0xba6a, 0xba6b, 0xba6c, 0xba6d, 0xba6e, 0xba6f, 0xba70, 0xba71,
+ 0xba72, 0xba73, 0xba74, 0xba75, 0xba76, 0xba77, 0xba78, 0xba79,
+ 0xba7a, 0xba7b, 0xba7c, 0xba7d, 0xba7e, 0xba80, 0xba81, 0xba82,
+ 0xba83, 0xba84, 0xba85, 0xba86, 0xba87, 0xba88, 0xba89, 0xba8a,
+ 0xba8b, 0xba8c, 0xba8d, 0xba8e, 0xba8f, 0xba90, 0xba91, 0xba92,
+ 0xba93, 0xba94, 0xba95, 0xba96, 0xba97, 0xba98, 0xba99, 0xba9a,
+ 0xba9b, 0xba9c, 0xba9d, 0xba9e, 0xba9f, 0xbaa0, 0xbb40, 0xbb41,
+ 0xbb42, 0xbb43, 0xbb44, 0xbb45, 0xbb46, 0xbb47, 0xbb48, 0xbb49,
+ 0xbb4a, 0xbb4b, 0xbb4c, 0xbb4d, 0xbb4e, 0xbb4f, 0xbb50, 0xbb51,
+ 0xbb52, 0xbb53, 0xbb54, 0xbb55, 0xbb56, 0xbb57, 0xbb58, 0xbb59,
+ 0xbb5a, 0xbb5b, 0xbb5c, 0xbb5d, 0xbb5e, 0xbb5f, 0xbb60, 0xbb61,
+ 0xbb62, 0xbb63, 0xbb64, 0xbb65, 0xbb66, 0xbb67, 0xbb68, 0xbb69,
+ 0xbb6a, 0xbb6b, 0xbb6c, 0xbb6d, 0xbb6e, 0xbb6f, 0xbb70, 0xbb71,
+ 0xbb72, 0xbb73, 0xbb74, 0xbb75, 0xbb76, 0xbb77, 0xbb78, 0xbb79,
+ 0xbb7a, 0xbb7b, 0xbb7c, 0xbb7d, 0xbb7e, 0xbb80, 0xbb81, 0xbb82,
+ 0xbb83, 0xbb84, 0xbb85, 0xbb86, 0xbb87, 0xbb88, 0xbb89, 0xbb8a,
+ 0xbb8b, 0xbb8c, 0xbb8d, 0xbb8e, 0xbb8f, 0xbb90, 0xbb91, 0xbb92,
+ 0xbb93, 0xbb94, 0xbb95, 0xbb96, 0xbb97, 0xbb98, 0xbb99, 0xbb9a,
+ 0xbb9b, 0xbb9c, 0xbb9d, 0xbb9e, 0xbb9f, 0xbba0, 0xbc40, 0xbc41,
+ 0xbc42, 0xbc43, 0xbc44, 0xbc45, 0xbc46, 0xbc47, 0xbc48, 0xbc49,
+ 0xbc4a, 0xbc4b, 0xbc4c, 0xbc4d, 0xbc4e, 0xbc4f, 0xbc50, 0xbc51,
+ 0xbc52, 0xbc53, 0xbc54, 0xbc55, 0xbc56, 0xbc57, 0xbc58, 0xbc59,
+ 0xbc5a, 0xbc5b, 0xbc5c, 0xbc5d, 0xbc5e, 0xbc5f, 0xbc60, 0xbc61,
+ 0xbc62, 0xbc63, 0xbc64, 0xbc65, 0xbc66, 0xbc67, 0xbc68, 0xbc69,
+ 0xbc6a, 0xbc6b, 0xbc6c, 0xbc6d, 0xbc6e, 0xbc6f, 0xbc70, 0xbc71,
+ 0xbc72, 0xbc73, 0xbc74, 0xbc75, 0xbc76, 0xbc77, 0xbc78, 0xbc79,
+ 0xbc7a, 0xbc7b, 0xbc7c, 0xbc7d, 0xbc7e, 0xbc80, 0xbc81, 0xbc82,
+ 0xbc83, 0xbc84, 0xbc85, 0xbc86, 0xbc87, 0xbc88, 0xbc89, 0xbc8a,
+ 0xbc8b, 0xbc8c, 0xbc8d, 0xbc8e, 0xbc8f, 0xbc90, 0xbc91, 0xbc92,
+ 0xbc93, 0xbc94, 0xbc95, 0xbc96, 0xbc97, 0xbc98, 0xbc99, 0xbc9a,
+ 0xbc9b, 0xbc9c, 0xbc9d, 0xbc9e, 0xbc9f, 0xbca0, 0xbd40, 0xbd41,
+ 0xbd42, 0xbd43, 0xbd44, 0xbd45, 0xbd46, 0xbd47, 0xbd48, 0xbd49,
+ 0xbd4a, 0xbd4b, 0xbd4c, 0xbd4d, 0xbd4e, 0xbd4f, 0xbd50, 0xbd51,
+ 0xbd52, 0xbd53, 0xbd54, 0xbd55, 0xbd56, 0xbd57, 0xbd58, 0xbd59,
+ 0xbd5a, 0xbd5b, 0xbd5c, 0xbd5d, 0xbd5e, 0xbd5f, 0xbd60, 0xbd61,
+ 0xbd62, 0xbd63, 0xbd64, 0xbd65, 0xbd66, 0xbd67, 0xbd68, 0xbd69,
+ 0xbd6a, 0xbd6b, 0xbd6c, 0xbd6d, 0xbd6e, 0xbd6f, 0xbd70, 0xbd71,
+ 0xbd72, 0xbd73, 0xbd74, 0xbd75, 0xbd76, 0xbd77, 0xbd78, 0xbd79,
+ 0xbd7a, 0xbd7b, 0xbd7c, 0xbd7d, 0xbd7e, 0xbd80, 0xbd81, 0xbd82,
+ 0xbd83, 0xbd84, 0xbd85, 0xbd86, 0xbd87, 0xbd88, 0xbd89, 0xbd8a,
+ 0xbd8b, 0xbd8c, 0xbd8d, 0xbd8e, 0xbd8f, 0xbd90, 0xbd91, 0xbd92,
+ 0xbd93, 0xbd94, 0xbd95, 0xbd96, 0xbd97, 0xbd98, 0xbd99, 0xbd9a,
+ 0xbd9b, 0xbd9c, 0xbd9d, 0xbd9e, 0xbd9f, 0xbda0, 0xbe40, 0xbe41,
+ 0xbe42, 0xbe43, 0xbe44, 0xbe45, 0xbe46, 0xbe47, 0xbe48, 0xbe49,
+ 0xbe4a, 0xbe4b, 0xbe4c, 0xbe4d, 0xbe4e, 0xbe4f, 0xbe50, 0xbe51,
+ 0xbe52, 0xbe53, 0xbe54, 0xbe55, 0xbe56, 0xbe57, 0xbe58, 0xbe59,
+ 0xbe5a, 0xbe5b, 0xbe5c, 0xbe5d, 0xbe5e, 0xbe5f, 0xbe60, 0xbe61,
+ 0xbe62, 0xbe63, 0xbe64, 0xbe65, 0xbe66, 0xbe67, 0xbe68, 0xbe69,
+ 0xbe6a, 0xbe6b, 0xbe6c, 0xbe6d, 0xbe6e, 0xbe6f, 0xbe70, 0xbe71,
+ 0xbe72, 0xbe73, 0xbe74, 0xbe75, 0xbe76, 0xbe77, 0xbe78, 0xbe79,
+ 0xbe7a, 0xbe7b, 0xbe7c, 0xbe7d, 0xbe7e, 0xbe80, 0xbe81, 0xbe82,
+ 0xbe83, 0xbe84, 0xbe85, 0xbe86, 0xbe87, 0xbe88, 0xbe89, 0xbe8a,
+ 0xbe8b, 0xbe8c, 0xbe8d, 0xbe8e, 0xbe8f, 0xbe90, 0xbe91, 0xbe92,
+ 0xbe93, 0xbe94, 0xbe95, 0xbe96, 0xbe97, 0xbe98, 0xbe99, 0xbe9a,
+ 0xbe9b, 0xbe9c, 0xbe9d, 0xbe9e, 0xbe9f, 0xbea0, 0xbf40, 0xbf41,
+ 0xbf42, 0xbf43, 0xbf44, 0xbf45, 0xbf46, 0xbf47, 0xbf48, 0xbf49,
+ 0xbf4a, 0xbf4b, 0xbf4c, 0xbf4d, 0xbf4e, 0xbf4f, 0xbf50, 0xbf51,
+ 0xbf52, 0xbf53, 0xbf54, 0xbf55, 0xbf56, 0xbf57, 0xbf58, 0xbf59,
+ 0xbf5a, 0xbf5b, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf5f, 0xbf60, 0xbf61,
+ 0xbf62, 0xbf63, 0xbf64, 0xbf65, 0xbf66, 0xbf67, 0xbf68, 0xbf69,
+ 0xbf6a, 0xbf6b, 0xbf6c, 0xbf6d, 0xbf6e, 0xbf6f, 0xbf70, 0xbf71,
+ 0xbf72, 0xbf73, 0xbf74, 0xbf75, 0xbf76, 0xbf77, 0xbf78, 0xbf79,
+ 0xbf7a, 0xbf7b, 0xbf7c, 0xbf7d, 0xbf7e, 0xbf80, 0xbf81, 0xbf82,
+ 0xbf83, 0xbf84, 0xbf85, 0xbf86, 0xbf87, 0xbf88, 0xbf89, 0xbf8a,
+ 0xbf8b, 0xbf8c, 0xbf8d, 0xbf8e, 0xbf8f, 0xbf90, 0xbf91, 0xbf92,
+ 0xbf93, 0xbf94, 0xbf95, 0xbf96, 0xbf97, 0xbf98, 0xbf99, 0xbf9a,
+ 0xbf9b, 0xbf9c, 0xbf9d, 0xbf9e, 0xbf9f, 0xbfa0, 0xc040, 0xc041,
+ 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, 0xc047, 0xc048, 0xc049,
+ 0xc04a, 0xc04b, 0xc04c, 0xc04d, 0xc04e, 0xc04f, 0xc050, 0xc051,
+ 0xc052, 0xc053, 0xc054, 0xc055, 0xc056, 0xc057, 0xc058, 0xc059,
+ 0xc05a, 0xc05b, 0xc05c, 0xc05d, 0xc05e, 0xc05f, 0xc060, 0xc061,
+ 0xc062, 0xc063, 0xc064, 0xc065, 0xc066, 0xc067, 0xc068, 0xc069,
+ 0xc06a, 0xc06b, 0xc06c, 0xc06d, 0xc06e, 0xc06f, 0xc070, 0xc071,
+ 0xc072, 0xc073, 0xc074, 0xc075, 0xc076, 0xc077, 0xc078, 0xc079,
+ 0xc07a, 0xc07b, 0xc07c, 0xc07d, 0xc07e, 0xc080, 0xc081, 0xc082,
+ 0xc083, 0xc084, 0xc085, 0xc086, 0xc087, 0xc088, 0xc089, 0xc08a,
+ 0xc08b, 0xc08c, 0xc08d, 0xc08e, 0xc08f, 0xc090, 0xc091, 0xc092,
+ 0xc093, 0xc094, 0xc095, 0xc096, 0xc097, 0xc098, 0xc099, 0xc09a,
+ 0xc09b, 0xc09c, 0xc09d, 0xc09e, 0xc09f, 0xc0a0, 0xc140, 0xc141,
+ 0xc142, 0xc143, 0xc144, 0xc145, 0xc146, 0xc147, 0xc148, 0xc149,
+ 0xc14a, 0xc14b, 0xc14c, 0xc14d, 0xc14e, 0xc14f, 0xc150, 0xc151,
+ 0xc152, 0xc153, 0xc154, 0xc155, 0xc156, 0xc157, 0xc158, 0xc159,
+ 0xc15a, 0xc15b, 0xc15c, 0xc15d, 0xc15e, 0xc15f, 0xc160, 0xc161,
+ 0xc162, 0xc163, 0xc164, 0xc165, 0xc166, 0xc167, 0xc168, 0xc169,
+ 0xc16a, 0xc16b, 0xc16c, 0xc16d, 0xc16e, 0xc16f, 0xc170, 0xc171,
+ 0xc172, 0xc173, 0xc174, 0xc175, 0xc176, 0xc177, 0xc178, 0xc179,
+ 0xc17a, 0xc17b, 0xc17c, 0xc17d, 0xc17e, 0xc180, 0xc181, 0xc182,
+ 0xc183, 0xc184, 0xc185, 0xc186, 0xc187, 0xc188, 0xc189, 0xc18a,
+ 0xc18b, 0xc18c, 0xc18d, 0xc18e, 0xc18f, 0xc190, 0xc191, 0xc192,
+ 0xc193, 0xc194, 0xc195, 0xc196, 0xc197, 0xc198, 0xc199, 0xc19a,
+ 0xc19b, 0xc19c, 0xc19d, 0xc19e, 0xc19f, 0xc1a0, 0xc240, 0xc241,
+ 0xc242, 0xc243, 0xc244, 0xc245, 0xc246, 0xc247, 0xc248, 0xc249,
+ 0xc24a, 0xc24b, 0xc24c, 0xc24d, 0xc24e, 0xc24f, 0xc250, 0xc251,
+ 0xc252, 0xc253, 0xc254, 0xc255, 0xc256, 0xc257, 0xc258, 0xc259,
+ 0xc25a, 0xc25b, 0xc25c, 0xc25d, 0xc25e, 0xc25f, 0xc260, 0xc261,
+ 0xc262, 0xc263, 0xc264, 0xc265, 0xc266, 0xc267, 0xc268, 0xc269,
+ 0xc26a, 0xc26b, 0xc26c, 0xc26d, 0xc26e, 0xc26f, 0xc270, 0xc271,
+ 0xc272, 0xc273, 0xc274, 0xc275, 0xc276, 0xc277, 0xc278, 0xc279,
+ 0xc27a, 0xc27b, 0xc27c, 0xc27d, 0xc27e, 0xc280, 0xc281, 0xc282,
+ 0xc283, 0xc284, 0xc285, 0xc286, 0xc287, 0xc288, 0xc289, 0xc28a,
+ 0xc28b, 0xc28c, 0xc28d, 0xc28e, 0xc28f, 0xc290, 0xc291, 0xc292,
+ 0xc293, 0xc294, 0xc295, 0xc296, 0xc297, 0xc298, 0xc299, 0xc29a,
+ 0xc29b, 0xc29c, 0xc29d, 0xc29e, 0xc29f, 0xc2a0, 0xc340, 0xc341,
+ 0xc342, 0xc343, 0xc344, 0xc345, 0xc346, 0xc347, 0xc348, 0xc349,
+ 0xc34a, 0xc34b, 0xc34c, 0xc34d, 0xc34e, 0xc34f, 0xc350, 0xc351,
+ 0xc352, 0xc353, 0xc354, 0xc355, 0xc356, 0xc357, 0xc358, 0xc359,
+ 0xc35a, 0xc35b, 0xc35c, 0xc35d, 0xc35e, 0xc35f, 0xc360, 0xc361,
+ 0xc362, 0xc363, 0xc364, 0xc365, 0xc366, 0xc367, 0xc368, 0xc369,
+ 0xc36a, 0xc36b, 0xc36c, 0xc36d, 0xc36e, 0xc36f, 0xc370, 0xc371,
+ 0xc372, 0xc373, 0xc374, 0xc375, 0xc376, 0xc377, 0xc378, 0xc379,
+ 0xc37a, 0xc37b, 0xc37c, 0xc37d, 0xc37e, 0xc380, 0xc381, 0xc382,
+ 0xc383, 0xc384, 0xc385, 0xc386, 0xc387, 0xc388, 0xc389, 0xc38a,
+ 0xc38b, 0xc38c, 0xc38d, 0xc38e, 0xc38f, 0xc390, 0xc391, 0xc392,
+ 0xc393, 0xc394, 0xc395, 0xc396, 0xc397, 0xc398, 0xc399, 0xc39a,
+ 0xc39b, 0xc39c, 0xc39d, 0xc39e, 0xc39f, 0xc3a0, 0xc440, 0xc441,
+ 0xc442, 0xc443, 0xc444, 0xc445, 0xc446, 0xc447, 0xc448, 0xc449,
+ 0xc44a, 0xc44b, 0xc44c, 0xc44d, 0xc44e, 0xc44f, 0xc450, 0xc451,
+ 0xc452, 0xc453, 0xc454, 0xc455, 0xc456, 0xc457, 0xc458, 0xc459,
+ 0xc45a, 0xc45b, 0xc45c, 0xc45d, 0xc45e, 0xc45f, 0xc460, 0xc461,
+ 0xc462, 0xc463, 0xc464, 0xc465, 0xc466, 0xc467, 0xc468, 0xc469,
+ 0xc46a, 0xc46b, 0xc46c, 0xc46d, 0xc46e, 0xc46f, 0xc470, 0xc471,
+ 0xc472, 0xc473, 0xc474, 0xc475, 0xc476, 0xc477, 0xc478, 0xc479,
+ 0xc47a, 0xc47b, 0xc47c, 0xc47d, 0xc47e, 0xc480, 0xc481, 0xc482,
+ 0xc483, 0xc484, 0xc485, 0xc486, 0xc487, 0xc488, 0xc489, 0xc48a,
+ 0xc48b, 0xc48c, 0xc48d, 0xc48e, 0xc48f, 0xc490, 0xc491, 0xc492,
+ 0xc493, 0xc494, 0xc495, 0xc496, 0xc497, 0xc498, 0xc499, 0xc49a,
+ 0xc49b, 0xc49c, 0xc49d, 0xc49e, 0xc49f, 0xc4a0, 0xc540, 0xc541,
+ 0xc542, 0xc543, 0xc544, 0xc545, 0xc546, 0xc547, 0xc548, 0xc549,
+ 0xc54a, 0xc54b, 0xc54c, 0xc54d, 0xc54e, 0xc54f, 0xc550, 0xc551,
+ 0xc552, 0xc553, 0xc554, 0xc555, 0xc556, 0xc557, 0xc558, 0xc559,
+ 0xc55a, 0xc55b, 0xc55c, 0xc55d, 0xc55e, 0xc55f, 0xc560, 0xc561,
+ 0xc562, 0xc563, 0xc564, 0xc565, 0xc566, 0xc567, 0xc568, 0xc569,
+ 0xc56a, 0xc56b, 0xc56c, 0xc56d, 0xc56e, 0xc56f, 0xc570, 0xc571,
+ 0xc572, 0xc573, 0xc574, 0xc575, 0xc576, 0xc577, 0xc578, 0xc579,
+ 0xc57a, 0xc57b, 0xc57c, 0xc57d, 0xc57e, 0xc580, 0xc581, 0xc582,
+ 0xc583, 0xc584, 0xc585, 0xc586, 0xc587, 0xc588, 0xc589, 0xc58a,
+ 0xc58b, 0xc58c, 0xc58d, 0xc58e, 0xc58f, 0xc590, 0xc591, 0xc592,
+ 0xc593, 0xc594, 0xc595, 0xc596, 0xc597, 0xc598, 0xc599, 0xc59a,
+ 0xc59b, 0xc59c, 0xc59d, 0xc59e, 0xc59f, 0xc5a0, 0xc640, 0xc641,
+ 0xc642, 0xc643, 0xc644, 0xc645, 0xc646, 0xc647, 0xc648, 0xc649,
+ 0xc64a, 0xc64b, 0xc64c, 0xc64d, 0xc64e, 0xc64f, 0xc650, 0xc651,
+ 0xc652, 0xc653, 0xc654, 0xc655, 0xc656, 0xc657, 0xc658, 0xc659,
+ 0xc65a, 0xc65b, 0xc65c, 0xc65d, 0xc65e, 0xc65f, 0xc660, 0xc661,
+ 0xc662, 0xc663, 0xc664, 0xc665, 0xc666, 0xc667, 0xc668, 0xc669,
+ 0xc66a, 0xc66b, 0xc66c, 0xc66d, 0xc66e, 0xc66f, 0xc670, 0xc671,
+ 0xc672, 0xc673, 0xc674, 0xc675, 0xc676, 0xc677, 0xc678, 0xc679,
+ 0xc67a, 0xc67b, 0xc67c, 0xc67d, 0xc67e, 0xc680, 0xc681, 0xc682,
+ 0xc683, 0xc684, 0xc685, 0xc686, 0xc687, 0xc688, 0xc689, 0xc68a,
+ 0xc68b, 0xc68c, 0xc68d, 0xc68e, 0xc68f, 0xc690, 0xc691, 0xc692,
+ 0xc693, 0xc694, 0xc695, 0xc696, 0xc697, 0xc698, 0xc699, 0xc69a,
+ 0xc69b, 0xc69c, 0xc69d, 0xc69e, 0xc69f, 0xc6a0, 0xc740, 0xc741,
+ 0xc742, 0xc743, 0xc744, 0xc745, 0xc746, 0xc747, 0xc748, 0xc749,
+ 0xc74a, 0xc74b, 0xc74c, 0xc74d, 0xc74e, 0xc74f, 0xc750, 0xc751,
+ 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc759,
+ 0xc75a, 0xc75b, 0xc75c, 0xc75d, 0xc75e, 0xc75f, 0xc760, 0xc761,
+ 0xc762, 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 0xc768, 0xc769,
+ 0xc76a, 0xc76b, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 0xc770, 0xc771,
+ 0xc772, 0xc773, 0xc774, 0xc775, 0xc776, 0xc777, 0xc778, 0xc779,
+ 0xc77a, 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc780, 0xc781, 0xc782,
+ 0xc783, 0xc784, 0xc785, 0xc786, 0xc787, 0xc788, 0xc789, 0xc78a,
+ 0xc78b, 0xc78c, 0xc78d, 0xc78e, 0xc78f, 0xc790, 0xc791, 0xc792,
+ 0xc793, 0xc794, 0xc795, 0xc796, 0xc797, 0xc798, 0xc799, 0xc79a,
+ 0xc79b, 0xc79c, 0xc79d, 0xc79e, 0xc79f, 0xc7a0, 0xc840, 0xc841,
+ 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, 0xc847, 0xc848, 0xc849,
+ 0xc84a, 0xc84b, 0xc84c, 0xc84d, 0xc84e, 0xc84f, 0xc850, 0xc851,
+ 0xc852, 0xc853, 0xc854, 0xc855, 0xc856, 0xc857, 0xc858, 0xc859,
+ 0xc85a, 0xc85b, 0xc85c, 0xc85d, 0xc85e, 0xc85f, 0xc860, 0xc861,
+ 0xc862, 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, 0xc868, 0xc869,
+ 0xc86a, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, 0xc870, 0xc871,
+ 0xc872, 0xc873, 0xc874, 0xc875, 0xc876, 0xc877, 0xc878, 0xc879,
+ 0xc87a, 0xc87b, 0xc87c, 0xc87d, 0xc87e, 0xc880, 0xc881, 0xc882,
+ 0xc883, 0xc884, 0xc885, 0xc886, 0xc887, 0xc888, 0xc889, 0xc88a,
+ 0xc88b, 0xc88c, 0xc88d, 0xc88e, 0xc88f, 0xc890, 0xc891, 0xc892,
+ 0xc893, 0xc894, 0xc895, 0xc896, 0xc897, 0xc898, 0xc899, 0xc89a,
+ 0xc89b, 0xc89c, 0xc89d, 0xc89e, 0xc89f, 0xc8a0, 0xc940, 0xc941,
+ 0xc942, 0xc943, 0xc944, 0xc945, 0xc946, 0xc947, 0xc948, 0xc949,
+ 0xc94a, 0xc94b, 0xc94c, 0xc94d, 0xc94e, 0xc94f, 0xc950, 0xc951,
+ 0xc952, 0xc953, 0xc954, 0xc955, 0xc956, 0xc957, 0xc958, 0xc959,
+ 0xc95a, 0xc95b, 0xc95c, 0xc95d, 0xc95e, 0xc95f, 0xc960, 0xc961,
+ 0xc962, 0xc963, 0xc964, 0xc965, 0xc966, 0xc967, 0xc968, 0xc969,
+ 0xc96a, 0xc96b, 0xc96c, 0xc96d, 0xc96e, 0xc96f, 0xc970, 0xc971,
+ 0xc972, 0xc973, 0xc974, 0xc975, 0xc976, 0xc977, 0xc978, 0xc979,
+ 0xc97a, 0xc97b, 0xc97c, 0xc97d, 0xc97e, 0xc980, 0xc981, 0xc982,
+ 0xc983, 0xc984, 0xc985, 0xc986, 0xc987, 0xc988, 0xc989, 0xc98a,
+ 0xc98b, 0xc98c, 0xc98d, 0xc98e, 0xc98f, 0xc990, 0xc991, 0xc992,
+ 0xc993, 0xc994, 0xc995, 0xc996, 0xc997, 0xc998, 0xc999, 0xc99a,
+ 0xc99b, 0xc99c, 0xc99d, 0xc99e, 0xc99f, 0xc9a0, 0xca40, 0xca41,
+ 0xca42, 0xca43, 0xca44, 0xca45, 0xca46, 0xca47, 0xca48, 0xca49,
+ 0xca4a, 0xca4b, 0xca4c, 0xca4d, 0xca4e, 0xca4f, 0xca50, 0xca51,
+ 0xca52, 0xca53, 0xca54, 0xca55, 0xca56, 0xca57, 0xca58, 0xca59,
+ 0xca5a, 0xca5b, 0xca5c, 0xca5d, 0xca5e, 0xca5f, 0xca60, 0xca61,
+ 0xca62, 0xca63, 0xca64, 0xca65, 0xca66, 0xca67, 0xca68, 0xca69,
+ 0xca6a, 0xca6b, 0xca6c, 0xca6d, 0xca6e, 0xca6f, 0xca70, 0xca71,
+ 0xca72, 0xca73, 0xca74, 0xca75, 0xca76, 0xca77, 0xca78, 0xca79,
+ 0xca7a, 0xca7b, 0xca7c, 0xca7d, 0xca7e, 0xca80, 0xca81, 0xca82,
+ 0xca83, 0xca84, 0xca85, 0xca86, 0xca87, 0xca88, 0xca89, 0xca8a,
+ 0xca8b, 0xca8c, 0xca8d, 0xca8e, 0xca8f, 0xca90, 0xca91, 0xca92,
+ 0xca93, 0xca94, 0xca95, 0xca96, 0xca97, 0xca98, 0xca99, 0xca9a,
+ 0xca9b, 0xca9c, 0xca9d, 0xca9e, 0xca9f, 0xcaa0, 0xcb40, 0xcb41,
+ 0xcb42, 0xcb43, 0xcb44, 0xcb45, 0xcb46, 0xcb47, 0xcb48, 0xcb49,
+ 0xcb4a, 0xcb4b, 0xcb4c, 0xcb4d, 0xcb4e, 0xcb4f, 0xcb50, 0xcb51,
+ 0xcb52, 0xcb53, 0xcb54, 0xcb55, 0xcb56, 0xcb57, 0xcb58, 0xcb59,
+ 0xcb5a, 0xcb5b, 0xcb5c, 0xcb5d, 0xcb5e, 0xcb5f, 0xcb60, 0xcb61,
+ 0xcb62, 0xcb63, 0xcb64, 0xcb65, 0xcb66, 0xcb67, 0xcb68, 0xcb69,
+ 0xcb6a, 0xcb6b, 0xcb6c, 0xcb6d, 0xcb6e, 0xcb6f, 0xcb70, 0xcb71,
+ 0xcb72, 0xcb73, 0xcb74, 0xcb75, 0xcb76, 0xcb77, 0xcb78, 0xcb79,
+ 0xcb7a, 0xcb7b, 0xcb7c, 0xcb7d, 0xcb7e, 0xcb80, 0xcb81, 0xcb82,
+ 0xcb83, 0xcb84, 0xcb85, 0xcb86, 0xcb87, 0xcb88, 0xcb89, 0xcb8a,
+ 0xcb8b, 0xcb8c, 0xcb8d, 0xcb8e, 0xcb8f, 0xcb90, 0xcb91, 0xcb92,
+ 0xcb93, 0xcb94, 0xcb95, 0xcb96, 0xcb97, 0xcb98, 0xcb99, 0xcb9a,
+ 0xcb9b, 0xcb9c, 0xcb9d, 0xcb9e, 0xcb9f, 0xcba0, 0xcc40, 0xcc41,
+ 0xcc42, 0xcc43, 0xcc44, 0xcc45, 0xcc46, 0xcc47, 0xcc48, 0xcc49,
+ 0xcc4a, 0xcc4b, 0xcc4c, 0xcc4d, 0xcc4e, 0xcc4f, 0xcc50, 0xcc51,
+ 0xcc52, 0xcc53, 0xcc54, 0xcc55, 0xcc56, 0xcc57, 0xcc58, 0xcc59,
+ 0xcc5a, 0xcc5b, 0xcc5c, 0xcc5d, 0xcc5e, 0xcc5f, 0xcc60, 0xcc61,
+ 0xcc62, 0xcc63, 0xcc64, 0xcc65, 0xcc66, 0xcc67, 0xcc68, 0xcc69,
+ 0xcc6a, 0xcc6b, 0xcc6c, 0xcc6d, 0xcc6e, 0xcc6f, 0xcc70, 0xcc71,
+ 0xcc72, 0xcc73, 0xcc74, 0xcc75, 0xcc76, 0xcc77, 0xcc78, 0xcc79,
+ 0xcc7a, 0xcc7b, 0xcc7c, 0xcc7d, 0xcc7e, 0xcc80, 0xcc81, 0xcc82,
+ 0xcc83, 0xcc84, 0xcc85, 0xcc86, 0xcc87, 0xcc88, 0xcc89, 0xcc8a,
+ 0xcc8b, 0xcc8c, 0xcc8d, 0xcc8e, 0xcc8f, 0xcc90, 0xcc91, 0xcc92,
+ 0xcc93, 0xcc94, 0xcc95, 0xcc96, 0xcc97, 0xcc98, 0xcc99, 0xcc9a,
+ 0xcc9b, 0xcc9c, 0xcc9d, 0xcc9e, 0xcc9f, 0xcca0, 0xcd40, 0xcd41,
+ 0xcd42, 0xcd43, 0xcd44, 0xcd45, 0xcd46, 0xcd47, 0xcd48, 0xcd49,
+ 0xcd4a, 0xcd4b, 0xcd4c, 0xcd4d, 0xcd4e, 0xcd4f, 0xcd50, 0xcd51,
+ 0xcd52, 0xcd53, 0xcd54, 0xcd55, 0xcd56, 0xcd57, 0xcd58, 0xcd59,
+ 0xcd5a, 0xcd5b, 0xcd5c, 0xcd5d, 0xcd5e, 0xcd5f, 0xcd60, 0xcd61,
+ 0xcd62, 0xcd63, 0xcd64, 0xcd65, 0xcd66, 0xcd67, 0xcd68, 0xcd69,
+ 0xcd6a, 0xcd6b, 0xcd6c, 0xcd6d, 0xcd6e, 0xcd6f, 0xcd70, 0xcd71,
+ 0xcd72, 0xcd73, 0xcd74, 0xcd75, 0xcd76, 0xcd77, 0xcd78, 0xcd79,
+ 0xcd7a, 0xcd7b, 0xcd7c, 0xcd7d, 0xcd7e, 0xcd80, 0xcd81, 0xcd82,
+ 0xcd83, 0xcd84, 0xcd85, 0xcd86, 0xcd87, 0xcd88, 0xcd89, 0xcd8a,
+ 0xcd8b, 0xcd8c, 0xcd8d, 0xcd8e, 0xcd8f, 0xcd90, 0xcd91, 0xcd92,
+ 0xcd93, 0xcd94, 0xcd95, 0xcd96, 0xcd97, 0xcd98, 0xcd99, 0xcd9a,
+ 0xcd9b, 0xcd9c, 0xcd9d, 0xcd9e, 0xcd9f, 0xcda0, 0xce40, 0xce41,
+ 0xce42, 0xce43, 0xce44, 0xce45, 0xce46, 0xce47, 0xce48, 0xce49,
+ 0xce4a, 0xce4b, 0xce4c, 0xce4d, 0xce4e, 0xce4f, 0xce50, 0xce51,
+ 0xce52, 0xce53, 0xce54, 0xce55, 0xce56, 0xce57, 0xce58, 0xce59,
+ 0xce5a, 0xce5b, 0xce5c, 0xce5d, 0xce5e, 0xce5f, 0xce60, 0xce61,
+ 0xce62, 0xce63, 0xce64, 0xce65, 0xce66, 0xce67, 0xce68, 0xce69,
+ 0xce6a, 0xce6b, 0xce6c, 0xce6d, 0xce6e, 0xce6f, 0xce70, 0xce71,
+ 0xce72, 0xce73, 0xce74, 0xce75, 0xce76, 0xce77, 0xce78, 0xce79,
+ 0xce7a, 0xce7b, 0xce7c, 0xce7d, 0xce7e, 0xce80, 0xce81, 0xce82,
+ 0xce83, 0xce84, 0xce85, 0xce86, 0xce87, 0xce88, 0xce89, 0xce8a,
+ 0xce8b, 0xce8c, 0xce8d, 0xce8e, 0xce8f, 0xce90, 0xce91, 0xce92,
+ 0xce93, 0xce94, 0xce95, 0xce96, 0xce97, 0xce98, 0xce99, 0xce9a,
+ 0xce9b, 0xce9c, 0xce9d, 0xce9e, 0xce9f, 0xcea0, 0xcf40, 0xcf41,
+ 0xcf42, 0xcf43, 0xcf44, 0xcf45, 0xcf46, 0xcf47, 0xcf48, 0xcf49,
+ 0xcf4a, 0xcf4b, 0xcf4c, 0xcf4d, 0xcf4e, 0xcf4f, 0xcf50, 0xcf51,
+ 0xcf52, 0xcf53, 0xcf54, 0xcf55, 0xcf56, 0xcf57, 0xcf58, 0xcf59,
+ 0xcf5a, 0xcf5b, 0xcf5c, 0xcf5d, 0xcf5e, 0xcf5f, 0xcf60, 0xcf61,
+ 0xcf62, 0xcf63, 0xcf64, 0xcf65, 0xcf66, 0xcf67, 0xcf68, 0xcf69,
+ 0xcf6a, 0xcf6b, 0xcf6c, 0xcf6d, 0xcf6e, 0xcf6f, 0xcf70, 0xcf71,
+ 0xcf72, 0xcf73, 0xcf74, 0xcf75, 0xcf76, 0xcf77, 0xcf78, 0xcf79,
+ 0xcf7a, 0xcf7b, 0xcf7c, 0xcf7d, 0xcf7e, 0xcf80, 0xcf81, 0xcf82,
+ 0xcf83, 0xcf84, 0xcf85, 0xcf86, 0xcf87, 0xcf88, 0xcf89, 0xcf8a,
+ 0xcf8b, 0xcf8c, 0xcf8d, 0xcf8e, 0xcf8f, 0xcf90, 0xcf91, 0xcf92,
+ 0xcf93, 0xcf94, 0xcf95, 0xcf96, 0xcf97, 0xcf98, 0xcf99, 0xcf9a,
+ 0xcf9b, 0xcf9c, 0xcf9d, 0xcf9e, 0xcf9f, 0xcfa0, 0xd040, 0xd041,
+ 0xd042, 0xd043, 0xd044, 0xd045, 0xd046, 0xd047, 0xd048, 0xd049,
+ 0xd04a, 0xd04b, 0xd04c, 0xd04d, 0xd04e, 0xd04f, 0xd050, 0xd051,
+ 0xd052, 0xd053, 0xd054, 0xd055, 0xd056, 0xd057, 0xd058, 0xd059,
+ 0xd05a, 0xd05b, 0xd05c, 0xd05d, 0xd05e, 0xd05f, 0xd060, 0xd061,
+ 0xd062, 0xd063, 0xd064, 0xd065, 0xd066, 0xd067, 0xd068, 0xd069,
+ 0xd06a, 0xd06b, 0xd06c, 0xd06d, 0xd06e, 0xd06f, 0xd070, 0xd071,
+ 0xd072, 0xd073, 0xd074, 0xd075, 0xd076, 0xd077, 0xd078, 0xd079,
+ 0xd07a, 0xd07b, 0xd07c, 0xd07d, 0xd07e, 0xd080, 0xd081, 0xd082,
+ 0xd083, 0xd084, 0xd085, 0xd086, 0xd087, 0xd088, 0xd089, 0xd08a,
+ 0xd08b, 0xd08c, 0xd08d, 0xd08e, 0xd08f, 0xd090, 0xd091, 0xd092,
+ 0xd093, 0xd094, 0xd095, 0xd096, 0xd097, 0xd098, 0xd099, 0xd09a,
+ 0xd09b, 0xd09c, 0xd09d, 0xd09e, 0xd09f, 0xd0a0, 0xd140, 0xd141,
+ 0xd142, 0xd143, 0xd144, 0xd145, 0xd146, 0xd147, 0xd148, 0xd149,
+ 0xd14a, 0xd14b, 0xd14c, 0xd14d, 0xd14e, 0xd14f, 0xd150, 0xd151,
+ 0xd152, 0xd153, 0xd154, 0xd155, 0xd156, 0xd157, 0xd158, 0xd159,
+ 0xd15a, 0xd15b, 0xd15c, 0xd15d, 0xd15e, 0xd15f, 0xd160, 0xd161,
+ 0xd162, 0xd163, 0xd164, 0xd165, 0xd166, 0xd167, 0xd168, 0xd169,
+ 0xd16a, 0xd16b, 0xd16c, 0xd16d, 0xd16e, 0xd16f, 0xd170, 0xd171,
+ 0xd172, 0xd173, 0xd174, 0xd175, 0xd176, 0xd177, 0xd178, 0xd179,
+ 0xd17a, 0xd17b, 0xd17c, 0xd17d, 0xd17e, 0xd180, 0xd181, 0xd182,
+ 0xd183, 0xd184, 0xd185, 0xd186, 0xd187, 0xd188, 0xd189, 0xd18a,
+ 0xd18b, 0xd18c, 0xd18d, 0xd18e, 0xd18f, 0xd190, 0xd191, 0xd192,
+ 0xd193, 0xd194, 0xd195, 0xd196, 0xd197, 0xd198, 0xd199, 0xd19a,
+ 0xd19b, 0xd19c, 0xd19d, 0xd19e, 0xd19f, 0xd1a0, 0xd240, 0xd241,
+ 0xd242, 0xd243, 0xd244, 0xd245, 0xd246, 0xd247, 0xd248, 0xd249,
+ 0xd24a, 0xd24b, 0xd24c, 0xd24d, 0xd24e, 0xd24f, 0xd250, 0xd251,
+ 0xd252, 0xd253, 0xd254, 0xd255, 0xd256, 0xd257, 0xd258, 0xd259,
+ 0xd25a, 0xd25b, 0xd25c, 0xd25d, 0xd25e, 0xd25f, 0xd260, 0xd261,
+ 0xd262, 0xd263, 0xd264, 0xd265, 0xd266, 0xd267, 0xd268, 0xd269,
+ 0xd26a, 0xd26b, 0xd26c, 0xd26d, 0xd26e, 0xd26f, 0xd270, 0xd271,
+ 0xd272, 0xd273, 0xd274, 0xd275, 0xd276, 0xd277, 0xd278, 0xd279,
+ 0xd27a, 0xd27b, 0xd27c, 0xd27d, 0xd27e, 0xd280, 0xd281, 0xd282,
+ 0xd283, 0xd284, 0xd285, 0xd286, 0xd287, 0xd288, 0xd289, 0xd28a,
+ 0xd28b, 0xd28c, 0xd28d, 0xd28e, 0xd28f, 0xd290, 0xd291, 0xd292,
+ 0xd293, 0xd294, 0xd295, 0xd296, 0xd297, 0xd298, 0xd299, 0xd29a,
+ 0xd29b, 0xd29c, 0xd29d, 0xd29e, 0xd29f, 0xd2a0, 0xd340, 0xd341,
+ 0xd342, 0xd343, 0xd344, 0xd345, 0xd346, 0xd347, 0xd348, 0xd349,
+ 0xd34a, 0xd34b, 0xd34c, 0xd34d, 0xd34e, 0xd34f, 0xd350, 0xd351,
+ 0xd352, 0xd353, 0xd354, 0xd355, 0xd356, 0xd357, 0xd358, 0xd359,
+ 0xd35a, 0xd35b, 0xd35c, 0xd35d, 0xd35e, 0xd35f, 0xd360, 0xd361,
+ 0xd362, 0xd363, 0xd364, 0xd365, 0xd366, 0xd367, 0xd368, 0xd369,
+ 0xd36a, 0xd36b, 0xd36c, 0xd36d, 0xd36e, 0xd36f, 0xd370, 0xd371,
+ 0xd372, 0xd373, 0xd374, 0xd375, 0xd376, 0xd377, 0xd378, 0xd379,
+ 0xd37a, 0xd37b, 0xd37c, 0xd37d, 0xd37e, 0xd380, 0xd381, 0xd382,
+ 0xd383, 0xd384, 0xd385, 0xd386, 0xd387, 0xd388, 0xd389, 0xd38a,
+ 0xd38b, 0xd38c, 0xd38d, 0xd38e, 0xd38f, 0xd390, 0xd391, 0xd392,
+ 0xd393, 0xd394, 0xd395, 0xd396, 0xd397, 0xd398, 0xd399, 0xd39a,
+ 0xd39b, 0xd39c, 0xd39d, 0xd39e, 0xd39f, 0xd3a0, 0xd440, 0xd441,
+ 0xd442, 0xd443, 0xd444, 0xd445, 0xd446, 0xd447, 0xd448, 0xd449,
+ 0xd44a, 0xd44b, 0xd44c, 0xd44d, 0xd44e, 0xd44f, 0xd450, 0xd451,
+ 0xd452, 0xd453, 0xd454, 0xd455, 0xd456, 0xd457, 0xd458, 0xd459,
+ 0xd45a, 0xd45b, 0xd45c, 0xd45d, 0xd45e, 0xd45f, 0xd460, 0xd461,
+ 0xd462, 0xd463, 0xd464, 0xd465, 0xd466, 0xd467, 0xd468, 0xd469,
+ 0xd46a, 0xd46b, 0xd46c, 0xd46d, 0xd46e, 0xd46f, 0xd470, 0xd471,
+ 0xd472, 0xd473, 0xd474, 0xd475, 0xd476, 0xd477, 0xd478, 0xd479,
+ 0xd47a, 0xd47b, 0xd47c, 0xd47d, 0xd47e, 0xd480, 0xd481, 0xd482,
+ 0xd483, 0xd484, 0xd485, 0xd486, 0xd487, 0xd488, 0xd489, 0xd48a,
+ 0xd48b, 0xd48c, 0xd48d, 0xd48e, 0xd48f, 0xd490, 0xd491, 0xd492,
+ 0xd493, 0xd494, 0xd495, 0xd496, 0xd497, 0xd498, 0xd499, 0xd49a,
+ 0xd49b, 0xd49c, 0xd49d, 0xd49e, 0xd49f, 0xd4a0, 0xd540, 0xd541,
+ 0xd542, 0xd543, 0xd544, 0xd545, 0xd546, 0xd547, 0xd548, 0xd549,
+ 0xd54a, 0xd54b, 0xd54c, 0xd54d, 0xd54e, 0xd54f, 0xd550, 0xd551,
+ 0xd552, 0xd553, 0xd554, 0xd555, 0xd556, 0xd557, 0xd558, 0xd559,
+ 0xd55a, 0xd55b, 0xd55c, 0xd55d, 0xd55e, 0xd55f, 0xd560, 0xd561,
+ 0xd562, 0xd563, 0xd564, 0xd565, 0xd566, 0xd567, 0xd568, 0xd569,
+ 0xd56a, 0xd56b, 0xd56c, 0xd56d, 0xd56e, 0xd56f, 0xd570, 0xd571,
+ 0xd572, 0xd573, 0xd574, 0xd575, 0xd576, 0xd577, 0xd578, 0xd579,
+ 0xd57a, 0xd57b, 0xd57c, 0xd57d, 0xd57e, 0xd580, 0xd581, 0xd582,
+ 0xd583, 0xd584, 0xd585, 0xd586, 0xd587, 0xd588, 0xd589, 0xd58a,
+ 0xd58b, 0xd58c, 0xd58d, 0xd58e, 0xd58f, 0xd590, 0xd591, 0xd592,
+ 0xd593, 0xd594, 0xd595, 0xd596, 0xd597, 0xd598, 0xd599, 0xd59a,
+ 0xd59b, 0xd59c, 0xd59d, 0xd59e, 0xd59f, 0xd5a0, 0xd640, 0xd641,
+ 0xd642, 0xd643, 0xd644, 0xd645, 0xd646, 0xd647, 0xd648, 0xd649,
+ 0xd64a, 0xd64b, 0xd64c, 0xd64d, 0xd64e, 0xd64f, 0xd650, 0xd651,
+ 0xd652, 0xd653, 0xd654, 0xd655, 0xd656, 0xd657, 0xd658, 0xd659,
+ 0xd65a, 0xd65b, 0xd65c, 0xd65d, 0xd65e, 0xd65f, 0xd660, 0xd661,
+ 0xd662, 0xd663, 0xd664, 0xd665, 0xd666, 0xd667, 0xd668, 0xd669,
+ 0xd66a, 0xd66b, 0xd66c, 0xd66d, 0xd66e, 0xd66f, 0xd670, 0xd671,
+ 0xd672, 0xd673, 0xd674, 0xd675, 0xd676, 0xd677, 0xd678, 0xd679,
+ 0xd67a, 0xd67b, 0xd67c, 0xd67d, 0xd67e, 0xd680, 0xd681, 0xd682,
+ 0xd683, 0xd684, 0xd685, 0xd686, 0xd687, 0xd688, 0xd689, 0xd68a,
+ 0xd68b, 0xd68c, 0xd68d, 0xd68e, 0xd68f, 0xd690, 0xd691, 0xd692,
+ 0xd693, 0xd694, 0xd695, 0xd696, 0xd697, 0xd698, 0xd699, 0xd69a,
+ 0xd69b, 0xd69c, 0xd69d, 0xd69e, 0xd69f, 0xd6a0, 0xd740, 0xd741,
+ 0xd742, 0xd743, 0xd744, 0xd745, 0xd746, 0xd747, 0xd748, 0xd749,
+ 0xd74a, 0xd74b, 0xd74c, 0xd74d, 0xd74e, 0xd74f, 0xd750, 0xd751,
+ 0xd752, 0xd753, 0xd754, 0xd755, 0xd756, 0xd757, 0xd758, 0xd759,
+ 0xd75a, 0xd75b, 0xd75c, 0xd75d, 0xd75e, 0xd75f, 0xd760, 0xd761,
+ 0xd762, 0xd763, 0xd764, 0xd765, 0xd766, 0xd767, 0xd768, 0xd769,
+ 0xd76a, 0xd76b, 0xd76c, 0xd76d, 0xd76e, 0xd76f, 0xd770, 0xd771,
+ 0xd772, 0xd773, 0xd774, 0xd775, 0xd776, 0xd777, 0xd778, 0xd779,
+ 0xd77a, 0xd77b, 0xd77c, 0xd77d, 0xd77e, 0xd780, 0xd781, 0xd782,
+ 0xd783, 0xd784, 0xd785, 0xd786, 0xd787, 0xd788, 0xd789, 0xd78a,
+ 0xd78b, 0xd78c, 0xd78d, 0xd78e, 0xd78f, 0xd790, 0xd791, 0xd792,
+ 0xd793, 0xd794, 0xd795, 0xd796, 0xd797, 0xd798, 0xd799, 0xd79a,
+ 0xd79b, 0xd79c, 0xd79d, 0xd79e, 0xd79f, 0xd7a0, 0xd840, 0xd841,
+ 0xd842, 0xd843, 0xd844, 0xd845, 0xd846, 0xd847, 0xd848, 0xd849,
+ 0xd84a, 0xd84b, 0xd84c, 0xd84d, 0xd84e, 0xd84f, 0xd850, 0xd851,
+ 0xd852, 0xd853, 0xd854, 0xd855, 0xd856, 0xd857, 0xd858, 0xd859,
+ 0xd85a, 0xd85b, 0xd85c, 0xd85d, 0xd85e, 0xd85f, 0xd860, 0xd861,
+ 0xd862, 0xd863, 0xd864, 0xd865, 0xd866, 0xd867, 0xd868, 0xd869,
+ 0xd86a, 0xd86b, 0xd86c, 0xd86d, 0xd86e, 0xd86f, 0xd870, 0xd871,
+ 0xd872, 0xd873, 0xd874, 0xd875, 0xd876, 0xd877, 0xd878, 0xd879,
+ 0xd87a, 0xd87b, 0xd87c, 0xd87d, 0xd87e, 0xd880, 0xd881, 0xd882,
+ 0xd883, 0xd884, 0xd885, 0xd886, 0xd887, 0xd888, 0xd889, 0xd88a,
+ 0xd88b, 0xd88c, 0xd88d, 0xd88e, 0xd88f, 0xd890, 0xd891, 0xd892,
+ 0xd893, 0xd894, 0xd895, 0xd896, 0xd897, 0xd898, 0xd899, 0xd89a,
+ 0xd89b, 0xd89c, 0xd89d, 0xd89e, 0xd89f, 0xd8a0, 0xd940, 0xd941,
+ 0xd942, 0xd943, 0xd944, 0xd945, 0xd946, 0xd947, 0xd948, 0xd949,
+ 0xd94a, 0xd94b, 0xd94c, 0xd94d, 0xd94e, 0xd94f, 0xd950, 0xd951,
+ 0xd952, 0xd953, 0xd954, 0xd955, 0xd956, 0xd957, 0xd958, 0xd959,
+ 0xd95a, 0xd95b, 0xd95c, 0xd95d, 0xd95e, 0xd95f, 0xd960, 0xd961,
+ 0xd962, 0xd963, 0xd964, 0xd965, 0xd966, 0xd967, 0xd968, 0xd969,
+ 0xd96a, 0xd96b, 0xd96c, 0xd96d, 0xd96e, 0xd96f, 0xd970, 0xd971,
+ 0xd972, 0xd973, 0xd974, 0xd975, 0xd976, 0xd977, 0xd978, 0xd979,
+ 0xd97a, 0xd97b, 0xd97c, 0xd97d, 0xd97e, 0xd980, 0xd981, 0xd982,
+ 0xd983, 0xd984, 0xd985, 0xd986, 0xd987, 0xd988, 0xd989, 0xd98a,
+ 0xd98b, 0xd98c, 0xd98d, 0xd98e, 0xd98f, 0xd990, 0xd991, 0xd992,
+ 0xd993, 0xd994, 0xd995, 0xd996, 0xd997, 0xd998, 0xd999, 0xd99a,
+ 0xd99b, 0xd99c, 0xd99d, 0xd99e, 0xd99f, 0xd9a0, 0xda40, 0xda41,
+ 0xda42, 0xda43, 0xda44, 0xda45, 0xda46, 0xda47, 0xda48, 0xda49,
+ 0xda4a, 0xda4b, 0xda4c, 0xda4d, 0xda4e, 0xda4f, 0xda50, 0xda51,
+ 0xda52, 0xda53, 0xda54, 0xda55, 0xda56, 0xda57, 0xda58, 0xda59,
+ 0xda5a, 0xda5b, 0xda5c, 0xda5d, 0xda5e, 0xda5f, 0xda60, 0xda61,
+ 0xda62, 0xda63, 0xda64, 0xda65, 0xda66, 0xda67, 0xda68, 0xda69,
+ 0xda6a, 0xda6b, 0xda6c, 0xda6d, 0xda6e, 0xda6f, 0xda70, 0xda71,
+ 0xda72, 0xda73, 0xda74, 0xda75, 0xda76, 0xda77, 0xda78, 0xda79,
+ 0xda7a, 0xda7b, 0xda7c, 0xda7d, 0xda7e, 0xda80, 0xda81, 0xda82,
+ 0xda83, 0xda84, 0xda85, 0xda86, 0xda87, 0xda88, 0xda89, 0xda8a,
+ 0xda8b, 0xda8c, 0xda8d, 0xda8e, 0xda8f, 0xda90, 0xda91, 0xda92,
+ 0xda93, 0xda94, 0xda95, 0xda96, 0xda97, 0xda98, 0xda99, 0xda9a,
+ 0xda9b, 0xda9c, 0xda9d, 0xda9e, 0xda9f, 0xdaa0, 0xdb40, 0xdb41,
+ 0xdb42, 0xdb43, 0xdb44, 0xdb45, 0xdb46, 0xdb47, 0xdb48, 0xdb49,
+ 0xdb4a, 0xdb4b, 0xdb4c, 0xdb4d, 0xdb4e, 0xdb4f, 0xdb50, 0xdb51,
+ 0xdb52, 0xdb53, 0xdb54, 0xdb55, 0xdb56, 0xdb57, 0xdb58, 0xdb59,
+ 0xdb5a, 0xdb5b, 0xdb5c, 0xdb5d, 0xdb5e, 0xdb5f, 0xdb60, 0xdb61,
+ 0xdb62, 0xdb63, 0xdb64, 0xdb65, 0xdb66, 0xdb67, 0xdb68, 0xdb69,
+ 0xdb6a, 0xdb6b, 0xdb6c, 0xdb6d, 0xdb6e, 0xdb6f, 0xdb70, 0xdb71,
+ 0xdb72, 0xdb73, 0xdb74, 0xdb75, 0xdb76, 0xdb77, 0xdb78, 0xdb79,
+ 0xdb7a, 0xdb7b, 0xdb7c, 0xdb7d, 0xdb7e, 0xdb80, 0xdb81, 0xdb82,
+ 0xdb83, 0xdb84, 0xdb85, 0xdb86, 0xdb87, 0xdb88, 0xdb89, 0xdb8a,
+ 0xdb8b, 0xdb8c, 0xdb8d, 0xdb8e, 0xdb8f, 0xdb90, 0xdb91, 0xdb92,
+ 0xdb93, 0xdb94, 0xdb95, 0xdb96, 0xdb97, 0xdb98, 0xdb99, 0xdb9a,
+ 0xdb9b, 0xdb9c, 0xdb9d, 0xdb9e, 0xdb9f, 0xdba0, 0xdc40, 0xdc41,
+ 0xdc42, 0xdc43, 0xdc44, 0xdc45, 0xdc46, 0xdc47, 0xdc48, 0xdc49,
+ 0xdc4a, 0xdc4b, 0xdc4c, 0xdc4d, 0xdc4e, 0xdc4f, 0xdc50, 0xdc51,
+ 0xdc52, 0xdc53, 0xdc54, 0xdc55, 0xdc56, 0xdc57, 0xdc58, 0xdc59,
+ 0xdc5a, 0xdc5b, 0xdc5c, 0xdc5d, 0xdc5e, 0xdc5f, 0xdc60, 0xdc61,
+ 0xdc62, 0xdc63, 0xdc64, 0xdc65, 0xdc66, 0xdc67, 0xdc68, 0xdc69,
+ 0xdc6a, 0xdc6b, 0xdc6c, 0xdc6d, 0xdc6e, 0xdc6f, 0xdc70, 0xdc71,
+ 0xdc72, 0xdc73, 0xdc74, 0xdc75, 0xdc76, 0xdc77, 0xdc78, 0xdc79,
+ 0xdc7a, 0xdc7b, 0xdc7c, 0xdc7d, 0xdc7e, 0xdc80, 0xdc81, 0xdc82,
+ 0xdc83, 0xdc84, 0xdc85, 0xdc86, 0xdc87, 0xdc88, 0xdc89, 0xdc8a,
+ 0xdc8b, 0xdc8c, 0xdc8d, 0xdc8e, 0xdc8f, 0xdc90, 0xdc91, 0xdc92,
+ 0xdc93, 0xdc94, 0xdc95, 0xdc96, 0xdc97, 0xdc98, 0xdc99, 0xdc9a,
+ 0xdc9b, 0xdc9c, 0xdc9d, 0xdc9e, 0xdc9f, 0xdca0, 0xdd40, 0xdd41,
+ 0xdd42, 0xdd43, 0xdd44, 0xdd45, 0xdd46, 0xdd47, 0xdd48, 0xdd49,
+ 0xdd4a, 0xdd4b, 0xdd4c, 0xdd4d, 0xdd4e, 0xdd4f, 0xdd50, 0xdd51,
+ 0xdd52, 0xdd53, 0xdd54, 0xdd55, 0xdd56, 0xdd57, 0xdd58, 0xdd59,
+ 0xdd5a, 0xdd5b, 0xdd5c, 0xdd5d, 0xdd5e, 0xdd5f, 0xdd60, 0xdd61,
+ 0xdd62, 0xdd63, 0xdd64, 0xdd65, 0xdd66, 0xdd67, 0xdd68, 0xdd69,
+ 0xdd6a, 0xdd6b, 0xdd6c, 0xdd6d, 0xdd6e, 0xdd6f, 0xdd70, 0xdd71,
+ 0xdd72, 0xdd73, 0xdd74, 0xdd75, 0xdd76, 0xdd77, 0xdd78, 0xdd79,
+ 0xdd7a, 0xdd7b, 0xdd7c, 0xdd7d, 0xdd7e, 0xdd80, 0xdd81, 0xdd82,
+ 0xdd83, 0xdd84, 0xdd85, 0xdd86, 0xdd87, 0xdd88, 0xdd89, 0xdd8a,
+ 0xdd8b, 0xdd8c, 0xdd8d, 0xdd8e, 0xdd8f, 0xdd90, 0xdd91, 0xdd92,
+ 0xdd93, 0xdd94, 0xdd95, 0xdd96, 0xdd97, 0xdd98, 0xdd99, 0xdd9a,
+ 0xdd9b, 0xdd9c, 0xdd9d, 0xdd9e, 0xdd9f, 0xdda0, 0xde40, 0xde41,
+ 0xde42, 0xde43, 0xde44, 0xde45, 0xde46, 0xde47, 0xde48, 0xde49,
+ 0xde4a, 0xde4b, 0xde4c, 0xde4d, 0xde4e, 0xde4f, 0xde50, 0xde51,
+ 0xde52, 0xde53, 0xde54, 0xde55, 0xde56, 0xde57, 0xde58, 0xde59,
+ 0xde5a, 0xde5b, 0xde5c, 0xde5d, 0xde5e, 0xde5f, 0xde60, 0xde61,
+ 0xde62, 0xde63, 0xde64, 0xde65, 0xde66, 0xde67, 0xde68, 0xde69,
+ 0xde6a, 0xde6b, 0xde6c, 0xde6d, 0xde6e, 0xde6f, 0xde70, 0xde71,
+ 0xde72, 0xde73, 0xde74, 0xde75, 0xde76, 0xde77, 0xde78, 0xde79,
+ 0xde7a, 0xde7b, 0xde7c, 0xde7d, 0xde7e, 0xde80, 0xde81, 0xde82,
+ 0xde83, 0xde84, 0xde85, 0xde86, 0xde87, 0xde88, 0xde89, 0xde8a,
+ 0xde8b, 0xde8c, 0xde8d, 0xde8e, 0xde8f, 0xde90, 0xde91, 0xde92,
+ 0xde93, 0xde94, 0xde95, 0xde96, 0xde97, 0xde98, 0xde99, 0xde9a,
+ 0xde9b, 0xde9c, 0xde9d, 0xde9e, 0xde9f, 0xdea0, 0xdf40, 0xdf41,
+ 0xdf42, 0xdf43, 0xdf44, 0xdf45, 0xdf46, 0xdf47, 0xdf48, 0xdf49,
+ 0xdf4a, 0xdf4b, 0xdf4c, 0xdf4d, 0xdf4e, 0xdf4f, 0xdf50, 0xdf51,
+ 0xdf52, 0xdf53, 0xdf54, 0xdf55, 0xdf56, 0xdf57, 0xdf58, 0xdf59,
+ 0xdf5a, 0xdf5b, 0xdf5c, 0xdf5d, 0xdf5e, 0xdf5f, 0xdf60, 0xdf61,
+ 0xdf62, 0xdf63, 0xdf64, 0xdf65, 0xdf66, 0xdf67, 0xdf68, 0xdf69,
+ 0xdf6a, 0xdf6b, 0xdf6c, 0xdf6d, 0xdf6e, 0xdf6f, 0xdf70, 0xdf71,
+ 0xdf72, 0xdf73, 0xdf74, 0xdf75, 0xdf76, 0xdf77, 0xdf78, 0xdf79,
+ 0xdf7a, 0xdf7b, 0xdf7c, 0xdf7d, 0xdf7e, 0xdf80, 0xdf81, 0xdf82,
+ 0xdf83, 0xdf84, 0xdf85, 0xdf86, 0xdf87, 0xdf88, 0xdf89, 0xdf8a,
+ 0xdf8b, 0xdf8c, 0xdf8d, 0xdf8e, 0xdf8f, 0xdf90, 0xdf91, 0xdf92,
+ 0xdf93, 0xdf94, 0xdf95, 0xdf96, 0xdf97, 0xdf98, 0xdf99, 0xdf9a,
+ 0xdf9b, 0xdf9c, 0xdf9d, 0xdf9e, 0xdf9f, 0xdfa0, 0xe040, 0xe041,
+ 0xe042, 0xe043, 0xe044, 0xe045, 0xe046, 0xe047, 0xe048, 0xe049,
+ 0xe04a, 0xe04b, 0xe04c, 0xe04d, 0xe04e, 0xe04f, 0xe050, 0xe051,
+ 0xe052, 0xe053, 0xe054, 0xe055, 0xe056, 0xe057, 0xe058, 0xe059,
+ 0xe05a, 0xe05b, 0xe05c, 0xe05d, 0xe05e, 0xe05f, 0xe060, 0xe061,
+ 0xe062, 0xe063, 0xe064, 0xe065, 0xe066, 0xe067, 0xe068, 0xe069,
+ 0xe06a, 0xe06b, 0xe06c, 0xe06d, 0xe06e, 0xe06f, 0xe070, 0xe071,
+ 0xe072, 0xe073, 0xe074, 0xe075, 0xe076, 0xe077, 0xe078, 0xe079,
+ 0xe07a, 0xe07b, 0xe07c, 0xe07d, 0xe07e, 0xe080, 0xe081, 0xe082,
+ 0xe083, 0xe084, 0xe085, 0xe086, 0xe087, 0xe088, 0xe089, 0xe08a,
+ 0xe08b, 0xe08c, 0xe08d, 0xe08e, 0xe08f, 0xe090, 0xe091, 0xe092,
+ 0xe093, 0xe094, 0xe095, 0xe096, 0xe097, 0xe098, 0xe099, 0xe09a,
+ 0xe09b, 0xe09c, 0xe09d, 0xe09e, 0xe09f, 0xe0a0, 0xe140, 0xe141,
+ 0xe142, 0xe143, 0xe144, 0xe145, 0xe146, 0xe147, 0xe148, 0xe149,
+ 0xe14a, 0xe14b, 0xe14c, 0xe14d, 0xe14e, 0xe14f, 0xe150, 0xe151,
+ 0xe152, 0xe153, 0xe154, 0xe155, 0xe156, 0xe157, 0xe158, 0xe159,
+ 0xe15a, 0xe15b, 0xe15c, 0xe15d, 0xe15e, 0xe15f, 0xe160, 0xe161,
+ 0xe162, 0xe163, 0xe164, 0xe165, 0xe166, 0xe167, 0xe168, 0xe169,
+ 0xe16a, 0xe16b, 0xe16c, 0xe16d, 0xe16e, 0xe16f, 0xe170, 0xe171,
+ 0xe172, 0xe173, 0xe174, 0xe175, 0xe176, 0xe177, 0xe178, 0xe179,
+ 0xe17a, 0xe17b, 0xe17c, 0xe17d, 0xe17e, 0xe180, 0xe181, 0xe182,
+ 0xe183, 0xe184, 0xe185, 0xe186, 0xe187, 0xe188, 0xe189, 0xe18a,
+ 0xe18b, 0xe18c, 0xe18d, 0xe18e, 0xe18f, 0xe190, 0xe191, 0xe192,
+ 0xe193, 0xe194, 0xe195, 0xe196, 0xe197, 0xe198, 0xe199, 0xe19a,
+ 0xe19b, 0xe19c, 0xe19d, 0xe19e, 0xe19f, 0xe1a0, 0xe240, 0xe241,
+ 0xe242, 0xe243, 0xe244, 0xe245, 0xe246, 0xe247, 0xe248, 0xe249,
+ 0xe24a, 0xe24b, 0xe24c, 0xe24d, 0xe24e, 0xe24f, 0xe250, 0xe251,
+ 0xe252, 0xe253, 0xe254, 0xe255, 0xe256, 0xe257, 0xe258, 0xe259,
+ 0xe25a, 0xe25b, 0xe25c, 0xe25d, 0xe25e, 0xe25f, 0xe260, 0xe261,
+ 0xe262, 0xe263, 0xe264, 0xe265, 0xe266, 0xe267, 0xe268, 0xe269,
+ 0xe26a, 0xe26b, 0xe26c, 0xe26d, 0xe26e, 0xe26f, 0xe270, 0xe271,
+ 0xe272, 0xe273, 0xe274, 0xe275, 0xe276, 0xe277, 0xe278, 0xe279,
+ 0xe27a, 0xe27b, 0xe27c, 0xe27d, 0xe27e, 0xe280, 0xe281, 0xe282,
+ 0xe283, 0xe284, 0xe285, 0xe286, 0xe287, 0xe288, 0xe289, 0xe28a,
+ 0xe28b, 0xe28c, 0xe28d, 0xe28e, 0xe28f, 0xe290, 0xe291, 0xe292,
+ 0xe293, 0xe294, 0xe295, 0xe296, 0xe297, 0xe298, 0xe299, 0xe29a,
+ 0xe29b, 0xe29c, 0xe29d, 0xe29e, 0xe29f, 0xe2a0, 0xe340, 0xe341,
+ 0xe342, 0xe343, 0xe344, 0xe345, 0xe346, 0xe347, 0xe348, 0xe349,
+ 0xe34a, 0xe34b, 0xe34c, 0xe34d, 0xe34e, 0xe34f, 0xe350, 0xe351,
+ 0xe352, 0xe353, 0xe354, 0xe355, 0xe356, 0xe357, 0xe358, 0xe359,
+ 0xe35a, 0xe35b, 0xe35c, 0xe35d, 0xe35e, 0xe35f, 0xe360, 0xe361,
+ 0xe362, 0xe363, 0xe364, 0xe365, 0xe366, 0xe367, 0xe368, 0xe369,
+ 0xe36a, 0xe36b, 0xe36c, 0xe36d, 0xe36e, 0xe36f, 0xe370, 0xe371,
+ 0xe372, 0xe373, 0xe374, 0xe375, 0xe376, 0xe377, 0xe378, 0xe379,
+ 0xe37a, 0xe37b, 0xe37c, 0xe37d, 0xe37e, 0xe380, 0xe381, 0xe382,
+ 0xe383, 0xe384, 0xe385, 0xe386, 0xe387, 0xe388, 0xe389, 0xe38a,
+ 0xe38b, 0xe38c, 0xe38d, 0xe38e, 0xe38f, 0xe390, 0xe391, 0xe392,
+ 0xe393, 0xe394, 0xe395, 0xe396, 0xe397, 0xe398, 0xe399, 0xe39a,
+ 0xe39b, 0xe39c, 0xe39d, 0xe39e, 0xe39f, 0xe3a0, 0xe440, 0xe441,
+ 0xe442, 0xe443, 0xe444, 0xe445, 0xe446, 0xe447, 0xe448, 0xe449,
+ 0xe44a, 0xe44b, 0xe44c, 0xe44d, 0xe44e, 0xe44f, 0xe450, 0xe451,
+ 0xe452, 0xe453, 0xe454, 0xe455, 0xe456, 0xe457, 0xe458, 0xe459,
+ 0xe45a, 0xe45b, 0xe45c, 0xe45d, 0xe45e, 0xe45f, 0xe460, 0xe461,
+ 0xe462, 0xe463, 0xe464, 0xe465, 0xe466, 0xe467, 0xe468, 0xe469,
+ 0xe46a, 0xe46b, 0xe46c, 0xe46d, 0xe46e, 0xe46f, 0xe470, 0xe471,
+ 0xe472, 0xe473, 0xe474, 0xe475, 0xe476, 0xe477, 0xe478, 0xe479,
+ 0xe47a, 0xe47b, 0xe47c, 0xe47d, 0xe47e, 0xe480, 0xe481, 0xe482,
+ 0xe483, 0xe484, 0xe485, 0xe486, 0xe487, 0xe488, 0xe489, 0xe48a,
+ 0xe48b, 0xe48c, 0xe48d, 0xe48e, 0xe48f, 0xe490, 0xe491, 0xe492,
+ 0xe493, 0xe494, 0xe495, 0xe496, 0xe497, 0xe498, 0xe499, 0xe49a,
+ 0xe49b, 0xe49c, 0xe49d, 0xe49e, 0xe49f, 0xe4a0, 0xe540, 0xe541,
+ 0xe542, 0xe543, 0xe544, 0xe545, 0xe546, 0xe547, 0xe548, 0xe549,
+ 0xe54a, 0xe54b, 0xe54c, 0xe54d, 0xe54e, 0xe54f, 0xe550, 0xe551,
+ 0xe552, 0xe553, 0xe554, 0xe555, 0xe556, 0xe557, 0xe558, 0xe559,
+ 0xe55a, 0xe55b, 0xe55c, 0xe55d, 0xe55e, 0xe55f, 0xe560, 0xe561,
+ 0xe562, 0xe563, 0xe564, 0xe565, 0xe566, 0xe567, 0xe568, 0xe569,
+ 0xe56a, 0xe56b, 0xe56c, 0xe56d, 0xe56e, 0xe56f, 0xe570, 0xe571,
+ 0xe572, 0xe573, 0xe574, 0xe575, 0xe576, 0xe577, 0xe578, 0xe579,
+ 0xe57a, 0xe57b, 0xe57c, 0xe57d, 0xe57e, 0xe580, 0xe581, 0xe582,
+ 0xe583, 0xe584, 0xe585, 0xe586, 0xe587, 0xe588, 0xe589, 0xe58a,
+ 0xe58b, 0xe58c, 0xe58d, 0xe58e, 0xe58f, 0xe590, 0xe591, 0xe592,
+ 0xe593, 0xe594, 0xe595, 0xe596, 0xe597, 0xe598, 0xe599, 0xe59a,
+ 0xe59b, 0xe59c, 0xe59d, 0xe59e, 0xe59f, 0xe5a0, 0xe640, 0xe641,
+ 0xe642, 0xe643, 0xe644, 0xe645, 0xe646, 0xe647, 0xe648, 0xe649,
+ 0xe64a, 0xe64b, 0xe64c, 0xe64d, 0xe64e, 0xe64f, 0xe650, 0xe651,
+ 0xe652, 0xe653, 0xe654, 0xe655, 0xe656, 0xe657, 0xe658, 0xe659,
+ 0xe65a, 0xe65b, 0xe65c, 0xe65d, 0xe65e, 0xe65f, 0xe660, 0xe661,
+ 0xe662, 0xe663, 0xe664, 0xe665, 0xe666, 0xe667, 0xe668, 0xe669,
+ 0xe66a, 0xe66b, 0xe66c, 0xe66d, 0xe66e, 0xe66f, 0xe670, 0xe671,
+ 0xe672, 0xe673, 0xe674, 0xe675, 0xe676, 0xe677, 0xe678, 0xe679,
+ 0xe67a, 0xe67b, 0xe67c, 0xe67d, 0xe67e, 0xe680, 0xe681, 0xe682,
+ 0xe683, 0xe684, 0xe685, 0xe686, 0xe687, 0xe688, 0xe689, 0xe68a,
+ 0xe68b, 0xe68c, 0xe68d, 0xe68e, 0xe68f, 0xe690, 0xe691, 0xe692,
+ 0xe693, 0xe694, 0xe695, 0xe696, 0xe697, 0xe698, 0xe699, 0xe69a,
+ 0xe69b, 0xe69c, 0xe69d, 0xe69e, 0xe69f, 0xe6a0, 0xe740, 0xe741,
+ 0xe742, 0xe743, 0xe744, 0xe745, 0xe746, 0xe747, 0xe748, 0xe749,
+ 0xe74a, 0xe74b, 0xe74c, 0xe74d, 0xe74e, 0xe74f, 0xe750, 0xe751,
+ 0xe752, 0xe753, 0xe754, 0xe755, 0xe756, 0xe757, 0xe758, 0xe759,
+ 0xe75a, 0xe75b, 0xe75c, 0xe75d, 0xe75e, 0xe75f, 0xe760, 0xe761,
+ 0xe762, 0xe763, 0xe764, 0xe765, 0xe766, 0xe767, 0xe768, 0xe769,
+ 0xe76a, 0xe76b, 0xe76c, 0xe76d, 0xe76e, 0xe76f, 0xe770, 0xe771,
+ 0xe772, 0xe773, 0xe774, 0xe775, 0xe776, 0xe777, 0xe778, 0xe779,
+ 0xe77a, 0xe77b, 0xe77c, 0xe77d, 0xe77e, 0xe780, 0xe781, 0xe782,
+ 0xe783, 0xe784, 0xe785, 0xe786, 0xe787, 0xe788, 0xe789, 0xe78a,
+ 0xe78b, 0xe78c, 0xe78d, 0xe78e, 0xe78f, 0xe790, 0xe791, 0xe792,
+ 0xe793, 0xe794, 0xe795, 0xe796, 0xe797, 0xe798, 0xe799, 0xe79a,
+ 0xe79b, 0xe79c, 0xe79d, 0xe79e, 0xe79f, 0xe7a0, 0xe840, 0xe841,
+ 0xe842, 0xe843, 0xe844, 0xe845, 0xe846, 0xe847, 0xe848, 0xe849,
+ 0xe84a, 0xe84b, 0xe84c, 0xe84d, 0xe84e, 0xe84f, 0xe850, 0xe851,
+ 0xe852, 0xe853, 0xe854, 0xe855, 0xe856, 0xe857, 0xe858, 0xe859,
+ 0xe85a, 0xe85b, 0xe85c, 0xe85d, 0xe85e, 0xe85f, 0xe860, 0xe861,
+ 0xe862, 0xe863, 0xe864, 0xe865, 0xe866, 0xe867, 0xe868, 0xe869,
+ 0xe86a, 0xe86b, 0xe86c, 0xe86d, 0xe86e, 0xe86f, 0xe870, 0xe871,
+ 0xe872, 0xe873, 0xe874, 0xe875, 0xe876, 0xe877, 0xe878, 0xe879,
+ 0xe87a, 0xe87b, 0xe87c, 0xe87d, 0xe87e, 0xe880, 0xe881, 0xe882,
+ 0xe883, 0xe884, 0xe885, 0xe886, 0xe887, 0xe888, 0xe889, 0xe88a,
+ 0xe88b, 0xe88c, 0xe88d, 0xe88e, 0xe88f, 0xe890, 0xe891, 0xe892,
+ 0xe893, 0xe894, 0xe895, 0xe896, 0xe897, 0xe898, 0xe899, 0xe89a,
+ 0xe89b, 0xe89c, 0xe89d, 0xe89e, 0xe89f, 0xe8a0, 0xe940, 0xe941,
+ 0xe942, 0xe943, 0xe944, 0xe945, 0xe946, 0xe947, 0xe948, 0xe949,
+ 0xe94a, 0xe94b, 0xe94c, 0xe94d, 0xe94e, 0xe94f, 0xe950, 0xe951,
+ 0xe952, 0xe953, 0xe954, 0xe955, 0xe956, 0xe957, 0xe958, 0xe959,
+ 0xe95a, 0xe95b, 0xe95c, 0xe95d, 0xe95e, 0xe95f, 0xe960, 0xe961,
+ 0xe962, 0xe963, 0xe964, 0xe965, 0xe966, 0xe967, 0xe968, 0xe969,
+ 0xe96a, 0xe96b, 0xe96c, 0xe96d, 0xe96e, 0xe96f, 0xe970, 0xe971,
+ 0xe972, 0xe973, 0xe974, 0xe975, 0xe976, 0xe977, 0xe978, 0xe979,
+ 0xe97a, 0xe97b, 0xe97c, 0xe97d, 0xe97e, 0xe980, 0xe981, 0xe982,
+ 0xe983, 0xe984, 0xe985, 0xe986, 0xe987, 0xe988, 0xe989, 0xe98a,
+ 0xe98b, 0xe98c, 0xe98d, 0xe98e, 0xe98f, 0xe990, 0xe991, 0xe992,
+ 0xe993, 0xe994, 0xe995, 0xe996, 0xe997, 0xe998, 0xe999, 0xe99a,
+ 0xe99b, 0xe99c, 0xe99d, 0xe99e, 0xe99f, 0xe9a0, 0xea40, 0xea41,
+ 0xea42, 0xea43, 0xea44, 0xea45, 0xea46, 0xea47, 0xea48, 0xea49,
+ 0xea4a, 0xea4b, 0xea4c, 0xea4d, 0xea4e, 0xea4f, 0xea50, 0xea51,
+ 0xea52, 0xea53, 0xea54, 0xea55, 0xea56, 0xea57, 0xea58, 0xea59,
+ 0xea5a, 0xea5b, 0xea5c, 0xea5d, 0xea5e, 0xea5f, 0xea60, 0xea61,
+ 0xea62, 0xea63, 0xea64, 0xea65, 0xea66, 0xea67, 0xea68, 0xea69,
+ 0xea6a, 0xea6b, 0xea6c, 0xea6d, 0xea6e, 0xea6f, 0xea70, 0xea71,
+ 0xea72, 0xea73, 0xea74, 0xea75, 0xea76, 0xea77, 0xea78, 0xea79,
+ 0xea7a, 0xea7b, 0xea7c, 0xea7d, 0xea7e, 0xea80, 0xea81, 0xea82,
+ 0xea83, 0xea84, 0xea85, 0xea86, 0xea87, 0xea88, 0xea89, 0xea8a,
+ 0xea8b, 0xea8c, 0xea8d, 0xea8e, 0xea8f, 0xea90, 0xea91, 0xea92,
+ 0xea93, 0xea94, 0xea95, 0xea96, 0xea97, 0xea98, 0xea99, 0xea9a,
+ 0xea9b, 0xea9c, 0xea9d, 0xea9e, 0xea9f, 0xeaa0, 0xeb40, 0xeb41,
+ 0xeb42, 0xeb43, 0xeb44, 0xeb45, 0xeb46, 0xeb47, 0xeb48, 0xeb49,
+ 0xeb4a, 0xeb4b, 0xeb4c, 0xeb4d, 0xeb4e, 0xeb4f, 0xeb50, 0xeb51,
+ 0xeb52, 0xeb53, 0xeb54, 0xeb55, 0xeb56, 0xeb57, 0xeb58, 0xeb59,
+ 0xeb5a, 0xeb5b, 0xeb5c, 0xeb5d, 0xeb5e, 0xeb5f, 0xeb60, 0xeb61,
+ 0xeb62, 0xeb63, 0xeb64, 0xeb65, 0xeb66, 0xeb67, 0xeb68, 0xeb69,
+ 0xeb6a, 0xeb6b, 0xeb6c, 0xeb6d, 0xeb6e, 0xeb6f, 0xeb70, 0xeb71,
+ 0xeb72, 0xeb73, 0xeb74, 0xeb75, 0xeb76, 0xeb77, 0xeb78, 0xeb79,
+ 0xeb7a, 0xeb7b, 0xeb7c, 0xeb7d, 0xeb7e, 0xeb80, 0xeb81, 0xeb82,
+ 0xeb83, 0xeb84, 0xeb85, 0xeb86, 0xeb87, 0xeb88, 0xeb89, 0xeb8a,
+ 0xeb8b, 0xeb8c, 0xeb8d, 0xeb8e, 0xeb8f, 0xeb90, 0xeb91, 0xeb92,
+ 0xeb93, 0xeb94, 0xeb95, 0xeb96, 0xeb97, 0xeb98, 0xeb99, 0xeb9a,
+ 0xeb9b, 0xeb9c, 0xeb9d, 0xeb9e, 0xeb9f, 0xeba0, 0xec40, 0xec41,
+ 0xec42, 0xec43, 0xec44, 0xec45, 0xec46, 0xec47, 0xec48, 0xec49,
+ 0xec4a, 0xec4b, 0xec4c, 0xec4d, 0xec4e, 0xec4f, 0xec50, 0xec51,
+ 0xec52, 0xec53, 0xec54, 0xec55, 0xec56, 0xec57, 0xec58, 0xec59,
+ 0xec5a, 0xec5b, 0xec5c, 0xec5d, 0xec5e, 0xec5f, 0xec60, 0xec61,
+ 0xec62, 0xec63, 0xec64, 0xec65, 0xec66, 0xec67, 0xec68, 0xec69,
+ 0xec6a, 0xec6b, 0xec6c, 0xec6d, 0xec6e, 0xec6f, 0xec70, 0xec71,
+ 0xec72, 0xec73, 0xec74, 0xec75, 0xec76, 0xec77, 0xec78, 0xec79,
+ 0xec7a, 0xec7b, 0xec7c, 0xec7d, 0xec7e, 0xec80, 0xec81, 0xec82,
+ 0xec83, 0xec84, 0xec85, 0xec86, 0xec87, 0xec88, 0xec89, 0xec8a,
+ 0xec8b, 0xec8c, 0xec8d, 0xec8e, 0xec8f, 0xec90, 0xec91, 0xec92,
+ 0xec93, 0xec94, 0xec95, 0xec96, 0xec97, 0xec98, 0xec99, 0xec9a,
+ 0xec9b, 0xec9c, 0xec9d, 0xec9e, 0xec9f, 0xeca0, 0xed40, 0xed41,
+ 0xed42, 0xed43, 0xed44, 0xed45, 0xed46, 0xed47, 0xed48, 0xed49,
+ 0xed4a, 0xed4b, 0xed4c, 0xed4d, 0xed4e, 0xed4f, 0xed50, 0xed51,
+ 0xed52, 0xed53, 0xed54, 0xed55, 0xed56, 0xed57, 0xed58, 0xed59,
+ 0xed5a, 0xed5b, 0xed5c, 0xed5d, 0xed5e, 0xed5f, 0xed60, 0xed61,
+ 0xed62, 0xed63, 0xed64, 0xed65, 0xed66, 0xed67, 0xed68, 0xed69,
+ 0xed6a, 0xed6b, 0xed6c, 0xed6d, 0xed6e, 0xed6f, 0xed70, 0xed71,
+ 0xed72, 0xed73, 0xed74, 0xed75, 0xed76, 0xed77, 0xed78, 0xed79,
+ 0xed7a, 0xed7b, 0xed7c, 0xed7d, 0xed7e, 0xed80, 0xed81, 0xed82,
+ 0xed83, 0xed84, 0xed85, 0xed86, 0xed87, 0xed88, 0xed89, 0xed8a,
+ 0xed8b, 0xed8c, 0xed8d, 0xed8e, 0xed8f, 0xed90, 0xed91, 0xed92,
+ 0xed93, 0xed94, 0xed95, 0xed96, 0xed97, 0xed98, 0xed99, 0xed9a,
+ 0xed9b, 0xed9c, 0xed9d, 0xed9e, 0xed9f, 0xeda0, 0xee40, 0xee41,
+ 0xee42, 0xee43, 0xee44, 0xee45, 0xee46, 0xee47, 0xee48, 0xee49,
+ 0xee4a, 0xee4b, 0xee4c, 0xee4d, 0xee4e, 0xee4f, 0xee50, 0xee51,
+ 0xee52, 0xee53, 0xee54, 0xee55, 0xee56, 0xee57, 0xee58, 0xee59,
+ 0xee5a, 0xee5b, 0xee5c, 0xee5d, 0xee5e, 0xee5f, 0xee60, 0xee61,
+ 0xee62, 0xee63, 0xee64, 0xee65, 0xee66, 0xee67, 0xee68, 0xee69,
+ 0xee6a, 0xee6b, 0xee6c, 0xee6d, 0xee6e, 0xee6f, 0xee70, 0xee71,
+ 0xee72, 0xee73, 0xee74, 0xee75, 0xee76, 0xee77, 0xee78, 0xee79,
+ 0xee7a, 0xee7b, 0xee7c, 0xee7d, 0xee7e, 0xee80, 0xee81, 0xee82,
+ 0xee83, 0xee84, 0xee85, 0xee86, 0xee87, 0xee88, 0xee89, 0xee8a,
+ 0xee8b, 0xee8c, 0xee8d, 0xee8e, 0xee8f, 0xee90, 0xee91, 0xee92,
+ 0xee93, 0xee94, 0xee95, 0xee96, 0xee97, 0xee98, 0xee99, 0xee9a,
+ 0xee9b, 0xee9c, 0xee9d, 0xee9e, 0xee9f, 0xeea0, 0xef40, 0xef41,
+ 0xef42, 0xef43, 0xef44, 0xef45, 0xef46, 0xef47, 0xef48, 0xef49,
+ 0xef4a, 0xef4b, 0xef4c, 0xef4d, 0xef4e, 0xef4f, 0xef50, 0xef51,
+ 0xef52, 0xef53, 0xef54, 0xef55, 0xef56, 0xef57, 0xef58, 0xef59,
+ 0xef5a, 0xef5b, 0xef5c, 0xef5d, 0xef5e, 0xef5f, 0xef60, 0xef61,
+ 0xef62, 0xef63, 0xef64, 0xef65, 0xef66, 0xef67, 0xef68, 0xef69,
+ 0xef6a, 0xef6b, 0xef6c, 0xef6d, 0xef6e, 0xef6f, 0xef70, 0xef71,
+ 0xef72, 0xef73, 0xef74, 0xef75, 0xef76, 0xef77, 0xef78, 0xef79,
+ 0xef7a, 0xef7b, 0xef7c, 0xef7d, 0xef7e, 0xef80, 0xef81, 0xef82,
+ 0xef83, 0xef84, 0xef85, 0xef86, 0xef87, 0xef88, 0xef89, 0xef8a,
+ 0xef8b, 0xef8c, 0xef8d, 0xef8e, 0xef8f, 0xef90, 0xef91, 0xef92,
+ 0xef93, 0xef94, 0xef95, 0xef96, 0xef97, 0xef98, 0xef99, 0xef9a,
+ 0xef9b, 0xef9c, 0xef9d, 0xef9e, 0xef9f, 0xefa0, 0xf040, 0xf041,
+ 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047, 0xf048, 0xf049,
+ 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f, 0xf050, 0xf051,
+ 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057, 0xf058, 0xf059,
+ 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f, 0xf060, 0xf061,
+ 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067, 0xf068, 0xf069,
+ 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f, 0xf070, 0xf071,
+ 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077, 0xf078, 0xf079,
+ 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf080, 0xf081, 0xf082,
+ 0xf083, 0xf084, 0xf085, 0xf086, 0xf087, 0xf088, 0xf089, 0xf08a,
+ 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f, 0xf090, 0xf091, 0xf092,
+ 0xf093, 0xf094, 0xf095, 0xf096, 0xf097, 0xf098, 0xf099, 0xf09a,
+ 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f, 0xf0a0, 0xf140, 0xf141,
+ 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, 0xf148, 0xf149,
+ 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, 0xf150, 0xf151,
+ 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, 0xf158, 0xf159,
+ 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, 0xf160, 0xf161,
+ 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, 0xf168, 0xf169,
+ 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, 0xf170, 0xf171,
+ 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, 0xf178, 0xf179,
+ 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf180, 0xf181, 0xf182,
+ 0xf183, 0xf184, 0xf185, 0xf186, 0xf187, 0xf188, 0xf189, 0xf18a,
+ 0xf18b, 0xf18c, 0xf18d, 0xf18e, 0xf18f, 0xf190, 0xf191, 0xf192,
+ 0xf193, 0xf194, 0xf195, 0xf196, 0xf197, 0xf198, 0xf199, 0xf19a,
+ 0xf19b, 0xf19c, 0xf19d, 0xf19e, 0xf19f, 0xf1a0, 0xf240, 0xf241,
+ 0xf242, 0xf243, 0xf244, 0xf245, 0xf246, 0xf247, 0xf248, 0xf249,
+ 0xf24a, 0xf24b, 0xf24c, 0xf24d, 0xf24e, 0xf24f, 0xf250, 0xf251,
+ 0xf252, 0xf253, 0xf254, 0xf255, 0xf256, 0xf257, 0xf258, 0xf259,
+ 0xf25a, 0xf25b, 0xf25c, 0xf25d, 0xf25e, 0xf25f, 0xf260, 0xf261,
+ 0xf262, 0xf263, 0xf264, 0xf265, 0xf266, 0xf267, 0xf268, 0xf269,
+ 0xf26a, 0xf26b, 0xf26c, 0xf26d, 0xf26e, 0xf26f, 0xf270, 0xf271,
+ 0xf272, 0xf273, 0xf274, 0xf275, 0xf276, 0xf277, 0xf278, 0xf279,
+ 0xf27a, 0xf27b, 0xf27c, 0xf27d, 0xf27e, 0xf280, 0xf281, 0xf282,
+ 0xf283, 0xf284, 0xf285, 0xf286, 0xf287, 0xf288, 0xf289, 0xf28a,
+ 0xf28b, 0xf28c, 0xf28d, 0xf28e, 0xf28f, 0xf290, 0xf291, 0xf292,
+ 0xf293, 0xf294, 0xf295, 0xf296, 0xf297, 0xf298, 0xf299, 0xf29a,
+ 0xf29b, 0xf29c, 0xf29d, 0xf29e, 0xf29f, 0xf2a0, 0xf340, 0xf341,
+ 0xf342, 0xf343, 0xf344, 0xf345, 0xf346, 0xf347, 0xf348, 0xf349,
+ 0xf34a, 0xf34b, 0xf34c, 0xf34d, 0xf34e, 0xf34f, 0xf350, 0xf351,
+ 0xf352, 0xf353, 0xf354, 0xf355, 0xf356, 0xf357, 0xf358, 0xf359,
+ 0xf35a, 0xf35b, 0xf35c, 0xf35d, 0xf35e, 0xf35f, 0xf360, 0xf361,
+ 0xf362, 0xf363, 0xf364, 0xf365, 0xf366, 0xf367, 0xf368, 0xf369,
+ 0xf36a, 0xf36b, 0xf36c, 0xf36d, 0xf36e, 0xf36f, 0xf370, 0xf371,
+ 0xf372, 0xf373, 0xf374, 0xf375, 0xf376, 0xf377, 0xf378, 0xf379,
+ 0xf37a, 0xf37b, 0xf37c, 0xf37d, 0xf37e, 0xf380, 0xf381, 0xf382,
+ 0xf383, 0xf384, 0xf385, 0xf386, 0xf387, 0xf388, 0xf389, 0xf38a,
+ 0xf38b, 0xf38c, 0xf38d, 0xf38e, 0xf38f, 0xf390, 0xf391, 0xf392,
+ 0xf393, 0xf394, 0xf395, 0xf396, 0xf397, 0xf398, 0xf399, 0xf39a,
+ 0xf39b, 0xf39c, 0xf39d, 0xf39e, 0xf39f, 0xf3a0, 0xf440, 0xf441,
+ 0xf442, 0xf443, 0xf444, 0xf445, 0xf446, 0xf447, 0xf448, 0xf449,
+ 0xf44a, 0xf44b, 0xf44c, 0xf44d, 0xf44e, 0xf44f, 0xf450, 0xf451,
+ 0xf452, 0xf453, 0xf454, 0xf455, 0xf456, 0xf457, 0xf458, 0xf459,
+ 0xf45a, 0xf45b, 0xf45c, 0xf45d, 0xf45e, 0xf45f, 0xf460, 0xf461,
+ 0xf462, 0xf463, 0xf464, 0xf465, 0xf466, 0xf467, 0xf468, 0xf469,
+ 0xf46a, 0xf46b, 0xf46c, 0xf46d, 0xf46e, 0xf46f, 0xf470, 0xf471,
+ 0xf472, 0xf473, 0xf474, 0xf475, 0xf476, 0xf477, 0xf478, 0xf479,
+ 0xf47a, 0xf47b, 0xf47c, 0xf47d, 0xf47e, 0xf480, 0xf481, 0xf482,
+ 0xf483, 0xf484, 0xf485, 0xf486, 0xf487, 0xf488, 0xf489, 0xf48a,
+ 0xf48b, 0xf48c, 0xf48d, 0xf48e, 0xf48f, 0xf490, 0xf491, 0xf492,
+ 0xf493, 0xf494, 0xf495, 0xf496, 0xf497, 0xf498, 0xf499, 0xf49a,
+ 0xf49b, 0xf49c, 0xf49d, 0xf49e, 0xf49f, 0xf4a0, 0xf540, 0xf541,
+ 0xf542, 0xf543, 0xf544, 0xf545, 0xf546, 0xf547, 0xf548, 0xf549,
+ 0xf54a, 0xf54b, 0xf54c, 0xf54d, 0xf54e, 0xf54f, 0xf550, 0xf551,
+ 0xf552, 0xf553, 0xf554, 0xf555, 0xf556, 0xf557, 0xf558, 0xf559,
+ 0xf55a, 0xf55b, 0xf55c, 0xf55d, 0xf55e, 0xf55f, 0xf560, 0xf561,
+ 0xf562, 0xf563, 0xf564, 0xf565, 0xf566, 0xf567, 0xf568, 0xf569,
+ 0xf56a, 0xf56b, 0xf56c, 0xf56d, 0xf56e, 0xf56f, 0xf570, 0xf571,
+ 0xf572, 0xf573, 0xf574, 0xf575, 0xf576, 0xf577, 0xf578, 0xf579,
+ 0xf57a, 0xf57b, 0xf57c, 0xf57d, 0xf57e, 0xf580, 0xf581, 0xf582,
+ 0xf583, 0xf584, 0xf585, 0xf586, 0xf587, 0xf588, 0xf589, 0xf58a,
+ 0xf58b, 0xf58c, 0xf58d, 0xf58e, 0xf58f, 0xf590, 0xf591, 0xf592,
+ 0xf593, 0xf594, 0xf595, 0xf596, 0xf597, 0xf598, 0xf599, 0xf59a,
+ 0xf59b, 0xf59c, 0xf59d, 0xf59e, 0xf59f, 0xf5a0, 0xf640, 0xf641,
+ 0xf642, 0xf643, 0xf644, 0xf645, 0xf646, 0xf647, 0xf648, 0xf649,
+ 0xf64a, 0xf64b, 0xf64c, 0xf64d, 0xf64e, 0xf64f, 0xf650, 0xf651,
+ 0xf652, 0xf653, 0xf654, 0xf655, 0xf656, 0xf657, 0xf658, 0xf659,
+ 0xf65a, 0xf65b, 0xf65c, 0xf65d, 0xf65e, 0xf65f, 0xf660, 0xf661,
+ 0xf662, 0xf663, 0xf664, 0xf665, 0xf666, 0xf667, 0xf668, 0xf669,
+ 0xf66a, 0xf66b, 0xf66c, 0xf66d, 0xf66e, 0xf66f, 0xf670, 0xf671,
+ 0xf672, 0xf673, 0xf674, 0xf675, 0xf676, 0xf677, 0xf678, 0xf679,
+ 0xf67a, 0xf67b, 0xf67c, 0xf67d, 0xf67e, 0xf680, 0xf681, 0xf682,
+ 0xf683, 0xf684, 0xf685, 0xf686, 0xf687, 0xf688, 0xf689, 0xf68a,
+ 0xf68b, 0xf68c, 0xf68d, 0xf68e, 0xf68f, 0xf690, 0xf691, 0xf692,
+ 0xf693, 0xf694, 0xf695, 0xf696, 0xf697, 0xf698, 0xf699, 0xf69a,
+ 0xf69b, 0xf69c, 0xf69d, 0xf69e, 0xf69f, 0xf6a0, 0xf740, 0xf741,
+ 0xf742, 0xf743, 0xf744, 0xf745, 0xf746, 0xf747, 0xf748, 0xf749,
+ 0xf74a, 0xf74b, 0xf74c, 0xf74d, 0xf74e, 0xf74f, 0xf750, 0xf751,
+ 0xf752, 0xf753, 0xf754, 0xf755, 0xf756, 0xf757, 0xf758, 0xf759,
+ 0xf75a, 0xf75b, 0xf75c, 0xf75d, 0xf75e, 0xf75f, 0xf760, 0xf761,
+ 0xf762, 0xf763, 0xf764, 0xf765, 0xf766, 0xf767, 0xf768, 0xf769,
+ 0xf76a, 0xf76b, 0xf76c, 0xf76d, 0xf76e, 0xf76f, 0xf770, 0xf771,
+ 0xf772, 0xf773, 0xf774, 0xf775, 0xf776, 0xf777, 0xf778, 0xf779,
+ 0xf77a, 0xf77b, 0xf77c, 0xf77d, 0xf77e, 0xf780, 0xf781, 0xf782,
+ 0xf783, 0xf784, 0xf785, 0xf786, 0xf787, 0xf788, 0xf789, 0xf78a,
+ 0xf78b, 0xf78c, 0xf78d, 0xf78e, 0xf78f, 0xf790, 0xf791, 0xf792,
+ 0xf793, 0xf794, 0xf795, 0xf796, 0xf797, 0xf798, 0xf799, 0xf79a,
+ 0xf79b, 0xf79c, 0xf79d, 0xf79e, 0xf79f, 0xf7a0, 0xf840, 0xf841,
+ 0xf842, 0xf843, 0xf844, 0xf845, 0xf846, 0xf847, 0xf848, 0xf849,
+ 0xf84a, 0xf84b, 0xf84c, 0xf84d, 0xf84e, 0xf84f, 0xf850, 0xf851,
+ 0xf852, 0xf853, 0xf854, 0xf855, 0xf856, 0xf857, 0xf858, 0xf859,
+ 0xf85a, 0xf85b, 0xf85c, 0xf85d, 0xf85e, 0xf85f, 0xf860, 0xf861,
+ 0xf862, 0xf863, 0xf864, 0xf865, 0xf866, 0xf867, 0xf868, 0xf869,
+ 0xf86a, 0xf86b, 0xf86c, 0xf86d, 0xf86e, 0xf86f, 0xf870, 0xf871,
+ 0xf872, 0xf873, 0xf874, 0xf875, 0xf876, 0xf877, 0xf878, 0xf879,
+ 0xf87a, 0xf87b, 0xf87c, 0xf87d, 0xf87e, 0xf880, 0xf881, 0xf882,
+ 0xf883, 0xf884, 0xf885, 0xf886, 0xf887, 0xf888, 0xf889, 0xf88a,
+ 0xf88b, 0xf88c, 0xf88d, 0xf88e, 0xf88f, 0xf890, 0xf891, 0xf892,
+ 0xf893, 0xf894, 0xf895, 0xf896, 0xf897, 0xf898, 0xf899, 0xf89a,
+ 0xf89b, 0xf89c, 0xf89d, 0xf89e, 0xf89f, 0xf8a0, 0xf940, 0xf941,
+ 0xf942, 0xf943, 0xf944, 0xf945, 0xf946, 0xf947, 0xf948, 0xf949,
+ 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, 0xf94f, 0xf950, 0xf951,
+ 0xf952, 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0xf958, 0xf959,
+ 0xf95a, 0xf95b, 0xf95c, 0xf95d, 0xf95e, 0xf95f, 0xf960, 0xf961,
+ 0xf962, 0xf963, 0xf964, 0xf965, 0xf966, 0xf967, 0xf968, 0xf969,
+ 0xf96a, 0xf96b, 0xf96c, 0xf96d, 0xf96e, 0xf96f, 0xf970, 0xf971,
+ 0xf972, 0xf973, 0xf974, 0xf975, 0xf976, 0xf977, 0xf978, 0xf979,
+ 0xf97a, 0xf97b, 0xf97c, 0xf97d, 0xf97e, 0xf980, 0xf981, 0xf982,
+ 0xf983, 0xf984, 0xf985, 0xf986, 0xf987, 0xf988, 0xf989, 0xf98a,
+ 0xf98b, 0xf98c, 0xf98d, 0xf98e, 0xf98f, 0xf990, 0xf991, 0xf992,
+ 0xf993, 0xf994, 0xf995, 0xf996, 0xf997, 0xf998, 0xf999, 0xf99a,
+ 0xf99b, 0xf99c, 0xf99d, 0xf99e, 0xf99f, 0xf9a0, 0xfa40, 0xfa41,
+ 0xfa42, 0xfa43, 0xfa44, 0xfa45, 0xfa46, 0xfa47, 0xfa48, 0xfa49,
+ 0xfa4a, 0xfa4b, 0xfa4c, 0xfa4d, 0xfa4e, 0xfa4f, 0xfa50, 0xfa51,
+ 0xfa52, 0xfa53, 0xfa54, 0xfa55, 0xfa56, 0xfa57, 0xfa58, 0xfa59,
+ 0xfa5a, 0xfa5b, 0xfa5c, 0xfa5d, 0xfa5e, 0xfa5f, 0xfa60, 0xfa61,
+ 0xfa62, 0xfa63, 0xfa64, 0xfa65, 0xfa66, 0xfa67, 0xfa68, 0xfa69,
+ 0xfa6a, 0xfa6b, 0xfa6c, 0xfa6d, 0xfa6e, 0xfa6f, 0xfa70, 0xfa71,
+ 0xfa72, 0xfa73, 0xfa74, 0xfa75, 0xfa76, 0xfa77, 0xfa78, 0xfa79,
+ 0xfa7a, 0xfa7b, 0xfa7c, 0xfa7d, 0xfa7e, 0xfa80, 0xfa81, 0xfa82,
+ 0xfa83, 0xfa84, 0xfa85, 0xfa86, 0xfa87, 0xfa88, 0xfa89, 0xfa8a,
+ 0xfa8b, 0xfa8c, 0xfa8d, 0xfa8e, 0xfa8f, 0xfa90, 0xfa91, 0xfa92,
+ 0xfa93, 0xfa94, 0xfa95, 0xfa96, 0xfa97, 0xfa98, 0xfa99, 0xfa9a,
+ 0xfa9b, 0xfa9c, 0xfa9d, 0xfa9e, 0xfa9f, 0xfaa0, 0xfb40, 0xfb41,
+ 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47, 0xfb48, 0xfb49,
+ 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f, 0xfb50, 0xfb51,
+ 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57, 0xfb58, 0xfb59,
+ 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5e, 0xfb5f, 0xfb60, 0xfb61,
+ 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67, 0xfb68, 0xfb69,
+ 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f, 0xfb70, 0xfb71,
+ 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77, 0xfb78, 0xfb79,
+ 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7e, 0xfb80, 0xfb81, 0xfb82,
+ 0xfb83, 0xfb84, 0xfb85, 0xfb86, 0xfb87, 0xfb88, 0xfb89, 0xfb8a,
+ 0xfb8b, 0xfb8c, 0xfb8d, 0xfb8e, 0xfb8f, 0xfb90, 0xfb91, 0xfb92,
+ 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97, 0xfb98, 0xfb99, 0xfb9a,
+ 0xfb9b, 0xfb9c, 0xfb9d, 0xfb9e, 0xfb9f, 0xfba0, 0xfc40, 0xfc41,
+ 0xfc42, 0xfc43, 0xfc44, 0xfc45, 0xfc46, 0xfc47, 0xfc48, 0xfc49,
+ 0xfc4a, 0xfc4b, 0xfc4c, 0xfc4d, 0xfc4e, 0xfc4f, 0xfc50, 0xfc51,
+ 0xfc52, 0xfc53, 0xfc54, 0xfc55, 0xfc56, 0xfc57, 0xfc58, 0xfc59,
+ 0xfc5a, 0xfc5b, 0xfc5c, 0xfc5d, 0xfc5e, 0xfc5f, 0xfc60, 0xfc61,
+ 0xfc62, 0xfc63, 0xfc64, 0xfc65, 0xfc66, 0xfc67, 0xfc68, 0xfc69,
+ 0xfc6a, 0xfc6b, 0xfc6c, 0xfc6d, 0xfc6e, 0xfc6f, 0xfc70, 0xfc71,
+ 0xfc72, 0xfc73, 0xfc74, 0xfc75, 0xfc76, 0xfc77, 0xfc78, 0xfc79,
+ 0xfc7a, 0xfc7b, 0xfc7c, 0xfc7d, 0xfc7e, 0xfc80, 0xfc81, 0xfc82,
+ 0xfc83, 0xfc84, 0xfc85, 0xfc86, 0xfc87, 0xfc88, 0xfc89, 0xfc8a,
+ 0xfc8b, 0xfc8c, 0xfc8d, 0xfc8e, 0xfc8f, 0xfc90, 0xfc91, 0xfc92,
+ 0xfc93, 0xfc94, 0xfc95, 0xfc96, 0xfc97, 0xfc98, 0xfc99, 0xfc9a,
+ 0xfc9b, 0xfc9c, 0xfc9d, 0xfc9e, 0xfc9f, 0xfca0, 0xfd40, 0xfd41,
+ 0xfd42, 0xfd43, 0xfd44, 0xfd45, 0xfd46, 0xfd47, 0xfd48, 0xfd49,
+ 0xfd4a, 0xfd4b, 0xfd4c, 0xfd4d, 0xfd4e, 0xfd4f, 0xfd50, 0xfd51,
+ 0xfd52, 0xfd53, 0xfd54, 0xfd55, 0xfd56, 0xfd57, 0xfd58, 0xfd59,
+ 0xfd5a, 0xfd5b, 0xfd5c, 0xfd5d, 0xfd5e, 0xfd5f, 0xfd60, 0xfd61,
+ 0xfd62, 0xfd63, 0xfd64, 0xfd65, 0xfd66, 0xfd67, 0xfd68, 0xfd69,
+ 0xfd6a, 0xfd6b, 0xfd6c, 0xfd6d, 0xfd6e, 0xfd6f, 0xfd70, 0xfd71,
+ 0xfd72, 0xfd73, 0xfd74, 0xfd75, 0xfd76, 0xfd77, 0xfd78, 0xfd79,
+ 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, 0xfd7e, 0xfd80, 0xfd81, 0xfd82,
+ 0xfd83, 0xfd84, 0xfd85, 0xfd86, 0xfd87, 0xfd88, 0xfd89, 0xfd8a,
+ 0xfd8b, 0xfd8c, 0xfd8d, 0xfd8e, 0xfd8f, 0xfd90, 0xfd91, 0xfd92,
+ 0xfd93, 0xfd94, 0xfd95, 0xfd96, 0xfd97, 0xfd98, 0xfd99, 0xfd9a,
+ 0xfd9b, 0xfd9c, 0xfd9d, 0xfd9e, 0xfd9f, 0xfda0, 0xfe40, 0xfe41,
+ 0xfe42, 0xfe43, 0xfe44, 0xfe45, 0xfe46, 0xfe47, 0xfe48, 0xfe49,
+ 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 0xa955, 0xa968,
+ 0xa969, 0xa96a, 0xa96b, 0xa96c, 0xa96d, 0xa96e, 0xa96f, 0xa970,
+ 0xa971, 0xa972, 0xa973, 0xa974, 0xa975, 0xa976, 0xa977, 0xa978,
+ 0xa979, 0xa97a, 0xa97b, 0xa97c, 0xa97d, 0xa97e, 0xa980, 0xa981,
+ 0xa982, 0xa983, 0xa984, 0xa985, 0xa986, 0xa987, 0xa988, 0xa956,
+ 0xa957,
+};
+
+static const Summary16 gbkext_inv_uni2indx_page02[14] = {
+ /* 0x0200 */
+ {0, 0x0000}, {0, 0x0000}, {0, 0x0000}, {0, 0x0000},
+ {0, 0x0000}, {0, 0x0000}, {0, 0x0000}, {0, 0x0000},
+ {0, 0x0000}, {0, 0x0000}, {0, 0x0000}, {0, 0x0000},
+ {0, 0x0c00}, {2, 0x0200},
+};
+static const Summary16 gbkext_inv_uni2indx_page20[44] = {
+ /* 0x2000 */
+ {3, 0x0000}, {3, 0x0029}, {6, 0x0020}, {7, 0x0020},
+ {8, 0x0000}, {8, 0x0000}, {8, 0x0000}, {8, 0x0000},
+ {8, 0x0000}, {8, 0x0000}, {8, 0x0000}, {8, 0x0000},
+ {8, 0x0000}, {8, 0x0000}, {8, 0x0000}, {8, 0x0000},
+ /* 0x2100 */
+ {8, 0x0220}, {10, 0x0000}, {10, 0x0002}, {11, 0x0000},
+ {11, 0x0000}, {11, 0x0000}, {11, 0x0000}, {11, 0x0000},
+ {11, 0x0000}, {11, 0x03c0}, {15, 0x0000}, {15, 0x0000},
+ {15, 0x0000}, {15, 0x0000}, {15, 0x0000}, {15, 0x0000},
+ /* 0x2200 */
+ {15, 0x0000}, {15, 0x8020}, {17, 0x0008}, {18, 0x0000},
+ {18, 0x0000}, {18, 0x0004}, {19, 0x00c0}, {21, 0x0000},
+ {21, 0x0000}, {21, 0x0020}, {22, 0x0000}, {22, 0x8000},
+};
+static const Summary16 gbkext_inv_uni2indx_page25[17] = {
+ /* 0x2500 */
+ {23, 0x0000}, {23, 0x0000}, {23, 0x0000}, {23, 0x0000},
+ {23, 0x0000}, {23, 0xffff}, {39, 0xffff}, {55, 0x000f},
+ {59, 0xfffe}, {74, 0x0038}, {77, 0x0000}, {77, 0x3000},
+ {79, 0x0000}, {79, 0x0000}, {79, 0x003c}, {83, 0x0000},
+ /* 0x2600 */
+ {83, 0x0200},
+};
+static const Summary16 gbkext_inv_uni2indx_page30[16] = {
+ /* 0x3000 */
+ {84, 0x00c0}, {86, 0x6004}, {89, 0x03fe}, {98, 0x0000},
+ {98, 0x0000}, {98, 0x0000}, {98, 0x0000}, {98, 0x0000},
+ {98, 0x0000}, {98, 0x7800}, {102, 0x0000}, {102, 0x0000},
+ {102, 0x0000}, {102, 0x0000}, {102, 0x0000}, {102, 0x7000},
+};
+static const Summary16 gbkext_inv_uni2indx_page32[30] = {
+ /* 0x3200 */
+ {105, 0x0000}, {105, 0x0000}, {105, 0x0000}, {105, 0x0002},
+ {106, 0x0000}, {106, 0x0000}, {106, 0x0000}, {106, 0x0000},
+ {106, 0x0000}, {106, 0x0000}, {106, 0x0008}, {107, 0x0000},
+ {107, 0x0000}, {107, 0x0000}, {107, 0x0000}, {107, 0x0000},
+ /* 0x3300 */
+ {107, 0x0000}, {107, 0x0000}, {107, 0x0000}, {107, 0x0000},
+ {107, 0x0000}, {107, 0x0000}, {107, 0x0000}, {107, 0x0000},
+ {107, 0xc000}, {109, 0x7000}, {112, 0x0002}, {113, 0x0000},
+ {113, 0x4010}, {115, 0x0026},
+};
+static const Summary16 gbkext_inv_uni2indx_page4e[1307] = {
+ /* 0x4e00 */
+ {118, 0x8074}, {123, 0x8084}, {126, 0xc24b}, {133, 0x10aa},
+ {138, 0x0457}, {144, 0x0ca2}, {149, 0xfdbc}, {161, 0xbff4},
+ {173, 0x04bf}, {181, 0x72c1}, {188, 0x8408}, {191, 0x73d3},
+ {201, 0x9100}, {204, 0x1c05}, {209, 0xe2c5}, {217, 0x5712},
+ /* 0x4f00 */
+ {224, 0x19fd}, {234, 0x307c}, {241, 0x730a}, {248, 0xcaaa},
+ {256, 0x1fb7}, {267, 0x0054}, {270, 0x6d46}, {278, 0x27a6},
+ {286, 0x54e7}, {295, 0xd76d}, {306, 0x2816}, {311, 0x7fdf},
+ {325, 0x3bc7}, {335, 0x0a7c}, {342, 0x18b5}, {349, 0xbaf5},
+ /* 0x5000 */
+ {360, 0x4fff}, {373, 0x68eb}, {382, 0x889d}, {389, 0xabff},
+ {402, 0x2e77}, {412, 0xebdf}, {425, 0xefdf}, {439, 0x373f},
+ {450, 0xdede}, {462, 0xffff}, {478, 0xec57}, {488, 0xf3fb},
+ {501, 0x7fff}, {516, 0xfbbf}, {530, 0x8f3f}, {541, 0xf7d7},
+ /* 0x5100 */
+ {554, 0xf73f}, {567, 0xfffb}, {582, 0xfffd}, {597, 0x7fff},
+ {612, 0xd484}, {618, 0xeb8d}, {628, 0x86db}, {637, 0xc404},
+ {641, 0xccd8}, {649, 0xe51b}, {658, 0x67ca}, {667, 0xc710},
+ {673, 0x652e}, {681, 0xd7fd}, {694, 0x57ec}, {704, 0x4096},
+ /* 0x5200 */
+ {709, 0x9a30}, {715, 0xd039}, {722, 0x94ee}, {731, 0x5036},
+ {737, 0xcbf0}, {746, 0xafac}, {756, 0x795d}, {766, 0x5ffb},
+ {779, 0xfef9}, {792, 0x17f6}, {802, 0xc0f0}, {808, 0x3ff1},
+ {819, 0xf577}, {831, 0x7eba}, {842, 0xffef}, {857, 0x39fe},
+ /* 0x5300 */
+ {868, 0x5e9e}, {878, 0xd91e}, {887, 0xbbb4}, {897, 0x31ff},
+ {908, 0x3855}, {915, 0x2b11}, {921, 0x3520}, {926, 0x7a44},
+ {933, 0xc58b}, {941, 0x5adf}, {952, 0xbc93}, {961, 0x77bf},
+ {974, 0xc0f9}, {982, 0x742d}, {990, 0x0086}, {993, 0xc410},
+ /* 0x5400 */
+ {997, 0x08a5}, {1002, 0x1710}, {1007, 0x0434}, {1011, 0xa4c9},
+ {1018, 0xf2b6}, {1028, 0xe402}, {1033, 0xfeab}, {1045, 0xc611},
+ {1051, 0x27aa}, {1059, 0xd18a}, {1066, 0x4027}, {1071, 0x56e5},
+ {1080, 0x0c28}, {1084, 0x0940}, {1087, 0x981f}, {1095, 0x4bf3},
+ /* 0x5500 */
+ {1105, 0x7d3d}, {1116, 0xf7ec}, {1128, 0x2b62}, {1135, 0x2f74},
+ {1144, 0xf9a5}, {1154, 0xef9e}, {1166, 0x8b0d}, {1173, 0xa61f},
+ {1182, 0x7060}, {1187, 0x4ced}, {1196, 0xff7f}, {1211, 0x9555},
+ {1219, 0xcdcf}, {1230, 0x4fa1}, {1238, 0x6285}, {1244, 0x9f53},
+ /* 0x5600 */
+ {1254, 0x2cfc}, {1263, 0x36ff}, {1275, 0xcf67}, {1286, 0x75a9},
+ {1295, 0x8fff}, {1308, 0xec6f}, {1319, 0xe0eb}, {1328, 0xe7bd},
+ {1340, 0x3f9f}, {1352, 0xfff7}, {1367, 0x7ff7}, {1381, 0xef7f},
+ {1395, 0xfbff}, {1410, 0x136f}, {1419, 0xd7e8}, {1429, 0x19cc},
+ /* 0x5700 */
+ {1436, 0xf8a7}, {1446, 0x6fff}, {1460, 0x08f7}, {1468, 0xb1f6},
+ {1478, 0x0b7a}, {1486, 0x037c}, {1493, 0x50ac}, {1499, 0xe737},
+ {1510, 0xe783}, {1519, 0xf7f3}, {1532, 0x9520}, {1537, 0xfeeb},
+ {1550, 0x37f3}, {1561, 0x58cb}, {1569, 0x5fee}, {1581, 0xd8ef},
+ /* 0x5800 */
+ {1592, 0xd73a}, {1602, 0xbddd}, {1614, 0xfbec}, {1626, 0xffde},
+ {1640, 0xcfef}, {1653, 0xbeed}, {1665, 0xe7df}, {1678, 0xbfff},
+ {1693, 0xfdd4}, {1704, 0x39f3}, {1714, 0xfcff}, {1728, 0xefff},
+ {1743, 0xffdd}, {1757, 0xffdd}, {1771, 0xa7ef}, {1783, 0xfdb6},
+ /* 0x5900 */
+ {1795, 0x5f6b}, {1806, 0x698f}, {1815, 0x114f}, {1822, 0xe86d},
+ {1831, 0x3469}, {1838, 0xfa0d}, {1847, 0xffda}, {1860, 0xdca7},
+ {1870, 0xda21}, {1877, 0xbd33}, {1887, 0x30c7}, {1894, 0xb5fb},
+ {1906, 0xf3bf}, {1919, 0xca60}, {1925, 0xeed7}, {1937, 0x75ff},
+ /* 0x5a00 */
+ {1950, 0xec05}, {1957, 0x6ef5}, {1968, 0xfdd6}, {1980, 0xefa9},
+ {1991, 0xf9be}, {2003, 0xfbdf}, {2017, 0xfb7b}, {2030, 0x7b0f},
+ {2040, 0xffff}, {2056, 0xf3fb}, {2069, 0xfbff}, {2084, 0xbed3},
+ {2095, 0xedf9}, {2107, 0xeeab}, {2118, 0xf5b4}, {2128, 0xfffd},
+ /* 0x5b00 */
+ {2143, 0xfdff}, {2158, 0xff3f}, {2172, 0xffff}, {2188, 0xff6b},
+ {2201, 0xfffe}, {2216, 0x4044}, {2219, 0xe983}, {2227, 0xdbd4},
+ {2237, 0x6444}, {2242, 0x8057}, {2248, 0xf380}, {2255, 0x1c86},
+ {2261, 0xef0b}, {2271, 0x1ff2}, {2281, 0xbecd}, {2292, 0x60fe},
+ /* 0x5c00 */
+ {2301, 0x79ad}, {2311, 0xca8d}, {2319, 0xef4b}, {2330, 0x00ed},
+ {2336, 0x30d8}, {2342, 0xbddc}, {2353, 0x3f94}, {2362, 0x79fd},
+ {2374, 0xcef9}, {2385, 0xe02c}, {2391, 0xc5f3}, {2401, 0x5e55},
+ {2410, 0xf7ed}, {2423, 0xfdfb}, {2437, 0xda8d}, {2446, 0xf7fe},
+ /* 0x5d00 */
+ {2460, 0xbf33}, {2471, 0xb7af}, {2483, 0x9d2f}, {2493, 0x9fef},
+ {2506, 0xe37f}, {2518, 0xd6ff}, {2531, 0x65ff}, {2543, 0xffef},
+ {2558, 0xfffb}, {2573, 0xddff}, {2587, 0xffff}, {2603, 0xff7f},
+ {2618, 0xdfdf}, {2632, 0x97ff}, {2645, 0x3419}, {2651, 0x9f61},
+ /* 0x5e00 */
+ {2660, 0x6e91}, {2668, 0xc08c}, {2673, 0x9f3f}, {2685, 0xc67d},
+ {2695, 0xefcb}, {2707, 0xb7cf}, {2719, 0xfff9}, {2733, 0x42a3},
+ {2739, 0x732e}, {2748, 0x2904}, {2752, 0xdf1e}, {2763, 0xbc17},
+ {2772, 0xf9ff}, {2786, 0xf7b1}, {2797, 0xfaff}, {2811, 0x3b2f},
+ /* 0x5f00 */
+ {2821, 0x72e0}, {2828, 0x7655}, {2837, 0x591e}, {2845, 0xe9fd},
+ {2857, 0xfffe}, {2872, 0xde12}, {2880, 0xc9a9}, {2888, 0xe574},
+ {2897, 0xe048}, {2902, 0xec5a}, {2911, 0x9afd}, {2922, 0xcf5f},
+ {2934, 0x4d87}, {2942, 0xdc38}, {2950, 0x936c}, {2958, 0x16dd},
+ /* 0x6000 */
+ {2967, 0x1b80}, {2972, 0xc58b}, {2980, 0x701c}, {2986, 0x67df},
+ {2998, 0xd7f1}, {3009, 0xd9da}, {3019, 0x4063}, {3024, 0x40b6},
+ {3030, 0xcde7}, {3041, 0x53ab}, {3050, 0x46b6}, {3058, 0xe6e9},
+ {3068, 0xf39f}, {3080, 0x4add}, {3089, 0x043e}, {3095, 0xf9a6},
+ /* 0x6100 */
+ {3105, 0x1cbc}, {3113, 0x7bdf}, {3126, 0xf726}, {3136, 0x7fff},
+ {3151, 0xaaff}, {3163, 0xdfdd}, {3176, 0xfe7b}, {3189, 0xff5e},
+ {3202, 0xb7ff}, {3216, 0xdfef}, {3230, 0xec7f}, {3242, 0xbf7f},
+ {3256, 0xf2fb}, {3268, 0xffe9}, {3281, 0xffbf}, {3296, 0x7fdf},
+ /* 0x6200 */
+ {3310, 0x02bf}, {3318, 0x7218}, {3324, 0xabc9}, {3333, 0x1f67},
+ {3343, 0x8474}, {3349, 0xf6e1}, {3359, 0x0137}, {3365, 0x2db6},
+ {3374, 0xf9ee}, {3386, 0x7211}, {3392, 0xe6c8}, {3400, 0x45dd},
+ {3409, 0x880b}, {3414, 0x6022}, {3418, 0x0c13}, {3423, 0x0f25},
+ /* 0x6300 */
+ {3430, 0xbc79}, {3440, 0x13bd}, {3449, 0x72c0}, {3455, 0xd9fb},
+ {3467, 0x0593}, {3473, 0x3fde}, {3485, 0x9d71}, {3494, 0xf33d},
+ {3505, 0x287a}, {3512, 0xfeba}, {3524, 0x8852}, {3529, 0xaa66},
+ {3537, 0x1daf}, {3547, 0xbfba}, {3559, 0xd9f4}, {3569, 0x5eab},
+ /* 0x6400 */
+ {3579, 0x67d8}, {3588, 0xa7e6}, {3598, 0xcbbc}, {3608, 0x5bef},
+ {3620, 0xfa0d}, {3629, 0xbeeb}, {3641, 0xdd7f}, {3654, 0xf8ff},
+ {3667, 0xff4b}, {3679, 0xbd99}, {3689, 0x8def}, {3700, 0xea5e},
+ {3710, 0x9fda}, {3721, 0xbe7a}, {3732, 0xffab}, {3745, 0xffff},
+ /* 0x6500 */
+ {3761, 0xfdfe}, {3775, 0xfefb}, {3789, 0x37df}, {3801, 0x348f},
+ {3809, 0x6cdf}, {3820, 0x959d}, {3829, 0xe7b3}, {3840, 0xff6a},
+ {3852, 0xe77f}, {3865, 0x6574}, {3873, 0x554d}, {3881, 0xcdfe},
+ {3893, 0x2785}, {3900, 0xff3b}, {3913, 0x0c1a}, {3918, 0xfb3c},
+ /* 0x6600 */
+ {3929, 0x2bb2}, {3937, 0x5dc7}, {3947, 0x5e5e}, {3957, 0xaf8d},
+ {3967, 0x67f5}, {3978, 0x7b03}, {3986, 0x3ead}, {3996, 0xbb2e},
+ {4006, 0xef6b}, {4018, 0xdf3d}, {4030, 0xbe7f}, {4043, 0xbdef},
+ {4056, 0xffff}, {4072, 0xc5ff}, {4084, 0xfdbf}, {4098, 0x2d62},
+ /* 0x6700 */
+ {4105, 0xd0fe}, {4115, 0x574e}, {4124, 0x42bf}, {4133, 0xdbcd},
+ {4144, 0x2cb2}, {4151, 0x2fb4}, {4160, 0x58dc}, {4168, 0x2f52},
+ {4176, 0xf56d}, {4187, 0x8a5e}, {4195, 0x5253}, {4202, 0xfe16},
+ {4212, 0x7fe5}, {4224, 0x88e0}, {4229, 0x6dda}, {4239, 0x5fe4},
+ /* 0x6800 */
+ {4249, 0x205e}, {4255, 0xdf35}, {4266, 0xf9fd}, {4279, 0x8c73},
+ {4287, 0xa880}, {4291, 0xffc4}, {4302, 0xf400}, {4307, 0xff2f},
+ {4320, 0x7f95}, {4331, 0xff77}, {4345, 0x5e3b}, {4355, 0xffd6},
+ {4368, 0xd5fa}, {4379, 0xfadb}, {4391, 0xbff6}, {4404, 0xe9dc},
+ /* 0x6900 */
+ {4414, 0x97dd}, {4425, 0x7ffa}, {4438, 0xdfee}, {4451, 0x5dee},
+ {4462, 0xfffb}, {4477, 0x9b6f}, {4488, 0xb7b6}, {4499, 0xec7d},
+ {4510, 0xdc2a}, {4518, 0xe6cf}, {4529, 0xd67f}, {4541, 0xf76d},
+ {4553, 0xabfd}, {4565, 0x77ee}, {4577, 0xdffe}, {4591, 0x5ffb},
+ /* 0x6a00 */
+ {4604, 0xfbff}, {4619, 0x7e7f}, {4632, 0x7afd}, {4644, 0x9fdd},
+ {4656, 0xff6f}, {4670, 0xf4fe}, {4682, 0xffdd}, {4696, 0xedfd},
+ {4709, 0xbfee}, {4722, 0xff7c}, {4735, 0xe5fe}, {4747, 0xffff},
+ {4763, 0xffff}, {4779, 0xffff}, {4795, 0xffff}, {4811, 0xffff},
+ /* 0x6b00 */
+ {4827, 0xffff}, {4843, 0xffff}, {4859, 0xff60}, {4869, 0xb97b},
+ {4880, 0xed37}, {4891, 0xfdff}, {4906, 0xfb03}, {4915, 0xe5ff},
+ {4928, 0xd121}, {4934, 0xf3b3}, {4945, 0xfbfd}, {4959, 0x7f47},
+ {4970, 0x57d9}, {4980, 0xf503}, {4988, 0x73fd}, {5000, 0xddd7},
+ /* 0x6c00 */
+ {5012, 0x5f1f}, {5023, 0x7084}, {5028, 0x3829}, {5034, 0xdeca},
+ {5044, 0xf938}, {5053, 0x074e}, {5060, 0xf8ec}, {5070, 0x9daa},
+ {5079, 0x6c91}, {5086, 0x75e6}, {5096, 0x9105}, {5101, 0x04f1},
+ {5107, 0xe9cf}, {5118, 0xb706}, {5126, 0x32d0}, {5132, 0x8214},
+ /* 0x6d00 */
+ {5136, 0xa76d}, {5146, 0xb17b}, {5156, 0xb35f}, {5167, 0x85d1},
+ {5174, 0x1215}, {5179, 0xa9e1}, {5187, 0x39b6}, {5196, 0xee6f},
+ {5208, 0xacdb}, {5218, 0x17c5}, {5226, 0x3024}, {5230, 0x7edb},
+ {5242, 0xe70e}, {5251, 0x9cbd}, {5261, 0xa7ac}, {5270, 0xe575},
+ /* 0x6e00 */
+ {5280, 0x8bdf}, {5291, 0xdb2c}, {5300, 0x55c4}, {5307, 0xfaeb},
+ {5319, 0x9fe7}, {5331, 0x76a7}, {5341, 0xb7ff}, {5355, 0x3fff},
+ {5369, 0x7d97}, {5380, 0x6efe}, {5392, 0x7b5b}, {5403, 0xd329},
+ {5411, 0x7779}, {5422, 0x3b45}, {5430, 0xfc88}, {5438, 0xfdef},
+ /* 0x6f00 */
+ {5452, 0x7dbb}, {5464, 0xffc7}, {5477, 0x51ee}, {5486, 0xbfb5},
+ {5498, 0xd73f}, {5510, 0xaeff}, {5523, 0x9fbb}, {5535, 0xeaeb},
+ {5546, 0x8cef}, {5556, 0xefff}, {5571, 0xff7d}, {5585, 0xfdb7},
+ {5598, 0xfdfa}, {5611, 0xbff9}, {5624, 0x3ffc}, {5636, 0xffff},
+ /* 0x7000 */
+ {5652, 0xffff}, {5668, 0xf3fd}, {5681, 0xfff7}, {5696, 0xfddf},
+ {5710, 0x6fff}, {5724, 0xbfff}, {5739, 0x47ff}, {5751, 0x2e9e},
+ {5760, 0xb9de}, {5771, 0xcd8b}, {5780, 0x07ff}, {5791, 0xc475},
+ {5799, 0xfaf0}, {5809, 0x74ff}, {5821, 0x442f}, {5828, 0xdd7f},
+ /* 0x7100 */
+ {5841, 0xf9ff}, {5855, 0xf896}, {5864, 0x7fbf}, {5878, 0xffbc},
+ {5891, 0xabdf}, {5903, 0xafff}, {5917, 0xbe2f}, {5928, 0xdaf3},
+ {5939, 0x7bef}, {5952, 0x7cef}, {5964, 0xeefe}, {5977, 0xfdd7},
+ {5990, 0xbff7}, {6004, 0xffcf}, {6018, 0xbf5e}, {6030, 0xfdff},
+ /* 0x7200 */
+ {6045, 0xffbf}, {6060, 0xdfff}, {6075, 0xeaff}, {6088, 0x541c},
+ {6094, 0xce7f}, {6106, 0x55bb}, {6116, 0x3d39}, {6125, 0x39db},
+ {6135, 0x53ec}, {6144, 0x7ffb}, {6158, 0x4fff}, {6171, 0xfc2e},
+ {6181, 0x9ee1}, {6190, 0xbd7a}, {6201, 0x0cfc}, {6209, 0xe260},
+ /* 0x7300 */
+ {6215, 0xbbf5}, {6227, 0x8717}, {6235, 0xa1d9}, {6243, 0x3c6d},
+ {6252, 0xdfff}, {6267, 0xff7a}, {6280, 0x4ffe}, {6292, 0xbfff},
+ {6307, 0xb56f}, {6318, 0x77bd}, {6330, 0x35fb}, {6341, 0xf372},
+ {6351, 0x58fa}, {6360, 0xbdfc}, {6372, 0xdd5e}, {6383, 0xfffb},
+ /* 0x7400 */
+ {6398, 0x7997}, {6408, 0xf3fe}, {6421, 0xaa9b}, {6430, 0xef86},
+ {6440, 0xfffd}, {6455, 0x215f}, {6463, 0xdfff}, {6478, 0xbf3e},
+ {6490, 0xb774}, {6500, 0xaffe}, {6513, 0xfc7f}, {6526, 0xfbff},
+ {6541, 0xffff}, {6557, 0xaffb}, {6570, 0x3fa2}, {6579, 0x7f2f},
+ /* 0x7500 */
+ {6591, 0x5fef}, {6604, 0x68f5}, {6613, 0x44df}, {6622, 0xb250},
+ {6628, 0x26de}, {6637, 0xe1ef}, {6648, 0xfb9f}, {6661, 0x7ceb},
+ {6672, 0x77b7}, {6684, 0x5929}, {6691, 0x27c4}, {6698, 0x8cc0},
+ {6703, 0xd843}, {6710, 0xb68b}, {6719, 0xf223}, {6727, 0x6dec},
+ /* 0x7600 */
+ {6737, 0xebd4}, {6747, 0x745e}, {6756, 0xd18a}, {6763, 0x2ec6},
+ {6771, 0xcff6}, {6783, 0xafaf}, {6795, 0x77f7}, {6808, 0x96ff},
+ {6820, 0xb62b}, {6829, 0xfdb5}, {6841, 0xbfef}, {6855, 0x7fe9},
+ {6867, 0x1a9b}, {6875, 0x7628}, {6882, 0x3fdf}, {6895, 0xace9},
+ /* 0x7700 */
+ {6904, 0xd46d}, {6913, 0x79ff}, {6926, 0x5cba}, {6935, 0xea1f},
+ {6945, 0xff74}, {6957, 0xf3fc}, {6969, 0xe691}, {6977, 0x1dff},
+ {6989, 0x8fce}, {6999, 0x7ff9}, {7012, 0xe95a}, {7021, 0x57d6},
+ {7031, 0xdfff}, {7046, 0xe77f}, {7059, 0x8553}, {7066, 0x1eb7},
+ /* 0x7800 */
+ {7076, 0xcdf8}, {7086, 0x4a29}, {7092, 0xcd17}, {7101, 0xa06e},
+ {7108, 0xaf5e}, {7119, 0xdf1a}, {7129, 0x83ff}, {7140, 0xef7f},
+ {7154, 0x8d7f}, {7165, 0x6275}, {7173, 0xff55}, {7185, 0xbde0},
+ {7194, 0xf1dd}, {7205, 0xfdce}, {7217, 0xeeff}, {7231, 0xfb6b},
+ /* 0x7900 */
+ {7243, 0xffdd}, {7257, 0xbff7}, {7271, 0xffef}, {7286, 0xa3ef},
+ {7297, 0xfcbc}, {7308, 0x0337}, {7315, 0x5e5a}, {7324, 0xfa7f},
+ {7337, 0x7bcc}, {7347, 0xfbff}, {7362, 0xff7f}, {7377, 0x91f7},
+ {7387, 0xd5b4}, {7396, 0x7ed9}, {7407, 0x5527}, {7415, 0xd6fe},
+ /* 0x7a00 */
+ {7427, 0x97b2}, {7436, 0xbb6f}, {7448, 0xfff6}, {7462, 0x4577},
+ {7471, 0xffbf}, {7486, 0xff7d}, {7500, 0xffff}, {7516, 0x782e},
+ {7524, 0xdea4}, {7533, 0x4e19}, {7540, 0xce9e}, {7550, 0x7ff7},
+ {7564, 0xf7ff}, {7579, 0x3dbf}, {7591, 0x5f96}, {7601, 0x59ff},
+ /* 0x7b00 */
+ {7613, 0x72a7}, {7622, 0xb5cd}, {7632, 0xa28e}, {7639, 0xaaf5},
+ {7649, 0x655f}, {7659, 0xd2a8}, {7666, 0xbffa}, {7679, 0xb559},
+ {7688, 0xdfde}, {7701, 0xcf4e}, {7711, 0xc039}, {7717, 0xfeed},
+ {7730, 0xef3d}, {7742, 0xd9f5}, {7753, 0xbb9d}, {7764, 0xaf7d},
+ /* 0x7c00 */
+ {7776, 0x677f}, {7788, 0x7fbf}, {7802, 0xfb3f}, {7815, 0x7eff},
+ {7829, 0xdffc}, {7842, 0xffff}, {7858, 0xffff}, {7874, 0xc7e7},
+ {7885, 0xfdff}, {7900, 0x0e59}, {7907, 0xbbcb}, {7918, 0x8df1},
+ {7927, 0xca5d}, {7936, 0x6d1f}, {7946, 0x7efe}, {7959, 0xf6ff},
+ /* 0x7d00 */
+ {7973, 0xfbff}, {7988, 0xffff}, {8004, 0x777a}, {8015, 0xffff},
+ {8031, 0xffff}, {8047, 0xffff}, {8063, 0xbfff}, {8078, 0xff7f},
+ {8093, 0xffff}, {8109, 0xffff}, {8125, 0xbfbf}, {8139, 0xffff},
+ {8155, 0xffff}, {8171, 0xffff}, {8187, 0xffff}, {8203, 0xffff},
+ /* 0x7e00 */
+ {8219, 0xffff}, {8235, 0xffff}, {8251, 0xffff}, {8267, 0xf7ff},
+ {8282, 0xff7d}, {8296, 0xffff}, {8312, 0xffff}, {8328, 0xffff},
+ {8344, 0xfffb}, {8359, 0x77ff}, {8373, 0x4000}, {8374, 0x1810},
+ {8377, 0x0000}, {8377, 0x0040}, {8378, 0x1010}, {8380, 0x0200},
+ /* 0x7f00 */
+ {8381, 0x0400}, {8382, 0x4001}, {8384, 0x0000}, {8384, 0xfa80},
+ {8391, 0xffcb}, {8404, 0x7a4c}, {8412, 0xb8f9}, {8422, 0xbde9},
+ {8433, 0xabfd}, {8445, 0x1bef}, {8456, 0x7f6d}, {8468, 0x4cfa},
+ {8477, 0xabdd}, {8488, 0x7ecf}, {8500, 0xbd9c}, {8510, 0xe7f4},
+ /* 0x8000 */
+ {8521, 0xc784}, {8528, 0xec0a}, {8535, 0xf81a}, {8543, 0x5615},
+ {8550, 0xc3b3}, {8559, 0xfaeb}, {8571, 0xf9ff}, {8585, 0x7ffd},
+ {8599, 0xe526}, {8607, 0x42b7}, {8615, 0x11c8}, {8620, 0x0b69},
+ {8627, 0x8fa0}, {8634, 0x813f}, {8642, 0x404d}, {8647, 0xcaa0},
+ /* 0x8100 */
+ {8653, 0x19bb}, {8662, 0xbaa0}, {8669, 0x6fff}, {8683, 0xbeb9},
+ {8694, 0xe2bf}, {8705, 0xf9c4}, {8714, 0x9d5e}, {8724, 0x01ec},
+ {8730, 0x7afa}, {8741, 0xc6fd}, {8752, 0xfab7}, {8764, 0xf3f7},
+ {8777, 0xebb0}, {8786, 0xffff}, {8802, 0xcb77}, {8813, 0xa7e7},
+ /* 0x8200 */
+ {8824, 0xcf88}, {8832, 0x27ea}, {8841, 0x42f1}, {8848, 0xb404},
+ {8853, 0x756f}, {8864, 0x7aff}, {8877, 0x3eff}, {8890, 0x19e2},
+ {8897, 0x12eb}, {8905, 0x4c79}, {8913, 0x008d}, {8917, 0x9c64},
+ {8924, 0x026d}, {8930, 0x2641}, {8935, 0x7784}, {8943, 0xf56d},
+ /* 0x8300 */
+ {8954, 0x2c01}, {8958, 0xe34d}, {8967, 0x467f}, {8977, 0xe885},
+ {8984, 0x7d36}, {8994, 0x23e8}, {9001, 0x0004}, {9002, 0xc67f},
+ {9013, 0xbd9f}, {9025, 0xa6f3}, {9035, 0xf0fe}, {9046, 0xc820},
+ {9050, 0x6b5c}, {9059, 0x4eaf}, {9069, 0xf9dc}, {9080, 0xdcf8},
+ /* 0x8400 */
+ {9090, 0x07a5}, {9097, 0xcefd}, {9109, 0xfe0f}, {9120, 0xcefd},
+ {9132, 0xffbf}, {9147, 0xe17d}, {9157, 0xc5f5}, {9167, 0xfa95},
+ {9177, 0xa47b}, {9186, 0xed7f}, {9199, 0x7ffd}, {9213, 0x58eb},
+ {9222, 0xd9ed}, {9233, 0x5fb4}, {9243, 0xef96}, {9254, 0x6ffe},
+ /* 0x8500 */
+ {9267, 0xefff}, {9282, 0x7b75}, {9293, 0xe7fd}, {9306, 0xc07f},
+ {9315, 0xf8f7}, {9327, 0xbdbf}, {9340, 0xfeef}, {9354, 0xb1eb},
+ {9364, 0x7f4f}, {9376, 0xe7ff}, {9390, 0x3aef}, {9401, 0xfd7e},
+ {9414, 0x7dfd}, {9427, 0xefd6}, {9439, 0xfdef}, {9453, 0x77ff},
+ /* 0x8600 */
+ {9467, 0xffdf}, {9482, 0xffbd}, {9496, 0xfd7f}, {9510, 0xeeff},
+ {9524, 0x1fff}, {9537, 0xbbec}, {9548, 0xa7fb}, {9560, 0x01fd},
+ {9568, 0xc3f8}, {9577, 0xcfd7}, {9589, 0x6867}, {9597, 0xfb8c},
+ {9607, 0x312e}, {9614, 0x34ec}, {9622, 0x9def}, {9634, 0xbce0},
+ /* 0x8700 */
+ {9642, 0xd872}, {9650, 0xaa53}, {9658, 0xbdd1}, {9668, 0x376d},
+ {9678, 0xac7f}, {9689, 0xfd77}, {9702, 0xbfc6}, {9713, 0x87ae},
+ {9722, 0xd6d3}, {9732, 0x7f77}, {9745, 0x46ff}, {9756, 0xdbd7},
+ {9768, 0xf3be}, {9780, 0xf7f1}, {9792, 0xbbde}, {9804, 0xbdff},
+ /* 0x8800 */
+ {9818, 0xfbf7}, {9832, 0xf797}, {9844, 0xfff9}, {9858, 0xedfb},
+ {9871, 0xcfce}, {9882, 0xfd6f}, {9895, 0xa4c1}, {9901, 0x1f7a},
+ {9911, 0xd6c9}, {9920, 0xefbb}, {9933, 0xd7eb}, {9945, 0xef7d},
+ {9958, 0xbd99}, {9968, 0x7ccb}, {9978, 0xfec3}, {9989, 0xace4},
+ /* 0x8900 */
+ {9997, 0xfbfb}, {10011, 0xf1f2}, {10021, 0xf3dd}, {10033, 0xffae},
+ {10046, 0xffed}, {10060, 0x3fff}, {10074, 0xffbf}, {10089, 0x77ff},
+ {10103, 0xffb5}, {10116, 0xffff}, {10132, 0xffff}, {10148, 0xffff},
+ {10164, 0x2009}, {10167, 0xabb8}, {10176, 0x7797}, {10187, 0xfff7},
+ /* 0x8a00 */
+ {10202, 0xff7e}, {10216, 0xffff}, {10232, 0xffff}, {10248, 0xbfff},
+ {10263, 0xfeff}, {10278, 0xffff}, {10294, 0xffff}, {10310, 0xfdff},
+ {10325, 0xf9ff}, {10339, 0xfff7}, {10354, 0xffff}, {10370, 0xffff},
+ {10386, 0xffff}, {10402, 0xffff}, {10418, 0xffff}, {10434, 0xffff},
+ /* 0x8b00 */
+ {10450, 0xff7f}, {10465, 0xffff}, {10481, 0xffbf}, {10496, 0xffff},
+ {10512, 0xffff}, {10528, 0xffff}, {10544, 0xefbf}, {10558, 0xffff},
+ {10574, 0xffff}, {10590, 0xffff}, {10606, 0x1000}, {10607, 0x0802},
+ {10609, 0x0080}, {10610, 0x0001}, {10611, 0x0400}, {10612, 0x0000},
+ /* 0x8c00 */
+ {10612, 0x0200}, {10613, 0x4000}, {10614, 0x0000}, {10614, 0xff00},
+ {10622, 0xed3d}, {10633, 0xfbdf}, {10647, 0xf3f9}, {10659, 0xf8f7},
+ {10671, 0xe9db}, {10682, 0xfeef}, {10696, 0xffff}, {10712, 0xffff},
+ {10728, 0xffff}, {10744, 0xffff}, {10760, 0xffff}, {10776, 0xffff},
+ /* 0x8d00 */
+ {10792, 0xffff}, {10808, 0x1fff}, {10821, 0x0001}, {10822, 0x0000},
+ {10822, 0x0000}, {10822, 0x8086}, {10826, 0xd720}, {10833, 0xff06},
+ {10843, 0xf3cd}, {10854, 0x7fed}, {10867, 0xfff7}, {10882, 0x2ac5},
+ {10889, 0x27a7}, {10898, 0x133d}, {10906, 0x62e7}, {10915, 0xd057},
+ /* 0x8e00 */
+ {10923, 0x69df}, {10934, 0x1fef}, {10946, 0x29f3}, {10955, 0xd9dd},
+ {10966, 0xf068}, {10973, 0xfdf9}, {10986, 0x4dbf}, {10997, 0x6faa},
+ {11007, 0x7f5d}, {11019, 0xafee}, {11031, 0x67ff}, {11044, 0xfbfb},
+ {11058, 0xbfff}, {11073, 0xffff}, {11089, 0xffff}, {11105, 0xffff},
+ /* 0x8f00 */
+ {11121, 0xffff}, {11137, 0xffff}, {11153, 0xffff}, {11169, 0xffff},
+ {11185, 0xffff}, {11201, 0xffff}, {11217, 0x043f}, {11224, 0x0000},
+ {11224, 0x1001}, {11226, 0x2004}, {11228, 0xf4f7}, {11240, 0x9dbc},
+ {11250, 0xbe49}, {11259, 0x04c4}, {11263, 0x908b}, {11269, 0xdc76},
+ /* 0x9000 */
+ {11279, 0x5180}, {11283, 0x1328}, {11288, 0x1fb8}, {11297, 0xa69f},
+ {11307, 0x5f69}, {11317, 0xf670}, {11326, 0x9ed3}, {11336, 0x5fcf},
+ {11348, 0xf6f2}, {11359, 0xd555}, {11368, 0x2bb1}, {11376, 0xb084},
+ {11381, 0x3b4d}, {11390, 0xc774}, {11399, 0x5639}, {11407, 0x9eef},
+ /* 0x9100 */
+ {11419, 0xffeb}, {11433, 0xbdff}, {11447, 0x7ff3}, {11460, 0xfdfd},
+ {11474, 0x01b7}, {11481, 0x9b7a}, {11491, 0x29c1}, {11497, 0x1c08},
+ {11501, 0xc55f}, {11511, 0xf3f8}, {11522, 0x1bf3}, {11532, 0xfbcf},
+ {11545, 0x097f}, {11554, 0xeffd}, {11568, 0xffff}, {11584, 0xffff},
+ /* 0x9200 */
+ {11600, 0xffff}, {11616, 0xffff}, {11632, 0xffff}, {11648, 0xffff},
+ {11664, 0xffff}, {11680, 0xffff}, {11696, 0xffff}, {11712, 0xffef},
+ {11727, 0xbfff}, {11742, 0xffff}, {11758, 0xbfff}, {11773, 0xffff},
+ {11789, 0xfeff}, {11804, 0xffff}, {11820, 0xffff}, {11836, 0xffff},
+ /* 0x9300 */
+ {11852, 0xffff}, {11868, 0xffff}, {11884, 0xffff}, {11900, 0xbfff},
+ {11915, 0xffff}, {11931, 0xffff}, {11947, 0xfbff}, {11962, 0xffff},
+ {11978, 0x7fff}, {11993, 0xffff}, {12009, 0xffff}, {12025, 0xffff},
+ {12041, 0xfbff}, {12056, 0xffbf}, {12071, 0xffff}, {12087, 0xffff},
+ /* 0x9400 */
+ {12103, 0xffff}, {12119, 0xffff}, {12135, 0xffff}, {12151, 0xbfff},
+ {12166, 0xffff}, {12182, 0xffff}, {12198, 0xf7ff}, {12213, 0xffff},
+ {12229, 0x001f}, {12234, 0x0142}, {12237, 0x0000}, {12237, 0x0000},
+ {12237, 0x8080}, {12239, 0x0418}, {12242, 0x0040}, {12243, 0x0800},
+ /* 0x9500 */
+ {12244, 0x0000}, {12244, 0x1000}, {12245, 0x0081}, {12247, 0x2008},
+ {12249, 0x0908}, {12252, 0x0420}, {12254, 0x4001}, {12256, 0x7fb0},
+ {12266, 0xffff}, {12282, 0xffff}, {12298, 0xffff}, {12314, 0xffff},
+ {12330, 0xffff}, {12346, 0xffff}, {12362, 0x10ff}, {12371, 0x8000},
+ /* 0x9600 */
+ {12372, 0x0080}, {12373, 0x4908}, {12377, 0xbbf9}, {12389, 0x4781},
+ {12395, 0xc40a}, {12400, 0x77ce}, {12411, 0xe869}, {12419, 0xff0b},
+ {12430, 0x569f}, {12440, 0xec6e}, {12450, 0xff7f}, {12465, 0x8db6},
+ {12474, 0x0d0c}, {12479, 0xffdb}, {12493, 0x78fe}, {12504, 0xbd37},
+ /* 0x9700 */
+ {12515, 0x1c2c}, {12521, 0xafb7}, {12533, 0xdbff}, {12547, 0xbcfa},
+ {12558, 0xffff}, {12574, 0xb5b3}, {12584, 0xfdd8}, {12595, 0xefa7},
+ {12607, 0xd7df}, {12620, 0xfee9}, {12632, 0x57f6}, {12643, 0xffeb},
+ {12657, 0xffff}, {12673, 0xffff}, {12689, 0xc13f}, {12698, 0xff97},
+ /* 0x9800 */
+ {12711, 0xffff}, {12727, 0xffff}, {12743, 0xffff}, {12759, 0xffff},
+ {12775, 0xffff}, {12791, 0xffff}, {12807, 0xffff}, {12823, 0x001f},
+ {12828, 0x4800}, {12830, 0x0224}, {12833, 0xff08}, {12842, 0xffff},
+ {12858, 0xbfff}, {12873, 0x38d1}, {12880, 0xfe7f}, {12894, 0xffff},
+ /* 0x9900 */
+ {12910, 0xdfff}, {12925, 0xfffe}, {12940, 0xbfff}, {12955, 0xffff},
+ {12971, 0xffff}, {12987, 0xffcf}, {13001, 0x0057}, {13006, 0x4b08},
+ {13011, 0x520c}, {13016, 0xfc00}, {13022, 0xfedf}, {13036, 0xffff},
+ {13052, 0xffff}, {13068, 0xffff}, {13084, 0xffff}, {13100, 0xffff},
+ /* 0x9a00 */
+ {13116, 0xffff}, {13132, 0xffff}, {13148, 0xffff}, {13164, 0xffff},
+ {13180, 0xffff}, {13196, 0xffff}, {13212, 0x0fff}, {13224, 0x0004},
+ {13225, 0x6208}, {13229, 0x0230}, {13232, 0xfe40}, {13240, 0xea3c},
+ {13249, 0xe7d8}, {13259, 0x7ef5}, {13271, 0x57bd}, {13282, 0xf5ff},
+ /* 0x9b00 */
+ {13296, 0x7ef7}, {13309, 0x7ff7}, {13323, 0x7ff7}, {13337, 0xe7fb},
+ {13350, 0x5c41}, {13356, 0xffed}, {13370, 0xffff}, {13386, 0xffff},
+ {13402, 0xffff}, {13418, 0xffff}, {13434, 0xffff}, {13450, 0xffff},
+ {13466, 0xffff}, {13482, 0xffff}, {13498, 0xffff}, {13514, 0xffff},
+ /* 0x9c00 */
+ {13530, 0xffff}, {13546, 0xffff}, {13562, 0xffff}, {13578, 0xffff},
+ {13594, 0xffff}, {13610, 0xffff}, {13626, 0xffff}, {13642, 0x6fff},
+ {13656, 0x9619}, {13663, 0x23c8}, {13669, 0x9400}, {13672, 0xc200},
+ {13675, 0x0307}, {13680, 0x0c06}, {13684, 0xfffb}, {13699, 0xffff},
+ /* 0x9d00 */
+ {13715, 0xffff}, {13731, 0xffff}, {13747, 0xffff}, {13763, 0xffff},
+ {13779, 0xffff}, {13795, 0xffff}, {13811, 0xffff}, {13827, 0xffff},
+ {13843, 0xffff}, {13859, 0xffff}, {13875, 0xffff}, {13891, 0xffff},
+ {13907, 0xffff}, {13923, 0xffff}, {13939, 0xffff}, {13955, 0xffff},
+ /* 0x9e00 */
+ {13971, 0xffff}, {13987, 0x7fff}, {14002, 0x4090}, {14005, 0x1811},
+ {14009, 0x2001}, {14011, 0xa25d}, {14019, 0xc027}, {14025, 0x3ff4},
+ {14036, 0xf67b}, {14048, 0x5ff3}, {14060, 0xffbf}, {14075, 0x96ef},
+ {14086, 0x1def}, {14097, 0x46ed}, {14106, 0x795a}, {14115, 0xa5ff},
+ /* 0x9f00 */
+ {14127, 0x97ff}, {14140, 0xfd76}, {14152, 0x6ffa}, {14164, 0x957f},
+ {14175, 0xffef}, {14190, 0xfffc}, {14204, 0xffff}, {14220, 0x7fff},
+ {14235, 0xe006}, {14240, 0x71ff}, {14252, 0x003e},
+};
+static const Summary16 gbkext_inv_uni2indx_pagef9[19] = {
+ /* 0xf900 */
+ {14257, 0x0000}, {14257, 0x0000}, {14257, 0x1000}, {14258, 0x0000},
+ {14258, 0x0000}, {14258, 0x0000}, {14258, 0x0000}, {14258, 0x0200},
+ {14259, 0x0000}, {14259, 0x0020}, {14260, 0x0000}, {14260, 0x0000},
+ {14260, 0x0000}, {14260, 0x0000}, {14260, 0x0080}, {14261, 0x0002},
+ /* 0xfa00 */
+ {14262, 0xf000}, {14266, 0x811a}, {14271, 0x039b},
+};
+static const Summary16 gbkext_inv_uni2indx_pagefe[31] = {
+ /* 0xfe00 */
+ {14278, 0x0000}, {14278, 0x0000}, {14278, 0x0000}, {14278, 0x0001},
+ {14279, 0xfe00}, {14286, 0xfef7}, {14300, 0x0f7f}, {14311, 0x0000},
+ {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000},
+ {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000},
+ /* 0xff00 */
+ {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000},
+ {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000},
+ {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0000},
+ {14311, 0x0000}, {14311, 0x0000}, {14311, 0x0014},
+};
+
+static const unsigned short cp936ext_2uni_pagea6[181 - 159] = {
+ /* 0xa6 */
+ 0xfe35,
+ 0xfe36, 0xfe39, 0xfe3a, 0xfe3f, 0xfe40, 0xfe3d, 0xfe3e, 0xfe41,
+ 0xfe42, 0xfe43, 0xfe44, 0xfffd, 0xfffd, 0xfe3b, 0xfe3c, 0xfe37,
+ 0xfe38, 0xfe31, 0xfffd, 0xfe33, 0xfe34,
+};
+static const unsigned short cp936ext_2uni_pagea8[128 - 122] = {
+ /* 0xa8 */
+ 0x0251, 0xfffd, 0x0144, 0x0148, 0xfffd, 0x0261,
+};
+
+static const unsigned short cp936ext_page01[16] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xa8bd, 0x0000, 0x0000, 0x0000, /*0x40-0x47 */
+ 0xa8be, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f */
+};
+static const unsigned short cp936ext_page02[24] = {
+ 0x0000, 0xa8bb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57 */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f */
+ 0x0000, 0xa8c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67 */
+};
+static const unsigned short cp936ext_pagefe[24] = {
+ 0x0000, 0xa6f2, 0x0000, 0xa6f4, 0xa6f5, 0xa6e0, 0xa6e1, 0xa6f0, /*0x30-0x37 */
+ 0xa6f1, 0xa6e2, 0xa6e3, 0xa6ee, 0xa6ef, 0xa6e6, 0xa6e7, 0xa6e4, /*0x38-0x3f */
+ 0xa6e5, 0xa6e8, 0xa6e9, 0xa6ea, 0xa6eb, 0x0000, 0x0000, 0x0000, /*0x40-0x47 */
+};
+
+static const unsigned short gb2312_2uni_page21[831] = {
+ /* 0x21 */
+ 0x3000, 0x3001, 0x3002, 0x30fb, 0x02c9, 0x02c7, 0x00a8, 0x3003,
+ 0x3005, 0x2015, 0xff5e, 0x2016, 0x2026, 0x2018, 0x2019, 0x201c,
+ 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c,
+ 0x300d, 0x300e, 0x300f, 0x3016, 0x3017, 0x3010, 0x3011, 0x00b1,
+ 0x00d7, 0x00f7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220f, 0x222a,
+ 0x2229, 0x2208, 0x2237, 0x221a, 0x22a5, 0x2225, 0x2220, 0x2312,
+ 0x2299, 0x222b, 0x222e, 0x2261, 0x224c, 0x2248, 0x223d, 0x221d,
+ 0x2260, 0x226e, 0x226f, 0x2264, 0x2265, 0x221e, 0x2235, 0x2234,
+ 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xff04, 0x00a4,
+ 0xffe0, 0xffe1, 0x2030, 0x00a7, 0x2116, 0x2606, 0x2605, 0x25cb,
+ 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2,
+ 0x203b, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013,
+ /* 0x22 */
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f,
+ 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497,
+ 0x2498, 0x2499, 0x249a, 0x249b, 0x2474, 0x2475, 0x2476, 0x2477,
+ 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f,
+ 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487,
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0xfffd, 0xfffd, 0x3220, 0x3221, 0x3222, 0x3223,
+ 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xfffd, 0xfffd,
+ 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167,
+ 0x2168, 0x2169, 0x216a, 0x216b, 0xfffd, 0xfffd,
+ /* 0x23 */
+ 0xff01, 0xff02, 0xff03, 0xffe5, 0xff05, 0xff06, 0xff07, 0xff08,
+ 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10,
+ 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18,
+ 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20,
+ 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28,
+ 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30,
+ 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38,
+ 0xff39, 0xff3a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, 0xff40,
+ 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48,
+ 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50,
+ 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58,
+ 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3,
+ /* 0x24 */
+ 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048,
+ 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050,
+ 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058,
+ 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060,
+ 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068,
+ 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070,
+ 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078,
+ 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080,
+ 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088,
+ 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090,
+ 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0x25 */
+ 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8,
+ 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0,
+ 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8,
+ 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0,
+ 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8,
+ 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0,
+ 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8,
+ 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0,
+ 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8,
+ 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0,
+ 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0x26 */
+ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
+ 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0,
+ 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8,
+ 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0,
+ 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0x27 */
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416,
+ 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426,
+ 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e,
+ 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436,
+ 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
+ 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446,
+ 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e,
+ 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0x28 */
+ 0x0101, 0x00e1, 0x01ce, 0x00e0, 0x0113, 0x00e9, 0x011b, 0x00e8,
+ 0x012b, 0x00ed, 0x01d0, 0x00ec, 0x014d, 0x00f3, 0x01d2, 0x00f2,
+ 0x016b, 0x00fa, 0x01d4, 0x00f9, 0x01d6, 0x01d8, 0x01da, 0x01dc,
+ 0x00fc, 0x00ea, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3105, 0x3106, 0x3107, 0x3108,
+ 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110,
+ 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118,
+ 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120,
+ 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128,
+ 0x3129, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0x29 */
+ 0xfffd, 0xfffd, 0xfffd, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504,
+ 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250a, 0x250b, 0x250c,
+ 0x250d, 0x250e, 0x250f, 0x2510, 0x2511, 0x2512, 0x2513, 0x2514,
+ 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251a, 0x251b, 0x251c,
+ 0x251d, 0x251e, 0x251f, 0x2520, 0x2521, 0x2522, 0x2523, 0x2524,
+ 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c,
+ 0x252d, 0x252e, 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534,
+ 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c,
+ 0x253d, 0x253e, 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544,
+ 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b,
+};
+static const unsigned short gb2312_2uni_page30[6768] = {
+ /* 0x30 */
+ 0x554a, 0x963f, 0x57c3, 0x6328, 0x54ce, 0x5509, 0x54c0, 0x7691,
+ 0x764c, 0x853c, 0x77ee, 0x827e, 0x788d, 0x7231, 0x9698, 0x978d,
+ 0x6c28, 0x5b89, 0x4ffa, 0x6309, 0x6697, 0x5cb8, 0x80fa, 0x6848,
+ 0x80ae, 0x6602, 0x76ce, 0x51f9, 0x6556, 0x71ac, 0x7ff1, 0x8884,
+ 0x50b2, 0x5965, 0x61ca, 0x6fb3, 0x82ad, 0x634c, 0x6252, 0x53ed,
+ 0x5427, 0x7b06, 0x516b, 0x75a4, 0x5df4, 0x62d4, 0x8dcb, 0x9776,
+ 0x628a, 0x8019, 0x575d, 0x9738, 0x7f62, 0x7238, 0x767d, 0x67cf,
+ 0x767e, 0x6446, 0x4f70, 0x8d25, 0x62dc, 0x7a17, 0x6591, 0x73ed,
+ 0x642c, 0x6273, 0x822c, 0x9881, 0x677f, 0x7248, 0x626e, 0x62cc,
+ 0x4f34, 0x74e3, 0x534a, 0x529e, 0x7eca, 0x90a6, 0x5e2e, 0x6886,
+ 0x699c, 0x8180, 0x7ed1, 0x68d2, 0x78c5, 0x868c, 0x9551, 0x508d,
+ 0x8c24, 0x82de, 0x80de, 0x5305, 0x8912, 0x5265,
+ /* 0x31 */
+ 0x8584, 0x96f9, 0x4fdd, 0x5821, 0x9971, 0x5b9d, 0x62b1, 0x62a5,
+ 0x66b4, 0x8c79, 0x9c8d, 0x7206, 0x676f, 0x7891, 0x60b2, 0x5351,
+ 0x5317, 0x8f88, 0x80cc, 0x8d1d, 0x94a1, 0x500d, 0x72c8, 0x5907,
+ 0x60eb, 0x7119, 0x88ab, 0x5954, 0x82ef, 0x672c, 0x7b28, 0x5d29,
+ 0x7ef7, 0x752d, 0x6cf5, 0x8e66, 0x8ff8, 0x903c, 0x9f3b, 0x6bd4,
+ 0x9119, 0x7b14, 0x5f7c, 0x78a7, 0x84d6, 0x853d, 0x6bd5, 0x6bd9,
+ 0x6bd6, 0x5e01, 0x5e87, 0x75f9, 0x95ed, 0x655d, 0x5f0a, 0x5fc5,
+ 0x8f9f, 0x58c1, 0x81c2, 0x907f, 0x965b, 0x97ad, 0x8fb9, 0x7f16,
+ 0x8d2c, 0x6241, 0x4fbf, 0x53d8, 0x535e, 0x8fa8, 0x8fa9, 0x8fab,
+ 0x904d, 0x6807, 0x5f6a, 0x8198, 0x8868, 0x9cd6, 0x618b, 0x522b,
+ 0x762a, 0x5f6c, 0x658c, 0x6fd2, 0x6ee8, 0x5bbe, 0x6448, 0x5175,
+ 0x51b0, 0x67c4, 0x4e19, 0x79c9, 0x997c, 0x70b3,
+ /* 0x32 */
+ 0x75c5, 0x5e76, 0x73bb, 0x83e0, 0x64ad, 0x62e8, 0x94b5, 0x6ce2,
+ 0x535a, 0x52c3, 0x640f, 0x94c2, 0x7b94, 0x4f2f, 0x5e1b, 0x8236,
+ 0x8116, 0x818a, 0x6e24, 0x6cca, 0x9a73, 0x6355, 0x535c, 0x54fa,
+ 0x8865, 0x57e0, 0x4e0d, 0x5e03, 0x6b65, 0x7c3f, 0x90e8, 0x6016,
+ 0x64e6, 0x731c, 0x88c1, 0x6750, 0x624d, 0x8d22, 0x776c, 0x8e29,
+ 0x91c7, 0x5f69, 0x83dc, 0x8521, 0x9910, 0x53c2, 0x8695, 0x6b8b,
+ 0x60ed, 0x60e8, 0x707f, 0x82cd, 0x8231, 0x4ed3, 0x6ca7, 0x85cf,
+ 0x64cd, 0x7cd9, 0x69fd, 0x66f9, 0x8349, 0x5395, 0x7b56, 0x4fa7,
+ 0x518c, 0x6d4b, 0x5c42, 0x8e6d, 0x63d2, 0x53c9, 0x832c, 0x8336,
+ 0x67e5, 0x78b4, 0x643d, 0x5bdf, 0x5c94, 0x5dee, 0x8be7, 0x62c6,
+ 0x67f4, 0x8c7a, 0x6400, 0x63ba, 0x8749, 0x998b, 0x8c17, 0x7f20,
+ 0x94f2, 0x4ea7, 0x9610, 0x98a4, 0x660c, 0x7316,
+ /* 0x33 */
+ 0x573a, 0x5c1d, 0x5e38, 0x957f, 0x507f, 0x80a0, 0x5382, 0x655e,
+ 0x7545, 0x5531, 0x5021, 0x8d85, 0x6284, 0x949e, 0x671d, 0x5632,
+ 0x6f6e, 0x5de2, 0x5435, 0x7092, 0x8f66, 0x626f, 0x64a4, 0x63a3,
+ 0x5f7b, 0x6f88, 0x90f4, 0x81e3, 0x8fb0, 0x5c18, 0x6668, 0x5ff1,
+ 0x6c89, 0x9648, 0x8d81, 0x886c, 0x6491, 0x79f0, 0x57ce, 0x6a59,
+ 0x6210, 0x5448, 0x4e58, 0x7a0b, 0x60e9, 0x6f84, 0x8bda, 0x627f,
+ 0x901e, 0x9a8b, 0x79e4, 0x5403, 0x75f4, 0x6301, 0x5319, 0x6c60,
+ 0x8fdf, 0x5f1b, 0x9a70, 0x803b, 0x9f7f, 0x4f88, 0x5c3a, 0x8d64,
+ 0x7fc5, 0x65a5, 0x70bd, 0x5145, 0x51b2, 0x866b, 0x5d07, 0x5ba0,
+ 0x62bd, 0x916c, 0x7574, 0x8e0c, 0x7a20, 0x6101, 0x7b79, 0x4ec7,
+ 0x7ef8, 0x7785, 0x4e11, 0x81ed, 0x521d, 0x51fa, 0x6a71, 0x53a8,
+ 0x8e87, 0x9504, 0x96cf, 0x6ec1, 0x9664, 0x695a,
+ /* 0x34 */
+ 0x7840, 0x50a8, 0x77d7, 0x6410, 0x89e6, 0x5904, 0x63e3, 0x5ddd,
+ 0x7a7f, 0x693d, 0x4f20, 0x8239, 0x5598, 0x4e32, 0x75ae, 0x7a97,
+ 0x5e62, 0x5e8a, 0x95ef, 0x521b, 0x5439, 0x708a, 0x6376, 0x9524,
+ 0x5782, 0x6625, 0x693f, 0x9187, 0x5507, 0x6df3, 0x7eaf, 0x8822,
+ 0x6233, 0x7ef0, 0x75b5, 0x8328, 0x78c1, 0x96cc, 0x8f9e, 0x6148,
+ 0x74f7, 0x8bcd, 0x6b64, 0x523a, 0x8d50, 0x6b21, 0x806a, 0x8471,
+ 0x56f1, 0x5306, 0x4ece, 0x4e1b, 0x51d1, 0x7c97, 0x918b, 0x7c07,
+ 0x4fc3, 0x8e7f, 0x7be1, 0x7a9c, 0x6467, 0x5d14, 0x50ac, 0x8106,
+ 0x7601, 0x7cb9, 0x6dec, 0x7fe0, 0x6751, 0x5b58, 0x5bf8, 0x78cb,
+ 0x64ae, 0x6413, 0x63aa, 0x632b, 0x9519, 0x642d, 0x8fbe, 0x7b54,
+ 0x7629, 0x6253, 0x5927, 0x5446, 0x6b79, 0x50a3, 0x6234, 0x5e26,
+ 0x6b86, 0x4ee3, 0x8d37, 0x888b, 0x5f85, 0x902e,
+ /* 0x35 */
+ 0x6020, 0x803d, 0x62c5, 0x4e39, 0x5355, 0x90f8, 0x63b8, 0x80c6,
+ 0x65e6, 0x6c2e, 0x4f46, 0x60ee, 0x6de1, 0x8bde, 0x5f39, 0x86cb,
+ 0x5f53, 0x6321, 0x515a, 0x8361, 0x6863, 0x5200, 0x6363, 0x8e48,
+ 0x5012, 0x5c9b, 0x7977, 0x5bfc, 0x5230, 0x7a3b, 0x60bc, 0x9053,
+ 0x76d7, 0x5fb7, 0x5f97, 0x7684, 0x8e6c, 0x706f, 0x767b, 0x7b49,
+ 0x77aa, 0x51f3, 0x9093, 0x5824, 0x4f4e, 0x6ef4, 0x8fea, 0x654c,
+ 0x7b1b, 0x72c4, 0x6da4, 0x7fdf, 0x5ae1, 0x62b5, 0x5e95, 0x5730,
+ 0x8482, 0x7b2c, 0x5e1d, 0x5f1f, 0x9012, 0x7f14, 0x98a0, 0x6382,
+ 0x6ec7, 0x7898, 0x70b9, 0x5178, 0x975b, 0x57ab, 0x7535, 0x4f43,
+ 0x7538, 0x5e97, 0x60e6, 0x5960, 0x6dc0, 0x6bbf, 0x7889, 0x53fc,
+ 0x96d5, 0x51cb, 0x5201, 0x6389, 0x540a, 0x9493, 0x8c03, 0x8dcc,
+ 0x7239, 0x789f, 0x8776, 0x8fed, 0x8c0d, 0x53e0,
+ /* 0x36 */
+ 0x4e01, 0x76ef, 0x53ee, 0x9489, 0x9876, 0x9f0e, 0x952d, 0x5b9a,
+ 0x8ba2, 0x4e22, 0x4e1c, 0x51ac, 0x8463, 0x61c2, 0x52a8, 0x680b,
+ 0x4f97, 0x606b, 0x51bb, 0x6d1e, 0x515c, 0x6296, 0x6597, 0x9661,
+ 0x8c46, 0x9017, 0x75d8, 0x90fd, 0x7763, 0x6bd2, 0x728a, 0x72ec,
+ 0x8bfb, 0x5835, 0x7779, 0x8d4c, 0x675c, 0x9540, 0x809a, 0x5ea6,
+ 0x6e21, 0x5992, 0x7aef, 0x77ed, 0x953b, 0x6bb5, 0x65ad, 0x7f0e,
+ 0x5806, 0x5151, 0x961f, 0x5bf9, 0x58a9, 0x5428, 0x8e72, 0x6566,
+ 0x987f, 0x56e4, 0x949d, 0x76fe, 0x9041, 0x6387, 0x54c6, 0x591a,
+ 0x593a, 0x579b, 0x8eb2, 0x6735, 0x8dfa, 0x8235, 0x5241, 0x60f0,
+ 0x5815, 0x86fe, 0x5ce8, 0x9e45, 0x4fc4, 0x989d, 0x8bb9, 0x5a25,
+ 0x6076, 0x5384, 0x627c, 0x904f, 0x9102, 0x997f, 0x6069, 0x800c,
+ 0x513f, 0x8033, 0x5c14, 0x9975, 0x6d31, 0x4e8c,
+ /* 0x37 */
+ 0x8d30, 0x53d1, 0x7f5a, 0x7b4f, 0x4f10, 0x4e4f, 0x9600, 0x6cd5,
+ 0x73d0, 0x85e9, 0x5e06, 0x756a, 0x7ffb, 0x6a0a, 0x77fe, 0x9492,
+ 0x7e41, 0x51e1, 0x70e6, 0x53cd, 0x8fd4, 0x8303, 0x8d29, 0x72af,
+ 0x996d, 0x6cdb, 0x574a, 0x82b3, 0x65b9, 0x80aa, 0x623f, 0x9632,
+ 0x59a8, 0x4eff, 0x8bbf, 0x7eba, 0x653e, 0x83f2, 0x975e, 0x5561,
+ 0x98de, 0x80a5, 0x532a, 0x8bfd, 0x5420, 0x80ba, 0x5e9f, 0x6cb8,
+ 0x8d39, 0x82ac, 0x915a, 0x5429, 0x6c1b, 0x5206, 0x7eb7, 0x575f,
+ 0x711a, 0x6c7e, 0x7c89, 0x594b, 0x4efd, 0x5fff, 0x6124, 0x7caa,
+ 0x4e30, 0x5c01, 0x67ab, 0x8702, 0x5cf0, 0x950b, 0x98ce, 0x75af,
+ 0x70fd, 0x9022, 0x51af, 0x7f1d, 0x8bbd, 0x5949, 0x51e4, 0x4f5b,
+ 0x5426, 0x592b, 0x6577, 0x80a4, 0x5b75, 0x6276, 0x62c2, 0x8f90,
+ 0x5e45, 0x6c1f, 0x7b26, 0x4f0f, 0x4fd8, 0x670d,
+ /* 0x38 */
+ 0x6d6e, 0x6daa, 0x798f, 0x88b1, 0x5f17, 0x752b, 0x629a, 0x8f85,
+ 0x4fef, 0x91dc, 0x65a7, 0x812f, 0x8151, 0x5e9c, 0x8150, 0x8d74,
+ 0x526f, 0x8986, 0x8d4b, 0x590d, 0x5085, 0x4ed8, 0x961c, 0x7236,
+ 0x8179, 0x8d1f, 0x5bcc, 0x8ba3, 0x9644, 0x5987, 0x7f1a, 0x5490,
+ 0x5676, 0x560e, 0x8be5, 0x6539, 0x6982, 0x9499, 0x76d6, 0x6e89,
+ 0x5e72, 0x7518, 0x6746, 0x67d1, 0x7aff, 0x809d, 0x8d76, 0x611f,
+ 0x79c6, 0x6562, 0x8d63, 0x5188, 0x521a, 0x94a2, 0x7f38, 0x809b,
+ 0x7eb2, 0x5c97, 0x6e2f, 0x6760, 0x7bd9, 0x768b, 0x9ad8, 0x818f,
+ 0x7f94, 0x7cd5, 0x641e, 0x9550, 0x7a3f, 0x544a, 0x54e5, 0x6b4c,
+ 0x6401, 0x6208, 0x9e3d, 0x80f3, 0x7599, 0x5272, 0x9769, 0x845b,
+ 0x683c, 0x86e4, 0x9601, 0x9694, 0x94ec, 0x4e2a, 0x5404, 0x7ed9,
+ 0x6839, 0x8ddf, 0x8015, 0x66f4, 0x5e9a, 0x7fb9,
+ /* 0x39 */
+ 0x57c2, 0x803f, 0x6897, 0x5de5, 0x653b, 0x529f, 0x606d, 0x9f9a,
+ 0x4f9b, 0x8eac, 0x516c, 0x5bab, 0x5f13, 0x5de9, 0x6c5e, 0x62f1,
+ 0x8d21, 0x5171, 0x94a9, 0x52fe, 0x6c9f, 0x82df, 0x72d7, 0x57a2,
+ 0x6784, 0x8d2d, 0x591f, 0x8f9c, 0x83c7, 0x5495, 0x7b8d, 0x4f30,
+ 0x6cbd, 0x5b64, 0x59d1, 0x9f13, 0x53e4, 0x86ca, 0x9aa8, 0x8c37,
+ 0x80a1, 0x6545, 0x987e, 0x56fa, 0x96c7, 0x522e, 0x74dc, 0x5250,
+ 0x5be1, 0x6302, 0x8902, 0x4e56, 0x62d0, 0x602a, 0x68fa, 0x5173,
+ 0x5b98, 0x51a0, 0x89c2, 0x7ba1, 0x9986, 0x7f50, 0x60ef, 0x704c,
+ 0x8d2f, 0x5149, 0x5e7f, 0x901b, 0x7470, 0x89c4, 0x572d, 0x7845,
+ 0x5f52, 0x9f9f, 0x95fa, 0x8f68, 0x9b3c, 0x8be1, 0x7678, 0x6842,
+ 0x67dc, 0x8dea, 0x8d35, 0x523d, 0x8f8a, 0x6eda, 0x68cd, 0x9505,
+ 0x90ed, 0x56fd, 0x679c, 0x88f9, 0x8fc7, 0x54c8,
+ /* 0x3a */
+ 0x9ab8, 0x5b69, 0x6d77, 0x6c26, 0x4ea5, 0x5bb3, 0x9a87, 0x9163,
+ 0x61a8, 0x90af, 0x97e9, 0x542b, 0x6db5, 0x5bd2, 0x51fd, 0x558a,
+ 0x7f55, 0x7ff0, 0x64bc, 0x634d, 0x65f1, 0x61be, 0x608d, 0x710a,
+ 0x6c57, 0x6c49, 0x592f, 0x676d, 0x822a, 0x58d5, 0x568e, 0x8c6a,
+ 0x6beb, 0x90dd, 0x597d, 0x8017, 0x53f7, 0x6d69, 0x5475, 0x559d,
+ 0x8377, 0x83cf, 0x6838, 0x79be, 0x548c, 0x4f55, 0x5408, 0x76d2,
+ 0x8c89, 0x9602, 0x6cb3, 0x6db8, 0x8d6b, 0x8910, 0x9e64, 0x8d3a,
+ 0x563f, 0x9ed1, 0x75d5, 0x5f88, 0x72e0, 0x6068, 0x54fc, 0x4ea8,
+ 0x6a2a, 0x8861, 0x6052, 0x8f70, 0x54c4, 0x70d8, 0x8679, 0x9e3f,
+ 0x6d2a, 0x5b8f, 0x5f18, 0x7ea2, 0x5589, 0x4faf, 0x7334, 0x543c,
+ 0x539a, 0x5019, 0x540e, 0x547c, 0x4e4e, 0x5ffd, 0x745a, 0x58f6,
+ 0x846b, 0x80e1, 0x8774, 0x72d0, 0x7cca, 0x6e56,
+ /* 0x3b */
+ 0x5f27, 0x864e, 0x552c, 0x62a4, 0x4e92, 0x6caa, 0x6237, 0x82b1,
+ 0x54d7, 0x534e, 0x733e, 0x6ed1, 0x753b, 0x5212, 0x5316, 0x8bdd,
+ 0x69d0, 0x5f8a, 0x6000, 0x6dee, 0x574f, 0x6b22, 0x73af, 0x6853,
+ 0x8fd8, 0x7f13, 0x6362, 0x60a3, 0x5524, 0x75ea, 0x8c62, 0x7115,
+ 0x6da3, 0x5ba6, 0x5e7b, 0x8352, 0x614c, 0x9ec4, 0x78fa, 0x8757,
+ 0x7c27, 0x7687, 0x51f0, 0x60f6, 0x714c, 0x6643, 0x5e4c, 0x604d,
+ 0x8c0e, 0x7070, 0x6325, 0x8f89, 0x5fbd, 0x6062, 0x86d4, 0x56de,
+ 0x6bc1, 0x6094, 0x6167, 0x5349, 0x60e0, 0x6666, 0x8d3f, 0x79fd,
+ 0x4f1a, 0x70e9, 0x6c47, 0x8bb3, 0x8bf2, 0x7ed8, 0x8364, 0x660f,
+ 0x5a5a, 0x9b42, 0x6d51, 0x6df7, 0x8c41, 0x6d3b, 0x4f19, 0x706b,
+ 0x83b7, 0x6216, 0x60d1, 0x970d, 0x8d27, 0x7978, 0x51fb, 0x573e,
+ 0x57fa, 0x673a, 0x7578, 0x7a3d, 0x79ef, 0x7b95,
+ /* 0x3c */
+ 0x808c, 0x9965, 0x8ff9, 0x6fc0, 0x8ba5, 0x9e21, 0x59ec, 0x7ee9,
+ 0x7f09, 0x5409, 0x6781, 0x68d8, 0x8f91, 0x7c4d, 0x96c6, 0x53ca,
+ 0x6025, 0x75be, 0x6c72, 0x5373, 0x5ac9, 0x7ea7, 0x6324, 0x51e0,
+ 0x810a, 0x5df1, 0x84df, 0x6280, 0x5180, 0x5b63, 0x4f0e, 0x796d,
+ 0x5242, 0x60b8, 0x6d4e, 0x5bc4, 0x5bc2, 0x8ba1, 0x8bb0, 0x65e2,
+ 0x5fcc, 0x9645, 0x5993, 0x7ee7, 0x7eaa, 0x5609, 0x67b7, 0x5939,
+ 0x4f73, 0x5bb6, 0x52a0, 0x835a, 0x988a, 0x8d3e, 0x7532, 0x94be,
+ 0x5047, 0x7a3c, 0x4ef7, 0x67b6, 0x9a7e, 0x5ac1, 0x6b7c, 0x76d1,
+ 0x575a, 0x5c16, 0x7b3a, 0x95f4, 0x714e, 0x517c, 0x80a9, 0x8270,
+ 0x5978, 0x7f04, 0x8327, 0x68c0, 0x67ec, 0x78b1, 0x7877, 0x62e3,
+ 0x6361, 0x7b80, 0x4fed, 0x526a, 0x51cf, 0x8350, 0x69db, 0x9274,
+ 0x8df5, 0x8d31, 0x89c1, 0x952e, 0x7bad, 0x4ef6,
+ /* 0x3d */
+ 0x5065, 0x8230, 0x5251, 0x996f, 0x6e10, 0x6e85, 0x6da7, 0x5efa,
+ 0x50f5, 0x59dc, 0x5c06, 0x6d46, 0x6c5f, 0x7586, 0x848b, 0x6868,
+ 0x5956, 0x8bb2, 0x5320, 0x9171, 0x964d, 0x8549, 0x6912, 0x7901,
+ 0x7126, 0x80f6, 0x4ea4, 0x90ca, 0x6d47, 0x9a84, 0x5a07, 0x56bc,
+ 0x6405, 0x94f0, 0x77eb, 0x4fa5, 0x811a, 0x72e1, 0x89d2, 0x997a,
+ 0x7f34, 0x7ede, 0x527f, 0x6559, 0x9175, 0x8f7f, 0x8f83, 0x53eb,
+ 0x7a96, 0x63ed, 0x63a5, 0x7686, 0x79f8, 0x8857, 0x9636, 0x622a,
+ 0x52ab, 0x8282, 0x6854, 0x6770, 0x6377, 0x776b, 0x7aed, 0x6d01,
+ 0x7ed3, 0x89e3, 0x59d0, 0x6212, 0x85c9, 0x82a5, 0x754c, 0x501f,
+ 0x4ecb, 0x75a5, 0x8beb, 0x5c4a, 0x5dfe, 0x7b4b, 0x65a4, 0x91d1,
+ 0x4eca, 0x6d25, 0x895f, 0x7d27, 0x9526, 0x4ec5, 0x8c28, 0x8fdb,
+ 0x9773, 0x664b, 0x7981, 0x8fd1, 0x70ec, 0x6d78,
+ /* 0x3e */
+ 0x5c3d, 0x52b2, 0x8346, 0x5162, 0x830e, 0x775b, 0x6676, 0x9cb8,
+ 0x4eac, 0x60ca, 0x7cbe, 0x7cb3, 0x7ecf, 0x4e95, 0x8b66, 0x666f,
+ 0x9888, 0x9759, 0x5883, 0x656c, 0x955c, 0x5f84, 0x75c9, 0x9756,
+ 0x7adf, 0x7ade, 0x51c0, 0x70af, 0x7a98, 0x63ea, 0x7a76, 0x7ea0,
+ 0x7396, 0x97ed, 0x4e45, 0x7078, 0x4e5d, 0x9152, 0x53a9, 0x6551,
+ 0x65e7, 0x81fc, 0x8205, 0x548e, 0x5c31, 0x759a, 0x97a0, 0x62d8,
+ 0x72d9, 0x75bd, 0x5c45, 0x9a79, 0x83ca, 0x5c40, 0x5480, 0x77e9,
+ 0x4e3e, 0x6cae, 0x805a, 0x62d2, 0x636e, 0x5de8, 0x5177, 0x8ddd,
+ 0x8e1e, 0x952f, 0x4ff1, 0x53e5, 0x60e7, 0x70ac, 0x5267, 0x6350,
+ 0x9e43, 0x5a1f, 0x5026, 0x7737, 0x5377, 0x7ee2, 0x6485, 0x652b,
+ 0x6289, 0x6398, 0x5014, 0x7235, 0x89c9, 0x51b3, 0x8bc0, 0x7edd,
+ 0x5747, 0x83cc, 0x94a7, 0x519b, 0x541b, 0x5cfb,
+ /* 0x3f */
+ 0x4fca, 0x7ae3, 0x6d5a, 0x90e1, 0x9a8f, 0x5580, 0x5496, 0x5361,
+ 0x54af, 0x5f00, 0x63e9, 0x6977, 0x51ef, 0x6168, 0x520a, 0x582a,
+ 0x52d8, 0x574e, 0x780d, 0x770b, 0x5eb7, 0x6177, 0x7ce0, 0x625b,
+ 0x6297, 0x4ea2, 0x7095, 0x8003, 0x62f7, 0x70e4, 0x9760, 0x5777,
+ 0x82db, 0x67ef, 0x68f5, 0x78d5, 0x9897, 0x79d1, 0x58f3, 0x54b3,
+ 0x53ef, 0x6e34, 0x514b, 0x523b, 0x5ba2, 0x8bfe, 0x80af, 0x5543,
+ 0x57a6, 0x6073, 0x5751, 0x542d, 0x7a7a, 0x6050, 0x5b54, 0x63a7,
+ 0x62a0, 0x53e3, 0x6263, 0x5bc7, 0x67af, 0x54ed, 0x7a9f, 0x82e6,
+ 0x9177, 0x5e93, 0x88e4, 0x5938, 0x57ae, 0x630e, 0x8de8, 0x80ef,
+ 0x5757, 0x7b77, 0x4fa9, 0x5feb, 0x5bbd, 0x6b3e, 0x5321, 0x7b50,
+ 0x72c2, 0x6846, 0x77ff, 0x7736, 0x65f7, 0x51b5, 0x4e8f, 0x76d4,
+ 0x5cbf, 0x7aa5, 0x8475, 0x594e, 0x9b41, 0x5080,
+ /* 0x40 */
+ 0x9988, 0x6127, 0x6e83, 0x5764, 0x6606, 0x6346, 0x56f0, 0x62ec,
+ 0x6269, 0x5ed3, 0x9614, 0x5783, 0x62c9, 0x5587, 0x8721, 0x814a,
+ 0x8fa3, 0x5566, 0x83b1, 0x6765, 0x8d56, 0x84dd, 0x5a6a, 0x680f,
+ 0x62e6, 0x7bee, 0x9611, 0x5170, 0x6f9c, 0x8c30, 0x63fd, 0x89c8,
+ 0x61d2, 0x7f06, 0x70c2, 0x6ee5, 0x7405, 0x6994, 0x72fc, 0x5eca,
+ 0x90ce, 0x6717, 0x6d6a, 0x635e, 0x52b3, 0x7262, 0x8001, 0x4f6c,
+ 0x59e5, 0x916a, 0x70d9, 0x6d9d, 0x52d2, 0x4e50, 0x96f7, 0x956d,
+ 0x857e, 0x78ca, 0x7d2f, 0x5121, 0x5792, 0x64c2, 0x808b, 0x7c7b,
+ 0x6cea, 0x68f1, 0x695e, 0x51b7, 0x5398, 0x68a8, 0x7281, 0x9ece,
+ 0x7bf1, 0x72f8, 0x79bb, 0x6f13, 0x7406, 0x674e, 0x91cc, 0x9ca4,
+ 0x793c, 0x8389, 0x8354, 0x540f, 0x6817, 0x4e3d, 0x5389, 0x52b1,
+ 0x783e, 0x5386, 0x5229, 0x5088, 0x4f8b, 0x4fd0,
+ /* 0x41 */
+ 0x75e2, 0x7acb, 0x7c92, 0x6ca5, 0x96b6, 0x529b, 0x7483, 0x54e9,
+ 0x4fe9, 0x8054, 0x83b2, 0x8fde, 0x9570, 0x5ec9, 0x601c, 0x6d9f,
+ 0x5e18, 0x655b, 0x8138, 0x94fe, 0x604b, 0x70bc, 0x7ec3, 0x7cae,
+ 0x51c9, 0x6881, 0x7cb1, 0x826f, 0x4e24, 0x8f86, 0x91cf, 0x667e,
+ 0x4eae, 0x8c05, 0x64a9, 0x804a, 0x50da, 0x7597, 0x71ce, 0x5be5,
+ 0x8fbd, 0x6f66, 0x4e86, 0x6482, 0x9563, 0x5ed6, 0x6599, 0x5217,
+ 0x88c2, 0x70c8, 0x52a3, 0x730e, 0x7433, 0x6797, 0x78f7, 0x9716,
+ 0x4e34, 0x90bb, 0x9cde, 0x6dcb, 0x51db, 0x8d41, 0x541d, 0x62ce,
+ 0x73b2, 0x83f1, 0x96f6, 0x9f84, 0x94c3, 0x4f36, 0x7f9a, 0x51cc,
+ 0x7075, 0x9675, 0x5cad, 0x9886, 0x53e6, 0x4ee4, 0x6e9c, 0x7409,
+ 0x69b4, 0x786b, 0x998f, 0x7559, 0x5218, 0x7624, 0x6d41, 0x67f3,
+ 0x516d, 0x9f99, 0x804b, 0x5499, 0x7b3c, 0x7abf,
+ /* 0x42 */
+ 0x9686, 0x5784, 0x62e2, 0x9647, 0x697c, 0x5a04, 0x6402, 0x7bd3,
+ 0x6f0f, 0x964b, 0x82a6, 0x5362, 0x9885, 0x5e90, 0x7089, 0x63b3,
+ 0x5364, 0x864f, 0x9c81, 0x9e93, 0x788c, 0x9732, 0x8def, 0x8d42,
+ 0x9e7f, 0x6f5e, 0x7984, 0x5f55, 0x9646, 0x622e, 0x9a74, 0x5415,
+ 0x94dd, 0x4fa3, 0x65c5, 0x5c65, 0x5c61, 0x7f15, 0x8651, 0x6c2f,
+ 0x5f8b, 0x7387, 0x6ee4, 0x7eff, 0x5ce6, 0x631b, 0x5b6a, 0x6ee6,
+ 0x5375, 0x4e71, 0x63a0, 0x7565, 0x62a1, 0x8f6e, 0x4f26, 0x4ed1,
+ 0x6ca6, 0x7eb6, 0x8bba, 0x841d, 0x87ba, 0x7f57, 0x903b, 0x9523,
+ 0x7ba9, 0x9aa1, 0x88f8, 0x843d, 0x6d1b, 0x9a86, 0x7edc, 0x5988,
+ 0x9ebb, 0x739b, 0x7801, 0x8682, 0x9a6c, 0x9a82, 0x561b, 0x5417,
+ 0x57cb, 0x4e70, 0x9ea6, 0x5356, 0x8fc8, 0x8109, 0x7792, 0x9992,
+ 0x86ee, 0x6ee1, 0x8513, 0x66fc, 0x6162, 0x6f2b,
+ /* 0x43 */
+ 0x8c29, 0x8292, 0x832b, 0x76f2, 0x6c13, 0x5fd9, 0x83bd, 0x732b,
+ 0x8305, 0x951a, 0x6bdb, 0x77db, 0x94c6, 0x536f, 0x8302, 0x5192,
+ 0x5e3d, 0x8c8c, 0x8d38, 0x4e48, 0x73ab, 0x679a, 0x6885, 0x9176,
+ 0x9709, 0x7164, 0x6ca1, 0x7709, 0x5a92, 0x9541, 0x6bcf, 0x7f8e,
+ 0x6627, 0x5bd0, 0x59b9, 0x5a9a, 0x95e8, 0x95f7, 0x4eec, 0x840c,
+ 0x8499, 0x6aac, 0x76df, 0x9530, 0x731b, 0x68a6, 0x5b5f, 0x772f,
+ 0x919a, 0x9761, 0x7cdc, 0x8ff7, 0x8c1c, 0x5f25, 0x7c73, 0x79d8,
+ 0x89c5, 0x6ccc, 0x871c, 0x5bc6, 0x5e42, 0x68c9, 0x7720, 0x7ef5,
+ 0x5195, 0x514d, 0x52c9, 0x5a29, 0x7f05, 0x9762, 0x82d7, 0x63cf,
+ 0x7784, 0x85d0, 0x79d2, 0x6e3a, 0x5e99, 0x5999, 0x8511, 0x706d,
+ 0x6c11, 0x62bf, 0x76bf, 0x654f, 0x60af, 0x95fd, 0x660e, 0x879f,
+ 0x9e23, 0x94ed, 0x540d, 0x547d, 0x8c2c, 0x6478,
+ /* 0x44 */
+ 0x6479, 0x8611, 0x6a21, 0x819c, 0x78e8, 0x6469, 0x9b54, 0x62b9,
+ 0x672b, 0x83ab, 0x58a8, 0x9ed8, 0x6cab, 0x6f20, 0x5bde, 0x964c,
+ 0x8c0b, 0x725f, 0x67d0, 0x62c7, 0x7261, 0x4ea9, 0x59c6, 0x6bcd,
+ 0x5893, 0x66ae, 0x5e55, 0x52df, 0x6155, 0x6728, 0x76ee, 0x7766,
+ 0x7267, 0x7a46, 0x62ff, 0x54ea, 0x5450, 0x94a0, 0x90a3, 0x5a1c,
+ 0x7eb3, 0x6c16, 0x4e43, 0x5976, 0x8010, 0x5948, 0x5357, 0x7537,
+ 0x96be, 0x56ca, 0x6320, 0x8111, 0x607c, 0x95f9, 0x6dd6, 0x5462,
+ 0x9981, 0x5185, 0x5ae9, 0x80fd, 0x59ae, 0x9713, 0x502a, 0x6ce5,
+ 0x5c3c, 0x62df, 0x4f60, 0x533f, 0x817b, 0x9006, 0x6eba, 0x852b,
+ 0x62c8, 0x5e74, 0x78be, 0x64b5, 0x637b, 0x5ff5, 0x5a18, 0x917f,
+ 0x9e1f, 0x5c3f, 0x634f, 0x8042, 0x5b7d, 0x556e, 0x954a, 0x954d,
+ 0x6d85, 0x60a8, 0x67e0, 0x72de, 0x51dd, 0x5b81,
+ /* 0x45 */
+ 0x62e7, 0x6cde, 0x725b, 0x626d, 0x94ae, 0x7ebd, 0x8113, 0x6d53,
+ 0x519c, 0x5f04, 0x5974, 0x52aa, 0x6012, 0x5973, 0x6696, 0x8650,
+ 0x759f, 0x632a, 0x61e6, 0x7cef, 0x8bfa, 0x54e6, 0x6b27, 0x9e25,
+ 0x6bb4, 0x85d5, 0x5455, 0x5076, 0x6ca4, 0x556a, 0x8db4, 0x722c,
+ 0x5e15, 0x6015, 0x7436, 0x62cd, 0x6392, 0x724c, 0x5f98, 0x6e43,
+ 0x6d3e, 0x6500, 0x6f58, 0x76d8, 0x78d0, 0x76fc, 0x7554, 0x5224,
+ 0x53db, 0x4e53, 0x5e9e, 0x65c1, 0x802a, 0x80d6, 0x629b, 0x5486,
+ 0x5228, 0x70ae, 0x888d, 0x8dd1, 0x6ce1, 0x5478, 0x80da, 0x57f9,
+ 0x88f4, 0x8d54, 0x966a, 0x914d, 0x4f69, 0x6c9b, 0x55b7, 0x76c6,
+ 0x7830, 0x62a8, 0x70f9, 0x6f8e, 0x5f6d, 0x84ec, 0x68da, 0x787c,
+ 0x7bf7, 0x81a8, 0x670b, 0x9e4f, 0x6367, 0x78b0, 0x576f, 0x7812,
+ 0x9739, 0x6279, 0x62ab, 0x5288, 0x7435, 0x6bd7,
+ /* 0x46 */
+ 0x5564, 0x813e, 0x75b2, 0x76ae, 0x5339, 0x75de, 0x50fb, 0x5c41,
+ 0x8b6c, 0x7bc7, 0x504f, 0x7247, 0x9a97, 0x98d8, 0x6f02, 0x74e2,
+ 0x7968, 0x6487, 0x77a5, 0x62fc, 0x9891, 0x8d2b, 0x54c1, 0x8058,
+ 0x4e52, 0x576a, 0x82f9, 0x840d, 0x5e73, 0x51ed, 0x74f6, 0x8bc4,
+ 0x5c4f, 0x5761, 0x6cfc, 0x9887, 0x5a46, 0x7834, 0x9b44, 0x8feb,
+ 0x7c95, 0x5256, 0x6251, 0x94fa, 0x4ec6, 0x8386, 0x8461, 0x83e9,
+ 0x84b2, 0x57d4, 0x6734, 0x5703, 0x666e, 0x6d66, 0x8c31, 0x66dd,
+ 0x7011, 0x671f, 0x6b3a, 0x6816, 0x621a, 0x59bb, 0x4e03, 0x51c4,
+ 0x6f06, 0x67d2, 0x6c8f, 0x5176, 0x68cb, 0x5947, 0x6b67, 0x7566,
+ 0x5d0e, 0x8110, 0x9f50, 0x65d7, 0x7948, 0x7941, 0x9a91, 0x8d77,
+ 0x5c82, 0x4e5e, 0x4f01, 0x542f, 0x5951, 0x780c, 0x5668, 0x6c14,
+ 0x8fc4, 0x5f03, 0x6c7d, 0x6ce3, 0x8bab, 0x6390,
+ /* 0x47 */
+ 0x6070, 0x6d3d, 0x7275, 0x6266, 0x948e, 0x94c5, 0x5343, 0x8fc1,
+ 0x7b7e, 0x4edf, 0x8c26, 0x4e7e, 0x9ed4, 0x94b1, 0x94b3, 0x524d,
+ 0x6f5c, 0x9063, 0x6d45, 0x8c34, 0x5811, 0x5d4c, 0x6b20, 0x6b49,
+ 0x67aa, 0x545b, 0x8154, 0x7f8c, 0x5899, 0x8537, 0x5f3a, 0x62a2,
+ 0x6a47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77a7, 0x4e54, 0x4fa8,
+ 0x5de7, 0x9798, 0x64ac, 0x7fd8, 0x5ced, 0x4fcf, 0x7a8d, 0x5207,
+ 0x8304, 0x4e14, 0x602f, 0x7a83, 0x94a6, 0x4fb5, 0x4eb2, 0x79e6,
+ 0x7434, 0x52e4, 0x82b9, 0x64d2, 0x79bd, 0x5bdd, 0x6c81, 0x9752,
+ 0x8f7b, 0x6c22, 0x503e, 0x537f, 0x6e05, 0x64ce, 0x6674, 0x6c30,
+ 0x60c5, 0x9877, 0x8bf7, 0x5e86, 0x743c, 0x7a77, 0x79cb, 0x4e18,
+ 0x90b1, 0x7403, 0x6c42, 0x56da, 0x914b, 0x6cc5, 0x8d8b, 0x533a,
+ 0x86c6, 0x66f2, 0x8eaf, 0x5c48, 0x9a71, 0x6e20,
+ /* 0x48 */
+ 0x53d6, 0x5a36, 0x9f8b, 0x8da3, 0x53bb, 0x5708, 0x98a7, 0x6743,
+ 0x919b, 0x6cc9, 0x5168, 0x75ca, 0x62f3, 0x72ac, 0x5238, 0x529d,
+ 0x7f3a, 0x7094, 0x7638, 0x5374, 0x9e4a, 0x69b7, 0x786e, 0x96c0,
+ 0x88d9, 0x7fa4, 0x7136, 0x71c3, 0x5189, 0x67d3, 0x74e4, 0x58e4,
+ 0x6518, 0x56b7, 0x8ba9, 0x9976, 0x6270, 0x7ed5, 0x60f9, 0x70ed,
+ 0x58ec, 0x4ec1, 0x4eba, 0x5fcd, 0x97e7, 0x4efb, 0x8ba4, 0x5203,
+ 0x598a, 0x7eab, 0x6254, 0x4ecd, 0x65e5, 0x620e, 0x8338, 0x84c9,
+ 0x8363, 0x878d, 0x7194, 0x6eb6, 0x5bb9, 0x7ed2, 0x5197, 0x63c9,
+ 0x67d4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5b7a, 0x5982, 0x8fb1,
+ 0x4e73, 0x6c5d, 0x5165, 0x8925, 0x8f6f, 0x962e, 0x854a, 0x745e,
+ 0x9510, 0x95f0, 0x6da6, 0x82e5, 0x5f31, 0x6492, 0x6d12, 0x8428,
+ 0x816e, 0x9cc3, 0x585e, 0x8d5b, 0x4e09, 0x53c1,
+ /* 0x49 */
+ 0x4f1e, 0x6563, 0x6851, 0x55d3, 0x4e27, 0x6414, 0x9a9a, 0x626b,
+ 0x5ac2, 0x745f, 0x8272, 0x6da9, 0x68ee, 0x50e7, 0x838e, 0x7802,
+ 0x6740, 0x5239, 0x6c99, 0x7eb1, 0x50bb, 0x5565, 0x715e, 0x7b5b,
+ 0x6652, 0x73ca, 0x82eb, 0x6749, 0x5c71, 0x5220, 0x717d, 0x886b,
+ 0x95ea, 0x9655, 0x64c5, 0x8d61, 0x81b3, 0x5584, 0x6c55, 0x6247,
+ 0x7f2e, 0x5892, 0x4f24, 0x5546, 0x8d4f, 0x664c, 0x4e0a, 0x5c1a,
+ 0x88f3, 0x68a2, 0x634e, 0x7a0d, 0x70e7, 0x828d, 0x52fa, 0x97f6,
+ 0x5c11, 0x54e8, 0x90b5, 0x7ecd, 0x5962, 0x8d4a, 0x86c7, 0x820c,
+ 0x820d, 0x8d66, 0x6444, 0x5c04, 0x6151, 0x6d89, 0x793e, 0x8bbe,
+ 0x7837, 0x7533, 0x547b, 0x4f38, 0x8eab, 0x6df1, 0x5a20, 0x7ec5,
+ 0x795e, 0x6c88, 0x5ba1, 0x5a76, 0x751a, 0x80be, 0x614e, 0x6e17,
+ 0x58f0, 0x751f, 0x7525, 0x7272, 0x5347, 0x7ef3,
+ /* 0x4a */
+ 0x7701, 0x76db, 0x5269, 0x80dc, 0x5723, 0x5e08, 0x5931, 0x72ee,
+ 0x65bd, 0x6e7f, 0x8bd7, 0x5c38, 0x8671, 0x5341, 0x77f3, 0x62fe,
+ 0x65f6, 0x4ec0, 0x98df, 0x8680, 0x5b9e, 0x8bc6, 0x53f2, 0x77e2,
+ 0x4f7f, 0x5c4e, 0x9a76, 0x59cb, 0x5f0f, 0x793a, 0x58eb, 0x4e16,
+ 0x67ff, 0x4e8b, 0x62ed, 0x8a93, 0x901d, 0x52bf, 0x662f, 0x55dc,
+ 0x566c, 0x9002, 0x4ed5, 0x4f8d, 0x91ca, 0x9970, 0x6c0f, 0x5e02,
+ 0x6043, 0x5ba4, 0x89c6, 0x8bd5, 0x6536, 0x624b, 0x9996, 0x5b88,
+ 0x5bff, 0x6388, 0x552e, 0x53d7, 0x7626, 0x517d, 0x852c, 0x67a2,
+ 0x68b3, 0x6b8a, 0x6292, 0x8f93, 0x53d4, 0x8212, 0x6dd1, 0x758f,
+ 0x4e66, 0x8d4e, 0x5b70, 0x719f, 0x85af, 0x6691, 0x66d9, 0x7f72,
+ 0x8700, 0x9ecd, 0x9f20, 0x5c5e, 0x672f, 0x8ff0, 0x6811, 0x675f,
+ 0x620d, 0x7ad6, 0x5885, 0x5eb6, 0x6570, 0x6f31,
+ /* 0x4b */
+ 0x6055, 0x5237, 0x800d, 0x6454, 0x8870, 0x7529, 0x5e05, 0x6813,
+ 0x62f4, 0x971c, 0x53cc, 0x723d, 0x8c01, 0x6c34, 0x7761, 0x7a0e,
+ 0x542e, 0x77ac, 0x987a, 0x821c, 0x8bf4, 0x7855, 0x6714, 0x70c1,
+ 0x65af, 0x6495, 0x5636, 0x601d, 0x79c1, 0x53f8, 0x4e1d, 0x6b7b,
+ 0x8086, 0x5bfa, 0x55e3, 0x56db, 0x4f3a, 0x4f3c, 0x9972, 0x5df3,
+ 0x677e, 0x8038, 0x6002, 0x9882, 0x9001, 0x5b8b, 0x8bbc, 0x8bf5,
+ 0x641c, 0x8258, 0x64de, 0x55fd, 0x82cf, 0x9165, 0x4fd7, 0x7d20,
+ 0x901f, 0x7c9f, 0x50f3, 0x5851, 0x6eaf, 0x5bbf, 0x8bc9, 0x8083,
+ 0x9178, 0x849c, 0x7b97, 0x867d, 0x968b, 0x968f, 0x7ee5, 0x9ad3,
+ 0x788e, 0x5c81, 0x7a57, 0x9042, 0x96a7, 0x795f, 0x5b59, 0x635f,
+ 0x7b0b, 0x84d1, 0x68ad, 0x5506, 0x7f29, 0x7410, 0x7d22, 0x9501,
+ 0x6240, 0x584c, 0x4ed6, 0x5b83, 0x5979, 0x5854,
+ /* 0x4c */
+ 0x736d, 0x631e, 0x8e4b, 0x8e0f, 0x80ce, 0x82d4, 0x62ac, 0x53f0,
+ 0x6cf0, 0x915e, 0x592a, 0x6001, 0x6c70, 0x574d, 0x644a, 0x8d2a,
+ 0x762b, 0x6ee9, 0x575b, 0x6a80, 0x75f0, 0x6f6d, 0x8c2d, 0x8c08,
+ 0x5766, 0x6bef, 0x8892, 0x78b3, 0x63a2, 0x53f9, 0x70ad, 0x6c64,
+ 0x5858, 0x642a, 0x5802, 0x68e0, 0x819b, 0x5510, 0x7cd6, 0x5018,
+ 0x8eba, 0x6dcc, 0x8d9f, 0x70eb, 0x638f, 0x6d9b, 0x6ed4, 0x7ee6,
+ 0x8404, 0x6843, 0x9003, 0x6dd8, 0x9676, 0x8ba8, 0x5957, 0x7279,
+ 0x85e4, 0x817e, 0x75bc, 0x8a8a, 0x68af, 0x5254, 0x8e22, 0x9511,
+ 0x63d0, 0x9898, 0x8e44, 0x557c, 0x4f53, 0x66ff, 0x568f, 0x60d5,
+ 0x6d95, 0x5243, 0x5c49, 0x5929, 0x6dfb, 0x586b, 0x7530, 0x751c,
+ 0x606c, 0x8214, 0x8146, 0x6311, 0x6761, 0x8fe2, 0x773a, 0x8df3,
+ 0x8d34, 0x94c1, 0x5e16, 0x5385, 0x542c, 0x70c3,
+ /* 0x4d */
+ 0x6c40, 0x5ef7, 0x505c, 0x4ead, 0x5ead, 0x633a, 0x8247, 0x901a,
+ 0x6850, 0x916e, 0x77b3, 0x540c, 0x94dc, 0x5f64, 0x7ae5, 0x6876,
+ 0x6345, 0x7b52, 0x7edf, 0x75db, 0x5077, 0x6295, 0x5934, 0x900f,
+ 0x51f8, 0x79c3, 0x7a81, 0x56fe, 0x5f92, 0x9014, 0x6d82, 0x5c60,
+ 0x571f, 0x5410, 0x5154, 0x6e4d, 0x56e2, 0x63a8, 0x9893, 0x817f,
+ 0x8715, 0x892a, 0x9000, 0x541e, 0x5c6f, 0x81c0, 0x62d6, 0x6258,
+ 0x8131, 0x9e35, 0x9640, 0x9a6e, 0x9a7c, 0x692d, 0x59a5, 0x62d3,
+ 0x553e, 0x6316, 0x54c7, 0x86d9, 0x6d3c, 0x5a03, 0x74e6, 0x889c,
+ 0x6b6a, 0x5916, 0x8c4c, 0x5f2f, 0x6e7e, 0x73a9, 0x987d, 0x4e38,
+ 0x70f7, 0x5b8c, 0x7897, 0x633d, 0x665a, 0x7696, 0x60cb, 0x5b9b,
+ 0x5a49, 0x4e07, 0x8155, 0x6c6a, 0x738b, 0x4ea1, 0x6789, 0x7f51,
+ 0x5f80, 0x65fa, 0x671b, 0x5fd8, 0x5984, 0x5a01,
+ /* 0x4e */
+ 0x5dcd, 0x5fae, 0x5371, 0x97e6, 0x8fdd, 0x6845, 0x56f4, 0x552f,
+ 0x60df, 0x4e3a, 0x6f4d, 0x7ef4, 0x82c7, 0x840e, 0x59d4, 0x4f1f,
+ 0x4f2a, 0x5c3e, 0x7eac, 0x672a, 0x851a, 0x5473, 0x754f, 0x80c3,
+ 0x5582, 0x9b4f, 0x4f4d, 0x6e2d, 0x8c13, 0x5c09, 0x6170, 0x536b,
+ 0x761f, 0x6e29, 0x868a, 0x6587, 0x95fb, 0x7eb9, 0x543b, 0x7a33,
+ 0x7d0a, 0x95ee, 0x55e1, 0x7fc1, 0x74ee, 0x631d, 0x8717, 0x6da1,
+ 0x7a9d, 0x6211, 0x65a1, 0x5367, 0x63e1, 0x6c83, 0x5deb, 0x545c,
+ 0x94a8, 0x4e4c, 0x6c61, 0x8bec, 0x5c4b, 0x65e0, 0x829c, 0x68a7,
+ 0x543e, 0x5434, 0x6bcb, 0x6b66, 0x4e94, 0x6342, 0x5348, 0x821e,
+ 0x4f0d, 0x4fae, 0x575e, 0x620a, 0x96fe, 0x6664, 0x7269, 0x52ff,
+ 0x52a1, 0x609f, 0x8bef, 0x6614, 0x7199, 0x6790, 0x897f, 0x7852,
+ 0x77fd, 0x6670, 0x563b, 0x5438, 0x9521, 0x727a,
+ /* 0x4f */
+ 0x7a00, 0x606f, 0x5e0c, 0x6089, 0x819d, 0x5915, 0x60dc, 0x7184,
+ 0x70ef, 0x6eaa, 0x6c50, 0x7280, 0x6a84, 0x88ad, 0x5e2d, 0x4e60,
+ 0x5ab3, 0x559c, 0x94e3, 0x6d17, 0x7cfb, 0x9699, 0x620f, 0x7ec6,
+ 0x778e, 0x867e, 0x5323, 0x971e, 0x8f96, 0x6687, 0x5ce1, 0x4fa0,
+ 0x72ed, 0x4e0b, 0x53a6, 0x590f, 0x5413, 0x6380, 0x9528, 0x5148,
+ 0x4ed9, 0x9c9c, 0x7ea4, 0x54b8, 0x8d24, 0x8854, 0x8237, 0x95f2,
+ 0x6d8e, 0x5f26, 0x5acc, 0x663e, 0x9669, 0x73b0, 0x732e, 0x53bf,
+ 0x817a, 0x9985, 0x7fa1, 0x5baa, 0x9677, 0x9650, 0x7ebf, 0x76f8,
+ 0x53a2, 0x9576, 0x9999, 0x7bb1, 0x8944, 0x6e58, 0x4e61, 0x7fd4,
+ 0x7965, 0x8be6, 0x60f3, 0x54cd, 0x4eab, 0x9879, 0x5df7, 0x6a61,
+ 0x50cf, 0x5411, 0x8c61, 0x8427, 0x785d, 0x9704, 0x524a, 0x54ee,
+ 0x56a3, 0x9500, 0x6d88, 0x5bb5, 0x6dc6, 0x6653,
+ /* 0x50 */
+ 0x5c0f, 0x5b5d, 0x6821, 0x8096, 0x5578, 0x7b11, 0x6548, 0x6954,
+ 0x4e9b, 0x6b47, 0x874e, 0x978b, 0x534f, 0x631f, 0x643a, 0x90aa,
+ 0x659c, 0x80c1, 0x8c10, 0x5199, 0x68b0, 0x5378, 0x87f9, 0x61c8,
+ 0x6cc4, 0x6cfb, 0x8c22, 0x5c51, 0x85aa, 0x82af, 0x950c, 0x6b23,
+ 0x8f9b, 0x65b0, 0x5ffb, 0x5fc3, 0x4fe1, 0x8845, 0x661f, 0x8165,
+ 0x7329, 0x60fa, 0x5174, 0x5211, 0x578b, 0x5f62, 0x90a2, 0x884c,
+ 0x9192, 0x5e78, 0x674f, 0x6027, 0x59d3, 0x5144, 0x51f6, 0x80f8,
+ 0x5308, 0x6c79, 0x96c4, 0x718a, 0x4f11, 0x4fee, 0x7f9e, 0x673d,
+ 0x55c5, 0x9508, 0x79c0, 0x8896, 0x7ee3, 0x589f, 0x620c, 0x9700,
+ 0x865a, 0x5618, 0x987b, 0x5f90, 0x8bb8, 0x84c4, 0x9157, 0x53d9,
+ 0x65ed, 0x5e8f, 0x755c, 0x6064, 0x7d6e, 0x5a7f, 0x7eea, 0x7eed,
+ 0x8f69, 0x55a7, 0x5ba3, 0x60ac, 0x65cb, 0x7384,
+ /* 0x51 */
+ 0x9009, 0x7663, 0x7729, 0x7eda, 0x9774, 0x859b, 0x5b66, 0x7a74,
+ 0x96ea, 0x8840, 0x52cb, 0x718f, 0x5faa, 0x65ec, 0x8be2, 0x5bfb,
+ 0x9a6f, 0x5de1, 0x6b89, 0x6c5b, 0x8bad, 0x8baf, 0x900a, 0x8fc5,
+ 0x538b, 0x62bc, 0x9e26, 0x9e2d, 0x5440, 0x4e2b, 0x82bd, 0x7259,
+ 0x869c, 0x5d16, 0x8859, 0x6daf, 0x96c5, 0x54d1, 0x4e9a, 0x8bb6,
+ 0x7109, 0x54bd, 0x9609, 0x70df, 0x6df9, 0x76d0, 0x4e25, 0x7814,
+ 0x8712, 0x5ca9, 0x5ef6, 0x8a00, 0x989c, 0x960e, 0x708e, 0x6cbf,
+ 0x5944, 0x63a9, 0x773c, 0x884d, 0x6f14, 0x8273, 0x5830, 0x71d5,
+ 0x538c, 0x781a, 0x96c1, 0x5501, 0x5f66, 0x7130, 0x5bb4, 0x8c1a,
+ 0x9a8c, 0x6b83, 0x592e, 0x9e2f, 0x79e7, 0x6768, 0x626c, 0x4f6f,
+ 0x75a1, 0x7f8a, 0x6d0b, 0x9633, 0x6c27, 0x4ef0, 0x75d2, 0x517b,
+ 0x6837, 0x6f3e, 0x9080, 0x8170, 0x5996, 0x7476,
+ /* 0x52 */
+ 0x6447, 0x5c27, 0x9065, 0x7a91, 0x8c23, 0x59da, 0x54ac, 0x8200,
+ 0x836f, 0x8981, 0x8000, 0x6930, 0x564e, 0x8036, 0x7237, 0x91ce,
+ 0x51b6, 0x4e5f, 0x9875, 0x6396, 0x4e1a, 0x53f6, 0x66f3, 0x814b,
+ 0x591c, 0x6db2, 0x4e00, 0x58f9, 0x533b, 0x63d6, 0x94f1, 0x4f9d,
+ 0x4f0a, 0x8863, 0x9890, 0x5937, 0x9057, 0x79fb, 0x4eea, 0x80f0,
+ 0x7591, 0x6c82, 0x5b9c, 0x59e8, 0x5f5d, 0x6905, 0x8681, 0x501a,
+ 0x5df2, 0x4e59, 0x77e3, 0x4ee5, 0x827a, 0x6291, 0x6613, 0x9091,
+ 0x5c79, 0x4ebf, 0x5f79, 0x81c6, 0x9038, 0x8084, 0x75ab, 0x4ea6,
+ 0x88d4, 0x610f, 0x6bc5, 0x5fc6, 0x4e49, 0x76ca, 0x6ea2, 0x8be3,
+ 0x8bae, 0x8c0a, 0x8bd1, 0x5f02, 0x7ffc, 0x7fcc, 0x7ece, 0x8335,
+ 0x836b, 0x56e0, 0x6bb7, 0x97f3, 0x9634, 0x59fb, 0x541f, 0x94f6,
+ 0x6deb, 0x5bc5, 0x996e, 0x5c39, 0x5f15, 0x9690,
+ /* 0x53 */
+ 0x5370, 0x82f1, 0x6a31, 0x5a74, 0x9e70, 0x5e94, 0x7f28, 0x83b9,
+ 0x8424, 0x8425, 0x8367, 0x8747, 0x8fce, 0x8d62, 0x76c8, 0x5f71,
+ 0x9896, 0x786c, 0x6620, 0x54df, 0x62e5, 0x4f63, 0x81c3, 0x75c8,
+ 0x5eb8, 0x96cd, 0x8e0a, 0x86f9, 0x548f, 0x6cf3, 0x6d8c, 0x6c38,
+ 0x607f, 0x52c7, 0x7528, 0x5e7d, 0x4f18, 0x60a0, 0x5fe7, 0x5c24,
+ 0x7531, 0x90ae, 0x94c0, 0x72b9, 0x6cb9, 0x6e38, 0x9149, 0x6709,
+ 0x53cb, 0x53f3, 0x4f51, 0x91c9, 0x8bf1, 0x53c8, 0x5e7c, 0x8fc2,
+ 0x6de4, 0x4e8e, 0x76c2, 0x6986, 0x865e, 0x611a, 0x8206, 0x4f59,
+ 0x4fde, 0x903e, 0x9c7c, 0x6109, 0x6e1d, 0x6e14, 0x9685, 0x4e88,
+ 0x5a31, 0x96e8, 0x4e0e, 0x5c7f, 0x79b9, 0x5b87, 0x8bed, 0x7fbd,
+ 0x7389, 0x57df, 0x828b, 0x90c1, 0x5401, 0x9047, 0x55bb, 0x5cea,
+ 0x5fa1, 0x6108, 0x6b32, 0x72f1, 0x80b2, 0x8a89,
+ /* 0x54 */
+ 0x6d74, 0x5bd3, 0x88d5, 0x9884, 0x8c6b, 0x9a6d, 0x9e33, 0x6e0a,
+ 0x51a4, 0x5143, 0x57a3, 0x8881, 0x539f, 0x63f4, 0x8f95, 0x56ed,
+ 0x5458, 0x5706, 0x733f, 0x6e90, 0x7f18, 0x8fdc, 0x82d1, 0x613f,
+ 0x6028, 0x9662, 0x66f0, 0x7ea6, 0x8d8a, 0x8dc3, 0x94a5, 0x5cb3,
+ 0x7ca4, 0x6708, 0x60a6, 0x9605, 0x8018, 0x4e91, 0x90e7, 0x5300,
+ 0x9668, 0x5141, 0x8fd0, 0x8574, 0x915d, 0x6655, 0x97f5, 0x5b55,
+ 0x531d, 0x7838, 0x6742, 0x683d, 0x54c9, 0x707e, 0x5bb0, 0x8f7d,
+ 0x518d, 0x5728, 0x54b1, 0x6512, 0x6682, 0x8d5e, 0x8d43, 0x810f,
+ 0x846c, 0x906d, 0x7cdf, 0x51ff, 0x85fb, 0x67a3, 0x65e9, 0x6fa1,
+ 0x86a4, 0x8e81, 0x566a, 0x9020, 0x7682, 0x7076, 0x71e5, 0x8d23,
+ 0x62e9, 0x5219, 0x6cfd, 0x8d3c, 0x600e, 0x589e, 0x618e, 0x66fe,
+ 0x8d60, 0x624e, 0x55b3, 0x6e23, 0x672d, 0x8f67,
+ /* 0x55 */
+ 0x94e1, 0x95f8, 0x7728, 0x6805, 0x69a8, 0x548b, 0x4e4d, 0x70b8,
+ 0x8bc8, 0x6458, 0x658b, 0x5b85, 0x7a84, 0x503a, 0x5be8, 0x77bb,
+ 0x6be1, 0x8a79, 0x7c98, 0x6cbe, 0x76cf, 0x65a9, 0x8f97, 0x5d2d,
+ 0x5c55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7ad9, 0x6e5b, 0x7efd,
+ 0x6a1f, 0x7ae0, 0x5f70, 0x6f33, 0x5f20, 0x638c, 0x6da8, 0x6756,
+ 0x4e08, 0x5e10, 0x8d26, 0x4ed7, 0x80c0, 0x7634, 0x969c, 0x62db,
+ 0x662d, 0x627e, 0x6cbc, 0x8d75, 0x7167, 0x7f69, 0x5146, 0x8087,
+ 0x53ec, 0x906e, 0x6298, 0x54f2, 0x86f0, 0x8f99, 0x8005, 0x9517,
+ 0x8517, 0x8fd9, 0x6d59, 0x73cd, 0x659f, 0x771f, 0x7504, 0x7827,
+ 0x81fb, 0x8d1e, 0x9488, 0x4fa6, 0x6795, 0x75b9, 0x8bca, 0x9707,
+ 0x632f, 0x9547, 0x9635, 0x84b8, 0x6323, 0x7741, 0x5f81, 0x72f0,
+ 0x4e89, 0x6014, 0x6574, 0x62ef, 0x6b63, 0x653f,
+ /* 0x56 */
+ 0x5e27, 0x75c7, 0x90d1, 0x8bc1, 0x829d, 0x679d, 0x652f, 0x5431,
+ 0x8718, 0x77e5, 0x80a2, 0x8102, 0x6c41, 0x4e4b, 0x7ec7, 0x804c,
+ 0x76f4, 0x690d, 0x6b96, 0x6267, 0x503c, 0x4f84, 0x5740, 0x6307,
+ 0x6b62, 0x8dbe, 0x53ea, 0x65e8, 0x7eb8, 0x5fd7, 0x631a, 0x63b7,
+ 0x81f3, 0x81f4, 0x7f6e, 0x5e1c, 0x5cd9, 0x5236, 0x667a, 0x79e9,
+ 0x7a1a, 0x8d28, 0x7099, 0x75d4, 0x6ede, 0x6cbb, 0x7a92, 0x4e2d,
+ 0x76c5, 0x5fe0, 0x949f, 0x8877, 0x7ec8, 0x79cd, 0x80bf, 0x91cd,
+ 0x4ef2, 0x4f17, 0x821f, 0x5468, 0x5dde, 0x6d32, 0x8bcc, 0x7ca5,
+ 0x8f74, 0x8098, 0x5e1a, 0x5492, 0x76b1, 0x5b99, 0x663c, 0x9aa4,
+ 0x73e0, 0x682a, 0x86db, 0x6731, 0x732a, 0x8bf8, 0x8bdb, 0x9010,
+ 0x7af9, 0x70db, 0x716e, 0x62c4, 0x77a9, 0x5631, 0x4e3b, 0x8457,
+ 0x67f1, 0x52a9, 0x86c0, 0x8d2e, 0x94f8, 0x7b51,
+ /* 0x57 */
+ 0x4f4f, 0x6ce8, 0x795d, 0x9a7b, 0x6293, 0x722a, 0x62fd, 0x4e13,
+ 0x7816, 0x8f6c, 0x64b0, 0x8d5a, 0x7bc6, 0x6869, 0x5e84, 0x88c5,
+ 0x5986, 0x649e, 0x58ee, 0x72b6, 0x690e, 0x9525, 0x8ffd, 0x8d58,
+ 0x5760, 0x7f00, 0x8c06, 0x51c6, 0x6349, 0x62d9, 0x5353, 0x684c,
+ 0x7422, 0x8301, 0x914c, 0x5544, 0x7740, 0x707c, 0x6d4a, 0x5179,
+ 0x54a8, 0x8d44, 0x59ff, 0x6ecb, 0x6dc4, 0x5b5c, 0x7d2b, 0x4ed4,
+ 0x7c7d, 0x6ed3, 0x5b50, 0x81ea, 0x6e0d, 0x5b57, 0x9b03, 0x68d5,
+ 0x8e2a, 0x5b97, 0x7efc, 0x603b, 0x7eb5, 0x90b9, 0x8d70, 0x594f,
+ 0x63cd, 0x79df, 0x8db3, 0x5352, 0x65cf, 0x7956, 0x8bc5, 0x963b,
+ 0x7ec4, 0x94bb, 0x7e82, 0x5634, 0x9189, 0x6700, 0x7f6a, 0x5c0a,
+ 0x9075, 0x6628, 0x5de6, 0x4f50, 0x67de, 0x505a, 0x4f5c, 0x5750,
+ 0x5ea7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ /* 0x58 */
+ 0x4e8d, 0x4e0c, 0x5140, 0x4e10, 0x5eff, 0x5345, 0x4e15, 0x4e98,
+ 0x4e1e, 0x9b32, 0x5b6c, 0x5669, 0x4e28, 0x79ba, 0x4e3f, 0x5315,
+ 0x4e47, 0x592d, 0x723b, 0x536e, 0x6c10, 0x56df, 0x80e4, 0x9997,
+ 0x6bd3, 0x777e, 0x9f17, 0x4e36, 0x4e9f, 0x9f10, 0x4e5c, 0x4e69,
+ 0x4e93, 0x8288, 0x5b5b, 0x556c, 0x560f, 0x4ec4, 0x538d, 0x539d,
+ 0x53a3, 0x53a5, 0x53ae, 0x9765, 0x8d5d, 0x531a, 0x53f5, 0x5326,
+ 0x532e, 0x533e, 0x8d5c, 0x5366, 0x5363, 0x5202, 0x5208, 0x520e,
+ 0x522d, 0x5233, 0x523f, 0x5240, 0x524c, 0x525e, 0x5261, 0x525c,
+ 0x84af, 0x527d, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182, 0x7f54,
+ 0x4ebb, 0x4ec3, 0x4ec9, 0x4ec2, 0x4ee8, 0x4ee1, 0x4eeb, 0x4ede,
+ 0x4f1b, 0x4ef3, 0x4f22, 0x4f64, 0x4ef5, 0x4f25, 0x4f27, 0x4f09,
+ 0x4f2b, 0x4f5e, 0x4f67, 0x6538, 0x4f5a, 0x4f5d,
+ /* 0x59 */
+ 0x4f5f, 0x4f57, 0x4f32, 0x4f3d, 0x4f76, 0x4f74, 0x4f91, 0x4f89,
+ 0x4f83, 0x4f8f, 0x4f7e, 0x4f7b, 0x4faa, 0x4f7c, 0x4fac, 0x4f94,
+ 0x4fe6, 0x4fe8, 0x4fea, 0x4fc5, 0x4fda, 0x4fe3, 0x4fdc, 0x4fd1,
+ 0x4fdf, 0x4ff8, 0x5029, 0x504c, 0x4ff3, 0x502c, 0x500f, 0x502e,
+ 0x502d, 0x4ffe, 0x501c, 0x500c, 0x5025, 0x5028, 0x507e, 0x5043,
+ 0x5055, 0x5048, 0x504e, 0x506c, 0x507b, 0x50a5, 0x50a7, 0x50a9,
+ 0x50ba, 0x50d6, 0x5106, 0x50ed, 0x50ec, 0x50e6, 0x50ee, 0x5107,
+ 0x510b, 0x4edd, 0x6c3d, 0x4f58, 0x4f65, 0x4fce, 0x9fa0, 0x6c46,
+ 0x7c74, 0x516e, 0x5dfd, 0x9ec9, 0x9998, 0x5181, 0x5914, 0x52f9,
+ 0x530d, 0x8a07, 0x5310, 0x51eb, 0x5919, 0x5155, 0x4ea0, 0x5156,
+ 0x4eb3, 0x886e, 0x88a4, 0x4eb5, 0x8114, 0x88d2, 0x7980, 0x5b34,
+ 0x8803, 0x7fb8, 0x51ab, 0x51b1, 0x51bd, 0x51bc,
+ /* 0x5a */
+ 0x51c7, 0x5196, 0x51a2, 0x51a5, 0x8ba0, 0x8ba6, 0x8ba7, 0x8baa,
+ 0x8bb4, 0x8bb5, 0x8bb7, 0x8bc2, 0x8bc3, 0x8bcb, 0x8bcf, 0x8bce,
+ 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd6, 0x8bd8, 0x8bd9, 0x8bdc, 0x8bdf,
+ 0x8be0, 0x8be4, 0x8be8, 0x8be9, 0x8bee, 0x8bf0, 0x8bf3, 0x8bf6,
+ 0x8bf9, 0x8bfc, 0x8bff, 0x8c00, 0x8c02, 0x8c04, 0x8c07, 0x8c0c,
+ 0x8c0f, 0x8c11, 0x8c12, 0x8c14, 0x8c15, 0x8c16, 0x8c19, 0x8c1b,
+ 0x8c18, 0x8c1d, 0x8c1f, 0x8c20, 0x8c21, 0x8c25, 0x8c27, 0x8c2a,
+ 0x8c2b, 0x8c2e, 0x8c2f, 0x8c32, 0x8c33, 0x8c35, 0x8c36, 0x5369,
+ 0x537a, 0x961d, 0x9622, 0x9621, 0x9631, 0x962a, 0x963d, 0x963c,
+ 0x9642, 0x9649, 0x9654, 0x965f, 0x9667, 0x966c, 0x9672, 0x9674,
+ 0x9688, 0x968d, 0x9697, 0x96b0, 0x9097, 0x909b, 0x909d, 0x9099,
+ 0x90ac, 0x90a1, 0x90b4, 0x90b3, 0x90b6, 0x90ba,
+ /* 0x5b */
+ 0x90b8, 0x90b0, 0x90cf, 0x90c5, 0x90be, 0x90d0, 0x90c4, 0x90c7,
+ 0x90d3, 0x90e6, 0x90e2, 0x90dc, 0x90d7, 0x90db, 0x90eb, 0x90ef,
+ 0x90fe, 0x9104, 0x9122, 0x911e, 0x9123, 0x9131, 0x912f, 0x9139,
+ 0x9143, 0x9146, 0x520d, 0x5942, 0x52a2, 0x52ac, 0x52ad, 0x52be,
+ 0x54ff, 0x52d0, 0x52d6, 0x52f0, 0x53df, 0x71ee, 0x77cd, 0x5ef4,
+ 0x51f5, 0x51fc, 0x9b2f, 0x53b6, 0x5f01, 0x755a, 0x5def, 0x574c,
+ 0x57a9, 0x57a1, 0x587e, 0x58bc, 0x58c5, 0x58d1, 0x5729, 0x572c,
+ 0x572a, 0x5733, 0x5739, 0x572e, 0x572f, 0x575c, 0x573b, 0x5742,
+ 0x5769, 0x5785, 0x576b, 0x5786, 0x577c, 0x577b, 0x5768, 0x576d,
+ 0x5776, 0x5773, 0x57ad, 0x57a4, 0x578c, 0x57b2, 0x57cf, 0x57a7,
+ 0x57b4, 0x5793, 0x57a0, 0x57d5, 0x57d8, 0x57da, 0x57d9, 0x57d2,
+ 0x57b8, 0x57f4, 0x57ef, 0x57f8, 0x57e4, 0x57dd,
+ /* 0x5c */
+ 0x580b, 0x580d, 0x57fd, 0x57ed, 0x5800, 0x581e, 0x5819, 0x5844,
+ 0x5820, 0x5865, 0x586c, 0x5881, 0x5889, 0x589a, 0x5880, 0x99a8,
+ 0x9f19, 0x61ff, 0x8279, 0x827d, 0x827f, 0x828f, 0x828a, 0x82a8,
+ 0x8284, 0x828e, 0x8291, 0x8297, 0x8299, 0x82ab, 0x82b8, 0x82be,
+ 0x82b0, 0x82c8, 0x82ca, 0x82e3, 0x8298, 0x82b7, 0x82ae, 0x82cb,
+ 0x82cc, 0x82c1, 0x82a9, 0x82b4, 0x82a1, 0x82aa, 0x829f, 0x82c4,
+ 0x82ce, 0x82a4, 0x82e1, 0x8309, 0x82f7, 0x82e4, 0x830f, 0x8307,
+ 0x82dc, 0x82f4, 0x82d2, 0x82d8, 0x830c, 0x82fb, 0x82d3, 0x8311,
+ 0x831a, 0x8306, 0x8314, 0x8315, 0x82e0, 0x82d5, 0x831c, 0x8351,
+ 0x835b, 0x835c, 0x8308, 0x8392, 0x833c, 0x8334, 0x8331, 0x839b,
+ 0x835e, 0x832f, 0x834f, 0x8347, 0x8343, 0x835f, 0x8340, 0x8317,
+ 0x8360, 0x832d, 0x833a, 0x8333, 0x8366, 0x8365,
+ /* 0x5d */
+ 0x8368, 0x831b, 0x8369, 0x836c, 0x836a, 0x836d, 0x836e, 0x83b0,
+ 0x8378, 0x83b3, 0x83b4, 0x83a0, 0x83aa, 0x8393, 0x839c, 0x8385,
+ 0x837c, 0x83b6, 0x83a9, 0x837d, 0x83b8, 0x837b, 0x8398, 0x839e,
+ 0x83a8, 0x83ba, 0x83bc, 0x83c1, 0x8401, 0x83e5, 0x83d8, 0x5807,
+ 0x8418, 0x840b, 0x83dd, 0x83fd, 0x83d6, 0x841c, 0x8438, 0x8411,
+ 0x8406, 0x83d4, 0x83df, 0x840f, 0x8403, 0x83f8, 0x83f9, 0x83ea,
+ 0x83c5, 0x83c0, 0x8426, 0x83f0, 0x83e1, 0x845c, 0x8451, 0x845a,
+ 0x8459, 0x8473, 0x8487, 0x8488, 0x847a, 0x8489, 0x8478, 0x843c,
+ 0x8446, 0x8469, 0x8476, 0x848c, 0x848e, 0x8431, 0x846d, 0x84c1,
+ 0x84cd, 0x84d0, 0x84e6, 0x84bd, 0x84d3, 0x84ca, 0x84bf, 0x84ba,
+ 0x84e0, 0x84a1, 0x84b9, 0x84b4, 0x8497, 0x84e5, 0x84e3, 0x850c,
+ 0x750d, 0x8538, 0x84f0, 0x8539, 0x851f, 0x853a,
+ /* 0x5e */
+ 0x8556, 0x853b, 0x84ff, 0x84fc, 0x8559, 0x8548, 0x8568, 0x8564,
+ 0x855e, 0x857a, 0x77a2, 0x8543, 0x8572, 0x857b, 0x85a4, 0x85a8,
+ 0x8587, 0x858f, 0x8579, 0x85ae, 0x859c, 0x8585, 0x85b9, 0x85b7,
+ 0x85b0, 0x85d3, 0x85c1, 0x85dc, 0x85ff, 0x8627, 0x8605, 0x8629,
+ 0x8616, 0x863c, 0x5efe, 0x5f08, 0x593c, 0x5941, 0x8037, 0x5955,
+ 0x595a, 0x5958, 0x530f, 0x5c22, 0x5c25, 0x5c2c, 0x5c34, 0x624c,
+ 0x626a, 0x629f, 0x62bb, 0x62ca, 0x62da, 0x62d7, 0x62ee, 0x6322,
+ 0x62f6, 0x6339, 0x634b, 0x6343, 0x63ad, 0x63f6, 0x6371, 0x637a,
+ 0x638e, 0x63b4, 0x636d, 0x63ac, 0x638a, 0x6369, 0x63ae, 0x63bc,
+ 0x63f2, 0x63f8, 0x63e0, 0x63ff, 0x63c4, 0x63de, 0x63ce, 0x6452,
+ 0x63c6, 0x63be, 0x6445, 0x6441, 0x640b, 0x641b, 0x6420, 0x640c,
+ 0x6426, 0x6421, 0x645e, 0x6484, 0x646d, 0x6496,
+ /* 0x5f */
+ 0x647a, 0x64b7, 0x64b8, 0x6499, 0x64ba, 0x64c0, 0x64d0, 0x64d7,
+ 0x64e4, 0x64e2, 0x6509, 0x6525, 0x652e, 0x5f0b, 0x5fd2, 0x7519,
+ 0x5f11, 0x535f, 0x53f1, 0x53fd, 0x53e9, 0x53e8, 0x53fb, 0x5412,
+ 0x5416, 0x5406, 0x544b, 0x5452, 0x5453, 0x5454, 0x5456, 0x5443,
+ 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494, 0x5477,
+ 0x5471, 0x5464, 0x549a, 0x549b, 0x5484, 0x5476, 0x5466, 0x549d,
+ 0x54d0, 0x54ad, 0x54c2, 0x54b4, 0x54d2, 0x54a7, 0x54a6, 0x54d3,
+ 0x54d4, 0x5472, 0x54a3, 0x54d5, 0x54bb, 0x54bf, 0x54cc, 0x54d9,
+ 0x54da, 0x54dc, 0x54a9, 0x54aa, 0x54a4, 0x54dd, 0x54cf, 0x54de,
+ 0x551b, 0x54e7, 0x5520, 0x54fd, 0x5514, 0x54f3, 0x5522, 0x5523,
+ 0x550f, 0x5511, 0x5527, 0x552a, 0x5567, 0x558f, 0x55b5, 0x5549,
+ 0x556d, 0x5541, 0x5555, 0x553f, 0x5550, 0x553c,
+ /* 0x60 */
+ 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530, 0x555c,
+ 0x558b, 0x55d2, 0x5583, 0x55b1, 0x55b9, 0x5588, 0x5581, 0x559f,
+ 0x557e, 0x55d6, 0x5591, 0x557b, 0x55df, 0x55bd, 0x55be, 0x5594,
+ 0x5599, 0x55ea, 0x55f7, 0x55c9, 0x561f, 0x55d1, 0x55eb, 0x55ec,
+ 0x55d4, 0x55e6, 0x55dd, 0x55c4, 0x55ef, 0x55e5, 0x55f2, 0x55f3,
+ 0x55cc, 0x55cd, 0x55e8, 0x55f5, 0x55e4, 0x8f94, 0x561e, 0x5608,
+ 0x560c, 0x5601, 0x5624, 0x5623, 0x55fe, 0x5600, 0x5627, 0x562d,
+ 0x5658, 0x5639, 0x5657, 0x562c, 0x564d, 0x5662, 0x5659, 0x565c,
+ 0x564c, 0x5654, 0x5686, 0x5664, 0x5671, 0x566b, 0x567b, 0x567c,
+ 0x5685, 0x5693, 0x56af, 0x56d4, 0x56d7, 0x56dd, 0x56e1, 0x56f5,
+ 0x56eb, 0x56f9, 0x56ff, 0x5704, 0x570a, 0x5709, 0x571c, 0x5e0f,
+ 0x5e19, 0x5e14, 0x5e11, 0x5e31, 0x5e3b, 0x5e3c,
+ /* 0x61 */
+ 0x5e37, 0x5e44, 0x5e54, 0x5e5b, 0x5e5e, 0x5e61, 0x5c8c, 0x5c7a,
+ 0x5c8d, 0x5c90, 0x5c96, 0x5c88, 0x5c98, 0x5c99, 0x5c91, 0x5c9a,
+ 0x5c9c, 0x5cb5, 0x5ca2, 0x5cbd, 0x5cac, 0x5cab, 0x5cb1, 0x5ca3,
+ 0x5cc1, 0x5cb7, 0x5cc4, 0x5cd2, 0x5ce4, 0x5ccb, 0x5ce5, 0x5d02,
+ 0x5d03, 0x5d27, 0x5d26, 0x5d2e, 0x5d24, 0x5d1e, 0x5d06, 0x5d1b,
+ 0x5d58, 0x5d3e, 0x5d34, 0x5d3d, 0x5d6c, 0x5d5b, 0x5d6f, 0x5d5d,
+ 0x5d6b, 0x5d4b, 0x5d4a, 0x5d69, 0x5d74, 0x5d82, 0x5d99, 0x5d9d,
+ 0x8c73, 0x5db7, 0x5dc5, 0x5f73, 0x5f77, 0x5f82, 0x5f87, 0x5f89,
+ 0x5f8c, 0x5f95, 0x5f99, 0x5f9c, 0x5fa8, 0x5fad, 0x5fb5, 0x5fbc,
+ 0x8862, 0x5f61, 0x72ad, 0x72b0, 0x72b4, 0x72b7, 0x72b8, 0x72c3,
+ 0x72c1, 0x72ce, 0x72cd, 0x72d2, 0x72e8, 0x72ef, 0x72e9, 0x72f2,
+ 0x72f4, 0x72f7, 0x7301, 0x72f3, 0x7303, 0x72fa,
+ /* 0x62 */
+ 0x72fb, 0x7317, 0x7313, 0x7321, 0x730a, 0x731e, 0x731d, 0x7315,
+ 0x7322, 0x7339, 0x7325, 0x732c, 0x7338, 0x7331, 0x7350, 0x734d,
+ 0x7357, 0x7360, 0x736c, 0x736f, 0x737e, 0x821b, 0x5925, 0x98e7,
+ 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996a, 0x996b,
+ 0x996c, 0x9974, 0x9977, 0x997d, 0x9980, 0x9984, 0x9987, 0x998a,
+ 0x998d, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5e80, 0x5e91,
+ 0x5e8b, 0x5e96, 0x5ea5, 0x5ea0, 0x5eb9, 0x5eb5, 0x5ebe, 0x5eb3,
+ 0x8d53, 0x5ed2, 0x5ed1, 0x5edb, 0x5ee8, 0x5eea, 0x81ba, 0x5fc4,
+ 0x5fc9, 0x5fd6, 0x5fcf, 0x6003, 0x5fee, 0x6004, 0x5fe1, 0x5fe4,
+ 0x5ffe, 0x6005, 0x6006, 0x5fea, 0x5fed, 0x5ff8, 0x6019, 0x6035,
+ 0x6026, 0x601b, 0x600f, 0x600d, 0x6029, 0x602b, 0x600a, 0x603f,
+ 0x6021, 0x6078, 0x6079, 0x607b, 0x607a, 0x6042,
+ /* 0x63 */
+ 0x606a, 0x607d, 0x6096, 0x609a, 0x60ad, 0x609d, 0x6083, 0x6092,
+ 0x608c, 0x609b, 0x60ec, 0x60bb, 0x60b1, 0x60dd, 0x60d8, 0x60c6,
+ 0x60da, 0x60b4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60f4, 0x6100,
+ 0x610e, 0x612b, 0x614a, 0x6175, 0x61ac, 0x6194, 0x61a7, 0x61b7,
+ 0x61d4, 0x61f5, 0x5fdd, 0x96b3, 0x95e9, 0x95eb, 0x95f1, 0x95f3,
+ 0x95f5, 0x95f6, 0x95fc, 0x95fe, 0x9603, 0x9604, 0x9606, 0x9608,
+ 0x960a, 0x960b, 0x960c, 0x960d, 0x960f, 0x9612, 0x9615, 0x9616,
+ 0x9617, 0x9619, 0x961a, 0x4e2c, 0x723f, 0x6215, 0x6c35, 0x6c54,
+ 0x6c5c, 0x6c4a, 0x6ca3, 0x6c85, 0x6c90, 0x6c94, 0x6c8c, 0x6c68,
+ 0x6c69, 0x6c74, 0x6c76, 0x6c86, 0x6ca9, 0x6cd0, 0x6cd4, 0x6cad,
+ 0x6cf7, 0x6cf8, 0x6cf1, 0x6cd7, 0x6cb2, 0x6ce0, 0x6cd6, 0x6cfa,
+ 0x6ceb, 0x6cee, 0x6cb1, 0x6cd3, 0x6cef, 0x6cfe,
+ /* 0x64 */
+ 0x6d39, 0x6d27, 0x6d0c, 0x6d43, 0x6d48, 0x6d07, 0x6d04, 0x6d19,
+ 0x6d0e, 0x6d2b, 0x6d4d, 0x6d2e, 0x6d35, 0x6d1a, 0x6d4f, 0x6d52,
+ 0x6d54, 0x6d33, 0x6d91, 0x6d6f, 0x6d9e, 0x6da0, 0x6d5e, 0x6d93,
+ 0x6d94, 0x6d5c, 0x6d60, 0x6d7c, 0x6d63, 0x6e1a, 0x6dc7, 0x6dc5,
+ 0x6dde, 0x6e0e, 0x6dbf, 0x6de0, 0x6e11, 0x6de6, 0x6ddd, 0x6dd9,
+ 0x6e16, 0x6dab, 0x6e0c, 0x6dae, 0x6e2b, 0x6e6e, 0x6e4e, 0x6e6b,
+ 0x6eb2, 0x6e5f, 0x6e86, 0x6e53, 0x6e54, 0x6e32, 0x6e25, 0x6e44,
+ 0x6edf, 0x6eb1, 0x6e98, 0x6ee0, 0x6f2d, 0x6ee2, 0x6ea5, 0x6ea7,
+ 0x6ebd, 0x6ebb, 0x6eb7, 0x6ed7, 0x6eb4, 0x6ecf, 0x6e8f, 0x6ec2,
+ 0x6e9f, 0x6f62, 0x6f46, 0x6f47, 0x6f24, 0x6f15, 0x6ef9, 0x6f2f,
+ 0x6f36, 0x6f4b, 0x6f74, 0x6f2a, 0x6f09, 0x6f29, 0x6f89, 0x6f8d,
+ 0x6f8c, 0x6f78, 0x6f72, 0x6f7c, 0x6f7a, 0x6fd1,
+ /* 0x65 */
+ 0x6fc9, 0x6fa7, 0x6fb9, 0x6fb6, 0x6fc2, 0x6fe1, 0x6fee, 0x6fde,
+ 0x6fe0, 0x6fef, 0x701a, 0x7023, 0x701b, 0x7039, 0x7035, 0x704f,
+ 0x705e, 0x5b80, 0x5b84, 0x5b95, 0x5b93, 0x5ba5, 0x5bb8, 0x752f,
+ 0x9a9e, 0x6434, 0x5be4, 0x5bee, 0x8930, 0x5bf0, 0x8e47, 0x8b07,
+ 0x8fb6, 0x8fd3, 0x8fd5, 0x8fe5, 0x8fee, 0x8fe4, 0x8fe9, 0x8fe6,
+ 0x8ff3, 0x8fe8, 0x9005, 0x9004, 0x900b, 0x9026, 0x9011, 0x900d,
+ 0x9016, 0x9021, 0x9035, 0x9036, 0x902d, 0x902f, 0x9044, 0x9051,
+ 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905b, 0x66b9, 0x9074,
+ 0x907d, 0x9082, 0x9088, 0x9083, 0x908b, 0x5f50, 0x5f57, 0x5f56,
+ 0x5f58, 0x5c3b, 0x54ab, 0x5c50, 0x5c59, 0x5b71, 0x5c63, 0x5c66,
+ 0x7fbc, 0x5f2a, 0x5f29, 0x5f2d, 0x8274, 0x5f3c, 0x9b3b, 0x5c6e,
+ 0x5981, 0x5983, 0x598d, 0x59a9, 0x59aa, 0x59a3,
+ /* 0x66 */
+ 0x5997, 0x59ca, 0x59ab, 0x599e, 0x59a4, 0x59d2, 0x59b2, 0x59af,
+ 0x59d7, 0x59be, 0x5a05, 0x5a06, 0x59dd, 0x5a08, 0x59e3, 0x59d8,
+ 0x59f9, 0x5a0c, 0x5a09, 0x5a32, 0x5a34, 0x5a11, 0x5a23, 0x5a13,
+ 0x5a40, 0x5a67, 0x5a4a, 0x5a55, 0x5a3c, 0x5a62, 0x5a75, 0x80ec,
+ 0x5aaa, 0x5a9b, 0x5a77, 0x5a7a, 0x5abe, 0x5aeb, 0x5ab2, 0x5ad2,
+ 0x5ad4, 0x5ab8, 0x5ae0, 0x5ae3, 0x5af1, 0x5ad6, 0x5ae6, 0x5ad8,
+ 0x5adc, 0x5b09, 0x5b17, 0x5b16, 0x5b32, 0x5b37, 0x5b40, 0x5c15,
+ 0x5c1c, 0x5b5a, 0x5b65, 0x5b73, 0x5b51, 0x5b53, 0x5b62, 0x9a75,
+ 0x9a77, 0x9a78, 0x9a7a, 0x9a7f, 0x9a7d, 0x9a80, 0x9a81, 0x9a85,
+ 0x9a88, 0x9a8a, 0x9a90, 0x9a92, 0x9a93, 0x9a96, 0x9a98, 0x9a9b,
+ 0x9a9c, 0x9a9d, 0x9a9f, 0x9aa0, 0x9aa2, 0x9aa3, 0x9aa5, 0x9aa7,
+ 0x7e9f, 0x7ea1, 0x7ea3, 0x7ea5, 0x7ea8, 0x7ea9,
+ /* 0x67 */
+ 0x7ead, 0x7eb0, 0x7ebe, 0x7ec0, 0x7ec1, 0x7ec2, 0x7ec9, 0x7ecb,
+ 0x7ecc, 0x7ed0, 0x7ed4, 0x7ed7, 0x7edb, 0x7ee0, 0x7ee1, 0x7ee8,
+ 0x7eeb, 0x7eee, 0x7eef, 0x7ef1, 0x7ef2, 0x7f0d, 0x7ef6, 0x7efa,
+ 0x7efb, 0x7efe, 0x7f01, 0x7f02, 0x7f03, 0x7f07, 0x7f08, 0x7f0b,
+ 0x7f0c, 0x7f0f, 0x7f11, 0x7f12, 0x7f17, 0x7f19, 0x7f1c, 0x7f1b,
+ 0x7f1f, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27,
+ 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2f, 0x7f30, 0x7f31, 0x7f32,
+ 0x7f33, 0x7f35, 0x5e7a, 0x757f, 0x5ddb, 0x753e, 0x9095, 0x738e,
+ 0x7391, 0x73ae, 0x73a2, 0x739f, 0x73cf, 0x73c2, 0x73d1, 0x73b7,
+ 0x73b3, 0x73c0, 0x73c9, 0x73c8, 0x73e5, 0x73d9, 0x987c, 0x740a,
+ 0x73e9, 0x73e7, 0x73de, 0x73ba, 0x73f2, 0x740f, 0x742a, 0x745b,
+ 0x7426, 0x7425, 0x7428, 0x7430, 0x742e, 0x742c,
+ /* 0x68 */
+ 0x741b, 0x741a, 0x7441, 0x745c, 0x7457, 0x7455, 0x7459, 0x7477,
+ 0x746d, 0x747e, 0x749c, 0x748e, 0x7480, 0x7481, 0x7487, 0x748b,
+ 0x749e, 0x74a8, 0x74a9, 0x7490, 0x74a7, 0x74d2, 0x74ba, 0x97ea,
+ 0x97eb, 0x97ec, 0x674c, 0x6753, 0x675e, 0x6748, 0x6769, 0x67a5,
+ 0x6787, 0x676a, 0x6773, 0x6798, 0x67a7, 0x6775, 0x67a8, 0x679e,
+ 0x67ad, 0x678b, 0x6777, 0x677c, 0x67f0, 0x6809, 0x67d8, 0x680a,
+ 0x67e9, 0x67b0, 0x680c, 0x67d9, 0x67b5, 0x67da, 0x67b3, 0x67dd,
+ 0x6800, 0x67c3, 0x67b8, 0x67e2, 0x680e, 0x67c1, 0x67fd, 0x6832,
+ 0x6833, 0x6860, 0x6861, 0x684e, 0x6862, 0x6844, 0x6864, 0x6883,
+ 0x681d, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683e, 0x684a,
+ 0x6849, 0x6829, 0x68b5, 0x688f, 0x6874, 0x6877, 0x6893, 0x686b,
+ 0x68c2, 0x696e, 0x68fc, 0x691f, 0x6920, 0x68f9,
+ /* 0x69 */
+ 0x6924, 0x68f0, 0x690b, 0x6901, 0x6957, 0x68e3, 0x6910, 0x6971,
+ 0x6939, 0x6960, 0x6942, 0x695d, 0x6984, 0x696b, 0x6980, 0x6998,
+ 0x6978, 0x6934, 0x69cc, 0x6987, 0x6988, 0x69ce, 0x6989, 0x6966,
+ 0x6963, 0x6979, 0x699b, 0x69a7, 0x69bb, 0x69ab, 0x69ad, 0x69d4,
+ 0x69b1, 0x69c1, 0x69ca, 0x69df, 0x6995, 0x69e0, 0x698d, 0x69ff,
+ 0x6a2f, 0x69ed, 0x6a17, 0x6a18, 0x6a65, 0x69f2, 0x6a44, 0x6a3e,
+ 0x6aa0, 0x6a50, 0x6a5b, 0x6a35, 0x6a8e, 0x6a79, 0x6a3d, 0x6a28,
+ 0x6a58, 0x6a7c, 0x6a91, 0x6a90, 0x6aa9, 0x6a97, 0x6aab, 0x7337,
+ 0x7352, 0x6b81, 0x6b82, 0x6b87, 0x6b84, 0x6b92, 0x6b93, 0x6b8d,
+ 0x6b9a, 0x6b9b, 0x6ba1, 0x6baa, 0x8f6b, 0x8f6d, 0x8f71, 0x8f72,
+ 0x8f73, 0x8f75, 0x8f76, 0x8f78, 0x8f77, 0x8f79, 0x8f7a, 0x8f7c,
+ 0x8f7e, 0x8f81, 0x8f82, 0x8f84, 0x8f87, 0x8f8b,
+ /* 0x6a */
+ 0x8f8d, 0x8f8e, 0x8f8f, 0x8f98, 0x8f9a, 0x8ece, 0x620b, 0x6217,
+ 0x621b, 0x621f, 0x6222, 0x6221, 0x6225, 0x6224, 0x622c, 0x81e7,
+ 0x74ef, 0x74f4, 0x74ff, 0x750f, 0x7511, 0x7513, 0x6534, 0x65ee,
+ 0x65ef, 0x65f0, 0x660a, 0x6619, 0x6772, 0x6603, 0x6615, 0x6600,
+ 0x7085, 0x66f7, 0x661d, 0x6634, 0x6631, 0x6636, 0x6635, 0x8006,
+ 0x665f, 0x6654, 0x6641, 0x664f, 0x6656, 0x6661, 0x6657, 0x6677,
+ 0x6684, 0x668c, 0x66a7, 0x669d, 0x66be, 0x66db, 0x66dc, 0x66e6,
+ 0x66e9, 0x8d32, 0x8d33, 0x8d36, 0x8d3b, 0x8d3d, 0x8d40, 0x8d45,
+ 0x8d46, 0x8d48, 0x8d49, 0x8d47, 0x8d4d, 0x8d55, 0x8d59, 0x89c7,
+ 0x89ca, 0x89cb, 0x89cc, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x726e,
+ 0x729f, 0x725d, 0x7266, 0x726f, 0x727e, 0x727f, 0x7284, 0x728b,
+ 0x728d, 0x728f, 0x7292, 0x6308, 0x6332, 0x63b0,
+ /* 0x6b */
+ 0x643f, 0x64d8, 0x8004, 0x6bea, 0x6bf3, 0x6bfd, 0x6bf5, 0x6bf9,
+ 0x6c05, 0x6c07, 0x6c06, 0x6c0d, 0x6c15, 0x6c18, 0x6c19, 0x6c1a,
+ 0x6c21, 0x6c29, 0x6c24, 0x6c2a, 0x6c32, 0x6535, 0x6555, 0x656b,
+ 0x724d, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809f, 0x809c,
+ 0x8093, 0x80bc, 0x670a, 0x80bd, 0x80b1, 0x80ab, 0x80ad, 0x80b4,
+ 0x80b7, 0x80e7, 0x80e8, 0x80e9, 0x80ea, 0x80db, 0x80c2, 0x80c4,
+ 0x80d9, 0x80cd, 0x80d7, 0x6710, 0x80dd, 0x80eb, 0x80f1, 0x80f4,
+ 0x80ed, 0x810d, 0x810e, 0x80f2, 0x80fc, 0x6715, 0x8112, 0x8c5a,
+ 0x8136, 0x811e, 0x812c, 0x8118, 0x8132, 0x8148, 0x814c, 0x8153,
+ 0x8174, 0x8159, 0x815a, 0x8171, 0x8160, 0x8169, 0x817c, 0x817d,
+ 0x816d, 0x8167, 0x584d, 0x5ab5, 0x8188, 0x8182, 0x8191, 0x6ed5,
+ 0x81a3, 0x81aa, 0x81cc, 0x6726, 0x81ca, 0x81bb,
+ /* 0x6c */
+ 0x81c1, 0x81a6, 0x6b24, 0x6b37, 0x6b39, 0x6b43, 0x6b46, 0x6b59,
+ 0x98d1, 0x98d2, 0x98d3, 0x98d5, 0x98d9, 0x98da, 0x6bb3, 0x5f40,
+ 0x6bc2, 0x89f3, 0x6590, 0x9f51, 0x6593, 0x65bc, 0x65c6, 0x65c4,
+ 0x65c3, 0x65cc, 0x65ce, 0x65d2, 0x65d6, 0x7080, 0x709c, 0x7096,
+ 0x709d, 0x70bb, 0x70c0, 0x70b7, 0x70ab, 0x70b1, 0x70e8, 0x70ca,
+ 0x7110, 0x7113, 0x7116, 0x712f, 0x7131, 0x7173, 0x715c, 0x7168,
+ 0x7145, 0x7172, 0x714a, 0x7178, 0x717a, 0x7198, 0x71b3, 0x71b5,
+ 0x71a8, 0x71a0, 0x71e0, 0x71d4, 0x71e7, 0x71f9, 0x721d, 0x7228,
+ 0x706c, 0x7118, 0x7166, 0x71b9, 0x623e, 0x623d, 0x6243, 0x6248,
+ 0x6249, 0x793b, 0x7940, 0x7946, 0x7949, 0x795b, 0x795c, 0x7953,
+ 0x795a, 0x7962, 0x7957, 0x7960, 0x796f, 0x7967, 0x797a, 0x7985,
+ 0x798a, 0x799a, 0x79a7, 0x79b3, 0x5fd1, 0x5fd0,
+ /* 0x6d */
+ 0x603c, 0x605d, 0x605a, 0x6067, 0x6041, 0x6059, 0x6063, 0x60ab,
+ 0x6106, 0x610d, 0x615d, 0x61a9, 0x619d, 0x61cb, 0x61d1, 0x6206,
+ 0x8080, 0x807f, 0x6c93, 0x6cf6, 0x6dfc, 0x77f6, 0x77f8, 0x7800,
+ 0x7809, 0x7817, 0x7818, 0x7811, 0x65ab, 0x782d, 0x781c, 0x781d,
+ 0x7839, 0x783a, 0x783b, 0x781f, 0x783c, 0x7825, 0x782c, 0x7823,
+ 0x7829, 0x784e, 0x786d, 0x7856, 0x7857, 0x7826, 0x7850, 0x7847,
+ 0x784c, 0x786a, 0x789b, 0x7893, 0x789a, 0x7887, 0x789c, 0x78a1,
+ 0x78a3, 0x78b2, 0x78b9, 0x78a5, 0x78d4, 0x78d9, 0x78c9, 0x78ec,
+ 0x78f2, 0x7905, 0x78f4, 0x7913, 0x7924, 0x791e, 0x7934, 0x9f9b,
+ 0x9ef9, 0x9efb, 0x9efc, 0x76f1, 0x7704, 0x770d, 0x76f9, 0x7707,
+ 0x7708, 0x771a, 0x7722, 0x7719, 0x772d, 0x7726, 0x7735, 0x7738,
+ 0x7750, 0x7751, 0x7747, 0x7743, 0x775a, 0x7768,
+ /* 0x6e */
+ 0x7762, 0x7765, 0x777f, 0x778d, 0x777d, 0x7780, 0x778c, 0x7791,
+ 0x779f, 0x77a0, 0x77b0, 0x77b5, 0x77bd, 0x753a, 0x7540, 0x754e,
+ 0x754b, 0x7548, 0x755b, 0x7572, 0x7579, 0x7583, 0x7f58, 0x7f61,
+ 0x7f5f, 0x8a48, 0x7f68, 0x7f74, 0x7f71, 0x7f79, 0x7f81, 0x7f7e,
+ 0x76cd, 0x76e5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948b, 0x948a,
+ 0x948c, 0x948d, 0x948f, 0x9490, 0x9494, 0x9497, 0x9495, 0x949a,
+ 0x949b, 0x949c, 0x94a3, 0x94a4, 0x94ab, 0x94aa, 0x94ad, 0x94ac,
+ 0x94af, 0x94b0, 0x94b2, 0x94b4, 0x94b6, 0x94b7, 0x94b8, 0x94b9,
+ 0x94ba, 0x94bc, 0x94bd, 0x94bf, 0x94c4, 0x94c8, 0x94c9, 0x94ca,
+ 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94d0, 0x94d1, 0x94d2, 0x94d5,
+ 0x94d6, 0x94d7, 0x94d9, 0x94d8, 0x94db, 0x94de, 0x94df, 0x94e0,
+ 0x94e2, 0x94e4, 0x94e5, 0x94e7, 0x94e8, 0x94ea,
+ /* 0x6f */
+ 0x94e9, 0x94eb, 0x94ee, 0x94ef, 0x94f3, 0x94f4, 0x94f5, 0x94f7,
+ 0x94f9, 0x94fc, 0x94fd, 0x94ff, 0x9503, 0x9502, 0x9506, 0x9507,
+ 0x9509, 0x950a, 0x950d, 0x950e, 0x950f, 0x9512, 0x9513, 0x9514,
+ 0x9515, 0x9516, 0x9518, 0x951b, 0x951d, 0x951e, 0x951f, 0x9522,
+ 0x952a, 0x952b, 0x9529, 0x952c, 0x9531, 0x9532, 0x9534, 0x9536,
+ 0x9537, 0x9538, 0x953c, 0x953e, 0x953f, 0x9542, 0x9535, 0x9544,
+ 0x9545, 0x9546, 0x9549, 0x954c, 0x954e, 0x954f, 0x9552, 0x9553,
+ 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955b, 0x955e, 0x955f,
+ 0x955d, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568,
+ 0x9569, 0x956a, 0x956b, 0x956c, 0x956f, 0x9571, 0x9572, 0x9573,
+ 0x953a, 0x77e7, 0x77ec, 0x96c9, 0x79d5, 0x79ed, 0x79e3, 0x79eb,
+ 0x7a06, 0x5d47, 0x7a03, 0x7a02, 0x7a1e, 0x7a14,
+ /* 0x70 */
+ 0x7a39, 0x7a37, 0x7a51, 0x9ecf, 0x99a5, 0x7a70, 0x7688, 0x768e,
+ 0x7693, 0x7699, 0x76a4, 0x74de, 0x74e0, 0x752c, 0x9e20, 0x9e22,
+ 0x9e28, 0x9e29, 0x9e2a, 0x9e2b, 0x9e2c, 0x9e32, 0x9e31, 0x9e36,
+ 0x9e38, 0x9e37, 0x9e39, 0x9e3a, 0x9e3e, 0x9e41, 0x9e42, 0x9e44,
+ 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4b, 0x9e4c, 0x9e4e, 0x9e51,
+ 0x9e55, 0x9e57, 0x9e5a, 0x9e5b, 0x9e5c, 0x9e5e, 0x9e63, 0x9e66,
+ 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b, 0x9e6c, 0x9e71, 0x9e6d,
+ 0x9e73, 0x7592, 0x7594, 0x7596, 0x75a0, 0x759d, 0x75ac, 0x75a3,
+ 0x75b3, 0x75b4, 0x75b8, 0x75c4, 0x75b1, 0x75b0, 0x75c3, 0x75c2,
+ 0x75d6, 0x75cd, 0x75e3, 0x75e8, 0x75e6, 0x75e4, 0x75eb, 0x75e7,
+ 0x7603, 0x75f1, 0x75fc, 0x75ff, 0x7610, 0x7600, 0x7605, 0x760c,
+ 0x7617, 0x760a, 0x7625, 0x7618, 0x7615, 0x7619,
+ /* 0x71 */
+ 0x761b, 0x763c, 0x7622, 0x7620, 0x7640, 0x762d, 0x7630, 0x763f,
+ 0x7635, 0x7643, 0x763e, 0x7633, 0x764d, 0x765e, 0x7654, 0x765c,
+ 0x7656, 0x766b, 0x766f, 0x7fca, 0x7ae6, 0x7a78, 0x7a79, 0x7a80,
+ 0x7a86, 0x7a88, 0x7a95, 0x7aa6, 0x7aa0, 0x7aac, 0x7aa8, 0x7aad,
+ 0x7ab3, 0x8864, 0x8869, 0x8872, 0x887d, 0x887f, 0x8882, 0x88a2,
+ 0x88c6, 0x88b7, 0x88bc, 0x88c9, 0x88e2, 0x88ce, 0x88e3, 0x88e5,
+ 0x88f1, 0x891a, 0x88fc, 0x88e8, 0x88fe, 0x88f0, 0x8921, 0x8919,
+ 0x8913, 0x891b, 0x890a, 0x8934, 0x892b, 0x8936, 0x8941, 0x8966,
+ 0x897b, 0x758b, 0x80e5, 0x76b2, 0x76b4, 0x77dc, 0x8012, 0x8014,
+ 0x8016, 0x801c, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027, 0x8029,
+ 0x8028, 0x8031, 0x800b, 0x8035, 0x8043, 0x8046, 0x804d, 0x8052,
+ 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883,
+ /* 0x72 */
+ 0x9889, 0x988c, 0x988d, 0x988f, 0x9894, 0x989a, 0x989b, 0x989e,
+ 0x989f, 0x98a1, 0x98a2, 0x98a5, 0x98a6, 0x864d, 0x8654, 0x866c,
+ 0x866e, 0x867f, 0x867a, 0x867c, 0x867b, 0x86a8, 0x868d, 0x868b,
+ 0x86ac, 0x869d, 0x86a7, 0x86a3, 0x86aa, 0x8693, 0x86a9, 0x86b6,
+ 0x86c4, 0x86b5, 0x86ce, 0x86b0, 0x86ba, 0x86b1, 0x86af, 0x86c9,
+ 0x86cf, 0x86b4, 0x86e9, 0x86f1, 0x86f2, 0x86ed, 0x86f3, 0x86d0,
+ 0x8713, 0x86de, 0x86f4, 0x86df, 0x86d8, 0x86d1, 0x8703, 0x8707,
+ 0x86f8, 0x8708, 0x870a, 0x870d, 0x8709, 0x8723, 0x873b, 0x871e,
+ 0x8725, 0x872e, 0x871a, 0x873e, 0x8748, 0x8734, 0x8731, 0x8729,
+ 0x8737, 0x873f, 0x8782, 0x8722, 0x877d, 0x877e, 0x877b, 0x8760,
+ 0x8770, 0x874c, 0x876e, 0x878b, 0x8753, 0x8763, 0x877c, 0x8764,
+ 0x8759, 0x8765, 0x8793, 0x87af, 0x87a8, 0x87d2,
+ /* 0x73 */
+ 0x87c6, 0x8788, 0x8785, 0x87ad, 0x8797, 0x8783, 0x87ab, 0x87e5,
+ 0x87ac, 0x87b5, 0x87b3, 0x87cb, 0x87d3, 0x87bd, 0x87d1, 0x87c0,
+ 0x87ca, 0x87db, 0x87ea, 0x87e0, 0x87ee, 0x8816, 0x8813, 0x87fe,
+ 0x880a, 0x881b, 0x8821, 0x8839, 0x883c, 0x7f36, 0x7f42, 0x7f44,
+ 0x7f45, 0x8210, 0x7afa, 0x7afd, 0x7b08, 0x7b03, 0x7b04, 0x7b15,
+ 0x7b0a, 0x7b2b, 0x7b0f, 0x7b47, 0x7b38, 0x7b2a, 0x7b19, 0x7b2e,
+ 0x7b31, 0x7b20, 0x7b25, 0x7b24, 0x7b33, 0x7b3e, 0x7b1e, 0x7b58,
+ 0x7b5a, 0x7b45, 0x7b75, 0x7b4c, 0x7b5d, 0x7b60, 0x7b6e, 0x7b7b,
+ 0x7b62, 0x7b72, 0x7b71, 0x7b90, 0x7ba6, 0x7ba7, 0x7bb8, 0x7bac,
+ 0x7b9d, 0x7ba8, 0x7b85, 0x7baa, 0x7b9c, 0x7ba2, 0x7bab, 0x7bb4,
+ 0x7bd1, 0x7bc1, 0x7bcc, 0x7bdd, 0x7bda, 0x7be5, 0x7be6, 0x7bea,
+ 0x7c0c, 0x7bfe, 0x7bfc, 0x7c0f, 0x7c16, 0x7c0b,
+ /* 0x74 */
+ 0x7c1f, 0x7c2a, 0x7c26, 0x7c38, 0x7c41, 0x7c40, 0x81fe, 0x8201,
+ 0x8202, 0x8204, 0x81ec, 0x8844, 0x8221, 0x8222, 0x8223, 0x822d,
+ 0x822f, 0x8228, 0x822b, 0x8238, 0x823b, 0x8233, 0x8234, 0x823e,
+ 0x8244, 0x8249, 0x824b, 0x824f, 0x825a, 0x825f, 0x8268, 0x887e,
+ 0x8885, 0x8888, 0x88d8, 0x88df, 0x895e, 0x7f9d, 0x7f9f, 0x7fa7,
+ 0x7faf, 0x7fb0, 0x7fb2, 0x7c7c, 0x6549, 0x7c91, 0x7c9d, 0x7c9c,
+ 0x7c9e, 0x7ca2, 0x7cb2, 0x7cbc, 0x7cbd, 0x7cc1, 0x7cc7, 0x7ccc,
+ 0x7ccd, 0x7cc8, 0x7cc5, 0x7cd7, 0x7ce8, 0x826e, 0x66a8, 0x7fbf,
+ 0x7fce, 0x7fd5, 0x7fe5, 0x7fe1, 0x7fe6, 0x7fe9, 0x7fee, 0x7ff3,
+ 0x7cf8, 0x7d77, 0x7da6, 0x7dae, 0x7e47, 0x7e9b, 0x9eb8, 0x9eb4,
+ 0x8d73, 0x8d84, 0x8d94, 0x8d91, 0x8db1, 0x8d67, 0x8d6d, 0x8c47,
+ 0x8c49, 0x914a, 0x9150, 0x914e, 0x914f, 0x9164,
+ /* 0x75 */
+ 0x9162, 0x9161, 0x9170, 0x9169, 0x916f, 0x917d, 0x917e, 0x9172,
+ 0x9174, 0x9179, 0x918c, 0x9185, 0x9190, 0x918d, 0x9191, 0x91a2,
+ 0x91a3, 0x91aa, 0x91ad, 0x91ae, 0x91af, 0x91b5, 0x91b4, 0x91ba,
+ 0x8c55, 0x9e7e, 0x8db8, 0x8deb, 0x8e05, 0x8e59, 0x8e69, 0x8db5,
+ 0x8dbf, 0x8dbc, 0x8dba, 0x8dc4, 0x8dd6, 0x8dd7, 0x8dda, 0x8dde,
+ 0x8dce, 0x8dcf, 0x8ddb, 0x8dc6, 0x8dec, 0x8df7, 0x8df8, 0x8de3,
+ 0x8df9, 0x8dfb, 0x8de4, 0x8e09, 0x8dfd, 0x8e14, 0x8e1d, 0x8e1f,
+ 0x8e2c, 0x8e2e, 0x8e23, 0x8e2f, 0x8e3a, 0x8e40, 0x8e39, 0x8e35,
+ 0x8e3d, 0x8e31, 0x8e49, 0x8e41, 0x8e42, 0x8e51, 0x8e52, 0x8e4a,
+ 0x8e70, 0x8e76, 0x8e7c, 0x8e6f, 0x8e74, 0x8e85, 0x8e8f, 0x8e94,
+ 0x8e90, 0x8e9c, 0x8e9e, 0x8c78, 0x8c82, 0x8c8a, 0x8c85, 0x8c98,
+ 0x8c94, 0x659b, 0x89d6, 0x89de, 0x89da, 0x89dc,
+ /* 0x76 */
+ 0x89e5, 0x89eb, 0x89ef, 0x8a3e, 0x8b26, 0x9753, 0x96e9, 0x96f3,
+ 0x96ef, 0x9706, 0x9701, 0x9708, 0x970f, 0x970e, 0x972a, 0x972d,
+ 0x9730, 0x973e, 0x9f80, 0x9f83, 0x9f85, 0x9f86, 0x9f87, 0x9f88,
+ 0x9f89, 0x9f8a, 0x9f8c, 0x9efe, 0x9f0b, 0x9f0d, 0x96b9, 0x96bc,
+ 0x96bd, 0x96ce, 0x96d2, 0x77bf, 0x96e0, 0x928e, 0x92ae, 0x92c8,
+ 0x933e, 0x936a, 0x93ca, 0x938f, 0x943e, 0x946b, 0x9c7f, 0x9c82,
+ 0x9c85, 0x9c86, 0x9c87, 0x9c88, 0x7a23, 0x9c8b, 0x9c8e, 0x9c90,
+ 0x9c91, 0x9c92, 0x9c94, 0x9c95, 0x9c9a, 0x9c9b, 0x9c9e, 0x9c9f,
+ 0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8,
+ 0x9ca9, 0x9cab, 0x9cad, 0x9cae, 0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3,
+ 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd,
+ 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cca, 0x9ccb,
+ /* 0x77 */
+ 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, 0x9cd3, 0x9cd4, 0x9cd5,
+ 0x9cd7, 0x9cd8, 0x9cd9, 0x9cdc, 0x9cdd, 0x9cdf, 0x9ce2, 0x977c,
+ 0x9785, 0x9791, 0x9792, 0x9794, 0x97af, 0x97ab, 0x97a3, 0x97b2,
+ 0x97b4, 0x9ab1, 0x9ab0, 0x9ab7, 0x9e58, 0x9ab6, 0x9aba, 0x9abc,
+ 0x9ac1, 0x9ac0, 0x9ac5, 0x9ac2, 0x9acb, 0x9acc, 0x9ad1, 0x9b45,
+ 0x9b43, 0x9b47, 0x9b49, 0x9b48, 0x9b4d, 0x9b51, 0x98e8, 0x990d,
+ 0x992e, 0x9955, 0x9954, 0x9adf, 0x9ae1, 0x9ae6, 0x9aef, 0x9aeb,
+ 0x9afb, 0x9aed, 0x9af9, 0x9b08, 0x9b0f, 0x9b13, 0x9b1f, 0x9b23,
+ 0x9ebd, 0x9ebe, 0x7e3b, 0x9e82, 0x9e87, 0x9e88, 0x9e8b, 0x9e92,
+ 0x93d6, 0x9e9d, 0x9e9f, 0x9edb, 0x9edc, 0x9edd, 0x9ee0, 0x9edf,
+ 0x9ee2, 0x9ee9, 0x9ee7, 0x9ee5, 0x9eea, 0x9eef, 0x9f22, 0x9f2c,
+ 0x9f2f, 0x9f39, 0x9f37, 0x9f3d, 0x9f3e, 0x9f44,
+};
+
+static const unsigned short gb2312_2charset[7445] = {
+ 0x2168, 0x216c, 0x2127, 0x2163, 0x2140, 0x2141, 0x2824, 0x2822,
+ 0x2828, 0x2826, 0x283a, 0x282c, 0x282a, 0x2830, 0x282e, 0x2142,
+ 0x2834, 0x2832, 0x2839, 0x2821, 0x2825, 0x2827, 0x2829, 0x282d,
+ 0x2831, 0x2823, 0x282b, 0x282f, 0x2833, 0x2835, 0x2836, 0x2837,
+ 0x2838, 0x2126, 0x2125, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625,
+ 0x2626, 0x2627, 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d,
+ 0x262e, 0x262f, 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635,
+ 0x2636, 0x2637, 0x2638, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645,
+ 0x2646, 0x2647, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d,
+ 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655,
+ 0x2656, 0x2657, 0x2658, 0x2727, 0x2721, 0x2722, 0x2723, 0x2724,
+ 0x2725, 0x2726, 0x2728, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d,
+ 0x272e, 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735,
+ 0x2736, 0x2737, 0x2738, 0x2739, 0x273a, 0x273b, 0x273c, 0x273d,
+ 0x273e, 0x273f, 0x2740, 0x2741, 0x2751, 0x2752, 0x2753, 0x2754,
+ 0x2755, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c, 0x275d,
+ 0x275e, 0x275f, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765,
+ 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, 0x276d,
+ 0x276e, 0x276f, 0x2770, 0x2771, 0x2757, 0x212a, 0x212c, 0x212e,
+ 0x212f, 0x2130, 0x2131, 0x212d, 0x216b, 0x2164, 0x2165, 0x2179,
+ 0x2166, 0x216d, 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, 0x2276,
+ 0x2277, 0x2278, 0x2279, 0x227a, 0x227b, 0x227c, 0x217b, 0x217c,
+ 0x217a, 0x217d, 0x214a, 0x2147, 0x2146, 0x214c, 0x2158, 0x215e,
+ 0x214f, 0x214e, 0x2144, 0x2145, 0x2149, 0x2148, 0x2152, 0x2153,
+ 0x2160, 0x215f, 0x2143, 0x214b, 0x2157, 0x2156, 0x2155, 0x2159,
+ 0x2154, 0x215c, 0x215d, 0x215a, 0x215b, 0x2151, 0x214d, 0x2150,
+ 0x2259, 0x225a, 0x225b, 0x225c, 0x225d, 0x225e, 0x225f, 0x2260,
+ 0x2261, 0x2262, 0x2245, 0x2246, 0x2247, 0x2248, 0x2249, 0x224a,
+ 0x224b, 0x224c, 0x224d, 0x224e, 0x224f, 0x2250, 0x2251, 0x2252,
+ 0x2253, 0x2254, 0x2255, 0x2256, 0x2257, 0x2258, 0x2231, 0x2232,
+ 0x2233, 0x2234, 0x2235, 0x2236, 0x2237, 0x2238, 0x2239, 0x223a,
+ 0x223b, 0x223c, 0x223d, 0x223e, 0x223f, 0x2240, 0x2241, 0x2242,
+ 0x2243, 0x2244, 0x2924, 0x2925, 0x2926, 0x2927, 0x2928, 0x2929,
+ 0x292a, 0x292b, 0x292c, 0x292d, 0x292e, 0x292f, 0x2930, 0x2931,
+ 0x2932, 0x2933, 0x2934, 0x2935, 0x2936, 0x2937, 0x2938, 0x2939,
+ 0x293a, 0x293b, 0x293c, 0x293d, 0x293e, 0x293f, 0x2940, 0x2941,
+ 0x2942, 0x2943, 0x2944, 0x2945, 0x2946, 0x2947, 0x2948, 0x2949,
+ 0x294a, 0x294b, 0x294c, 0x294d, 0x294e, 0x294f, 0x2950, 0x2951,
+ 0x2952, 0x2953, 0x2954, 0x2955, 0x2956, 0x2957, 0x2958, 0x2959,
+ 0x295a, 0x295b, 0x295c, 0x295d, 0x295e, 0x295f, 0x2960, 0x2961,
+ 0x2962, 0x2963, 0x2964, 0x2965, 0x2966, 0x2967, 0x2968, 0x2969,
+ 0x296a, 0x296b, 0x296c, 0x296d, 0x296e, 0x296f, 0x2176, 0x2175,
+ 0x2178, 0x2177, 0x2174, 0x2173, 0x2170, 0x2172, 0x2171, 0x216f,
+ 0x216e, 0x2162, 0x2161, 0x2121, 0x2122, 0x2123, 0x2128, 0x2129,
+ 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213a, 0x213b,
+ 0x213e, 0x213f, 0x217e, 0x2132, 0x2133, 0x213c, 0x213d, 0x2421,
+ 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429,
+ 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431,
+ 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439,
+ 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441,
+ 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449,
+ 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451,
+ 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459,
+ 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461,
+ 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469,
+ 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471,
+ 0x2472, 0x2473, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526,
+ 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e,
+ 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536,
+ 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e,
+ 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546,
+ 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e,
+ 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556,
+ 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e,
+ 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566,
+ 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e,
+ 0x256f, 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576,
+ 0x2124, 0x2845, 0x2846, 0x2847, 0x2848, 0x2849, 0x284a, 0x284b,
+ 0x284c, 0x284d, 0x284e, 0x284f, 0x2850, 0x2851, 0x2852, 0x2853,
+ 0x2854, 0x2855, 0x2856, 0x2857, 0x2858, 0x2859, 0x285a, 0x285b,
+ 0x285c, 0x285d, 0x285e, 0x285f, 0x2860, 0x2861, 0x2862, 0x2863,
+ 0x2864, 0x2865, 0x2866, 0x2867, 0x2868, 0x2869, 0x2265, 0x2266,
+ 0x2267, 0x2268, 0x2269, 0x226a, 0x226b, 0x226c, 0x226d, 0x226e,
+ 0x523b, 0x3621, 0x465f, 0x4d72, 0x5549, 0x487d, 0x494f, 0x4f42,
+ 0x5822, 0x323b, 0x536b, 0x5824, 0x3373, 0x5728, 0x4752, 0x5827,
+ 0x4a40, 0x4770, 0x317b, 0x5235, 0x3454, 0x362b, 0x4b3f, 0x5829,
+ 0x362a, 0x413d, 0x514f, 0x4925, 0x582d, 0x3876, 0x513e, 0x635c,
+ 0x5650, 0x3761, 0x342e, 0x4159, 0x583c, 0x4d68, 0x3524, 0x4e2a,
+ 0x5677, 0x4076, 0x3e59, 0x582f, 0x444b, 0x3e43, 0x5831, 0x4334,
+ 0x5265, 0x562e, 0x4e5a, 0x5527, 0x3a75, 0x3726, 0x4056, 0x4639,
+ 0x4552, 0x4747, 0x3954, 0x334b, 0x5252, 0x583f, 0x3e45, 0x4672,
+ 0x5232, 0x4f30, 0x4f67, 0x4a69, 0x5840, 0x4272, 0x4252, 0x4869,
+ 0x472c, 0x414b, 0x5368, 0x5579, 0x4a42, 0x367e, 0x5821, 0x535a,
+ 0x3f77, 0x5446, 0x3b25, 0x5841, 0x4e65, 0x3e2e, 0x5828, 0x5147,
+ 0x5029, 0x583d, 0x596f, 0x4d76, 0x3f3a, 0x3d3b, 0x3a25, 0x5260,
+ 0x327a, 0x3a60, 0x4436, 0x4f6d, 0x3e29, 0x4d24, 0x4141, 0x4757,
+ 0x5971, 0x5974, 0x484b, 0x5869, 0x525a, 0x4a32, 0x484a, 0x586c,
+ 0x586a, 0x5846, 0x3d76, 0x464d, 0x3370, 0x586b, 0x3d71, 0x3d69,
+ 0x4854, 0x3453, 0x4258, 0x3256, 0x5750, 0x4a4b, 0x4b7b, 0x554c,
+ 0x3836, 0x4f49, 0x595a, 0x5870, 0x472a, 0x586e, 0x347a, 0x416e,
+ 0x5254, 0x586d, 0x5247, 0x586f, 0x4347, 0x5176, 0x5659, 0x5872,
+ 0x5875, 0x3c7e, 0x3c5b, 0x484e, 0x375d, 0x3742, 0x4673, 0x5878,
+ 0x5241, 0x4e69, 0x3c3f, 0x377c, 0x3725, 0x505d, 0x565a, 0x5345,
+ 0x3b6f, 0x3b61, 0x5871, 0x4921, 0x4e30, 0x342b, 0x5873, 0x494b,
+ 0x5876, 0x4257, 0x5877, 0x4e31, 0x5879, 0x322e, 0x3940, 0x5923,
+ 0x3069, 0x4166, 0x496c, 0x4b45, 0x4b46, 0x5924, 0x3568, 0x352b,
+ 0x4e3b, 0x354d, 0x5721, 0x5774, 0x5353, 0x4c65, 0x3a4e, 0x5922,
+ 0x595c, 0x5360, 0x587d, 0x3770, 0x5777, 0x587e, 0x587a, 0x5921,
+ 0x4463, 0x5336, 0x5874, 0x595d, 0x587b, 0x4565, 0x4050, 0x5170,
+ 0x305b, 0x3c51, 0x5926, 0x5925, 0x592c, 0x592e, 0x592b, 0x4a39,
+ 0x5929, 0x5636, 0x335e, 0x5928, 0x407d, 0x4a4c, 0x592a, 0x5927,
+ 0x5930, 0x3631, 0x3929, 0x5240, 0x4f40, 0x4242, 0x3d44, 0x556c,
+ 0x3260, 0x4748, 0x3f6b, 0x592d, 0x592f, 0x4e6a, 0x3a6e, 0x4756,
+ 0x3163, 0x3459, 0x366d, 0x5934, 0x3f21, 0x595e, 0x474e, 0x407e,
+ 0x5938, 0x4b57, 0x377d, 0x5935, 0x5937, 0x3123, 0x5361, 0x5939,
+ 0x5045, 0x5936, 0x5931, 0x5932, 0x4129, 0x5933, 0x3c73, 0x505e,
+ 0x3829, 0x3e63, 0x593d, 0x593a, 0x3033, 0x5942, 0x5944, 0x3136,
+ 0x593f, 0x3539, 0x3e73, 0x4c48, 0x3a72, 0x5250, 0x5943, 0x3d68,
+ 0x332b, 0x5945, 0x3e6b, 0x5946, 0x593b, 0x445f, 0x593e, 0x5941,
+ 0x5940, 0x552e, 0x5635, 0x4763, 0x5948, 0x3c59, 0x594a, 0x593c,
+ 0x594b, 0x462b, 0x5949, 0x5776, 0x4d23, 0x3d21, 0x594c, 0x453c,
+ 0x4d35, 0x594d, 0x5947, 0x3325, 0x3f7e, 0x3835, 0x407c, 0x3078,
+ 0x3476, 0x594e, 0x594f, 0x3422, 0x5950, 0x345f, 0x3041, 0x5951,
+ 0x4935, 0x4f71, 0x5952, 0x4145, 0x5956, 0x492e, 0x5955, 0x5954,
+ 0x5957, 0x4b5b, 0x3d29, 0x4627, 0x5953, 0x5958, 0x5959, 0x4865,
+ 0x405c, 0x3679, 0x5823, 0x544a, 0x542a, 0x5056, 0x3364, 0x5557,
+ 0x4f48, 0x3962, 0x3f4b, 0x4362, 0x3652, 0x4d43, 0x596e, 0x5970,
+ 0x3533, 0x3635, 0x3e24, 0x486b, 0x482b, 0x304b, 0x392b, 0x4179,
+ 0x5962, 0x403c, 0x3932, 0x3958, 0x504b, 0x3178, 0x4664, 0x3e5f,
+ 0x3564, 0x5748, 0x5178, 0x3c66, 0x4a5e, 0x3c3d, 0x5966, 0x5867,
+ 0x445a, 0x3854, 0x483d, 0x3261, 0x5459, 0x4330, 0x4361, 0x5a22,
+ 0x485f, 0x5034, 0x3e7c, 0x4529, 0x395a, 0x5a23, 0x5429, 0x5a24,
+ 0x597b, 0x362c, 0x376b, 0x3179, 0x597c, 0x3365, 0x3e76, 0x3f76,
+ 0x5231, 0x4064, 0x3633, 0x597e, 0x597d, 0x3e3b, 0x4660, 0x573c,
+ 0x5a21, 0x4139, 0x3572, 0x4168, 0x3c75, 0x3455, 0x415d, 0x447d,
+ 0x3c38, 0x3732, 0x376f, 0x596c, 0x463e, 0x3f2d, 0x3b4b, 0x354a,
+ 0x5b49, 0x5057, 0x4d39, 0x303c, 0x3376, 0x3b77, 0x5b4a, 0x3a2f,
+ 0x5464, 0x3536, 0x3573, 0x5856, 0x4850, 0x3756, 0x4750, 0x5857,
+ 0x3f2f, 0x5b3b, 0x5858, 0x504c, 0x3b2e, 0x6b3e, 0x4150, 0x4175,
+ 0x5472, 0x3855, 0x3434, 0x3375, 0x493e, 0x4550, 0x4559, 0x407b,
+ 0x3170, 0x5859, 0x394e, 0x353d, 0x585a, 0x5646, 0x4b22, 0x482f,
+ 0x4932, 0x344c, 0x3f4c, 0x3974, 0x585b, 0x585c, 0x3667, 0x3c41,
+ 0x4c6a, 0x4f77, 0x585d, 0x4730, 0x3950, 0x3d23, 0x4c5e, 0x464a,
+ 0x5860, 0x585e, 0x585f, 0x307e, 0x3e67, 0x4a23, 0x3c74, 0x3831,
+ 0x386e, 0x5862, 0x3d4b, 0x5864, 0x5863, 0x457c, 0x5865, 0x5866,
+ 0x4126, 0x4830, 0x306c, 0x3926, 0x3c53, 0x4e71, 0x5b3d, 0x4153,
+ 0x362f, 0x567a, 0x452c, 0x3d59, 0x5b3e, 0x5b3f, 0x4078, 0x3e22,
+ 0x404d, 0x5b40, 0x4a46, 0x322a, 0x5342, 0x4363, 0x512b, 0x5b42,
+ 0x4055, 0x5b43, 0x3f31, 0x443c, 0x475a, 0x5b44, 0x5968, 0x4957,
+ 0x3934, 0x4e70, 0x5448, 0x307c, 0x3452, 0x5059, 0x5969, 0x5e4b,
+ 0x596b, 0x5830, 0x3b2f, 0x3131, 0x3357, 0x584e, 0x5451, 0x3d33,
+ 0x3f6f, 0x4f3b, 0x5850, 0x374b, 0x5851, 0x4625, 0x4778, 0x523d,
+ 0x5852, 0x4464, 0x4a2e, 0x4727, 0x5826, 0x497d, 0x4e67, 0x3b5c,
+ 0x306b, 0x3b2a, 0x502d, 0x3130, 0x5764, 0x573f, 0x3525, 0x4274,
+ 0x444f, 0x3229, 0x3237, 0x3165, 0x5f32, 0x553c, 0x3f28, 0x422c,
+ 0x5855, 0x4231, 0x5854, 0x4e54, 0x5a60, 0x4e40, 0x5834, 0x432e,
+ 0x5321, 0x4e23, 0x3c34, 0x4834, 0x4251, 0x3e6d, 0x5036, 0x5a61,
+ 0x4764, 0x3327, 0x3672, 0x4c7c, 0x407a, 0x4077, 0x5139, 0x5161,
+ 0x5847, 0x325e, 0x4065, 0x3a71, 0x5848, 0x542d, 0x4f61, 0x5849,
+ 0x584a, 0x4f43, 0x3378, 0x3e47, 0x584b, 0x5b4c, 0x4825, 0x4f58,
+ 0x487e, 0x324e, 0x5356, 0x3266, 0x3c30, 0x5351, 0x4b2b, 0x3734,
+ 0x3722, 0x4a65, 0x4821, 0x4a5c, 0x3164, 0x5070, 0x4551, 0x5b45,
+ 0x357e, 0x3f5a, 0x3945, 0x3e64, 0x416d, 0x5f36, 0x5f35, 0x563b,
+ 0x3d50, 0x5559, 0x3048, 0x3623, 0x3f49, 0x4c28, 0x5f33, 0x4a37,
+ 0x5352, 0x584f, 0x5236, 0x3a45, 0x4b3e, 0x4c3e, 0x5f37, 0x3570,
+ 0x5f34, 0x5375, 0x3354, 0x3877, 0x5f3a, 0x3a4f, 0x3c2a, 0x3575,
+ 0x4d2c, 0x437b, 0x3a73, 0x4074, 0x4d42, 0x4f72, 0x5f38, 0x4f45,
+ 0x4240, 0x5f39, 0x4270, 0x3e7d, 0x415f, 0x4d4c, 0x5277, 0x374d,
+ 0x5f41, 0x5f44, 0x3771, 0x3049, 0x3656, 0x3754, 0x3a2c, 0x4c7d,
+ 0x3f54, 0x4b31, 0x4674, 0x5628, 0x5f45, 0x4e62, 0x3333, 0x4e7c,
+ 0x3435, 0x4e47, 0x3a70, 0x4e61, 0x513d, 0x5f40, 0x3474, 0x334a,
+ 0x3866, 0x5f3b, 0x4445, 0x5f3c, 0x5f3d, 0x5f3e, 0x453b, 0x5f3f,
+ 0x5f42, 0x5431, 0x5f43, 0x473a, 0x4e58, 0x4458, 0x5f4a, 0x5f4f,
+ 0x565c, 0x5f49, 0x5f5a, 0x4e36, 0x3a47, 0x5f4e, 0x5f48, 0x455e,
+ 0x496b, 0x3a74, 0x437c, 0x3e57, 0x5f46, 0x5f4d, 0x4558, 0x5526,
+ 0x3a4d, 0x3e4c, 0x533d, 0x3840, 0x5664, 0x5f47, 0x393e, 0x3f27,
+ 0x417c, 0x5f4b, 0x5f4c, 0x5f50, 0x5f5b, 0x5f65, 0x5f57, 0x5f56,
+ 0x5749, 0x5f63, 0x5f64, 0x656b, 0x5227, 0x5f52, 0x3f29, 0x545b,
+ 0x3f48, 0x5f54, 0x4f4c, 0x5f5d, 0x514a, 0x5f5e, 0x3027, 0x4637,
+ 0x5f53, 0x3a65, 0x365f, 0x4d5b, 0x397e, 0x5455, 0x5f5f, 0x4f6c,
+ 0x3025, 0x5f67, 0x5f51, 0x5146, 0x5f55, 0x5f58, 0x5f59, 0x5f5c,
+ 0x3b29, 0x5f60, 0x5f61, 0x5f62, 0x5f66, 0x5f68, 0x5334, 0x3867,
+ 0x4536, 0x5f6a, 0x495a, 0x4128, 0x4444, 0x3f5e, 0x4f78, 0x555c,
+ 0x5f6e, 0x3238, 0x3a5f, 0x5f6c, 0x5b41, 0x5164, 0x4b74, 0x343d,
+ 0x3026, 0x5f71, 0x4c46, 0x5f72, 0x5f6d, 0x5f69, 0x5f6b, 0x5f6f,
+ 0x5f70, 0x3b3d, 0x5f73, 0x5f74, 0x3b23, 0x4a5b, 0x4e28, 0x6027,
+ 0x332a, 0x6026, 0x6021, 0x5f7e, 0x4d59, 0x5f7c, 0x5f7a, 0x3f50,
+ 0x5744, 0x494c, 0x5f78, 0x3021, 0x5f7d, 0x5f7b, 0x6022, 0x6028,
+ 0x3748, 0x4621, 0x4936, 0x4032, 0x5f75, 0x453e, 0x5844, 0x5f79,
+ 0x4476, 0x6023, 0x6024, 0x6025, 0x5025, 0x6034, 0x4c64, 0x6031,
+ 0x3f26, 0x602f, 0x4e39, 0x602b, 0x4946, 0x402e, 0x602e, 0x3a6d,
+ 0x3a30, 0x6029, 0x5f76, 0x6033, 0x6038, 0x342d, 0x6039, 0x4f32,
+ 0x3a48, 0x6030, 0x507a, 0x602c, 0x547b, 0x5f77, 0x4567, 0x602d,
+ 0x5377, 0x6036, 0x6037, 0x6044, 0x5061, 0x603c, 0x6049, 0x604a,
+ 0x603e, 0x602a, 0x4924, 0x6041, 0x6032, 0x4a48, 0x6043, 0x6035,
+ 0x4e4b, 0x4b43, 0x604d, 0x6046, 0x6042, 0x604b, 0x603a, 0x603f,
+ 0x6040, 0x6045, 0x6047, 0x6048, 0x604c, 0x603b, 0x4b54, 0x6055,
+ 0x6056, 0x6052, 0x6050, 0x3c4e, 0x6051, 0x3842, 0x5845, 0x506a,
+ 0x426f, 0x604f, 0x603d, 0x6054, 0x6053, 0x6057, 0x605c, 0x6058,
+ 0x5676, 0x3330, 0x576c, 0x4b3b, 0x605a, 0x4e7b, 0x3a59, 0x6061,
+ 0x605d, 0x522d, 0x6062, 0x605b, 0x6059, 0x605f, 0x6060, 0x605e,
+ 0x6064, 0x4677, 0x582c, 0x546b, 0x6066, 0x4a49, 0x6065, 0x3841,
+ 0x6067, 0x6068, 0x6069, 0x6063, 0x3a3f, 0x4c67, 0x606a, 0x4f79,
+ 0x606b, 0x4842, 0x3d40, 0x4452, 0x606c, 0x606d, 0x4774, 0x4b44,
+ 0x606e, 0x3b58, 0x5836, 0x5272, 0x606f, 0x4d45, 0x365a, 0x6071,
+ 0x5430, 0x4027, 0x3451, 0x4e27, 0x6070, 0x6072, 0x394c, 0x397a,
+ 0x4d3c, 0x6073, 0x4654, 0x6074, 0x5432, 0x4826, 0x6076, 0x6075,
+ 0x6077, 0x4d41, 0x4a25, 0x545a, 0x5b57, 0x5b59, 0x5b58, 0x3967,
+ 0x5b5c, 0x5b5d, 0x3558, 0x5b5a, 0x5b5b, 0x3321, 0x5b5f, 0x3b78,
+ 0x5637, 0x5b60, 0x3e79, 0x373b, 0x5b50, 0x4c2e, 0x3f32, 0x3b35,
+ 0x5778, 0x3f53, 0x3f69, 0x3c61, 0x4c33, 0x5b5e, 0x3053, 0x4e6b,
+ 0x3758, 0x5739, 0x4642, 0x4024, 0x4c39, 0x5b67, 0x5b61, 0x463a,
+ 0x5b63, 0x5b68, 0x4577, 0x5b6a, 0x5b69, 0x3f40, 0x5b66, 0x5b65,
+ 0x3439, 0x402c, 0x4222, 0x5b62, 0x5b64, 0x504d, 0x5b6d, 0x405d,
+ 0x5b72, 0x3662, 0x5b73, 0x5b52, 0x3938, 0x542b, 0x5b6c, 0x3f51,
+ 0x5b70, 0x5b51, 0x3566, 0x5b6b, 0x3f65, 0x5b6e, 0x5b71, 0x5b79,
+ 0x3921, 0x3023, 0x4271, 0x3347, 0x5b6f, 0x5b78, 0x4652, 0x5b74,
+ 0x5b75, 0x5b77, 0x5b76, 0x5b7e, 0x5372, 0x323a, 0x5b7d, 0x5c24,
+ 0x5b7b, 0x5b7a, 0x5b7c, 0x4560, 0x3b79, 0x5c23, 0x5c25, 0x4c43,
+ 0x3651, 0x5d40, 0x5c21, 0x5c22, 0x4735, 0x3669, 0x5c27, 0x5c26,
+ 0x5c29, 0x3124, 0x354c, 0x3f30, 0x515f, 0x3642, 0x5c28, 0x4b7a,
+ 0x6b73, 0x4b5c, 0x4b7e, 0x4c41, 0x487b, 0x5c2a, 0x4c6e, 0x5c2b,
+ 0x5b53, 0x5c2f, 0x5c2c, 0x3e33, 0x4a7b, 0x5c2d, 0x494a, 0x4439,
+ 0x473d, 0x5c2e, 0x5476, 0x5066, 0x442b, 0x3655, 0x5b54, 0x315a,
+ 0x5b55, 0x5b56, 0x3a3e, 0x4840, 0x4a3f, 0x4849, 0x5733, 0x4979,
+ 0x3f47, 0x3a78, 0x523c, 0x623a, 0x3426, 0x3138, 0x3834, 0x4f44,
+ 0x5967, 0x4f26, 0x4d62, 0x596d, 0x3660, 0x5239, 0x393b, 0x6239,
+ 0x6237, 0x3473, 0x4c6c, 0x4c2b, 0x3772, 0x5832, 0x516b, 0x3a3b,
+ 0x4a27, 0x4d37, 0x5244, 0x3f64, 0x3c50, 0x3661, 0x5e45, 0x5e46,
+ 0x5b3c, 0x5159, 0x4666, 0x444e, 0x376e, 0x375c, 0x3f7c, 0x5760,
+ 0x4675, 0x313c, 0x5e48, 0x3d31, 0x4c57, 0x5e4a, 0x5e49, 0x356c,
+ 0x495d, 0x3042, 0x452e, 0x452b, 0x444c, 0x3c69, 0x4b7d, 0x3a43,
+ 0x6579, 0x4867, 0x657a, 0x4d7d, 0x5731, 0x383e, 0x4268, 0x4851,
+ 0x657b, 0x364a, 0x3c4b, 0x517d, 0x6621, 0x436e, 0x6624, 0x657e,
+ 0x6625, 0x4d57, 0x3741, 0x657c, 0x657d, 0x6623, 0x445d, 0x6628,
+ 0x6627, 0x4343, 0x465e, 0x662a, 0x4437, 0x6622, 0x4a3c, 0x3d63,
+ 0x3943, 0x6626, 0x5055, 0x4e2f, 0x6629, 0x6630, 0x5226, 0x3d2a,
+ 0x662d, 0x662f, 0x4051, 0x524c, 0x3c27, 0x6631, 0x5276, 0x574b,
+ 0x4d7e, 0x4d5e, 0x4226, 0x662b, 0x662c, 0x3d3f, 0x662e, 0x6633,
+ 0x6632, 0x6636, 0x6638, 0x446f, 0x4448, 0x3e6a, 0x496f, 0x6637,
+ 0x3670, 0x4364, 0x5369, 0x6634, 0x6635, 0x4822, 0x663d, 0x6639,
+ 0x4645, 0x4d71, 0x663b, 0x663c, 0x3b69, 0x663e, 0x663a, 0x4037,
+ 0x5324, 0x663f, 0x4974, 0x6643, 0x6644, 0x5076, 0x433d, 0x4344,
+ 0x6642, 0x6641, 0x6647, 0x4f31, 0x6b74, 0x664a, 0x6645, 0x3c5e,
+ 0x4929, 0x3c35, 0x4f53, 0x6648, 0x6649, 0x664e, 0x6650, 0x6651,
+ 0x664b, 0x3555, 0x664c, 0x664f, 0x445b, 0x6646, 0x664d, 0x6652,
+ 0x6654, 0x6653, 0x6655, 0x5978, 0x6656, 0x6657, 0x5753, 0x665d,
+ 0x665e, 0x3f57, 0x5450, 0x5756, 0x3466, 0x4b6f, 0x665a, 0x5843,
+ 0x574e, 0x5022, 0x434f, 0x665f, 0x3c3e, 0x3942, 0x665b, 0x5127,
+ 0x3a22, 0x424f, 0x582b, 0x4a6b, 0x656e, 0x665c, 0x3775, 0x4866,
+ 0x4475, 0x6532, 0x447e, 0x4b7c, 0x6533, 0x552c, 0x536e, 0x4a58,
+ 0x3032, 0x4b4e, 0x4d6a, 0x3a6a, 0x6535, 0x6534, 0x575a, 0x3959,
+ 0x5666, 0x3628, 0x4d70, 0x524b, 0x3126, 0x4a35, 0x3368, 0x4973,
+ 0x3f4d, 0x507b, 0x4a52, 0x6536, 0x3b42, 0x4f5c, 0x392c, 0x5457,
+ 0x3a26, 0x5167, 0x4f7c, 0x3c52, 0x6537, 0x485d, 0x3f6d, 0x3176,
+ 0x4b5e, 0x3c45, 0x3c44, 0x527a, 0x435c, 0x3f5c, 0x383b, 0x4342,
+ 0x3a2e, 0x5422, 0x475e, 0x442f, 0x326c, 0x3951, 0x653b, 0x4148,
+ 0x552f, 0x653c, 0x653e, 0x3467, 0x3654, 0x4b42, 0x5130, 0x353c,
+ 0x4a59, 0x3762, 0x4964, 0x3d2b, 0x4e3e, 0x5770, 0x5021, 0x4959,
+ 0x367b, 0x6658, 0x3c62, 0x333e, 0x4950, 0x6659, 0x3322, 0x5e4c,
+ 0x5348, 0x5e4d, 0x5222, 0x5e4e, 0x3e4d, 0x5e4f, 0x4a2c, 0x527c,
+ 0x335f, 0x656a, 0x4461, 0x3e21, 0x4e32, 0x4472, 0x3e56, 0x4628,
+ 0x3263, 0x3e53, 0x477c, 0x4c6b, 0x3d6c, 0x4e5d, 0x4a3a, 0x4641,
+ 0x656c, 0x503c, 0x5539, 0x656d, 0x4a74, 0x4d40, 0x4245, 0x656f,
+ 0x4244, 0x6570, 0x6578, 0x4d4d, 0x493d, 0x5259, 0x6128, 0x536c,
+ 0x4b6a, 0x4671, 0x612c, 0x6127, 0x6129, 0x612a, 0x612f, 0x326d,
+ 0x612b, 0x385a, 0x612d, 0x612e, 0x6130, 0x353a, 0x6131, 0x6133,
+ 0x6138, 0x5152, 0x6136, 0x6135, 0x416b, 0x6137, 0x5440, 0x6132,
+ 0x613a, 0x3036, 0x6134, 0x3f79, 0x6139, 0x613b, 0x613e, 0x613c,
+ 0x5645, 0x4f3f, 0x613d, 0x613f, 0x424d, 0x366b, 0x5378, 0x474d,
+ 0x3765, 0x3e7e, 0x6140, 0x6141, 0x6147, 0x3367, 0x4669, 0x345e,
+ 0x5142, 0x6148, 0x6146, 0x6145, 0x6143, 0x6142, 0x3140, 0x5538,
+ 0x6144, 0x614b, 0x614c, 0x614a, 0x6f7a, 0x6153, 0x6152, 0x4736,
+ 0x6149, 0x614e, 0x6150, 0x6154, 0x6151, 0x614d, 0x614f, 0x6155,
+ 0x6156, 0x6157, 0x6158, 0x615a, 0x615b, 0x4e21, 0x675d, 0x3428,
+ 0x565d, 0x5132, 0x3332, 0x3924, 0x5773, 0x4749, 0x3e5e, 0x392e,
+ 0x4e57, 0x326e, 0x5b4f, 0x3c3a, 0x5251, 0x4b48, 0x304d, 0x4f6f,
+ 0x5963, 0x3d6d, 0x3152, 0x4a50, 0x323c, 0x4b27, 0x372b, 0x4a26,
+ 0x4f23, 0x6078, 0x554a, 0x607b, 0x607a, 0x4541, 0x4c7b, 0x4131,
+ 0x6079, 0x5663, 0x322f, 0x5644, 0x355b, 0x3478, 0x5621, 0x4f2f,
+ 0x306f, 0x607c, 0x6121, 0x3323, 0x607d, 0x607e, 0x4331, 0x435d,
+ 0x6122, 0x3779, 0x3b4f, 0x6123, 0x443b, 0x6124, 0x6125, 0x6126,
+ 0x3431, 0x3849, 0x463d, 0x446a, 0x3222, 0x5052, 0x675b, 0x3b43,
+ 0x5357, 0x5344, 0x3963, 0x624f, 0x572f, 0x476c, 0x3153, 0x3432,
+ 0x6251, 0x5072, 0x422e, 0x6250, 0x3f62, 0x5326, 0x3557, 0x6252,
+ 0x356a, 0x436d, 0x387d, 0x382e, 0x4553, 0x374f, 0x6254, 0x6253,
+ 0x3648, 0x5779, 0x4d25, 0x6258, 0x6256, 0x4a7c, 0x3f35, 0x5339,
+ 0x6255, 0x6257, 0x412e, 0x4048, 0x625b, 0x625a, 0x402a, 0x414e,
+ 0x625c, 0x625d, 0x625e, 0x5b48, 0x5153, 0x4d22, 0x3d28, 0x5e43,
+ 0x5825, 0x3f2a, 0x5b4d, 0x526c, 0x467a, 0x452a, 0x5e44, 0x3157,
+ 0x5f2e, 0x4a3d, 0x5f31, 0x392d, 0x527d, 0x3825, 0x3a6b, 0x335a,
+ 0x355c, 0x5545, 0x4356, 0x4f52, 0x3b21, 0x6573, 0x6572, 0x6574,
+ 0x4d64, 0x4875, 0x352f, 0x473f, 0x6576, 0x6c30, 0x6566, 0x3969,
+ 0x3531, 0x423c, 0x6568, 0x6567, 0x6569, 0x524d, 0x616a, 0x504e,
+ 0x4d2e, 0x5165, 0x324a, 0x316b, 0x3172, 0x456d, 0x5543, 0x5330,
+ 0x615c, 0x615d, 0x525b, 0x3339, 0x314b, 0x4d79, 0x5577, 0x615e,
+ 0x3e36, 0x347d, 0x615f, 0x3a5c, 0x6160, 0x3b32, 0x4249, 0x6161,
+ 0x506c, 0x4d3d, 0x6162, 0x3543, 0x4547, 0x6163, 0x6164, 0x5379,
+ 0x6165, 0x512d, 0x6166, 0x4e22, 0x6167, 0x3542, 0x6168, 0x3b55,
+ 0x5044, 0x6260, 0x3158, 0x5264, 0x6261, 0x3c49, 0x484c, 0x6263,
+ 0x6c7e, 0x6c7d, 0x5f2f, 0x6262, 0x563e, 0x4d7c, 0x4326, 0x6343,
+ 0x5652, 0x6267, 0x6268, 0x5347, 0x626c, 0x3f6c, 0x626d, 0x6265,
+ 0x3340, 0x446e, 0x626e, 0x5043, 0x3a76, 0x6269, 0x375e, 0x3b33,
+ 0x4c2c, 0x4b4b, 0x6264, 0x6266, 0x626a, 0x626b, 0x6277, 0x6274,
+ 0x5475, 0x6273, 0x452d, 0x557a, 0x4542, 0x3240, 0x626f, 0x6272,
+ 0x412f, 0x4b3c, 0x3521, 0x6279, 0x3c31, 0x6271, 0x5054, 0x5439,
+ 0x6275, 0x3956, 0x6276, 0x4753, 0x6270, 0x575c, 0x6d21, 0x6278,
+ 0x6d25, 0x627e, 0x4a51, 0x4135, 0x3b50, 0x3f56, 0x3a63, 0x4b21,
+ 0x6d26, 0x6d23, 0x6d22, 0x3b56, 0x6d27, 0x5074, 0x6d24, 0x3a5e,
+ 0x3677, 0x6321, 0x3632, 0x4c71, 0x3927, 0x4f22, 0x4721, 0x3f52,
+ 0x3671, 0x627a, 0x627b, 0x627d, 0x627c, 0x4455, 0x6322, 0x5341,
+ 0x6327, 0x4744, 0x4f24, 0x6329, 0x3a37, 0x6328, 0x3b5a, 0x6323,
+ 0x6324, 0x632a, 0x6326, 0x4e72, 0x5346, 0x3b3c, 0x5443, 0x447a,
+ 0x6d28, 0x507c, 0x6325, 0x4375, 0x632d, 0x312f, 0x6332, 0x3c42,
+ 0x632c, 0x353f, 0x4769, 0x6330, 0x3e2a, 0x4d6f, 0x3b73, 0x4c68,
+ 0x632f, 0x6331, 0x4f27, 0x632e, 0x4e29, 0x3b5d, 0x356b, 0x3e65,
+ 0x3252, 0x334d, 0x3139, 0x632b, 0x3251, 0x352c, 0x395f, 0x3668,
+ 0x4f6b, 0x6337, 0x3b4c, 0x4847, 0x504a, 0x6338, 0x336e, 0x6d29,
+ 0x537a, 0x5364, 0x6d2a, 0x6339, 0x5262, 0x6335, 0x535e, 0x3850,
+ 0x6333, 0x6336, 0x375f, 0x6334, 0x4022, 0x633a, 0x5438, 0x3448,
+ 0x633b, 0x3b45, 0x4977, 0x4965, 0x443d, 0x6d2b, 0x427d, 0x3b5b,
+ 0x3f2e, 0x4e3f, 0x633c, 0x3f36, 0x316f, 0x5477, 0x633e, 0x6d2d,
+ 0x633f, 0x3a29, 0x6d2c, 0x633d, 0x6340, 0x3a36, 0x362e, 0x5038,
+ 0x3043, 0x6d2e, 0x6d2f, 0x4041, 0x6341, 0x4533, 0x6342, 0x5c32,
+ 0x6d30, 0x386a, 0x4e6c, 0x6a27, 0x5067, 0x4a79, 0x4856, 0x4f37,
+ 0x3349, 0x4e52, 0x3d64, 0x635e, 0x3b72, 0x6a28, 0x553d, 0x465d,
+ 0x6a29, 0x6a2a, 0x6a2c, 0x6a2b, 0x6a2e, 0x6a2d, 0x3d58, 0x6a2f,
+ 0x423e, 0x3441, 0x3477, 0x3b27, 0x6c66, 0x6c65, 0x373f, 0x4b79,
+ 0x3162, 0x6c67, 0x4948, 0x6c68, 0x6c69, 0x4a56, 0x5e50, 0x3245,
+ 0x547a, 0x464b, 0x3047, 0x3472, 0x4853, 0x4d50, 0x3f38, 0x3f5b,
+ 0x4724, 0x5634, 0x4029, 0x5e51, 0x4928, 0x516f, 0x4524, 0x3067,
+ 0x3336, 0x4845, 0x3062, 0x3776, 0x457a, 0x3673, 0x5552, 0x3350,
+ 0x3c3c, 0x332d, 0x3e71, 0x3051, 0x5256, 0x4a63, 0x5725, 0x4d36,
+ 0x3636, 0x3f39, 0x555b, 0x3827, 0x4557, 0x5e52, 0x3f59, 0x4255,
+ 0x4740, 0x3b24, 0x3128, 0x456a, 0x457b, 0x4c27, 0x3127, 0x3556,
+ 0x4428, 0x5e53, 0x513a, 0x3369, 0x4372, 0x3777, 0x5674, 0x3523,
+ 0x3270, 0x4434, 0x4469, 0x402d, 0x5e54, 0x3068, 0x4544, 0x4160,
+ 0x3955, 0x3e5c, 0x4d58, 0x304e, 0x4d4f, 0x5e56, 0x3e50, 0x573e,
+ 0x5e55, 0x5550, 0x305d, 0x4462, 0x4223, 0x3c70, 0x5335, 0x4039,
+ 0x4521, 0x3226, 0x5471, 0x4028, 0x4a43, 0x5e57, 0x557c, 0x3930,
+ 0x482d, 0x4b29, 0x5e59, 0x3f3d, 0x4634, 0x5727, 0x4a30, 0x4443,
+ 0x3356, 0x3952, 0x5638, 0x6a7c, 0x3034, 0x3f66, 0x4c74, 0x4d5a,
+ 0x563f, 0x424e, 0x4e4e, 0x4c22, 0x502e, 0x4453, 0x3532, 0x5e58,
+ 0x5575, 0x3c37, 0x3b53, 0x3024, 0x4532, 0x346c, 0x5571, 0x6a7d,
+ 0x5e5a, 0x4d26, 0x4d6c, 0x4e66, 0x5e5c, 0x4d31, 0x4026, 0x573d,
+ 0x5e5b, 0x3046, 0x3a34, 0x4953, 0x4473, 0x3e68, 0x3236, 0x404c,
+ 0x4b70, 0x3c71, 0x3b3b, 0x3537, 0x4575, 0x5e66, 0x5e63, 0x3e5d,
+ 0x5e5f, 0x3437, 0x3d5d, 0x5e60, 0x446d, 0x4f46, 0x3560, 0x365e,
+ 0x4a5a, 0x3574, 0x5e65, 0x5546, 0x5e61, 0x4c4d, 0x467e, 0x4545,
+ 0x5234, 0x3e72, 0x4253, 0x4c3d, 0x3338, 0x3d53, 0x3f58, 0x4d46,
+ 0x515a, 0x346b, 0x5e64, 0x5e5d, 0x5e67, 0x6a7e, 0x4230, 0x5e62,
+ 0x5640, 0x3527, 0x3274, 0x5e68, 0x5e72, 0x5e6d, 0x5e71, 0x4860,
+ 0x5761, 0x5e6f, 0x4368, 0x4c61, 0x3265, 0x523e, 0x5e6e, 0x5e6b,
+ 0x4e55, 0x3427, 0x3f2b, 0x3e3e, 0x3d52, 0x5e69, 0x542e, 0x5e5e,
+ 0x5e6a, 0x403f, 0x5e6c, 0x3273, 0x3869, 0x4227, 0x3d41, 0x5e75,
+ 0x5e78, 0x322b, 0x3424, 0x346a, 0x4926, 0x5e76, 0x4b51, 0x3863,
+ 0x5e77, 0x5e7a, 0x5e79, 0x4c42, 0x3061, 0x346e, 0x653a, 0x502f,
+ 0x326b, 0x6b21, 0x5e74, 0x4963, 0x5e73, 0x305a, 0x5221, 0x3177,
+ 0x4c2f, 0x5e70, 0x4b24, 0x552a, 0x5e7b, 0x345d, 0x4426, 0x5e7d,
+ 0x437e, 0x4421, 0x5f21, 0x414c, 0x5e7c, 0x3e6f, 0x4632, 0x3345,
+ 0x4876, 0x4b3a, 0x5e7e, 0x5f24, 0x5732, 0x3337, 0x4143, 0x474b,
+ 0x3225, 0x3469, 0x572b, 0x446c, 0x5f22, 0x5f23, 0x5f25, 0x3a33,
+ 0x5f26, 0x405e, 0x4943, 0x3259, 0x4766, 0x5f27, 0x475c, 0x5f28,
+ 0x6b22, 0x4b53, 0x5f2a, 0x5f29, 0x3241, 0x454a, 0x5f2b, 0x545c,
+ 0x4841, 0x5f2c, 0x3e70, 0x5f2d, 0x5627, 0x6a37, 0x6b36, 0x4a55,
+ 0x587c, 0x3844, 0x3925, 0x3745, 0x557e, 0x394a, 0x5027, 0x744d,
+ 0x3550, 0x4374, 0x3e48, 0x6b37, 0x303d, 0x3d4c, 0x4132, 0x3156,
+ 0x3328, 0x3852, 0x4922, 0x3658, 0x6b38, 0x3e34, 0x4a7d, 0x4743,
+ 0x557b, 0x3773, 0x4e44, 0x552b, 0x3173, 0x6c33, 0x305f, 0x6c35,
+ 0x3637, 0x414f, 0x757a, 0x5031, 0x5565, 0x4e53, 0x3d6f, 0x3362,
+ 0x382b, 0x5536, 0x6d3d, 0x364f, 0x4b39, 0x5042, 0x373d, 0x6c36,
+ 0x4a29, 0x4554, 0x6c39, 0x6c38, 0x4243, 0x6c37, 0x507d, 0x6c3a,
+ 0x6c3b, 0x5765, 0x6c3c, 0x6c3d, 0x466c, 0x4e5e, 0x3c48, 0x4855,
+ 0x3529, 0x3e49, 0x563c, 0x5467, 0x512e, 0x5071, 0x6a38, 0x6a39,
+ 0x6a3a, 0x3a35, 0x4a31, 0x3f75, 0x4d7a, 0x6a40, 0x303a, 0x6a3e,
+ 0x4025, 0x6a3b, 0x327d, 0x4377, 0x3b68, 0x5257, 0x4e74, 0x6a3f,
+ 0x6a3c, 0x6a43, 0x5047, 0x5333, 0x343a, 0x4341, 0x5772, 0x5551,
+ 0x4a47, 0x6a45, 0x6a44, 0x6a47, 0x6a46, 0x5667, 0x4f54, 0x6a4b,
+ 0x3b4e, 0x3d7a, 0x494e, 0x6a4c, 0x4939, 0x4f7e, 0x6a4a, 0x544e,
+ 0x6a4d, 0x6a4f, 0x4d6d, 0x6a49, 0x6a4e, 0x4e6e, 0x3b5e, 0x333f,
+ 0x4655, 0x3e30, 0x4e7a, 0x4767, 0x3e27, 0x6a50, 0x5647, 0x4140,
+ 0x545d, 0x6a51, 0x4f3e, 0x6a52, 0x4a6e, 0x452f, 0x3035, 0x6a54,
+ 0x6a53, 0x745f, 0x443a, 0x3129, 0x655f, 0x6a55, 0x4a6f, 0x6a56,
+ 0x6a57, 0x4658, 0x6a58, 0x6a59, 0x543b, 0x477a, 0x5237, 0x387c,
+ 0x6a42, 0x325c, 0x427c, 0x5478, 0x4c66, 0x576e, 0x5442, 0x5350,
+ 0x6b43, 0x4573, 0x377e, 0x6b54, 0x4b37, 0x6b5e, 0x404a, 0x4d7b,
+ 0x332f, 0x465a, 0x6b7c, 0x443e, 0x4e34, 0x4429, 0x313e, 0x547d,
+ 0x4a75, 0x566c, 0x4653, 0x3664, 0x3b7a, 0x5060, 0x4931, 0x5453,
+ 0x4828, 0x384b, 0x683e, 0x493c, 0x683b, 0x406e, 0x5053, 0x3244,
+ 0x3465, 0x683c, 0x5548, 0x3645, 0x683d, 0x4a78, 0x385c, 0x4c75,
+ 0x4034, 0x516e, 0x683f, 0x6842, 0x3a3c, 0x312d, 0x3d5c, 0x6a3d,
+ 0x6843, 0x6846, 0x684b, 0x684c, 0x4b49, 0x3065, 0x3c2b, 0x3939,
+ 0x6841, 0x4d77, 0x684a, 0x4e76, 0x556d, 0x4156, 0x6844, 0x4336,
+ 0x397b, 0x5626, 0x6848, 0x4a60, 0x5466, 0x6840, 0x6845, 0x6847,
+ 0x4739, 0x3763, 0x6849, 0x3f5d, 0x6852, 0x6857, 0x6855, 0x3c5c,
+ 0x3c4f, 0x685b, 0x685e, 0x685a, 0x317a, 0x3058, 0x4433, 0x384c,
+ 0x4662, 0x483e, 0x4861, 0x684f, 0x6854, 0x6856, 0x3971, 0x6858,
+ 0x5775, 0x447b, 0x685c, 0x3269, 0x6851, 0x3c6d, 0x3f42, 0x684d,
+ 0x5679, 0x4178, 0x3271, 0x685f, 0x4a41, 0x6859, 0x5524, 0x316a,
+ 0x553b, 0x684e, 0x6850, 0x3630, 0x6853, 0x685d, 0x4038, 0x4a77,
+ 0x4b28, 0x465c, 0x4075, 0x6869, 0x5023, 0x6872, 0x566a, 0x6860,
+ 0x6861, 0x5179, 0x3a4b, 0x3879, 0x3871, 0x5454, 0x686f, 0x686e,
+ 0x686c, 0x3970, 0x4c52, 0x6866, 0x4e26, 0x3f72, 0x3038, 0x6871,
+ 0x6870, 0x5740, 0x6864, 0x4d29, 0x4923, 0x3b38, 0x3d5b, 0x686a,
+ 0x6862, 0x6863, 0x6865, 0x3535, 0x6867, 0x4745, 0x686b, 0x686d,
+ 0x3d30, 0x572e, 0x6878, 0x6875, 0x4d30, 0x6876, 0x413a, 0x6868,
+ 0x4337, 0x3070, 0x6874, 0x6877, 0x3923, 0x4952, 0x434e, 0x4e60,
+ 0x4066, 0x4b73, 0x4c5d, 0x5035, 0x4a61, 0x6873, 0x3c6c, 0x6879,
+ 0x435e, 0x4665, 0x3977, 0x3074, 0x5758, 0x3c2c, 0x456f, 0x4c44,
+ 0x6926, 0x492d, 0x6922, 0x4062, 0x3f43, 0x687e, 0x3957, 0x687b,
+ 0x6924, 0x524e, 0x6923, 0x5632, 0x5735, 0x6927, 0x3d37, 0x687c,
+ 0x687d, 0x6921, 0x4d56, 0x522c, 0x6932, 0x6929, 0x342a, 0x343b,
+ 0x692b, 0x5028, 0x6925, 0x337e, 0x692c, 0x4063, 0x692a, 0x6939,
+ 0x6938, 0x692e, 0x687a, 0x6928, 0x3f2c, 0x6931, 0x693a, 0x4225,
+ 0x692f, 0x3845, 0x692d, 0x535c, 0x6934, 0x6935, 0x6937, 0x6947,
+ 0x4046, 0x6945, 0x6930, 0x693b, 0x3071, 0x693c, 0x5525, 0x693e,
+ 0x693f, 0x6941, 0x4171, 0x4836, 0x693d, 0x6942, 0x6943, 0x6933,
+ 0x6936, 0x3b31, 0x6940, 0x3c77, 0x6944, 0x6946, 0x694a, 0x694e,
+ 0x325b, 0x6948, 0x372e, 0x694b, 0x694c, 0x5541, 0x4423, 0x6958,
+ 0x3a61, 0x6949, 0x5323, 0x6954, 0x6957, 0x6950, 0x694f, 0x4741,
+ 0x6952, 0x6959, 0x3348, 0x6953, 0x4f70, 0x694d, 0x3377, 0x6956,
+ 0x695a, 0x4c34, 0x4f2d, 0x6955, 0x695c, 0x695b, 0x695e, 0x6951,
+ 0x695d, 0x695f, 0x434a, 0x4737, 0x344e, 0x3b36, 0x5040, 0x6c23,
+ 0x4537, 0x537b, 0x6c24, 0x6c25, 0x465b, 0x3f6e, 0x6c26, 0x6c27,
+ 0x502a, 0x4738, 0x3868, 0x6c28, 0x5639, 0x557d, 0x344b, 0x323d,
+ 0x4e64, 0x4667, 0x4d61, 0x3475, 0x4b40, 0x3c5f, 0x6962, 0x6963,
+ 0x516a, 0x6965, 0x3479, 0x6964, 0x5133, 0x4a62, 0x3250, 0x6968,
+ 0x6966, 0x6967, 0x5633, 0x6969, 0x696a, 0x696b, 0x696c, 0x6c2f,
+ 0x4539, 0x364e, 0x5273, 0x356e, 0x3b59, 0x6c31, 0x5263, 0x4e63,
+ 0x4438, 0x433f, 0x363e, 0x5839, 0x3148, 0x314f, 0x3151, 0x457e,
+ 0x3150, 0x432b, 0x5531, 0x6b24, 0x3a41, 0x4c3a, 0x6b25, 0x6b27,
+ 0x6b28, 0x6b26, 0x6b29, 0x6b2b, 0x6b2a, 0x6b2c, 0x4a4f, 0x5835,
+ 0x4371, 0x4325, 0x4678, 0x6b2d, 0x444a, 0x6b2e, 0x6b2f, 0x6b30,
+ 0x3755, 0x377a, 0x6b31, 0x4762, 0x6b33, 0x3a24, 0x5175, 0x3031,
+ 0x6b32, 0x6b34, 0x352a, 0x4248, 0x4768, 0x6b35, 0x4b2e, 0x635f,
+ 0x5340, 0x595b, 0x4d21, 0x562d, 0x4773, 0x5960, 0x3b63, 0x3a3a,
+ 0x6362, 0x4f2b, 0x6360, 0x4947, 0x3a39, 0x5134, 0x6361, 0x486a,
+ 0x392f, 0x3d2d, 0x3358, 0x4e5b, 0x4c40, 0x6368, 0x6369, 0x4d74,
+ 0x4c2d, 0x3c33, 0x636a, 0x636b, 0x505a, 0x467b, 0x375a, 0x475f,
+ 0x524a, 0x4e56, 0x6364, 0x636c, 0x4972, 0x3341, 0x6367, 0x4663,
+ 0x6365, 0x6d33, 0x6366, 0x4933, 0x4566, 0x3935, 0x433b, 0x6363,
+ 0x453d, 0x4124, 0x4259, 0x3257, 0x636d, 0x3b26, 0x442d, 0x6370,
+ 0x3e5a, 0x637b, 0x6375, 0x3a53, 0x3750, 0x534d, 0x564e, 0x5553,
+ 0x3941, 0x5534, 0x5158, 0x5039, 0x4776, 0x482a, 0x3234, 0x435a,
+ 0x636e, 0x637c, 0x636f, 0x3728, 0x6377, 0x6374, 0x373a, 0x4522,
+ 0x6376, 0x455d, 0x3228, 0x467c, 0x4460, 0x5722, 0x4061, 0x6379,
+ 0x637a, 0x637d, 0x4c29, 0x6373, 0x533e, 0x3143, 0x6d34, 0x6371,
+ 0x6372, 0x6378, 0x503a, 0x4643, 0x5473, 0x637e, 0x3d60, 0x6427,
+ 0x6426, 0x5173, 0x6423, 0x6429, 0x4877, 0x4f34, 0x6428, 0x642e,
+ 0x4265, 0x3634, 0x3d72, 0x6422, 0x3a69, 0x642a, 0x642c, 0x367d,
+ 0x565e, 0x6432, 0x642d, 0x6421, 0x3b6e, 0x4d5d, 0x4722, 0x4549,
+ 0x4177, 0x6424, 0x4733, 0x3d2c, 0x3d3d, 0x6425, 0x5747, 0x3262,
+ 0x642b, 0x3c43, 0x642f, 0x3b6b, 0x6430, 0x4528, 0x6431, 0x5563,
+ 0x3f23, 0x643a, 0x6437, 0x643b, 0x643d, 0x4656, 0x3a46, 0x404b,
+ 0x3821, 0x6434, 0x5421, 0x3a23, 0x3d7e, 0x643c, 0x4d3f, 0x4479,
+ 0x4f7b, 0x4966, 0x533f, 0x4f51, 0x6433, 0x6438, 0x6439, 0x4c69,
+ 0x4c4e, 0x4054, 0x6435, 0x4130, 0x6436, 0x4e50, 0x3b41, 0x3553,
+ 0x4873, 0x3d27, 0x5547, 0x492c, 0x3822, 0x644a, 0x644c, 0x5144,
+ 0x523a, 0x3a2d, 0x3a54, 0x6443, 0x356d, 0x574d, 0x6440, 0x4f7d,
+ 0x643f, 0x415c, 0x4c4a, 0x4a67, 0x4457, 0x4c54, 0x6448, 0x6447,
+ 0x6441, 0x6444, 0x352d, 0x5359, 0x6446, 0x5279, 0x3463, 0x3b34,
+ 0x496e, 0x343e, 0x3b6c, 0x514d, 0x4c6d, 0x6d35, 0x4765, 0x5428,
+ 0x644b, 0x5755, 0x6442, 0x3d25, 0x6445, 0x5366, 0x6449, 0x4978,
+ 0x643e, 0x5365, 0x477e, 0x3649, 0x547c, 0x3233, 0x6457, 0x4e42,
+ 0x644d, 0x4e3c, 0x385b, 0x6456, 0x3f4a, 0x534e, 0x436c, 0x4548,
+ 0x6458, 0x4d44, 0x644f, 0x6454, 0x6455, 0x3a7e, 0x4f66, 0x553f,
+ 0x6452, 0x6450, 0x644e, 0x4d65, 0x4a2a, 0x4023, 0x3d26, 0x6453,
+ 0x3848, 0x6467, 0x5434, 0x645b, 0x416f, 0x6469, 0x5267, 0x645f,
+ 0x6460, 0x4f2a, 0x4b5d, 0x645a, 0x6451, 0x6465, 0x485c, 0x6463,
+ 0x4467, 0x6462, 0x6461, 0x337c, 0x6468, 0x3561, 0x574c, 0x6466,
+ 0x3b2c, 0x5752, 0x4c4f, 0x6b78, 0x6464, 0x3976, 0x564d, 0x6459,
+ 0x645c, 0x427a, 0x645e, 0x424b, 0x4044, 0x4250, 0x3175, 0x4c32,
+ 0x354e, 0x646f, 0x462f, 0x4661, 0x6475, 0x4229, 0x406c, 0x515d,
+ 0x646e, 0x442e, 0x646d, 0x6476, 0x6474, 0x427e, 0x645d, 0x6470,
+ 0x4a7e, 0x5544, 0x6471, 0x517a, 0x646b, 0x646c, 0x6472, 0x4e2b,
+ 0x454b, 0x4731, 0x423a, 0x646a, 0x414a, 0x4c36, 0x3331, 0x647b,
+ 0x6473, 0x647a, 0x647d, 0x647c, 0x334e, 0x333a, 0x6477, 0x6479,
+ 0x6478, 0x456c, 0x403d, 0x5468, 0x6522, 0x3044, 0x6524, 0x6523,
+ 0x3c24, 0x6525, 0x6521, 0x647e, 0x3174, 0x6528, 0x6529, 0x6526,
+ 0x6527, 0x652a, 0x4659, 0x652b, 0x652d, 0x652c, 0x652f, 0x652e,
+ 0x3960, 0x6530, 0x6531, 0x3b70, 0x6c61, 0x4370, 0x3546, 0x3b52,
+ 0x4169, 0x546e, 0x3e44, 0x5746, 0x5456, 0x3253, 0x6c3e, 0x6a41,
+ 0x422f, 0x3436, 0x5157, 0x3334, 0x4832, 0x3f3b, 0x6c40, 0x564b,
+ 0x6c3f, 0x6c41, 0x6c45, 0x3e66, 0x4c3f, 0x455a, 0x3e3c, 0x6c46,
+ 0x317e, 0x6c44, 0x5528, 0x3563, 0x6c42, 0x4136, 0x3363, 0x6c43,
+ 0x4b38, 0x4043, 0x4c7e, 0x4152, 0x6c48, 0x3a66, 0x4053, 0x5672,
+ 0x514c, 0x3f3e, 0x3733, 0x4955, 0x6c47, 0x3b62, 0x4c4c, 0x3d7d,
+ 0x4848, 0x4f29, 0x4d69, 0x456b, 0x3769, 0x5149, 0x3a38, 0x6c49,
+ 0x6c4a, 0x3b40, 0x6c4b, 0x6c62, 0x313a, 0x3759, 0x3d39, 0x6c4c,
+ 0x5166, 0x6c4d, 0x483b, 0x6c51, 0x6c53, 0x3b4d, 0x3c65, 0x6c4f,
+ 0x4937, 0x433a, 0x6c63, 0x5555, 0x6c50, 0x5673, 0x6c52, 0x6c4e,
+ 0x6c54, 0x6c55, 0x493f, 0x4f28, 0x505c, 0x512c, 0x485b, 0x6c56,
+ 0x4e75, 0x4a6c, 0x6c5a, 0x6c59, 0x303e, 0x6c57, 0x6c58, 0x6c64,
+ 0x483c, 0x4147, 0x6c5c, 0x5160, 0x6c5b, 0x546f, 0x6c5d, 0x5b46,
+ 0x6c5e, 0x312c, 0x6c5f, 0x6c60, 0x5726, 0x4540, 0x6b3c, 0x302e,
+ 0x3e74, 0x3838, 0x522f, 0x3056, 0x3579, 0x5833, 0x4b2c, 0x635d,
+ 0x462c, 0x3066, 0x4546, 0x6b39, 0x6b3a, 0x6b3b, 0x5140, 0x4523,
+ 0x6a72, 0x4432, 0x4435, 0x404e, 0x6a73, 0x4441, 0x4e6f, 0x6a70,
+ 0x6a74, 0x497c, 0x4723, 0x4c58, 0x4e7e, 0x6a75, 0x6a76, 0x4f2c,
+ 0x4067, 0x6a77, 0x363f, 0x6a78, 0x6a79, 0x6a7a, 0x6a7b, 0x6a71,
+ 0x482e, 0x616b, 0x3738, 0x616c, 0x616d, 0x5734, 0x616e, 0x616f,
+ 0x534c, 0x6171, 0x3f71, 0x6170, 0x3552, 0x3137, 0x6173, 0x6172,
+ 0x3a7c, 0x6174, 0x3937, 0x3e51, 0x447c, 0x3a5d, 0x3d46, 0x6175,
+ 0x6177, 0x3640, 0x4f41, 0x4a28, 0x6176, 0x5578, 0x537c, 0x6178,
+ 0x617c, 0x6179, 0x617a, 0x406a, 0x617e, 0x6221, 0x4047, 0x617b,
+ 0x617d, 0x6225, 0x4154, 0x6223, 0x6228, 0x327e, 0x6222, 0x434d,
+ 0x3242, 0x6227, 0x6226, 0x6224, 0x6229, 0x622b, 0x5049, 0x566d,
+ 0x4328, 0x622c, 0x4f57, 0x622e, 0x3a6f, 0x6960, 0x622d, 0x622a,
+ 0x3b2b, 0x5433, 0x6230, 0x622f, 0x6961, 0x6231, 0x6232, 0x6233,
+ 0x4c21, 0x6234, 0x6235, 0x507e, 0x424a, 0x5371, 0x4d75, 0x6760,
+ 0x6761, 0x3e41, 0x426a, 0x6764, 0x6763, 0x4d66, 0x4335, 0x6762,
+ 0x3b37, 0x4f56, 0x4161, 0x6769, 0x6768, 0x6774, 0x3223, 0x676a,
+ 0x6766, 0x676c, 0x676b, 0x493a, 0x5564, 0x6765, 0x3729, 0x6767,
+ 0x676e, 0x6773, 0x5669, 0x676d, 0x6772, 0x6771, 0x3060, 0x6775,
+ 0x4772, 0x4045, 0x406d, 0x4170, 0x6770, 0x6776, 0x4b76, 0x6822,
+ 0x6821, 0x5741, 0x677a, 0x6779, 0x677b, 0x6777, 0x677e, 0x677d,
+ 0x677c, 0x4155, 0x4759, 0x457d, 0x4543, 0x476d, 0x6823, 0x6826,
+ 0x6825, 0x6827, 0x3a77, 0x6778, 0x6824, 0x4870, 0x492a, 0x6829,
+ 0x3965, 0x517e, 0x6828, 0x682a, 0x682d, 0x682e, 0x4127, 0x682f,
+ 0x6830, 0x682c, 0x6834, 0x682b, 0x6831, 0x6835, 0x6832, 0x6833,
+ 0x6837, 0x6836, 0x394f, 0x702c, 0x702d, 0x4630, 0x306a, 0x483f,
+ 0x4d5f, 0x4e4d, 0x6a31, 0x6a32, 0x463f, 0x3449, 0x6a33, 0x5567,
+ 0x5d79, 0x6a34, 0x6a35, 0x6a36, 0x384a, 0x5f30, 0x4975, 0x4c70,
+ 0x497a, 0x497b, 0x5343, 0x4b26, 0x3826, 0x702e, 0x3142, 0x6538,
+ 0x4c6f, 0x5349, 0x3c57, 0x496a, 0x3567, 0x4450, 0x3569, 0x6e2e,
+ 0x3b2d, 0x675e, 0x6e2f, 0x3329, 0x6e32, 0x6e31, 0x3d67, 0x6e30,
+ 0x4e37, 0x454f, 0x4174, 0x5b4e, 0x6e33, 0x5073, 0x4254, 0x4668,
+ 0x372c, 0x6e34, 0x336b, 0x3b7b, 0x6e35, 0x675c, 0x6e36, 0x3d2e,
+ 0x7162, 0x4a68, 0x5249, 0x705a, 0x705b, 0x705c, 0x4146, 0x386d,
+ 0x3e4e, 0x705e, 0x4531, 0x705d, 0x5171, 0x7060, 0x304c, 0x3d6a,
+ 0x525f, 0x705f, 0x342f, 0x3768, 0x7066, 0x7065, 0x4623, 0x7061,
+ 0x7062, 0x3443, 0x7063, 0x556e, 0x4c5b, 0x3e52, 0x3c32, 0x7068,
+ 0x7067, 0x7064, 0x3221, 0x5622, 0x5338, 0x3e37, 0x482c, 0x706a,
+ 0x5177, 0x564c, 0x3a5b, 0x7069, 0x363b, 0x4d34, 0x4626, 0x4121,
+ 0x706b, 0x706e, 0x706d, 0x7070, 0x706c, 0x3b3e, 0x706f, 0x4c35,
+ 0x7072, 0x3355, 0x3154, 0x7073, 0x7074, 0x7076, 0x3461, 0x7071,
+ 0x7077, 0x707a, 0x7078, 0x7075, 0x707d, 0x7079, 0x707c, 0x707e,
+ 0x7121, 0x4e41, 0x7124, 0x7123, 0x4176, 0x707b, 0x4a5d, 0x3471,
+ 0x3171, 0x4c31, 0x7126, 0x7127, 0x712c, 0x554e, 0x7129, 0x4833,
+ 0x7122, 0x712b, 0x7128, 0x7125, 0x712a, 0x3029, 0x712d, 0x712f,
+ 0x7131, 0x7130, 0x712e, 0x5122, 0x7132, 0x7133, 0x396f, 0x3547,
+ 0x3057, 0x3059, 0x546d, 0x3544, 0x3d54, 0x3b4a, 0x7027, 0x385e,
+ 0x7028, 0x3028, 0x7029, 0x4d6e, 0x702a, 0x702b, 0x4624, 0x5665,
+ 0x7164, 0x7165, 0x4373, 0x535b, 0x5651, 0x4568, 0x532f, 0x5266,
+ 0x6e41, 0x303b, 0x5535, 0x514e, 0x3c60, 0x3a50, 0x3f78, 0x3847,
+ 0x3541, 0x454c, 0x4a22, 0x434b, 0x6e42, 0x443f, 0x3622, 0x6d6c,
+ 0x4324, 0x5631, 0x4f60, 0x6d6f, 0x454e, 0x365c, 0x4a21, 0x6d6d,
+ 0x6d70, 0x6d71, 0x433c, 0x3f34, 0x6d6e, 0x6d74, 0x6d72, 0x5566,
+ 0x435f, 0x6d73, 0x6d76, 0x5523, 0x5123, 0x6d75, 0x4350, 0x6d77,
+ 0x3f74, 0x3e6c, 0x6d78, 0x4c77, 0x515b, 0x5745, 0x5576, 0x6d7c,
+ 0x6d7b, 0x6d79, 0x6d7a, 0x6d7d, 0x3e26, 0x4b2f, 0x6e21, 0x363d,
+ 0x6e22, 0x4440, 0x6d7e, 0x3d5e, 0x3247, 0x3643, 0x6e25, 0x583a,
+ 0x6e23, 0x6e26, 0x4369, 0x3372, 0x6e27, 0x6e24, 0x4f39, 0x6e28,
+ 0x4277, 0x6e29, 0x6e2a, 0x5e2b, 0x4633, 0x4746, 0x5675, 0x3549,
+ 0x4b32, 0x6e2b, 0x4d2b, 0x6e2c, 0x5530, 0x6e2d, 0x7644, 0x5b47,
+ 0x3423, 0x432c, 0x7166, 0x4a38, 0x5253, 0x562a, 0x6f72, 0x3e58,
+ 0x3d43, 0x6f73, 0x364c, 0x302b, 0x4a2f, 0x6d36, 0x6d37, 0x4e79,
+ 0x372f, 0x3f73, 0x6d38, 0x426b, 0x4930, 0x6d39, 0x4676, 0x3f33,
+ 0x6d3c, 0x4578, 0x5150, 0x5729, 0x6d3a, 0x6d3b, 0x5162, 0x6d3f,
+ 0x6d40, 0x6d44, 0x6d48, 0x6d46, 0x6d4e, 0x5568, 0x6d49, 0x6d47,
+ 0x6d3e, 0x4569, 0x4646, 0x4969, 0x5452, 0x6d41, 0x6d42, 0x6d43,
+ 0x6d45, 0x4079, 0x3421, 0x3968, 0x6d50, 0x6d51, 0x6d4a, 0x6d4f,
+ 0x4e78, 0x4b36, 0x6d4c, 0x6d4d, 0x4f75, 0x6d52, 0x4172, 0x5332,
+ 0x6d4b, 0x4837, 0x3c6f, 0x4570, 0x6d56, 0x356f, 0x4235, 0x302d,
+ 0x4b69, 0x312e, 0x6d54, 0x4d6b, 0x3562, 0x6d55, 0x6d53, 0x6d57,
+ 0x357a, 0x6d58, 0x6d59, 0x6d5c, 0x314c, 0x4576, 0x3c6e, 0x6d5a,
+ 0x4c3c, 0x326a, 0x6d5b, 0x446b, 0x3445, 0x3075, 0x6d5f, 0x405a,
+ 0x3468, 0x454d, 0x6d5d, 0x3f44, 0x6d5e, 0x4425, 0x6d60, 0x6d61,
+ 0x6d63, 0x4157, 0x3b47, 0x3d38, 0x6d62, 0x6d64, 0x6d66, 0x6d65,
+ 0x6d67, 0x4a3e, 0x6c6a, 0x4071, 0x4967, 0x6c6b, 0x466e, 0x6c6c,
+ 0x466d, 0x6c6d, 0x6c70, 0x5766, 0x6c73, 0x6c71, 0x6c6e, 0x6c6f,
+ 0x5723, 0x4971, 0x4b6e, 0x6c74, 0x6c72, 0x4f69, 0x6c76, 0x4631,
+ 0x3c40, 0x6c75, 0x353b, 0x3b76, 0x6c77, 0x5977, 0x3d7b, 0x423b,
+ 0x6c78, 0x6c79, 0x3823, 0x6c7a, 0x6c7b, 0x6c7c, 0x536d, 0x582e,
+ 0x406b, 0x475d, 0x3a4c, 0x5063, 0x4b3d, 0x4d3a, 0x3851, 0x317c,
+ 0x476f, 0x5656, 0x3f46, 0x436b, 0x6f75, 0x4358, 0x5762, 0x6f77,
+ 0x3353, 0x4758, 0x516d, 0x5648, 0x6f78, 0x6f76, 0x3b7d, 0x3346,
+ 0x3d55, 0x5246, 0x3b60, 0x4f21, 0x6f7c, 0x6f7b, 0x6f79, 0x334c,
+ 0x4954, 0x4b30, 0x6f7e, 0x305e, 0x5649, 0x6f7d, 0x336d, 0x7655,
+ 0x4e48, 0x7022, 0x7021, 0x353e, 0x3c5a, 0x3b7c, 0x3865, 0x4442,
+ 0x7023, 0x4b6b, 0x7026, 0x5128, 0x3e3f, 0x476e, 0x7136, 0x7137,
+ 0x3f55, 0x3429, 0x7138, 0x4d3b, 0x4754, 0x552d, 0x7139, 0x713a,
+ 0x474f, 0x5224, 0x564f, 0x713b, 0x3d51, 0x3430, 0x3e3d, 0x345c,
+ 0x4e51, 0x3f5f, 0x713d, 0x3f7a, 0x713c, 0x713f, 0x713e, 0x7140,
+ 0x7141, 0x417e, 0x4122, 0x4a7a, 0x553e, 0x3e3a, 0x3e39, 0x5542,
+ 0x3f22, 0x4d2f, 0x7135, 0x3d5f, 0x364b, 0x5671, 0x7343, 0x7344,
+ 0x384d, 0x7346, 0x7347, 0x304a, 0x7345, 0x7349, 0x4b71, 0x734b,
+ 0x5026, 0x314a, 0x7348, 0x734f, 0x3551, 0x7357, 0x7352, 0x7354,
+ 0x7353, 0x377b, 0x313f, 0x734e, 0x734a, 0x355a, 0x7350, 0x7351,
+ 0x7355, 0x734d, 0x3c63, 0x417d, 0x7356, 0x735a, 0x734c, 0x3548,
+ 0x3d6e, 0x735c, 0x3724, 0x3f70, 0x567e, 0x4d32, 0x3470, 0x325f,
+ 0x7358, 0x7359, 0x4938, 0x735d, 0x735e, 0x7361, 0x735f, 0x7363,
+ 0x7362, 0x735b, 0x3f6a, 0x336f, 0x7360, 0x4729, 0x3c72, 0x736b,
+ 0x393f, 0x7364, 0x322d, 0x3b7e, 0x4b63, 0x736d, 0x7369, 0x395c,
+ 0x736e, 0x7365, 0x7366, 0x736a, 0x4261, 0x736c, 0x736f, 0x7368,
+ 0x3c7d, 0x4f64, 0x7370, 0x7367, 0x7372, 0x572d, 0x462a, 0x7373,
+ 0x7371, 0x4228, 0x385d, 0x7375, 0x7374, 0x345b, 0x7376, 0x7377,
+ 0x7378, 0x403a, 0x4069, 0x4571, 0x737b, 0x737a, 0x3458, 0x737e,
+ 0x7379, 0x737c, 0x737d, 0x7421, 0x7423, 0x3b49, 0x7422, 0x7424,
+ 0x323e, 0x7426, 0x7425, 0x3c2e, 0x4357, 0x5961, 0x4060, 0x744c,
+ 0x5751, 0x375b, 0x744e, 0x4123, 0x4649, 0x3456, 0x5533, 0x7450,
+ 0x744f, 0x7451, 0x4b5a, 0x7452, 0x5441, 0x5660, 0x3760, 0x4138,
+ 0x413b, 0x7453, 0x3e2c, 0x3462, 0x7454, 0x7455, 0x3e2b, 0x7456,
+ 0x745b, 0x7457, 0x745a, 0x3a7d, 0x7458, 0x7459, 0x3862, 0x4c47,
+ 0x745c, 0x325a, 0x4353, 0x5463, 0x3f37, 0x745d, 0x4534, 0x7469,
+ 0x4f35, 0x4e49, 0x4b58, 0x4b77, 0x3d74, 0x574f, 0x405b, 0x5075,
+ 0x746a, 0x746b, 0x746c, 0x7763, 0x3731, 0x746d, 0x576b, 0x746e,
+ 0x6679, 0x3e40, 0x667a, 0x3a6c, 0x667b, 0x4f4b, 0x667c, 0x543c,
+ 0x3c36, 0x667d, 0x667e, 0x3c4d, 0x4852, 0x4e33, 0x6721, 0x343f,
+ 0x6722, 0x4934, 0x3859, 0x4449, 0x575d, 0x425a, 0x3757, 0x563d,
+ 0x4e46, 0x3744, 0x4526, 0x6723, 0x4f5f, 0x6724, 0x6725, 0x6726,
+ 0x4137, 0x5769, 0x4970, 0x4f38, 0x562f, 0x5655, 0x6727, 0x306d,
+ 0x6728, 0x6729, 0x495c, 0x526f, 0x3e2d, 0x672a, 0x3073, 0x485e,
+ 0x3d61, 0x672b, 0x4846, 0x672c, 0x3b66, 0x3878, 0x5124, 0x672d,
+ 0x4267, 0x3e78, 0x3d4a, 0x4d33, 0x672e, 0x672f, 0x3e6e, 0x5065,
+ 0x4b67, 0x4c50, 0x3c4c, 0x6730, 0x3c28, 0x5077, 0x6731, 0x5078,
+ 0x6732, 0x6733, 0x3442, 0x6734, 0x6735, 0x497e, 0x4e2c, 0x4360,
+ 0x6737, 0x3141, 0x3371, 0x6738, 0x6739, 0x575b, 0x5540, 0x673a,
+ 0x424c, 0x573a, 0x673b, 0x673c, 0x673d, 0x3c6a, 0x4365, 0x4042,
+ 0x673e, 0x673f, 0x3c29, 0x6740, 0x6741, 0x6736, 0x3650, 0x6742,
+ 0x6743, 0x6744, 0x3b3a, 0x355e, 0x4246, 0x3160, 0x6745, 0x5435,
+ 0x6746, 0x383f, 0x6748, 0x6747, 0x376c, 0x6749, 0x3278, 0x674a,
+ 0x674b, 0x674c, 0x674d, 0x674e, 0x674f, 0x6750, 0x5327, 0x4b75,
+ 0x6751, 0x6752, 0x6753, 0x6754, 0x4949, 0x6755, 0x6756, 0x6757,
+ 0x6758, 0x6759, 0x3d49, 0x675a, 0x733e, 0x3857, 0x4831, 0x733f,
+ 0x7340, 0x7341, 0x395e, 0x4d78, 0x5868, 0x3a31, 0x425e, 0x6e37,
+ 0x3723, 0x6e39, 0x6e38, 0x3055, 0x6e3b, 0x5556, 0x576f, 0x5643,
+ 0x6e3d, 0x4a70, 0x6e3c, 0x6e3e, 0x6e40, 0x6e3f, 0x5172, 0x473c,
+ 0x4340, 0x3861, 0x4167, 0x7446, 0x505f, 0x7447, 0x4f5b, 0x483a,
+ 0x7448, 0x7449, 0x744a, 0x744b, 0x597a, 0x387e, 0x6571, 0x5370,
+ 0x7460, 0x4e4c, 0x3361, 0x7134, 0x526e, 0x7461, 0x4f68, 0x7462,
+ 0x474c, 0x3554, 0x3464, 0x7464, 0x7463, 0x7465, 0x7466, 0x7467,
+ 0x3a32, 0x303f, 0x7468, 0x372d, 0x526d, 0x522b, 0x404f, 0x3f3c,
+ 0x6b23, 0x555f, 0x6a48, 0x7173, 0x3678, 0x4b23, 0x444d, 0x7167,
+ 0x7168, 0x387b, 0x7169, 0x3a44, 0x5445, 0x3052, 0x716a, 0x716b,
+ 0x716c, 0x716d, 0x716e, 0x716f, 0x7171, 0x7170, 0x4555, 0x7172,
+ 0x367a, 0x7174, 0x522e, 0x5e47, 0x4b4a, 0x335c, 0x3522, 0x3922,
+ 0x4474, 0x7175, 0x7176, 0x4144, 0x417b, 0x5630, 0x7177, 0x7178,
+ 0x412a, 0x4638, 0x3e5b, 0x7179, 0x344f, 0x717a, 0x6d32, 0x6d31,
+ 0x4b60, 0x525e, 0x4b41, 0x5558, 0x4862, 0x405f, 0x3c21, 0x6b41,
+ 0x5024, 0x5662, 0x3647, 0x3858, 0x6b40, 0x384e, 0x6b3f, 0x3326,
+ 0x3949, 0x562b, 0x3774, 0x374a, 0x3c67, 0x373e, 0x6b46, 0x6b47,
+ 0x3039, 0x3f4f, 0x6b45, 0x537d, 0x6b48, 0x6b49, 0x374e, 0x6b42,
+ 0x6b44, 0x4976, 0x5657, 0x554d, 0x5032, 0x6b4f, 0x4e38, 0x6b50,
+ 0x3528, 0x3133, 0x6b52, 0x4c25, 0x4556, 0x6b53, 0x6b51, 0x455f,
+ 0x6b4e, 0x4a24, 0x6b55, 0x307b, 0x3a7a, 0x5837, 0x7163, 0x6b4a,
+ 0x6b4b, 0x6b4c, 0x6b4d, 0x6b56, 0x6640, 0x6b59, 0x3f68, 0x5248,
+ 0x6b57, 0x6b5c, 0x386c, 0x6b58, 0x3d3a, 0x5058, 0x3037, 0x6b5d,
+ 0x445c, 0x562c, 0x3460, 0x4276, 0x3c39, 0x6b5a, 0x6b5b, 0x5460,
+ 0x466a, 0x4454, 0x6b5f, 0x4527, 0x5975, 0x3231, 0x6b64, 0x3d45,
+ 0x6b62, 0x6b63, 0x382c, 0x4d51, 0x6b65, 0x6b61, 0x4133, 0x4622,
+ 0x4c73, 0x6b66, 0x4030, 0x5238, 0x6b67, 0x382f, 0x382d, 0x6b68,
+ 0x473b, 0x4d73, 0x6b6a, 0x6b6b, 0x6b6d, 0x5048, 0x6b72, 0x6b6e,
+ 0x6b71, 0x4879, 0x517c, 0x6b6c, 0x6b69, 0x3839, 0x4f59, 0x4465,
+ 0x6b6f, 0x6b70, 0x4c5a, 0x4d48, 0x3072, 0x6b76, 0x6b75, 0x3232,
+ 0x3860, 0x6b77, 0x316c, 0x4c45, 0x4424, 0x4f25, 0x6b79, 0x6c22,
+ 0x4572, 0x6b7a, 0x4945, 0x625f, 0x6b7e, 0x4d4e, 0x6c21, 0x315b,
+ 0x5337, 0x525c, 0x6b7d, 0x6b7b, 0x333c, 0x6a30, 0x5754, 0x742b,
+ 0x3374, 0x5641, 0x5642, 0x5569, 0x3e4a, 0x7427, 0x5228, 0x7428,
+ 0x7429, 0x742a, 0x3e4b, 0x535f, 0x4960, 0x4961, 0x7342, 0x4a66,
+ 0x4c72, 0x6236, 0x4b34, 0x4e68, 0x565b, 0x742d, 0x742e, 0x742f,
+ 0x7432, 0x3a3d, 0x7433, 0x3063, 0x7430, 0x7431, 0x3d22, 0x3255,
+ 0x7436, 0x7437, 0x3666, 0x3230, 0x4f4f, 0x7434, 0x342c, 0x7435,
+ 0x7438, 0x7439, 0x4d27, 0x743a, 0x743b, 0x743c, 0x4b52, 0x743d,
+ 0x743e, 0x743f, 0x745e, 0x413c, 0x3c68, 0x492b, 0x515e, 0x6575,
+ 0x5c33, 0x5255, 0x5c34, 0x302c, 0x5c35, 0x3d5a, 0x5c39, 0x5842,
+ 0x5c37, 0x5373, 0x4956, 0x5c3a, 0x5c36, 0x5c3b, 0x4322, 0x5c3c,
+ 0x5c45, 0x5c3d, 0x4e5f, 0x5625, 0x5c4f, 0x5c4d, 0x5c52, 0x3d66,
+ 0x422b, 0x5c38, 0x5c4b, 0x5c4e, 0x5c3e, 0x3752, 0x3045, 0x5c47,
+ 0x503e, 0x5c41, 0x3b28, 0x373c, 0x5c4c, 0x5c46, 0x5c3f, 0x475b,
+ 0x513f, 0x5c40, 0x5c4a, 0x5c50, 0x4e2d, 0x5c42, 0x5c43, 0x5c48,
+ 0x5c49, 0x3254, 0x5c51, 0x4b55, 0x5437, 0x5c5b, 0x5c5f, 0x4c26,
+ 0x5c66, 0x4367, 0x5c5c, 0x3f41, 0x5c59, 0x307a, 0x3936, 0x5c65,
+ 0x5c53, 0x5c44, 0x5c56, 0x4874, 0x3f60, 0x493b, 0x313d, 0x5322,
+ 0x5c5a, 0x5c55, 0x463b, 0x5c5e, 0x5742, 0x432f, 0x3736, 0x4751,
+ 0x4329, 0x5c62, 0x5c58, 0x5c6b, 0x5c54, 0x5c5d, 0x3e25, 0x5c57,
+ 0x5c60, 0x5c63, 0x5c64, 0x5c78, 0x5c61, 0x5d22, 0x5c67, 0x3c6b,
+ 0x3444, 0x4323, 0x3267, 0x5c7a, 0x5c72, 0x5c6f, 0x5c7c, 0x5c6e,
+ 0x5270, 0x3268, 0x4857, 0x4863, 0x5c7b, 0x5c6d, 0x5c77, 0x5c75,
+ 0x3e23, 0x5c74, 0x325d, 0x5c73, 0x3c76, 0x5c68, 0x3b44, 0x4073,
+ 0x3c54, 0x5c69, 0x5c6a, 0x5c71, 0x5c76, 0x5c79, 0x3534, 0x4859,
+ 0x3b67, 0x5c7e, 0x5c7d, 0x532b, 0x5d21, 0x5d23, 0x5d25, 0x5271,
+ 0x5d24, 0x5d26, 0x5d27, 0x5229, 0x3a49, 0x5d29, 0x5d36, 0x5d31,
+ 0x5d34, 0x5d30, 0x464e, 0x4072, 0x492f, 0x5c6c, 0x5d2e, 0x5d37,
+ 0x5c70, 0x5d2f, 0x5d38, 0x5d2c, 0x5d39, 0x5d33, 0x5d2d, 0x442a,
+ 0x5d28, 0x4033, 0x412b, 0x5d2a, 0x5d2b, 0x5d32, 0x3b71, 0x5d35,
+ 0x5328, 0x5d3a, 0x5d3b, 0x4327, 0x5d52, 0x5d3c, 0x5d51, 0x393d,
+ 0x3e55, 0x3e7a, 0x3a4a, 0x5d4a, 0x5d45, 0x5d3f, 0x324b, 0x5d43,
+ 0x5d4b, 0x3224, 0x5d55, 0x5d3e, 0x4650, 0x5d50, 0x5d54, 0x4162,
+ 0x3746, 0x5d4e, 0x5d4f, 0x5d44, 0x5d3d, 0x5d4d, 0x4c51, 0x5d49,
+ 0x5d42, 0x4348, 0x463c, 0x4e2e, 0x5d4c, 0x5d48, 0x5d41, 0x5d46,
+ 0x425c, 0x5329, 0x532a, 0x5d53, 0x4f74, 0x4878, 0x5d66, 0x5d47,
+ 0x5d60, 0x4264, 0x5d61, 0x5d57, 0x5678, 0x5d59, 0x5d58, 0x3870,
+ 0x5d56, 0x464f, 0x362d, 0x5d62, 0x3a79, 0x5461, 0x5d67, 0x3450,
+ 0x5d5a, 0x3f7b, 0x5d63, 0x5d5f, 0x5d5d, 0x3559, 0x5d5b, 0x5d5c,
+ 0x5d5e, 0x3d2f, 0x5d64, 0x5d65, 0x5d75, 0x4349, 0x4b62, 0x5d72,
+ 0x5861, 0x4651, 0x5d74, 0x5574, 0x5d73, 0x5d70, 0x5d6c, 0x5d6f,
+ 0x5d68, 0x506e, 0x4858, 0x5d6e, 0x5d69, 0x5d6a, 0x4b72, 0x5d6d,
+ 0x314d, 0x4036, 0x3c3b, 0x5d71, 0x5d77, 0x5d76, 0x5d6b, 0x456e,
+ 0x5d7b, 0x5e24, 0x5e23, 0x5d78, 0x436f, 0x427b, 0x5561, 0x4e35,
+ 0x5d7d, 0x324c, 0x4468, 0x4a5f, 0x473e, 0x5d7a, 0x5d7c, 0x5d7e,
+ 0x5e22, 0x302a, 0x314e, 0x5e2c, 0x5e26, 0x3d36, 0x486f, 0x5e21,
+ 0x5e25, 0x5e29, 0x5e28, 0x5e27, 0x5e2d, 0x544c, 0x5e33, 0x5e2a,
+ 0x5e2e, 0x4059, 0x3121, 0x5e36, 0x5e31, 0x5e32, 0x5126, 0x5e35,
+ 0x5e2f, 0x5e30, 0x503d, 0x5e34, 0x4a6d, 0x5e39, 0x5e38, 0x5e37,
+ 0x5e3b, 0x3d65, 0x3258, 0x436a, 0x5e3a, 0x453a, 0x5e3c, 0x4c59,
+ 0x372a, 0x5465, 0x5e3d, 0x5e3f, 0x4422, 0x5e41, 0x5e3e, 0x5e40,
+ 0x553a, 0x5e42, 0x722e, 0x3b22, 0x4232, 0x4530, 0x4247, 0x722f,
+ 0x5069, 0x535d, 0x6b3d, 0x3366, 0x7230, 0x7231, 0x4a2d, 0x3a67,
+ 0x7233, 0x7235, 0x7234, 0x4b64, 0x4f3a, 0x7232, 0x4a34, 0x524f,
+ 0x426c, 0x4e43, 0x7238, 0x3076, 0x7237, 0x723e, 0x324f, 0x5141,
+ 0x723a, 0x723c, 0x5469, 0x723b, 0x7236, 0x723f, 0x723d, 0x7239,
+ 0x7247, 0x7244, 0x7246, 0x724a, 0x7242, 0x7240, 0x7245, 0x567b,
+ 0x7241, 0x4779, 0x495f, 0x7248, 0x3946, 0x3530, 0x7243, 0x7249,
+ 0x7250, 0x7256, 0x3b57, 0x7255, 0x4d5c, 0x566b, 0x7252, 0x7254,
+ 0x3872, 0x724b, 0x724e, 0x4279, 0x555d, 0x724c, 0x724d, 0x724f,
+ 0x7253, 0x7259, 0x533c, 0x366a, 0x4a71, 0x3764, 0x7257, 0x7258,
+ 0x725a, 0x725d, 0x725b, 0x725c, 0x5151, 0x7251, 0x4d49, 0x4e4f,
+ 0x5629, 0x7263, 0x435b, 0x7260, 0x402f, 0x726c, 0x725e, 0x7261,
+ 0x7268, 0x7262, 0x7267, 0x7266, 0x7269, 0x725f, 0x7264, 0x726a,
+ 0x532c, 0x7265, 0x3275, 0x7272, 0x502b, 0x7275, 0x3b48, 0x7279,
+ 0x7270, 0x7276, 0x7278, 0x727a, 0x7273, 0x7271, 0x3a7b, 0x357b,
+ 0x726f, 0x7277, 0x726d, 0x726e, 0x726b, 0x7326, 0x7323, 0x7322,
+ 0x7274, 0x485a, 0x727b, 0x7325, 0x4378, 0x727d, 0x7327, 0x7329,
+ 0x7324, 0x727c, 0x732b, 0x732a, 0x425d, 0x732e, 0x7330, 0x7321,
+ 0x7331, 0x732c, 0x732f, 0x727e, 0x732d, 0x7332, 0x7334, 0x7328,
+ 0x7333, 0x7335, 0x5037, 0x7338, 0x5979, 0x7339, 0x7337, 0x4864,
+ 0x7336, 0x733a, 0x733b, 0x3440, 0x6e43, 0x733c, 0x733d, 0x512a,
+ 0x742c, 0x5046, 0x5050, 0x515c, 0x4f4e, 0x3d56, 0x5143, 0x3a62,
+ 0x6169, 0x5242, 0x7142, 0x3239, 0x316d, 0x7143, 0x4940, 0x3344,
+ 0x5972, 0x4b25, 0x7144, 0x5654, 0x7145, 0x7440, 0x7146, 0x542c,
+ 0x7147, 0x3040, 0x7441, 0x7442, 0x347c, 0x455b, 0x4c3b, 0x5064,
+ 0x4d60, 0x7148, 0x5973, 0x313b, 0x4f2e, 0x3824, 0x714a, 0x714b,
+ 0x3243, 0x4151, 0x5730, 0x7149, 0x714c, 0x714e, 0x5976, 0x5261,
+ 0x5423, 0x7443, 0x4839, 0x7444, 0x714d, 0x714f, 0x3f63, 0x7150,
+ 0x7154, 0x7156, 0x7151, 0x4951, 0x4561, 0x4263, 0x397c, 0x7153,
+ 0x7155, 0x3953, 0x715b, 0x3a56, 0x307d, 0x7159, 0x7158, 0x7152,
+ 0x715a, 0x7157, 0x486c, 0x4d4a, 0x715d, 0x653d, 0x715c, 0x715e,
+ 0x715f, 0x4f65, 0x7445, 0x3d73, 0x7160, 0x7161, 0x4e77, 0x522a,
+ 0x717b, 0x3832, 0x3c7b, 0x395b, 0x3966, 0x4359, 0x4a53, 0x6a68,
+ 0x4040, 0x3e75, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d, 0x6a6e,
+ 0x6a6f, 0x3d47, 0x757b, 0x757d, 0x757e, 0x757c, 0x3d62, 0x7621,
+ 0x3425, 0x7622, 0x7623, 0x6c32, 0x5154, 0x596a, 0x7624, 0x6e3a,
+ 0x5532, 0x537e, 0x4c5c, 0x4a44, 0x6540, 0x7625, 0x3e2f, 0x4629,
+ 0x5a25, 0x3c46, 0x3629, 0x383c, 0x484f, 0x3c25, 0x5a26, 0x5a27,
+ 0x4c56, 0x4843, 0x5a28, 0x467d, 0x5135, 0x5269, 0x5136, 0x3c47,
+ 0x3d32, 0x3b64, 0x5a29, 0x5a2a, 0x5148, 0x5a2b, 0x506d, 0x366f,
+ 0x425b, 0x4b4f, 0x376d, 0x4968, 0x3743, 0x3e77, 0x5624, 0x5a2c,
+ 0x5a2d, 0x4640, 0x5767, 0x4a36, 0x5529, 0x4b5f, 0x556f, 0x5a2e,
+ 0x565f, 0x344a, 0x5a30, 0x5a2f, 0x526b, 0x5a31, 0x5a32, 0x5a33,
+ 0x4a54, 0x5a34, 0x4a2b, 0x5a35, 0x5a36, 0x334f, 0x566f, 0x5a37,
+ 0x3b30, 0x352e, 0x5a38, 0x5a39, 0x396e, 0x512f, 0x5268, 0x5a3a,
+ 0x3843, 0x4f6a, 0x326f, 0x5a3b, 0x5a3c, 0x3d6b, 0x4e5c, 0x536f,
+ 0x5a3d, 0x4e73, 0x5a3e, 0x5355, 0x3b65, 0x5a3f, 0x4b35, 0x4b50,
+ 0x5a40, 0x476b, 0x566e, 0x5a41, 0x4535, 0x3641, 0x5a42, 0x374c,
+ 0x3f4e, 0x5a43, 0x5a44, 0x4b2d, 0x5a45, 0x3577, 0x5a46, 0x4142,
+ 0x573b, 0x5a47, 0x4c38, 0x526a, 0x4431, 0x5a48, 0x357d, 0x3b51,
+ 0x5a49, 0x5033, 0x5a4a, 0x5a4b, 0x4e3d, 0x5a4c, 0x5a4d, 0x5a4e,
+ 0x3277, 0x5a51, 0x5a4f, 0x5168, 0x5a50, 0x4355, 0x5a52, 0x5a53,
+ 0x5a54, 0x5a55, 0x503b, 0x5225, 0x3079, 0x5a56, 0x472b, 0x5a57,
+ 0x3d77, 0x4321, 0x5a58, 0x5a59, 0x437d, 0x4c37, 0x5a5a, 0x5a5b,
+ 0x403e, 0x4657, 0x5a5c, 0x5a5d, 0x4734, 0x5a5e, 0x5a5f, 0x3948,
+ 0x3b6d, 0x3639, 0x7478, 0x7479, 0x4d63, 0x7539, 0x6b60, 0x4f73,
+ 0x3b3f, 0x3a40, 0x5425, 0x6159, 0x7574, 0x312a, 0x3272, 0x7575,
+ 0x7577, 0x3a51, 0x7576, 0x4332, 0x7579, 0x7578, 0x3134, 0x556a,
+ 0x383a, 0x3931, 0x3246, 0x5470, 0x4f4d, 0x305c, 0x554b, 0x3b75,
+ 0x564a, 0x3737, 0x4c30, 0x4636, 0x3161, 0x393a, 0x567c, 0x3961,
+ 0x3721, 0x3c7a, 0x6a5a, 0x6a5b, 0x4c79, 0x3973, 0x6a5c, 0x347b,
+ 0x4333, 0x3751, 0x3a58, 0x6a5d, 0x5474, 0x6a5e, 0x3c56, 0x3b5f,
+ 0x6a5f, 0x415e, 0x4238, 0x545f, 0x574a, 0x6a60, 0x6a61, 0x6a64,
+ 0x6a62, 0x6a63, 0x495e, 0x3833, 0x3644, 0x6a65, 0x4a6a, 0x494d,
+ 0x344d, 0x6259, 0x4562, 0x6a66, 0x4035, 0x5738, 0x6a67, 0x572c,
+ 0x487c, 0x5853, 0x584d, 0x545e, 0x5479, 0x4944, 0x532e, 0x3853,
+ 0x3360, 0x4962, 0x7476, 0x3a55, 0x7477, 0x575f, 0x7471, 0x3830,
+ 0x5554, 0x384f, 0x4670, 0x3343, 0x7472, 0x332c, 0x543d, 0x4777,
+ 0x7474, 0x7473, 0x4c4b, 0x4824, 0x7475, 0x5763, 0x453f, 0x7540,
+ 0x753b, 0x7543, 0x7542, 0x563a, 0x7541, 0x543e, 0x7544, 0x754c,
+ 0x304f, 0x3578, 0x7549, 0x754a, 0x455c, 0x7545, 0x7546, 0x7547,
+ 0x754b, 0x3e60, 0x7548, 0x387a, 0x7550, 0x7553, 0x3f67, 0x3972,
+ 0x753c, 0x754d, 0x4237, 0x4c78, 0x3c79, 0x754e, 0x754f, 0x7551,
+ 0x3665, 0x7552, 0x7555, 0x753d, 0x7554, 0x533b, 0x336c, 0x4c24,
+ 0x7556, 0x7557, 0x3e61, 0x7558, 0x4c5f, 0x755b, 0x3248, 0x5759,
+ 0x7559, 0x755a, 0x755c, 0x7562, 0x7560, 0x755f, 0x755d, 0x7561,
+ 0x755e, 0x7564, 0x7565, 0x4c63, 0x653f, 0x3538, 0x7563, 0x7568,
+ 0x4c23, 0x7566, 0x7567, 0x753e, 0x3144, 0x753f, 0x3545, 0x3264,
+ 0x756c, 0x7569, 0x3657, 0x756d, 0x756a, 0x756b, 0x345a, 0x546a,
+ 0x756e, 0x3379, 0x756f, 0x7571, 0x7570, 0x7572, 0x7573, 0x496d,
+ 0x392a, 0x477b, 0x3663, 0x4c49, 0x6a26, 0x3335, 0x547e, 0x396c,
+ 0x5079, 0x696d, 0x572a, 0x696e, 0x4256, 0x486d, 0x3a64, 0x696f,
+ 0x6970, 0x6971, 0x5661, 0x6972, 0x6973, 0x6975, 0x6974, 0x6976,
+ 0x6977, 0x4761, 0x6978, 0x5458, 0x6979, 0x3d4e, 0x697a, 0x697b,
+ 0x3d4f, 0x697c, 0x3828, 0x413e, 0x697d, 0x3132, 0x3b54, 0x3975,
+ 0x697e, 0x6a21, 0x6a22, 0x6a23, 0x3778, 0x3c2d, 0x4a64, 0x604e,
+ 0x542f, 0x4f3d, 0x5537, 0x6a24, 0x555e, 0x6a25, 0x5041, 0x393c,
+ 0x3447, 0x3159, 0x4031, 0x3166, 0x3167, 0x3168, 0x333d, 0x4868,
+ 0x6541, 0x315f, 0x4149, 0x346f, 0x4728, 0x5358, 0x4679, 0x5138,
+ 0x397d, 0x4275, 0x532d, 0x544b, 0x3d7c, 0x6542, 0x3735, 0x6543,
+ 0x3b39, 0x5562, 0x3d78, 0x5436, 0x4e25, 0x412c, 0x3359, 0x4c76,
+ 0x6546, 0x6544, 0x6548, 0x654a, 0x6547, 0x354f, 0x4648, 0x357c,
+ 0x6545, 0x4a76, 0x6549, 0x4354, 0x3145, 0x3c23, 0x5737, 0x4d4b,
+ 0x4b4d, 0x4a4a, 0x4c53, 0x654c, 0x654b, 0x4466, 0x5121, 0x5137,
+ 0x654d, 0x6550, 0x4d38, 0x5670, 0x654f, 0x355d, 0x4d3e, 0x6551,
+ 0x363a, 0x4d28, 0x3964, 0x4a45, 0x3351, 0x4b59, 0x546c, 0x6552,
+ 0x376a, 0x654e, 0x6555, 0x347e, 0x6556, 0x6553, 0x6554, 0x525d,
+ 0x425f, 0x3146, 0x5362, 0x365d, 0x4b6c, 0x6557, 0x5376, 0x3169,
+ 0x3674, 0x655a, 0x6558, 0x6559, 0x3540, 0x5245, 0x655c, 0x655e,
+ 0x655d, 0x4732, 0x5223, 0x655b, 0x5462, 0x555a, 0x6560, 0x5771,
+ 0x6561, 0x315c, 0x517b, 0x6562, 0x6564, 0x6563, 0x6565, 0x5258,
+ 0x354b, 0x675f, 0x5a75, 0x5a78, 0x5a76, 0x5a77, 0x5a7a, 0x504f,
+ 0x4447, 0x306e, 0x5030, 0x5a79, 0x534a, 0x3a2a, 0x5b22, 0x4771,
+ 0x5a7c, 0x5a7b, 0x495b, 0x5a7d, 0x5b21, 0x575e, 0x5a7e, 0x415a,
+ 0x5b25, 0x5374, 0x5b27, 0x5b24, 0x5b28, 0x3d3c, 0x4049, 0x5b23,
+ 0x5b26, 0x5623, 0x5b29, 0x5b2d, 0x5b2e, 0x5b2c, 0x3a42, 0x3f24,
+ 0x5b2b, 0x5b2a, 0x5447, 0x323f, 0x5b2f, 0x3979, 0x5b30, 0x333b,
+ 0x3526, 0x363c, 0x5b31, 0x3675, 0x5b32, 0x3149, 0x5b34, 0x5b33,
+ 0x5b35, 0x5b37, 0x5b36, 0x5b38, 0x5b39, 0x5b3a, 0x534f, 0x747a,
+ 0x4775, 0x5743, 0x4564, 0x747c, 0x747d, 0x747b, 0x3e46, 0x506f,
+ 0x3753, 0x544d, 0x4c2a, 0x7522, 0x7521, 0x3a28, 0x747e, 0x4b56,
+ 0x7524, 0x4052, 0x336a, 0x4d2a, 0x7525, 0x7523, 0x3d34, 0x7528,
+ 0x7529, 0x3d4d, 0x4338, 0x3f61, 0x4b61, 0x752a, 0x7526, 0x7527,
+ 0x4470, 0x752c, 0x343c, 0x576d, 0x3457, 0x752b, 0x752e, 0x752d,
+ 0x752f, 0x5051, 0x4351, 0x4829, 0x7530, 0x7531, 0x7532, 0x7533,
+ 0x7534, 0x7535, 0x7537, 0x7536, 0x7538, 0x3249, 0x5354, 0x4a4d,
+ 0x406f, 0x5658, 0x5230, 0x413f, 0x3d70, 0x382a, 0x3c78, 0x7646,
+ 0x7647, 0x7648, 0x7649, 0x764a, 0x764c, 0x764b, 0x7769, 0x764d,
+ 0x764e, 0x6e44, 0x6e45, 0x6e46, 0x556b, 0x3624, 0x6e48, 0x6e47,
+ 0x6e49, 0x6e4a, 0x4725, 0x6e4b, 0x6e4c, 0x3730, 0x3576, 0x6e4d,
+ 0x6e4f, 0x6e4e, 0x3846, 0x6e50, 0x6e51, 0x6e52, 0x365b, 0x332e,
+ 0x5653, 0x4446, 0x3135, 0x3856, 0x6e53, 0x6e54, 0x543f, 0x4755,
+ 0x3e7b, 0x4e59, 0x3933, 0x6e56, 0x6e55, 0x6e58, 0x6e57, 0x4525,
+ 0x6e59, 0x6e5a, 0x472e, 0x6e5b, 0x472f, 0x6e5c, 0x3227, 0x6e5d,
+ 0x6e5e, 0x6e5f, 0x6e60, 0x6e61, 0x576a, 0x6e62, 0x6e63, 0x3c58,
+ 0x6e64, 0x534b, 0x4c7a, 0x322c, 0x4165, 0x6e65, 0x4726, 0x432d,
+ 0x6e66, 0x6e67, 0x6e68, 0x6e69, 0x6e6a, 0x6e6b, 0x6e6c, 0x6e6d,
+ 0x6e6e, 0x6e6f, 0x6e70, 0x6e71, 0x6e72, 0x6e74, 0x6e73, 0x6e75,
+ 0x4d2d, 0x4241, 0x6e76, 0x6e77, 0x6e78, 0x5521, 0x6e79, 0x4f33,
+ 0x6e7a, 0x6e7b, 0x6e7c, 0x6e7d, 0x6f21, 0x6e7e, 0x6f22, 0x3875,
+ 0x437a, 0x6f23, 0x6f24, 0x3d42, 0x523f, 0x3279, 0x6f25, 0x6f26,
+ 0x6f27, 0x5278, 0x6f28, 0x567d, 0x6f29, 0x464c, 0x6f2a, 0x6f2b,
+ 0x4134, 0x6f2c, 0x4f7a, 0x4b78, 0x6f2e, 0x6f2d, 0x337a, 0x3978,
+ 0x6f2f, 0x6f30, 0x5062, 0x6f31, 0x6f32, 0x3766, 0x503f, 0x6f33,
+ 0x6f34, 0x6f35, 0x4871, 0x4c60, 0x6f36, 0x6f37, 0x6f38, 0x6f39,
+ 0x6f3a, 0x5560, 0x6f3b, 0x346d, 0x432a, 0x6f3c, 0x6f3d, 0x6f3e,
+ 0x6f3f, 0x4e7d, 0x6f40, 0x4260, 0x3438, 0x5736, 0x3d75, 0x4f47,
+ 0x6f43, 0x6f41, 0x6f42, 0x6f44, 0x3627, 0x3c7c, 0x3e62, 0x434c,
+ 0x6f45, 0x6f46, 0x6f47, 0x6f4f, 0x6f48, 0x6f49, 0x6f4a, 0x4742,
+ 0x6f71, 0x364d, 0x6f4b, 0x6f4c, 0x6f4d, 0x3646, 0x433e, 0x6f4e,
+ 0x6f50, 0x6f51, 0x6f52, 0x5572, 0x6f53, 0x4477, 0x6f54, 0x4478,
+ 0x6f55, 0x6f56, 0x3864, 0x3077, 0x6f57, 0x6f58, 0x6f59, 0x6f5a,
+ 0x6f5b, 0x6f5c, 0x6f5d, 0x6f5e, 0x3e35, 0x6f61, 0x6f5f, 0x6f60,
+ 0x6f62, 0x6f63, 0x414d, 0x6f64, 0x6f65, 0x6f66, 0x6f67, 0x6f68,
+ 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c, 0x4058, 0x6f6d, 0x412d, 0x6f6e,
+ 0x6f6f, 0x6f70, 0x4f62, 0x3324, 0x4345, 0x6345, 0x4941, 0x6346,
+ 0x3155, 0x4e4a, 0x3433, 0x4872, 0x6347, 0x4f50, 0x6348, 0x3c64,
+ 0x6349, 0x634a, 0x4346, 0x5522, 0x4456, 0x396b, 0x4e45, 0x634b,
+ 0x4376, 0x634c, 0x3727, 0x3873, 0x3a52, 0x634d, 0x634e, 0x5444,
+ 0x634f, 0x6350, 0x514b, 0x6351, 0x6352, 0x6353, 0x6354, 0x5156,
+ 0x6355, 0x327b, 0x403b, 0x6356, 0x402b, 0x6357, 0x6358, 0x6359,
+ 0x635a, 0x635b, 0x3837, 0x5a62, 0x3653, 0x5a64, 0x5a63, 0x5a66,
+ 0x486e, 0x5a65, 0x3740, 0x5174, 0x5275, 0x5573, 0x3d57, 0x5768,
+ 0x5a68, 0x5a67, 0x3022, 0x4d53, 0x5a69, 0x383d, 0x3c4a, 0x423d,
+ 0x4224, 0x3342, 0x5a6a, 0x422a, 0x4430, 0x3d35, 0x4f5e, 0x5a6b,
+ 0x4942, 0x315d, 0x5a6c, 0x3638, 0x543a, 0x337d, 0x5a6d, 0x5449,
+ 0x4f55, 0x4563, 0x5a6e, 0x5a6f, 0x5a70, 0x416a, 0x4c55, 0x4f5d,
+ 0x5367, 0x4221, 0x5a71, 0x4b65, 0x5a72, 0x4b66, 0x527e, 0x3874,
+ 0x5a73, 0x302f, 0x4f36, 0x554f, 0x4b6d, 0x5a74, 0x6344, 0x4125,
+ 0x763f, 0x7640, 0x7641, 0x4451, 0x4838, 0x5163, 0x505b, 0x5145,
+ 0x3c2f, 0x394d, 0x6f74, 0x3446, 0x533a, 0x7642, 0x337b, 0x7643,
+ 0x3571, 0x7645, 0x536a, 0x7627, 0x5129, 0x7629, 0x7628, 0x4163,
+ 0x4057, 0x3122, 0x4e6d, 0x5068, 0x762b, 0x4f76, 0x762a, 0x5570,
+ 0x762c, 0x4339, 0x3b74, 0x762e, 0x762d, 0x445e, 0x4158, 0x4b2a,
+ 0x4f3c, 0x762f, 0x7630, 0x7631, 0x4236, 0x3054, 0x4579, 0x7632,
+ 0x4760, 0x7626, 0x3e38, 0x3e32, 0x3565, 0x3747, 0x3f3f, 0x4352,
+ 0x4366, 0x584c, 0x386f, 0x3d79, 0x5125, 0x3050, 0x7730, 0x7731,
+ 0x502c, 0x3030, 0x7732, 0x7733, 0x7734, 0x474a, 0x3e4f, 0x7737,
+ 0x7736, 0x315e, 0x7735, 0x7738, 0x7739, 0x4e24, 0x484d, 0x3a2b,
+ 0x6838, 0x6839, 0x683a, 0x3e42, 0x5274, 0x544f, 0x4958, 0x5233,
+ 0x3625, 0x476a, 0x717c, 0x4f6e, 0x4b33, 0x506b, 0x676f, 0x4d67,
+ 0x394b, 0x3659, 0x717d, 0x3064, 0x4b4c, 0x717e, 0x5424, 0x422d,
+ 0x416c, 0x4644, 0x3e31, 0x7221, 0x3c55, 0x7222, 0x7223, 0x7224,
+ 0x5243, 0x4635, 0x4d47, 0x7225, 0x5331, 0x3f45, 0x4c62, 0x7226,
+ 0x7227, 0x5155, 0x366e, 0x7228, 0x7229, 0x355f, 0x722a, 0x722b,
+ 0x327c, 0x722c, 0x722d, 0x4827, 0x3767, 0x6c29, 0x6c2a, 0x6c2b,
+ 0x6c2c, 0x462e, 0x6c2d, 0x6c2e, 0x3749, 0x4a33, 0x6238, 0x774f,
+ 0x7750, 0x324d, 0x7751, 0x7753, 0x7752, 0x623b, 0x3c22, 0x623c,
+ 0x623d, 0x623e, 0x623f, 0x6240, 0x6241, 0x3739, 0x527b, 0x3d24,
+ 0x4a4e, 0x3125, 0x4b47, 0x6242, 0x367c, 0x4844, 0x6243, 0x3d48,
+ 0x317d, 0x6244, 0x3676, 0x6245, 0x4459, 0x6246, 0x4f5a, 0x395d,
+ 0x6247, 0x4021, 0x6248, 0x3276, 0x6249, 0x4173, 0x624a, 0x624b,
+ 0x4278, 0x624c, 0x624d, 0x624e, 0x4a57, 0x5838, 0x5965, 0x4f63,
+ 0x7025, 0x5c30, 0x426d, 0x5426, 0x4d54, 0x5131, 0x335b, 0x477d,
+ 0x3235, 0x423f, 0x6660, 0x4a3b, 0x6661, 0x6662, 0x3e54, 0x6663,
+ 0x5724, 0x4d55, 0x6665, 0x3c5d, 0x6664, 0x6666, 0x6667, 0x426e,
+ 0x3d3e, 0x6668, 0x4266, 0x3a27, 0x6669, 0x666a, 0x3352, 0x5169,
+ 0x3f25, 0x666b, 0x466f, 0x666c, 0x666d, 0x666e, 0x462d, 0x666f,
+ 0x4927, 0x6670, 0x6671, 0x6672, 0x6539, 0x6673, 0x6674, 0x4262,
+ 0x6675, 0x6676, 0x5668, 0x6677, 0x6678, 0x3947, 0x773b, 0x773a,
+ 0x773e, 0x773c, 0x3a21, 0x773f, 0x7740, 0x7742, 0x7741, 0x7744,
+ 0x7743, 0x7745, 0x7746, 0x7747, 0x4b68, 0x385f, 0x7754, 0x7755,
+ 0x7756, 0x7758, 0x775a, 0x7757, 0x775b, 0x7759, 0x5757, 0x775c,
+ 0x775d, 0x775e, 0x775f, 0x7760, 0x5b4b, 0x582a, 0x6577, 0x396d,
+ 0x3f7d, 0x3b6a, 0x7749, 0x4647, 0x7748, 0x774a, 0x774c, 0x774b,
+ 0x774d, 0x4e3a, 0x774e, 0x4427, 0x5363, 0x764f, 0x4233, 0x7650,
+ 0x7651, 0x7652, 0x7653, 0x7654, 0x7656, 0x312b, 0x7657, 0x7658,
+ 0x7659, 0x765a, 0x765b, 0x765c, 0x765d, 0x765e, 0x4f4a, 0x765f,
+ 0x7660, 0x7661, 0x7662, 0x7663, 0x7664, 0x4070, 0x7665, 0x7666,
+ 0x7667, 0x7668, 0x7669, 0x766a, 0x766b, 0x766c, 0x766d, 0x766e,
+ 0x766f, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x3e28, 0x7675,
+ 0x7676, 0x7677, 0x7678, 0x487a, 0x7679, 0x767a, 0x767b, 0x767c,
+ 0x767d, 0x767e, 0x7721, 0x7722, 0x7723, 0x7724, 0x7725, 0x7726,
+ 0x7727, 0x7728, 0x316e, 0x7729, 0x772a, 0x772b, 0x772c, 0x772d,
+ 0x415b, 0x772e, 0x772f, 0x4471, 0x702f, 0x3c26, 0x7030, 0x4379,
+ 0x4538, 0x513b, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x513c,
+ 0x516c, 0x7037, 0x7036, 0x5427, 0x4d52, 0x7038, 0x703a, 0x7039,
+ 0x703b, 0x703c, 0x386b, 0x703d, 0x3a68, 0x703e, 0x703f, 0x3e69,
+ 0x7040, 0x366c, 0x7041, 0x7042, 0x7043, 0x7044, 0x4835, 0x7045,
+ 0x7046, 0x7047, 0x4574, 0x7048, 0x7049, 0x704a, 0x773d, 0x704b,
+ 0x704c, 0x704d, 0x704e, 0x704f, 0x3a57, 0x7050, 0x7051, 0x7052,
+ 0x7053, 0x7054, 0x7055, 0x7056, 0x7058, 0x5325, 0x7057, 0x7059,
+ 0x753a, 0x4239, 0x7764, 0x7765, 0x7766, 0x7767, 0x7768, 0x4234,
+ 0x776a, 0x776b, 0x4273, 0x7470, 0x746f, 0x4269, 0x7761, 0x7762,
+ 0x3b46, 0x5964, 0x4a72, 0x4068, 0x7024, 0x3a5a, 0x472d, 0x442c,
+ 0x776c, 0x776d, 0x776e, 0x7770, 0x776f, 0x7771, 0x7774, 0x7773,
+ 0x7772, 0x7775, 0x7776, 0x6d69, 0x6d6a, 0x6d6b, 0x763c, 0x763d,
+ 0x763e, 0x3626, 0x583e, 0x3944, 0x583b, 0x5c31, 0x4a73, 0x7777,
+ 0x7778, 0x7779, 0x777b, 0x777a, 0x3147, 0x777c, 0x777d, 0x777e,
+ 0x466b, 0x6c34, 0x335d, 0x7633, 0x7634, 0x4164, 0x7635, 0x7636,
+ 0x7637, 0x7638, 0x7639, 0x763a, 0x4823, 0x763b, 0x417a, 0x3928,
+ 0x6d68, 0x396a, 0x595f, 0x2321, 0x2322, 0x2323, 0x2167, 0x2325,
+ 0x2326, 0x2327, 0x2328, 0x2329, 0x232a, 0x232b, 0x232c, 0x232d,
+ 0x232e, 0x232f, 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335,
+ 0x2336, 0x2337, 0x2338, 0x2339, 0x233a, 0x233b, 0x233c, 0x233d,
+ 0x233e, 0x233f, 0x2340, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345,
+ 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d,
+ 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355,
+ 0x2356, 0x2357, 0x2358, 0x2359, 0x235a, 0x235b, 0x235c, 0x235d,
+ 0x235e, 0x235f, 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365,
+ 0x2366, 0x2367, 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d,
+ 0x236e, 0x236f, 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375,
+ 0x2376, 0x2377, 0x2378, 0x2379, 0x237a, 0x237b, 0x237c, 0x237d,
+ 0x212b, 0x2169, 0x216a, 0x237e, 0x2324,
+};
+
+static const Summary16 gb2312_uni2indx_page00[70] = {
+ /* 0x0000 */
+ {0, 0x0000}, {0, 0x0000}, {0, 0x0000}, {0, 0x0000},
+ {0, 0x0000}, {0, 0x0000}, {0, 0x0000}, {0, 0x0000},
+ {0, 0x0000}, {0, 0x0000}, {0, 0x0190}, {3, 0x0003},
+ {5, 0x0000}, {5, 0x0080}, {6, 0x3703}, {13, 0x168c},
+ /* 0x0100 */
+ {19, 0x0002}, {20, 0x0808}, {22, 0x0800}, {23, 0x0000},
+ {23, 0x2000}, {24, 0x0000}, {24, 0x0800}, {25, 0x0000},
+ {25, 0x0000}, {25, 0x0000}, {25, 0x0000}, {25, 0x0000},
+ {25, 0x4000}, {26, 0x1555}, {33, 0x0000}, {33, 0x0000},
+ /* 0x0200 */
+ {33, 0x0000}, {33, 0x0000}, {33, 0x0000}, {33, 0x0000},
+ {33, 0x0000}, {33, 0x0000}, {33, 0x0000}, {33, 0x0000},
+ {33, 0x0000}, {33, 0x0000}, {33, 0x0000}, {33, 0x0000},
+ {33, 0x0280}, {35, 0x0000}, {35, 0x0000}, {35, 0x0000},
+ /* 0x0300 */
+ {35, 0x0000}, {35, 0x0000}, {35, 0x0000}, {35, 0x0000},
+ {35, 0x0000}, {35, 0x0000}, {35, 0x0000}, {35, 0x0000},
+ {35, 0x0000}, {35, 0xfffe}, {50, 0x03fb}, {59, 0xfffe},
+ {74, 0x03fb}, {83, 0x0000}, {83, 0x0000}, {83, 0x0000},
+ /* 0x0400 */
+ {83, 0x0002}, {84, 0xffff}, {100, 0xffff}, {116, 0xffff},
+ {132, 0xffff}, {148, 0x0002},
+};
+static const Summary16 gb2312_uni2indx_page20[101] = {
+ /* 0x2000 */
+ {149, 0x0000}, {149, 0x3360}, {155, 0x0040}, {156, 0x080d},
+ {160, 0x0000}, {160, 0x0000}, {160, 0x0000}, {160, 0x0000},
+ {160, 0x0000}, {160, 0x0000}, {160, 0x0000}, {160, 0x0000},
+ {160, 0x0000}, {160, 0x0000}, {160, 0x0000}, {160, 0x0000},
+ /* 0x2100 */
+ {160, 0x0008}, {161, 0x0040}, {162, 0x0000}, {162, 0x0000},
+ {162, 0x0000}, {162, 0x0000}, {162, 0x0fff}, {174, 0x0000},
+ {174, 0x0000}, {174, 0x000f}, {178, 0x0000}, {178, 0x0000},
+ {178, 0x0000}, {178, 0x0000}, {178, 0x0000}, {178, 0x0000},
+ /* 0x2200 */
+ {178, 0x8100}, {180, 0x6402}, {184, 0x4fa1}, {192, 0x20f0},
+ {197, 0x1100}, {199, 0x0000}, {199, 0xc033}, {205, 0x0000},
+ {205, 0x0000}, {205, 0x0200}, {206, 0x0020}, {207, 0x0000},
+ {207, 0x0000}, {207, 0x0000}, {207, 0x0000}, {207, 0x0000},
+ /* 0x2300 */
+ {207, 0x0000}, {207, 0x0004}, {208, 0x0000}, {208, 0x0000},
+ {208, 0x0000}, {208, 0x0000}, {208, 0x0000}, {208, 0x0000},
+ {208, 0x0000}, {208, 0x0000}, {208, 0x0000}, {208, 0x0000},
+ {208, 0x0000}, {208, 0x0000}, {208, 0x0000}, {208, 0x0000},
+ /* 0x2400 */
+ {208, 0x0000}, {208, 0x0000}, {208, 0x0000}, {208, 0x0000},
+ {208, 0x0000}, {208, 0x0000}, {208, 0x03ff}, {218, 0xfff0},
+ {230, 0xffff}, {246, 0x0fff}, {258, 0x0000}, {258, 0x0000},
+ {258, 0x0000}, {258, 0x0000}, {258, 0x0000}, {258, 0x0000},
+ /* 0x2500 */
+ {258, 0xffff}, {274, 0xffff}, {290, 0xffff}, {306, 0xffff},
+ {322, 0x0fff}, {334, 0x0000}, {334, 0x0000}, {334, 0x0000},
+ {334, 0x0000}, {334, 0x0000}, {334, 0x0003}, {336, 0x000c},
+ {338, 0xc8c0}, {343, 0x0000}, {343, 0x0000}, {343, 0x0000},
+ /* 0x2600 */
+ {343, 0x0060}, {345, 0x0000}, {345, 0x0000}, {345, 0x0000},
+ {345, 0x0005},
+};
+static const Summary16 gb2312_uni2indx_page30[35] = {
+ /* 0x3000 */
+ {347, 0xff2f}, {360, 0x00fb}, {367, 0x0000}, {367, 0x0000},
+ {367, 0xfffe}, {382, 0xffff}, {398, 0xffff}, {414, 0xffff},
+ {430, 0xffff}, {446, 0x000f}, {450, 0xfffe}, {465, 0xffff},
+ {481, 0xffff}, {497, 0xffff}, {513, 0xffff}, {529, 0x087f},
+ /* 0x3100 */
+ {537, 0xffe0}, {548, 0xffff}, {564, 0x03ff}, {574, 0x0000},
+ {574, 0x0000}, {574, 0x0000}, {574, 0x0000}, {574, 0x0000},
+ {574, 0x0000}, {574, 0x0000}, {574, 0x0000}, {574, 0x0000},
+ {574, 0x0000}, {574, 0x0000}, {574, 0x0000}, {574, 0x0000},
+ /* 0x3200 */
+ {574, 0x0000}, {574, 0x0000}, {574, 0x03ff},
+};
+static const Summary16 gb2312_uni2indx_page4e[1263] = {
+ /* 0x4e00 */
+ {584, 0x7f8b}, {595, 0x7f7b}, {608, 0x3db4}, {617, 0xef55},
+ {628, 0xfba8}, {638, 0xf35d}, {649, 0x0243}, {653, 0x400b},
+ {657, 0xfb40}, {665, 0x8d3e}, {674, 0x7bf7}, {687, 0x8c2c},
+ {693, 0x6eff}, {706, 0xe3fa}, {717, 0x1d3a}, {725, 0xa8ed},
+ /* 0x4f00 */
+ {734, 0xe602}, {740, 0xcf83}, {749, 0x8cf5}, {758, 0x3555},
+ {766, 0xe048}, {771, 0xffab}, {784, 0x92b9}, {792, 0xd859},
+ {800, 0xab18}, {807, 0x2892}, {812, 0xd7e9}, {823, 0x8020},
+ {825, 0xc438}, {831, 0xf583}, {840, 0xe74a}, {849, 0x450a},
+ /* 0x5000 */
+ {854, 0xb000}, {857, 0x9714}, {864, 0x7762}, {873, 0x5400},
+ {876, 0xd188}, {882, 0x1420}, {885, 0x1020}, {887, 0xc8c0},
+ {892, 0x2121}, {896, 0x0000}, {896, 0x13a8}, {902, 0x0c04},
+ {905, 0x8000}, {906, 0x0440}, {908, 0x70c0}, {913, 0x0828},
+ /* 0x5100 */
+ {916, 0x08c0}, {919, 0x0004}, {920, 0x0002}, {921, 0x8000},
+ {922, 0x2b7b}, {932, 0x1472}, {938, 0x7924}, {945, 0x3bfb},
+ {957, 0x3327}, {965, 0x1ae4}, {972, 0x9835}, {979, 0x38ef},
+ {989, 0x9ad1}, {997, 0x2802}, {1000, 0xa813}, {1006, 0xbf69},
+ /* 0x5200 */
+ {1017, 0x65cf}, {1027, 0x2fc6}, {1036, 0x6b11}, {1043, 0xafc9},
+ {1053, 0x340f}, {1060, 0x5053}, {1066, 0x86a2}, {1072, 0xa004},
+ {1075, 0x0106}, {1078, 0xe809}, {1084, 0x3f0f}, {1094, 0xc00e},
+ {1099, 0x0a88}, {1103, 0x8145}, {1108, 0x0010}, {1109, 0xc601},
+ /* 0x5300 */
+ {1114, 0xa161}, {1120, 0x26e1}, {1127, 0x444b}, {1133, 0xce00},
+ {1138, 0xc7aa}, {1147, 0xd4ee}, {1157, 0xcadf}, {1168, 0x85bb},
+ {1177, 0x3a74}, {1185, 0xa520}, {1190, 0x436c}, {1197, 0x8840},
+ {1200, 0x3f06}, {1208, 0x8bd2}, {1216, 0xff79}, {1229, 0x3bef},
+ /* 0x5400 */
+ {1241, 0xf75a}, {1252, 0xe8ef}, {1263, 0xfbcb}, {1275, 0x5b36},
+ {1284, 0x0d49}, {1290, 0x1bfd}, {1301, 0x0154}, {1305, 0x39ee},
+ {1315, 0xd855}, {1323, 0x2e75}, {1332, 0xbfd8}, {1343, 0xa91a},
+ {1350, 0xf3d7}, {1362, 0xf6bf}, {1375, 0x67e0}, {1383, 0xb40c},
+ /* 0x5500 */
+ {1389, 0x82c2}, {1394, 0x0813}, {1398, 0xd49d}, {1407, 0xd08b},
+ {1414, 0x065a}, {1420, 0x1061}, {1424, 0x74f2}, {1433, 0x59e0},
+ {1440, 0x8f9f}, {1451, 0xb312}, {1458, 0x0080}, {1459, 0x6aaa},
+ {1467, 0x3230}, {1472, 0xb05e}, {1480, 0x9d7a}, {1490, 0x60ac},
+ /* 0x5600 */
+ {1496, 0xd303}, {1503, 0xc900}, {1507, 0x3098}, {1512, 0x8a56},
+ {1519, 0x7000}, {1522, 0x1390}, {1527, 0x1f14}, {1534, 0x1842},
+ {1538, 0xc060}, {1542, 0x0008}, {1543, 0x8008}, {1545, 0x1080},
+ {1547, 0x0400}, {1548, 0xec90}, {1555, 0x2817}, {1561, 0xe633},
+ /* 0x5700 */
+ {1570, 0x0758}, {1576, 0x9000}, {1578, 0xf708}, {1586, 0x4e09},
+ {1592, 0xf485}, {1600, 0xfc83}, {1609, 0xaf53}, {1619, 0x18c8},
+ {1624, 0x187c}, {1631, 0x080c}, {1634, 0x6adf}, {1645, 0x0114},
+ {1648, 0xc80c}, {1653, 0xa734}, {1661, 0xa011}, {1665, 0x2710},
+ /* 0x5800 */
+ {1670, 0x28c5}, {1676, 0x4222}, {1680, 0x0413}, {1684, 0x0021},
+ {1686, 0x3010}, {1689, 0x4112}, {1693, 0x1820}, {1696, 0x4000},
+ {1697, 0x022b}, {1702, 0xc60c}, {1708, 0x0300}, {1710, 0x1000},
+ {1711, 0x0022}, {1713, 0x0022}, {1715, 0x5810}, {1719, 0x0249},
+ /* 0x5900 */
+ {1723, 0xa094}, {1728, 0x9670}, {1735, 0xeeb0}, {1744, 0x1792},
+ {1751, 0xcb96}, {1760, 0x05f2}, {1767, 0x0025}, {1770, 0x2358},
+ {1776, 0x25de}, {1785, 0x42cc}, {1791, 0xcf38}, {1800, 0x4a04},
+ {1804, 0x0c40}, {1807, 0x359f}, {1817, 0x1128}, {1821, 0x8a00},
+ /* 0x5a00 */
+ {1824, 0x13fa}, {1833, 0x910a}, {1838, 0x0229}, {1842, 0x1056},
+ {1847, 0x0641}, {1851, 0x0420}, {1853, 0x0484}, {1856, 0x84f0},
+ {1862, 0x0000}, {1862, 0x0c04}, {1865, 0x0400}, {1866, 0x412c},
+ {1871, 0x1206}, {1875, 0x1154}, {1880, 0x0a4b}, {1886, 0x0002},
+ /* 0x5b00 */
+ {1887, 0x0200}, {1888, 0x00c0}, {1890, 0x0000}, {1890, 0x0094},
+ {1893, 0x0001}, {1894, 0xbfbb}, {1907, 0x167c}, {1915, 0x242b},
+ {1921, 0x9bbb}, {1932, 0x7fa8}, {1942, 0x0c7f}, {1951, 0xe379},
+ {1961, 0x10f4}, {1967, 0xe00d}, {1973, 0x4132}, {1978, 0x9f01},
+ /* 0x5c00 */
+ {1985, 0x8652}, {1991, 0x3572}, {1999, 0x10b4}, {2004, 0xff12},
+ {2014, 0xcf27}, {2024, 0x4223}, {2029, 0xc06b}, {2036, 0x8602},
+ {2040, 0x3106}, {2045, 0x1fd3}, {2055, 0x3a0c}, {2061, 0xa1aa},
+ {2068, 0x0812}, {2071, 0x0204}, {2073, 0x2572}, {2080, 0x0801},
+ /* 0x5d00 */
+ {2082, 0x40cc}, {2087, 0x4850}, {2091, 0x62d0}, {2097, 0x6010},
+ {2100, 0x1c80}, {2104, 0x2900}, {2107, 0x9a00}, {2111, 0x0010},
+ {2112, 0x0004}, {2113, 0x2200}, {2115, 0x0000}, {2115, 0x0080},
+ {2116, 0x2020}, {2118, 0x6800}, {2121, 0xcbe6}, {2131, 0x609e},
+ /* 0x5e00 */
+ {2138, 0x916e}, {2146, 0x3f73}, {2157, 0x60c0}, {2161, 0x3982},
+ {2167, 0x1034}, {2171, 0x4830}, {2175, 0x0006}, {2177, 0xbd5c},
+ {2187, 0x8cd1}, {2194, 0xd6fb}, {2206, 0x20e1}, {2211, 0x43e8},
+ {2218, 0x0600}, {2220, 0x084e}, {2225, 0x0500}, {2227, 0xc4d0},
+ /* 0x5f00 */
+ {2233, 0x8d1f}, {2242, 0x89aa}, {2249, 0xa6e1}, {2257, 0x1602},
+ {2261, 0x0001}, {2262, 0x21ed}, {2270, 0x3656}, {2278, 0x1a8b},
+ {2285, 0x1fb7}, {2296, 0x13a5}, {2303, 0x6502}, {2308, 0x30a0},
+ {2312, 0xb278}, {2320, 0x23c7}, {2328, 0x6c93}, {2336, 0xe922},
+ /* 0x6000 */
+ {2343, 0xe47f}, {2354, 0x3a74}, {2362, 0x8fe3}, {2372, 0x9820},
+ {2376, 0x280e}, {2381, 0x2625}, {2387, 0xbf9c}, {2398, 0xbf49},
+ {2408, 0x3218}, {2413, 0xac54}, {2420, 0xb949}, {2428, 0x1916},
+ {2434, 0x0c60}, {2438, 0xb522}, {2445, 0xfbc1}, {2455, 0x0659},
+ /* 0x6100 */
+ {2461, 0xe343}, {2469, 0x8420}, {2472, 0x08d9}, {2478, 0x8000},
+ {2479, 0x5500}, {2483, 0x2022}, {2486, 0x0184}, {2489, 0x00a1},
+ {2492, 0x4800}, {2494, 0x2010}, {2496, 0x1380}, {2500, 0x4080},
+ {2502, 0x0d04}, {2506, 0x0016}, {2509, 0x0040}, {2510, 0x8020},
+ /* 0x6200 */
+ {2512, 0xfd40}, {2520, 0x8de7}, {2530, 0x5436}, {2537, 0xe098},
+ {2543, 0x7b8b}, {2553, 0x091e}, {2559, 0xfec8}, {2569, 0xd249},
+ {2576, 0x0611}, {2580, 0x8dee}, {2590, 0x1937}, {2598, 0xba22},
+ {2605, 0x77f4}, {2616, 0x9fdd}, {2628, 0xf3ec}, {2639, 0xf0da},
+ /* 0x6300 */
+ {2648, 0x4386}, {2654, 0xec42}, {2661, 0x8d3f}, {2671, 0x2604},
+ {2675, 0xfa6c}, {2685, 0xc021}, {2689, 0x628e}, {2696, 0x0cc2},
+ {2701, 0xd785}, {2710, 0x0145}, {2714, 0x77ad}, {2725, 0x5599},
+ {2733, 0xe250}, {2739, 0x4045}, {2743, 0x260b}, {2749, 0xa154},
+ /* 0x6400 */
+ {2755, 0x9827}, {2762, 0x5819}, {2768, 0x3443}, {2774, 0xa410},
+ {2778, 0x05f2}, {2785, 0x4114}, {2789, 0x2280}, {2792, 0x0700},
+ {2795, 0x00b4}, {2799, 0x4266}, {2805, 0x7210}, {2810, 0x15a1},
+ {2816, 0x6025}, {2821, 0x4185}, {2826, 0x0054}, {2829, 0x0000},
+ /* 0x6500 */
+ {2829, 0x0201}, {2831, 0x0104}, {2833, 0xc820}, {2837, 0xcb70},
+ {2845, 0x9320}, {2850, 0x6a62}, {2857, 0x184c}, {2862, 0x0095},
+ {2866, 0x1880}, {2869, 0x9a8b}, {2877, 0xaab2}, {2885, 0x3201},
+ {2889, 0xd87a}, {2898, 0x00c4}, {2901, 0xf3e5}, {2912, 0x04c3},
+ /* 0x6600 */
+ {2917, 0xd44d}, {2925, 0xa238}, {2931, 0xa1a1}, {2937, 0x5072},
+ {2943, 0x980a}, {2948, 0x84fc}, {2956, 0xc152}, {2962, 0x44d1},
+ {2968, 0x1094}, {2972, 0x20c2}, {2976, 0x4180}, {2979, 0x4210},
+ {2982, 0x0000}, {2982, 0x3a00}, {2986, 0x0240}, {2988, 0xd29d},
+ /* 0x6700 */
+ {2997, 0x2f01}, {3003, 0xa8b1}, {3010, 0xbd40}, {3017, 0x2432},
+ {3022, 0xd34d}, {3031, 0xd04b}, {3038, 0xa723}, {3046, 0xd0ad},
+ {3054, 0x0a92}, {3059, 0x75a1}, {3067, 0xadac}, {3076, 0x01e9},
+ {3082, 0x801a}, {3086, 0x771f}, {3097, 0x9225}, {3103, 0xa01b},
+ /* 0x6800 */
+ {3109, 0xdfa1}, {3119, 0x20ca}, {3124, 0x0602}, {3127, 0x738c},
+ {3135, 0x577f}, {3147, 0x003b}, {3152, 0x0bff}, {3163, 0x00d0},
+ {3166, 0x806a}, {3171, 0x0088}, {3173, 0xa1c4}, {3179, 0x0029},
+ {3182, 0x2a05}, {3187, 0x0524}, {3191, 0x4009}, {3194, 0x1623},
+ /* 0x6900 */
+ {3200, 0x6822}, {3205, 0x8005}, {3208, 0x2011}, {3211, 0xa211},
+ {3216, 0x0004}, {3217, 0x6490}, {3222, 0x4849}, {3227, 0x1382},
+ {3232, 0x23d5}, {3240, 0x1930}, {3245, 0x2980}, {3249, 0x0892},
+ {3253, 0x5402}, {3257, 0x8811}, {3261, 0x2001}, {3263, 0xa004},
+ /* 0x6a00 */
+ {3266, 0x0400}, {3267, 0x8180}, {3270, 0x8502}, {3274, 0x6022},
+ {3278, 0x0090}, {3280, 0x0b01}, {3284, 0x0022}, {3286, 0x1202},
+ {3289, 0x4011}, {3292, 0x0083}, {3295, 0x1a01}, {3299, 0x0000},
+ {3299, 0x0000}, {3299, 0x0000}, {3299, 0x0000}, {3299, 0x0000},
+ /* 0x6b00 */
+ {3299, 0x0000}, {3299, 0x0000}, {3299, 0x009f}, {3305, 0x4684},
+ {3310, 0x12c8}, {3315, 0x0200}, {3316, 0x04fc}, {3323, 0x1a00},
+ {3326, 0x2ede}, {3336, 0x0c4c}, {3341, 0x0402}, {3343, 0x80b8},
+ {3348, 0xa826}, {3354, 0x0afc}, {3362, 0x8c02}, {3366, 0x2228},
+ /* 0x6c00 */
+ {3370, 0xa0e0}, {3375, 0x8f7b}, {3386, 0xc7d6}, {3396, 0x2135},
+ {3402, 0x06c7}, {3409, 0xf8b1}, {3418, 0x0713}, {3424, 0x6255},
+ {3431, 0x936e}, {3440, 0x8a19}, {3446, 0x6efa}, {3457, 0xfb0e},
+ {3467, 0x1630}, {3472, 0x48f9}, {3480, 0xcd2f}, {3490, 0x7deb},
+ /* 0x6d00 */
+ {3502, 0x5892}, {3508, 0x4e84}, {3514, 0x4ca0}, {3519, 0x7a2e},
+ {3528, 0xedea}, {3539, 0x561e}, {3547, 0xc649}, {3554, 0x1190},
+ {3558, 0x5324}, {3564, 0xe83a}, {3572, 0xcfdb}, {3584, 0x8124},
+ {3588, 0x18f1}, {3595, 0x6342}, {3601, 0x5853}, {3608, 0x1a8a},
+ /* 0x6e00 */
+ {3614, 0x7420}, {3619, 0x24d3}, {3626, 0xaa3b}, {3635, 0x0514},
+ {3639, 0x6018}, {3643, 0x8958}, {3649, 0x4800}, {3651, 0xc000},
+ {3653, 0x8268}, {3658, 0x9101}, {3662, 0x84a4}, {3667, 0x2cd6},
+ {3675, 0x8886}, {3680, 0xc4ba}, {3688, 0x0377}, {3696, 0x0210},
+ /* 0x6f00 */
+ {3698, 0x8244}, {3702, 0x0038}, {3705, 0xae11}, {3712, 0x404a},
+ {3716, 0x28c0}, {3720, 0x5100}, {3723, 0x6044}, {3727, 0x1514},
+ {3732, 0x7310}, {3738, 0x1000}, {3739, 0x0082}, {3741, 0x0248},
+ {3744, 0x0205}, {3747, 0x4006}, {3750, 0xc003}, {3754, 0x0000},
+ /* 0x7000 */
+ {3754, 0x0000}, {3754, 0x0c02}, {3757, 0x0008}, {3758, 0x0220},
+ {3760, 0x9000}, {3762, 0x4000}, {3763, 0xb800}, {3767, 0xd161},
+ {3774, 0x4621}, {3779, 0x3274}, {3786, 0xf800}, {3791, 0x3b8a},
+ {3799, 0x050f}, {3805, 0x8b00}, {3809, 0xbbd0}, {3818, 0x2280},
+ /* 0x7100 */
+ {3821, 0x0600}, {3823, 0x0769}, {3830, 0x8040}, {3832, 0x0043},
+ {3835, 0x5420}, {3839, 0x5000}, {3841, 0x41d0}, {3846, 0x250c},
+ {3851, 0x8410}, {3854, 0x8310}, {3858, 0x1101}, {3861, 0x0228},
+ {3864, 0x4008}, {3866, 0x0030}, {3868, 0x40a1}, {3872, 0x0200},
+ /* 0x7200 */
+ {3873, 0x0040}, {3874, 0x2000}, {3875, 0x1500}, {3878, 0xabe3},
+ {3888, 0x3180}, {3892, 0xaa44}, {3898, 0xc2c6}, {3905, 0xc624},
+ {3911, 0xac13}, {3918, 0x8004}, {3920, 0xb000}, {3923, 0x03d1},
+ {3929, 0x611e}, {3936, 0x4285}, {3941, 0xf303}, {3949, 0x1d9f},
+ /* 0x7300 */
+ {3959, 0x440a}, {3963, 0x78e8}, {3971, 0x5e26}, {3979, 0xc392},
+ {3986, 0x2000}, {3987, 0x0085}, {3990, 0xb001}, {3994, 0x4000},
+ {3995, 0x4a90}, {4000, 0x8842}, {4004, 0xca04}, {4009, 0x0c8d},
+ {4015, 0xa705}, {4022, 0x4203}, {4026, 0x22a1}, {4031, 0x0004},
+ /* 0x7400 */
+ {4032, 0x8668}, {4038, 0x0c01}, {4041, 0x5564}, {4048, 0x1079},
+ {4054, 0x0002}, {4055, 0xdea0}, {4063, 0x2000}, {4064, 0x40c1},
+ {4068, 0x488b}, {4074, 0x5001}, {4077, 0x0380}, {4080, 0x0400},
+ {4081, 0x0000}, {4081, 0x5004}, {4084, 0xc05d}, {4091, 0x80d0},
+ /* 0x7500 */
+ {4095, 0xa010}, {4098, 0x970a}, {4105, 0xbb20}, {4112, 0x4daf},
+ {4122, 0xd921}, {4129, 0x1e10}, {4134, 0x0460}, {4137, 0x8314},
+ {4142, 0x8848}, {4146, 0xa6d6}, {4155, 0xd83b}, {4164, 0x733f},
+ {4175, 0x27bc}, {4184, 0x4974}, {4191, 0x0ddc}, {4199, 0x9213},
+ /* 0x7600 */
+ {4205, 0x142b}, {4211, 0x8ba1}, {4218, 0x2e75}, {4227, 0xd139},
+ {4235, 0x3009}, {4239, 0x5050}, {4243, 0x8808}, {4246, 0x6900},
+ {4250, 0x49d4}, {4257, 0x024a}, {4261, 0x4010}, {4263, 0x8016},
+ {4267, 0xe564}, {4275, 0x89d7}, {4284, 0xc020}, {4287, 0x5316},
+ /* 0x7700 */
+ {4294, 0x2b92}, {4301, 0x8600}, {4304, 0xa345}, {4311, 0x15e0},
+ {4317, 0x008b}, {4321, 0x0c03}, {4325, 0x196e}, {4333, 0xe200},
+ {4337, 0x7031}, {4343, 0x8006}, {4346, 0x16a5}, {4353, 0xa829},
+ {4359, 0x2000}, {4360, 0x1880}, {4363, 0x7aac}, {4372, 0xe148},
+ /* 0x7800 */
+ {4378, 0x3207}, {4384, 0xb5d6}, {4394, 0x32e8}, {4401, 0x5f91},
+ {4410, 0x50a1}, {4415, 0x20e5}, {4421, 0x7c00}, {4426, 0x1080},
+ {4428, 0x7280}, {4433, 0x9d8a}, {4441, 0x00aa}, {4445, 0x421f},
+ {4452, 0x0e22}, {4457, 0x0231}, {4461, 0x1100}, {4463, 0x0494},
+ /* 0x7900 */
+ {4467, 0x0022}, {4469, 0x4008}, {4471, 0x0010}, {4472, 0x5c10},
+ {4477, 0x0343}, {4482, 0xfcc8}, {4491, 0xa1a5}, {4498, 0x0580},
+ {4501, 0x8433}, {4507, 0x0400}, {4508, 0x0080}, {4509, 0x6e08},
+ {4515, 0x2a4b}, {4522, 0x8126}, {4527, 0xaad8}, {4535, 0x2901},
+ /* 0x7a00 */
+ {4539, 0x684d}, {4546, 0x4490}, {4550, 0x0009}, {4552, 0xba88},
+ {4559, 0x0040}, {4560, 0x0082}, {4562, 0x0000}, {4562, 0x87d1},
+ {4570, 0x215b}, {4577, 0xb1e6}, {4586, 0x3161}, {4592, 0x8008},
+ {4594, 0x0800}, {4595, 0xc240}, {4599, 0xa069}, {4605, 0xa600},
+ /* 0x7b00 */
+ {4609, 0x8d58}, {4616, 0x4a32}, {4622, 0x5d71}, {4631, 0x550a},
+ {4637, 0x9aa0}, {4643, 0x2d57}, {4652, 0x4005}, {4655, 0x4aa6},
+ {4662, 0x2021}, {4665, 0x30b1}, {4671, 0x3fc6}, {4681, 0x0112},
+ {4684, 0x10c2}, {4688, 0x260a}, {4693, 0x4462}, {4698, 0x5082},
+ /* 0x7c00 */
+ {4702, 0x9880}, {4706, 0x8040}, {4708, 0x04c0}, {4711, 0x8100},
+ {4713, 0x2003}, {4716, 0x0000}, {4716, 0x0000}, {4716, 0x3818},
+ {4721, 0x0200}, {4722, 0xf1a6}, {4731, 0x4434}, {4736, 0x720e},
+ {4743, 0x35a2}, {4750, 0x92e0}, {4756, 0x8101}, {4759, 0x0900},
+ /* 0x7d00 */
+ {4761, 0x0400}, {4762, 0x0000}, {4762, 0x8885}, {4767, 0x0000},
+ {4767, 0x0000}, {4767, 0x0000}, {4767, 0x4000}, {4768, 0x0080},
+ {4769, 0x0000}, {4769, 0x0000}, {4769, 0x4040}, {4771, 0x0000},
+ {4771, 0x0000}, {4771, 0x0000}, {4771, 0x0000}, {4771, 0x0000},
+ /* 0x7e00 */
+ {4771, 0x0000}, {4771, 0x0000}, {4771, 0x0000}, {4771, 0x0800},
+ {4772, 0x0082}, {4774, 0x0000}, {4774, 0x0000}, {4774, 0x0000},
+ {4774, 0x0004}, {4775, 0x8800}, {4777, 0xbfff}, {4792, 0xe7ef},
+ {4805, 0xffff}, {4821, 0xffbf}, {4836, 0xefef}, {4850, 0xfdff},
+ /* 0x7f00 */
+ {4865, 0xfbff}, {4880, 0xbffe}, {4894, 0xffff}, {4910, 0x057f},
+ {4919, 0x0034}, {4922, 0x85b3}, {4930, 0x4706}, {4936, 0x4216},
+ {4941, 0x5402}, {4945, 0xe410}, {4950, 0x8092}, {4954, 0xb305},
+ {4961, 0x5422}, {4966, 0x8130}, {4970, 0x4263}, {4976, 0x180b},
+ /* 0x8000 */
+ {4981, 0x387b}, {4990, 0x13f5}, {4999, 0x07e5}, {5007, 0xa9ea},
+ {5016, 0x3c4c}, {5023, 0x0514}, {5027, 0x0600}, {5029, 0x8002},
+ {5031, 0x1ad9}, {5039, 0xbd48}, {5047, 0xee37}, {5058, 0xf496},
+ {5067, 0x705f}, {5076, 0x7ec0}, {5084, 0xbfb2}, {5095, 0x355f},
+ /* 0x8100 */
+ {5105, 0xe644}, {5112, 0x455f}, {5121, 0x9000}, {5123, 0x4146},
+ {5128, 0x1d40}, {5133, 0x063b}, {5140, 0x62a1}, {5146, 0xfe13},
+ {5156, 0x8505}, {5161, 0x3902}, {5166, 0x0548}, {5170, 0x0c08},
+ {5173, 0x144f}, {5180, 0x0000}, {5180, 0x3488}, {5185, 0x5818},
+ /* 0x8200 */
+ {5190, 0x3077}, {5198, 0xd815}, {5205, 0xbd0e}, {5214, 0x4bfb},
+ {5225, 0x8a90}, {5230, 0x8500}, {5233, 0xc100}, {5236, 0xe61d},
+ {5245, 0xed14}, {5253, 0xb386}, {5261, 0xff72}, {5273, 0x639b},
+ {5282, 0xfd92}, {5292, 0xd9be}, {5303, 0x887b}, {5311, 0x0a92},
+ /* 0x8300 */
+ {5316, 0xd3fe}, {5328, 0x1cb2}, {5335, 0xb980}, {5341, 0x177a},
+ {5350, 0x82c9}, {5356, 0xdc17}, {5365, 0xfffb}, {5380, 0x3980},
+ {5385, 0x4260}, {5389, 0x590c}, {5395, 0x0f01}, {5400, 0x37df},
+ {5412, 0x94a3}, {5419, 0xb150}, {5425, 0x0623}, {5430, 0x2307},
+ /* 0x8400 */
+ {5436, 0xf85a}, {5445, 0x3102}, {5449, 0x01f0}, {5454, 0x3102},
+ {5458, 0x0040}, {5459, 0x1e82}, {5465, 0x3a0a}, {5471, 0x056a},
+ {5477, 0x5b84}, {5484, 0x1280}, {5487, 0x8002}, {5489, 0xa714},
+ {5496, 0x2612}, {5501, 0xa04b}, {5507, 0x1069}, {5512, 0x9001},
+ /* 0x8500 */
+ {5515, 0x1000}, {5516, 0x848a}, {5521, 0x1802}, {5524, 0x3f80},
+ {5531, 0x0708}, {5535, 0x4240}, {5538, 0x0110}, {5540, 0x4e14},
+ {5546, 0x80b0}, {5550, 0x1800}, {5552, 0xc510}, {5557, 0x0281},
+ {5560, 0x8202}, {5563, 0x1029}, {5567, 0x0210}, {5569, 0x8800},
+ /* 0x8600 */
+ {5571, 0x0020}, {5572, 0x0042}, {5574, 0x0280}, {5576, 0x1100},
+ {5578, 0xe000}, {5581, 0x4413}, {5586, 0x5804}, {5590, 0xfe02},
+ {5598, 0x3c07}, {5605, 0x3028}, {5609, 0x9798}, {5617, 0x0473},
+ {5623, 0xced1}, {5632, 0xcb13}, {5640, 0x6210}, {5644, 0x431f},
+ /* 0x8700 */
+ {5652, 0x278d}, {5660, 0x55ac}, {5668, 0x422e}, {5674, 0xc892},
+ {5680, 0x5380}, {5685, 0x0288}, {5688, 0x4039}, {5693, 0x7851},
+ {5700, 0x292c}, {5706, 0x8088}, {5709, 0xb900}, {5714, 0x2428},
+ {5718, 0x0c41}, {5722, 0x080e}, {5726, 0x4421}, {5730, 0x4200},
+ /* 0x8800 */
+ {5732, 0x0408}, {5734, 0x0868}, {5738, 0x0006}, {5740, 0x1204},
+ {5743, 0x3031}, {5748, 0x0290}, {5751, 0x5b3e}, {5761, 0xe085},
+ {5767, 0x2936}, {5774, 0x1044}, {5777, 0x2814}, {5781, 0x1082},
+ {5784, 0x4266}, {5790, 0x8334}, {5796, 0x013c}, {5801, 0x531b},
+ /* 0x8900 */
+ {5809, 0x0404}, {5811, 0x0e0d}, {5817, 0x0c22}, {5821, 0x0051},
+ {5824, 0x0012}, {5826, 0xc000}, {5828, 0x0040}, {5829, 0x8800},
+ {5831, 0x004a}, {5834, 0x0000}, {5834, 0x0000}, {5834, 0x0000},
+ {5834, 0xdff6}, {5847, 0x5447}, {5854, 0x8868}, {5859, 0x0008},
+ /* 0x8a00 */
+ {5860, 0x0081}, {5862, 0x0000}, {5862, 0x0000}, {5862, 0x4000},
+ {5863, 0x0100}, {5864, 0x0000}, {5864, 0x0000}, {5864, 0x0200},
+ {5865, 0x0600}, {5867, 0x0008}, {5868, 0x0000}, {5868, 0x0000},
+ {5868, 0x0000}, {5868, 0x0000}, {5868, 0x0000}, {5868, 0x0000},
+ /* 0x8b00 */
+ {5868, 0x0080}, {5869, 0x0000}, {5869, 0x0040}, {5870, 0x0000},
+ {5870, 0x0000}, {5870, 0x0000}, {5870, 0x1040}, {5872, 0x0000},
+ {5872, 0x0000}, {5872, 0x0000}, {5872, 0xefff}, {5887, 0xf7fd},
+ {5901, 0xff7f}, {5916, 0xfffe}, {5931, 0xfbff}, {5946, 0xffff},
+ /* 0x8c00 */
+ {5962, 0xfdff}, {5977, 0xbfff}, {5992, 0xffff}, {6008, 0x00ff},
+ {6016, 0x12c2}, {6021, 0x0420}, {6023, 0x0c06}, {6027, 0x0708},
+ {6031, 0x1624}, {6036, 0x0110}, {6038, 0x0000}, {6038, 0x0000},
+ {6038, 0x0000}, {6038, 0x0000}, {6038, 0x0000}, {6038, 0x0000},
+ /* 0x8d00 */
+ {6038, 0x0000}, {6038, 0xe000}, {6041, 0xfffe}, {6056, 0xffff},
+ {6072, 0xffff}, {6088, 0x7f79}, {6100, 0x28df}, {6109, 0x00f9},
+ {6115, 0x0c32}, {6120, 0x8012}, {6123, 0x0008}, {6124, 0xd53a},
+ {6133, 0xd858}, {6140, 0xecc2}, {6148, 0x9d18}, {6155, 0x2fa8},
+ /* 0x8e00 */
+ {6163, 0x9620}, {6168, 0xe010}, {6172, 0xd60c}, {6179, 0x2622},
+ {6184, 0x0f97}, {6193, 0x0206}, {6196, 0xb240}, {6201, 0x9055},
+ {6207, 0x80a2}, {6211, 0x5011}, {6215, 0x9800}, {6218, 0x0404},
+ {6220, 0x4000}, {6221, 0x0000}, {6221, 0x0000}, {6221, 0x0000},
+ /* 0x8f00 */
+ {6221, 0x0000}, {6221, 0x0000}, {6221, 0x0000}, {6221, 0x0000},
+ {6221, 0x0000}, {6221, 0x0000}, {6221, 0xfbc0}, {6230, 0xffff},
+ {6246, 0xeffe}, {6260, 0xdffb}, {6274, 0x0b08}, {6278, 0x6243},
+ {6284, 0x41b6}, {6291, 0xfb3b}, {6303, 0x6f74}, {6313, 0x2389},
+ /* 0x9000 */
+ {6319, 0xae7f}, {6331, 0xecd7}, {6342, 0xe047}, {6349, 0x5960},
+ {6355, 0xa096}, {6361, 0x098f}, {6368, 0x612c}, {6374, 0xa030},
+ {6378, 0x090d}, {6383, 0x2aaa}, {6390, 0xd44e}, {6398, 0x4f7b},
+ {6409, 0xc4b2}, {6416, 0x388b}, {6423, 0xa9c6}, {6431, 0x6110},
+ /* 0x9100 */
+ {6435, 0x0014}, {6437, 0x4200}, {6439, 0x800c}, {6442, 0x0202},
+ {6444, 0xfe48}, {6453, 0x6485}, {6459, 0xd63e}, {6469, 0xe3f7},
+ {6481, 0x3aa0}, {6487, 0x0c07}, {6492, 0xe40c}, {6498, 0x0430},
+ {6501, 0xf680}, {6508, 0x1002}, {6510, 0x0000}, {6510, 0x0000},
+ /* 0x9200 */
+ {6510, 0x0000}, {6510, 0x0000}, {6510, 0x0000}, {6510, 0x0000},
+ {6510, 0x0000}, {6510, 0x0000}, {6510, 0x0000}, {6510, 0x0010},
+ {6511, 0x4000}, {6512, 0x0000}, {6512, 0x4000}, {6513, 0x0000},
+ {6513, 0x0100}, {6514, 0x0000}, {6514, 0x0000}, {6514, 0x0000},
+ /* 0x9300 */
+ {6514, 0x0000}, {6514, 0x0000}, {6514, 0x0000}, {6514, 0x4000},
+ {6515, 0x0000}, {6515, 0x0000}, {6515, 0x0400}, {6516, 0x0000},
+ {6516, 0x8000}, {6517, 0x0000}, {6517, 0x0000}, {6517, 0x0000},
+ {6517, 0x0400}, {6518, 0x0040}, {6519, 0x0000}, {6519, 0x0000},
+ /* 0x9400 */
+ {6519, 0x0000}, {6519, 0x0000}, {6519, 0x0000}, {6519, 0x4000},
+ {6520, 0x0000}, {6520, 0x0000}, {6520, 0x0800}, {6521, 0x0000},
+ {6521, 0xffe0}, {6532, 0xfebd}, {6545, 0xffff}, {6561, 0xffff},
+ {6577, 0x7f7f}, {6591, 0xfbe7}, {6604, 0xffbf}, {6619, 0xf7ff},
+ /* 0x9500 */
+ {6634, 0xffff}, {6650, 0xefff}, {6665, 0xff7e}, {6679, 0xdff7},
+ {6693, 0xf6f7}, {6706, 0xfbdf}, {6720, 0xbffe}, {6734, 0x804f},
+ {6740, 0x0000}, {6740, 0x0000}, {6740, 0x0000}, {6740, 0x0000},
+ {6740, 0x0000}, {6740, 0x0000}, {6740, 0xef00}, {6747, 0x7fff},
+ /* 0x9600 */
+ {6762, 0xff7f}, {6777, 0xb6f7}, {6789, 0x4406}, {6793, 0xb87e},
+ {6803, 0x3bf5}, {6814, 0x8831}, {6819, 0x1796}, {6827, 0x00f4},
+ {6832, 0xa960}, {6838, 0x1391}, {6844, 0x0080}, {6845, 0x7249},
+ {6852, 0xf2f3}, {6863, 0x0024}, {6865, 0x8701}, {6870, 0x42c8},
+ /* 0x9700 */
+ {6875, 0xe3d3}, {6885, 0x5048}, {6889, 0x2400}, {6891, 0x4305},
+ {6896, 0x0000}, {6896, 0x4a4c}, {6902, 0x0227}, {6907, 0x1058},
+ {6911, 0x2820}, {6914, 0x0116}, {6918, 0xa809}, {6923, 0x0014},
+ {6925, 0x0000}, {6925, 0x0000}, {6925, 0x3ec0}, {6932, 0x0068},
+ /* 0x9800 */
+ {6935, 0x0000}, {6935, 0x0000}, {6935, 0x0000}, {6935, 0x0000},
+ {6935, 0x0000}, {6935, 0x0000}, {6935, 0x0000}, {6935, 0xffe0},
+ {6946, 0xb7ff}, {6960, 0xfddb}, {6973, 0x00f7}, {6980, 0x0000},
+ {6980, 0x4000}, {6981, 0xc72e}, {6990, 0x0180}, {6992, 0x0000},
+ /* 0x9900 */
+ {6992, 0x2000}, {6993, 0x0001}, {6994, 0x4000}, {6995, 0x0000},
+ {6995, 0x0000}, {6995, 0x0030}, {6997, 0xffa8}, {7008, 0xb4f7},
+ {7019, 0xadf3}, {7030, 0x03ff}, {7040, 0x0120}, {7042, 0x0000},
+ {7042, 0x0000}, {7042, 0x0000}, {7042, 0x0000}, {7042, 0x0000},
+ /* 0x9a00 */
+ {7042, 0x0000}, {7042, 0x0000}, {7042, 0x0000}, {7042, 0x0000},
+ {7042, 0x0000}, {7042, 0x0000}, {7042, 0xf000}, {7046, 0xfffb},
+ {7061, 0x9df7}, {7073, 0xfdcf}, {7086, 0x01bf}, {7094, 0x15c3},
+ {7101, 0x1827}, {7107, 0x810a}, {7111, 0xa842}, {7116, 0x0a00},
+ /* 0x9b00 */
+ {7118, 0x8108}, {7121, 0x8008}, {7123, 0x8008}, {7125, 0x1804},
+ {7128, 0xa3be}, {7138, 0x0012}, {7140, 0x0000}, {7140, 0x0000},
+ {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000},
+ {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000},
+ /* 0x9c00 */
+ {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000},
+ {7140, 0x0000}, {7140, 0x0000}, {7140, 0x0000}, {7140, 0x9000},
+ {7142, 0x69e6}, {7151, 0xdc37}, {7161, 0x6bff}, {7174, 0x3dff},
+ {7187, 0xfcf8}, {7198, 0xf3f9}, {7210, 0x0004},
+};
+static const Summary16 gb2312_uni2indx_page9e[27] = {
+ /* 0x9e00 */
+ {7211, 0x0000}, {7211, 0x8000}, {7212, 0xbf6f}, {7225, 0xe7ee},
+ {7237, 0xdffe}, {7251, 0x5da2}, {7259, 0x3fd8}, {7269, 0xc00b},
+ {7274, 0x0984}, {7278, 0xa00c}, {7282, 0x0040}, {7283, 0x6910},
+ {7288, 0xe210}, {7293, 0xb912}, {7300, 0x86a5}, {7307, 0x5a00},
+ /* 0x9f00 */
+ {7311, 0x6800}, {7314, 0x0289}, {7318, 0x9005}, {7322, 0x6a80},
+ {7327, 0x0010}, {7328, 0x0003}, {7330, 0x0000}, {7330, 0x8000},
+ {7331, 0x1ff9}, {7342, 0x8e00}, {7346, 0x0001},
+};
+static const Summary16 gb2312_uni2indx_pageff[15] = {
+ /* 0xff00 */
+ {7347, 0xfffe}, {7362, 0xffff}, {7378, 0xffff}, {7394, 0xffff},
+ {7410, 0xffff}, {7426, 0x7fff}, {7441, 0x0000}, {7441, 0x0000},
+ {7441, 0x0000}, {7441, 0x0000}, {7441, 0x0000}, {7441, 0x0000},
+ {7441, 0x0000}, {7441, 0x0000}, {7441, 0x002b},
+};
+
+/* ASCII <-> ucs4 */
+
+static int ascii_wctomb(unsigned char * r, ucs4_t wc, int n)
+{
+ if (wc < 0x0080) {
+ *r = wc;
+ return 1;
+ }
+ return RET_ILUNI;
+}
+
+static int ascii_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c = *s;
+
+ if (c < 0x80) {
+ *pwc = (ucs4_t) c;
+ return 1;
+ }
+ return RET_ILSEQ;
+}
+
+/* BIG5 convert to ucs4 */
+
+static int big5_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c1 = s[0];
+
+ if ((c1 >= 0xa1 && c1 <= 0xc7) || (c1 >= 0xc9 && c1 <= 0xf9)) {
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) {
+ unsigned int i = 157 * (c1 - 0xa1) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40));
+ unsigned short wc = 0xfffd;
+
+ if (i < 6280) {
+ if (i < 6121)
+ wc = big5_2uni_pagea1[i];
+ } else {
+ if (i < 13932)
+ wc = big5_2uni_pagec9[i - 6280];
+ }
+ if (wc != 0xfffd) {
+ *pwc = (ucs4_t) wc;
+ return 2;
+ }
+ }
+ return RET_ILSEQ;
+ }
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+}
+
+/* HKSCS convert to ucs4 */
+
+static int hkscs_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c1 = s[0];
+
+ if ((c1 >= 0x88 && c1 <= 0x8b) || (c1 >= 0x8d && c1 <= 0xa0)
+ || (c1 >= 0xc6 && c1 <= 0xc8) || (c1 >= 0xf9 && c1 <= 0xfe)) {
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) {
+ unsigned int i = 157 * (c1 - 0x80) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40));
+ ucs4_t wc = 0xfffd;
+ unsigned short swc;
+
+ if (i < 2041) {
+ if (i < 1883)
+ swc = hkscs_2uni_page88[i - 1256],
+ wc = hkscs_2uni_upages[swc >> 6] | (swc & 0x3f);
+ } else if (i < 10990) {
+ if (i < 5181)
+ swc = hkscs_2uni_page8d[i - 2041],
+ wc = hkscs_2uni_upages[swc >> 6] | (swc & 0x3f);
+ } else if (i < 18997) {
+ if (i < 11461)
+ swc = hkscs_2uni_pagec6[i - 10990],
+ wc = hkscs_2uni_upages[swc >> 6] | (swc & 0x3f);
+ } else {
+ if (i < 19939)
+ swc = hkscs_2uni_pagef9[i - 18997],
+ wc = hkscs_2uni_upages[swc >> 6] | (swc & 0x3f);
+ }
+ if (wc != 0xfffd) {
+ *pwc = wc;
+ return 2;
+ }
+ }
+ return RET_ILSEQ;
+ }
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+}
+
+/* BIG5/HKSCS convert to ucs4 */
+
+static int big5hkscs_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c = *s;
+
+ /* Code set 0 (ASCII) */
+ if (c < 0x80)
+ return ascii_mbtowc(pwc, s, n);
+ /* Code set 1 (BIG5 extended) */
+ if (c >= 0xa1 && c < 0xff) {
+ if (n < 2)
+ return RET_TOOFEW(0);
+ {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) {
+ if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) {
+ int ret = big5_mbtowc(pwc, s, 2);
+
+ if (ret != RET_ILSEQ)
+ return ret;
+ }
+ }
+ }
+ }
+ return hkscs_mbtowc(pwc, s, n);
+}
+
+/* JISX0213 -> ucs4 */
+
+static ucs4_t jisx0213_to_ucs4(unsigned int row, unsigned int col)
+{
+ ucs4_t val;
+
+ if (row >= 0x121 && row <= 0x17e)
+ row -= 289;
+ else if (row == 0x221)
+ row -= 451;
+ else if (row >= 0x223 && row <= 0x225)
+ row -= 452;
+ else if (row == 0x228)
+ row -= 454;
+ else if (row >= 0x22c && row <= 0x22f)
+ row -= 457;
+ else if (row >= 0x26e && row <= 0x27e)
+ row -= 519;
+ else
+ return 0x0000;
+
+ if (col >= 0x21 && col <= 0x7e)
+ col -= 0x21;
+ else
+ return 0x0000;
+
+ val = jisx0213_to_ucs_main[row * 94 + col];
+ val = jisx0213_to_ucs_pagestart[val >> 8] + (val & 0xff);
+ if (val == 0xfffd)
+ val = 0x0000;
+ return val;
+}
+
+static ucs4_t istate = 0;
+
+static int shift_jisx0213_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ ucs4_t last_wc = istate;
+
+ if (last_wc) {
+ /* Output the buffered character. */
+ istate = 0;
+ *pwc = last_wc;
+ return 0; /* Don't advance the input pointer. */
+ } else {
+ unsigned char c = *s;
+
+ if (c < 0x80) {
+ /* Plain ISO646-JP character. */
+ *pwc = (ucs4_t) c;
+ return 1;
+ } else if (c >= 0xa1 && c <= 0xdf) {
+ *pwc = c + 0xfec0;
+ return 1;
+ } else {
+ if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) {
+ /* Two byte character. */
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 <= 0x7e)
+ || (c2 >= 0x80 && c2 <= 0xfc)) {
+ unsigned int c1;
+ ucs4_t wc;
+
+ /* Convert to row and column. */
+ if (c < 0xe0)
+ c -= 0x81;
+ else
+ c -= 0xc1;
+ if (c2 < 0x80)
+ c2 -= 0x40;
+ else
+ c2 -= 0x41;
+ /* Now 0 <= c <= 0x3b, 0 <= c2 <= 0xbb. */
+ c1 = 2 * c;
+ if (c2 >= 0x5e)
+ c2 -= 0x5e, c1++;
+ c2 += 0x21;
+ if (c1 >= 0x5e) {
+ /* Handling of JISX 0213 plane 2 rows. */
+ if (c1 >= 0x67)
+ c1 += 230;
+ else if (c1 >= 0x63 || c1 == 0x5f)
+ c1 += 168;
+ else
+ c1 += 162;
+ }
+ wc = jisx0213_to_ucs4(0x121 + c1, c2);
+ if (wc) {
+ if (wc < 0x80) {
+ /* It's a combining character. */
+ ucs4_t wc1 =
+ jisx0213_to_ucs_combining[wc - 1][0];
+ ucs4_t wc2 =
+ jisx0213_to_ucs_combining[wc - 1][1];
+ /* We cannot output two Unicode characters at once. So,
+ output the first character and buffer the second one. */
+ *pwc = wc1;
+ istate = wc2;
+ } else
+ *pwc = wc;
+ return 2;
+ }
+ }
+ } else
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+ }
+ }
+}
+
+int utf8_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c = s[0];
+
+ if (c < 0x80) {
+ *pwc = c;
+ return 1;
+ } else if (c < 0xc2) {
+ return RET_ILSEQ;
+ } else if (c < 0xe0) {
+ if (n < 2)
+ return RET_TOOFEW(0);
+ if (!((s[1] ^ 0x80) < 0x40))
+ return RET_ILSEQ;
+ *pwc = ((ucs4_t) (c & 0x1f) << 6)
+ | (ucs4_t) (s[1] ^ 0x80);
+ return 2;
+ } else if (c < 0xf0) {
+ if (n < 3)
+ return RET_TOOFEW(0);
+ if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ && (c >= 0xe1 || s[1] >= 0xa0)))
+ return RET_ILSEQ;
+ *pwc = ((ucs4_t) (c & 0x0f) << 12)
+ | ((ucs4_t) (s[1] ^ 0x80) << 6)
+ | (ucs4_t) (s[2] ^ 0x80);
+ return 3;
+ } else if (c < 0xf8 && sizeof(ucs4_t) * 8 >= 32) {
+ if (n < 4)
+ return RET_TOOFEW(0);
+ if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ && (s[3] ^ 0x80) < 0x40 && (c >= 0xf1 || s[1] >= 0x90)))
+ return RET_ILSEQ;
+ *pwc = ((ucs4_t) (c & 0x07) << 18)
+ | ((ucs4_t) (s[1] ^ 0x80) << 12)
+ | ((ucs4_t) (s[2] ^ 0x80) << 6)
+ | (ucs4_t) (s[3] ^ 0x80);
+ return 4;
+ } else if (c < 0xfc && sizeof(ucs4_t) * 8 >= 32) {
+ if (n < 5)
+ return RET_TOOFEW(0);
+ if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
+ && (c >= 0xf9 || s[1] >= 0x88)))
+ return RET_ILSEQ;
+ *pwc = ((ucs4_t) (c & 0x03) << 24)
+ | ((ucs4_t) (s[1] ^ 0x80) << 18)
+ | ((ucs4_t) (s[2] ^ 0x80) << 12)
+ | ((ucs4_t) (s[3] ^ 0x80) << 6)
+ | (ucs4_t) (s[4] ^ 0x80);
+ return 5;
+ } else if (c < 0xfe && sizeof(ucs4_t) * 8 >= 32) {
+ if (n < 6)
+ return RET_TOOFEW(0);
+ if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
+ && (s[5] ^ 0x80) < 0x40 && (c >= 0xfd || s[1] >= 0x84)))
+ return RET_ILSEQ;
+ *pwc = ((ucs4_t) (c & 0x01) << 30)
+ | ((ucs4_t) (s[1] ^ 0x80) << 24)
+ | ((ucs4_t) (s[2] ^ 0x80) << 18)
+ | ((ucs4_t) (s[3] ^ 0x80) << 12)
+ | ((ucs4_t) (s[4] ^ 0x80) << 6)
+ | (ucs4_t) (s[5] ^ 0x80);
+ return 6;
+ } else
+ return RET_ILSEQ;
+}
+
+int utf16_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ ucs4_t state = istate;
+ int count = 0;
+
+ for (; n >= 2;) {
+ ucs4_t wc = (state ? s[0] + (s[1] << 8) : (s[0] << 8) + s[1]);
+
+ if (wc == 0xfeff) {
+ } else if (wc == 0xfffe) {
+ state ^= 1;
+ } else if (wc >= 0xd800 && wc < 0xdc00) {
+ if (n >= 4) {
+ ucs4_t wc2 = (state ? s[2] + (s[3] << 8) : (s[2] << 8) + s[3]);
+
+ if (!(wc2 >= 0xdc00 && wc2 < 0xe000))
+ return RET_ILSEQ;
+ *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00);
+ istate = state;
+ return count + 4;
+ } else
+ break;
+ } else if (wc >= 0xdc00 && wc < 0xe000) {
+ return RET_ILSEQ;
+ } else {
+ *pwc = wc;
+ istate = state;
+ return count + 2;
+ }
+ s += 2;
+ n -= 2;
+ count += 2;
+ }
+ istate = state;
+ return RET_TOOFEW(count);
+}
+
+int utf16be_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ int count = 0;
+
+ if (n >= 2) {
+ ucs4_t wc = (s[0] << 8) + s[1];
+
+ if (wc >= 0xd800 && wc < 0xdc00) {
+ if (n >= 4) {
+ ucs4_t wc2 = (s[2] << 8) + s[3];
+
+ if (!(wc2 >= 0xdc00 && wc2 < 0xe000))
+ return RET_ILSEQ;
+ *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00);
+ return count + 4;
+ }
+ } else if (wc >= 0xdc00 && wc < 0xe000) {
+ return RET_ILSEQ;
+ } else {
+ *pwc = wc;
+ return count + 2;
+ }
+ }
+ return RET_TOOFEW(count);
+}
+
+/* unicode <-> cjk */
+int gbkext1_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c1 = s[0];
+
+ if ((c1 >= 0x81 && c1 <= 0xa0)) {
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xff)) {
+ unsigned int i = 190 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40));
+ unsigned short wc = 0xfffd;
+
+ {
+ if (i < 6080)
+ wc = gbkext1_2uni_page81[i];
+ }
+ if (wc != 0xfffd) {
+ *pwc = (ucs4_t) wc;
+ return 2;
+ }
+ }
+ return RET_ILSEQ;
+ }
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+}
+
+int gbkext2_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c1 = s[0];
+
+ if ((c1 >= 0xa8 && c1 <= 0xfe)) {
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xa1)) {
+ unsigned int i = 96 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40));
+ unsigned short wc = 0xfffd;
+
+ {
+ if (i < 12016)
+ wc = gbkext2_2uni_pagea8[i - 3744];
+ }
+ if (wc != 0xfffd) {
+ *pwc = (ucs4_t) wc;
+ return 2;
+ }
+ }
+ return RET_ILSEQ;
+ }
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+}
+
+int gbkext_inv_wctomb(unsigned char * r, ucs4_t wc, int n)
+{
+ if (n >= 2) {
+ const Summary16 *summary = NULL;
+
+ if (wc >= 0x0200 && wc < 0x02e0)
+ summary = &gbkext_inv_uni2indx_page02[(wc >> 4) - 0x020];
+ else if (wc >= 0x2000 && wc < 0x22c0)
+ summary = &gbkext_inv_uni2indx_page20[(wc >> 4) - 0x200];
+ else if (wc >= 0x2500 && wc < 0x2610)
+ summary = &gbkext_inv_uni2indx_page25[(wc >> 4) - 0x250];
+ else if (wc >= 0x3000 && wc < 0x3100)
+ summary = &gbkext_inv_uni2indx_page30[(wc >> 4) - 0x300];
+ else if (wc >= 0x3200 && wc < 0x33e0)
+ summary = &gbkext_inv_uni2indx_page32[(wc >> 4) - 0x320];
+ else if (wc >= 0x4e00 && wc < 0x9fb0)
+ summary = &gbkext_inv_uni2indx_page4e[(wc >> 4) - 0x4e0];
+ else if (wc >= 0xf900 && wc < 0xfa30)
+ summary = &gbkext_inv_uni2indx_pagef9[(wc >> 4) - 0xf90];
+ else if (wc >= 0xfe00 && wc < 0xfff0)
+ summary = &gbkext_inv_uni2indx_pagefe[(wc >> 4) - 0xfe0];
+ if (summary) {
+ unsigned short used = summary->used;
+ unsigned int i = wc & 0x0f;
+
+ if (used & ((unsigned short) 1 << i)) {
+ unsigned short c;
+
+ /* Keep in `used' only the bits 0..i-1. */
+ used &= ((unsigned short) 1 << i) - 1;
+ /* Add `summary->indx' and the number of bits set in `used'. */
+ used = (used & 0x5555) + ((used & 0xaaaa) >> 1);
+ used = (used & 0x3333) + ((used & 0xcccc) >> 2);
+ used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);
+ used = (used & 0x00ff) + (used >> 8);
+ c = gbkext_inv_2charset[summary->indx + used];
+ r[0] = (c >> 8);
+ r[1] = (c & 0xff);
+ return 2;
+ }
+ }
+ return RET_ILUNI;
+ }
+ return RET_TOOSMALL;
+}
+
+int cp936ext_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c1 = s[0];
+
+ if ((c1 == 0xa6) || (c1 == 0xa8)) {
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xff)) {
+ unsigned int i = 190 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40));
+ unsigned short wc = 0xfffd;
+
+ if (i < 7410) {
+ if (i >= 7189 && i < 7211)
+ wc = cp936ext_2uni_pagea6[i - 7189];
+ } else {
+ if (i >= 7532 && i < 7538)
+ wc = cp936ext_2uni_pagea8[i - 7532];
+ }
+ if (wc != 0xfffd) {
+ *pwc = (ucs4_t) wc;
+ return 2;
+ }
+ }
+ return RET_ILSEQ;
+ }
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+}
+
+int cp936ext_wctomb(unsigned char * r, ucs4_t wc, int n)
+{
+ if (n >= 2) {
+ unsigned short c = 0;
+
+ if (wc >= 0x0140 && wc < 0x0150)
+ c = cp936ext_page01[wc - 0x0140];
+ else if (wc >= 0x0250 && wc < 0x0268)
+ c = cp936ext_page02[wc - 0x0250];
+ else if (wc >= 0xfe30 && wc < 0xfe48)
+ c = cp936ext_pagefe[wc - 0xfe30];
+ if (c != 0) {
+ r[0] = (c >> 8);
+ r[1] = (c & 0xff);
+ return 2;
+ }
+ return RET_ILUNI;
+ }
+ return RET_TOOSMALL;
+}
+
+int gb2312_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c1 = s[0];
+
+ if ((c1 >= 0x21 && c1 <= 0x29) || (c1 >= 0x30 && c1 <= 0x77)) {
+ if (n >= 2) {
+ unsigned char c2 = s[1];
+
+ if (c2 >= 0x21 && c2 < 0x7f) {
+ unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21);
+ unsigned short wc = 0xfffd;
+
+ if (i < 1410) {
+ if (i < 831)
+ wc = gb2312_2uni_page21[i];
+ } else {
+ if (i < 8178)
+ wc = gb2312_2uni_page30[i - 1410];
+ }
+ if (wc != 0xfffd) {
+ *pwc = (ucs4_t) wc;
+ return 2;
+ }
+ }
+ return RET_ILSEQ;
+ }
+ return RET_TOOFEW(0);
+ }
+ return RET_ILSEQ;
+}
+
+int gb2312_wctomb(unsigned char * r, ucs4_t wc, int n)
+{
+ if (n >= 2) {
+ const Summary16 *summary = NULL;
+
+ if (wc >= 0x0000 && wc < 0x0460)
+ summary = &gb2312_uni2indx_page00[(wc >> 4)];
+ else if (wc >= 0x2000 && wc < 0x2650)
+ summary = &gb2312_uni2indx_page20[(wc >> 4) - 0x200];
+ else if (wc >= 0x3000 && wc < 0x3230)
+ summary = &gb2312_uni2indx_page30[(wc >> 4) - 0x300];
+ else if (wc >= 0x4e00 && wc < 0x9cf0)
+ summary = &gb2312_uni2indx_page4e[(wc >> 4) - 0x4e0];
+ else if (wc >= 0x9e00 && wc < 0x9fb0)
+ summary = &gb2312_uni2indx_page9e[(wc >> 4) - 0x9e0];
+ else if (wc >= 0xff00 && wc < 0xfff0)
+ summary = &gb2312_uni2indx_pageff[(wc >> 4) - 0xff0];
+ if (summary) {
+ unsigned short used = summary->used;
+ unsigned int i = wc & 0x0f;
+
+ if (used & ((unsigned short) 1 << i)) {
+ unsigned short c;
+
+ /* Keep in `used' only the bits 0..i-1. */
+ used &= ((unsigned short) 1 << i) - 1;
+ /* Add `summary->indx' and the number of bits set in `used'. */
+ used = (used & 0x5555) + ((used & 0xaaaa) >> 1);
+ used = (used & 0x3333) + ((used & 0xcccc) >> 2);
+ used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);
+ used = (used & 0x00ff) + (used >> 8);
+ c = gb2312_2charset[summary->indx + used];
+ r[0] = (c >> 8);
+ r[1] = (c & 0xff);
+ return 2;
+ }
+ }
+ return RET_ILUNI;
+ }
+ return RET_TOOSMALL;
+}
+
+int _gbk_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c = *s;
+
+ if (c >= 0x81 && c < 0xff) {
+ if (n < 2)
+ return RET_TOOFEW(0);
+ if (c >= 0xa1 && c <= 0xf7) {
+ unsigned char c2 = s[1];
+
+ if (c == 0xa1) {
+ if (c2 == 0xa4) {
+ *pwc = 0x00b7;
+ return 2;
+ }
+ if (c2 == 0xaa) {
+ *pwc = 0x2014;
+ return 2;
+ }
+ }
+ if (c2 >= 0xa1 && c2 < 0xff) {
+ unsigned char buf[2];
+ int ret;
+
+ buf[0] = c - 0x80;
+ buf[1] = c2 - 0x80;
+ ret = gb2312_mbtowc(pwc, buf, 2);
+ if (ret != RET_ILSEQ)
+ return ret;
+ buf[0] = c;
+ buf[1] = c2;
+ ret = cp936ext_mbtowc(pwc, buf, 2);
+ if (ret != RET_ILSEQ)
+ return ret;
+ }
+ }
+ if (c >= 0x81 && c <= 0xa0)
+ return gbkext1_mbtowc(pwc, s, 2);
+ if (c >= 0xa8 && c <= 0xfe)
+ return gbkext2_mbtowc(pwc, s, 2);
+ if (c == 0xa2) {
+ unsigned char c2 = s[1];
+
+ if (c2 >= 0xa1 && c2 <= 0xaa) {
+ *pwc = 0x2170 + (c2 - 0xa1);
+ return 2;
+ }
+ }
+ }
+ return RET_ILSEQ;
+}
+
+int _gbk_wctomb(unsigned char * r, ucs4_t wc, int n)
+{
+ unsigned char buf[2];
+ int ret;
+
+ if (wc != 0x30fb && wc != 0x2015) {
+ ret = gb2312_wctomb(buf, wc, 2);
+ if (ret != RET_ILUNI) {
+// if (ret != 2)
+// abort();
+// if (n < 2)
+ if (n <= 2)
+ return RET_TOOSMALL;
+ r[0] = buf[0] + 0x80;
+ r[1] = buf[1] + 0x80;
+ return 2;
+ }
+ }
+ ret = gbkext_inv_wctomb(buf, wc, 2);
+ if (ret != RET_ILUNI) {
+// if (ret != 2)
+// abort();
+// if (n < 2)
+ if (n <= 2)
+ return RET_TOOSMALL;
+ r[0] = buf[0];
+ r[1] = buf[1];
+ return 2;
+ }
+ if (wc >= 0x2170 && wc <= 0x2179) {
+ r[0] = 0xa2;
+ r[1] = 0xa1 + (wc - 0x2170);
+ return 2;
+ }
+ ret = cp936ext_wctomb(buf, wc, 2);
+ if (ret != RET_ILUNI) {
+// if (ret != 2)
+// abort();
+// if (n < 2)
+ if (n <= 2)
+ return RET_TOOSMALL;
+ r[0] = buf[0];
+ r[1] = buf[1];
+ return 2;
+ }
+ if (wc == 0x00b7) {
+ if (n < 2)
+ return RET_TOOSMALL;
+ r[0] = 0xa1;
+ r[1] = 0xa4;
+ return 2;
+ }
+ if (wc == 0x2014) {
+ if (n < 2)
+ return RET_TOOSMALL;
+ r[0] = 0xa1;
+ r[1] = 0xaa;
+ return 2;
+ }
+
+ return RET_ILUNI;
+}
+
+int gbk_mbtowc(ucs4_t * pwc, const unsigned char * s, int n)
+{
+ unsigned char c = *s;
+
+ /* Code set 0 (ASCII or GB 1988-89) */
+ if (c < 0x80)
+ return ascii_mbtowc(pwc, s, n);
+ /* Code set 1 (GBK) */
+ if (c >= 0x81 && c < 0xff) {
+ if (n < 2)
+ return RET_TOOFEW(0);
+ return _gbk_mbtowc(pwc, s, 2);
+ }
+ return RET_ILSEQ;
+}
+
+int gbk_wctomb(unsigned char * r, ucs4_t wc, int n)
+{
+ unsigned char buf[2];
+ int ret;
+
+ /* Code set 0 (ASCII or GB 1988-89) */
+ ret = ascii_wctomb(r, wc, n);
+ if (ret != RET_ILUNI)
+ return ret;
+
+ /* Code set 1 (GBK) */
+ ret = _gbk_wctomb(buf, wc, 2);
+ if (ret != RET_ILUNI) {
+// if (ret != 2)
+// abort();
+// if (n < 2)
+ if (n <= 2)
+ return RET_TOOSMALL;
+ r[0] = buf[0];
+ r[1] = buf[1];
+ return 2;
+ }
+ r[0] = 0xa1;
+ r[1] = 0xf6;
+
+ return 2;
+}
+
+/* bg5hk -> unicode */
+int charsets_bg5hk2cjk(const unsigned char * big5hk, unsigned char * cjk)
+{
+ //if(cjk==NULL)cjk=jis;
+ int transcount = 0;
+
+ if (big5hk[0] < 0x81) {
+ cjk[0] = big5hk[0];
+ transcount = 1;
+ } else {
+ unsigned int iunic = 0x1fff;
+
+ big5hkscs_mbtowc(&iunic, big5hk, 2);
+ transcount = gbk_wctomb(cjk, iunic, 2);
+ }
+ return transcount;
+}
+
+/* utf-32 (used in rar) string convert */
+extern unsigned int charsets_utf32_conv(const unsigned char * ucs, unsigned char * cjk)
+{
+ int i = 0, j = 0;
+
+ if (cjk == NULL)
+ cjk = (unsigned char *) ucs;
+
+ while (*(ucs + i) != 0 || *(ucs + i + 1) != 0 ||
+ *(ucs + i + 2) != 0 || *(ucs + i + 3) != 0) {
+ j += gbk_wctomb(cjk + j, *(unsigned short *) (ucs + i), 2);
+ i += 4;
+ }
+ cjk[j] = 0;
+ return j;
+}
+
+/* unicode string convert */
+extern unsigned int charsets_ucs_conv(const unsigned char * ucs, unsigned char * cjk)
+{
+ int i = 0, j = 0;
+
+ if (cjk == NULL)
+ cjk = (unsigned char *) ucs;
+
+ while (*(ucs + i) != 0 || *(ucs + i + 1) != 0) {
+ j += gbk_wctomb(cjk + j, *(unsigned short *) (ucs + i), 2);
+ i += 2;
+ }
+ cjk[j] = 0;
+ return j;
+}
+
+/* utf-8 string convert */
+extern unsigned int charsets_utf8_conv(const unsigned char * ucs, unsigned char * cjk)
+{
+ int i = 0, j = 0, l = strlen((const char *) ucs);
+
+ if (cjk == NULL)
+ cjk = (unsigned char *) ucs;
+
+ while (i < l) {
+ ucs4_t u = 0x1FFF;
+ int p = utf8_mbtowc(&u, ucs + i, l - i);
+
+ if (p < 0)
+ break;
+ if (u > 0xFFFF)
+ u = 0x1FFF;
+ j += gbk_wctomb(cjk + j, u, 2);
+ i += p;
+ }
+ cjk[j] = 0;
+ return j;
+}
+
+/* utf-16 string convert */
+extern unsigned int charsets_utf16_conv(const unsigned char * ucs, unsigned char * cjk)
+{
+ int i = 0, j = 0, l = strlen((const char *) ucs);
+
+ if (cjk == NULL)
+ cjk = (unsigned char *) ucs;
+ istate = 0;
+
+ while (i < l) {
+ ucs4_t u = 0x1FFF;
+ int p = utf16_mbtowc(&u, ucs + i, l - i);
+
+ if (p < 0)
+ break;
+ if (u > 0xFFFF)
+ u = 0x1FFF;
+ j += gbk_wctomb(cjk + j, u, 2);
+ i += p;
+ }
+ cjk[j] = 0;
+ return j;
+}
+
+/* utf-16be string convert */
+extern unsigned int charsets_utf16be_conv(const unsigned char * ucs, unsigned char * cjk)
+{
+ int i = 0, j = 0, l = strlen((const char *) ucs);
+
+ if (cjk == NULL)
+ cjk = (unsigned char *) ucs;
+
+ while (i < l) {
+ ucs4_t u = 0x1FFF;
+ int p = utf16be_mbtowc(&u, ucs + i, l - i);
+
+ if (p < 0)
+ break;
+ if (u > 0xFFFF)
+ u = 0x1FFF;
+ j += gbk_wctomb(cjk + j, u, 2);
+ i += p;
+ }
+ cjk[j] = 0;
+ return j;
+}
+
+/* big5 string convert */
+extern void charsets_big5_conv(const unsigned char * big5, unsigned char * cjk)
+{
+ int ilen = strlen((const char *) big5);
+ int i = 0;
+
+ if (cjk == NULL)
+ cjk = (unsigned char *) big5;
+
+ while (i < ilen)
+ i += charsets_bg5hk2cjk(big5 + i, cjk + i);
+ cjk[i] = 0;
+}
+
+/* sjis -> unicode */
+int charsets_sjis2cjk(const unsigned char * jis, unsigned char * cjk, int *pcount)
+{
+ unsigned int iunic = 0x1fff;
+
+ *pcount = shift_jisx0213_mbtowc(&iunic, jis, 2);
+ if (*pcount > 0)
+ return gbk_wctomb(cjk, iunic, 2);
+ else {
+ cjk[0] = 0xa1;
+ cjk[1] = 0xf6;
+ *pcount = 2;
+ return 2;
+ }
+}
+
+/* sjis string convert */
+extern void charsets_sjis_conv(const unsigned char * jis, unsigned char ** cjk, unsigned int * newsize)
+{
+ int ilen = *newsize, jlen = ilen;
+ int i = 0, j = 0, p = 0;
+
+ istate = 0;
+ unsigned char *cjks = (unsigned char *) malloc(ilen + 1);
+
+ if (cjks == NULL) {
+ *cjk = NULL;
+ *newsize = 0;
+ return;
+ }
+
+ while (i < ilen) {
+ j += charsets_sjis2cjk(jis + i, cjks + j, &p);
+ i += p;
+ if (j >= jlen - 1) {
+//FIXME:no this function
+// cjks = (unsigned char *) realloc_free_when_fail(cjks, jlen + 256);
+//void *realloc_free_when_fail(void *ptr, size_t size)
+//{
+// void *p = realloc(ptr, size);
+//
+// if (p == NULL) {
+// if (ptr)
+// free(ptr);
+// ptr = NULL;
+// }
+//
+// return p;
+//}
+ if (cjks == NULL) {
+ *cjk = NULL;
+ *newsize = 0;
+ return;
+ }
+ jlen += 256;
+ }
+ }
+ cjks[j] = 0;
+ *newsize = j;
+ *cjk = cjks;
+}
+
+extern unsigned short charsets_gbk_to_ucs(const unsigned char * cjk)
+{
+ ucs4_t u = 0;
+
+ if (gbk_mbtowc(&u, cjk, 2) < 1)
+ u = 0x1FFF;
+ return u;
+}
+
diff --git a/source/nds/charsets.h b/source/nds/charsets.h
new file mode 100644
index 0000000..28b7b7f
--- /dev/null
+++ b/source/nds/charsets.h
@@ -0,0 +1,13 @@
+#ifndef __CHARSETS_H__
+#define __CHARSETS_H__
+
+extern unsigned int charsets_utf32_conv(const unsigned char * ucs, unsigned char * cjk);
+extern unsigned int charsets_ucs_conv(const unsigned char * uni, unsigned char * cjk);
+extern void charsets_big5_conv(const unsigned char * big5, unsigned char * cjk);
+extern void charsets_sjis_conv(const unsigned char * jis, unsigned char ** cjk, unsigned int * newsize);
+extern unsigned int charsets_utf8_conv(const unsigned char * ucs, unsigned char * cjk);
+extern unsigned int charsets_utf16_conv(const unsigned char * ucs, unsigned char * cjk);
+extern unsigned int charsets_utf16be_conv(const unsigned char * ucs, unsigned char * cjk);
+extern unsigned short charsets_gbk_to_ucs(const unsigned char * cjk);
+
+#endif //__CHARSETS_H__
diff --git a/source/nds/cheats3.cpp b/source/nds/cheats3.cpp
new file mode 100644
index 0000000..bdb5545
--- /dev/null
+++ b/source/nds/cheats3.cpp
@@ -0,0 +1,206 @@
+/* cheats3.cpp
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "snes9x.h"
+#include "cheats.h"
+#include "memmap.h"
+#include "gcheat.h"
+
+extern SCheatData Cheat;
+
+int S9xAddCheat_ex (unsigned int address, unsigned char* cheat_dat, unsigned int cheat_dat_len,
+ unsigned int cheat_cell_num, unsigned int part_id, unsigned int str_num)
+{
+ if(cheat_cell_num < MAX_CHEATS_T)
+ {
+ Cheat.c[cheat_cell_num].address = address;
+ Cheat.c[cheat_cell_num].enabled = FALSE;
+
+ if(cheat_dat_len > 1)
+ memcpy(Cheat.c[cheat_cell_num].name, cheat_dat, cheat_dat_len);
+ else
+ Cheat.c[cheat_cell_num].byte = cheat_dat[0];
+
+ Cheat.c[cheat_cell_num].total_part = 0; //default are sub-part
+ Cheat.c[cheat_cell_num].part_id = part_id;
+ Cheat.c[cheat_cell_num].part_len = cheat_dat_len;
+ Cheat.c[cheat_cell_num].cheat_type = 0; //default are sub-part
+ Cheat.c[cheat_cell_num].name_id = str_num;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+void S9xAddCheat_ov(unsigned int cheat_cell_num, unsigned int total_part)
+{
+ if(cheat_cell_num < MAX_CHEATS_T)
+ {
+ Cheat.c[cheat_cell_num].total_part = total_part; //default are sub-part
+ Cheat.c[cheat_cell_num].cheat_type = 0x80;
+ }
+}
+
+static unsigned int S9xGetSub_id(unsigned int start, unsigned int sub_part)
+{
+ unsigned int i, m, n;
+
+ if(0 == sub_part)
+ return start;
+
+ if((start+1) >= g_cheat_cell_num)
+ return start;
+
+ m = 0;
+ for(i= start; i < g_cheat_cell_num; )
+ {
+ n = Cheat.c[i].total_part;
+ i += n;
+ m += 1;
+ if(m == sub_part) break;
+ }
+
+ return i;
+}
+
+unsigned int S9xGetCheat_nameid(unsigned int start, unsigned int part)
+{
+#if 0
+ unsigned int m, n, i;
+ unsigned int ret;
+ unsigned int cell_num;
+
+ cell_num = g_cheat_cell_num;
+
+ ret = Cheat.c[start].name_id;
+ if((start+1) >= cell_num)
+ return ret;
+
+ m = 0;
+ for(i = start; i < cell_num; ) {
+ if(m == part) break;
+ n = Cheat.c[i].total_part;
+ i += n;
+ m += 1;
+ }
+
+ if(i < cell_num)
+ ret = Cheat.c[i].name_id;
+
+ return ret;
+#else
+ unsigned int i;
+
+ i = S9xGetSub_id(start, part);
+ return Cheat.c[i].name_id;
+#endif
+}
+
+void S9xCheat_switch(unsigned int start, unsigned int sub_part, unsigned int enable)
+{
+ unsigned int i, m, n;
+
+ if((start+1) >= g_cheat_cell_num)
+ return;
+
+ i = S9xGetSub_id(start, sub_part);
+ m = Cheat.c[i].total_part;
+ for(n = 0; n < m; n++)
+ Cheat.c[i+n].enabled = enable;
+}
+
+static inline void S9xApplyCheat_ex(unsigned int start, unsigned int num)
+{
+ unsigned int i, m;
+ unsigned int address, len;
+
+ for(i = 0; i < num; i++)
+ {
+ address = Cheat.c[start+i].address;
+ len = Cheat.c[start+i].part_len;
+
+ int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK;
+ unsigned char *ptr = Memory.Map [block];
+
+ if(1 == len)
+ {
+ if (ptr >= (uint8 *) CMemory::MAP_LAST)
+ *(ptr + (address & 0xffff)) = Cheat.c[start+i].byte;
+ else
+ S9xSetByte (Cheat.c[start+i].byte, address);
+ }
+ else
+ {
+ for(m= 0; m < len; m++)
+ {
+ if (ptr >= (uint8 *) CMemory::MAP_LAST)
+ *(ptr + (address & 0xffff)) = Cheat.c[start+i].name[m];
+ else
+ S9xSetByte (Cheat.c[start+i].name[m], address);
+ }
+ }
+ }
+}
+
+void S9xApplyCheats_ex(void)
+{
+ unsigned int i, m, n;
+
+ if (Settings.ApplyCheats)
+ {
+ for(i= 0; i < g_cheat_cell_num; i++)
+ {
+ m = Cheat.c[i].total_part;
+ if(Cheat.c[i].enabled)
+ S9xApplyCheat_ex(i, m);
+ i += m;
+ }
+ }
+}
+
+#if 1
+extern "C" void dump_mem(unsigned char* addr, unsigned int len);
+
+void S9x_dumpcheat(unsigned int id)
+{
+ cprintf("\nid %d------------\n", id);
+ cprintf("total %d; part %d\n", Cheat.c[id].total_part, Cheat.c[id].part_id);
+ cprintf("address: %08x; data: %d\n", Cheat.c[id].address, Cheat.c[id].part_len);
+ if(Cheat.c[id].part_len == 1)
+ cprintf("data: %02x\n", Cheat.c[id].byte);
+ else
+ dump_mem((unsigned char*)Cheat.c[id].name, Cheat.c[id].part_len);
+ cprintf(" ------\n");
+}
+#endif
+
+void S9xCheat_Disable(void)
+{
+ Settings.ApplyCheats = FALSE;
+}
+
+void S9xCheat_Enable(void)
+{
+ Settings.ApplyCheats = TRUE;
+}
+
diff --git a/source/nds/displaymodes.cpp b/source/nds/displaymodes.cpp
new file mode 100644
index 0000000..4b52753
--- /dev/null
+++ b/source/nds/displaymodes.cpp
@@ -0,0 +1,53 @@
+//entry.c
+#include <stdio.h>
+
+#include "ds2_types.h"
+#include "ds2_cpu.h"
+#include "ds2_timer.h"
+#include "ds2io.h"
+#include "fs_api.h"
+
+
+#include "gfx.h"
+
+
+u32 y_scale_ = (224<<8) / 192;
+
+
+static inline void Put_Pixel (unsigned char* screen, int y, int y_scale)
+{
+
+ memcpy(&screen[((y<<1) << 8)], &GFX.Screen [(((y*y_scale)>>8)<<1) <<8], 256*2);
+}
+
+
+bool Draw_Frame_Flip(bool flip)
+{
+
+ int y = 0;
+
+ do
+ {
+ int tempy = y << 4;
+
+
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_+1);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);tempy++;
+ Put_Pixel ((unsigned char*)up_screen_addr, tempy, y_scale_);
+ }
+ while(++y < 12);
+ return 1;
+}
diff --git a/source/nds/draw.c b/source/nds/draw.c
new file mode 100644
index 0000000..6223c6e
--- /dev/null
+++ b/source/nds/draw.c
@@ -0,0 +1,1376 @@
+/* draw.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+//v1.1
+
+/******************************************************************************
+ * draw.cpp
+ * basic program to draw some graphic
+ ******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include "ds2_malloc.h"
+#include "ds2_cpu.h"
+#include "bdf_font.h"
+#include "gui.h"
+#include "bitmap.h"
+#include "draw.h"
+
+/******************************************************************************
+ * macro definition
+ ******************************************************************************/
+#define progress_sx (screen_width2 - SCREEN_WIDTH / 3) // Center -160/-80
+#define progress_ex (screen_width2 + SCREEN_WIDTH / 3) // Center +160/+80
+#define progress_sy (screen_height2 + 3) // Center +3
+#define progress_ey (screen_height2 + 13) // Center +13
+#define yesno_sx (screen_width2 - SCREEN_WIDTH / 3) // Center -160/-80
+#define yesno_ex (screen_width2 + SCREEN_WIDTH / 3) // Center +160/+80
+#define yesno_sy (screen_height2 + 3) // Center +3
+#define yesno_ey (screen_height2 + 13) // Center +13
+#define progress_color COLOR16(15,15,15)
+
+//#define progress_wait (0.5 * 1000 * 1000)
+#define progress_wait (OS_TICKS_PER_SEC/2) //0.5S
+
+#define FONTS_HEIGHT 14
+
+#define SCREEN_PITCH 256
+
+#define VRAM_POS(screen, x, y) ((unsigned short*)screen + (x + (y) * SCREEN_PITCH))
+
+#define BOOTLOGO "SYSTEM/GUI/boot.bmp"
+#define GUI_SOURCE_PATH "SYSTEM/GUI"
+#define GUI_PIC_BUFSIZE 1024*512
+
+u32 screen_height = 272;//160;
+u32 screen_width2 = 256/2;
+u32 screen_height2 = 160 / 2;
+
+char gui_picture[GUI_PIC_BUFSIZE];
+
+struct gui_iconlist gui_icon_list[]= {
+ //file system
+ /* 00 */ {"gbafile", 16, 15, NULL},
+ /* 01 */ {"zipfile", 16, 16, NULL},
+ /* 02 */ {"directory", 16, 16, NULL},
+ /* 03 */ {"sfcfile", 16, 16, NULL},
+
+ //title
+ /* 04 */ {"stitle", 256, 33, NULL},
+ //main menu
+ /* 05 */ {"savo", 52, 52, NULL},
+ /* 06 */ {"ssaveo", 52, 52, NULL},
+ /* 07 */ {"stoolo", 52, 52, NULL},
+ /* 08 */ {"scheato", 52, 52, NULL},
+ /* 09 */ {"sother", 52, 52, NULL},
+ /* 10 */ {"sexito", 52, 52, NULL},
+ /* 11 */ {"smsel", 79, 15, NULL},
+ /* 12 */ {"smnsel", 79, 15, NULL},
+
+ /* 13 */ {"snavo", 52, 52, NULL},
+ /* 14 */ {"snsaveo", 52, 52, NULL},
+ /* 15 */ {"sntoolo", 52, 52, NULL},
+ /* 16 */ {"sncheato", 52, 52, NULL},
+ /* 17 */ {"snother", 52, 52, NULL},
+ /* 18 */ {"snexito", 52, 52, NULL},
+
+ /* 19 */ {"sunnof", 16, 16, NULL},
+ /* 20 */ {"snewo", 89, 38, NULL},
+ /* 21 */ {"snnewo", 89, 38, NULL},
+ /* 22 */ {"sreseto", 86, 38, NULL},
+ /* 23 */ {"snreseto", 86, 38, NULL},
+ /* 24 */ {"sreteno", 81, 38, NULL},
+ /* 25 */ {"snreteno", 81, 38, NULL},
+ /* 26 */ {"smaybgo", 256, 192, NULL},
+
+ /* 27 */ {"sticon", 29, 13, NULL},
+ /* 28 */ {"ssubbg", 256, 192, NULL},
+
+ /* 29 */ {"subsela", 245, 22, NULL},
+ /* 30 */ {"subselb", 245, 22, NULL},
+ /* 31 */ {"sfullo", 12, 12, NULL},
+ /* 32 */ {"snfullo", 12, 12, NULL},
+ /* 33 */ {"semptyo", 12, 12, NULL},
+ /* 34 */ {"snemptyo", 12, 12, NULL},
+ /* 35 */ {"fdoto", 16, 16, NULL},
+ /* 36 */ {"backo", 19, 13, NULL},
+ /* 37 */ {"nbacko", 19, 13, NULL},
+ /* 38 */ {"chtfile", 16, 15, NULL},
+ /* 39 */ {"smsgfr", 193, 111, NULL},
+ /* 40 */ {"sbutto", 61, 16, NULL}
+ };
+
+
+/*
+* Drawing string aroud center
+*/
+void print_string_center(void* screen_addr, u32 sy, u32 color, u32 bg_color, char *str)
+{
+ int width = 0;//fbm_getwidth(str);
+ u32 sx = (SCREEN_WIDTH - width) / 2;
+
+ PRINT_STRING_BG(screen_addr, str, color, bg_color, sx, sy);
+}
+
+/*
+* Drawing string with shadow around center
+*/
+void print_string_shadow_center(void* screen_addr, u32 sy, u32 color, char *str)
+{
+ int width = 0;//fbm_getwidth(str);
+ u32 sx = (SCREEN_WIDTH - width) / 2;
+
+ PRINT_STRING_SHADOW(screen_addr, str, color, sx, sy);
+}
+
+/*
+* Drawing horizontal line
+*/
+void drawhline(void* screen_addr, u32 sx, u32 ex, u32 y, u32 color)
+{
+ u32 x;
+ u32 width = (ex - sx) + 1;
+ volatile u16 *dst = VRAM_POS(screen_addr, sx, y);
+
+ for (x = 0; x < width; x++)
+ *dst++ = (u16)color;
+}
+
+/*
+* Drawing vertical line
+*/
+void drawvline(void* screen_addr, u32 x, u32 sy, u32 ey, u32 color)
+{
+ int y;
+ int height = (ey - sy) + 1;
+ volatile u16 *dst = VRAM_POS(screen_addr, x, sy);
+
+ for (y = 0; y < height; y++)
+ {
+ *dst = (u16)color;
+ dst += SCREEN_PITCH;
+ }
+}
+
+/*
+* Drawing rectangle
+*/
+void drawbox(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 color)
+{
+ drawhline(screen_addr, sx, ex - 1, sy, color);
+ drawvline(screen_addr, ex, sy, ey - 1, color);
+ drawhline(screen_addr, sx + 1, ex, ey, color);
+ drawvline(screen_addr, sx, sy + 1, ey, color);
+}
+
+/*
+* Filling a rectangle
+*/
+void drawboxfill(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 color)
+{
+ u32 x, y;
+ u32 width = (ex - sx) + 1;
+ u32 height = (ey - sy) + 1;
+ volatile u16 *dst = VRAM_POS(screen_addr, sx, sy);
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ dst[x + y * SCREEN_PITCH] = (u16)color;
+ }
+ }
+}
+
+/*
+* Drawing a selection item
+- active 0 not fill
+- 1 fill with gray
+- 2 fill with color
+- 3 fill with color and most brithness
+- color 0 Red
+- 1 Green
+- 2 Blue
+------------------------------------------------------*/
+void draw_selitem(void* screen_addr, u32 x, u32 y, u32 color, u32 active)
+{
+ u32 size;
+ u32 color0, color1, color2, color3;
+
+ size= 10;
+
+ switch(active)
+ {
+ case 1:
+ color0 = COLOR16(12, 12, 12);
+ color1 = COLOR16(2, 2, 2);
+ color2 = COLOR16(7, 7, 7);
+ color3 = COLOR16(22, 22, 22);
+ break;
+ case 2:
+ switch(color)
+ {
+ case 0: //Red
+ color0 = COLOR16(12, 12, 12);
+ color1 = COLOR16(8, 0, 0);
+ color2 = COLOR16(16, 0, 0);
+ color3 = COLOR16(24, 0, 0);
+ break;
+ case 1: //Green
+ color0 = COLOR16(12, 12, 12);
+ color1 = COLOR16(0, 8, 0);
+ color2 = COLOR16(0, 16, 0);
+ color3 = COLOR16(0, 24, 0);
+ break;
+ case 2: //Blue
+ color0 = COLOR16(12, 12, 12);
+ color1 = COLOR16(0, 0, 8);
+ color2 = COLOR16(0, 0, 16);
+ color3 = COLOR16(0, 0, 24);
+ break;
+ default:
+ color0 = COLOR16(12, 12, 12);
+ color1 = COLOR16(0, 8, 0);
+ color2 = COLOR16(0, 16, 0);
+ color3 = COLOR16(0, 24, 0);
+ break;
+ }
+ break;
+ case 3:
+ switch(color)
+ {
+ case 0: //Red
+ color0 = COLOR16(31, 31, 31);
+ color1 = COLOR16(16, 0, 0);
+ color2 = COLOR16(22, 0, 0);
+ color3 = COLOR16(31, 0, 0);
+ break;
+ case 1: //Green
+ color0 = COLOR16(31, 31, 31);
+ color1 = COLOR16(0, 16, 0);
+ color2 = COLOR16(0, 22, 0);
+ color3 = COLOR16(0, 31, 0);
+ break;
+ case 2: //Blue
+ color0 = COLOR16(31, 31, 31);
+ color1 = COLOR16(0, 0, 16);
+ color2 = COLOR16(0, 0, 22);
+ color3 = COLOR16(0, 0, 31);
+ break;
+ default:
+ color0 = COLOR16(31, 31, 31);
+ color1 = COLOR16(0, 16, 0);
+ color2 = COLOR16(0, 22, 0);
+ color3 = COLOR16(0, 31, 0);
+ break;
+ }
+ break;
+ default:
+ color0= COLOR16(18, 18, 18);
+ color1= color2= color3= COLOR16(18, 18, 18);
+ break;
+ }
+
+ drawbox(screen_addr, x, y, x+size-1, y+size-1, color0);
+
+ if(active >0)
+ {
+ drawbox(screen_addr, x+1, y+1, x+size-2, y+size-2, color1);
+ drawbox(screen_addr, x+2, y+2, x+size-3, y+size-3, color2);
+ drawboxfill(screen_addr, x+3, y+3, x+size-4, y+size-4, color3);
+ }
+}
+
+/*
+* Drawing message box
+* Note if color_fg is transparent, screen_bg can't be transparent
+*/
+void draw_message(void* screen_addr, u16 *screen_bg, u32 sx, u32 sy, u32 ex, u32 ey,
+ u32 color_fg)
+{
+ if(!(color_fg & 0x8000))
+ {
+// drawbox(screen_addr, sx, sy, ex, ey, COLOR16(12, 12, 12));
+// drawboxfill(screen_addr, sx+1, sy+1, ex-1, ey-1, color_fg);
+ show_icon(screen_addr, ICON_MSG, 34, 48);
+ }
+ else
+ {
+ u16 *screenp, *screenp1;
+ u32 width, height, i, k;
+ u32 tmp, tmp1, tmp2;
+ u32 r, g, b;
+
+ width= ex-sx;
+ height= ey-sy;
+ r= ((color_fg >> 10) & 0x1F) * 6/7;
+ g= ((color_fg >> 5) & 0x1F) * 6/7;
+ b= (color_fg & 0x1F) * 6/7;
+ for(k= 0; k < height; k++)
+ {
+ screenp = VRAM_POS(screen_addr, sx, sy+k);
+ screenp1 = screen_bg + sx + (sy + k) * SCREEN_PITCH;
+ for(i= 0; i < width; i++)
+ {
+ tmp = *screenp1++;
+ tmp1 = ((tmp >> 10) & 0x1F) *1/7 + r;
+ tmp2 = (tmp1 > 31) ? 31 : tmp1;
+ tmp1 = ((tmp >> 5) & 0x1F) *1/7 + g;
+ tmp2 = (tmp2 << 5) | ((tmp1 > 31) ? 31 : tmp1);
+ tmp1 = (tmp & 0x1F) *1/7 + b;
+ tmp2 = (tmp2 << 5) | ((tmp1 > 31) ? 31 : tmp1);
+ *screenp++ = tmp2;
+ }
+ }
+ }
+}
+
+/*
+* Drawing string horizontal center aligned
+*/
+void draw_string_vcenter(void* screen_addr, u32 sx, u32 sy, u32 width, u32 color_fg, char *string)
+{
+ u32 x, num, i, m;
+ u16 *screenp;
+ u16 unicode[256];
+
+ num= 0;
+ while(*string)
+ {
+ string= utf8decode(string, unicode+num);
+ if(unicode[num] != 0x0D && unicode[num] != 0x0A) num++;
+ }
+
+ if(num== 0) return;
+
+ i= BDF_cut_unicode(unicode, num, width, 1);
+ if(i == num)
+ {
+ x= BDF_cut_unicode(unicode, num, 0, 3);
+ sx += (width - x)/2;
+ }
+
+ screenp = (unsigned short*)screen_addr + sx + sy*SCREEN_WIDTH;
+ i= 0;
+ while(i < num)
+ {
+ m= BDF_cut_unicode(&unicode[i], num-i, width, 1);
+ x= 0;
+ while(m--)
+ {
+ x += BDF_render16_ucs(screenp+x, SCREEN_WIDTH, 0, COLOR_TRANS,
+ color_fg, unicode[i++]);
+ }
+ screenp += FONTS_HEIGHT * SCREEN_WIDTH;
+ }
+}
+
+/*------------------------------------------------------
+ Drawing a scroll string
+------------------------------------------------------*/
+//limited
+// < 256 Unicodes
+// width < 256+128
+//#define MAX_SCROLL_STRING 8
+
+/*------------------------------------------------------
+- scroll_val < 0 scroll toward left
+- > 0 scroll toward right
+------------------------------------------------------*/
+struct scroll_string_info{
+ u16 *screenp;
+ u32 sx;
+ u32 sy;
+ u32 width;
+ u32 height;
+ u16 *unicode;
+ u32 color_bg;
+ u32 color_fg;
+ u16 *buff_fonts;
+ u32 buff_width;
+ u16 *buff_bg;
+ s32 pos_pixel;
+ u32 str_start;
+ u32 str_end;
+ u32 str_len;
+};
+
+static struct scroll_string_info scroll_strinfo[MAX_SCROLL_STRING];
+static u32 scroll_string_num= 0;
+
+u32 draw_hscroll_init(void* screen_addr, u32 sx, u32 sy, u32 width,
+ u32 color_bg, u32 color_fg, char *string)
+{
+ u32 index, x, num, len, i;
+ u16 *unicode, *screenp;
+
+ for(i= 0; i < MAX_SCROLL_STRING; i++)
+ {
+ if(scroll_strinfo[i].screenp == NULL)
+ break;
+ }
+
+ if(i >= MAX_SCROLL_STRING)
+ return -1;
+
+ index= i;
+ screenp= (u16*)malloc((256+128)*FONTS_HEIGHT*2);
+ if(screenp == NULL)
+ {
+ scroll_strinfo[index].str_len = 0;
+ return -2;
+ }
+
+ unicode= (u16*)malloc(256*2);
+ if(unicode == NULL)
+ {
+ scroll_strinfo[index].str_len = 0;
+ free((void*)screenp);
+ return -3;
+ }
+
+ if(color_bg == COLOR_TRANS)
+ memset(screenp, 0, (256+128)*FONTS_HEIGHT*2);
+
+ scroll_string_num += 1;
+ scroll_strinfo[index].screenp = (unsigned short*)screen_addr;
+ scroll_strinfo[index].sx= sx;
+ scroll_strinfo[index].sy= sy;
+ scroll_strinfo[index].color_bg= color_bg;
+ scroll_strinfo[index].color_fg= color_fg;
+ scroll_strinfo[index].width= width;
+ scroll_strinfo[index].height= FONTS_HEIGHT;
+ scroll_strinfo[index].unicode= unicode;
+ scroll_strinfo[index].buff_fonts= screenp;
+ scroll_strinfo[index].buff_bg= 0;
+
+ num= 0;
+ while(*string)
+ {
+ string= utf8decode(string, unicode+num);
+ if(unicode[num] != 0x0D && unicode[num] != 0x0A) num++;
+ }
+
+ scroll_strinfo[index].str_len= num;
+ if(num == 0)
+ return index;
+
+ len= BDF_cut_unicode(unicode, num, 256+128, 1);
+ i= 0;
+ x= 0;
+ while(i < len)
+ {
+ x += BDF_render16_ucs(screenp + x, 256+128, 0, color_bg, color_fg, unicode[i++]);
+ }
+
+ scroll_strinfo[index].buff_width= x;
+ scroll_strinfo[index].pos_pixel= 0;
+ scroll_strinfo[index].str_start= 0;
+ scroll_strinfo[index].str_end= len-1;
+
+ num= scroll_strinfo[index].height;
+ len= width;
+
+ u16 *screenp1;
+
+ if(color_bg == COLOR_TRANS)
+ {
+ u16 pixel;
+
+ for(i= 0; i < num; i++)
+ {
+ screenp= (unsigned short*)screen_addr + sx + (sy + i) * SCREEN_WIDTH;
+ screenp1= scroll_strinfo[index].buff_fonts + i*(256+128);
+ for(x= 0; x < len; x++)
+ {
+ pixel= *screenp1++;
+ if(pixel) *screenp = pixel;
+ screenp ++;
+ }
+ }
+ }
+ else
+ {
+ screenp= (unsigned short*)screen_addr + sx + sy * SCREEN_WIDTH;
+ screenp1= scroll_strinfo[index].buff_fonts;
+
+ for(i= 0; i < num; i++)
+ {
+ memcpy((char*)screenp, (char*)screenp1, len*2);
+ screenp += SCREEN_WIDTH;
+ screenp1 += (256+128);
+ }
+ }
+
+ return index;
+}
+
+u32 draw_hscroll(u32 index, s32 scroll_val)
+{
+ u32 color_bg, color_fg, i, width, height;
+ s32 xoff;
+
+//static int flag= 0;
+
+ if(index >= MAX_SCROLL_STRING) return -1;
+ if(scroll_strinfo[index].screenp == NULL) return -2;
+ if(scroll_strinfo[index].str_len == 0) return 0;
+
+ width= scroll_strinfo[index].width;
+ height= scroll_strinfo[index].height;
+ xoff= scroll_strinfo[index].pos_pixel - scroll_val;
+ color_bg= scroll_strinfo[index].color_bg;
+ color_fg= scroll_strinfo[index].color_fg;
+
+ if(scroll_val > 0) //shift right
+ {
+ if(xoff <= 0)
+ {
+ if(scroll_strinfo[index].str_start > 0)
+ {
+ u32 x, y, len;
+ u16 *unicode;
+ u32 *ptr;
+ //we assume the malloced memory are 4 bytes aligned, or else this method is wrong
+ y= height*width;
+ ptr= (u32*)scroll_strinfo[index].buff_fonts;
+ y= ((256+128)*FONTS_HEIGHT*2+3)/4;
+ x= 0;
+ while(x<y) ptr[x++] = 0;
+
+ unicode= scroll_strinfo[index].unicode + scroll_strinfo[index].str_end;
+ len= scroll_strinfo[index].str_end +1;
+ x= (scroll_val > SCREEN_WIDTH/4) ? scroll_val : SCREEN_WIDTH/4;
+ y= BDF_cut_unicode(unicode, len, x, 0);
+ if(y < len) y += 1;
+
+ if(y < scroll_strinfo[index].str_start)
+ scroll_strinfo[index].str_start -= y;
+ else
+ {
+ y= scroll_strinfo[index].str_start;
+ scroll_strinfo[index].str_start = 0;
+ }
+
+ len= scroll_strinfo[index].str_len - scroll_strinfo[index].str_start;
+ unicode= scroll_strinfo[index].unicode + scroll_strinfo[index].str_start;
+ x= 0;
+ i= 0;
+ while(i < y)
+ {
+ x += BDF_render16_ucs(scroll_strinfo[index].buff_fonts + x, 256+128, 0,
+ color_bg, color_fg, unicode[i++]);
+ if(x >= (256+128-14)) break;
+ }
+
+ y= x;
+ while(i < len)
+ {
+ x += BDF_render16_ucs(scroll_strinfo[index].buff_fonts + x, 256+128, 0,
+ color_bg, color_fg, unicode[i++]);
+ if(x >= (256+128-14)) break;
+ }
+
+ scroll_strinfo[index].pos_pixel += y - scroll_val;
+ if((scroll_strinfo[index].pos_pixel + width) > (256+128))
+ scroll_strinfo[index].pos_pixel= 0;
+ scroll_strinfo[index].buff_width= x;
+ scroll_strinfo[index].str_end = scroll_strinfo[index].str_start + i -1;
+ }
+ else
+ {
+ if(scroll_strinfo[index].pos_pixel > 0)
+ scroll_strinfo[index].pos_pixel= 0;
+ else
+ return 0;
+ }
+
+ xoff= scroll_strinfo[index].pos_pixel;
+ }
+ else
+ scroll_strinfo[index].pos_pixel= xoff;
+ }
+ else if(xoff < (s32)scroll_strinfo[index].buff_width) //shift left
+ {
+ if((scroll_strinfo[index].buff_width + width) > (256+128))
+ if((xoff + width) > scroll_strinfo[index].buff_width)
+ {
+ u32 x, y, len;
+ u16 *unicode;
+ u32 *ptr;
+ //we assume the malloced memory are 4 bytes aligned, or else this method is wrong
+ y= height*width;
+ ptr= (u32*)scroll_strinfo[index].buff_fonts;
+ y= ((256+128)*FONTS_HEIGHT*2+3)/4;
+ x= 0;
+ while(x<y) ptr[x++] = 0;
+
+ unicode= scroll_strinfo[index].unicode + scroll_strinfo[index].str_start;
+ len= scroll_strinfo[index].str_len - scroll_strinfo[index].str_start;
+ x= (scroll_val > SCREEN_WIDTH/4) ? scroll_val : SCREEN_WIDTH/4;
+ x= ((s32)x < xoff) ? x : xoff;
+ y= BDF_cut_unicode(unicode, len, x, 1);
+
+ scroll_strinfo[index].str_start += y;
+ len= scroll_strinfo[index].str_len - scroll_strinfo[index].str_start;
+ y= scroll_strinfo[index].str_end - scroll_strinfo[index].str_start +1;
+ unicode= scroll_strinfo[index].unicode + scroll_strinfo[index].str_start;
+ x= 0;
+ i= 0;
+ while(i < y)
+ {
+ x += BDF_render16_ucs(scroll_strinfo[index].buff_fonts + x, 256+128, 0,
+ color_bg, color_fg, unicode[i++]);
+ }
+
+ xoff -= scroll_strinfo[index].buff_width - x;
+
+ while(i < len)
+ {
+ x += BDF_render16_ucs(scroll_strinfo[index].buff_fonts + x, 256+128, 0,
+ color_bg, color_fg, unicode[i++]);
+ if(x >= (256+128-14)) break;
+ }
+
+ scroll_strinfo[index].buff_width= x;
+ scroll_strinfo[index].str_end = scroll_strinfo[index].str_start + i -1;
+ }
+
+ scroll_strinfo[index].pos_pixel= xoff;
+ }
+ else
+ return 0;
+
+ u32 x, sx, sy, pixel;
+ u16 *screenp, *screenp1;
+
+ color_bg = scroll_strinfo[index].color_bg;
+ sx= scroll_strinfo[index].sx;
+ sy= scroll_strinfo[index].sy;
+
+ if(color_bg == COLOR_TRANS)
+ {
+ for(i= 0; i < height; i++)
+ {
+ screenp= scroll_strinfo[index].screenp + sx + (sy + i) * SCREEN_WIDTH;
+ screenp1= scroll_strinfo[index].buff_fonts + xoff + i*(256+128);
+ for(x= 0; x < width; x++)
+ {
+ pixel= *screenp1++;
+ if(pixel) *screenp = pixel;
+ screenp ++;
+ }
+ }
+ }
+ else
+ {
+ for(i= 0; i < height; i++)
+ {
+ screenp= scroll_strinfo[index].screenp + sx + (sy + i) * SCREEN_WIDTH;
+ screenp1= scroll_strinfo[index].buff_fonts + xoff + i*(256+128);
+ for(x= 0; x < width; x++)
+ *screenp++ = *screenp1++;
+ }
+ }
+
+ u32 ret;
+ if(scroll_val > 0)
+ ret= scroll_strinfo[index].pos_pixel;
+ else
+ ret= scroll_strinfo[index].buff_width - scroll_strinfo[index].pos_pixel;
+
+ return ret;
+}
+
+void draw_hscroll_over(u32 index)
+{
+ if(scroll_strinfo[index].screenp== NULL)
+ return;
+
+ if(index < MAX_SCROLL_STRING && scroll_string_num > 0)
+ {
+ if(scroll_strinfo[index].unicode)
+ {
+ free((void*)scroll_strinfo[index].unicode);
+ scroll_strinfo[index].unicode= NULL;
+ }
+ if(scroll_strinfo[index].buff_fonts)
+ {
+ free((void*)scroll_strinfo[index].buff_fonts);
+ scroll_strinfo[index].buff_fonts= NULL;
+ }
+ scroll_strinfo[index].screenp= NULL;
+ scroll_strinfo[index].str_len= 0;
+
+ scroll_string_num -=1;
+ }
+}
+
+/*
+* Drawing dialog
+*/
+void draw_dialog(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey)
+{
+ drawboxfill(screen_addr, sx + 5, sy + 5, ex + 5, ey + 5, COLOR_DIALOG_SHADOW);
+
+ drawhline(screen_addr, sx, ex - 1, sy, COLOR_FRAME);
+ drawvline(screen_addr, ex, sy, ey - 1, COLOR_FRAME);
+ drawhline(screen_addr, sx + 1, ex, ey, COLOR_FRAME);
+ drawvline(screen_addr, sx, sy + 1, ey, COLOR_FRAME);
+
+ sx++;
+ ex--;
+ sy++;
+ ey--;
+
+ drawhline(screen_addr, sx, ex - 1, sy, COLOR_FRAME);
+ drawvline(screen_addr, ex, sy, ey - 1, COLOR_FRAME);
+ drawhline(screen_addr, sx + 1, ex, ey, COLOR_FRAME);
+ drawvline(screen_addr, sx, sy + 1, ey, COLOR_FRAME);
+
+ sx++;
+ ex--;
+ sy++;
+ ey--;
+
+ drawboxfill(screen_addr, sx, sy, ex, ey, COLOR_DIALOG);
+}
+
+/*
+* Draw yer or no dialog
+*/
+u32 draw_yesno_dialog(enum SCREEN_ID screen, u32 sy, char *yes, char *no)
+{
+ u16 unicode[8];
+ u32 len, width, box_width, i;
+ char *string;
+ void* screen_addr;
+
+ len= 0;
+ string= yes;
+ while(*string)
+ {
+ string= utf8decode(string, &unicode[len]);
+ if(unicode[len] != 0x0D && unicode[len] != 0x0A)
+ {
+ if(len < 8) len++;
+ else break;
+ }
+ }
+ width= BDF_cut_unicode(unicode, len, 0, 3);
+
+ len= 0;
+ string= no;
+ while(*string)
+ {
+ string= utf8decode(string, &unicode[len]);
+ if(unicode[len] != 0x0D && unicode[len] != 0x0A)
+ {
+ if(len < 8) len++;
+ else break;
+ }
+ }
+ i= BDF_cut_unicode(unicode, len, 0, 3);
+
+ if(width < i) width= i;
+ box_width= 64;
+ if(box_width < (width +6)) box_width = width +6;
+
+ if(screen & UP_MASK)
+ screen_addr = up_screen_addr;
+ else
+ screen_addr = down_screen_addr;
+
+ i= SCREEN_WIDTH/2 - box_width - 2;
+// drawbox(screen_address, i, sy-1, i+box_width-1, sy+FONTS_HEIGHT, COLOR16(8, 8, 8));
+// drawboxfill(screen_address, i+1, sy, i+box_width-2, sy+FONTS_HEIGHT-1, COLOR16(15, 15, 15));
+ show_icon((unsigned short*)screen_addr, ICON_BUTTON, 64, 128);
+// draw_string_vcenter(screen_address, i+1, sy+1, box_width, COLOR_WHITE, yes);
+ draw_string_vcenter((unsigned short*)screen_addr, 66, 130, 58, COLOR_WHITE, yes);
+
+ i= SCREEN_WIDTH/2 + 3;
+// drawbox(screen_address, i, sy-1, i+box_width-1, sy+FONTS_HEIGHT, COLOR16(8, 8, 8));
+// drawboxfill(screen_address, i+1, sy, i+box_width-2, sy+FONTS_HEIGHT-1, COLOR16(15, 15, 15));
+ show_icon((unsigned short*)screen_addr, ICON_BUTTON, 136, 128);
+// draw_string_vcenter(screen_address, i+1, sy+1, box_width, COLOR_WHITE, no);
+ draw_string_vcenter((unsigned short*)screen_addr, 138, 130, 58, COLOR_WHITE, no);
+
+ ds2_flipScreen(screen, 1);
+
+ gui_action_type gui_action = CURSOR_NONE;
+ while((gui_action != CURSOR_SELECT) && (gui_action != CURSOR_BACK))
+ {
+ gui_action = get_gui_input();
+// OSTimeDly(OS_TICKS_PER_SEC/10);
+ mdelay(100);
+ }
+
+ if (gui_action == CURSOR_SELECT)
+ return 1;
+ else
+ return 0;
+}
+
+/*
+* Drawing progress bar
+*/
+static enum SCREEN_ID _progress_screen_id;
+static int progress_total;
+static int progress_current;
+static char progress_message[256];
+
+// progress bar initialize
+void init_progress(enum SCREEN_ID screen, u32 total, char *text)
+{
+ void* screen_addr;
+
+ _progress_screen_id = screen;
+ if(_progress_screen_id & UP_MASK)
+ screen_addr = up_screen_addr;
+ else
+ screen_addr = down_screen_addr;
+
+ progress_current = 0;
+ progress_total = total;
+// strcpy(progress_message, text);
+
+// draw_dialog(progress_sx - 8, progress_sy -29, progress_ex + 8, progress_ey + 13);
+
+// boxfill(progress_sx - 1, progress_sy - 1, progress_ex + 1, progress_ey + 1, 0);
+
+// if (text[0] != '\0')
+// print_string_center(progress_sy - 21, COLOR_PROGRESS_TEXT, COLOR_DIALOG, text);
+
+ drawboxfill((unsigned short*)screen_addr, progress_sx, progress_sy, progress_ex,
+ progress_ey, COLOR16(15, 15, 15));
+
+ ds2_flipScreen(_progress_screen_id, 1);
+}
+
+// update progress bar
+void update_progress(void)
+{
+ void* screen_addr;
+
+ if(_progress_screen_id & UP_MASK)
+ screen_addr = up_screen_addr;
+ else
+ screen_addr = down_screen_addr;
+
+ int width = (int)( ((float)++progress_current / (float)progress_total) * ((float)SCREEN_WIDTH / 3.0 * 2.0) );
+
+// draw_dialog(progress_sx - 8, progress_sy -29, progress_ex + 8, progress_ey + 13);
+
+// boxfill(progress_sx - 1, progress_sy - 1, progress_ex + 1, progress_ey + 1, COLOR_BLACK);
+// if (progress_message[0] != '\0')
+// print_string_center(progress_sy - 21, COLOR_PROGRESS_TEXT, COLOR_DIALOG, progress_message);
+
+ drawboxfill(screen_addr, progress_sx, progress_sy, progress_sx+width, progress_ey, COLOR16(30, 19, 7));
+
+ ds2_flipScreen(_progress_screen_id, 1);
+}
+
+// display progress string
+void show_progress(char *text)
+{
+ void* screen_addr;
+
+ if(_progress_screen_id & UP_MASK)
+ screen_addr = up_screen_addr;
+ else
+ screen_addr = down_screen_addr;
+
+// draw_dialog(progress_sx - 8, progress_sy -29, progress_ex + 8, progress_ey + 13);
+// boxfill(progress_sx - 1, progress_sy - 1, progress_ex + 1, progress_ey + 1, COLOR_BLACK);
+
+ if (progress_current)
+ {
+ int width = (int)( (float)(++progress_current / progress_total) * (float)(SCREEN_WIDTH / 3.0 * 2.0) );
+ drawboxfill(screen_addr, progress_sx, progress_sy, progress_sx+width, progress_ey, COLOR16(30, 19, 7));
+ }
+
+// if (text[0] != '\0')
+// print_string_center(progress_sy - 21, COLOR_PROGRESS_TEXT, COLOR_DIALOG, text);
+
+ ds2_flipScreen(_progress_screen_id, 1);
+
+// OSTimeDly(progress_wait);
+ mdelay(500);
+}
+
+/*
+* Drawing scroll bar
+*/
+#define SCROLLBAR_COLOR1 COLOR16( 0, 2, 8)
+#define SCROLLBAR_COLOR2 COLOR16(15,15,15)
+
+void scrollbar(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 all, u32 view, u32 now)
+{
+ u32 scrollbar_sy;
+ u32 scrollbar_ey;
+ u32 len;
+
+ len = ey - sy - 2;
+
+ if ((all != 0) && (all > now))
+ scrollbar_sy = (u32)((float)len * (float)now / (float)all) +sy + 1;
+ else
+ scrollbar_sy = sy + 1;
+
+ if ((all > (now + view)) && (all != 0))
+ scrollbar_ey = (u32)((float)len * (float)(now + view) / (float)all ) + sy + 1;
+ else
+ scrollbar_ey = len + sy + 1;
+
+ drawbox(screen_addr, sx, sy, ex, ey, COLOR_BLACK);
+ drawboxfill(screen_addr, sx + 1, sy + 1, ex - 1, ey - 1, SCROLLBAR_COLOR1);
+ drawboxfill(screen_addr, sx + 1, scrollbar_sy, ex - 1, scrollbar_ey, SCROLLBAR_COLOR2);
+}
+
+#if 0
+static struct background back_ground = {{0}, {0}};
+
+int show_background(void *screen, char *bgname)
+{
+ int ret;
+
+ if(strcasecmp(bgname, back_ground.bgname))
+ {
+ char *buff, *src;
+ int x, y;
+ unsigned short *dst;
+ unsigned int type;
+
+ buff= (char*)malloc(256*192*4);
+
+ ret= BMP_read(bgname, buff, 256, 192, &type);
+ if(ret != BMP_OK)
+ {
+ free((int)buff);
+ return(-1);
+ }
+
+ src = buff;
+
+ if(type ==2) //2 bytes per pixel
+ {
+ unsigned short *pt;
+ pt = (unsigned short*)buff;
+// memcpy((char*)back_ground.bgbuffer, buff, 256*192*2);
+ dst=(unsigned short*)back_ground.bgbuffer;
+ for(y= 0; y< 192; y++)
+ {
+ for(x= 0; x< 256; x++)
+ {
+ *dst++= RGB16_15(pt);
+ pt += 1;
+ }
+ }
+ }
+ else if(type ==3) //3 bytes per pixel
+ {
+ dst=(unsigned short*)back_ground.bgbuffer;
+ for(y= 0; y< 192; y++)
+ {
+ for(x= 0; x< 256; x++)
+ {
+ *dst++= RGB24_15(buff);
+ buff += 3;
+ }
+ }
+ }
+ else
+ {
+ free((int)buff);
+ return(-1);
+ }
+
+ free((int)src);
+ strcpy(back_ground.bgname, bgname);
+ }
+
+ memcpy((char*)screen, back_ground.bgbuffer, 256*192*2);
+
+ return 0;
+}
+#endif
+
+/*
+* change GUI icon
+*/
+int gui_change_icon(u32 language_id)
+{
+ char path[128];
+ char fpath[8];
+ u32 i, item;
+ int err, ret;
+ char *buff, *src;
+ u32 x, y;
+ char *icondst;
+ unsigned int type;
+
+ item= sizeof(gui_icon_list)/16;
+ buff= (char*)malloc(256*192*4);
+ if(buff == NULL)
+ return -1;
+
+ ret= 0;
+ icondst= gui_picture;
+
+ sprintf(fpath, "%d.bmp", language_id);
+ for(i= 0; i< item; i++)
+ {
+ sprintf(path, "%s/%s/%s%s", main_path, GUI_SOURCE_PATH, gui_icon_list[i].iconname, fpath);
+
+ src= buff;
+ err= BMP_read(path, src, gui_icon_list[i].x, gui_icon_list[i].y, &type);
+ if(err != BMP_OK)
+ {
+ sprintf(path, "%s/%s/%s%s", main_path, GUI_SOURCE_PATH, gui_icon_list[i].iconname, ".bmp");
+ err= BMP_read(path, src, gui_icon_list[i].x, gui_icon_list[i].y, &type);
+ }
+
+ if(type < 2) //< 1 byte per pixels, not surpport now
+ {
+ if(!ret) ret = -(i+1);
+ gui_icon_list[i].iconbuff= NULL;
+ continue;
+ }
+
+ if(err == BMP_OK)
+ {
+ unsigned short *dst;
+
+ if(icondst >= gui_picture + GUI_PIC_BUFSIZE -1)
+ {
+ ret = 1;
+ break;
+ }
+
+ if(type == 2)
+ {
+ unsigned short *pt;
+ pt = (unsigned short*)src;
+// memcpy((char*)icondst, src, 256*192*2);
+ dst = (unsigned short*)icondst;
+ for(y= 0; y< gui_icon_list[i].y; y++)
+ {
+ for(x= 0; x < gui_icon_list[i].x; x++)
+ {
+ *dst++ = RGB16_15(pt);
+ pt += 1;
+ }
+ }
+ }
+
+ if(type == 3)
+ {
+ dst = (unsigned short*)icondst;
+ for(y= 0; y< gui_icon_list[i].y; y++)
+ {
+ for(x= 0; x < gui_icon_list[i].x; x++)
+ {
+ *dst++ = RGB24_15(src);
+ src += 3;
+ }
+ }
+ }
+
+ gui_icon_list[i].iconbuff= icondst;
+ icondst += gui_icon_list[i].x*gui_icon_list[i].y*2;
+ }
+ else
+ {
+ if(!ret) ret = -(i+1);
+ gui_icon_list[i].iconbuff= NULL;
+ }
+ }
+
+ free((void*)buff);
+//printf("icon_buf: %08x\n", icondst - gui_picture );
+ return ret;
+}
+
+/*************************************************************/
+int icon_init(u32 language_id)
+{
+ u32 i;
+ int ret;
+
+//Initial draw_scroll_string function
+ scroll_string_num = 0;
+ for(i= 0; i < MAX_SCROLL_STRING; i++)
+ {
+ scroll_strinfo[i].unicode= NULL;
+ scroll_strinfo[i].buff_fonts= NULL;
+ scroll_strinfo[i].screenp = NULL;
+ scroll_strinfo[i].str_len = 0;
+ }
+
+ ret= gui_change_icon(language_id);
+
+//#define GUI_INIT_DEBUG
+#if 0
+ item= sizeof(gui_icon_list)/12;
+ buff= (char*)malloc(256*192*4);
+ src= buff;
+ ret= 0;
+ icondst= gui_picture;
+
+ for(i= 0; i< item; i++)
+ {
+ sprintf(path, "%s\\%s", GUI_SOURCE_PATH, gui_icon_list[i].iconname);
+
+ err= BMP_read(path, buff, gui_icon_list[i].x, gui_icon_list[i].y);
+ if(err == BMP_OK)
+ {
+ unsigned short *dst;
+
+ if(icondst >= gui_picture + GUI_PIC_BUFSIZE -1)
+ {
+ ret = 1;
+#ifdef GUI_INIT_DEBUG
+ printf("GUI Initial overflow\n");
+#endif
+ break;
+ }
+
+ for(y= 0; y< gui_icon_list[i].y; y++)
+ {
+ dst= (unsigned short*)(icondst + (gui_icon_list[i].y - y -1)*gui_icon_list[i].x*2);
+ for(x= 0; x < gui_icon_list[i].x; x++)
+ {
+ *dst++ = RGB24_15(buff);
+ buff += 4;
+ }
+ }
+
+ gui_icon_list[i].iconname= icondst;
+ icondst += gui_icon_list[i].x*gui_icon_list[i].y*2;
+ }
+ else
+ if(!ret)
+ {
+ ret = -(i+1);
+ gui_icon_list[i].iconname= NULL;
+#ifdef GUI_INIT_DEBUG
+ printf("GUI Initial: %s not open\n", path);
+#endif
+ }
+ }
+
+#ifdef GUI_INIT_DEBUG
+ printf("GUI buff %d\n", icondst - gui_picture);
+#endif
+
+ free((int)src);
+#endif
+
+ return ret;
+}
+
+/*************************************************************/
+void show_icon(void* screen, struct gui_iconlist icon, u32 x, u32 y)
+{
+ u32 i, k;
+ unsigned short *src, *dst;
+
+ src= (unsigned short*)icon.iconbuff;
+ dst = (unsigned short*)screen + y*NDS_SCREEN_WIDTH + x;
+ if(NULL == src) return; //The icon may initialized failure
+
+ for(i= 0; i < icon.y; i++)
+ {
+ for(k= 0; k < icon.x; k++)
+ {
+ if(0x03E0 != *src) dst[k]= *src;
+ src++;
+ }
+
+ dst += NDS_SCREEN_WIDTH;
+ }
+}
+
+/*************************************************************/
+void show_Vscrollbar(char *screen, u32 x, u32 y, u32 part, u32 total)
+{
+// show_icon((u16*)screen, ICON_VSCROL_UPAROW, x+235, y+55);
+// show_icon((u16*)screen, ICON_VSCROL_DWAROW, x+235, y+167);
+// show_icon((u16*)screen, ICON_VSCROL_SLIDER, x+239, y+64);
+// if(total <= 1)
+// show_icon((u16*)screen, ICON_VSCROL_BAR, x+236, y+64);
+// else
+// show_icon((u16*)screen, ICON_VSCROL_BAR, x+236, y+64+(part*90)/(total-1));
+}
+
+/*
+* display a log
+*/
+void show_log(void* screen_addr)
+{
+ char tmp_path[MAX_PATH];
+ char *buff;
+ int x, y;
+ unsigned short *dst;
+ unsigned int type;
+ int ret;
+
+ sprintf(tmp_path, "%s/%s", main_path, BOOTLOGO);
+ buff= (char*)malloc(256*192*4);
+
+ ret= BMP_read(tmp_path, buff, 256, 192, &type);
+ if(ret != BMP_OK)
+ {
+ free((void*)buff);
+ return;
+ }
+
+ if(type ==2) //2 bytes per pixel
+ {
+ unsigned short *pt;
+ pt = (unsigned short*)buff;
+ dst=(unsigned short*)screen_addr;
+ for(y= 0; y< 192; y++)
+ {
+ for(x= 0; x< 256; x++)
+ {
+ *dst++= RGB16_15(pt);
+ pt += 1;
+ }
+ }
+ }
+ else if(type ==3) //3 bytes per pixel
+ {
+ unsigned char *pt;
+ pt = (unsigned char*)buff;
+ dst=(unsigned short*)screen_addr;
+ for(y= 0; y< 192; y++)
+ {
+ for(x= 0; x< 256; x++)
+ {
+ *dst++= RGB24_15(pt);
+ pt += 3;
+ }
+ }
+ }
+
+ free((void*)buff);
+}
+
+/*************************************************************/
+extern const unsigned char font_map[128][8];
+
+//font size 8*8
+static inline void drawfont(unsigned short *addr, unsigned short f_color, unsigned short b_color, unsigned char ch)
+{
+ unsigned char *dot_map;
+ unsigned int j, k;
+ unsigned char dot;
+ unsigned short *dst;
+
+ dot_map = (unsigned char*)font_map[ch&0x7F];
+
+ for(j= 0; j < 8; j++)
+ {
+ dot = *dot_map++;
+ dst = addr + j*SCREEN_WIDTH;
+ for(k = 0; k < 8; k++)
+ *dst++ = (dot & (0x80>>k)) ? f_color : b_color;
+ }
+}
+
+static void drawstring(unsigned int x, unsigned int y, enum SCREEN_ID screen, char *string,
+ unsigned short f_color, unsigned short b_color)
+{
+ unsigned short *scr_addr, *dst;
+
+ if(screen & UP_MASK)
+ scr_addr = up_screen_addr;
+ else
+ scr_addr = down_screen_addr;
+
+ if(x>= 32 || y>= 24) return;
+
+ while(*string)
+ {
+ dst = scr_addr + (y*8)*SCREEN_WIDTH + x*8;
+ drawfont(dst, f_color, b_color, *string++);
+
+ x += 1;
+ if(x>= 32)
+ {
+ x = 0;
+ y+= 1;
+ if(y >= 24) break;
+ }
+ }
+}
+
+void err_msg(enum SCREEN_ID screen, char *msg)
+{
+ drawstring(0, 0, screen, msg, COLOR16(16, 16, 16), COLOR16(0, 0, 0));
+}
+
+/*
+* Copy screen
+*/
+void copy_screen(void* to, void *from, u32 x, u32 y, u32 w, u32 h)
+{
+ u32 yy;
+ unsigned short *src, *dst;
+
+ //not check argument
+ src = (unsigned short*)from;
+ dst = (unsigned short*)to;
+
+ src += y*256+x;
+ dst += y*256+x;
+ for(yy= 0; yy < h; yy++)
+ {
+ memcpy((void*)dst, (void*)src, w*2);
+ src += 256;
+ dst += 256;
+ }
+}
+
+/*
+*
+*/
+void blit_to_screen(void* screen_addr, u16 *src, u32 w, u32 h, u32 dest_x, u32 dest_y)
+{
+ u32 x, y;
+ u16 *dst;
+ u16 *screenp;
+
+ if(w > NDS_SCREEN_WIDTH) w= NDS_SCREEN_WIDTH;
+ if(h > NDS_SCREEN_HEIGHT) h= NDS_SCREEN_HEIGHT;
+ if(dest_x == -1) //align center
+ dest_x= (NDS_SCREEN_WIDTH - w)/2;
+ if(dest_y == -1)
+ dest_y= (NDS_SCREEN_HEIGHT - h)/2;
+
+ screenp= (unsigned short*)screen_addr -16*256 -8;
+ for(y= 0; y < h; y++)
+ {
+ dst= screenp + (y+dest_y)*256 + dest_x;
+ for(x= 0; x < w; x++)
+ *dst++ = *src++;
+ }
+}
+
+
diff --git a/source/nds/draw.h b/source/nds/draw.h
new file mode 100644
index 0000000..3bdf5be
--- /dev/null
+++ b/source/nds/draw.h
@@ -0,0 +1,207 @@
+/* draw.h
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __DRAW_H__
+#define __DRAW_H__
+
+#include "ds2_types.h"
+#include "ds2io.h"
+#include "bdf_font.h"
+
+#define NDS_SCREEN_WIDTH 256
+#define NDS_SCREEN_HEIGHT 192
+#define NDS_SCREEN_SIZE (NDS_SCREEN_WIDTH*NDS_SCREEN_HEIGHT)
+
+#define COLOR16(red, green, blue) ((blue << 10) | (green << 5) | red)
+#define GET_R16(color) (color & 0x1f)
+#define GET_G16(color) ((color >> 5) & 0x1f)
+#define GET_B16(color) ((color >> 10)& 0x1f)
+#define COLOR32(red, green, blue) (0xff000000 | ((blue & 0xff) << 16) | ((green & 0xff) << 8) | (red & 0xff))
+
+#define RGB24_15(pixel) ((((*pixel) & 0xF8) << 7) |\
+ (((*(pixel+1)) & 0xF8) << 2) |\
+ (((*(pixel+2)) & 0xF8)>>3))
+
+#define RGB16_15(pixel) ((((*pixel)>>10) & 0x1F) |\
+ (((*pixel) & 0x1F) << 10) |\
+ ((*pixel) & 0x83E0))
+
+
+#define PRINT_STRING(screen, str, fg_color, x, y) \
+ BDF_render_string(screen, x, y, COLOR_TRANS, fg_color, str) \
+
+#define PRINT_STRING_SHADOW(screen, str, fg_color, x, y) \
+ BDF_render_string(screen, x+1, y+1, 0, 0, str); \
+ BDF_render_string(screen, x, y, 0, 0, str) \
+
+#define PRINT_STRING_BG(screen, str, fg_color, bg_color, x, y) \
+ BDF_render_string(screen, x, y, bg_color, fg_color, str) \
+
+#define PRINT_STRING_BG_UTF8(screen, utf8, fg_color, bg_color, x, y) \
+ BDF_render_mix(screen, SCREEN_WIDTH, x, y, 0, bg_color, fg_color, utf8) \
+
+
+//colors
+#define COLOR_TRANS COLOR16(31, 31, 63)
+#define COLOR_WHITE COLOR16(31, 31, 31)
+#define COLOR_BLACK COLOR16( 0, 0, 0)
+#define COLOR_TEXT COLOR16(31, 31, 31)
+#define COLOR_PROGRESS_TEXT COLOR16( 0, 0, 0)
+#define COLOR_PROGRESS_BAR COLOR16(15, 15, 15)
+#define COLOR_ERROR COLOR16(31, 0, 0)
+#define COLOR_BG COLOR16(2, 4, 10)
+#define COLOR_BG32 COLOR32(2*8, 4*8, 10*8)
+#define COLOR_ROM_INFO COLOR16(22, 18, 26)
+#define COLOR_ACTIVE_ITEM COLOR16(31, 31, 31)
+#define COLOR_INACTIVE_ITEM COLOR16(13, 20, 18)
+#define COLOR_HELP_TEXT COLOR16(16, 20, 24)
+#define COLOR_DIALOG COLOR16(31, 31, 31)
+#define COLOR_DIALOG_SHADOW COLOR16( 0, 2, 8)
+#define COLOR_FRAME COLOR16( 0, 0, 0)
+#define COLOR_YESNO_TEXT COLOR16( 0, 0, 0)
+#define COLOR_GREEN COLOR16( 0, 31, 0 )
+#define COLOR_GREEN1 COLOR16( 0, 24, 0 )
+#define COLOR_GREEN2 COLOR16( 0, 18, 0 )
+#define COLOR_GREEN3 COLOR16( 0, 12, 0 )
+#define COLOR_GREEN4 COLOR16( 0, 6, 0 )
+#define COLOR_RED COLOR16( 31, 0, 0 )
+#define COLOR_MSSG COLOR16( 16, 8, 29)
+/******************************************************************************
+ *
+ ******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct background{
+ char bgname[128];
+ char bgbuffer[256*192*2];
+};
+
+struct gui_iconlist{
+ const char *iconname; //icon name
+ u32 x; //picture size
+ u32 y;
+ char *iconbuff;
+};
+
+//extern struct background back_ground;
+extern struct gui_iconlist gui_icon_list[];
+
+#define ICON_GBAFILE gui_icon_list[0]
+#define ICON_ZIPFILE gui_icon_list[1]
+#define ICON_DIRECTORY gui_icon_list[2]
+#define ICON_SFCFILE gui_icon_list[3]
+//not use
+#define ICON_TITLE gui_icon_list[4]
+
+#define ICON_AVO gui_icon_list[5]
+#define ICON_SAVO gui_icon_list[6]
+#define ICON_TOOL gui_icon_list[7]
+#define ICON_CHEAT gui_icon_list[8]
+#define ICON_OTHER gui_icon_list[9]
+#define ICON_EXIT gui_icon_list[10]
+#define ICON_MSEL gui_icon_list[11]
+#define ICON_MNSEL gui_icon_list[12]
+//not use
+#define ICON_NAVO gui_icon_list[13]
+#define ICON_NSAVO gui_icon_list[14]
+#define ICON_NTOOL gui_icon_list[15]
+#define ICON_NCHEAT gui_icon_list[16]
+#define ICON_NOTHER gui_icon_list[17]
+#define ICON_NEXIT gui_icon_list[18]
+
+#define ICON_UNKNOW gui_icon_list[19]
+#define ICON_NEW gui_icon_list[20]
+#define ICON_NNEW gui_icon_list[21]
+#define ICON_RESET gui_icon_list[22]
+#define ICON_NRESET gui_icon_list[23]
+#define ICON_RETURN gui_icon_list[24]
+#define ICON_NRETURN gui_icon_list[25]
+#define ICON_MAINBG gui_icon_list[26]
+
+#define ICON_TITLEICON gui_icon_list[27]
+#define ICON_SUBBG gui_icon_list[28]
+
+#define ICON_SUBSELA gui_icon_list[29]
+#define ICON_SUBSELB gui_icon_list[30]
+#define ICON_STATEFULL gui_icon_list[31]
+#define ICON_NSTATEFULL gui_icon_list[32]
+#define ICON_STATEEMPTY gui_icon_list[33]
+#define ICON_NSTATEEMPTY gui_icon_list[34]
+#define ICON_DOTDIR gui_icon_list[35]
+#define ICON_BACK gui_icon_list[36]
+#define ICON_NBACK gui_icon_list[37]
+#define ICON_CHTFILE gui_icon_list[38]
+#define ICON_MSG gui_icon_list[39]
+#define ICON_BUTTON gui_icon_list[40]
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+extern void print_string_center(void* screen_addr, u32 sy, u32 color, u32 bg_color, char *str);
+extern void print_string_shadow_center(void* screen_addr, u32 sy, u32 color, char *str);
+extern void hline(u32 sx, u32 ex, u32 y, u32 color);
+extern void hline_alpha(u32 sx, u32 ex, u32 y, u32 color, u32 alpha);
+extern void vline(u32 x, u32 sy, u32 ey, u32 color);
+extern void vline_alpha(u32 x, u32 sy, u32 ey, u32 color, u32 alpha);
+extern void drawbox(void* screen_address, u32 sx, u32 sy, u32 ex, u32 ey, u32 color);
+extern void drawboxfill(void* screen_address, u32 sx, u32 sy, u32 ex, u32 ey, u32 color);
+extern void draw_selitem(void* screen_address, u32 x, u32 y, u32 color, u32 active);
+extern void draw_message(void* screen_address, u16 *screen_bg, u32 sx, u32 sy, u32 ex, u32 ey,
+ u32 color_fg);
+extern void draw_string_vcenter(void* screen_address, u32 sx, u32 sy, u32 width,
+ u32 color_fg, char *string);
+
+#define MAX_SCROLL_STRING 8
+extern u32 draw_hscroll_init(void* screen_address, u32 sx, u32 sy, u32 width,
+ u32 color_bg, u32 color_fg, char *string);
+extern u32 draw_hscroll(u32 index, s32 scroll_val);
+extern void draw_hscroll_over(u32 index);
+extern void boxfill_alpha(u32 sx, u32 sy, u32 ex, u32 ey, u32 color, u32 alpha);
+extern void init_progress(enum SCREEN_ID screen, u32 total, char *text);
+extern void update_progress(void);
+extern void show_progress(char *text);
+extern void scrollbar(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 all, u32 view, u32 now);
+extern u32 yesno_dialog(char *text);
+extern u32 draw_yesno_dialog(enum SCREEN_ID screen, u32 sy, char *yes, char *no);
+extern void msg_screen_init(const char *title);
+extern void msg_screen_draw();
+extern void msg_printf(const char *text, ...);
+extern void msg_screen_clear(void);
+extern void msg_set_text_color(u32 color);
+
+extern int icon_init(u32 language_id);
+extern int gui_change_icon(u32 language_id);
+extern int show_background(void *screen, char *bgname);
+extern void show_icon(void* screen, struct gui_iconlist icon, u32 x, u32 y);
+extern void show_Vscrollbar(char *screen, u32 x, u32 y, u32 part, u32 total);
+
+extern void show_log(void* screen_addr);
+extern void err_msg(enum SCREEN_ID screen, char *msg);
+
+extern void copy_screen(void* to, void *from, u32 x, u32 y, u32 w, u32 h);
+extern void blit_to_screen(void* screen_addr, u16 *src, u32 w, u32 h, u32 dest_x, u32 dest_y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__DRAW_H__
+
diff --git a/source/nds/ds2_main.c b/source/nds/ds2_main.c
new file mode 100644
index 0000000..710215b
--- /dev/null
+++ b/source/nds/ds2_main.c
@@ -0,0 +1,65 @@
+/* ds2_main.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include "console.h"
+#include "fs_api.h"
+#include "ds2io.h"
+#include "ds2_timer.h"
+#include "ds2_malloc.h"
+
+#define BLACK_COLOR RGB15(0, 0, 0)
+#define WHITE_COLOR RGB15(31, 31, 31)
+
+extern int sfc_main (int argc, char **argv);
+
+#if 0
+void ddump_mem(unsigned char* addr, unsigned int len)
+{
+ unsigned int i;
+
+ for(i= 0; i < len; i++)
+ {
+ if(i%16 == 0) cprintf("\n%08x: ", i);
+ cprintf("%02x ", addr[i]);
+ }
+}
+#endif
+
+
+
+void ds2_main(void)
+{
+ int err;
+ds2_setCPUclocklevel(13);
+ //Initial video and audio and other input and output
+ err = ds2io_initb(512, 22050, 0, 0);
+ if(err) goto _failure;
+
+ //Initial file system
+ err = fat_init();
+ if(err) goto _failure;
+
+ //go to user main funtion
+ sfc_main (0, 0);
+
+_failure:
+ ds2_plug_exit();
+}
+
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp
new file mode 100644
index 0000000..d3dbae3
--- /dev/null
+++ b/source/nds/entry.cpp
@@ -0,0 +1,1234 @@
+//entry.c
+#include <stdio.h>
+
+#include "ds2_types.h"
+#include "ds2_cpu.h"
+#include "ds2_timer.h"
+#include "ds2io.h"
+#include "fs_api.h"
+
+#include "snes9x.h"
+#include "soundux.h"
+#include "memmap.h"
+#include "apu.h"
+#include "cheats.h"
+#include "snapshot.h"
+#include "display.h"
+#include "gfx.h"
+#include "cpuexec.h"
+#include "spc7110.h"
+
+#include "draw.h"
+#include "gui.h"
+
+void S9xProcessSound (unsigned int);
+
+char *rom_filename = NULL;
+char *SDD1_pack = NULL;
+
+static u8 Buf[MAX_BUFFER_SIZE];
+
+#define FIXED_POINT 0x10000
+#define FIXED_POINT_SHIFT 16
+#define FIXED_POINT_REMAINDER 0xffff
+
+static volatile bool8 block_signal = FALSE;
+static volatile bool8 block_generate_sound = FALSE;
+static volatile bool8 pending_signal = FALSE;
+
+static void Init_Timer (void);
+
+void S9xMessage (int /*type*/, int /*number*/, const char *message)
+{
+#if 1
+#define MAX_MESSAGE_LEN (36 * 3)
+
+ static char buffer [MAX_MESSAGE_LEN + 1];
+
+ printf ("%s\n", message);
+ strncpy (buffer, message, MAX_MESSAGE_LEN);
+ buffer [MAX_MESSAGE_LEN] = 0;
+ S9xSetInfoString (buffer);
+#endif
+}
+
+void S9xExtraUsage ()
+{
+ /*empty*/
+}
+
+/*
+* Release display device
+*/
+void S9xDeinitDisplay (void)
+{
+ if(GFX.Screen) free(GFX.Screen);
+ if(GFX.SubScreen) free(GFX.SubScreen);
+ if(GFX.ZBuffer) free(GFX.ZBuffer);
+ if(GFX.SubZBuffer) free(GFX.SubZBuffer);
+}
+
+void S9xInitDisplay (int, char **)
+{
+ int h = IMAGE_HEIGHT;
+
+ GFX.Pitch = IMAGE_WIDTH * 2;
+ GFX.Screen = (unsigned char*) malloc (GFX.Pitch * h);
+ GFX.SubScreen = (unsigned char*) malloc (GFX.Pitch * h);
+ GFX.ZBuffer = (unsigned char*) malloc ((GFX.Pitch >> 1) * h);
+ GFX.SubZBuffer =(unsigned char*) malloc ((GFX.Pitch >> 1) * h);
+ GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
+}
+
+void S9xParseArg (char **argv, int &i, int argc)
+{
+}
+
+void S9xParseDisplayArg (char **argv, int &ind, int)
+{
+}
+
+void S9xExit ()
+{
+ if(Settings.SPC7110)
+ (*CleanUp7110)();
+
+ S9xSetSoundMute (TRUE);
+ S9xDeinitDisplay ();
+ Memory.SaveSRAM (S9xGetFilename (".srm"));
+ S9xSaveCheatFile (S9xGetFilename (".cht"));
+ Memory.Deinit ();
+ S9xDeinitAPU ();
+
+#ifdef _NETPLAY_SUPPORT
+ if (Settings.NetPlay)
+ S9xNetPlayDisconnect ();
+#endif
+
+ exit(0);
+}
+
+const char *S9xBasename (const char *f)
+{
+ const char *p;
+ if ((p = strrchr (f, '/')) != NULL || (p = strrchr (f, '\\')) != NULL)
+ return (p + 1);
+
+ return (f);
+}
+
+bool8 S9xInitUpdate ()
+{
+ return (TRUE);
+}
+
+
+
+bool frame_flip = 0;
+
+extern bool Draw_Frame_Flip(bool flip);
+
+
+bool8 S9xDeinitUpdate (int Width, int Height, bool8 /*sixteen_bit*/)
+{
+
+
+ switch(game_config.graphic)
+ {
+ //Up
+ case 1:
+ memcpy(up_screen_addr, GFX.Screen+256*32*2, 256*192*2);
+ break;
+
+ //Down
+ case 2:
+ memcpy(up_screen_addr, GFX.Screen, 256*192*2);
+ break;
+
+ //Both
+ case 3:
+ memcpy(up_screen_addr, GFX.Screen+256*16*2, 256*192*2);
+ break;
+
+ case 4:
+ frame_flip = Draw_Frame_Flip(frame_flip);
+ break;
+
+
+ default:
+ {
+ unsigned char *src, *dst;
+ unsigned int m, n;
+
+ src = GFX.Screen;
+ dst = (unsigned char*)up_screen_addr;
+ for(m = 0; m < 32; m++)
+ {
+ memcpy(dst, src, 256*6*2);
+ dst += 256*6*2;
+ src += 256*7*2;
+ }
+ }
+ break;
+ }
+
+
+// memcpy(up_screen_addr, GFX.Screen, 256*192*2);
+// memcpy(down_screen_addr, GFX.Screen+256*192*2, 256*(224-192)*2);
+
+ ds2_flipScreen(UP_SCREEN, 0);
+// ds2_flipScreen(DOWN_SCREEN, 0);
+
+ return (TRUE);
+}
+
+void _makepath (char *path, const char *, const char *dir,
+ const char *fname, const char *ext)
+{
+ if (dir && *dir)
+ {
+ strcpy (path, dir);
+ strcat (path, "/");
+ }
+ else
+ *path = 0;
+ strcat (path, fname);
+ if (ext && *ext)
+ {
+ strcat (path, ".");
+ strcat (path, ext);
+ }
+}
+
+void _splitpath (const char *path, char *drive, char *dir, char *fname,
+ char *ext)
+{
+ *drive = 0;
+
+ char *slash = strrchr (path, '/');
+ if (!slash)
+ slash = strrchr (path, '\\');
+
+ char *dot = strrchr (path, '.');
+
+ if (dot && slash && dot < slash)
+ dot = NULL;
+
+ if (!slash)
+ {
+ strcpy (dir, "");
+ strcpy (fname, path);
+ if (dot)
+ {
+ *(fname + (dot - path)) = 0;
+ strcpy (ext, dot + 1);
+ }
+ else
+ strcpy (ext, "");
+ }
+ else
+ {
+ strcpy (dir, path);
+ *(dir + (slash - path)) = 0;
+ strcpy (fname, slash + 1);
+ if (dot)
+ {
+ *(fname + (dot - slash) - 1) = 0;
+ strcpy (ext, dot + 1);
+ }
+ else
+ strcpy (ext, "");
+ }
+}
+
+void S9xProcessEvents (bool8 block)
+{
+
+}
+
+void OutOfMemory ()
+{
+}
+
+
+const char *S9xGetROMDirectory ()
+{
+ return ((const char*)g_default_rom_dir);
+}
+
+
+const char *S9xGetSnapshotDirectory ()
+{
+ return ((const char*)DEFAULT_RTS_DIR);
+}
+
+
+const char *S9xGetFilename (const char *ex)
+{
+ static char filename [PATH_MAX + 1];
+ char drive [_MAX_DRIVE + 1];
+ char dir [_MAX_DIR + 1];
+ char fname [_MAX_FNAME + 1];
+ char ext [_MAX_EXT + 1];
+
+ _splitpath (Memory.ROMFilename, drive, dir, fname, ext);
+ strcpy (filename, S9xGetSnapshotDirectory ());
+ strcat (filename, SLASH_STR);
+ strcat (filename, fname);
+ strcat (filename, ex);
+
+ return (filename);
+}
+
+const char *S9xGetFilenameInc (const char *e)
+{
+ return e;
+#if 0
+ static char filename [_MAX_PATH + 1];
+ char drive [_MAX_DRIVE + 1];
+ char dir [_MAX_DIR + 1];
+ char fname [_MAX_FNAME + 1];
+ char ext [_MAX_EXT + 1];
+ char *ptr;
+ struct stat buf;
+
+ if (strlen (S9xGetSnapshotDirectory()))
+ {
+ _splitpath (Memory.ROMFilename, drive, dir, fname, ext);
+ strcpy (filename, S9xGetSnapshotDirectory());
+ strcat (filename, "/");
+ strcat (filename, fname);
+ ptr = filename + strlen (filename);
+ strcat (filename, "00/");
+ strcat (filename, e);
+ }
+ else
+ {
+ _splitpath (Memory.ROMFilename, drive, dir, fname, ext);
+ strcat (fname, "00/");
+ _makepath (filename, drive, dir, fname, e);
+ ptr = strstr (filename, "00/");
+ }
+
+ do
+ {
+ if (++*(ptr + 2) > '9')
+ {
+ *(ptr + 2) = '0';
+ if (++*(ptr + 1) > '9')
+ {
+ *(ptr + 1) = '0';
+ if (++*ptr > '9')
+ break;
+ }
+ }
+ } while( stat(filename, &buf) == 0 );
+
+ return (filename);
+#endif
+}
+
+void S9xInitInputDevices ()
+{
+#ifdef JOYSTICK_SUPPORT
+ InitJoysticks ();
+#endif
+}
+
+
+
+void game_disableAudio()
+{
+ if( game_enable_audio == 1)
+ {
+ Settings.APUEnabled = Settings.NextAPUEnabled = TRUE;
+ S9xSetSoundMute (FALSE);
+ }
+ else
+ {
+ Settings.APUEnabled = Settings.NextAPUEnabled = FALSE;
+ S9xSetSoundMute (TRUE);
+ }
+}
+
+void init_sfc_setting(void)
+{
+ ZeroMemory (&Settings, sizeof (Settings));
+#ifdef JOYSTICK_SUPPORT
+ Settings.JoystickEnabled = TRUE;
+#else
+ Settings.JoystickEnabled = FALSE;
+#endif
+
+ Settings.SoundPlaybackRate = 4; //2 = 11025, 4 = 22050, 6 = 44100
+ Settings.Stereo = TRUE;
+ Settings.SoundBufferSize = 0;
+ Settings.CyclesPercentage = 100;
+ Settings.DisableSoundEcho = FALSE;
+ //sound settings
+ Settings.APUEnabled = Settings.NextAPUEnabled = TRUE;
+ Settings.FixFrequency = 1;
+
+
+ Settings.H_Max = SNES_CYCLES_PER_SCANLINE;
+ Settings.SkipFrames = AUTO_FRAMERATE;
+ Settings.ShutdownMaster = TRUE;
+ Settings.FrameTimePAL = 20000;
+ Settings.FrameTimeNTSC = 16667;
+ Settings.FrameTime = Settings.FrameTimeNTSC;
+ Settings.DisableSampleCaching = FALSE;
+ Settings.DisableMasterVolume = FALSE;
+ Settings.Mouse = TRUE;
+ Settings.SuperScope = TRUE;
+ Settings.MultiPlayer5 = TRUE;
+ Settings.ControllerOption = SNES_JOYPAD;
+
+ Settings.Transparency = TRUE;
+ Settings.SixteenBit = TRUE;
+
+ Settings.SupportHiRes = FALSE;
+ Settings.NetPlay = FALSE;
+ Settings.ServerName [0] = 0;
+ Settings.ThreadSound = FALSE;
+ Settings.AutoSaveDelay = 0;
+#ifdef _NETPLAY_SUPPORT
+ Settings.Port = NP_DEFAULT_PORT;
+#endif
+ Settings.ApplyCheats =FALSE;
+ Settings.TurboMode = FALSE;
+ Settings.TurboSkipFrames = 40;
+ Settings.StretchScreenshots = 1;
+
+ Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;
+}
+
+extern "C" {
+ int game_load_state(char* file);
+ int game_save_state(char* file);
+ void S9xAutoSaveSRAM ();
+}
+
+void S9xAutoSaveSRAM ()
+{
+ Memory.SaveSRAM (S9xGetFilename (".srm"));
+}
+
+int game_load_state(char* file)
+{
+ int flag;
+
+ flag = 0;
+ if(S9xUnfreezeGame(file) == FALSE)
+ flag = -1;
+
+ return flag;
+}
+
+int game_save_state(char* file)
+{
+ int flag;
+
+ flag = 0;
+ if(S9xFreezeGame(file) == FALSE)
+ flag = -1;
+
+ S9xAutoSaveSRAM ();
+
+ return flag;
+}
+
+extern "C" void game_restart(void);
+
+void game_restart(void)
+{
+ CPU.Flags = 0;
+ S9xReset ();
+}
+
+extern "C" int load_gamepak(char* file);
+
+int load_gamepak(char* file)
+{
+ game_enable_audio = 1;
+ game_disableAudio();
+
+ CPU.Flags = 0;
+ S9xReset ();
+ mdelay(50);
+ if (!Memory.LoadROM (file))
+ return -1;
+
+ Memory.LoadSRAM (S9xGetFilename (".srm"));
+ mdelay(50);
+ //S9xLoadCheatFile (S9xGetFilename (".cht"));
+ S9xCheat_Disable();
+
+#ifdef _NETPLAY_SUPPORT
+ if (strlen (Settings.ServerName) == 0)
+ {
+ char *server = getenv ("S9XSERVER");
+ if (server)
+ {
+ strncpy (Settings.ServerName, server, 127);
+ Settings.ServerName [127] = 0;
+ }
+ }
+ char *port = getenv ("S9XPORT");
+ if (Settings.Port >= 0 && port)
+ Settings.Port = atoi (port);
+ else if (Settings.Port < 0)
+ Settings.Port = -Settings.Port;
+
+ if (Settings.NetPlay)
+ {
+ int player;
+
+ if (!S9xNetPlayConnectToServer (Settings.ServerName, Settings.Port,
+ Memory.ROMName, player))
+ {
+ fprintf (stderr, "Failed to connected to Snes9x netplay"
+ " server \"%s\" on port %d.\n",
+ Settings.ServerName, Settings.Port);
+ S9xExit ();
+ }
+ fprintf (stderr, "Connected to \"%s\" on port %d as"
+ " player #%d playing \"%s\"\n",
+ Settings.ServerName, Settings.Port, player, Memory.ROMName);
+ }
+
+#endif
+/*
+ if (snapshot_filename)
+ {
+ int Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
+ if (!S9xLoadSnapshot (snapshot_filename))
+ exit (1);
+ CPU.Flags |= Flags;
+ }
+*/
+
+ mdelay(50);
+ if (!Settings.APUEnabled)
+ S9xSetSoundMute (FALSE);
+
+ return 0;
+}
+
+extern "C" int sfc_main (int argc, char **argv);
+
+int sfc_main (int argc, char **argv)
+{
+ //Initialize GUI
+ gui_init(0);
+
+ init_sfc_setting();
+
+ if (!Memory.Init () || !S9xInitAPU())
+ OutOfMemory ();
+
+ S9xInitDisplay (argc, argv);
+ if (!S9xGraphicsInit())
+ OutOfMemory ();
+
+ S9xInitSound (Settings.SoundPlaybackRate, Settings.Stereo,
+ Settings.SoundBufferSize);
+
+ if (!Settings.APUEnabled)
+ S9xSetSoundMute (TRUE);
+
+#ifdef GFX_MULTI_FORMAT
+// S9xSetRenderPixelFormat (RGB565);
+ S9xSetRenderPixelFormat (BGR555);
+#endif
+
+#ifdef JOYSTICK_SUPPORT
+ uint32 JoypadSkip = 0;
+#endif
+
+// Init_Timer ();
+
+ /* FIXME: Is someone using this dead code, or should it go? */
+#if 0
+ {
+ FILE *fs = fopen ("test.bin", "r");
+ if (fs)
+ {
+ memset (IAPU.RAM, 0, 1024 * 64);
+ int bytes = fread (IAPU.RAM + 1024, 1, 13, fs);
+ bytes = fread (IAPU.RAM + 1024, 1, 1024 * 63, fs);
+ fclose (fs);
+#ifdef SPCTOOL
+ _FixSPC (1024, 0, 0, 0, 0, 0xff);
+#else
+ IAPU.PC = IAPU.RAM + 1024;
+#endif
+ APU.Flags ^= TRACE_FLAG;
+ extern FILE *apu_trace;
+ if (APU.Flags & TRACE_FLAG)
+ {
+#ifdef SPCTOOL
+ printf ("ENABLED\n");
+ _SetSPCDbg (TraceSPC); //Install debug handler
+#endif
+ if (apu_trace == NULL)
+ apu_trace = fopen ("aputrace.log", "wb");
+ }
+ CPU.Cycles = 1024 * 10;
+ APU_EXECUTE ();
+ exit (0);
+ }
+ }
+#endif
+
+ Settings.Paused = 1;
+
+ while (1)
+ {
+ if (!Settings.Paused
+#ifdef DEBUGGER
+ || (CPU.Flags & (DEBUG_MODE_FLAG | SINGLE_STEP_FLAG))
+#endif
+ )
+ S9xMainLoop ();
+
+
+#ifdef DEBUGGER
+ if (CPU.Flags & DEBUG_MODE_FLAG)
+ {
+ S9xDoDebug ();
+ }
+ else
+#endif
+ if (Settings.Paused)
+ {
+ S9xSetSoundMute (TRUE);
+ mdelay(50);
+ unsigned short screen[256*192];
+
+ copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192);
+ menu(screen);
+ Settings.Paused = 0;
+ game_disableAudio();
+ }
+
+#ifdef JOYSTICK_SUPPORT
+ //if (Settings.JoystickEnabled && (JoypadSkip++ & 1) == 0)
+ if (Settings.JoystickEnabled)
+ ReadJoysticks ();
+#endif
+
+ }
+
+ return (0);
+}
+
+void S9xSyncSpeed ()
+{
+#if 0
+#ifdef _NETPLAY_SUPPORT
+ if (Settings.NetPlay)
+ {
+ // XXX: Send joypad position update to server
+ // XXX: Wait for heart beat from server
+ S9xNetPlaySendJoypadUpdate (joypads [0]);
+ if (!S9xNetPlayCheckForHeartBeat ())
+ {
+ do
+ {
+ CHECK_SOUND ();
+// S9xProcessEvents (FALSE);
+ } while (!S9xNetPlayCheckForHeartBeat ());
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.SkippedFrames = 0;
+ }
+ else
+ {
+ if (IPPU.SkippedFrames < 10)
+ {
+ IPPU.SkippedFrames++;
+ IPPU.RenderThisFrame = FALSE;
+ }
+ else
+ {
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.SkippedFrames = 0;
+ }
+ }
+ }
+ else
+#endif
+
+#if 0
+ if (Settings.SoundSync == 2)
+ {
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.SkippedFrames = 0;
+ return;
+ }
+#endif
+
+#if 0
+ if (Settings.TurboMode)
+ {
+ if(++IPPU.FrameSkip >= Settings.TurboSkipFrames)
+ {
+ IPPU.FrameSkip = 0;
+ IPPU.SkippedFrames = 0;
+ IPPU.RenderThisFrame = TRUE;
+ }
+ else
+ {
+ ++IPPU.SkippedFrames;
+ IPPU.RenderThisFrame = FALSE;
+ }
+ return;
+ }
+#endif
+
+#ifdef __sgi
+ /* BS: saves on CPU usage */
+ sginap(1);
+#endif
+
+ /* Check events */
+
+ static struct timeval next1 = {0, 0};
+ struct timeval now;
+
+ CHECK_SOUND();
+// S9xProcessEvents(FALSE);
+
+ while (gettimeofday (&now, NULL) < 0) ;
+
+ /* If there is no known "next" frame, initialize it now */
+ if (next1.tv_sec == 0) { next1 = now; ++next1.tv_usec; }
+
+ /* If we're on AUTO_FRAMERATE, we'll display frames always
+ * only if there's excess time.
+ * Otherwise we'll display the defined amount of frames.
+ */
+ unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
+ ? (timercmp(&next1, &now, <) ? 10 : 1)
+ : Settings.SkipFrames;
+
+ IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
+ if(IPPU.RenderThisFrame)
+ {
+ IPPU.SkippedFrames = 0;
+ }
+ else
+ {
+ /* If we were behind the schedule, check how much it is */
+ if(timercmp(&next1, &now, <))
+ {
+ unsigned lag =
+ (now.tv_sec - next1.tv_sec) * 1000000
+ + now.tv_usec - next1.tv_usec;
+ if(lag >= 1000000)
+ {
+ /* More than a second behind means probably
+ * pause. The next line prevents the magic
+ * fast-forward effect.
+ */
+ next1 = now;
+ }
+ }
+ }
+
+ /* Delay until we're completed this frame */
+
+ /* Can't use setitimer because the sound code already could
+ * be using it. We don't actually need it either.
+ */
+
+ while(timercmp(&next1, &now, >))
+ {
+ /* If we're ahead of time, sleep a while */
+ unsigned timeleft =
+ (next1.tv_sec - now.tv_sec) * 1000000
+ + next1.tv_usec - now.tv_usec;
+ //fprintf(stderr, "<%u>", timeleft);
+ usleep(timeleft);
+
+ CHECK_SOUND();
+// S9xProcessEvents(FALSE);
+
+ while (gettimeofday (&now, NULL) < 0) ;
+ /* Continue with a while-loop because usleep()
+ * could be interrupted by a signal
+ */
+ }
+
+ /* Calculate the timestamp of the next frame. */
+ next1.tv_usec += Settings.FrameTime;
+ if (next1.tv_usec >= 1000000)
+ {
+ next1.tv_sec += next1.tv_usec / 1000000;
+ next1.tv_usec %= 1000000;
+ }
+#endif
+}
+
+/*
+* Open sound device
+*/
+static int Rates[8] =
+{
+ 0, 8000, 11025, 16000, 22050, 32000, 44100, 48000
+};
+
+static int BufferSizes [8] =
+{
+ 0, 256, 256, 256, 512, 512, 1024, 1024
+};
+
+bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size)
+{
+ so.sixteen_bit = TRUE;
+ so.stereo = stereo;
+ so.playback_rate = Rates[mode & 0x07];
+ S9xSetPlaybackRate (so.playback_rate);
+
+ if (buffer_size == 0)
+ buffer_size = BufferSizes [mode & 7];
+
+ if (buffer_size > MAX_BUFFER_SIZE / 4)
+ buffer_size = MAX_BUFFER_SIZE / 4;
+ if (so.sixteen_bit)
+ buffer_size *= 2;
+ if (so.stereo)
+ buffer_size *= 2;
+
+ so.buffer_size = buffer_size;
+
+ return (TRUE);
+}
+
+void S9xGenerateSound ()
+{
+ int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) :
+ so.samples_mixed_so_far;
+
+ if (bytes_so_far >= so.buffer_size)
+ return;
+
+ block_signal = TRUE;
+
+ so.err_counter += so.err_rate;
+ if (so.err_counter >= FIXED_POINT)
+ {
+ int sample_count = so.err_counter >> FIXED_POINT_SHIFT;
+ int byte_offset;
+ int byte_count;
+
+ so.err_counter &= FIXED_POINT_REMAINDER;
+ if (so.stereo)
+ sample_count <<= 1;
+ byte_offset = bytes_so_far + so.play_position;
+
+ do
+ {
+ int sc = sample_count;
+ byte_count = sample_count;
+ if (so.sixteen_bit)
+ byte_count <<= 1;
+
+ if ((byte_offset & SOUND_BUFFER_SIZE_MASK) + byte_count > SOUND_BUFFER_SIZE)
+ {
+ sc = SOUND_BUFFER_SIZE - (byte_offset & SOUND_BUFFER_SIZE_MASK);
+ byte_count = sc;
+ if (so.sixteen_bit)
+ sc >>= 1;
+ }
+
+ if (bytes_so_far + byte_count > so.buffer_size)
+ {
+ byte_count = so.buffer_size - bytes_so_far;
+ if (byte_count == 0)
+ break;
+ sc = byte_count;
+ if (so.sixteen_bit)
+ sc >>= 1;
+ }
+
+ S9xMixSamplesO (Buf, sc, byte_offset & SOUND_BUFFER_SIZE_MASK);
+ so.samples_mixed_so_far += sc;
+ sample_count -= sc;
+ bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) :
+ so.samples_mixed_so_far;
+ byte_offset += byte_count;
+ } while (sample_count > 0);
+ }
+
+ block_signal = FALSE;
+
+ if (pending_signal)
+ {
+ S9xProcessSound (0);
+ pending_signal = FALSE;
+ }
+}
+
+void S9xProcessSound (unsigned int)
+{
+ unsigned short *audiobuff;
+
+ if (!Settings.APUEnabled || so.mute_sound )
+ return;
+
+ if(ds2_checkAudiobuff() > 4)
+ return;
+
+ /* Number of samples to generate now */
+ int sample_count = so.buffer_size;
+
+ if (so.sixteen_bit)
+ {
+ /* to prevent running out of buffer space,
+ * create less samples
+ */
+ sample_count >>= 1;
+ }
+
+ if (block_signal)
+ {
+ pending_signal = TRUE;
+ return;
+ }
+
+// block_generate_sound = TRUE;
+
+ audiobuff = (unsigned short*)ds2_getAudiobuff();
+ if(NULL == audiobuff) //There are audio queue in sending or wait to send
+ {
+ return;
+ }
+
+ /* If we need more audio samples */
+ if (so.samples_mixed_so_far < sample_count)
+ {
+ /* Where to put the samples to */
+ unsigned byte_offset = so.play_position +
+ (so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far);
+
+ //printf ("%d:", sample_count - so.samples_mixed_so_far); fflush (stdout);
+ if (Settings.SoundSync == 2)
+ {
+ /*memset (Buf + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0,
+ sample_count - so.samples_mixed_so_far);*/
+ }
+ else
+ {
+ /* Mix the missing samples */
+ S9xMixSamplesO (Buf, sample_count - so.samples_mixed_so_far,
+ byte_offset & SOUND_BUFFER_SIZE_MASK);
+ }
+ so.samples_mixed_so_far = sample_count;
+ }
+
+// if (!so.mute_sound)
+ {
+ unsigned bytes_to_write = sample_count;
+ if(so.sixteen_bit) bytes_to_write <<= 1;
+
+ unsigned byte_offset = so.play_position;
+ so.play_position += bytes_to_write;
+ so.play_position &= SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */
+
+// block_generate_sound = FALSE;
+
+ unsigned short *dst_pt = audiobuff;
+ unsigned short *dst_pt1 = dst_pt + 512;
+
+ /* Feed the samples to the soundcard until nothing is left */
+ for(;;)
+ {
+ int I = bytes_to_write;
+ if (byte_offset + I > SOUND_BUFFER_SIZE)
+ {
+ I = SOUND_BUFFER_SIZE - byte_offset;
+ }
+ if(I == 0) break;
+
+// memcpy(dst_pt, (char *) Buf + byte_offset, I);
+// dst_pt += I;
+
+ unsigned short *src_pt= (unsigned short*)(Buf + byte_offset);
+ for(int m= 0; m < I/4; m++)
+ {
+ *dst_pt++= *src_pt++;//(*src_pt++) <<1;
+ *dst_pt1++= *src_pt++;//(*src_pt++) <<1;
+ }
+
+ bytes_to_write -= I;
+ byte_offset += I;
+ byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+ }
+
+ ds2_updateAudio();
+
+ /* All data sent. */
+ }
+
+ so.samples_mixed_so_far -= sample_count;
+}
+
+void Init_Timer (void)
+{
+}
+
+
+
+const unsigned int keymap[12] = {
+ 0x80, //KEY_A
+ 0x8000, //KEY_B
+ 0x2000, //KEY_SELECT
+ 0x1000, //KEY_START
+ 0x100, //KEY_RIGHT
+ 0x200, //KEY_LEFT
+ 0x800, //KEY_UP
+ 0x400, //KEY_DOWN
+ 0x10, //KEY_R
+ 0x20, //KEY_L
+ 0x40, //KEY_X
+ 0x4000 //KEY_Y
+ };
+
+unsigned int S9xReadJoypad (int which1)
+{
+ struct key_buf inputdata;
+
+ ds2_getrawInput(&inputdata);
+ if(inputdata.key & KEY_TOUCH) //Active menu
+ Settings.Paused = 1;
+
+ if(which1 < 1)
+ {
+ unsigned int key;
+ unsigned int i;
+
+ key = 0;
+ for(i= 0; i < 12; i++) //remap key
+ {
+ key |= (inputdata.key & (1<<i)) ? keymap[i] : 0;
+ }
+
+ return (key | 0x80000000);
+ }
+ else
+ return 0;
+}
+
+static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2)
+{
+ return (*(uint32 *) p1 - *(uint32 *) p2);
+}
+
+void S9xLoadSDD1Data ()
+{
+ char filename [_MAX_PATH + 1];
+ char index [_MAX_PATH + 1];
+ char data [_MAX_PATH + 1];
+ char patch [_MAX_PATH + 1];
+
+ Memory.FreeSDD1Data ();
+
+ strcpy (filename, S9xGetSnapshotDirectory ());
+
+ Settings.SDD1Pack=FALSE;
+ if (strncmp (Memory.ROMName, "Star Ocean", 10) == 0){
+ if(SDD1_pack) strcpy (filename, SDD1_pack);
+#ifdef SDD1_DECOMP
+ else Settings.SDD1Pack=TRUE;
+#else
+ strcat (filename, "/socnsdd1");
+#endif
+ } else if(strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21)==0){
+ if(SDD1_pack) strcpy (filename, SDD1_pack);
+#ifdef SDD1_DECOMP
+ else Settings.SDD1Pack=TRUE;
+#else
+ strcat (filename, "/sfa2sdd1");
+#endif
+ } else {
+ if(SDD1_pack) strcpy (filename, SDD1_pack);
+#ifdef SDD1_DECOMP
+ else Settings.SDD1Pack=TRUE;
+#else
+ S9xMessage(S9X_WARNING, S9X_ROM_INFO, "WARNING: No default SDD1 pack for this ROM");
+#endif
+ }
+
+ if(Settings.SDD1Pack) return;
+
+ DIR *dir = opendir (filename);
+
+ index [0] = 0;
+ data [0] = 0;
+ patch [0] = 0;
+
+ if (dir)
+ {
+// struct dirent *d;
+ dirent *d;
+
+ while ((d = readdir (dir)))
+ {
+ if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0)
+ {
+ strcpy (index, filename);
+ strcat (index, "/");
+ strcat (index, d->d_name);
+ }
+ else
+ if (strcasecmp (d->d_name, "SDD1GFX.DAT") == 0)
+ {
+ strcpy (data, filename);
+ strcat (data, "/");
+ strcat (data, d->d_name);
+ }
+ if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0)
+ {
+ strcpy (patch, filename);
+ strcat (patch, "/");
+ strcat (patch, d->d_name);
+ }
+ }
+ closedir (dir);
+
+ if (strlen (index) && strlen (data))
+ {
+ FILE *fs = fopen (index, "rb");
+ int len = 0;
+
+ if (fs)
+ {
+ // Index is stored as a sequence of entries, each entry being
+ // 12 bytes consisting of:
+ // 4 byte key: (24bit address & 0xfffff * 16) | translated block
+ // 4 byte ROM offset
+ // 4 byte length
+ fseek (fs, 0, SEEK_END);
+ len = ftell (fs);
+ //rewind (fs);
+ fseek (fs, 0, SEEK_SET);
+ Memory.SDD1Index = (uint8 *) malloc (len);
+ fread (Memory.SDD1Index, 1, len, fs);
+ fclose (fs);
+ Memory.SDD1Entries = len / 12;
+
+ if (!(fs = fopen (data, "rb")))
+ {
+ free ((char *) Memory.SDD1Index);
+ Memory.SDD1Index = NULL;
+ Memory.SDD1Entries = 0;
+ }
+ else
+ {
+ fseek (fs, 0, SEEK_END);
+ len = ftell (fs);
+ //rewind (fs);
+ fseek (fs, 0, SEEK_SET);
+ Memory.SDD1Data = (uint8 *) malloc (len);
+ fread (Memory.SDD1Data, 1, len, fs);
+ fclose (fs);
+
+ if (strlen (patch) > 0 &&
+ (fs = fopen (patch, "rb")))
+ {
+ fclose (fs);
+ }
+#ifdef MSB_FIRST
+ // Swap the byte order of the 32-bit value triplets on
+ // MSBFirst machines.
+ uint8 *ptr = Memory.SDD1Index;
+ for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12)
+ {
+ SWAP_DWORD ((*(uint32 *) (ptr + 0)));
+ SWAP_DWORD ((*(uint32 *) (ptr + 4)));
+ SWAP_DWORD ((*(uint32 *) (ptr + 8)));
+ }
+#endif
+ qsort (Memory.SDD1Index, Memory.SDD1Entries, 12,
+ S9xCompareSDD1IndexEntries);
+ }
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Decompressed data pack not found in '%s'.\n",
+ filename);
+ }
+ }
+}
+
+bool8 S9xReadMousePosition (int which1, int &x, int &y, uint32 &buttons)
+{
+ return (FALSE);
+}
+
+bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons)
+{
+ return (TRUE);
+}
+
+bool JustifierOffscreen()
+{
+ return (FALSE);
+}
+
+void JustifierButtons(uint32& justifiers)
+{
+}
+
+START_EXTERN_C
+char* osd_GetPackDir()
+{
+ static char filename[_MAX_PATH];
+ memset(filename, 0, _MAX_PATH);
+
+ if(strlen(S9xGetSnapshotDirectory())!=0)
+ strcpy (filename, S9xGetSnapshotDirectory());
+ else
+ {
+ char dir [_MAX_DIR + 1];
+ char drive [_MAX_DRIVE + 1];
+ char name [_MAX_FNAME + 1];
+ char ext [_MAX_EXT + 1];
+ _splitpath(Memory.ROMFilename, drive, dir, name, ext);
+ _makepath(filename, drive, dir, NULL, NULL);
+ }
+
+ if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21))
+ {
+ if (getenv("SPL4PACK"))
+ return getenv("SPL4PACK");
+ else
+ strcat(filename, "/SPL4-SP7");
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21))
+ {
+ if (getenv("MDHPACK"))
+ return getenv("MDHPACK");
+ else
+ strcat(filename, "/SMHT-SP7");
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21))
+ {
+ if (getenv("FEOEZPACK"))
+ return getenv("FEOEZPACK");
+ else
+ strcat(filename, "/FEOEZSP7");
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21))
+ {
+ if (getenv("SJNSPACK"))
+ return getenv("SJNSPACK");
+ else
+ strcat(filename, "/SJUMPSP7");
+ } else strcat(filename, "/MISC-SP7");
+ return filename;
+}
+END_EXTERN_C
+
+
diff --git a/source/nds/font_dot.h b/source/nds/font_dot.h
new file mode 100644
index 0000000..c3b534a
--- /dev/null
+++ b/source/nds/font_dot.h
@@ -0,0 +1,93 @@
+/* font_dot.h
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __FONT_DOT_H__
+#define __FONT_DOT_H__
+
+//version 0.1
+
+const unsigned char font_map[128][8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08,
+ 0x00, 0x00, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x08, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
+ 0x7c, 0x64, 0x44, 0x44, 0x64, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x70, 0x50, 0x50, 0x70, 0x00,
+ 0x24, 0x24, 0x1c, 0x08, 0x3f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x16, 0x1a, 0x12, 0x12, 0x16, 0x34, 0x20, 0x00, 0x3c, 0x24, 0x24, 0x66, 0x24, 0x3c, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x1c, 0x3c, 0x3c, 0x1c, 0x0c, 0x04, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, 0x00,
+ 0x54, 0x54, 0x34, 0x14, 0x14, 0x14, 0x14, 0x14, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08,
+ 0x00, 0x00, 0x08, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7c, 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, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x7e, 0x28, 0x7e, 0x28, 0x28, 0x00,
+ 0x1c, 0x2c, 0x28, 0x18, 0x0c, 0x2c, 0x3c, 0x08, 0x64, 0x68, 0x68, 0x7c, 0x1c, 0x1c, 0x2c, 0x00,
+ 0x30, 0x30, 0x3c, 0x28, 0x58, 0x50, 0x3c, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x08, 0x10, 0x10, 0x10, 0x10, 0x08, 0x04, 0x40, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0x40,
+ 0x10, 0x54, 0x38, 0x38, 0x54, 0x10, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x40,
+ 0x18, 0x24, 0x24, 0x24, 0x24, 0x24, 0x18, 0x00, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00,
+ 0x18, 0x24, 0x04, 0x08, 0x10, 0x20, 0x3c, 0x00, 0x18, 0x24, 0x04, 0x18, 0x04, 0x24, 0x18, 0x00,
+ 0x08, 0x18, 0x28, 0x48, 0x7c, 0x08, 0x08, 0x00, 0x3c, 0x20, 0x38, 0x04, 0x04, 0x24, 0x18, 0x00,
+ 0x38, 0x40, 0x40, 0x78, 0x44, 0x44, 0x38, 0x00, 0x3c, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x00,
+ 0x18, 0x24, 0x24, 0x18, 0x24, 0x24, 0x18, 0x00, 0x18, 0x24, 0x24, 0x1c, 0x04, 0x04, 0x18, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x20,
+ 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7c, 0x00, 0x00,
+ 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x10, 0x24, 0x24, 0x08, 0x10, 0x10, 0x00, 0x10,
+ 0x38, 0x4c, 0x54, 0x5c, 0x54, 0x44, 0x38, 0x00, 0x10, 0x10, 0x28, 0x28, 0x38, 0x28, 0x6c, 0x00,
+ 0x78, 0x24, 0x38, 0x24, 0x24, 0x24, 0x78, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00,
+ 0x78, 0x24, 0x24, 0x24, 0x24, 0x24, 0x78, 0x00, 0x7c, 0x24, 0x20, 0x38, 0x20, 0x24, 0x7c, 0x00,
+ 0x7c, 0x24, 0x28, 0x38, 0x28, 0x20, 0x70, 0x00, 0x38, 0x40, 0x40, 0x40, 0x5c, 0x48, 0x30, 0x00,
+ 0x76, 0x24, 0x24, 0x3c, 0x24, 0x24, 0x76, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00,
+ 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x60, 0x74, 0x28, 0x30, 0x30, 0x28, 0x28, 0x6c, 0x00,
+ 0x70, 0x20, 0x20, 0x20, 0x20, 0x24, 0x7c, 0x00, 0x66, 0x3c, 0x3c, 0x3c, 0x34, 0x24, 0x66, 0x00,
+ 0x6e, 0x24, 0x34, 0x34, 0x2c, 0x24, 0x74, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00,
+ 0x78, 0x24, 0x24, 0x38, 0x20, 0x20, 0x70, 0x00, 0x38, 0x44, 0x44, 0x44, 0x74, 0x4c, 0x38, 0x0c,
+ 0x78, 0x24, 0x38, 0x28, 0x24, 0x24, 0x76, 0x00, 0x1c, 0x24, 0x20, 0x18, 0x04, 0x24, 0x38, 0x00,
+ 0x7c, 0x54, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x66, 0x24, 0x24, 0x24, 0x24, 0x24, 0x18, 0x00,
+ 0x6c, 0x28, 0x28, 0x28, 0x28, 0x10, 0x10, 0x00, 0x7e, 0x52, 0x52, 0x2c, 0x2c, 0x24, 0x24, 0x00,
+ 0x6c, 0x28, 0x28, 0x10, 0x28, 0x28, 0x6c, 0x00, 0x6c, 0x28, 0x28, 0x10, 0x10, 0x10, 0x38, 0x00,
+ 0x7c, 0x48, 0x10, 0x10, 0x20, 0x24, 0x7c, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c,
+ 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38,
+ 0x10, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x38, 0x48, 0x3c, 0x00,
+ 0x60, 0x20, 0x38, 0x24, 0x24, 0x24, 0x38, 0x00, 0x00, 0x00, 0x1c, 0x24, 0x20, 0x20, 0x1c, 0x00,
+ 0x0c, 0x04, 0x1c, 0x24, 0x24, 0x24, 0x1e, 0x00, 0x00, 0x00, 0x18, 0x24, 0x3c, 0x20, 0x1c, 0x00,
+ 0x0c, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x28, 0x38, 0x20, 0x3c, 0x3c,
+ 0x60, 0x20, 0x38, 0x24, 0x24, 0x24, 0x76, 0x00, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x38, 0x00,
+ 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x38, 0x60, 0x20, 0x2c, 0x28, 0x30, 0x28, 0x6c, 0x00,
+ 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x78, 0x54, 0x54, 0x54, 0x54, 0x00,
+ 0x00, 0x00, 0x78, 0x24, 0x24, 0x24, 0x76, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
+ 0x00, 0x00, 0x78, 0x24, 0x24, 0x24, 0x38, 0x70, 0x00, 0x00, 0x1c, 0x24, 0x24, 0x24, 0x1c, 0x0e,
+ 0x00, 0x00, 0x34, 0x18, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x20, 0x18, 0x04, 0x3c, 0x00,
+ 0x10, 0x10, 0x38, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x6c, 0x24, 0x24, 0x24, 0x1e, 0x00,
+ 0x00, 0x00, 0x6c, 0x28, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x6f, 0x2a, 0x2a, 0x36, 0x14, 0x00,
+ 0x00, 0x00, 0x7c, 0x28, 0x10, 0x28, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0x28, 0x10, 0x10, 0x20, 0x60,
+ 0x00, 0x00, 0x3c, 0x08, 0x08, 0x10, 0x3c, 0x00, 0x00, 0x08, 0x10, 0x10, 0x20, 0x10, 0x10, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x20, 0x10, 0x10, 0x08, 0x10, 0x10, 0x20,
+ 0x00, 0x00, 0x20, 0x54, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+#endif //__FONT_DOT_H__
+
diff --git a/source/nds/gcheat.c b/source/nds/gcheat.c
new file mode 100644
index 0000000..062ce9d
--- /dev/null
+++ b/source/nds/gcheat.c
@@ -0,0 +1,527 @@
+/* gcheat.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "string.h"
+#include "fs_api.h"
+#include "ds2_malloc.h"
+#include "gcheat.h"
+#include "charsets.h"
+
+#define MAX_SFCCHEAT_NAME 24
+
+
+//GCHEAT_STRUCT gcheat[MAX_CHEATS];
+unsigned int g_cheat_cell_num;
+unsigned int g_cheat_num;
+
+#define SKIP_SPACE(pt) while(' ' == *pt) pt++
+
+static unsigned char* check_is_cht(unsigned char *str)
+{
+ unsigned char *pt, *pt1;
+
+ if(*str == '\0') return NULL;
+
+ pt = str;
+ while(*pt == ' ') pt++; //Skip leading space
+ if(*pt != '[') return NULL; //valid entry should be:[string]
+
+ pt1 = strrchr(str, ']');
+ if(pt1 == NULL) return NULL;
+
+ while(*(--pt1) == ' ');
+ *(pt1+1) = '\0'; //Cut trailing space between string and ']'
+
+ while(*(++pt) == ' '); //Cut space between '[' and string
+
+ return pt;
+}
+
+static unsigned int sscanf_hex_value(unsigned char* str, unsigned int *value)
+{
+ unsigned char *pt;
+ unsigned int tmp;
+ unsigned char ch;
+ unsigned int len;
+
+ pt = str;
+ len = 0;
+ tmp = 0;
+ while(*pt && len < 8)
+ {
+ ch = *pt;
+ if(ch >= 'a' && ch <= 'f') ch = ch - 'a' + 0xa;
+ else if(ch >= 'A' && ch <= 'F') ch = ch - 'A' + 0xa;
+ else if(ch >= '0' && ch <= '9') ch = ch - '0';
+ else if(ch == ' ') continue;
+ else break;
+
+ tmp = (tmp << 4) | ch;
+ pt++;
+ len += 1;
+ }
+
+ *value = tmp;
+ return len;
+}
+
+/*
+* Convert the src string to UTF8 coding dst string, and cut to length
+*/
+int string2utf8(unsigned char *src, unsigned char* dst, unsigned int length)
+{
+ unsigned char *pt;
+ unsigned char ch;
+ unsigned short ucode;
+ unsigned int type;
+ unsigned int len;
+
+ len = 0;
+ type = 0;
+ pt = src;
+ while(*pt)
+ {
+ pt = utf8decode(pt, &ucode);
+ if(ucode < 0x4e00) {
+ if(ucode == 0 || ucode > 0x7F) {
+ type = 1;
+ break;
+ }
+ } else if(ucode > 0x9FCF) {
+ type = 1;
+ break;
+ }
+ else
+ len++;
+
+ if(len >= 3) break; //There is enough UTF8, so it is, to save time(>_*)
+ }
+
+ if(type == 0) //UTF8
+ {
+ while(*src)
+ {
+ ch = *src++;
+ *dst++ = ch;
+
+ if(ch < 0x80) {
+ if(length > 1) length -= 1;
+ else break;
+ } else if (ch < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */
+ if(length > 2) length -= 2;
+ else break;
+ *dst++ = *src++;
+ } else if (ch < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */
+ if(length > 3) length -= 3;
+ else break;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ } else if (ch < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */
+ if(length > 4) length -= 4;
+ else break;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ } else {
+ break;
+ }
+ }
+ *dst = '\0';
+ }
+ else //assume it is GBK code
+ {
+ //GBK to UTF8
+ while(*src)
+ {
+ ch = *src;
+ if(ch < 0x80)
+ {
+ if(length > 1) length -= 1;
+ else break;
+
+ *dst++= ch;
+ src ++;
+ }
+ else
+ {
+ ucode = charsets_gbk_to_ucs(src);
+
+ if (ucode < 0x800) //2 bytes
+ {
+ if(length > 2) length -= 2;
+ else break;
+
+ *dst++ = 0xC0 | ((ucode >> 6) & 0x1F);
+ *dst++ = 0x80 | (ucode & 0x3F);
+ }
+ else //3 bytes
+ {
+ if(length > 3) length -= 3;
+ else break;
+
+ *dst++ = 0xE0 | (ucode >> 12);
+ *dst++ = 0x80 | ((ucode >>6) & 0x3F);
+ *dst++ = 0x80 | (ucode & 0x3F);
+ }
+
+ src += 2;
+ }
+ }
+ *dst = '\0';
+ }
+
+ return 0;
+}
+
+int load_cheatname(const char* filename, unsigned int string_num, unsigned int string_len, MSG_TABLE* mssg_table)
+{
+ FILE *fp;
+ unsigned char current_line[256];
+ unsigned char current_line_tmp[256];
+ int len, m;
+ unsigned char** indexp;
+ unsigned char* msg;
+ unsigned char* pt;
+
+ mssg_table->msg_index = (unsigned char**)malloc(string_num*4);
+ if(NULL == mssg_table->msg_index)
+ return -1;
+
+ string_len = string_len + string_len/2;
+ mssg_table->msg_pool = (unsigned char*)malloc((string_len+31)&(~31));
+ if(NULL == mssg_table->msg_pool) {
+ free((void*)mssg_table->msg_index);
+ return -1;
+ }
+
+ fp = fopen(filename, "r");
+ if(fp == NULL) {
+ free((void*)mssg_table->msg_index);
+ free((void*)mssg_table->msg_pool);
+ return -1;
+ }
+
+ len = 0;
+ m= 0;
+ indexp = mssg_table->msg_index;
+ msg = mssg_table->msg_pool;
+ while(fgets(current_line, 256, fp))
+ {
+ unsigned int str_len;
+
+ if((pt = check_is_cht(current_line)) != NULL)
+ {
+ if(!strcasecmp(pt, "gameinfo"))
+ continue;
+
+ string2utf8(pt, current_line_tmp, 255);
+
+ str_len = strlen(current_line_tmp);
+ strncpy(msg+len, current_line_tmp, str_len);
+
+ indexp[m++] = msg+len;
+ len += str_len;
+ msg[len] = '\0';
+ len += 1;
+
+ if(len >= string_len) break;
+ if(m >= string_num) break;
+
+ while(fgets(current_line, 256, fp))
+ {
+ str_len = strlen(current_line);
+ if(str_len < 4) break;
+
+ if((pt = strchr(current_line, '=')) == NULL) //valid cheat item
+ break;
+
+ *pt = '\0';
+ pt = current_line;
+
+ string2utf8(pt, current_line_tmp, 255);
+
+ str_len = strlen(current_line_tmp);
+ strncpy(msg+len, current_line_tmp, str_len);
+
+ indexp[m++] = msg+len;
+ len += str_len;
+ msg[len] = '\0';
+ len += 1;
+
+ if(len >= string_len) break;
+ if(m >= string_num) break;
+ }
+
+ if(len >= string_len) break;
+ if(m >= string_num) break;
+ }
+ }
+
+ mssg_table -> msg_num = m;
+ fclose(fp);
+
+#if 0
+cprintf("string_len %d; len %d\n", string_len, len);
+for(m= 0; m<mssg_table -> msg_num; m++)
+{
+cprintf("msg%d:%s\n", m, indexp[m]);
+}
+#endif
+
+ return 0;
+}
+
+#define MAX_CHEAT_DATE_LEN (MAX_SFCCHEAT_NAME/2) //other part hold the saved data
+
+/*
+* Load cheat file
+*/
+int load_cheatfile(const char* filename, unsigned int *string_num, unsigned int *string_len,
+ GCHEAT_STRUCT *gcheat)
+{
+ FILE *cheats_file;
+ unsigned char current_line[256];
+ unsigned char current_line_tmp[256];
+ unsigned int current_line_len;
+ unsigned char *pt;
+ int gcheat_num;
+
+ unsigned int str_num;
+ unsigned int str_len;
+ unsigned int cheat_cell_num;
+ int flag;
+
+ cheats_file = fopen(filename, "r");
+ if(NULL == cheats_file)
+ return -1;
+ g_cheat_cell_num = 0;
+ g_cheat_num = 0;
+ cheat_cell_num = 0;
+ gcheat_num = 0;
+ str_num = 0;
+ str_len = 0;
+ flag = 0;
+
+ while(fgets(current_line, 256, cheats_file))
+ {
+ if((pt = check_is_cht(current_line)) == NULL) //Check valid cht cheat
+ continue;
+
+ if(!strcasecmp(pt, "gameinfo")) //maybe file end
+ continue;
+
+ gcheat[gcheat_num].name_id = str_num;
+ gcheat[gcheat_num].item_id = cheat_cell_num;
+ gcheat[gcheat_num].item_num = 0;
+
+ string2utf8(pt, current_line_tmp, CHEAT_NAME_LENGTH);
+ strcpy(gcheat[gcheat_num].name_shot, current_line_tmp); //store a cut name shot
+ //Initialize other parameter of gcheat
+ gcheat[gcheat_num].active = 0;
+ gcheat[gcheat_num].sub_active = 0;
+
+ current_line_len = strlen(pt);
+ str_len += current_line_len +1;
+ str_num++;
+
+ //Cheat items
+ while(fgets(current_line, 256, cheats_file) != NULL)
+ {
+ if(strlen(current_line) < 4)
+ break;
+
+ if((pt = strchr(current_line, '=')) == NULL) //No valid content
+ break;
+
+ //one sub item each pass
+ unsigned int first_part; //first part of a cheat item
+ unsigned int first_part_id;
+ unsigned int sub_part_id;
+ unsigned int hex_len;
+
+ unsigned int cheat_addr;
+ unsigned char cheat_dat[MAX_CHEAT_DATE_LEN];
+ unsigned int cheat_dat_len;
+ unsigned int str_num_saved;
+
+ str_num_saved = str_num;
+ str_len += pt - current_line +1;
+ str_num++;
+
+ first_part = 1;
+ first_part_id = cheat_cell_num;
+ sub_part_id = 0;
+
+ //skip name part
+ pt += 1;
+ current_line_len = strlen(pt);
+
+ //data part
+ while(1)
+ {
+ //fill current_line buffer as full as possible
+ if(current_line_len < (MAX_CHEAT_DATE_LEN*3+8))
+ { //the data length can fill a cheat cell
+ if(NULL == strchr(pt, 0x0A)) { //this line not end
+ memmove(current_line, pt, current_line_len+1);
+ fgets(current_line+current_line_len, 256-current_line_len, cheats_file);
+ pt = current_line;
+ current_line_len = strlen(pt);
+ }
+ }
+#if 0
+cprintf("------\n");
+cprintf("new %d:[%s]\n", current_line_len, pt);
+dump_mem(pt, strlen(pt));
+cprintf("\n------\n");
+#endif
+ //get address
+ if(first_part)
+ {
+ hex_len = sscanf_hex_value(pt, &cheat_addr);
+ if(0 == hex_len) {
+ goto load_cheatfile_error;
+ }
+
+ pt += hex_len;
+ current_line_len -= hex_len +1;
+ // strict to follow the formate
+ if(',' != *pt++ || '\0' == *pt || 0x0D == *pt || 0x0A == *pt) {
+ goto load_cheatfile_error;
+ }
+
+ if(cheat_addr < 0x10000)
+ cheat_addr |= 0x7e0000;
+ else {
+ cheat_addr &= 0xffff;
+ cheat_addr |= 0x7f0000;
+ }
+ }
+
+ //get data
+ unsigned int tmp, m;
+
+ m = 0;
+ cheat_dat_len = 0;
+ while(m++ < MAX_CHEAT_DATE_LEN)
+ {
+ hex_len = sscanf_hex_value(pt, &tmp);
+ if(0 == hex_len) break;
+
+ cheat_dat[cheat_dat_len++] = (unsigned char)tmp;
+
+ pt += hex_len;
+ current_line_len -= hex_len +1;
+ if(',' == *pt) pt++;
+ }
+
+ //In first part, get data error
+ if(0 == cheat_dat_len) {
+ if(0 == sub_part_id)
+ goto load_cheatfile_error;
+ }
+ else {
+ //record data
+ flag = S9xAddCheat_ex(cheat_addr, cheat_dat, cheat_dat_len, cheat_cell_num++, sub_part_id++, str_num_saved);
+ if(0 != flag) {
+ cheat_cell_num -= sub_part_id;
+ break;
+ }
+ }
+
+ if(0 == *pt || 0x0D == *pt || 0x0A == *pt) break; //a line over
+
+ first_part = 0;
+ if(';' == *pt) first_part = 1, pt += 1; //other address of the cheat cell
+ else cheat_addr += cheat_dat_len; //more data
+ } //data part
+
+ //have no enough cheat_cell struct to store cheat
+ if(0 != flag) break;
+
+ S9xAddCheat_ov(first_part_id, sub_part_id);
+ gcheat[gcheat_num].item_num += 1;
+ } //Cheat items
+
+ if(0 != flag) break;
+
+ gcheat_num += 1;
+ if(gcheat_num >= MAX_CHEATS)
+ break;
+ }
+
+ g_cheat_cell_num = cheat_cell_num;
+ g_cheat_num = gcheat_num;
+ *string_num = str_num;
+ *string_len = str_len;
+ fclose(cheats_file);
+
+#if 0
+cprintf("g_cheat_num %d; g_cheat_cell_num %d\n", g_cheat_num, g_cheat_cell_num);
+
+int i;
+for(i= 0; i < g_cheat_cell_num; i++)
+S9x_dumpcheat(i);
+
+for(i= 0; i < g_cheat_num; i++)
+{
+ cprintf("cheat %d\n", i);
+ cprintf("item num %d; item id %d\n", gcheat[i].item_num, gcheat[i].item_id);
+}
+#endif
+
+ return 0;
+
+load_cheatfile_error:
+ fclose(cheats_file);
+ return -1;
+}
+
+void gcheat_Managment(GCHEAT_STRUCT *gcheat)
+{
+ unsigned int i, enable, m, en_flag;
+ unsigned int active, item_id, sub_active, item_num;
+
+ //no cheat
+ if(0 == g_cheat_num || 0 == g_cheat_cell_num) {
+ S9xCheat_Disable();
+ return;
+ }
+
+ enable = 0;
+ for(i = 0; i < g_cheat_num; i++)
+ {
+ active = gcheat[i].active & 0x1;
+ item_id = gcheat[i].item_id;
+ item_num = gcheat[i].item_num;
+ sub_active = gcheat[i].sub_active;
+
+ for(m = 0; m < item_num; m++)
+ {
+ en_flag = sub_active == m ? active : 0;
+ S9xCheat_switch(item_id, m, en_flag);
+ }
+
+ if(active) enable = 1;
+ }
+
+ if(enable)
+ S9xCheat_Enable();
+}
+
diff --git a/source/nds/gcheat.h b/source/nds/gcheat.h
new file mode 100644
index 0000000..e5131f6
--- /dev/null
+++ b/source/nds/gcheat.h
@@ -0,0 +1,65 @@
+/* gcheat.h
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __GCHEAT_H__
+#define __GCHEAT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CHEAT_NAME_LENGTH (32)
+#define MAX_CHEATS_PAGE 10
+#define CHEATS_PER_PAGE 4
+#define MAX_CHEATS (MAX_CHEATS_PAGE * CHEATS_PER_PAGE)
+
+//Support EMU Cheat(emulator cheat) code
+typedef struct
+{
+ u32 name_id; //name ID in another table
+ u32 active; //status
+ u16 item_num; //sub-item number
+ u16 sub_active;
+ u32 item_id; //There is another struct array to store the cheat data
+ char name_shot[CHEAT_NAME_LENGTH];
+ u32 reserved;
+} GCHEAT_STRUCT;
+
+typedef struct
+{
+ unsigned char** msg_index;
+ unsigned char* msg_pool;
+ unsigned int msg_num;
+} MSG_TABLE;
+
+extern GCHEAT_STRUCT gcheat[MAX_CHEATS];
+extern unsigned int g_cheat_cell_num;
+extern unsigned int g_cheat_num;
+
+extern int load_cheatfile(const char* filename, unsigned int *string_num,
+ unsigned int *string_len, GCHEAT_STRUCT *gcheat);
+extern int load_cheatname(const char* filename, unsigned int string_num,
+ unsigned int string_len, MSG_TABLE* mssg_table);
+extern void gcheat_Managment(GCHEAT_STRUCT *gcheat);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__GCHEAT_H__
diff --git a/source/nds/gui.c b/source/nds/gui.c
new file mode 100644
index 0000000..8b8be4a
--- /dev/null
+++ b/source/nds/gui.c
@@ -0,0 +1,4587 @@
+/* gui.c
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "ds2_types.h"
+#include "ds2io.h"
+#include "ds2_malloc.h"
+#include "ds2_cpu.h"
+#include "fs_api.h"
+#include "key.h"
+#include "gui.h"
+#include "draw.h"
+#include "message.h"
+#include "bitmap.h"
+#include "gcheat.h"
+
+char main_path[MAX_PATH];
+char rom_path[MAX_PATH];
+char gamepak_name[MAX_PATH];
+char gcheat_filename[MAX_PATH];
+
+char *lang[2] =
+ {
+ "English", // 0
+ "简体中文", // 1
+ };
+
+/******************************************************************************
+* Macro definition
+ ******************************************************************************/
+#define SUBMENU_ROW_NUM 6
+
+#define NDSSFC_VERSION "1.07"
+
+#define SAVE_STATE_SLOT_NUM 10
+
+#define LANGUAGE_PACK "SYSTEM/language.msg"
+#define EMU_CONFIG_FILENAME "SYSTEM/ndssfc.cfg"
+
+//emulator configure file's header
+#define EMU_CONFIG_HEADER "NSFC1.0"
+#define EMU_CONFIG_HEADER_SIZE 7
+EMU_CONFIG emu_config;
+
+//game configure file's header
+#define GAME_CONFIG_HEADER "GSFC1.0"
+#define GAME_CONFIG_HEADER_SIZE 7
+GAME_CONFIG game_config;
+
+//save state file map
+char savestate_map[SAVE_STATE_SLOT_NUM];
+static unsigned int savestate_index;
+
+#define MAKE_MENU(name, init_function, passive_function, key_function, end_function, \
+ focus_option, screen_focus) \
+ MENU_TYPE name##_menu = \
+ { \
+ init_function, \
+ passive_function, \
+ key_function, \
+ end_function, \
+ name##_options, \
+ sizeof(name##_options) / sizeof(MENU_OPTION_TYPE), \
+ focus_option, \
+ screen_focus \
+ } \
+
+#define INIT_MENU(name, init_functions, passive_functions, key, end, focus, screen)\
+ { \
+ name##_menu.init_function = init_functions, \
+ name##_menu.passive_function = passive_functions, \
+ name##_menu.key_function = key, \
+ name##_menu.end_function = end, \
+ name##_menu.options = name##_options, \
+ name##_menu.num_options = sizeof(name##_options) / sizeof(MENU_OPTION_TYPE),\
+ name##_menu.focus_option = focus, \
+ name##_menu.screen_focus = screen; \
+ } \
+
+#define CHEAT_OPTION(action_function, passive_function, number, line_number) \
+{ \
+ action_function, \
+ passive_function, \
+ NULL, \
+ &cheat_format_ptr[number], \
+ enable_disable_options, \
+ &(game_config.cheats_flag[number].active), \
+ 2, \
+ NULL, \
+ line_number, \
+ STRING_SELECTION_TYPE | ACTION_TYPE \
+} \
+
+#define ACTION_OPTION(action_function, passive_function, display_string, \
+ help_string, line_number) \
+{ \
+ action_function, \
+ passive_function, \
+ NULL, \
+ display_string, \
+ NULL, \
+ NULL, \
+ 0, \
+ help_string, \
+ line_number, \
+ ACTION_TYPE \
+} \
+
+#define SUBMENU_OPTION(sub_menu, display_string, help_string, line_number) \
+{ \
+ NULL, \
+ NULL, \
+ sub_menu, \
+ display_string, \
+ NULL, \
+ NULL, \
+ sizeof(sub_menu) / sizeof(MENU_OPTION_TYPE), \
+ help_string, \
+ line_number, \
+ SUBMENU_TYPE \
+} \
+
+#define SELECTION_OPTION(passive_function, display_string, options, \
+ option_ptr, num_options, help_string, line_number, type) \
+{ \
+ NULL, \
+ passive_function, \
+ NULL, \
+ display_string, \
+ options, \
+ option_ptr, \
+ num_options, \
+ help_string, \
+ line_number, \
+ type \
+} \
+
+#define ACTION_SELECTION_OPTION(action_function, passive_function, \
+ display_string, options, option_ptr, num_options, help_string, line_number, \
+ type) \
+{ \
+ action_function, \
+ passive_function, \
+ NULL, \
+ display_string, \
+ options, \
+ option_ptr, \
+ num_options, \
+ help_string, \
+ line_number, \
+ type | ACTION_TYPE \
+} \
+
+#define STRING_SELECTION_OPTION(action_function, passive_function, \
+ display_string, options, option_ptr, num_options, help_string, action, line_number)\
+{ \
+ action_function, \
+ passive_function, \
+ NULL, \
+ display_string, \
+ options, \
+ option_ptr, \
+ num_options, \
+ help_string, \
+ line_number, \
+ STRING_SELECTION_TYPE | action \
+}
+
+#define NUMERIC_SELECTION_OPTION(passive_function, display_string, \
+ option_ptr, num_options, help_string, line_number) \
+ SELECTION_OPTION(passive_function, display_string, NULL, option_ptr, \
+ num_options, help_string, line_number, NUMBER_SELECTION_TYPE) \
+
+#define STRING_SELECTION_HIDEN_OPTION(action_function, passive_function, \
+ display_string, options, option_ptr, num_options, help_string, line_number) \
+ ACTION_SELECTION_OPTION(action_function, passive_function, \
+ display_string, options, option_ptr, num_options, help_string, \
+ line_number, (STRING_SELECTION_TYPE | HIDEN_TYPE)) \
+
+#define NUMERIC_SELECTION_ACTION_OPTION(action_function, passive_function, \
+ display_string, option_ptr, num_options, help_string, line_number) \
+ ACTION_SELECTION_OPTION(action_function, passive_function, \
+ display_string, NULL, option_ptr, num_options, help_string, \
+ line_number, NUMBER_SELECTION_TYPE) \
+
+#define NUMERIC_SELECTION_HIDE_OPTION(action_function, passive_function, \
+ display_string, option_ptr, num_options, help_string, line_number) \
+ ACTION_SELECTION_OPTION(action_function, passive_function, \
+ display_string, NULL, option_ptr, num_options, help_string, \
+ line_number, NUMBER_SELECTION_TYPE) \
+
+
+typedef enum
+{
+ NUMBER_SELECTION_TYPE = 0x01,
+ STRING_SELECTION_TYPE = 0x02,
+ SUBMENU_TYPE = 0x04,
+ ACTION_TYPE = 0x08,
+ HIDEN_TYPE = 0x10,
+ PASSIVE_TYPE = 0x00,
+} MENU_OPTION_TYPE_ENUM;
+
+struct _MENU_OPTION_TYPE
+{
+ void (* action_function)(); //Active option to process input
+ void (* passive_function)(); //Passive function to process this option
+ struct _MENU_TYPE *sub_menu; //Sub-menu of this option
+ char **display_string; //Name and other things of this option
+ void *options; //output value of this option
+ u32 *current_option; //output values
+ u32 num_options; //Total output values
+ char **help_string; //Help string
+ u32 line_number; //Order id of this option in it menu
+ MENU_OPTION_TYPE_ENUM option_type; //Option types
+};
+
+struct _MENU_TYPE
+{
+ void (* init_function)(); //Function to initialize this menu
+ void (* passive_function)(); //Function to draw this menu
+ void (* key_function)(); //Function to process input
+ void (* end_function)(); //End process of this menu
+ struct _MENU_OPTION_TYPE *options; //Options array
+ u32 num_options; //Total options of this menu
+ u32 focus_option; //Option which obtained focus
+ u32 screen_focus; //screen positon of the focus option
+};
+
+typedef struct _MENU_OPTION_TYPE MENU_OPTION_TYPE;
+typedef struct _MENU_TYPE MENU_TYPE;
+
+/******************************************************************************
+ ******************************************************************************/
+char g_default_rom_dir[MAX_PATH];
+char DEFAULT_RTS_DIR[MAX_PATH];
+char DEFAULT_CFG_DIR[MAX_PATH];
+char DEFAULT_SS_DIR[MAX_PATH];
+char DEFAULT_CHEAT_DIR[MAX_PATH];
+u32 game_fast_forward= 0;
+u32 game_enable_audio = 1;
+
+
+
+
+/******************************************************************************
+ ******************************************************************************/
+static u32 menu_cheat_page = 0;
+static u32 clock_speed_number = 2;
+u32 gamepad_config_menu;
+
+/******************************************************************************
+ ******************************************************************************/
+static void get_savestate_filelist(void);
+static FILE* get_savestate_snapshot(char *savestate_filename);
+static void get_savestate_filename(u32 slot, char *name_buffer);
+static u32 get_savestate_slot(void);
+static void reorder_savestate_slot(void);
+void get_newest_savestate(char *name_buffer);
+static int sort_function(const void *dest_str_ptr, const void *src_str_ptr);
+static u32 parse_line(char *current_line, char *current_str);
+static void get_timestamp_string(char *buffer, u16 msg_id, u16 year, u16 mon, u16 day, u16 wday, u16 hour, u16 min, u16 sec, u32 msec);
+static void get_time_string(char *buff, struct rtc *rtcp);
+static u32 save_ss_bmp(u16 *image);
+static void init_game_config(void);
+static void init_emulator_config(void);
+static void load_game_config_file(void);
+static int load_emu_config_file(void);
+static int save_game_config_file(void);
+static int save_emu_config_file(void);
+static void reorder_latest_file(void);
+static void quit(void);
+
+/*--------------------------------------------------------
+ Get GUI input
+--------------------------------------------------------*/
+gui_action_type get_gui_input(void)
+{
+ unsigned int key;
+ gui_action_type ret;
+
+ key = getKey();
+
+ switch(key)
+ {
+ case KEY_UP:
+ ret = CURSOR_UP;
+ break;
+ case KEY_DOWN:
+ ret = CURSOR_DOWN;
+ break;
+ case KEY_LEFT:
+ ret = CURSOR_LEFT;
+ break;
+ case KEY_RIGHT:
+ ret = CURSOR_RIGHT;
+ break;
+ case KEY_L:
+ ret = CURSOR_LTRIGGER;
+ break;
+ case KEY_R:
+ ret = CURSOR_RTRIGGER;
+ break;
+ case KEY_A:
+ ret = CURSOR_SELECT;
+ break;
+ case KEY_B:
+ ret = CURSOR_BACK;
+ break;
+ case KEY_X:
+ ret = CURSOR_EXIT;
+ break;
+ default:
+ ret = CURSOR_NONE;
+ break;
+ }
+
+ return ret;
+}
+
+/*--------------------------------------------------------
+ Wait any key in [key_list] pressed
+ if key_list == NULL, return at any key pressed
+--------------------------------------------------------*/
+unsigned int wait_Anykey_press(unsigned int key_list)
+{
+ unsigned int key;
+
+ while(1)
+ {
+ key = getKey();
+ if(key) {
+ if(0 == key_list) break;
+ else if(key & key_list) break;
+ }
+ }
+
+ return key;
+}
+
+/*--------------------------------------------------------
+ Wait all key in [key_list] released
+ if key_list == NULL, return at all key released
+--------------------------------------------------------*/
+void wait_Allkey_release(unsigned int key_list)
+{
+ unsigned int key;
+ struct key_buf inputdata;
+
+ while(1)
+ {
+ ds2_getrawInput(&inputdata);
+ key = inputdata.key;
+
+ if(0 == key) break;
+ else if(!key_list) continue;
+ else if(0 == (key_list & key)) break;
+ }
+}
+
+void change_ext(char *src, char *buffer, char *extension)
+{
+ char *dot_position;
+
+ strcpy(buffer, src);
+ dot_position = strrchr(buffer, '.');
+
+ if(dot_position)
+ strcpy(dot_position, extension);
+}
+
+/*--------------------------------------------------------
+ Sort function
+--------------------------------------------------------*/
+static int sort_function(const void *dest_str_ptr, const void *src_str_ptr)
+{
+ char *dest_str = *((char **)dest_str_ptr);
+ char *src_str = *((char **)src_str_ptr);
+
+ if(src_str[0] == '.')
+ return 1;
+
+ if(dest_str[0] == '.')
+ return -1;
+
+ return strcasecmp(dest_str, src_str);
+}
+
+static int my_array_partion(void *array, int left, int right)
+{
+ unsigned int pivot= *((unsigned int*)array + left);
+
+ while(left < right)
+ {
+ while(sort_function((void*)((unsigned int*)array+left), (void*)((unsigned int *)array+right)) < 0) {
+ right--;
+ }
+
+ if(right== left) break;
+ *((unsigned int*)array + left) = *((unsigned int*)array + right);
+ *((unsigned int*)array + right) = pivot;
+
+ if(left < right)
+ {
+ left++;
+ if(right== left) break;
+ }
+
+ while(sort_function((void*)((unsigned int*)array+right), (void*)((unsigned int *)array+left)) > 0) {
+ left++;
+ }
+
+ if(left== right) break;
+ *((unsigned int*)array + right) = *((unsigned int*)array + left);
+ *((unsigned int*)array + left) = pivot;
+ right--;
+ }
+
+ return left;
+}
+
+static void my_qsort(void *array, int left, int right)
+{
+ if(left < right)
+ {
+ int mid= my_array_partion(array, left, right);
+ my_qsort(array, left, mid-1);
+ my_qsort(array, mid+1, right);
+ }
+}
+
+static void strupr(char *str)
+{
+ while(*str)
+ {
+ if(*str <= 0x7A && *str >= 0x61) *str -= 0x20;
+ str++;
+ }
+}
+
+//******************************************************************************
+// get file list
+//******************************************************************************
+#define FILE_LIST_MAX 512
+#define DIR_LIST_MAX 64
+#define NAME_MEM_SIZE (320*64)
+
+struct FILE_LIST_INFO
+{
+ char current_path[MAX_PATH];
+ char **wildcards;
+ unsigned int file_num;
+ unsigned int dir_num;
+ unsigned int mem_size;
+ unsigned int file_size;
+ unsigned int dir_size;
+ char **file_list;
+ char **dir_list;
+ char *filename_mem;
+};
+
+/*
+* Function: internal function to manage FILE_LIST_INFO structure
+* filelist_infop: a pointer to a predefined FILE_LIST_INFO structure
+* flag: 0 initialize the structure
+* 1 increase filename memory size
+* 2 increase file name buffer size
+* 4 increase directory name buffer size
+* -1 free all allocated memroy
+* other value are invalide
+* return: -1 on failure
+*/
+static int manage_filelist_info(struct FILE_LIST_INFO *filelist_infop, int flag)
+{
+ //Initialize
+ if(0 == flag)
+ {
+ filelist_infop->file_list = (char**)malloc(FILE_LIST_MAX*4);
+ if(NULL == filelist_infop->file_list)
+ return -1;
+
+ filelist_infop->dir_list = (char**)malloc(DIR_LIST_MAX*4);
+ if(NULL == filelist_infop->dir_list)
+ {
+ free((void*)filelist_infop->file_list);
+ return -1;
+ }
+
+ filelist_infop->filename_mem = (char*)malloc(NAME_MEM_SIZE);
+ if(NULL == filelist_infop->filename_mem)
+ {
+ free((void*)filelist_infop->file_list);
+ free((void*)filelist_infop->dir_list);
+ return -1;
+ }
+
+ filelist_infop->mem_size = NAME_MEM_SIZE;
+ filelist_infop->file_size = FILE_LIST_MAX;
+ filelist_infop->dir_size = DIR_LIST_MAX;
+ return 0;
+ }
+ //free all memroy
+ if(-1 == flag)
+ {
+ free((void*)filelist_infop->file_list);
+ free((void*)filelist_infop->dir_list);
+ free((void*)filelist_infop->filename_mem);
+ return 0;
+ }
+
+ int i;
+ void *pt;
+
+ //Increase all
+ if(flag & 0x1)
+ {
+ i = NAME_MEM_SIZE;
+
+ do
+ {
+ pt = (void*)realloc(filelist_infop->filename_mem, filelist_infop->mem_size+i);
+ if(NULL == pt) i /= 2;
+ } while(i > 256);
+
+ if(NULL == pt) return -1;
+
+ filelist_infop->mem_size += i;
+ filelist_infop->filename_mem = (char*)pt;
+ i = (int)pt - (int)filelist_infop->file_list;
+
+ int k;
+ char **m;
+
+ k = 0;
+ m = filelist_infop->file_list;
+ for(k= 0; k < filelist_infop->file_num; k++)
+ m[k] += i;
+
+ k = 0;
+ m = filelist_infop->dir_list;
+ for(k = 0; k < filelist_infop->dir_num; k++)
+ m[k] += i;
+ }
+ //Increase file name buffer
+ if(flag & 0x2)
+ {
+ i = filelist_infop->file_size + FILE_LIST_MAX;
+
+ pt = (void*)realloc(filelist_infop->file_list, i*4);
+ if(NULL == pt) return -1;
+
+ filelist_infop->file_list = (char**)pt;
+ filelist_infop->file_size = i;
+ }
+ //Increase directory name buffer
+ if(flag & 0x4)
+ {
+ i = filelist_infop->dir_size + DIR_LIST_MAX;
+
+ pt = (void*)realloc(filelist_infop->dir_list, i*4);
+ if(NULL == pt) return -1;
+
+ filelist_infop->dir_list = (char**)pt;
+ filelist_infop->dir_size = i;
+ }
+
+ return 0;
+}
+
+static int load_file_list(struct FILE_LIST_INFO *filelist_infop)
+{
+ DIR* current_dir;
+ char current_dir_name[MAX_PATH];
+ dirent *current_file;
+ struct stat st;
+ char *file_name;
+ unsigned int len;
+ unsigned int file_name_length;
+ char* name_mem_base;
+ char **file_list;
+ char **dir_list;
+ unsigned int mem_size;
+ unsigned int file_size;
+ unsigned int dir_size;
+ unsigned int num_files;
+ unsigned int num_dirs;
+ char **wildcards;
+ char utf8[512+256];
+
+ if(filelist_infop -> current_path == NULL)
+ return -1;
+
+ name_mem_base = &(filelist_infop -> filename_mem[0]);
+ mem_size = filelist_infop -> mem_size;
+ file_size = filelist_infop -> file_size;
+ dir_size = filelist_infop -> dir_size;
+ file_list = filelist_infop -> file_list;
+ dir_list = filelist_infop -> dir_list;
+ num_files = 0;
+ num_dirs = 0;
+ wildcards = filelist_infop -> wildcards;
+
+ strcpy(current_dir_name, filelist_infop -> current_path);
+
+ //* path formate should be: "fat:/" or "fat:/dir0" or "fat:", not "fat:/dir0/"
+ current_dir = opendir(current_dir_name);
+ //Open directory faiure
+ if(current_dir == NULL) {
+ return -1;
+ }
+
+ file_name_length = 0;
+ //while((current_file = readdir(current_dir)) != NULL)
+ while((current_file = readdir_ex(current_dir, &st)) != NULL)
+ {
+ //lstat(current_file->d_name, &st);
+ file_name = current_file->d_name;
+
+ len = strlen(file_name) +1;
+ if((file_name_length+len) > mem_size)
+ {
+ //get more memory
+ if(manage_filelist_info(filelist_infop, 1) == -1)
+ break;
+
+ name_mem_base = &(filelist_infop -> filename_mem[0]);
+ mem_size = filelist_infop -> mem_size;
+ }
+ //Increase file_list
+ if(num_files >= file_size) {
+ if(manage_filelist_info(filelist_infop, 2) == -1)
+ break;
+ file_size = filelist_infop -> file_size;
+ }
+ //Increase dir_list
+ if(num_dirs >= dir_size) {
+ if(manage_filelist_info(filelist_infop, 4) == -1)
+ break;
+ dir_size = filelist_infop -> dir_size;
+ }
+
+ //If dirctory
+ if(S_ISDIR(st.st_mode))
+ {
+ if(file_name[0] != '.')
+ {
+ dir_list[num_dirs] = name_mem_base + file_name_length;
+ strcpy(dir_list[num_dirs], file_name);
+ num_dirs++;
+ file_name_length += len;
+ }
+ //take ".." directory as file
+ else if(file_name[1] == '.')
+ {
+ file_list[num_files] = name_mem_base + file_name_length;
+ strcpy(file_list[num_files], file_name);
+ num_files++;
+ file_name_length += len;
+ }
+ }
+ else
+ {
+ char *ext_pos;
+ unsigned int i;
+
+ ext_pos = (char*)strrchr((const char*)file_name, '.');
+ if(NULL != ext_pos)
+ for(i = 0; wildcards[i] != NULL; i++)
+ {
+ if(!strcasecmp(ext_pos, wildcards[i]))
+ {
+ file_list[num_files] = name_mem_base + file_name_length;
+ strcpy(file_list[num_files], file_name);
+ num_files++;
+ file_name_length += len;
+ break;
+ }
+ }
+ }
+ }
+
+ closedir(current_dir);
+
+ filelist_infop -> file_num = num_files;
+ filelist_infop -> dir_num = num_dirs;
+ //printf("%s: num_files %d; num_dirs %d\n", filelist_infop ->current_path, num_files, num_dirs);
+#if 0
+ my_qsort((void *)file_list, 0, num_files-1);
+#else //to support ".." directory, but take it as file
+ my_qsort((void *)file_list, 1, num_files-1);
+#endif
+ my_qsort((void *)dir_list, 0, num_dirs-1);
+
+ return 0;
+}
+
+/*--------------------------------------------------------
+ 读å–文件
+--------------------------------------------------------*/
+#define FILE_LIST_ROWS 6
+#define FILE_LIST_ROWS_CENTER ((FILE_LIST_ROWS+1)/2-1)
+#define FILE_LIST_POSITION 42 //Started displaying x position
+
+s32 load_file(char **wildcards, char *result, char *default_dir_name)
+{
+ struct FILE_LIST_INFO filelist_info;
+ u32 repeat;
+ int return_value;
+ gui_action_type gui_action;
+ u32 selected_item_on_list;
+ u32 selected_item_on_screen;
+ u32 to_update_filelist;
+ u32 total_items_num;
+ int redraw;
+ u32 path_scroll;
+ u32 num_files; //File numbers on the directory
+ u32 num_dirs; //Directory numbers on the dirctory
+ char **file_list;
+ char **dir_list;
+ int flag;
+
+ //Have no path
+ if(NULL == default_dir_name)
+ return -1;
+
+ //construct filelist_info struct
+ if(-1 == manage_filelist_info(&filelist_info, 0))
+ return -1;
+
+ result[0] = '\0';
+ strcpy(filelist_info.current_path, default_dir_name);
+
+ filelist_info.wildcards = wildcards;
+ filelist_info.file_num = 0;
+ filelist_info.dir_num = 0;
+
+ flag = load_file_list(&filelist_info);
+ if(-1 == flag)
+ {
+ //deconstruct filelist_info struct
+ manage_filelist_info(&filelist_info, -1);
+ return -1;
+ }
+
+ num_files = filelist_info.file_num;
+ num_dirs = filelist_info.dir_num;
+ file_list = filelist_info.file_list;
+ dir_list = filelist_info.dir_list;
+
+ selected_item_on_list = 0; //Selected item on list
+ selected_item_on_screen = 0; //Selected item on screen's position
+ redraw = -1; //redraw all
+ total_items_num = num_files + num_dirs;
+ to_update_filelist = 0; //to load new file list
+ path_scroll = 0x8000; //path scroll method, first scroll left
+
+ repeat= 1;
+ return_value = -1;
+ while(repeat)
+ {
+ gui_action = get_gui_input();
+
+ switch(gui_action)
+ {
+ case CURSOR_UP:
+ redraw = 1;
+ if(selected_item_on_screen > 0)
+ {
+ //Not the first item on list
+ selected_item_on_list -= 1;
+ //Selected item on screen center
+ if(FILE_LIST_ROWS_CENTER == selected_item_on_screen) {
+ if(selected_item_on_screen > selected_item_on_list)
+ selected_item_on_screen -= 1;
+ }
+ //Selected item on down half screen
+ else if(FILE_LIST_ROWS_CENTER < selected_item_on_screen) {
+ selected_item_on_screen -= 1;
+ }
+ //Selected item on up half screen
+ else {
+ if(selected_item_on_screen < selected_item_on_list)
+ selected_item_on_screen += 1;
+ else if(selected_item_on_screen > selected_item_on_list)
+ selected_item_on_screen -= 1;
+ }
+ }
+ else if(selected_item_on_screen > selected_item_on_list) {
+ selected_item_on_screen -= 1;
+ }
+ else
+ redraw = 0;
+
+ break;
+
+ case CURSOR_DOWN:
+ {
+ unsigned int m, n;
+ m = total_items_num - (selected_item_on_list + 1);
+ n = FILE_LIST_ROWS - (FILE_LIST_ROWS_CENTER + 1);
+ //Selected item on screen center
+ if(FILE_LIST_ROWS_CENTER == selected_item_on_screen) {
+ if(m > 0 && m < n)
+ selected_item_on_screen += 1;
+ redraw = 1;
+ }
+ //Selected item on down half screen
+ else if(FILE_LIST_ROWS_CENTER < selected_item_on_screen) {
+ if(m > 0) {
+ redraw = 1;
+ if(m <= n) selected_item_on_screen += 1;
+ else if(m > n) selected_item_on_screen -= 1;
+ else redraw = 0; //cancel
+ }
+ }
+ //Selected item on up half screen
+ else {
+ if(m > 0) {
+ selected_item_on_screen += 1;
+ redraw = 1;
+ }
+ }
+
+ //Not reach the last item
+ if((selected_item_on_list + 1) < total_items_num)
+ selected_item_on_list += 1;
+
+ break;
+ }
+ //scroll page down
+ case CURSOR_RTRIGGER:
+ {
+ unsigned int m, n;
+ //first item on screen in item list's position
+ m = selected_item_on_list - selected_item_on_screen;
+ n = total_items_num - (m+1);
+ //there are more than 1 page after the m item
+ if(n >= FILE_LIST_ROWS) {
+ m += FILE_LIST_ROWS -1;
+ selected_item_on_list = m;
+
+ m = total_items_num - (selected_item_on_list +1);
+ if(m >= (FILE_LIST_ROWS_CENTER +1))
+ selected_item_on_screen = FILE_LIST_ROWS_CENTER;
+ else
+ selected_item_on_screen = 0;
+
+ selected_item_on_list += selected_item_on_screen;
+ redraw = 1;
+ }
+
+ break;
+ }
+ //scroll page up
+ case CURSOR_LTRIGGER:
+ {
+ unsigned int m;
+ //first item on screen in item list's position
+ m = selected_item_on_list - selected_item_on_screen;
+ //there are more than 1 page befroe the m item
+ if((m+1) >= FILE_LIST_ROWS)
+ {
+ m -= FILE_LIST_ROWS -1;
+ selected_item_on_list = m;
+
+ selected_item_on_screen = FILE_LIST_ROWS_CENTER;
+ selected_item_on_list += selected_item_on_screen;
+ redraw = 1;
+ }
+
+ break;
+ }
+ //scroll string
+ case CURSOR_RIGHT:
+ redraw = -5;
+ break;
+ //scroll string
+ case CURSOR_LEFT:
+ redraw = 5;
+ break;
+
+ case CURSOR_SELECT:
+ //file selected
+ if(selected_item_on_list + 1 <= num_files)
+ {
+ //The ".." directory
+ if(!strcasecmp(file_list[selected_item_on_list], ".."))
+ {
+ char *ext_pos;
+
+ strcpy(filelist_info.current_path, default_dir_name);
+ ext_pos = strrchr(filelist_info.current_path, '/');
+ if(NULL != ext_pos) //Not root directory
+ {
+ *ext_pos = '\0';
+ to_update_filelist= 1;
+ }
+ }
+ else
+ {
+ repeat = 0;
+ return_value = 0;
+ strcpy(default_dir_name, filelist_info.current_path);
+ strcpy(result, file_list[selected_item_on_list]);
+ }
+ }
+ //directory selected
+ else if(num_dirs > 0)
+ {
+ unsigned int m;
+
+ m = selected_item_on_list - num_files;
+ strcpy(filelist_info.current_path, default_dir_name);
+ strcat(filelist_info.current_path, "/");
+ strcat(filelist_info.current_path, dir_list[m]);
+ to_update_filelist= 1;
+ }
+ break;
+
+ case CURSOR_BACK:
+ {
+ char *ext_pos;
+
+ strcpy(filelist_info.current_path, default_dir_name);
+ ext_pos = strrchr(filelist_info.current_path, '/');
+ if(NULL != ext_pos) //Not root directory
+ {
+ *ext_pos = '\0';
+ to_update_filelist= 1;
+ }
+ else { //is root directory
+ return_value = -1;
+ repeat = 0;
+ }
+ break;
+ }
+
+ case CURSOR_EXIT:
+ return_value = -1;
+ repeat = 0;
+ break;
+
+ default:
+ break;
+ } //end switch
+
+ if(to_update_filelist)
+ {
+ flag = load_file_list(&filelist_info);
+ if(-1 != flag) {
+ strcpy(default_dir_name, filelist_info.current_path);
+ num_files = filelist_info.file_num;
+ num_dirs = filelist_info.dir_num;
+ total_items_num = num_files + num_dirs;;
+
+ selected_item_on_list = 0; //Selected item on list
+ selected_item_on_screen = 0; //Selected item on screen's position
+
+ redraw = -1; //redraw all
+ }
+ to_update_filelist = 0;
+ }
+
+ //redraw, code reuse
+ if(-1 == redraw || 1 == redraw)
+ {
+ unsigned int m, n, k;
+ char *pt;
+ unsigned short color;
+
+ //draw background
+ show_icon(down_screen_addr, ICON_SUBBG, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ //release data struct to draw scrolling string
+ //Path
+ if(-1 == redraw) {
+ draw_hscroll_over(0);
+ draw_hscroll_init(down_screen_addr, 49, 10, 170, COLOR_TRANS,
+ COLOR_WHITE, default_dir_name);
+ path_scroll = 0x8000; //first scroll left
+ }
+
+ for(m = 0; m < MAX_SCROLL_STRING; m++)
+ draw_hscroll_over(m+1);
+
+ //file and directory list
+ //the first displayed item
+ m = selected_item_on_list - selected_item_on_screen;
+ //nubers of item to displayed
+ n = total_items_num - m;
+ if(n > FILE_LIST_ROWS) n = FILE_LIST_ROWS;
+
+ for(k= 0; k < n; k++, m++)
+ {
+ if(k == selected_item_on_screen) {
+ color = COLOR_ACTIVE_ITEM;
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + k*27);
+ }
+ else
+ color = COLOR_INACTIVE_ITEM;
+
+ //directorys
+ if((m+1) > num_files) {
+ show_icon(down_screen_addr, ICON_DIRECTORY, 17, 37 + k*27);
+ pt = dir_list[m - num_files];
+ }
+ //files
+ else {
+ pt= strrchr(file_list[m], '.');
+
+ if(!strcasecmp(pt, ".smc") || !strcasecmp(pt, ".sfc"))
+ show_icon(down_screen_addr, ICON_SFCFILE, 17, 37 + k*27);
+ else if(!strcasecmp(pt, ".zip"))
+ show_icon(down_screen_addr, ICON_ZIPFILE, 17, 37 + k*27);
+ else if(!strcasecmp(pt, ".cht"))
+ show_icon(down_screen_addr, ICON_CHTFILE, 17, 37 + k*27);
+ else if(!strcasecmp(file_list[m], ".."))
+ show_icon(down_screen_addr, ICON_DOTDIR, 17, 37 + k*27);
+ else //Not recoganized file
+ show_icon(down_screen_addr, ICON_UNKNOW, 17, 37 + k*27);
+
+ pt = file_list[m];
+ }
+
+ draw_hscroll_init(down_screen_addr, 41, 40 + k*27, 185,
+ COLOR_TRANS, color, pt);
+ }
+
+ redraw = 0;
+ ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer
+ } //end if(0 != redraw)
+ else if(0 != redraw) {
+ unsigned int m, n;
+ char *pt;
+
+ m = selected_item_on_screen;
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + m*27);
+
+ n = selected_item_on_list;
+ if((n+1) > num_files)
+ show_icon(down_screen_addr, ICON_DIRECTORY, 17, 37 + m*27);
+ else {
+ pt= strrchr(file_list[n], '.');
+
+ if(!strcasecmp(pt, ".smc"))
+ show_icon(down_screen_addr, ICON_SFCFILE, 17, 37 + m*27);
+ else if(!strcasecmp(pt, ".zip"))
+ show_icon(down_screen_addr, ICON_ZIPFILE, 17, 37 + m*27);
+ else if(!strcasecmp(pt, ".cht"))
+ show_icon(down_screen_addr, ICON_CHTFILE, 17, 37 + m*27);
+ else if(!strcasecmp(file_list[m], ".."))
+ show_icon(down_screen_addr, ICON_DOTDIR, 17, 37 + m*27);
+ else //Not recoganized file
+ show_icon(down_screen_addr, ICON_UNKNOW, 17, 37 + m*27);
+ }
+
+ draw_hscroll(m+1, redraw);
+ ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer
+ redraw = 0;
+ }
+
+ //Path auto scroll
+ unsigned int m = path_scroll & 0xFF;
+ if(m < 20) //pause 0.5sec
+ path_scroll += 1;
+ else {
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ if(path_scroll & 0x8000) //scroll left
+ {
+ if(draw_hscroll(0, -1) <= 1) path_scroll = 0; //scroll right
+ }
+ else
+ {
+ if(draw_hscroll(0, 1) <= 1) path_scroll = 0x8000; //scroll left
+ }
+ ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer
+ }
+
+ mdelay(50); //about 50ms
+ } //end while(repeat)
+
+ unsigned int i;
+ for(i= 0; i < (FILE_LIST_ROWS +1); i++)
+ draw_hscroll_over(i);
+
+ //deconstruct filelist_info struct
+ manage_filelist_info(&filelist_info, -1);
+
+ ds2_clearScreen(DOWN_SCREEN, COLOR_BLACK);
+ ds2_flipScreen(DOWN_SCREEN, 2); //not switch down screen buffer
+
+ return return_value;
+}
+
+/*--------------------------------------------------------
+ 放映幻ç¯ç‰‡
+--------------------------------------------------------*/
+u32 play_screen_snapshot(void)
+{
+ struct FILE_LIST_INFO filelist_info;
+ char *file_ext[] = { ".bmp", NULL };
+ u32 file_num;
+ char **file_list;
+ s32 flag;
+ u32 repeat, i;
+ u16 *screenp;
+ u32 color_bg;
+
+ screenp= (u16*)malloc(256*192*2);
+ if(screenp == NULL)
+ {
+ screenp = (u16*)down_screen_addr;
+ color_bg = COLOR_BG;
+ }
+ else
+ {
+ memcpy(screenp, down_screen_addr, 256*192*2);
+ color_bg = COLOR16(43, 11, 11);
+ }
+
+ //construct filelist_info struct
+ if(-1 == manage_filelist_info(&filelist_info, 0))
+ return -1;
+
+ strcpy(filelist_info.current_path, DEFAULT_SS_DIR);
+
+ filelist_info.wildcards = file_ext;
+ filelist_info.file_num = 0;
+ filelist_info.dir_num = 0;
+
+ flag = load_file_list(&filelist_info);
+ if(-1 == flag)
+ {
+ //construct filelist_info struct
+ manage_filelist_info(&filelist_info, -1);
+ return -1;
+ }
+
+ flag = load_file_list(&filelist_info);
+ file_num = filelist_info.file_num;
+ file_list = filelist_info.file_list;
+
+ if(flag < 0 || file_num== 0)
+ {
+ draw_message(down_screen_addr, screenp, 28, 31, 227, 165, color_bg);
+ draw_string_vcenter(down_screen_addr, 36, 55, 190, COLOR_MSSG, msg[MSG_NO_SLIDE]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ if(screenp) free((void*)screenp);
+ //construct filelist_info struct
+ manage_filelist_info(&filelist_info, -1);
+
+ if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(A)"))
+ return 1;
+ else
+ return 0;
+ }
+
+ char bmp_path[MAX_PATH];
+ BMPINFO SbmpInfo;
+
+ u32 buff[256*192];
+ u32 time0= 10;
+ u32 pause= 0;
+ unsigned int type;
+
+ draw_message(down_screen_addr, screenp, 28, 31, 227, 165, color_bg);
+ draw_string_vcenter(down_screen_addr, 36, 70, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE1]);
+ draw_string_vcenter(down_screen_addr, 36, 85, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE2]);
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE3]);
+ draw_string_vcenter(down_screen_addr, 36, 115, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE4]);
+ draw_string_vcenter(down_screen_addr, 36, 130, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE5]);
+ draw_string_vcenter(down_screen_addr, 36, 145, 190, COLOR_MSSG, msg[MSG_PLAY_SLIDE6]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ repeat= 1;
+ i= 0;
+ while(repeat)
+ {
+ sprintf(bmp_path, "%s/%s", filelist_info.current_path, file_list[i]);
+
+ flag = openBMP(&SbmpInfo, (const char*)bmp_path);
+ if(flag == BMP_OK)
+ {
+ type = SbmpInfo.bmpHead.bfImghead.imBitpixel >>3;
+ if(2 == type || 3 == type) //2 bytes per pixel
+ {
+ u16 *dst, *dst0;
+ u32 w, h, x, y;
+
+ w= SbmpInfo.bmpHead.bfImghead.imBitmapW;
+ h= SbmpInfo.bmpHead.bfImghead.imBitmapH;
+ if(w > 256) w = 256;
+ if(h > 192) h = 192;
+
+ flag = readBMP(&SbmpInfo, 0, 0, w, h, (void*)buff);
+ if(0 == flag)
+ {
+ ds2_clearScreen(UP_SCREEN, 0);
+
+ dst= (unsigned short*)up_screen_addr + (192-h)/2*256 +(256-w)/2;
+ dst0 = dst;
+ if(2 == type) {
+ unsigned short* pt;
+
+ pt = (unsigned short*) buff;
+ for(y= 0; y<h; y++) {
+ for(x= 0; x < w; x++) {
+ *dst++ = RGB16_15(pt);
+ pt += 1;
+ }
+ dst0 += 256;
+ dst = dst0;
+ }
+ }
+ else {
+ unsigned char* pt;
+
+ pt= (char*)buff;
+ for(y= 0; y< h; y++) {
+ for(x= 0; x < w; x++) {
+ *dst++ = RGB24_15(pt);
+ pt += 3;
+ }
+ dst0 += 256;
+ dst = dst0;
+ }
+ }
+
+ ds2_flipScreen(UP_SCREEN, 1);
+ }
+
+ closeBMP(&SbmpInfo);
+ }
+ else
+ closeBMP(&SbmpInfo);
+ }
+
+ if(i+1 < file_num) i++;
+ else i= 0;
+
+ gui_action_type gui_action;
+ u32 ticks= 0;
+ u32 time1;
+
+ time1= time0;
+ while(ticks < time1)
+ {
+ gui_action = get_gui_input();
+
+ switch(gui_action)
+ {
+ case CURSOR_UP:
+ if(!pause)
+ {
+ if(time0 > 1) time0 -= 1;
+ time1= time0;
+ }
+ break;
+
+ case CURSOR_DOWN:
+ if(!pause)
+ {
+ time0 += 1;
+ time1= time0;
+ }
+ break;
+
+ case CURSOR_LEFT:
+ time1 = ticks;
+ if(i > 1) i -= 2;
+ else if(i == 1) i= file_num -1;
+ else i= file_num -2;
+ break;
+
+ case CURSOR_RIGHT:
+ time1 = ticks;
+ break;
+
+ case CURSOR_SELECT:
+ if(!pause)
+ {
+ time1 = -1;
+ pause= 1;
+ }
+ else
+ {
+ time1 = ticks;
+ pause= 0;
+ }
+ break;
+
+ case CURSOR_BACK:
+ if(screenp) free((void*)screenp);
+ //deconstruct filelist_info struct
+ manage_filelist_info(&filelist_info, -1);
+ repeat = 0;
+ break;
+
+ default: gui_action= CURSOR_NONE;
+ break;
+ }
+
+ if(gui_action != CURSOR_BACK)
+ mdelay(100);
+ if(!pause)
+ ticks ++;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+* Function: search directory on directory_path
+* directory: directory name will be searched
+* directory_path: path, note that the buffer which hold directory_path should
+* be large enough for nested
+* return: 0= found, directory lay on directory_path
+*/
+int search_dir(char *directory, char* directory_path)
+{
+ DIR *current_dir;
+ dirent *current_file;
+ struct stat st;
+ int directory_path_len;
+
+ current_dir= opendir(directory_path);
+ if(current_dir == NULL)
+ return -1;
+
+ directory_path_len = strlen(directory_path);
+
+ //while((current_file = readdir(current_dir)) != NULL)
+ while((current_file = readdir_ex(current_dir, &st)) != NULL)
+ {
+ //Is directory
+ if(S_ISDIR(st.st_mode))
+ {
+ if(strcmp(".", current_file->d_name) || strcmp("..", current_file->d_name))
+ continue;
+
+ strcpy(directory_path+directory_path_len, current_file->d_name);
+
+ if(!strcasecmp(current_file->d_name, directory))
+ {//dirctory find
+ closedir(current_dir);
+ return 0;
+ }
+
+ if(search_dir(directory, directory_path) == 0)
+ {//dirctory find
+ closedir(current_dir);
+ return 0;
+ }
+
+ directory_path[directory_path_len] = '\0';
+ }
+ }
+
+ closedir(current_dir);
+ return -1;
+}
+
+
+const u32 gamepad_config_map_init[MAX_GAMEPAD_MAP] =
+{
+ BUTTON_ID_A, /* 0 A */
+ BUTTON_ID_B, /* 1 B */
+ BUTTON_ID_SELECT, /* 2 [SELECT] */
+ BUTTON_ID_START, /* 3 [START] */
+ BUTTON_ID_RIGHT, /* 4 → */
+ BUTTON_ID_LEFT, /* 5 ↠*/
+ BUTTON_ID_UP, /* 6 ↑ */
+ BUTTON_ID_DOWN, /* 7 ↓ */
+ BUTTON_ID_R, /* 8 [R] */
+ BUTTON_ID_L, /* 9 [L] */
+ BUTTON_ID_NONE, /* 10 FA */
+ BUTTON_ID_NONE, /* 11 FB */
+ BUTTON_ID_TOUCH, /* 12 MENU */
+ BUTTON_ID_NONE, /* 13 NONE */
+ BUTTON_ID_NONE, /* 14 NONE */
+ BUTTON_ID_NONE /* 15 NONE */
+};
+
+u32 gamepad_config_map[MAX_GAMEPAD_MAP];
+
+#define BUTTON_MAP_A gamepad_config_map[0]
+#define BUTTON_MAP_B gamepad_config_map[1]
+#define BUTTON_MAP_FA gamepad_config_map[10]
+#define BUTTON_MAP_FB gamepad_config_map[11]
+#define BUTTON_MAP_MENU gamepad_config_map[12]
+
+int load_state(char* file)
+{
+ int flag;
+ FILE* fp;
+ unsigned int n;
+ char tmp_path[MAX_PATH];
+
+ sprintf(tmp_path, "%s/%s", DEFAULT_RTS_DIR, file);
+
+ flag = game_load_state(tmp_path);
+ if(0 != flag)
+ return -1;
+
+ fp = fopen(tmp_path, "r");
+ if(NULL == fp)
+ return -1;
+
+ n = 0;
+ if(fread((void*)&n, 1, 4, fp) < 4)
+ {
+ fclose(fp);
+ return -1;
+ }
+
+ fseek(fp, n+sizeof(struct rtc), SEEK_SET);
+ fread(up_screen_addr, 1, 256*192*2, fp);
+ fclose(fp);
+
+ ds2_flipScreen(UP_SCREEN, 1);
+
+ return 0;
+}
+
+int load_game_stat_snapshot(char* file)
+{
+ FILE* fp;
+ char tmp_path[MAX_PATH];
+ unsigned int n, m;
+
+ sprintf(tmp_path, "%s/%s", DEFAULT_RTS_DIR, file);
+ fp = fopen(tmp_path, "r");
+ if(NULL == fp)
+ return -1;
+
+ m = fread((void*)&n, 1, 4, fp);
+ if(m < 4)
+ {
+ fclose(fp);
+ return - 2;
+ }
+
+ fseek(fp, n+sizeof(struct rtc), SEEK_SET);
+
+ m = fread(up_screen_addr, 1, 256*192*2, fp);
+ if(m < 256*192*2)
+ {
+ fclose(fp);
+ return -4;
+ }
+
+ fclose(fp);
+ ds2_flipScreen(UP_SCREEN, 1);
+ return 0;
+}
+
+#if 0
+int bak_file(char* file)
+{
+ FILE *fp1, *fp2;
+ char tmp_path[MAX_PATH];
+ char buff[512];
+ int m;
+
+ fp1= fopen(file, "r");
+ if(NULL == fp1)
+ return -1;
+
+ strcpy(tmp_path, file);
+ strcat(tmp_path, ".bak");
+ fp2 = fopen(tmp_path, "w");
+ if(NULL == fp2)
+ {
+ fclose(fp1);
+ return -2;
+ }
+
+ while(1)
+ {
+ m= fread(buff, 1, 512, fp1);
+ if(m <= 0) break;
+ fwrite(buff, 1, m, fp2);
+ }
+
+ fclose(fp1);
+ fclose(fp2);
+ return 0;
+}
+#endif
+
+int save_state(char* file, void* screen)
+{
+ int flag;
+ FILE *fp;
+ unsigned int n;
+ struct rtc time;
+ char str[64];
+ char tmp_path[MAX_PATH];
+
+ sprintf(tmp_path, "%s/%s", DEFAULT_RTS_DIR, file);
+
+ flag = game_save_state(tmp_path);
+ if(0 != flag)
+ return -1;
+
+ fp = fopen(tmp_path, "r+");
+ if(NULL == fp)
+ return -1;
+
+ fseek(fp, 0, SEEK_END);
+ n = ftell(fp);
+
+ ds2_getTime(&time);
+ sprintf(str, "%02d-%02d %02d:%02d:%02d",
+ time.month, time.day, time.hours, time.minutes, time.seconds);
+
+ PRINT_STRING_BG(screen, str, COLOR_WHITE, COLOR_BLACK, 0, 0);
+ fwrite((void*)&time, 1, sizeof(struct rtc), fp);
+ fwrite(screen, 1, 256*192*2, fp);
+
+ fseek(fp, 0, SEEK_SET);
+ fwrite((void*)&n, 1, 4, fp);
+
+ fclose(fp);
+
+ return 0;
+}
+
+void set_cpu_clock(u32 num)
+{
+ u32 clock_speed_table[6] = {6, 9, 10, 11, 12, 13}; //240, 300, 336, 360, 384, 394
+
+ if(num <= 5)
+ ds2_setCPUclocklevel(clock_speed_table[num]);
+}
+
+void savefast_int(void)
+{
+
+}
+
+#if 1
+void dump_mem(unsigned char* addr, unsigned int len)
+{
+ unsigned int i;
+
+ for(i= 0; i < len; i++)
+ {
+ cprintf("%02x ", addr[i]);
+ if((i+1)%16 == 0) cprintf("\n");
+ }
+}
+#endif
+
+unsigned int frame_interval;
+
+/*--------------------------------------------------------
+ Main Menu
+--------------------------------------------------------*/
+u32 menu(u16 *screen)
+{
+ mdelay(50);
+ gui_action_type gui_action;
+ u32 i;
+ u32 repeat;
+ u32 return_value = 0;
+ u32 first_load = 0;
+ char tmp_filename[MAX_FILE];
+ char line_buffer[512];
+ char cheat_format_str[MAX_CHEATS][41*4];
+ char *cheat_format_ptr[MAX_CHEATS];
+
+ MENU_TYPE *current_menu;
+ MENU_OPTION_TYPE *current_option;
+ MENU_OPTION_TYPE *display_option;
+
+ u32 current_option_num;
+// u32 parent_option_num;
+ u32 string_select;
+
+ u16 *bg_screenp;
+ u32 bg_screenp_color;
+
+ auto void choose_menu();
+ auto void menu_return();
+ auto void menu_exit();
+ auto void menu_load();
+ auto void menu_restart();
+ auto void menu_save_state();
+ auto void menu_load_state();
+ auto void menu_load_cheat_file();
+ auto void others_menu_init();
+ auto void keyremap_show();
+ auto void main_menu_passive();
+ auto void main_menu_key();
+ auto void delette_savestate();
+ auto void save_screen_snapshot();
+ auto void browse_screen_snapshot();
+ auto void keyremap();
+ auto void time_backward_action();
+ auto void time_period_passive();
+ auto void time_period_action();
+ auto void tools_menu_init();
+ auto void load_default_setting();
+ auto void check_gbaemu_version();
+ auto void load_lastest_played();
+ auto void latest_game_menu_passive();
+ auto void latest_game_menu_init();
+ auto void latest_game_menu_key();
+ auto void latest_game_menu_end();
+ auto void language_set();
+ auto void game_fastforward();
+ auto void show_card_space();
+ auto void savestate_selitem(u32 sel, u32 y_pos);
+ auto void game_state_menu_passive();
+ auto void gamestate_delette_menu_passive();
+ auto void cheat_menu_init();
+ auto void cheat_menu_end();
+ auto void reload_cheats_page();
+ auto void cheat_option_action();
+ auto void cheat_option_passive();
+ auto void dynamic_cheat_menu_end();
+
+//Local function definition
+
+ void menu_exit()
+ {
+ if(gamepak_name[0] != 0)
+ {
+ game_config.clock_speed_number = clock_speed_number;
+
+ reorder_latest_file();
+ //S9xAutoSaveSRAM ();
+ save_game_config_file();
+ }
+ save_emu_config_file();
+ quit();
+ }
+
+ void menu_load()
+ {
+ char *file_ext[] = { ".smc", ".sfc", ".zip", NULL };
+
+ if(gamepak_name[0] != 0)
+ {
+ //S9xAutoSaveSRAM ();
+ save_game_config_file();
+ }
+
+ if(load_file(file_ext, tmp_filename, g_default_rom_dir) != -1)
+ {
+ strcpy(line_buffer, g_default_rom_dir);
+ strcat(line_buffer, "/");
+ strcat(line_buffer, tmp_filename);
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ if(load_gamepak(line_buffer) == -1)
+ {
+ first_load = 1;
+ gamepak_name[0] = '\0';
+ return;
+ }
+
+ strcpy(gamepak_name, tmp_filename);
+ first_load = 0;
+ load_game_config_file();
+// time_period_action();
+
+ return_value = 1;
+ repeat = 0;
+
+ reorder_latest_file();
+ get_savestate_filelist();
+
+ game_fast_forward= 0;
+ }
+ else
+ {
+ choose_menu(current_menu);
+ }
+ }
+
+ bool Get_Args(char *file, char **filebuf)
+ {
+ FILE* dat = fat_fopen(file, "rb");
+ if(dat)
+ {
+ int i = 0;
+ while(!fat_feof (dat))
+ {
+ fat_fgets(filebuf[i], 512, dat);
+ int len = strlen(filebuf[i]);
+ if(filebuf[i][len - 1] == '\n')
+ filebuf[i][len - 1] = '\0';
+ i++;
+ }
+
+ fat_fclose(dat);
+ fat_remove(file);
+ return i;
+ }
+ return 0;
+ }
+
+ int CheckLoad_Arg()
+ {
+ char args[2][512];
+ char *argarray[2];
+
+ argarray[0] = args[0];
+ argarray[1] = args[1];
+
+ if(!Get_Args("/plgargs.dat", argarray))
+ return 0;
+
+ fat_remove("plgargs.dat");
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ if(load_gamepak(args[1]) == -1)
+ {
+ first_load = 1;
+ gamepak_name[0] = '\0';
+ return 0;
+ }
+
+ strcpy(gamepak_name, args[1]);
+ first_load = 0;
+ load_game_config_file();
+
+ return_value = 1;
+ repeat = 0;
+
+ reorder_latest_file();
+ get_savestate_filelist();
+
+ game_fast_forward= 0;
+ return 1;
+
+ }
+
+ void menu_restart()
+ {
+ if(!first_load)
+ {
+ game_restart();
+ return_value = 1;
+ repeat = 0;
+ }
+ }
+
+ void menu_return()
+ {
+ if(!first_load)
+ repeat = 0;
+ }
+
+ void clear_savestate_slot(u32 slot_index)
+ {
+ get_savestate_filename(slot_index, tmp_filename);
+ sprintf(line_buffer, "%s/%s", DEFAULT_RTS_DIR, tmp_filename);
+ remove(line_buffer);
+ if(savestate_map[slot_index] > 0)
+ savestate_map[slot_index]= -savestate_map[slot_index];
+ reorder_savestate_slot();
+ }
+
+ void savestate_selitem(u32 selected, u32 y_pos)
+ {
+ u32 k;
+
+ for(k= 0; k < 10; k++) //Only display 10 slot
+ {
+ if(selected != k)
+ {
+ if(savestate_map[k] > 0) //full
+ show_icon((unsigned short*)down_screen_addr, ICON_NSTATEFULL, 28+k*21, y_pos);
+ else
+ show_icon((unsigned short*)down_screen_addr, ICON_NSTATEEMPTY, 28+k*21, y_pos);
+ }
+ else //Highlight
+ {
+ if(savestate_map[k] > 0) //full
+ show_icon((unsigned short*)down_screen_addr, ICON_STATEFULL, 28+k*21, y_pos);
+ else
+ show_icon((unsigned short*)down_screen_addr, ICON_STATEEMPTY, 28+k*21, y_pos);
+ }
+ }
+ }
+
+ void game_state_menu_passive()
+ {
+ unsigned short color;
+ unsigned int line[3] = {0, 1, 3};
+
+ //draw background
+ show_icon(down_screen_addr, ICON_SUBBG, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ if(current_option_num == 0)
+ show_icon(down_screen_addr, ICON_BACK, 229, 10);
+ else
+ show_icon(down_screen_addr, ICON_NBACK, 229, 10);
+
+ strcpy(line_buffer, *(display_option->display_string));
+ draw_string_vcenter(down_screen_addr, 0, 9, 256, COLOR_ACTIVE_ITEM, line_buffer);
+
+ display_option += 1;
+ for(i= 0; i < 3; i++, display_option++)
+ {
+ unsigned short color;
+
+ if(display_option == current_option)
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + line[i]*27);
+
+ if(display_option->option_type & NUMBER_SELECTION_TYPE)
+ {
+ sprintf(line_buffer, *(display_option->display_string),
+ *(display_option->current_option)+1); //ADD 1 here
+ }
+ else if(display_option->option_type & STRING_SELECTION_TYPE)
+ {
+ sprintf(line_buffer, *(display_option->display_string),
+ *((u32*)(((u32 *)display_option->options)[*(display_option->current_option)])));
+ }
+ else
+ {
+ strcpy(line_buffer, *(display_option->display_string));
+ }
+
+ if(display_option == current_option)
+ color= COLOR_ACTIVE_ITEM;
+ else
+ color= COLOR_INACTIVE_ITEM;
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + line[i]*27);
+ }
+
+ int slot_index;
+ unsigned int selected;
+
+ selected = -1;
+ //write save
+ slot_index= get_savestate_slot();
+
+ sprintf(line_buffer, "%d", (slot_index+2) > SAVE_STATE_SLOT_NUM ? SAVE_STATE_SLOT_NUM : (slot_index+2));
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 146, 40 + 0*27);
+ if(current_option_num == 1)
+ selected = slot_index+1;
+
+ //Read save
+ if(current_option_num == 2)
+ selected = savestate_index;
+
+ savestate_selitem(selected, 93);
+ }
+
+ u32 delette_savestate_num= 0;
+ void gamestate_delette_menu_passive()
+ {
+ unsigned short color;
+ unsigned int line[2] = {0, 1};
+
+ //draw background
+ show_icon(down_screen_addr, ICON_SUBBG, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ if(current_option_num == 0)
+ show_icon(down_screen_addr, ICON_BACK, 229, 6);
+ else
+ show_icon(down_screen_addr, ICON_NBACK, 229, 6);
+
+ strcpy(line_buffer, *(display_option->display_string));
+ draw_string_vcenter(down_screen_addr, 0, 9, 256, COLOR_ACTIVE_ITEM, line_buffer);
+
+ display_option += 1;
+ for(i= 0; i < 2; i++, display_option++)
+ {
+ unsigned short color;
+
+ if(display_option == current_option)
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + line[i]*27);
+
+ if(display_option->option_type & NUMBER_SELECTION_TYPE)
+ {
+ sprintf(line_buffer, *(display_option->display_string),
+ *(display_option->current_option)+1);
+ }
+ else if(display_option->option_type & STRING_SELECTION_TYPE)
+ {
+ sprintf(line_buffer, *(display_option->display_string),
+ *((u32*)(((u32 *)display_option->options)[*(display_option->current_option)])));
+ }
+ else
+ {
+ strcpy(line_buffer, *(display_option->display_string));
+ }
+
+ if(display_option == current_option)
+ color= COLOR_ACTIVE_ITEM;
+ else
+ color= COLOR_INACTIVE_ITEM;
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + line[i]*27);
+ }
+
+ if(current_option_num == 2)
+ savestate_selitem(delette_savestate_num, 93);
+ else
+ savestate_selitem(-1, 93);
+ }
+
+ void menu_save_state()
+ {
+ if(gui_action == CURSOR_SELECT)
+ {
+ //The slot is empty
+ if(!first_load)
+ {
+ u32 key;
+ s32 slot_index;
+
+ slot_index= get_savestate_slot();
+ //the slot already have a savestate file
+ if(slot_index >= 9)
+ {
+ draw_message(down_screen_addr, NULL, 28, 31, 227, 165, 0);
+ draw_string_vcenter(down_screen_addr, 36, 74, 190, COLOR_MSSG, msg[MSG_SAVESTATE_FULL]);
+ if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(B)") == 0)
+ return;
+
+ clear_savestate_slot(0);
+ }
+ else
+ slot_index += 1;
+
+ savestate_map[slot_index]= -savestate_map[slot_index];
+ get_savestate_filename(slot_index, tmp_filename);
+
+ draw_message(down_screen_addr, NULL, 28, 31, 227, 165, 0);
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_SAVESTATE_DOING]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ int flag = save_state(tmp_filename, (void*)screen);
+ //clear message
+ draw_message(down_screen_addr, NULL, 28, 31, 227, 96, 0);
+ if(flag < 0)
+ {
+ draw_string_vcenter(down_screen_addr, 36, 74, 190, COLOR_MSSG, msg[MSG_SAVESTATE_FAILUER]);
+ savestate_map[slot_index]= -savestate_map[slot_index];
+ }
+ else
+ {
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_SAVESTATE_SUCCESS]);
+ savestate_index = slot_index;
+ }
+
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ //save game config
+ reorder_latest_file();
+ save_game_config_file();
+
+ mdelay(500);
+ }
+ }
+ }
+
+ void menu_load_state()
+ {
+ if(!first_load)
+ {
+ FILE *fp= NULL;
+
+ if(bg_screenp != NULL)
+ {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ memcpy(bg_screenp, down_screen_addr, 256*192*2);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ //Slot not emtpy
+ if(savestate_map[savestate_index] > 0)
+ {
+ get_savestate_filename(savestate_index, tmp_filename);
+ sprintf(line_buffer, "%s/%s", DEFAULT_RTS_DIR, tmp_filename);
+ fp= fopen(line_buffer, "r");
+
+ //file error
+ if(fp == NULL)
+ {
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_SAVESTATE_FILE_BAD]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ wait_Allkey_release(0);
+ if(gui_action == CURSOR_SELECT)
+ wait_Anykey_press(0);
+ else
+ mdelay(1000);
+ return;
+ }
+
+ fclose(fp);
+ //right
+ if(gui_action == CURSOR_SELECT)
+ {
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(up_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_LOADSTATE_DOING]);
+
+ int flag = load_state(tmp_filename);
+ if(0 == flag)
+ {
+ return_value = 1;
+ repeat = 0;
+ draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_LOADSTATE_SUCCESS]);
+ }
+ else
+ draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_LOADSTATE_FAILURE]);
+ }
+ else //load screen snapshot
+ {
+ load_game_stat_snapshot(tmp_filename);
+ }
+ }
+ else
+ {
+ ds2_clearScreen(UP_SCREEN, COLOR_BLACK);
+ draw_string_vcenter(up_screen_addr, 36, 75, 190, COLOR_WHITE, msg[MSG_SAVESTATE_SLOT_EMPTY]);
+ ds2_flipScreen(UP_SCREEN, 1);
+ }
+ }
+ }
+
+ void delette_savestate()
+ {
+ if(!first_load && (gui_action == CURSOR_SELECT))
+ {
+ if(bg_screenp != NULL)
+ {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ memcpy(bg_screenp, down_screen_addr, 256*192*2);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ wait_Allkey_release(0);
+ if(current_option_num == 1) //delette all
+ {
+ u32 i, flag;
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_DELETTE_ALL_SAVESTATE_WARING]);
+
+ flag= 0;
+ for(i= 0; i < SAVE_STATE_SLOT_NUM; i++)
+ if(savestate_map[i] > 0)
+ {flag= 1; break;}
+
+ if(flag)
+ {
+ if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(B)"))
+ {
+ for(i= 0; i < SAVE_STATE_SLOT_NUM; i++)
+ {
+ get_savestate_filename(i, tmp_filename);
+ sprintf(line_buffer, "%s/%s", DEFAULT_RTS_DIR, tmp_filename);
+ remove(line_buffer);
+ if(savestate_map[i] > 0)
+ savestate_map[i]= -savestate_map[i];
+ }
+ savestate_index= 0;
+ }
+ }
+ else
+ {
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_DELETTE_SAVESTATE_NOTHING]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+ mdelay(500);
+ }
+ }
+ else if(current_option_num == 2) //delette single
+ {
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+
+ if(savestate_map[delette_savestate_num] > 0)
+ {
+ sprintf(line_buffer, msg[MSG_DELETTE_SINGLE_SAVESTATE_WARING], delette_savestate_num);
+ draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, line_buffer);
+
+ if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes(A)", "No(B)"))
+ clear_savestate_slot(delette_savestate_num);
+ }
+ else
+ {
+ draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_DELETTE_SAVESTATE_NOTHING]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+ mdelay(500);
+ }
+ }
+ }
+ }
+
+ MENU_TYPE cheats_menu;
+ MENU_TYPE *dynamic_cheat_menu = NULL;
+ MENU_OPTION_TYPE *dynamic_cheat_options = NULL;
+ unsigned char *dynamic_cheat_msg = NULL;
+ unsigned char **dynamic_cheat_pt = NULL;
+ unsigned int dynamic_cheat_active;
+ int dynamic_cheat_scroll_value= 0;
+ MSG_TABLE cheat_msg= {NULL, NULL};
+
+ void cheat_menu_init()
+ {
+ for(i = 0; i < MAX_CHEATS; i++)
+ {
+ if(i >= g_cheat_num)
+ {
+ sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_NON_LOAD], i);
+ }
+ else
+ {
+ sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_LOADED], i, game_config.cheats_flag[i].name_shot);
+ }
+
+ cheat_format_ptr[i]= cheat_format_str[i];
+ }
+
+ reload_cheats_page();
+ }
+
+ void cheat_menu_end()
+ {
+ if(!first_load)
+ gcheat_Managment(game_config.cheats_flag);
+ }
+
+ void dynamic_cheat_key()
+ {
+ unsigned int m, n;
+
+ switch(gui_action)
+ {
+ case CURSOR_DOWN:
+ if(current_menu->screen_focus > 0 && (current_option_num+1) < current_menu->num_options)
+ {
+ if(current_menu->screen_focus < SUBMENU_ROW_NUM)
+ {
+ m= current_menu->screen_focus -1;
+ draw_hscroll_over(m+1);
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
+ }
+ else
+ {
+ for(n= 0; n < SUBMENU_ROW_NUM; n++)
+ draw_hscroll_over(n+1);
+
+ m= current_menu->focus_option - current_menu->screen_focus+2;
+ for(n= 0; n < SUBMENU_ROW_NUM-1; n++)
+ draw_hscroll_init(down_screen_addr, 23, 40 + n*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[m+n].display_string);
+ }
+ }
+
+ if(current_option_num == 0)
+ {
+ draw_hscroll_over(0);
+ draw_hscroll_init(down_screen_addr, 50, 9, 180,
+ COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string);
+ }
+
+ current_option_num += 1;
+ if(current_option_num >= current_menu->num_options)
+ current_option_num -=1;
+ else
+ {
+ m= current_menu->screen_focus;
+ if(m >= SUBMENU_ROW_NUM) m -= 1;
+
+ draw_hscroll_over(m+1);
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
+ }
+
+ current_option = current_menu->options + current_option_num;
+ break;
+
+ case CURSOR_UP:
+ if(current_menu->screen_focus > 0)
+ {
+ if(current_menu->screen_focus > 1 || current_option_num < 2)
+ {
+ m = current_menu->screen_focus -1;
+ draw_hscroll_over(m+1);
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
+ }
+ else
+ {
+ unsigned int k;
+
+ for(n= 1; n < SUBMENU_ROW_NUM; n++)
+ draw_hscroll_over(n+1);
+
+ m = current_option_num -1;
+ k = current_menu->num_options - m -1;
+ if(k > SUBMENU_ROW_NUM) k = SUBMENU_ROW_NUM;
+
+ for(n= 1; n < k; n++)
+ draw_hscroll_init(down_screen_addr, 23, 40 + n*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[m+n].display_string);
+ }
+ }
+
+ if(current_option_num)
+ {
+ current_option_num--;
+
+ if(current_option_num == 0)
+ {
+ draw_hscroll_over(0);
+ draw_hscroll_init(down_screen_addr, 50, 9, 180,
+ COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string);
+ }
+ }
+
+ current_option = current_menu->options + current_option_num;
+
+ if(current_option_num > 0)
+ {
+ if(current_menu->screen_focus > 1)
+ m = current_menu->screen_focus -2;
+ else
+ m = current_menu->screen_focus -1;
+
+ draw_hscroll_over(m+1);
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
+ }
+ break;
+
+ case CURSOR_RIGHT:
+ dynamic_cheat_scroll_value= -5;
+ break;
+
+ case CURSOR_LEFT:
+ dynamic_cheat_scroll_value= 5;
+ break;
+ }
+ }
+
+ void dynamic_cheat_action()
+ {
+ dynamic_cheat_active &= 1;
+ dynamic_cheat_active |= (current_option_num -1) << 16;
+ }
+
+ void dynamic_cheat_menu_passive()
+ {
+ unsigned int m, n, k;
+ u32 line_num, screen_focus, focus_option;
+
+ line_num = current_option_num;
+ screen_focus = current_menu -> screen_focus;
+ focus_option = current_menu -> focus_option;
+
+ if(focus_option < line_num) //focus next option
+ {
+ focus_option = line_num - focus_option;
+ screen_focus += focus_option;
+ if(screen_focus > SUBMENU_ROW_NUM) //Reach max row numbers can display
+ screen_focus = SUBMENU_ROW_NUM;
+
+ current_menu -> screen_focus = screen_focus;
+ focus_option = line_num;
+ }
+ else if(focus_option > line_num) //focus last option
+ {
+ focus_option = focus_option - line_num;
+ if(screen_focus > focus_option)
+ screen_focus -= focus_option;
+ else
+ screen_focus = 0;
+
+ if(screen_focus == 0 && line_num > 0)
+ screen_focus = 1;
+
+ current_menu -> screen_focus = screen_focus;
+ focus_option = line_num;
+ }
+ current_menu -> focus_option = focus_option;
+
+ //draw background
+ show_icon(down_screen_addr, ICON_SUBBG, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ if(current_menu -> screen_focus > 0)
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + (current_menu -> screen_focus-1)*27);
+
+ if(current_menu->screen_focus == 0)
+ {
+ draw_hscroll(0, dynamic_cheat_scroll_value);
+ dynamic_cheat_scroll_value = 0;
+ show_icon(down_screen_addr, ICON_BACK, 229, 10);
+ }
+ else
+ {
+ draw_hscroll(0, 0);
+ show_icon(down_screen_addr, ICON_NBACK, 229, 10);
+ }
+
+ k = current_menu->num_options -1;
+ if(k > SUBMENU_ROW_NUM) k = SUBMENU_ROW_NUM;
+
+ m = (dynamic_cheat_active>>16) +1;
+ n = current_option_num - current_menu->screen_focus + 1;
+
+ for(i= 0; i < k; i++)
+ {
+ if((i+1) == current_menu->screen_focus)
+ {
+ draw_hscroll(i+1, dynamic_cheat_scroll_value);
+ dynamic_cheat_scroll_value = 0;
+ }
+ else
+ draw_hscroll(i+1, 0);
+
+ if(m == (n +i))
+ {
+ if(dynamic_cheat_active & 1)
+ show_icon((unsigned short*)down_screen_addr, ICON_STATEFULL, 230, 40 + i*27);
+ else
+ show_icon((unsigned short*)down_screen_addr, ICON_NSTATEFULL, 230, 40 + i*27);
+ }
+ else
+ {
+ if(dynamic_cheat_active & 1)
+ show_icon((unsigned short*)down_screen_addr, ICON_STATEEMPTY, 230, 40 + i*27);
+ else
+ show_icon((unsigned short*)down_screen_addr, ICON_NSTATEEMPTY, 230, 40 + i*27);
+ }
+ }
+ }
+
+ void cheat_option_action()
+ {
+ unsigned int nums;
+
+ nums = (CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1;
+ if(gui_action == CURSOR_SELECT && nums < g_cheat_num)
+ {
+ unsigned int m;
+
+ nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num;
+
+ if(dynamic_cheat_options)
+ {
+ free((void*)dynamic_cheat_options);
+ dynamic_cheat_options = NULL;
+ }
+
+ if(dynamic_cheat_menu)
+ {
+ free((void*)dynamic_cheat_menu);
+ dynamic_cheat_menu = NULL;
+ }
+
+ dynamic_cheat_options = (MENU_OPTION_TYPE*)malloc(sizeof(MENU_OPTION_TYPE)*(nums+1));
+ if(dynamic_cheat_options == NULL) return;
+
+ dynamic_cheat_menu = (MENU_TYPE*)malloc(sizeof(MENU_TYPE));
+ if(dynamic_cheat_menu == NULL)
+ {
+ free((void*)dynamic_cheat_options);
+ dynamic_cheat_options = NULL;
+ return;
+ }
+
+ //menu
+ dynamic_cheat_menu->init_function = NULL;
+ dynamic_cheat_menu->passive_function = dynamic_cheat_menu_passive;
+ dynamic_cheat_menu->key_function = dynamic_cheat_key;
+ dynamic_cheat_menu->end_function = dynamic_cheat_menu_end;
+ dynamic_cheat_menu->options = dynamic_cheat_options;
+ dynamic_cheat_menu->num_options = nums+1;
+ dynamic_cheat_menu->focus_option = 0;
+ dynamic_cheat_menu->screen_focus = 0;
+ //back option
+ dynamic_cheat_options[0].action_function = NULL;
+ dynamic_cheat_options[0].passive_function = NULL;
+ dynamic_cheat_options[0].sub_menu = &cheats_menu;
+ dynamic_cheat_options[0].display_string = (char**)(dynamic_cheat_pt + game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].name_id);
+ dynamic_cheat_options[0].options = NULL;
+ dynamic_cheat_options[0].current_option = NULL;
+ dynamic_cheat_options[0].num_options = 0;
+ dynamic_cheat_options[0].help_string = NULL;
+ dynamic_cheat_options[0].line_number = 0;
+ dynamic_cheat_options[0].option_type = SUBMENU_TYPE;
+
+ m = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_id;
+ for(i= 0; i < nums; i++)
+ {
+ dynamic_cheat_options[i+1].action_function = dynamic_cheat_action;
+ dynamic_cheat_options[i+1].passive_function = NULL;
+ dynamic_cheat_options[i+1].sub_menu = NULL;
+ dynamic_cheat_options[i+1].display_string = (char**)(dynamic_cheat_pt + S9xGetCheat_nameid(m, i, g_cheat_cell_num));
+ dynamic_cheat_options[i+1].options = NULL;
+ dynamic_cheat_options[i+1].current_option = NULL;
+ dynamic_cheat_options[i+1].num_options = 2;
+ dynamic_cheat_options[i+1].help_string = NULL;
+ dynamic_cheat_options[i+1].line_number = i+1;
+ dynamic_cheat_options[i+1].option_type = ACTION_TYPE;
+ }
+
+ dynamic_cheat_active = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) +
+ current_option_num -1].active & 0x1;
+ dynamic_cheat_active |= game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) +
+ current_option_num -1].sub_active << 16;
+
+ //Initial srollable options
+ int k;
+
+ draw_hscroll_init(down_screen_addr, 50, 9, 180, COLOR_TRANS,
+ COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string);
+
+ if(nums>5) nums = SUBMENU_ROW_NUM;
+ for(k= 0; k < nums; k++)
+ {
+ draw_hscroll_init(down_screen_addr, 23, 40 + k*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[k+1].display_string);
+ }
+ dynamic_cheat_scroll_value= 0;
+
+ choose_menu(dynamic_cheat_menu);
+ }
+ }
+
+ void cheat_option_passive()
+ {
+ unsigned short color;
+ unsigned char tmp_buf[512];
+ unsigned int len;
+ unsigned char *pt;
+
+ if(display_option == current_option)
+ color= COLOR_ACTIVE_ITEM;
+ else
+ color= COLOR_INACTIVE_ITEM;
+
+ //sprintf("%A") will have problem ?
+ strcpy(tmp_buf, *(display_option->display_string));
+ pt = strrchr(tmp_buf, ':');
+ if(pt != NULL)
+ sprintf(pt+1, "%s", *((u32*)(((u32 *)display_option->options)[*(display_option->current_option)])));
+
+ strcpy(line_buffer, tmp_buf);
+ pt = strrchr(line_buffer, ')');
+ *pt = '\0';
+ pt = strchr(line_buffer, '(');
+
+ len = BDF_cut_string(pt+1, 0, 2);
+ if(len > 90)
+ {
+ len = BDF_cut_string(pt+1, 90, 1);
+ *(pt+1+len) = '\0';
+ strcat(line_buffer, "...");
+ }
+
+ pt = strrchr(tmp_buf, ')');
+ strcat(line_buffer, pt);
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 40 + display_option-> line_number*27);
+ }
+
+ void dynamic_cheat_menu_end()
+ {
+ unsigned int m, k;
+
+ m = cheats_menu.focus_option-1;
+ game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + m].sub_active = dynamic_cheat_active >> 16;
+
+ k = SUBMENU_ROW_NUM +1;
+ for(m= 0; m<k; m++)
+ draw_hscroll_over(m);
+ }
+
+ void destroy_dynamic_cheats()
+ {
+ if(dynamic_cheat_menu) free((void*)dynamic_cheat_menu);
+ if(dynamic_cheat_options) free((void*)dynamic_cheat_options);
+ if(dynamic_cheat_msg) free((void*)dynamic_cheat_msg);
+ if(dynamic_cheat_pt) free((void*)dynamic_cheat_pt);
+ dynamic_cheat_menu = NULL;
+ dynamic_cheat_options = NULL;
+ dynamic_cheat_msg = NULL;
+ dynamic_cheat_pt = NULL;
+ }
+
+ void menu_load_cheat_file()
+ {
+ char *file_ext[] = { ".cht", NULL };
+ u32 i, string_num, string_len;
+ int flag;
+
+ if(load_file(file_ext, tmp_filename, DEFAULT_CHEAT_DIR) != -1)
+ {
+ if(NULL != cheat_msg.msg_index) free((void*)cheat_msg.msg_index);
+ if(NULL != cheat_msg.msg_pool) free((void*)cheat_msg.msg_pool);
+
+ sprintf(line_buffer, "%s/%s", DEFAULT_CHEAT_DIR, tmp_filename);
+
+ flag = load_cheatfile(line_buffer, &string_num, &string_len, game_config.cheats_flag);
+ if(0 != flag)
+ { //load cheat file failure
+ game_config.cheat_str_num = 0;
+ game_config.cheat_str_size = 0;
+ game_config.cheat_filename[0] = '\0';
+ g_cheat_num = 0;
+
+ cheat_menu_init();
+ return;
+ }
+
+ flag = load_cheatname(line_buffer, string_num, string_len, &cheat_msg);
+ if(0 != flag)
+ { //load cheat string information failure
+ game_config.cheat_str_num = 0;
+ game_config.cheat_str_size = 0;
+ game_config.cheat_filename[0] = '\0';
+ g_cheat_num = 0;
+
+ cheat_menu_init();
+ return;
+ }
+
+ game_config.cheat_str_num = string_num;
+ game_config.cheat_str_size = string_len;
+ strcpy(game_config.cheat_filename, line_buffer);
+
+ dynamic_cheat_msg = cheat_msg.msg_pool;
+ dynamic_cheat_pt = cheat_msg.msg_index;;
+ menu_cheat_page = 0;
+ cheat_menu_init();
+ }
+ }
+
+ void save_screen_snapshot()
+ {
+ if((gui_action == CURSOR_SELECT))
+ {
+ if(bg_screenp != NULL)
+ {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ memcpy(bg_screenp, down_screen_addr, 256*192*2);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ if(!first_load)
+ {
+ draw_string_vcenter(down_screen_addr, 36, 70, 190, COLOR_MSSG, msg[MSG_SAVE_SNAPSHOT]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+ if(save_ss_bmp(screen))
+ draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_SAVE_SNAPSHOT_COMPLETE]);
+ else
+ draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_SAVE_SNAPSHOT_FAILURE]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+ mdelay(500);
+ }
+ else
+ {
+ draw_string_vcenter(down_screen_addr, 36, 90, 190, COLOR_MSSG, msg[MSG_SAVESTATE_SLOT_EMPTY]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+ mdelay(500);
+ }
+ }
+ }
+
+ void browse_screen_snapshot()
+ {
+ if(current_option_num == 2)
+ play_screen_snapshot();
+ }
+
+ void keyremap()
+ {
+ if(gui_action== CURSOR_RIGHT || gui_action== CURSOR_LEFT)
+ {
+// if(current_option_num != 0)
+// game_config.use_default_gamepad_map = 0;
+ switch(current_option_num)
+ {
+ case 1: //GBA KEY A
+ if(BUTTON_MAP_A == BUTTON_ID_A)
+ BUTTON_MAP_A = BUTTON_ID_Y;
+ else if(BUTTON_MAP_A == BUTTON_ID_Y)
+ BUTTON_MAP_A = BUTTON_ID_A;
+
+ BUTTON_MAP_FA = BUTTON_ID_NONE;
+ BUTTON_MAP_FB = BUTTON_ID_NONE;
+ break;
+ case 2: //GBA KEY B(fixed B)
+ break;
+ case 3: //GBA KEY FA(fixed X)
+ if(BUTTON_MAP_FA == BUTTON_ID_NONE)
+ {
+ BUTTON_MAP_FA = BUTTON_ID_X;
+ }
+ else
+ BUTTON_MAP_FA = BUTTON_ID_NONE;
+
+ break;
+ case 4: //GBA KEY FB
+ if(BUTTON_MAP_A == BUTTON_ID_A)
+ {
+ if(BUTTON_MAP_FB == BUTTON_ID_Y)
+ BUTTON_MAP_FB = BUTTON_ID_NONE;
+ else
+ BUTTON_MAP_FB = BUTTON_ID_Y;
+ }
+ else if(BUTTON_MAP_A == BUTTON_ID_Y)
+ {
+ if(BUTTON_MAP_FB == BUTTON_ID_NONE)
+ BUTTON_MAP_FB = BUTTON_ID_A;
+ else
+ BUTTON_MAP_FB = BUTTON_ID_NONE;
+ }
+ break;
+ case 5: //Awaking menu
+ if(BUTTON_MAP_MENU == BUTTON_ID_X)
+ {
+ if(BUTTON_MAP_A != BUTTON_ID_Y && BUTTON_MAP_FB != BUTTON_ID_Y)
+ BUTTON_MAP_MENU = BUTTON_ID_Y;
+ else
+ BUTTON_MAP_MENU = BUTTON_ID_TOUCH;
+ }
+ else if(BUTTON_MAP_MENU == BUTTON_ID_TOUCH)
+ {
+ if(BUTTON_MAP_FA != BUTTON_ID_X)
+ BUTTON_MAP_MENU = BUTTON_ID_X;
+ else if(BUTTON_MAP_A != BUTTON_ID_Y && BUTTON_MAP_FB != BUTTON_ID_Y)
+ BUTTON_MAP_MENU = BUTTON_ID_Y;
+ }
+ else
+ BUTTON_MAP_MENU = BUTTON_ID_TOUCH;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(BUTTON_MAP_MENU == BUTTON_ID_X && BUTTON_MAP_FA == BUTTON_ID_X)
+ {
+ if(BUTTON_MAP_A == BUTTON_ID_Y || BUTTON_MAP_FB == BUTTON_ID_Y)
+ BUTTON_MAP_MENU = BUTTON_ID_TOUCH;
+ else
+ BUTTON_MAP_MENU = BUTTON_ID_Y;
+ }
+ else if(BUTTON_MAP_MENU == BUTTON_ID_Y)
+ {
+ if(BUTTON_MAP_A == BUTTON_ID_Y || BUTTON_MAP_FB == BUTTON_ID_Y)
+ {
+ if(BUTTON_MAP_FA == BUTTON_ID_X)
+ BUTTON_MAP_MENU = BUTTON_ID_TOUCH;
+ else
+ BUTTON_MAP_MENU = BUTTON_ID_X;
+ }
+ }
+
+// gamepad_config_menu = BUTTON_MAP_MENU;
+ }
+
+ void time_backward_action()
+ {
+ tools_menu_init();
+ if(game_config.backward)
+ savefast_int();
+ }
+
+ void time_period_passive()
+ {
+ char* str[] = {"0.2", "0.5", "1.0", "2.0", "5.0", "10 "};
+ unsigned int mm;
+ unsigned short color;
+
+ if(display_option == current_option)
+ color= COLOR_ACTIVE_ITEM;
+ else
+ color= COLOR_INACTIVE_ITEM;
+
+ mm = *(display_option->current_option);
+ sprintf(line_buffer, *(display_option->display_string), str[mm]);
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 27,
+ 38 + (display_option-> line_number)*32);
+ }
+
+ void time_period_action()
+ {
+ switch(game_config.backward_time)
+ {
+ case 0 : frame_interval = 15; break;
+ case 1 : frame_interval = 30; break;
+ case 2 : frame_interval = 60; break;
+ case 3 : frame_interval = 120; break;
+ case 4 : frame_interval = 300; break;
+ case 5 : frame_interval = 600; break;
+ default: frame_interval = 60; break;
+ }
+ }
+
+ void load_default_setting()
+ {
+ if(bg_screenp != NULL)
+ {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ memcpy(bg_screenp, down_screen_addr, 256*192*2);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 70, 190, COLOR_MSSG, msg[MSG_LOAD_DEFAULT_WARING]);
+
+ if(draw_yesno_dialog(DOWN_SCREEN, 115, "Yes", "No"))
+ {
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_DEFAULT_LOADING]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ sprintf(line_buffer, "%s/%s", main_path, EMU_CONFIG_FILENAME);
+ remove(line_buffer);
+
+ first_load= 1;
+ init_emulator_config();
+ init_game_config();
+
+ ds2_clearScreen(UP_SCREEN, 0);
+ draw_string_vcenter(up_screen_addr, 0, 80, 256, COLOR_WHITE, msg[MSG_NON_LOAD_GAME]);
+ ds2_flipScreen(UP_SCREEN, 1);
+
+ mdelay(500);
+ }
+ }
+
+ void check_gbaemu_version()
+ {
+ if(bg_screenp != NULL)
+ {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ memcpy(bg_screenp, down_screen_addr, 256*192*2);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 80, 190, COLOR_MSSG, msg[MSG_EMU_VERSION0]);
+ sprintf(line_buffer, "%s %s", msg[MSG_EMU_VERSION1], NDSSFC_VERSION);
+ draw_string_vcenter(down_screen_addr, 36, 95, 190, COLOR_MSSG, line_buffer);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ wait_Anykey_press(0);
+ }
+
+ void language_set()
+ {
+ if(gui_action == CURSOR_LEFT || gui_action == CURSOR_RIGHT)
+ {
+ if(bg_screenp != NULL)
+ {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ memcpy(bg_screenp, down_screen_addr, 256*192*2);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_CHANGE_LANGUAGE]);
+ draw_string_vcenter(down_screen_addr, 36, 95, 190, COLOR_MSSG, msg[MSG_CHANGE_LANGUAGE_WAITING]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ load_language_msg(LANGUAGE_PACK, emu_config.language);
+ gui_change_icon(emu_config.language);
+
+ if(first_load)
+ {
+ ds2_clearScreen(UP_SCREEN, 0);
+ draw_string_vcenter(up_screen_addr, 0, 80, 256, COLOR_WHITE, msg[MSG_NON_LOAD_GAME]);
+ ds2_flipScreen(UP_SCREEN, 1);
+ mdelay(10); //FIXME: Stranger?
+ }
+
+ save_emu_config_file();
+ mdelay(500);
+ }
+ }
+
+ unsigned int freespace;
+ void show_card_space ()
+ {
+ u32 line_num;
+ u32 num_byte;
+
+ strcpy(line_buffer, *(display_option->display_string));
+ line_num= display_option-> line_number;
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 27,
+ 40 + (display_option->line_number)*27);
+
+ num_byte = freespace;
+
+ if(num_byte <= 9999*2)
+ { /* < 9999KB */
+ sprintf(line_buffer, "%d", num_byte/2);
+ if(num_byte & 1)
+ strcat(line_buffer, ".5 KB");
+ else
+ strcat(line_buffer, ".0 KB");
+ }
+ else if(num_byte <= 9999*1024*2)
+ { /* < 9999MB */
+ num_byte /= 1024;
+ sprintf(line_buffer, "%d", num_byte/2);
+ if(num_byte & 1)
+ strcat(line_buffer, ".5 MB");
+ else
+ strcat(line_buffer, ".0 MB");
+ }
+ else
+ {
+ num_byte /= 1024*1024;
+ sprintf(line_buffer, "%d", num_byte/2);
+ if(num_byte & 1)
+ strcat(line_buffer, ".5 GB");
+ else
+ strcat(line_buffer, ".0 GB");
+ }
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 147,
+ 40 + (display_option->line_number)*27);
+ }
+
+ char *screen_ratio_options[] = { (char*)&msg[MSG_SCREEN_RATIO_0],
+ (char*)&msg[MSG_SCREEN_RATIO_1],
+ (char*)&msg[MSG_SCREEN_RATIO_2],
+ (char*)&msg[MSG_SCREEN_RATIO_3],
+ (char*)&msg[MSG_SCREEN_RATIO_4]};
+
+ char *frameskip_options[] = { (char*)&msg[MSG_FRAMESKIP_0], (char*)&msg[MSG_FRAMESKIP_1] };
+
+ char *on_off_options[] = { (char*)&msg[MSG_ON_OFF_0], (char*)&msg[MSG_ON_OFF_1] };
+
+// char *sound_seletion[] = { (char*)&msg[MSG_SOUND_SWITCH_0], (char*)&msg[MSG_SOUND_SWITCH_1] };
+
+// char *snap_frame_options[] = { (char*)&msg[MSG_SNAP_FRAME_0], (char*)&msg[MSG_SNAP_FRAME_1] };
+
+ char *enable_disable_options[] = { (char*)&msg[MSG_EN_DIS_ABLE_0], (char*)&msg[MSG_EN_DIS_ABLE_1] };
+
+ char *language_options[] = { (char*)&lang[1], (char*)&lang[0] };
+
+ char *keyremap_options[] = {(char*)&msg[MSG_KEY_MAP_NONE], (char*)&msg[MSG_KEY_MAP_A], (char*)&msg[MSG_KEY_MAP_B],
+ (char*)&msg[MSG_KEY_MAP_SL], (char*)&msg[MSG_KEY_MAP_ST], (char*)&msg[MSG_KEY_MAP_RT],
+ (char*)&msg[MSG_KEY_MAP_LF], (char*)&msg[MSG_KEY_MAP_UP], (char*)&msg[MSG_KEY_MAP_DW],
+ (char*)&msg[MSG_KEY_MAP_R], (char*)&msg[MSG_KEY_MAP_L], (char*)&msg[MSG_KEY_MAP_X],
+ (char*)&msg[MSG_KEY_MAP_Y], (char*)&msg[MSG_KEY_MAP_TOUCH]
+ };
+
+ /*--------------------------------------------------------
+ Video & Audio
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE graphics_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_0], NULL, 0),
+
+ /* 01 */ STRING_SELECTION_OPTION(NULL, NULL, &msg[MSG_SUB_MENU_00], screen_ratio_options,
+ &game_config.graphic, 5, NULL, PASSIVE_TYPE, 1),
+
+ /* 02 */ STRING_SELECTION_OPTION(game_fastforward, NULL, &msg[MSG_SUB_MENU_01], on_off_options,
+ &game_fast_forward, 2, NULL, ACTION_TYPE, 2),
+
+ /* 03 */ STRING_SELECTION_OPTION(game_disableAudio, NULL, &msg[MSG_SUB_MENU_04],on_off_options,
+ &game_enable_audio, 2, NULL, ACTION_TYPE, 3)
+ };
+
+ MAKE_MENU(graphics, NULL, NULL, NULL, NULL, 0, 0);
+
+ /*--------------------------------------------------------
+ Game state -- delette
+ --------------------------------------------------------*/
+ MENU_TYPE game_state_menu;
+
+ MENU_OPTION_TYPE gamestate_delette_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(&game_state_menu, &msg[MSG_SUB_MENU_13], NULL, 0),
+
+ /* 01 */ ACTION_OPTION(delette_savestate, NULL, &msg[MSG_SUB_MENU_130], NULL, 1),
+
+ /* 02 */ NUMERIC_SELECTION_ACTION_OPTION(delette_savestate, NULL,
+ &msg[MSG_SUB_MENU_131], &delette_savestate_num, 10, NULL, 2)
+ };
+
+ MAKE_MENU(gamestate_delette, NULL, gamestate_delette_menu_passive, NULL, NULL, 0, 0);
+
+ /*--------------------------------------------------------
+ Game state
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE game_state_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_1], NULL, 0),
+
+ /* 01 */ ACTION_OPTION(menu_save_state, NULL, &msg[MSG_SUB_MENU_10], NULL, 1),
+
+ /* 02 */ NUMERIC_SELECTION_ACTION_OPTION(menu_load_state, NULL,
+ &msg[MSG_SUB_MENU_11], &savestate_index, 10, NULL, 2),
+
+ /* 03 */ SUBMENU_OPTION(&gamestate_delette_menu, &msg[MSG_SUB_MENU_13], NULL, 5),
+ };
+
+ INIT_MENU(game_state, NULL, game_state_menu_passive, NULL, NULL, 0, 0);
+
+ /*--------------------------------------------------------
+ Cheat options
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE cheats_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_2], NULL,0),
+
+ /* 01 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
+ ((CHEATS_PER_PAGE * menu_cheat_page) + 0), 1),
+ /* 02 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
+ ((CHEATS_PER_PAGE * menu_cheat_page) + 1), 2),
+ /* 03 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
+ ((CHEATS_PER_PAGE * menu_cheat_page) + 2), 3),
+ /* 04 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
+ ((CHEATS_PER_PAGE * menu_cheat_page) + 3), 4),
+
+ /* 05 */ NUMERIC_SELECTION_ACTION_OPTION(reload_cheats_page, NULL, &msg[MSG_SUB_MENU_20],
+ &menu_cheat_page, MAX_CHEATS_PAGE, NULL, 5),
+
+ /* 06 */ ACTION_OPTION(menu_load_cheat_file, NULL, &msg[MSG_SUB_MENU_21],
+ NULL, 6)
+ };
+
+ INIT_MENU(cheats, cheat_menu_init, NULL, NULL, cheat_menu_end, 0, 0);
+
+ /*--------------------------------------------------------
+ Tools-screensanp
+ --------------------------------------------------------*/
+ MENU_TYPE tools_menu;
+
+ MENU_OPTION_TYPE tools_screensnap_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(&tools_menu, &msg[MSG_SUB_MENU_30], NULL, 0),
+
+ /* 01 */ ACTION_OPTION(save_screen_snapshot, NULL, &msg[MSG_SUB_MENU_300], NULL, 1),
+
+ /* 02 */ ACTION_OPTION(browse_screen_snapshot, NULL, &msg[MSG_SUB_MENU_301], NULL, 2)
+ };
+
+ MAKE_MENU(tools_screensnap, NULL, NULL, NULL, NULL, 0, 0);
+
+ /*--------------------------------------------------------
+ Tools-keyremap
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE tools_keyremap_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(&tools_menu, &msg[MSG_SUB_MENU_31], NULL, 0),
+
+ /* 01 */ STRING_SELECTION_OPTION(keyremap, keyremap_show, &msg[MSG_SUB_MENU_310],
+ NULL, &string_select, 2, NULL, ACTION_TYPE, 1),
+
+ /* 02 */ STRING_SELECTION_OPTION(keyremap, keyremap_show, &msg[MSG_SUB_MENU_311],
+ NULL, &string_select, 1, NULL, ACTION_TYPE | HIDEN_TYPE, 2),
+
+ /* 03 */ STRING_SELECTION_OPTION(keyremap, keyremap_show, &msg[MSG_SUB_MENU_312],
+ NULL, &string_select, 2, NULL, ACTION_TYPE, 3),
+
+ /* 04 */ STRING_SELECTION_OPTION(keyremap, keyremap_show, &msg[MSG_SUB_MENU_313],
+ NULL, &string_select, 3, NULL, ACTION_TYPE, 4),
+
+ /* 05 */ STRING_SELECTION_OPTION(keyremap, keyremap_show, &msg[MSG_SUB_MENU_314],
+ NULL, &string_select, 3, NULL, ACTION_TYPE, 5)
+ };
+
+ MAKE_MENU(tools_keyremap, NULL, NULL, NULL, NULL, 0, 0);
+ /*--------------------------------------------------------
+ Tools
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE tools_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_3], NULL, 0),
+
+ /* 01 */ SUBMENU_OPTION(&tools_screensnap_menu, &msg[MSG_SUB_MENU_30], NULL, 1),
+
+// /* 02 */ SUBMENU_OPTION(&tools_keyremap_menu, &msg[MSG_SUB_MENU_31], NULL, 2),
+
+// /* 03 */ STRING_SELECTION_OPTION(time_backward_action, NULL, &msg[MSG_SUB_MENU_302], enable_disable_options,
+// &game_config.backward, 2, NULL, ACTION_TYPE, 3),
+
+// /* 04 */ NUMERIC_SELECTION_ACTION_OPTION(time_period_action, time_period_passive, &msg[MSG_SUB_MENU_32],
+// &game_config.backward_time, 6, NULL, 4)
+ };
+
+ INIT_MENU(tools, tools_menu_init, NULL, NULL, NULL, 0, 0);
+
+ /*--------------------------------------------------------
+ Others
+ --------------------------------------------------------*/
+ u32 desert= 0;
+ MENU_OPTION_TYPE others_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_4], NULL, 0),
+
+ //CPU speed
+ /* 01 */ NUMERIC_SELECTION_OPTION(NULL, &msg[MSG_SUB_MENU_42], &clock_speed_number, 6, NULL, 1),
+
+ /* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[MSG_SUB_MENU_41], language_options,
+ &emu_config.language, 2, NULL, ACTION_TYPE, 2),
+
+ /* 03 */ STRING_SELECTION_OPTION(NULL, show_card_space, &msg[MSG_SUB_MENU_43], NULL,
+ &desert, 2, NULL, PASSIVE_TYPE | HIDEN_TYPE, 3),
+
+ /* 04 */ ACTION_OPTION(load_default_setting, NULL, &msg[MSG_SUB_MENU_44], NULL, 4),
+
+ /* 05 */ ACTION_OPTION(check_gbaemu_version, NULL, &msg[MSG_SUB_MENU_45], NULL, 5),
+ };
+
+ MAKE_MENU(others, others_menu_init, NULL, NULL, NULL, 1, 1);
+
+ /*--------------------------------------------------------
+ Load_game
+ --------------------------------------------------------*/
+ MENU_TYPE latest_game_menu;
+
+ MENU_OPTION_TYPE load_game_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_SUB_MENU_62], NULL, 0),
+
+ /* 01 */ ACTION_OPTION(menu_load, NULL, &msg[MSG_SUB_MENU_61], NULL, 1),
+
+ /* 02 */ SUBMENU_OPTION(&latest_game_menu, &msg[MSG_SUB_MENU_60], NULL, 2)
+ };
+
+ MAKE_MENU(load_game, NULL, NULL, NULL, NULL, 1, 1);
+
+ /*--------------------------------------------------------
+ Latest game
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE latest_game_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(&load_game_menu, &msg[MSG_SUB_MENU_60], NULL, 0),
+
+ /* 01 */ ACTION_OPTION(load_lastest_played, NULL, NULL, NULL, 1),
+
+ /* 02 */ ACTION_OPTION(load_lastest_played, NULL, NULL, NULL, 2),
+
+ /* 03 */ ACTION_OPTION(load_lastest_played, NULL, NULL, NULL, 3),
+
+ /* 04 */ ACTION_OPTION(load_lastest_played, NULL, NULL, NULL, 4),
+
+ /* 05 */ ACTION_OPTION(load_lastest_played, NULL, NULL, NULL, 5)
+ };
+
+ INIT_MENU(latest_game, latest_game_menu_init, latest_game_menu_passive,
+ latest_game_menu_key, latest_game_menu_end, 0, 0);
+
+ /*--------------------------------------------------------
+ MAIN MENU
+ --------------------------------------------------------*/
+ MENU_OPTION_TYPE main_options[] =
+ {
+ /* 00 */ SUBMENU_OPTION(&graphics_menu, &msg[MSG_MAIN_MENU_0], NULL, 0),
+
+ /* 01 */ SUBMENU_OPTION(&game_state_menu, &msg[MSG_MAIN_MENU_1], NULL, 1),
+
+ /* 02 */ SUBMENU_OPTION(&cheats_menu, &msg[MSG_MAIN_MENU_2], NULL, 2),
+
+ /* 03 */ SUBMENU_OPTION(&tools_menu, &msg[MSG_MAIN_MENU_3], NULL, 3),
+
+ /* 04 */ SUBMENU_OPTION(&others_menu, &msg[MSG_MAIN_MENU_4], NULL, 4),
+
+ /* 05 */ ACTION_OPTION(menu_exit, NULL, &msg[MSG_MAIN_MENU_5], NULL, 5),
+
+ /* 06 */ SUBMENU_OPTION(&load_game_menu, NULL, NULL, 6),
+
+ /* 07 */ ACTION_OPTION(menu_return, NULL, NULL, NULL, 7),
+
+ /* 08 */ ACTION_OPTION(menu_restart, NULL, NULL, NULL, 8)
+ };
+
+ MAKE_MENU(main, NULL, main_menu_passive, main_menu_key, NULL, 6, 0);
+
+ void main_menu_passive()
+ {
+ show_icon(down_screen_addr, ICON_MAINBG, 0, 0);
+ current_menu -> focus_option = current_option -> line_number;
+
+ //Audio/Video
+ strcpy(line_buffer, *(display_option->display_string));
+ if(display_option++ == current_option) {
+ show_icon(down_screen_addr, ICON_AVO, 22, 2);
+ show_icon(down_screen_addr, ICON_MSEL, 11, 57);
+ }
+ else {
+ show_icon(down_screen_addr, ICON_NAVO, 22, 2);
+ show_icon(down_screen_addr, ICON_MNSEL, 11, 57);
+ }
+ draw_string_vcenter(down_screen_addr, 13, 57, 76, COLOR_WHITE, line_buffer);
+
+ //Save
+ strcpy(line_buffer, *(display_option->display_string));
+ if(display_option++ == current_option) {
+ show_icon(down_screen_addr, ICON_SAVO, 102, 2);
+ show_icon(down_screen_addr, ICON_MSEL, 92, 57);
+ }
+ else {
+ show_icon(down_screen_addr, ICON_NSAVO, 102, 2);
+ show_icon(down_screen_addr, ICON_MNSEL, 92, 57);
+ }
+ draw_string_vcenter(down_screen_addr, 95, 57, 72, COLOR_WHITE, line_buffer);
+
+ //Cheat
+ strcpy(line_buffer, *(display_option->display_string));
+ if(display_option++ == current_option) {
+ show_icon(down_screen_addr, ICON_CHEAT, 182, 2);
+ show_icon(down_screen_addr, ICON_MSEL, 173, 57);
+ }
+ else {
+ show_icon(down_screen_addr, ICON_NCHEAT, 182, 2);
+ show_icon(down_screen_addr, ICON_MNSEL, 173, 57);
+ }
+ draw_string_vcenter(down_screen_addr, 176, 57, 68, COLOR_WHITE, line_buffer);
+
+ //Tools
+ strcpy(line_buffer, *(display_option->display_string));
+ if(display_option++ == current_option) {
+ show_icon(down_screen_addr, ICON_TOOL, 22, 75);
+ show_icon(down_screen_addr, ICON_MSEL, 11, 131);
+ }
+ else {
+ show_icon(down_screen_addr, ICON_NTOOL, 22, 75);
+ show_icon(down_screen_addr, ICON_MNSEL, 11, 131);
+ }
+ draw_string_vcenter(down_screen_addr, 14, 131, 68, COLOR_WHITE, line_buffer);
+
+ //Other
+ strcpy(line_buffer, *(display_option->display_string));
+ if(display_option++ == current_option) {
+ show_icon(down_screen_addr, ICON_OTHER, 102, 75);
+ show_icon(down_screen_addr, ICON_MSEL, 92, 131);
+ }
+ else {
+ show_icon(down_screen_addr, ICON_NOTHER, 102, 75);
+ show_icon(down_screen_addr, ICON_MNSEL, 92, 131);
+ }
+ draw_string_vcenter(down_screen_addr, 95, 131, 68, COLOR_WHITE, line_buffer);
+
+ //Exit
+ strcpy(line_buffer, *(display_option->display_string));
+ if(display_option++ == current_option) {
+ show_icon(down_screen_addr, ICON_EXIT, 182, 75);
+ show_icon(down_screen_addr, ICON_MSEL, 173, 131);
+ }
+ else {
+ show_icon(down_screen_addr, ICON_NEXIT, 182, 75);
+ show_icon(down_screen_addr, ICON_MNSEL, 173, 131);
+ }
+ draw_string_vcenter(down_screen_addr, 176, 131, 68, COLOR_WHITE, line_buffer);
+
+ //New
+ if(display_option++ == current_option)
+ show_icon(down_screen_addr, ICON_NEW, 0, 154);
+ else
+ show_icon(down_screen_addr, ICON_NNEW, 0, 154);
+
+ //Restart
+ if(display_option++ == current_option)
+ show_icon(down_screen_addr, ICON_RETURN, 89, 154);
+ else
+ show_icon(down_screen_addr, ICON_NRETURN, 89, 154);
+
+ //Return
+ if(display_option++ == current_option)
+ show_icon(down_screen_addr, ICON_RESET, 170, 154);
+ else
+ show_icon(down_screen_addr, ICON_NRESET, 170, 154);
+ }
+
+ void main_menu_key()
+ {
+ switch(gui_action)
+ {
+ case CURSOR_DOWN:
+ if(current_option_num < 6) current_option_num += 3;
+ else current_option_num -= 6;
+
+ current_option = current_menu->options + current_option_num;
+ break;
+
+ case CURSOR_UP:
+ if(current_option_num < 3) current_option_num += 6;
+ else current_option_num -= 3;
+
+ current_option = current_menu->options + current_option_num;
+ break;
+
+ case CURSOR_RIGHT:
+ if(current_option_num == 2) current_option_num -= 2;
+ else if(current_option_num == 5) current_option_num -= 2;
+ else if(current_option_num == 8) current_option_num -= 2;
+ else current_option_num += 1;
+
+ current_option = main_menu.options + current_option_num;
+ break;
+
+ case CURSOR_LEFT:
+ if(current_option_num == 0) current_option_num += 2;
+ else if(current_option_num == 3) current_option_num += 2;
+ else if(current_option_num == 6) current_option_num += 2;
+ else current_option_num -= 1;
+
+ current_option = main_menu.options + current_option_num;
+ break;
+
+ default:
+ break;
+ }// end swith
+ }
+
+ void tools_menu_init()
+ {
+ if(game_config.backward)
+ tools_options[4].option_type &= ~HIDEN_TYPE;
+ else
+ tools_options[4].option_type |= HIDEN_TYPE;
+ }
+
+ int lastest_game_menu_scroll_value;
+ void latest_game_menu_init()
+ {
+ u32 k;
+ char *ext_pos;
+
+ for(k= 0; k < 5; k++)
+ {
+ ext_pos= strrchr(emu_config.latest_file[k], '/');
+ if(ext_pos != NULL)
+ draw_hscroll_init(down_screen_addr, 26, 40 + k*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1);
+ else
+ break;
+ }
+
+ if(k < 5)
+ {
+ latest_game_menu.num_options = k+1;
+ }
+ else
+ latest_game_menu.num_options = 6;
+
+ latest_game_menu.num_options = k+1;
+
+ for(; k < 5; k++)
+ {
+ latest_game_options[k+1].option_type |= HIDEN_TYPE;
+ }
+
+ lastest_game_menu_scroll_value = 0;
+ }
+
+ void latest_game_menu_passive()
+ {
+ u32 k;
+ unsigned short color;
+
+ //draw background
+ show_icon(down_screen_addr, ICON_SUBBG, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ if(current_option_num == 0)
+ show_icon(down_screen_addr, ICON_BACK, 229, 10);
+ else
+ {
+ show_icon(down_screen_addr, ICON_NBACK, 229, 10);
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + (current_option_num-1)*27);
+ }
+
+ strcpy(line_buffer, *(display_option->display_string));
+ draw_string_vcenter(down_screen_addr, 0, 9, 256, COLOR_ACTIVE_ITEM, line_buffer);
+
+ for(k= 0; k<5; k++)
+ if(emu_config.latest_file[k][0] != '\0')
+ {
+ if(current_option_num != k+1)
+ draw_hscroll(k, 0);
+ else
+ {
+ draw_hscroll(k, lastest_game_menu_scroll_value);
+ lastest_game_menu_scroll_value = 0;
+ }
+ }
+ }
+
+ void latest_game_menu_end()
+ {
+ u32 k;
+
+ for(k= 0; k < 5; k++)
+ {
+ if(emu_config.latest_file[k][0] != '\0')
+ draw_hscroll_over(k);
+ }
+ }
+
+ void latest_game_menu_key()
+ {
+ char *ext_pos;
+
+ switch(gui_action)
+ {
+ case CURSOR_DOWN:
+ //clear last option's bg
+ if(current_option_num != 0)
+ {
+ draw_hscroll_over(current_option_num-1);
+ ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1);
+ }
+
+ current_option_num += 1;
+ if(current_option_num >= latest_game_menu.num_options)
+ current_option_num = 0;
+ current_option = current_menu->options + current_option_num;
+
+ //Set current bg
+ if(current_option_num != 0)
+ {
+ draw_hscroll_over(current_option_num-1);
+ ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ COLOR_TRANS, COLOR_ACTIVE_ITEM, ext_pos+1);
+ }
+
+ break;
+
+ case CURSOR_UP:
+ //clear last option's bg
+ if(current_option_num != 0)
+ {
+ draw_hscroll_over(current_option_num-1);
+ ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
+ draw_hscroll_init(down_screen_addr, 26, 35 + (current_option_num-1)*27, 200,
+ COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1);
+ }
+
+ if(current_option_num > 0) current_option_num -= 1;
+ else current_option_num = latest_game_menu.num_options -1;
+ current_option = current_menu->options + current_option_num;
+
+ //Set current bg
+ if(current_option_num != 0)
+ {
+ draw_hscroll_over(current_option_num-1);
+ ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ COLOR_TRANS, COLOR_ACTIVE_ITEM, ext_pos+1);
+ }
+
+ break;
+
+ case CURSOR_RIGHT:
+ lastest_game_menu_scroll_value = -5;
+ break;
+
+ case CURSOR_LEFT:
+ lastest_game_menu_scroll_value = 5;
+ break;
+
+ default:
+ break;
+ }// end swith
+ }
+
+ void load_lastest_played()
+ {
+ char *ext_pos;
+
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, 0);
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_LOADING_GAME]);
+ ds2_flipScreen(DOWN_SCREEN, 2);
+
+ if(gamepak_name[0] != 0)
+ {
+ //S9xAutoSaveSRAM ();
+ save_game_config_file();
+ }
+
+ if(bg_screenp != NULL) {
+ bg_screenp_color = COLOR16(43, 11, 11);
+ }
+ else
+ bg_screenp_color = COLOR_BG;
+
+ ext_pos= strrchr(emu_config.latest_file[current_option_num -1], '/');
+ *ext_pos= '\0';
+ strcpy(rom_path, emu_config.latest_file[current_option_num -1]);
+ *ext_pos= '/';
+
+ ext_pos = emu_config.latest_file[current_option_num -1];
+ if(load_gamepak(ext_pos) == -1) {
+ first_load = 1;
+ return;
+ }
+
+ strcpy(g_default_rom_dir, ext_pos);
+ ext_pos = strrchr(g_default_rom_dir, '/');
+ *ext_pos= '\0';
+ strcpy(gamepak_name, ext_pos+1);
+
+
+ load_game_config_file();
+// time_period_action();
+
+ reorder_latest_file();
+ get_savestate_filelist();
+ game_fast_forward= 0;
+
+ get_newest_savestate(tmp_filename);
+ if(tmp_filename[0] != '\0')
+ {
+ load_state(tmp_filename);
+ }
+
+ return_value = 1;
+ repeat = 0;
+ }
+
+ void keyremap_show()
+ {
+ unsigned short color;
+ u32 line_num;
+ u32 index;
+
+ if(display_option->option_type & STRING_SELECTION_TYPE)
+ {
+ switch(i+1)
+ {
+ case 1: index= BUTTON_MAP_A; break;
+ case 2: index= BUTTON_MAP_B; break;
+ case 3: index= BUTTON_MAP_FA; break;
+ case 4: index= BUTTON_MAP_FB; break;
+ case 5: index= BUTTON_MAP_MENU; break;
+ default: index= 0; break;
+ }
+
+ line_num= 0;
+ while(index) {index >>= 1; line_num++;}
+ sprintf(line_buffer, *(display_option->display_string), *((u32*)keyremap_options[line_num]));
+ }
+ else
+ strcpy(line_buffer, *(display_option->display_string));
+
+ line_num= display_option-> line_number;
+ if(display_option == current_option)
+ color= COLOR_ACTIVE_ITEM;
+ else
+ color= COLOR_INACTIVE_ITEM;
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 37 + line_num*32);
+ }
+
+ void game_fastforward()
+ {
+ }
+
+
+
+ void reload_cheats_page()
+ {
+ for(i = 0; i < CHEATS_PER_PAGE; i++)
+ {
+ cheats_options[i+1].display_string = &cheat_format_ptr[(CHEATS_PER_PAGE * menu_cheat_page) + i];
+ cheats_options[i+1].current_option = &(game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + i].active);
+ }
+ }
+
+ void others_menu_init()
+ {
+ unsigned int total, used;
+
+ //get card space info
+ freespace = 0;
+ fat_getDiskSpaceInfo("fat:", &total, &used, &freespace);
+ }
+
+ void choose_menu(MENU_TYPE *new_menu)
+ {
+ if(new_menu == NULL)
+ new_menu = &main_menu;
+
+ if(NULL != current_menu) {
+ if(current_menu->end_function)
+ current_menu->end_function();
+ }
+
+ current_menu = new_menu;
+ current_option_num= current_menu -> focus_option;
+ current_option = new_menu->options + current_option_num;
+ if(current_menu->init_function)
+ current_menu->init_function();
+ }
+
+//----------------------------------------------------------------------------//
+// Menu Start
+ ds2_setCPUclocklevel(0);
+ mdelay(200);
+ ds2_setBacklight(3);
+
+
+ wait_Allkey_release(0);
+ bg_screenp= (u16*)malloc(256*192*2);
+
+ repeat = 1;
+
+ if(gamepak_name[0] == 0)
+ {
+ first_load = 1;
+ if(CheckLoad_Arg())
+ repeat = 0;
+ else
+ {
+ ds2_clearScreen(UP_SCREEN, COLOR_BLACK);
+ draw_string_vcenter(up_screen_addr, 0, 80, 256, COLOR_WHITE, msg[MSG_NON_LOAD_GAME]);
+ ds2_flipScreen(UP_SCREEN, 1);
+ }
+ }
+ else
+ {
+ ds2_flipScreen(UP_SCREEN, 1);
+ ds2_flipScreen(UP_SCREEN, 1);
+ }
+
+ choose_menu(&main_menu);
+// Menu loop
+
+ mdelay(200);
+ while(repeat)
+ {
+
+
+
+ display_option = current_menu->options;
+ string_select= 0;
+
+ if(current_menu -> passive_function)
+ current_menu -> passive_function();
+ else
+ {
+ u32 line_num, screen_focus, focus_option;
+
+ //draw background
+ show_icon(down_screen_addr, ICON_SUBBG, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLE, 0, 0);
+ show_icon(down_screen_addr, ICON_TITLEICON, 12, 9);
+
+ strcpy(line_buffer, *(display_option->display_string));
+ draw_string_vcenter(down_screen_addr, 0, 9, 256, COLOR_ACTIVE_ITEM, line_buffer);
+
+ line_num = current_option_num;
+ screen_focus = current_menu -> screen_focus;
+ focus_option = current_menu -> focus_option;
+
+ if(focus_option < line_num) //focus next option
+ {
+ focus_option = line_num - focus_option;
+ screen_focus += focus_option;
+ if(screen_focus > SUBMENU_ROW_NUM) //Reach max row numbers can display
+ screen_focus = SUBMENU_ROW_NUM;
+
+ current_menu -> screen_focus = screen_focus;
+ focus_option = line_num;
+ }
+ else if(focus_option > line_num) //focus last option
+ {
+ focus_option = focus_option - line_num;
+ if(screen_focus > focus_option)
+ screen_focus -= focus_option;
+ else
+ screen_focus = 0;
+
+ if(screen_focus == 0 && line_num > 0)
+ screen_focus = 1;
+
+ current_menu -> screen_focus = screen_focus;
+ focus_option = line_num;
+ }
+ current_menu -> focus_option = focus_option;
+
+ i = focus_option - screen_focus;
+ display_option += i +1;
+
+ line_num = current_menu->num_options-1;
+ if(line_num > SUBMENU_ROW_NUM)
+ line_num = SUBMENU_ROW_NUM;
+
+ if(focus_option == 0)
+ show_icon(down_screen_addr, ICON_BACK, 229, 10);
+ else
+ show_icon(down_screen_addr, ICON_NBACK, 229, 10);
+
+ for(i= 0; i < line_num; i++, display_option++)
+ {
+ unsigned short color;
+
+ if(display_option == current_option)
+ show_icon(down_screen_addr, ICON_SUBSELA, 6, 35 + i*27);
+
+ if(display_option->passive_function)
+ {
+ display_option->line_number = i;
+ display_option->passive_function();
+ }
+ else if(display_option->option_type & NUMBER_SELECTION_TYPE)
+ {
+ sprintf(line_buffer, *(display_option->display_string),
+ *(display_option->current_option));
+ }
+ else if(display_option->option_type & STRING_SELECTION_TYPE)
+ {
+ sprintf(line_buffer, *(display_option->display_string),
+ *((u32*)(((u32 *)display_option->options)[*(display_option->current_option)])));
+ }
+ else
+ {
+ strcpy(line_buffer, *(display_option->display_string));
+ }
+
+ if(display_option->passive_function == NULL)
+ {
+ if(display_option == current_option)
+ color= COLOR_ACTIVE_ITEM;
+ else
+ color= COLOR_INACTIVE_ITEM;
+
+ PRINT_STRING_BG_UTF8(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + i*27);
+ }
+ }
+ }
+
+ gui_action = get_gui_input();
+ if(gui_action == CURSOR_TOUCH)
+ {
+ }
+ else
+ {
+ }
+
+ switch(gui_action)
+ {
+ case CURSOR_DOWN:
+ if(current_menu->key_function)
+ current_menu->key_function();
+ else
+ {
+ current_option_num = (current_option_num + 1) % current_menu->num_options;
+ current_option = current_menu->options + current_option_num;
+
+ while(current_option -> option_type & HIDEN_TYPE)
+ {
+ current_option_num = (current_option_num + 1) % current_menu->num_options;
+ current_option = current_menu->options + current_option_num;
+ }
+ }
+ break;
+
+ case CURSOR_UP:
+ if(current_menu->key_function)
+ current_menu->key_function();
+ else
+ {
+ if(current_option_num)
+ current_option_num--;
+ else
+ current_option_num = current_menu->num_options - 1;
+ current_option = current_menu->options + current_option_num;
+
+ while(current_option -> option_type & HIDEN_TYPE)
+ {
+ if(current_option_num)
+ current_option_num--;
+ else
+ current_option_num = current_menu->num_options - 1;
+ current_option = current_menu->options + current_option_num;
+ }
+ }
+ break;
+
+ case CURSOR_RIGHT:
+ if(current_menu->key_function)
+ current_menu->key_function();
+ else
+ {
+ if(current_option->option_type & (NUMBER_SELECTION_TYPE | STRING_SELECTION_TYPE))
+ {
+ u32 current_option_val = *(current_option->current_option);
+
+ if(current_option_val < current_option->num_options -1)
+ current_option_val++;
+ else
+ current_option_val= 0;
+ *(current_option->current_option) = current_option_val;
+
+ if(current_option->action_function)
+ current_option->action_function();
+ }
+ }
+ break;
+
+ case CURSOR_LEFT:
+ if(current_menu->key_function)
+ current_menu->key_function();
+ else
+ {
+ if(current_option->option_type & (NUMBER_SELECTION_TYPE | STRING_SELECTION_TYPE))
+ {
+ u32 current_option_val = *(current_option->current_option);
+
+ if(current_option_val)
+ current_option_val--;
+ else
+ current_option_val = current_option->num_options - 1;
+ *(current_option->current_option) = current_option_val;
+
+ if(current_option->action_function)
+ current_option->action_function();
+ }
+ }
+ break;
+
+ case CURSOR_EXIT:
+ break;
+
+ case CURSOR_SELECT:
+ if(current_option->option_type & ACTION_TYPE)
+ current_option->action_function();
+ else if(current_option->option_type & SUBMENU_TYPE)
+ choose_menu(current_option->sub_menu);
+ break;
+
+ case CURSOR_BACK:
+ if(current_menu != &main_menu)
+ choose_menu(current_menu->options->sub_menu);
+ else
+ menu_return();
+ break;
+
+ default:
+ break;
+ } // end swith
+
+ ds2_flipScreen(DOWN_SCREEN, 2);
+ } // end while
+ destroy_dynamic_cheats();
+ if(bg_screenp != NULL) free((void*)bg_screenp);
+
+ save_game_config_file();
+ mdelay(100);
+ set_cpu_clock(clock_speed_number);
+ mdelay(200);
+
+ ds2_clearScreen(DOWN_SCREEN, 0);
+ ds2_flipScreen(DOWN_SCREEN, 1);
+ ds2_clearScreen(UP_SCREEN, 0);
+ ds2_flipScreen(UP_SCREEN, 1);
+ ds2_clearScreen(UP_SCREEN, 0);
+ ds2_flipScreen(UP_SCREEN, 1);
+ ds2_setBacklight(2);
+
+//save game config
+// save_game_config_file();
+// save_emu_config_file();
+
+
+// ds2_setCPUclocklevel(12);
+ wait_Allkey_release(0);
+
+ return return_value;
+}
+
+/*--------------------------------------------------------
+ Initialize default path
+--------------------------------------------------------*/
+void initial_path_config(void)
+{
+ //Initial directory path
+ sprintf(g_default_rom_dir, "%s/gamepak", main_path);
+ sprintf(DEFAULT_RTS_DIR, "%s/gamerts", main_path);
+ sprintf(DEFAULT_CFG_DIR, "%s/gamerts", main_path);
+ sprintf(DEFAULT_SS_DIR, "%s/gamepic", main_path);
+ sprintf(DEFAULT_CHEAT_DIR, "%s/gamecht", main_path);
+}
+
+/*--------------------------------------------------------
+ Load language message
+--------------------------------------------------------*/
+int load_language_msg(char *filename, u32 language)
+{
+ FILE *fp;
+ char msg_path[MAX_PATH];
+ char string[256];
+ char start[32];
+ char end[32];
+ char *pt, *dst;
+ u32 cmplen;
+ u32 loop, offset, len;
+ int ret;
+
+ sprintf(msg_path, "%s/%s", main_path, filename);
+ fp = fopen(msg_path, "rb");
+ if(fp == NULL)
+ return -1;
+
+ switch(language)
+ {
+ case ENGLISH:
+ strcpy(start, "STARTENGLISH");
+ strcpy(end, "ENDENGLISH");
+ cmplen= 12;
+ break;
+ case CHINESE_SIMPLIFIED:
+ strcpy(start, "STARTCHINESESIM");
+ strcpy(end, "ENDCHINESESIM");
+ cmplen= 15;
+ break;
+ default:
+ strcpy(start, "STARTENGLISH");
+ strcpy(end, "ENDENGLISH");
+ cmplen= 12;
+ break;
+ }
+ //find the start flag
+ ret= 0;
+ while(1)
+ {
+ pt= fgets(string, 256, fp);
+ if(pt == NULL)
+ {
+ ret= -2;
+ goto load_language_msg_error;
+ }
+
+ if(!strncmp(pt, start, cmplen))
+ break;
+ }
+
+ loop= 0;
+ offset= 0;
+ dst= msg_data;
+ msg[0]= dst;
+
+ while(loop != MSG_END)
+ {
+ while(1)
+ {
+ pt = fgets(string, 256, fp);
+ if(pt[0] == '#' || pt[0] == 0x0D || pt[0] == 0x0A)
+ continue;
+ if(pt != NULL)
+ break;
+ else
+ {
+ ret = -3;
+ goto load_language_msg_error;
+ }
+ }
+
+ if(!strncmp(pt, end, cmplen-2))
+ break;
+
+ len= strlen(pt);
+ memcpy(dst, pt, len);
+
+ dst += len;
+ //at a line return, when "\n" paded, this message not end
+ if(*(dst-1) == 0x0A)
+ {
+ pt = strrchr(pt, '\\');
+ if((pt != NULL) && (*(pt+1) == 'n'))
+ {
+ if(*(dst-2) == 0x0D)
+ {
+ *(dst-4)= '\n';
+ dst -= 3;
+ }
+ else
+ {
+ *(dst-3)= '\n';
+ dst -= 2;
+ }
+ }
+ else//a message end
+ {
+ if(*(dst-2) == 0x0D)
+ dst -= 1;
+ *(dst-1) = '\0';
+ msg[++loop] = dst;
+ }
+ }
+ }
+
+#if 0
+ loop= 0;
+ printf("------\n");
+ while(loop != MSG_END)
+ printf("%d: %s\n",loop, msg[loop++]);
+#endif
+
+load_language_msg_error:
+ fclose(fp);
+ return ret;
+}
+
+/*--------------------------------------------------------
+--------------------------------------------------------*/
+
+
+/*--------------------------------------------------------
+ Load font library
+--------------------------------------------------------*/
+u32 load_font()
+{
+ return (u32)BDF_font_init();
+}
+
+/*--------------------------------------------------------
+ Game configure initialize
+--------------------------------------------------------*/
+void init_game_config(void)
+{
+ u32 i;
+
+ game_config.clock_speed_number = 2; //360MHz
+ clock_speed_number = 2;
+ game_config.graphic = 0;
+
+ game_config.gamepad_config_menu = BUTTON_ID_TOUCH;
+ memcpy(game_config.gamepad_config_map, gamepad_config_map_init, sizeof(gamepad_config_map_init));
+
+ for(i = 0; i < MAX_CHEATS; i++)
+ {
+ game_config.cheats_flag[i].active = 0;
+ game_config.cheats_flag[i].name_shot[0] = '\0';
+ }
+
+ memset(game_config.cheat_filename, 0x0, MAX_PATH);
+
+ game_config.backward = 0; //time backward disable
+ game_config.backward_time = 2; //time backward granularity 1s
+
+ savestate_index= 0;
+ for(i= 0; i < SAVE_STATE_SLOT_NUM; i++)
+ {
+ savestate_map[i]= (char)(-(i+1)); //empty
+ }
+}
+
+/*--------------------------------------------------------
+ Emulator configure initialize
+--------------------------------------------------------*/
+void init_emulator_config(void)
+{
+ emu_config.language = 0; //defalut language= English
+
+ emu_config.rom_file[0]= 0;
+ emu_config.rom_path[0]= 0;
+ memset(emu_config.latest_file, 0, sizeof(emu_config.latest_file));
+
+ gamepak_name[0] = '\0';
+}
+
+/*--------------------------------------------------------
+ Load game configure file
+--------------------------------------------------------*/
+void load_game_config_file(void)
+{
+ char game_config_filename[MAX_PATH];
+ FILE* fp;
+ char *pt;
+
+ //Set default
+ init_game_config();
+
+ sprintf(game_config_filename, "%s/%s", DEFAULT_CFG_DIR, gamepak_name);
+ pt= strrchr(game_config_filename, '.');
+ if(NULL == pt)
+ return;
+ *pt= 0;
+ strcat(game_config_filename, "_0.rts");
+
+ fp = fopen(game_config_filename, "r");
+ if(NULL == fp)
+ return;
+
+ //Check file header
+ pt= game_config_filename;
+ fread(pt, 1, GAME_CONFIG_HEADER_SIZE, fp);
+
+ if (!strncmp(pt, GAME_CONFIG_HEADER, GAME_CONFIG_HEADER_SIZE))
+ {
+ fread(&game_config, 1, sizeof(GAME_CONFIG), fp);
+
+ memcpy(gamepad_config_map, game_config.gamepad_config_map, sizeof(game_config.gamepad_config_map));
+ gamepad_config_menu = game_config.gamepad_config_menu;
+ clock_speed_number = game_config.clock_speed_number;
+ }
+
+ fclose(fp);
+}
+
+/*--------------------------------------------------------
+ Load emulator configure file
+--------------------------------------------------------*/
+int load_emu_config_file(void)
+{
+ char tmp_path[MAX_PATH];
+ FILE* fp;
+ char *pt;
+
+ sprintf(tmp_path, "%s/%s", main_path, EMU_CONFIG_FILENAME);
+
+ fp = fopen(tmp_path, "r");
+ if(NULL != fp)
+ {
+ // check the file header
+ pt= tmp_path;
+ fread(pt, 1, EMU_CONFIG_HEADER_SIZE, fp);
+ pt[EMU_CONFIG_HEADER_SIZE]= 0;
+ if(!strcmp(pt, EMU_CONFIG_HEADER))
+ {
+ fread(&emu_config, 1, sizeof(emu_config), fp);
+ fclose(fp);
+ return 0;
+ }
+ }
+
+ //have no confiure file, set default
+ init_emulator_config();
+ return -1;
+}
+
+/*--------------------------------------------------------
+ Save game configure file
+--------------------------------------------------------*/
+int save_game_config_file(void)
+{
+ char game_config_filename[MAX_PATH];
+ FILE* fp;
+ char *pt;
+
+ if(gamepak_name[0] == 0) return -1;
+
+ memcpy(game_config.gamepad_config_map, gamepad_config_map, sizeof(game_config.gamepad_config_map));
+ game_config.gamepad_config_menu = gamepad_config_menu;
+
+ sprintf(game_config_filename, "%s/%s", DEFAULT_CFG_DIR, gamepak_name);
+ pt = strrchr(game_config_filename, '.');
+ if(NULL == pt)
+ return -1;
+
+ *pt = '\0';
+ strcat(pt, "_0.rts");
+
+ fp = fopen(game_config_filename, "w");
+ if(NULL != fp)
+ {
+ fwrite(GAME_CONFIG_HEADER, 1, GAME_CONFIG_HEADER_SIZE, fp);
+ fwrite(&game_config, 1, sizeof(game_config), fp);
+ fclose(fp);
+ return 0;
+ }
+
+ return -1;
+}
+
+/*--------------------------------------------------------
+ Save emulator confiure file
+--------------------------------------------------------*/
+int save_emu_config_file()
+{
+ char tmp_path[MAX_PATH];
+ FILE* fp;
+
+ sprintf(tmp_path, "%s/%s", main_path, EMU_CONFIG_FILENAME);
+ fp = fopen(tmp_path, "w");
+ if(NULL != fp)
+ {
+ fwrite(EMU_CONFIG_HEADER, 1, EMU_CONFIG_HEADER_SIZE, fp);
+ fwrite(&emu_config, 1, sizeof(emu_config), fp);
+ fclose(fp);
+ return 0;
+ }
+
+ return -1;
+}
+
+/*--------------------------------------------------------
+ Reorder latest player game recorder
+--------------------------------------------------------*/
+void reorder_latest_file(void)
+{
+ char *ext_pos, *ext_pos1;
+ u32 i, len;
+ char full_file[512];
+
+ if(gamepak_name[0] == '\0')
+ return;
+
+ for(i= 0; i < 5; i++)
+ {
+ ext_pos= strrchr(emu_config.latest_file[i], '/');
+ if(ext_pos != NULL)
+ {
+ ext_pos1= strrchr(ext_pos + 1, '.');
+ len= ext_pos1 - ext_pos -1;
+ if(!strncasecmp(ext_pos + 1, gamepak_name, len))
+ break;
+ }
+ }
+
+ //some one match, move to last
+ if(i < 5)
+ {
+ if(i < 4)
+ {
+ strcpy(full_file, emu_config.latest_file[i]);
+ for(i+=1; i < 5; i++)
+ {
+ if(emu_config.latest_file[i][0] != '\0')
+ strcpy(emu_config.latest_file[i-1], emu_config.latest_file[i]);
+ else
+ break;
+ }
+
+ strcpy(emu_config.latest_file[i-1], full_file);
+ }
+ return ;
+ }
+
+ //none match
+ for(i= 0; i < 5; i++)
+ {
+ if(emu_config.latest_file[i][0] == '\0')
+ {
+ sprintf(emu_config.latest_file[i], "%s/%s", g_default_rom_dir, gamepak_name);
+ break;
+ }
+ }
+
+ if(i < 5) return;
+
+ //queue full
+ for(i=1; i < 5; i++)
+ strcpy(emu_config.latest_file[i-1], emu_config.latest_file[i]);
+
+ sprintf(emu_config.latest_file[i-1], "%s/%s", g_default_rom_dir, gamepak_name);
+}
+
+/*--------------------------------------------------------
+ Save state related
+--------------------------------------------------------*/
+static int rtc_time_cmp(struct rtc *t1, struct rtc *t2)
+{
+ int result;
+
+ result= (int)((unsigned int)(t1 -> year) - (unsigned int)(t2 -> year));
+ if(result != 0)
+ return result;
+ result= (int)((unsigned int)(t1 -> month) - (unsigned int)(t2 -> month));
+ if(result != 0)
+ return result;
+ result= (int)((unsigned int)(t1 -> day) - (unsigned int)(t2 -> day));
+ if(result != 0)
+ return result;
+ result= (int)((unsigned int)(t1 -> weekday) - (unsigned int)(t2 -> weekday));
+ if(result != 0)
+ return result;
+ result= (int)((unsigned int)(t1 -> hours) - (unsigned int)(t2 -> hours));
+ if(result != 0)
+ return result;
+ result= (int)((unsigned int)(t1 -> minutes) - (unsigned int)(t2 -> minutes));
+ if(result != 0)
+ return result;
+ result= (int)((unsigned int)(t1 -> seconds) - (unsigned int)(t2 -> seconds));
+// if(result != 0)
+ return result;
+}
+
+static void get_savestate_filelist(void)
+{
+ struct rtc current_time[SAVE_STATE_SLOT_NUM];
+ int i;
+ char savestate_path[MAX_PATH];
+ char postdrix[8];
+ char *pt;
+ FILE *fp;
+ unsigned int n, m;
+
+ memset((char*)current_time, 0xFF, sizeof(current_time));
+ for(i= 0; i < SAVE_STATE_SLOT_NUM; i++)
+ {
+ savestate_map[i]= (char)(-(i+1));
+ }
+
+ sprintf(savestate_path, "%s/%s", DEFAULT_RTS_DIR, gamepak_name);
+ pt= strrchr(savestate_path, '.');
+ for(i= 0; i < SAVE_STATE_SLOT_NUM; i++)
+ {
+ sprintf(postdrix, "_%d.rts", i+1);
+ strcpy(pt, postdrix);
+
+ fp= fopen(savestate_path, "r");
+ if (fp != NULL)
+ {
+ m = fread((void*)&n, 1, 4, fp);
+ if(m < 4) {
+ fclose(fp);
+ continue;
+ }
+
+ fseek(fp, n, SEEK_SET);
+ /* Read back the time stamp */
+ fread((char*)&current_time[i], 1, sizeof(struct rtc), fp);
+ savestate_map[i] = (char)(i+1);
+
+ fclose(fp);
+ }
+ }
+
+ int k, reslut;
+ struct rtc current_time_tmp;
+ for(i= 0; i < SAVE_STATE_SLOT_NUM-1; i++)
+ {
+ for(k=0; k < SAVE_STATE_SLOT_NUM-1-i; k++)
+ {
+ reslut= rtc_time_cmp(&current_time[k], &current_time[k+1]);
+ if(reslut > 0)
+ {
+ current_time_tmp = current_time[k];
+ current_time[k] = current_time[k+1];
+ current_time[k+1] = current_time_tmp;
+ reslut = savestate_map[k];
+ savestate_map[k] = savestate_map[k+1];
+ savestate_map[k+1] = reslut;
+ }
+ }
+ }
+
+ savestate_index= get_savestate_slot();
+ if(savestate_index < 0) savestate_index = 0;
+}
+
+static void get_savestate_filename(u32 slot, char *name_buffer)
+{
+ char savestate_ext[16];
+ char *pt;
+
+ sprintf(savestate_ext, "_%d.rts", savestate_map[slot]);
+ pt = strrchr(gamepak_name, '/');
+ if(NULL == pt)
+ pt = gamepak_name;
+ else
+ pt += 1;
+
+ change_ext(pt, name_buffer, savestate_ext);
+}
+
+static u32 get_savestate_slot(void)
+{
+ s32 i;
+ char *ptr;
+
+ i= SAVE_STATE_SLOT_NUM -1;
+ ptr= savestate_map;
+ while(i >= 0)
+ {
+ if(ptr[i] > 0) break;
+ i--;
+ }
+
+ return i;
+}
+
+static void reorder_savestate_slot(void)
+{
+ u32 x, y;
+ char *ptr;
+ s32 tmp;
+
+ ptr= savestate_map;
+ for(x= 0; x < SAVE_STATE_SLOT_NUM; x++)
+ {
+ tmp= ptr[x];
+ if(tmp< 0)
+ {
+ for(y= x+1; y< SAVE_STATE_SLOT_NUM; y++)
+ ptr[y-1]= ptr[y];
+ ptr[SAVE_STATE_SLOT_NUM-1]= tmp; //empty are moved to last
+ }
+ }
+}
+
+void get_newest_savestate(char *name_buffer)
+{
+ int i;
+
+ i= get_savestate_slot();
+ if (i < 0)
+ {
+ name_buffer[0]= '\0';
+ return;
+ }
+
+ get_savestate_filename(i, name_buffer);
+}
+
+static u32 parse_line(char *current_line, char *current_str)
+{
+ char *line_ptr;
+ char *line_ptr_new;
+
+ line_ptr = current_line;
+ /* NULL or comment or other */
+ if((current_line[0] == 0) || (current_line[0] == '#') || (current_line[0] != '!'))
+ return -1;
+
+ line_ptr++;
+
+ line_ptr_new = strchr(line_ptr, '\r');
+ while (line_ptr_new != NULL)
+ {
+ *line_ptr_new = '\n';
+ line_ptr_new = strchr(line_ptr, '\r');
+ }
+
+ line_ptr_new = strchr(line_ptr, '\n');
+ if (line_ptr_new == NULL)
+ return -1;
+
+ *line_ptr_new = 0;
+
+ // "\n" to '\n'
+ line_ptr_new = strstr(line_ptr, "\\n");
+ while (line_ptr_new != NULL)
+ {
+ *line_ptr_new = '\n';
+ memmove((line_ptr_new + 1), (line_ptr_new + 2), (strlen(line_ptr_new + 2) + 1));
+ line_ptr_new = strstr(line_ptr_new, "\\n");
+ }
+
+ strcpy(current_str, line_ptr);
+ return 0;
+}
+
+static void get_timestamp_string(char *buffer, u16 msg_id, u16 year, u16 mon,
+ u16 day, u16 wday, u16 hour, u16 min, u16 sec, u32 msec)
+{
+ char *weekday_strings[] =
+ {
+ "SUN", "MON", "TUE", "WED", "TUR", "FRI", "SAT"
+ };
+
+ sprintf(buffer, "%s %02d/%02d/%04d %02d:%02d:%02d", weekday_strings[wday],
+ day, mon, year, hour, min, sec);
+}
+
+static void get_time_string(char *buff, struct rtc *rtcp)
+{
+ get_timestamp_string(buff, 0,
+ rtcp -> year +2000,
+ rtcp -> month,
+ rtcp -> day,
+ rtcp -> weekday,
+ rtcp -> hours,
+ rtcp -> minutes,
+ rtcp -> seconds,
+ 0);
+}
+
+static u32 save_ss_bmp(u16 *image)
+{
+ static unsigned char header[] ={ 'B', 'M', 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0, 0x01, 0x00,
+ 0x00, 192, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ char ss_filename[MAX_FILE];
+ char save_ss_path[MAX_PATH];
+ struct rtc current_time;
+ char rgb_data[256*192*3];
+ unsigned int x,y;
+ unsigned short col;
+ unsigned char r,g,b;
+
+ change_ext(gamepak_name, ss_filename, "_");
+ ds2_getTime(&current_time);
+ sprintf(save_ss_path, "%s/%s%02d%02d%02d%02d%02d.bmp", DEFAULT_SS_DIR, ss_filename,
+ current_time.month, current_time.day, current_time.hours, current_time.minutes, current_time.seconds);
+
+ for(y = 0; y < 192; y++)
+ {
+ for(x = 0; x < 256; x++)
+ {
+ col = image[x + y * 256];
+ r = (col >> 10) & 0x1F;
+ g = (col >> 5) & 0x1F;
+ b = (col) & 0x1F;
+
+ rgb_data[(191-y)*256*3+x*3+2] = b << 3;
+ rgb_data[(191-y)*256*3+x*3+1] = g << 3;
+ rgb_data[(191-y)*256*3+x*3+0] = r << 3;
+ }
+ }
+
+ FILE *ss = fopen( save_ss_path, "wb" );
+ if( ss == NULL ) return 0;
+ fwrite( header, sizeof(header), 1, ss );
+ fwrite( rgb_data, 1, 256*192*3, ss);
+ fclose( ss );
+
+ return 1;
+}
+
+void quit(void)
+{
+/*
+ u32 reg_ra;
+
+ __asm__ __volatile__("or %0, $0, $ra"
+ : "=r" (reg_ra)
+ :);
+
+ dbg_printf("return address= %08x\n", reg_ra);
+*/
+
+#ifdef USE_DEBUG
+ fclose(g_dbg_file);
+#endif
+
+ ds2_plug_exit();
+ while(1);
+}
+
+u32 file_length(FILE* file)
+{
+ u32 pos, size;
+ pos= ftell(file);
+ fseek(file, 0, SEEK_END);
+ size= ftell(file);
+ fseek(file, pos, SEEK_SET);
+
+ return size;
+}
+
+/*
+* GUI Initialize
+*/
+void gui_init(u32 lang_id)
+{
+ int flag;
+
+ ds2_setCPUclocklevel(11);
+ printf_clock();
+
+ //Find the "BAGSFC" system directory
+ DIR *current_dir;
+
+ strcpy(main_path, "fat:/BAGSFC");
+ current_dir = opendir(main_path);
+ if(current_dir)
+ closedir(current_dir);
+ else
+ {
+ strcpy(main_path, "fat:/_SYSTEM/PLUGINS/BAGSFC");
+ current_dir = opendir(main_path);
+ if(current_dir)
+ closedir(current_dir);
+ else
+ {
+ strcpy(main_path, "fat:");
+ if(search_dir("BAGSFC", main_path) == 0)
+ {
+ printf("Dirctory find: %s\n", main_path);
+ }
+ else
+ {
+ err_msg(DOWN_SCREEN, "Can't fine BAGSFC directory, press any key to exit\n");
+ goto gui_init_err;
+ }
+ }
+ }
+
+ show_log(down_screen_addr);
+ ds2_flipScreen(DOWN_SCREEN, 1);
+
+ flag = icon_init(lang_id);
+ if(0 != flag)
+ {
+ err_msg(DOWN_SCREEN, "some icon can't open when initial GUI, press any key to exit\n");
+ goto gui_init_err;
+ }
+
+
+ flag = load_font();
+ if(0 != flag)
+ {
+ err_msg(DOWN_SCREEN, "initial font library error, press any key to exit\n");
+ goto gui_init_err;
+ }
+
+ load_emu_config_file();
+ lang_id = emu_config.language;
+
+ flag = load_language_msg(LANGUAGE_PACK, lang_id);
+ if(0 != flag)
+ {
+ err_msg(DOWN_SCREEN, "initial language package error, press any key to exit\n");
+ goto gui_init_err;
+ }
+
+ initial_path_config();
+
+
+ return;
+
+gui_init_err:
+ ds2_flipScreen(DOWN_SCREEN, 1);
+ wait_Anykey_press(0);
+ quit();
+ while(1);
+}
+
+
+
diff --git a/source/nds/gui.h b/source/nds/gui.h
new file mode 100644
index 0000000..e845994
--- /dev/null
+++ b/source/nds/gui.h
@@ -0,0 +1,125 @@
+/* gui.h
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __GUI_H__
+#define __GUI_H__
+
+#include "ds2_types.h"
+#include "fs_api.h"
+#include "gcheat.h"
+
+#define MAX_GAMEPAD_MAP 16
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+struct _EMU_CONFIG
+{
+ u32 language;
+ char rom_file[256];
+ char rom_path[256];
+ char latest_file[5][512];
+};
+
+struct _GAME_CONFIG
+{
+ u32 clock_speed_number;
+ u32 frameskip_type;
+ u32 frameskip_value;
+ u32 graphic;
+ u32 enable_audio;
+ u32 gamepad_config_menu;
+ u32 backward;
+ u32 backward_time;
+ u32 reserve[32];
+ u32 gamepad_config_map[MAX_GAMEPAD_MAP];
+ GCHEAT_STRUCT cheats_flag[MAX_CHEATS];
+ char cheat_filename[MAX_PATH];
+ unsigned int cheat_str_num;
+ unsigned int cheat_str_size;
+};
+
+typedef enum
+{
+ CURSOR_NONE = 0,
+ CURSOR_UP,
+ CURSOR_DOWN,
+ CURSOR_LEFT,
+ CURSOR_RIGHT,
+ CURSOR_SELECT,
+ CURSOR_BACK,
+ CURSOR_EXIT,
+ CURSOR_RTRIGGER,
+ CURSOR_LTRIGGER,
+ CURSOR_KEY_SELECT,
+ CURSOR_TOUCH
+} gui_action_type;
+
+typedef enum
+{
+ BUTTON_ID_A = 0x01,
+ BUTTON_ID_B = 0x02,
+ BUTTON_ID_SELECT = 0x04,
+ BUTTON_ID_START = 0x08,
+ BUTTON_ID_RIGHT = 0x10,
+ BUTTON_ID_LEFT = 0x20,
+ BUTTON_ID_UP = 0x40,
+ BUTTON_ID_DOWN = 0x80,
+ BUTTON_ID_R = 0x100,
+ BUTTON_ID_L = 0x200,
+ BUTTON_ID_X = 0x400,
+ BUTTON_ID_Y = 0x800,
+ BUTTON_ID_TOUCH = 0x1000,
+ BUTTON_ID_LID = 0x2000,
+ BUTTON_ID_FA = 0x4000,
+ BUTTON_ID_FB = 0x8000,
+ BUTTON_ID_NONE = 0
+} input_buttons_id_type;
+
+extern char main_path[MAX_PATH];
+extern char rom_path[MAX_PATH];
+
+extern u32 game_enable_audio;
+
+/******************************************************************************
+ ******************************************************************************/ extern char g_default_rom_dir[MAX_PATH];
+extern char DEFAULT_RTS_DIR[MAX_PATH];
+extern char DEFAULT_CFG_DIR[MAX_PATH];
+extern char DEFAULT_SS_DIR[MAX_PATH];
+extern char DEFAULT_CHEAT_DIR[MAX_PATH];
+
+typedef struct _EMU_CONFIG EMU_CONFIG;
+typedef struct _GAME_CONFIG GAME_CONFIG;
+
+extern EMU_CONFIG emu_config;
+extern GAME_CONFIG game_config;
+
+/******************************************************************************
+ ******************************************************************************/
+extern void gui_init(u32 lang_id);
+extern u32 menu(u16 *original_screen);
+extern void game_disableAudio();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__GUI_H__
diff --git a/source/nds/message.h b/source/nds/message.h
new file mode 100644
index 0000000..fc6bd33
--- /dev/null
+++ b/source/nds/message.h
@@ -0,0 +1,175 @@
+/* message.h
+ *
+ * Copyright (C) 2010 dking <dking024@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licens e 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MESSAGE_H__
+#define __MESSAGE_H__
+
+enum MSG
+{
+ MSG_MAIN_MENU_0, /* 0 */
+ MSG_MAIN_MENU_1, /* 1 */
+ MSG_MAIN_MENU_2, /* 2 */
+ MSG_MAIN_MENU_3, /* 3 */
+ MSG_MAIN_MENU_4, /* 4 */
+ MSG_MAIN_MENU_5, /* 5 */
+ MSG_SUB_MENU_00, /* 6 */
+ MSG_SUB_MENU_01, /* 7 */
+ MSG_SUB_MENU_02, /* 8 */
+ MSG_SUB_MENU_03, /* 9 */
+ MSG_SUB_MENU_04, /* 10 */
+ MSG_SUB_MENU_05, /* 11 */
+ MSG_SUB_MENU_10, /* 12 */
+ MSG_SUB_MENU_11, /* 13 */
+ MSG_SUB_MENU_12, /* 14 */
+ MSG_SUB_MENU_13, /* 15 */
+ MSG_SUB_MENU_14, /* 16 */
+ MSG_SUB_MENU_20, /* 17 */
+ MSG_SUB_MENU_21, /* 18 */
+ MSG_SUB_MENU_22, /* 19 */
+ MSG_SUB_MENU_23, /* 20 */
+ MSG_SUB_MENU_24, /* 21 */
+ MSG_SUB_MENU_30, /* 22 */
+ MSG_SUB_MENU_31, /* 23 */
+ MSG_SUB_MENU_32, /* 24 */
+ MSG_SUB_MENU_40, /* 25 */
+ MSG_SUB_MENU_41, /* 26 */
+ MSG_SUB_MENU_42, /* 27 */
+ MSG_SUB_MENU_43, /* 28 */
+ MSG_SUB_MENU_44, /* 29 */
+ MSG_SUB_MENU_45, /* 30 */
+ MSG_SUB_MENU_300, /* 31 */
+ MSG_SUB_MENU_301, /* 32 */
+ MSG_SUB_MENU_302, /* 33 */
+ MSG_SUB_MENU_310, /* 34 */
+ MSG_SUB_MENU_311, /* 35 */
+ MSG_SUB_MENU_312, /* 36 */
+ MSG_SUB_MENU_313, /* 37 */
+ MSG_SUB_MENU_314, /* 38 */
+ MSG_SUB_MENU_315, /* 39 */
+ MSG_SUB_MENU_60, /* 40 */
+ MSG_SUB_MENU_61, /* 41 */
+ MSG_SUB_MENU_62, /* 42 */
+
+ MSG_SCREEN_RATIO_0,
+ MSG_SCREEN_RATIO_1,
+ MSG_SCREEN_RATIO_2,
+ MSG_SCREEN_RATIO_3,
+ MSG_SCREEN_RATIO_4,
+
+ MSG_FRAMESKIP_0, /* 45 */
+ MSG_FRAMESKIP_1, /* 46 */
+
+ MSG_ON_OFF_0, /* 47 */
+ MSG_ON_OFF_1, /* 48 */
+
+ MSG_SOUND_SWITCH_0, /* 49 */
+ MSG_SOUND_SWITCH_1, /* 50 */
+
+ MSG_SNAP_FRAME_0, /* 51 */
+ MSG_SNAP_FRAME_1, /* 52 */
+
+ MSG_EN_DIS_ABLE_0, /* 53 */
+ MSG_EN_DIS_ABLE_1, /* 54 */
+
+ MSG_NON_LOAD_GAME, /* 55 */
+ MSG_CHEAT_MENU_NON_LOAD,/* 56 */
+ MSG_CHEAT_MENU_LOADED, /* 57 */
+
+ MSG_LOAD_STATE, /* 58 */
+ MSG_LOAD_STATE_END, /* 59 */
+ MSG_SAVE_STATE, /* 60 */
+ MSG_SAVE_STATE_END, /* 61 */
+
+ MSG_KEY_MAP_NONE, /* 62 */
+ MSG_KEY_MAP_A, /* 63 */
+ MSG_KEY_MAP_B, /* 64 */
+ MSG_KEY_MAP_SL, /* 65 */
+ MSG_KEY_MAP_ST, /* 66 */
+ MSG_KEY_MAP_RT, /* 67 */
+ MSG_KEY_MAP_LF, /* 68 */
+ MSG_KEY_MAP_UP, /* 69 */
+ MSG_KEY_MAP_DW, /* 70 */
+ MSG_KEY_MAP_R, /* 71 */
+ MSG_KEY_MAP_L, /* 72 */
+ MSG_KEY_MAP_X, /* 73 */
+ MSG_KEY_MAP_Y, /* 74 */
+ MSG_KEY_MAP_TOUCH, /* 75 */
+
+ MSG_SAVESTATE_EMPTY,/* 76 */
+ MSG_SAVESTATE_FULL, /* 77 */
+ MSG_SAVESTATE_DOING,/* 78 */
+ MSG_SAVESTATE_FAILUER,/* 79 */
+ MSG_SAVESTATE_SUCCESS,/* 80 */
+ MSG_SAVESTATE_SLOT_EMPTY,/* 81 */
+ MSG_SAVESTATE_FILE_BAD, /* 82 */
+ MSG_LOADSTATE_DOING,/* 83 */
+ MSG_LOADSTATE_FAILURE,/* 84 */
+ MSG_LOADSTATE_SUCCESS,/* 85 */
+
+ MSG_WARING_DIALOG, /* 86 */
+ MSG_TIME_FORMATE, /* 87 */
+
+ MSG_SUB_MENU_130, /* 88 */
+ MSG_SUB_MENU_131, /* 89 */
+
+ MSG_DELETTE_ALL_SAVESTATE_WARING,
+ MSG_DELETTE_SINGLE_SAVESTATE_WARING,
+ MSG_DELETTE_SAVESTATE_NOTHING,
+
+ MSG_SAVE_SNAPSHOT,
+ MSG_SAVE_SNAPSHOT_COMPLETE,
+ MSG_SAVE_SNAPSHOT_FAILURE,
+
+ MSG_CHANGE_LANGUAGE,
+ MSG_CHANGE_LANGUAGE_WAITING,
+
+ MSG_NO_SLIDE,
+ MSG_PLAYING_SLIDE,
+ MSG_PAUSE_SLIDE,
+ MSG_PLAY_SLIDE1,
+ MSG_PLAY_SLIDE2,
+ MSG_PLAY_SLIDE3,
+ MSG_PLAY_SLIDE4,
+ MSG_PLAY_SLIDE5,
+ MSG_PLAY_SLIDE6,
+
+ MSG_LOADING_GAME,
+
+ MSG_EMU_VERSION0,
+ MSG_EMU_VERSION1,
+
+ MSG_LOAD_DEFAULT_WARING,
+ MSG_DEFAULT_LOADING,
+
+ MSG_BACK,
+
+ MSG_END
+};
+
+enum LANGUAGE{
+ ENGLISH,
+ CHINESE_SIMPLIFIED,
+ CHINESE_TRADITIONAL
+};
+
+char *msg[MSG_END+1];
+char msg_data[16 * 1024];
+
+#endif //__MESSAGE_H__
+
diff --git a/source/netplay.cpp b/source/netplay.cpp
new file mode 100644
index 0000000..753f088
--- /dev/null
+++ b/source/netplay.cpp
@@ -0,0 +1,1048 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifdef NETPLAY_SUPPORT
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <memory.h>
+#include <sys/types.h>
+
+#ifndef __WIN32__
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#if defined (__WIN32__)
+#include <winsock.h>
+#include <process.h>
+
+#define ioctl ioctlsocket
+#define close closesocket
+#define read(a,b,c) recv(a, b, c, 0)
+#define write(a,b,c) send(a, b, c, 0)
+#else
+
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef __SVR4
+#include <sys/stropts.h>
+#endif
+#endif
+
+#ifdef USE_THREADS
+#include <pthread.h>
+#include <sched.h>
+#include <semaphore.h>
+#endif
+
+#include "snes9x.h"
+#include "cpuexec.h"
+#include "netplay.h"
+#include "memmap.h"
+#include "snapshot.h"
+#include "display.h"
+
+void S9xNPClientLoop (void *);
+bool8 S9xNPLoadROM (uint32 len);
+bool8 S9xNPLoadROMDialog (const char *);
+bool8 S9xNPGetROMImage (uint32 len);
+void S9xNPGetSRAMData (uint32 len);
+void S9xNPGetFreezeFile (uint32 len);
+
+unsigned long START = 0;
+
+bool8 S9xNPConnectToServer (const char *hostname, int port,
+ const char *rom_name)
+{
+ if (!S9xNPInitialise ())
+ return (FALSE);
+
+ S9xNPDisconnect ();
+
+ NetPlay.MySequenceNum = 0;
+ NetPlay.ServerSequenceNum = 0;
+ NetPlay.Connected = FALSE;
+ NetPlay.Abort = FALSE;
+ NetPlay.Player = 0;
+ NetPlay.Paused = FALSE;
+ NetPlay.PercentageComplete = 0;
+ NetPlay.Socket = 0;
+ if (NetPlay.ServerHostName)
+ free ((char *) NetPlay.ServerHostName);
+ NetPlay.ServerHostName = strdup (hostname);
+ if (NetPlay.ROMName)
+ free ((char *) NetPlay.ROMName);
+ NetPlay.ROMName = strdup (rom_name);
+ NetPlay.Port = port;
+ NetPlay.PendingWait4Sync = FALSE;
+
+#ifdef __WIN32__
+ if (GUI.ClientSemaphore == NULL)
+ GUI.ClientSemaphore = CreateSemaphore (NULL, 0, NP_JOYPAD_HIST_SIZE, NULL);
+
+ if (NetPlay.ReplyEvent == NULL)
+ NetPlay.ReplyEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ _beginthread (S9xNPClientLoop, 0, NULL);
+#endif
+
+ return (TRUE);
+}
+
+bool8 S9xNPConnect ()
+{
+ struct sockaddr_in address;
+ struct hostent *hostinfo;
+ unsigned int addr;
+
+ address.sin_family = AF_INET;
+ address.sin_port = htons (NetPlay.Port);
+#ifdef NP_DEBUG
+ printf ("CLIENT: Looking up server's hostname (%s) @%ld\n", NetPlay.ServerHostName, S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Looking up server's hostname...");
+ if ((int) (addr = inet_addr (NetPlay.ServerHostName)) == -1)
+ {
+ if ((hostinfo = gethostbyname (NetPlay.ServerHostName)))
+ {
+ memcpy ((char *)&address.sin_addr, hostinfo->h_addr,
+ hostinfo->h_length);
+ }
+ else
+ {
+ S9xNPSetError ("\
+Unable to look up server's IP address from hostname.\n\n\
+Unknown hostname or may be your nameserver isn't set\n\
+up correctly?");
+ return (FALSE);
+ }
+ }
+ else
+ {
+ memcpy ((char *)&address.sin_addr, &addr, sizeof (addr));
+ }
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Creating socket @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Creating network socket...");
+ if ((NetPlay.Socket = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ S9xNPSetError ("Creating network socket failed.");
+ return (FALSE);
+ }
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Trying to connect to server @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Trying to connect to Snes9X server...");
+
+ if (connect (NetPlay.Socket, (struct sockaddr *) &address, sizeof (address)) < 0)
+ {
+ char buf [100];
+#ifdef __WIN32__
+ if (WSAGetLastError () == WSAECONNREFUSED)
+#else
+ if (errno == ECONNREFUSED)
+#endif
+ {
+ S9xNPSetError ("\
+Connection to remote server socket refused:\n\n\
+Is there actually a Snes9X NetPlay server running\n\
+on the remote machine on this port?");
+ }
+ else
+ {
+ sprintf (buf, "Connection to server failed with error number %d",
+#ifdef __WIN32__
+ WSAGetLastError ()
+#else
+ errno
+#endif
+ );
+ S9xNPDisconnect ();
+ }
+ return (FALSE);
+ }
+ NetPlay.Connected = TRUE;
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Sending 'HELLO' message @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Sending 'HELLO' message...");
+ /* Send the server a HELLO packet*/
+ int len = 7 + 4 + strlen (NetPlay.ROMName) + 1;
+ uint8 *tmp = new uint8 [len];
+ uint8 *ptr = tmp;
+
+ *ptr++ = NP_CLNT_MAGIC;
+ *ptr++ = NetPlay.MySequenceNum++;
+ *ptr++ = NP_CLNT_HELLO;
+ WRITE_LONG (ptr, len);
+ ptr += 4;
+#ifdef __WIN32__
+ uint32 ft = Settings.FrameTime * 1000;
+
+ WRITE_LONG (ptr, ft);
+#else
+ WRITE_LONG (ptr, Settings.FrameTime);
+#endif
+ ptr += 4;
+ strcpy ((char *) ptr, NetPlay.ROMName);
+
+ if (!S9xNPSendData (NetPlay.Socket, tmp, len))
+ {
+ S9xNPSetError ("Sending 'HELLO' message failed.");
+ S9xNPDisconnect ();
+ delete tmp;
+ return (FALSE);
+ }
+ delete tmp;
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Waiting for 'WELCOME' reply from server @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Waiting for 'HELLO' reply from server...");
+
+ uint8 header [7];
+
+ if (!S9xNPGetData (NetPlay.Socket, header, 7) ||
+ header [0] != NP_SERV_MAGIC || header [1] != 0 ||
+ (header [2] & 0x1f) != NP_SERV_HELLO)
+ {
+ S9xNPSetError ("Error in 'HELLO' reply packet received from server.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+#ifdef NP_DEBUG
+ printf ("CLIENT: Got 'WELCOME' reply @%ld\n", S9xGetMilliTime () - START);
+#endif
+ len = READ_LONG (&header [3]);
+ if (len > 256)
+ {
+ S9xNPSetError ("Error in 'HELLO' reply packet received from server.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ uint8 *data = new uint8 [len];
+ if (!S9xNPGetData (NetPlay.Socket, data, len - 7))
+ {
+ S9xNPSetError ("Error in 'HELLO' reply packet received from server.");
+ delete data;
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+
+ if (data [0] != NP_VERSION)
+ {
+ S9xNPSetError ("\
+The Snes9X NetPlay server implements a different\n\
+version of the protocol. Disconnecting.");
+ delete data;
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+
+ NetPlay.FrameCount = READ_LONG (&data [2]);
+
+ if (!(header [2] & 0x80) &&
+ strcmp ((char *) data + 4 + 2, NetPlay.ROMName) != 0)
+ {
+ if (!S9xNPLoadROMDialog ((char *) data + 4 + 2))
+ {
+ delete data;
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ }
+ NetPlay.Player = data [1];
+ delete data;
+
+ NetPlay.PendingWait4Sync = TRUE;
+ Settings.NetPlay = TRUE;
+ S9xNPResetJoypadReadPos ();
+ NetPlay.ServerSequenceNum = 1;
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Sending 'READY' to server @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Sending 'READY' to the server...");
+
+ return (S9xNPSendReady ((header [2] & 0x80) ?
+ NP_CLNT_WAITING_FOR_ROM_IMAGE :
+ NP_CLNT_READY));
+}
+
+bool8 S9xNPSendReady (uint8 op)
+{
+ uint8 ready [7];
+ uint8 *ptr = ready;
+ *ptr++ = NP_CLNT_MAGIC;
+ *ptr++ = NetPlay.MySequenceNum++;
+ *ptr++ = op;
+ WRITE_LONG (ptr, 7);
+ ptr += 4;
+
+ if (!S9xNPSendData (NetPlay.Socket, ready, 7))
+ {
+ S9xNPDisconnect ();
+ S9xNPSetError ("Sending 'READY' message failed.");
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+bool8 S9xNPSendPause (bool8 paused)
+{
+#ifdef NP_DEBUG
+ printf ("CLIENT: Pause - %s @%ld\n", paused ? "YES" : "NO", S9xGetMilliTime () - START);
+#endif
+ uint8 pause [7];
+ uint8 *ptr = pause;
+ *ptr++ = NP_CLNT_MAGIC;
+ *ptr++ = NetPlay.MySequenceNum++;
+ *ptr++ = NP_CLNT_PAUSE | (paused ? 0x80 : 0);
+ WRITE_LONG (ptr, 7);
+ ptr += 4;
+
+ if (!S9xNPSendData (NetPlay.Socket, pause, 7))
+ {
+ S9xNPSetError ("Sending 'PAUSE' message failed.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+#ifdef __WIN32__
+void S9xNPClientLoop (void *)
+{
+ NetPlay.Waiting4EmulationThread = FALSE;
+
+ if (S9xNPConnect ())
+ {
+ S9xClearPause (PAUSE_NETPLAY_CONNECT);
+ while (NetPlay.Connected)
+ {
+ if (S9xNPWaitForHeartBeat ())
+ {
+ LONG prev;
+ if (!ReleaseSemaphore (GUI.ClientSemaphore, 1, &prev))
+ {
+#ifdef NP_DEBUG
+ printf ("CLIENT: ReleaseSemaphore failed - already hit max count (%d) %ld\n", NP_JOYPAD_HIST_SIZE, S9xGetMilliTime () - START);
+#endif
+ S9xNPSetWarning ("NetPlay: Client may be out of sync with server.");
+ }
+ else
+ {
+ if (!NetPlay.Waiting4EmulationThread &&
+ prev == (int) NetPlay.MaxBehindFrameCount)
+ {
+ NetPlay.Waiting4EmulationThread = TRUE;
+ S9xNPSendPause (TRUE);
+ }
+ }
+ }
+ else
+ S9xNPDisconnect ();
+ }
+ }
+ else
+ {
+ S9xClearPause (PAUSE_NETPLAY_CONNECT);
+ }
+#ifdef NP_DEBUG
+ printf ("CLIENT: Client thread exiting @%ld\n", S9xGetMilliTime () - START);
+#endif
+}
+#endif
+
+bool8 S9xNPWaitForHeartBeat ()
+{
+ uint8 header [3 + 4 + 4 * 5];
+
+ while (S9xNPGetData (NetPlay.Socket, header, 3 + 4))
+ {
+ if (header [0] != NP_SERV_MAGIC)
+ {
+ S9xNPSetError ("Bad magic value from server while waiting for heart-beat message\n");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ if (header [1] != NetPlay.ServerSequenceNum)
+ {
+ char buf [200];
+ sprintf (buf, "Unexpected message sequence number from server, expected %d, got %d\n", NetPlay.ServerSequenceNum, header [1]);
+ S9xNPSetWarning (buf);
+ NetPlay.ServerSequenceNum = header [1] + 1;
+ }
+ else
+ NetPlay.ServerSequenceNum++;
+
+ if ((header [2] & 0x1f) == NP_SERV_JOYPAD)
+ {
+ // Top 2 bits + 1 of opcode is joypad data count.
+ int num = (header [2] >> 6) + 1;
+
+ if (num)
+ {
+ if (!S9xNPGetData (NetPlay.Socket, header + 3 + 4, num * 4))
+ {
+ S9xNPSetError ("Error while receiving 'JOYPAD' message.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ }
+ NetPlay.Frame [NetPlay.JoypadWriteInd] = READ_LONG (&header [3]);
+
+ for (int i = 0; i < num; i++)
+ {
+ NetPlay.Joypads [NetPlay.JoypadWriteInd][i] =
+ READ_LONG (&header [3 + 4 + i * sizeof (uint32)]);
+ }
+ NetPlay.Paused = (header [2] & 0x20) != 0;
+
+ NetPlay.JoypadWriteInd = (NetPlay.JoypadWriteInd + 1) % NP_JOYPAD_HIST_SIZE;
+
+ if (NetPlay.JoypadWriteInd != (NetPlay.JoypadReadInd + 1) % NP_JOYPAD_HIST_SIZE)
+ {
+ //printf ("(%d)", (NetPlay.JoypadWriteInd - NetPlay.JoypadReadInd) % NP_JOYPAD_HIST_SIZE); fflush (stdout);
+ }
+//printf ("CLIENT: HB: @%d\n", S9xGetMilliTime () - START);
+ return (TRUE);
+ }
+ else
+ {
+ uint32 len = READ_LONG (&header [3]);
+ switch (header [2] & 0x1f)
+ {
+ case NP_SERV_RESET:
+#ifdef NP_DEBUG
+ printf ("CLIENT: RESET received @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPDiscardHeartbeats ();
+ S9xReset ();
+ NetPlay.FrameCount = READ_LONG (&header [3]);
+ S9xNPResetJoypadReadPos ();
+ S9xNPSendReady ();
+ break;
+ case NP_SERV_PAUSE:
+ NetPlay.Paused = (header [2] & 0x20) != 0;
+ break;
+ case NP_SERV_LOAD_ROM:
+#ifdef NP_DEBUG
+ printf ("CLIENT: LOAD_ROM received @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPDiscardHeartbeats ();
+ if (S9xNPLoadROM (len - 7))
+ S9xNPSendReady (NP_CLNT_LOADED_ROM);
+ break;
+ case NP_SERV_ROM_IMAGE:
+#ifdef NP_DEBUG
+ printf ("CLIENT: ROM_IMAGE received @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPDiscardHeartbeats ();
+ if (S9xNPGetROMImage (len - 7))
+ S9xNPSendReady (NP_CLNT_RECEIVED_ROM_IMAGE);
+ break;
+ case NP_SERV_SRAM_DATA:
+#ifdef NP_DEBUG
+ printf ("CLIENT: SRAM_DATA received @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPDiscardHeartbeats ();
+ S9xNPGetSRAMData (len - 7);
+ break;
+ case NP_SERV_FREEZE_FILE:
+#ifdef NP_DEBUG
+ printf ("CLIENT: FREEZE_FILE received @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPDiscardHeartbeats ();
+ S9xNPGetFreezeFile (len - 7);
+ S9xNPResetJoypadReadPos ();
+ S9xNPSendReady ();
+ break;
+ default:
+#ifdef NP_DEBUG
+ printf ("CLIENT: UNKNOWN received @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ }
+ }
+
+ S9xNPDisconnect ();
+ return (FALSE);
+}
+
+bool8 S9xNPLoadROMDialog (const char *rom_name)
+{
+ NetPlay.Answer = FALSE;
+
+#ifdef __WIN32__
+ ResetEvent (NetPlay.ReplyEvent);
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Asking GUI thread to open ROM load dialog...\n");
+#endif
+
+ PostMessage (GUI.hWnd, WM_USER + 3, (uint32) rom_name, (uint32) rom_name);
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Waiting for reply from GUI thread...\n");
+#endif
+
+ WaitForSingleObject (NetPlay.ReplyEvent, INFINITE);
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Got reply from GUI thread (%d)\n", NetPlay.Answer);
+#endif
+#endif
+
+ return (NetPlay.Answer);
+}
+
+bool8 S9xNPLoadROM (uint32 len)
+{
+ uint8 *data = new uint8 [len];
+
+ S9xNPSetAction ("Receiving ROM name...");
+ if (!S9xNPGetData (NetPlay.Socket, data, len))
+ {
+ S9xNPSetError ("Error while receiving ROM name.");
+ delete data;
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+
+ S9xNPSetAction ("Opening LoadROM dialog...");
+ if (!S9xNPLoadROMDialog ((char *) data))
+ {
+ S9xNPSetError ("Disconnected from NetPlay server because you are playing a different game!");
+ delete data;
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ delete data;
+ return (TRUE);
+}
+
+bool8 S9xNPGetROMImage (uint32 len)
+{
+ uint8 rom_info [5];
+
+ S9xNPSetAction ("Receiving ROM information...");
+ if (!S9xNPGetData (NetPlay.Socket, rom_info, 5))
+ {
+ S9xNPSetError ("Error while receiving ROM information.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ uint32 CalculatedSize = READ_LONG (&rom_info [1]);
+#ifdef NP_DEBUG
+ printf ("CLIENT: Hi-ROM: %s, Size: %04x\n", rom_info [0] ? "Y" : "N", CalculatedSize);
+#endif
+ if (CalculatedSize + 5 >= len ||
+ CalculatedSize >= CMemory::MAX_ROM_SIZE)
+ {
+ S9xNPSetError ("Size error in ROM image data received from server.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+
+ Memory.HiROM = rom_info [0];
+ Memory.LoROM = !Memory.HiROM;
+ Memory.HeaderCount = 0;
+ Memory.CalculatedSize = CalculatedSize;
+
+ // Load up ROM image
+#ifdef NP_DEBUG
+ printf ("CLIENT: Receiving ROM image @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Receiving ROM image...");
+ if (!S9xNPGetData (NetPlay.Socket, Memory.ROM, Memory.CalculatedSize))
+ {
+ S9xNPSetError ("Error while receiving ROM image from server.");
+ Settings.StopEmulation = TRUE;
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+#ifdef NP_DEBUG
+ printf ("CLIENT: Receiving ROM filename @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Receiving ROM filename...");
+ uint32 filename_len = len - Memory.CalculatedSize - 5;
+ if (filename_len > _MAX_PATH ||
+ !S9xNPGetData (NetPlay.Socket, (uint8 *) Memory.ROMFilename, filename_len))
+ {
+ S9xNPSetError ("Error while receiving ROM filename from server.");
+ S9xNPDisconnect ();
+ Settings.StopEmulation = TRUE;
+ return (FALSE);
+ }
+ Memory.InitROM (FALSE);
+ S9xReset ();
+ S9xNPResetJoypadReadPos ();
+ Settings.StopEmulation = FALSE;
+
+#ifdef __WIN32__
+ PostMessage (GUI.hWnd, WM_NULL, 0, 0);
+#endif
+
+ return (TRUE);
+}
+
+void S9xNPGetSRAMData (uint32 len)
+{
+ if (len > 0x10000)
+ {
+ S9xNPSetError ("Length error in S-RAM data received from server.");
+ S9xNPDisconnect ();
+ return;
+ }
+ S9xNPSetAction ("Receiving S-RAM data...");
+ if (len > 0 && !S9xNPGetData (NetPlay.Socket, ::SRAM, len))
+ {
+ S9xNPSetError ("Error while receiving S-RAM data from server.");
+ S9xNPDisconnect ();
+ }
+}
+
+void S9xNPGetFreezeFile (uint32 len)
+{
+ uint8 frame_count [4];
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Receiving freeze file information @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Receiving freeze file information...");
+ if (!S9xNPGetData (NetPlay.Socket, frame_count, 4))
+ {
+ S9xNPSetError ("Error while receiving freeze file information from server.");
+ S9xNPDisconnect ();
+ return;
+ }
+ NetPlay.FrameCount = READ_LONG (frame_count);
+
+#ifdef NP_DEBUG
+ printf ("CLIENT: Receiving freeze file @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Receiving freeze file...");
+ uint8 *data = new uint8 [len];
+ if (!S9xNPGetData (NetPlay.Socket, data, len - 4))
+ {
+ S9xNPSetError ("Error while receiving freeze file from server.");
+ S9xNPDisconnect ();
+ delete data;
+ return;
+ }
+
+ //FIXME: Setting umask here wouldn't hurt.
+ FILE *file;
+#ifdef HAVE_MKSTEMP
+ int fd;
+ char fname[] = "/tmp/snes9x_fztmpXXXXXX";
+ if ((fd = mkstemp(fname)) < 0)
+ {
+ if ((file = fdopen (fd, "wb")))
+#else
+ char fname [L_tmpnam];
+ if (tmpnam (fname))
+ {
+ if ((file = fopen (fname, "wb")))
+#endif
+ {
+ if (fwrite (data, 1, len, file) == len)
+ {
+ fclose(file);
+ if (!S9xUnfreezeGame (fname))
+ S9xNPSetError ("Unable to load freeze file just received.");
+ } else {
+ S9xNPSetError ("Failed to write to temporary freeze file.");
+ fclose (file);
+ }
+ } else
+ S9xNPSetError ("Failed to create temporary freeze file.");
+ remove (fname);
+ } else
+ S9xNPSetError ("Unable to get name for temporary freeze file.");
+ delete data;
+}
+
+uint32 S9xNPGetJoypad (int which1)
+{
+ if (Settings.NetPlay && which1 < 5)
+ return (NetPlay.Joypads [NetPlay.JoypadReadInd][which1]);
+
+ return (0);
+}
+
+void S9xNPStepJoypadHistory ()
+{
+ if ((NetPlay.JoypadReadInd + 1) % NP_JOYPAD_HIST_SIZE != NetPlay.JoypadWriteInd)
+ {
+ NetPlay.JoypadReadInd = (NetPlay.JoypadReadInd + 1) % NP_JOYPAD_HIST_SIZE;
+ if (NetPlay.FrameCount != NetPlay.Frame [NetPlay.JoypadReadInd])
+ {
+ S9xNPSetWarning ("This Snes9X session may be out of sync with the server.");
+#ifdef NP_DEBUG
+ printf ("*** CLIENT: client out of sync with server (%d, %d) @%ld\n", NetPlay.FrameCount, NetPlay.Frame [NetPlay.JoypadReadInd], S9xGetMilliTime () - START);
+#endif
+ }
+ }
+ else
+ {
+#ifdef NP_DEBUG
+ printf ("*** CLIENT: S9xNPStepJoypadHistory NOT OK@%ld\n", S9xGetMilliTime () - START);
+#endif
+ }
+}
+
+
+void S9xNPResetJoypadReadPos ()
+{
+#ifdef NP_DEBUG
+ printf ("CLIENT: ResetJoyReadPos @%ld\n", S9xGetMilliTime () - START); fflush (stdout);
+#endif
+ NetPlay.JoypadWriteInd = 0;
+ NetPlay.JoypadReadInd = NP_JOYPAD_HIST_SIZE - 1;
+ for (int h = 0; h < NP_JOYPAD_HIST_SIZE; h++)
+ memset ((void *) &NetPlay.Joypads [h], 0, sizeof (NetPlay.Joypads [0]));
+}
+
+bool8 S9xNPSendJoypadUpdate (uint32 joypad)
+{
+ uint8 data [7];
+ uint8 *ptr = data;
+
+ *ptr++ = NP_CLNT_MAGIC;
+ *ptr++ = NetPlay.MySequenceNum++;
+ *ptr++ = NP_CLNT_JOYPAD;
+
+ joypad |= 0x80000000;
+
+ WRITE_LONG (ptr, joypad);
+ if (!S9xNPSendData (NetPlay.Socket, data, 7))
+ {
+ S9xNPSetError ("Error while sending joypad data server.");
+ S9xNPDisconnect ();
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+void S9xNPDisconnect ()
+{
+ close (NetPlay.Socket);
+ NetPlay.Socket = -1;
+ NetPlay.Connected = FALSE;
+ Settings.NetPlay = FALSE;
+}
+
+bool8 S9xNPSendData (int socket, const uint8 *data, int length)
+{
+ int len = length;
+ const uint8 *ptr = data;
+
+ NetPlay.PercentageComplete = 0;
+
+ do
+ {
+ if (NetPlay.Abort)
+ return (FALSE);
+
+ int num_bytes = len;
+
+ // Write the data in small chunks, allowing this thread to spot an
+ // abort request from another thread.
+ if (num_bytes > 512)
+ num_bytes = 512;
+
+ int sent = write (socket, (char *) ptr, num_bytes);
+ if (sent < 0)
+ {
+ if (errno == EINTR
+#ifdef EAGAIN
+ || errno == EAGAIN
+#endif
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+ )
+ {
+#ifdef NP_DEBUG
+ printf ("CLIENT: EINTR, EAGAIN or EWOULDBLOCK while sending data @%ld\n", S9xGetMilliTime () - START);
+#endif
+ continue;
+ }
+ return (FALSE);
+ }
+ else
+ if (sent == 0)
+ return (FALSE);
+ len -= sent;
+ ptr += sent;
+
+ NetPlay.PercentageComplete = (uint8) (((length - len) * 100) / length);
+ } while (len > 0);
+
+ return (TRUE);
+}
+
+bool8 S9xNPGetData (int socket, uint8 *data, int length)
+{
+ int len = length;
+ uint8 *ptr = data;
+ int chunk = length / 50;
+
+ if (chunk < 1024)
+ chunk = 1024;
+
+ NetPlay.PercentageComplete = 0;
+ do
+ {
+ if (NetPlay.Abort)
+ return (FALSE);
+
+ int num_bytes = len;
+
+ // Read the data in small chunks, allowing this thread to spot an
+ // abort request from another thread.
+ if (num_bytes > chunk)
+ num_bytes = chunk;
+
+ int got = read (socket, (char *) ptr, num_bytes);
+ if (got < 0)
+ {
+ if (errno == EINTR
+#ifdef EAGAIN
+ || errno == EAGAIN
+#endif
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+#ifdef WSAEWOULDBLOCK
+ || errno == WSAEWOULDBLOCK
+#endif
+ )
+ {
+#ifdef NP_DEBUG
+ printf ("CLIENT: EINTR, EAGAIN or EWOULDBLOCK while receiving data @%ld\n", S9xGetMilliTime () - START);
+#endif
+ continue;
+ }
+#ifdef WSAEMSGSIZE
+ if (errno != WSAEMSGSIZE)
+ return (FALSE);
+ else
+ {
+ got = num_bytes;
+#ifdef NP_DEBUG
+ printf ("CLIENT: WSAEMSGSIZE, actual bytes %d while receiving data @%ld\n", got, S9xGetMilliTime () - START);
+#endif
+ }
+#else
+ return (FALSE);
+#endif
+ }
+ else
+ if (got == 0)
+ return (FALSE);
+
+ len -= got;
+ ptr += got;
+
+ if (!Settings.NetPlayServer && length > 1024)
+ {
+ NetPlay.PercentageComplete = (uint8) (((length - len) * 100) / length);
+#ifdef __WIN32__
+ PostMessage (GUI.hWnd, WM_USER, NetPlay.PercentageComplete,
+ NetPlay.PercentageComplete);
+ Sleep (0);
+#endif
+ }
+
+ } while (len > 0);
+
+ return (TRUE);
+}
+
+bool8 S9xNPInitialise ()
+{
+#ifdef __WIN32__
+ static bool8 initialised = FALSE;
+
+ if (!initialised)
+ {
+ initialised = TRUE;
+ WSADATA data;
+
+#ifdef NP_DEBUG
+ START = S9xGetMilliTime ();
+
+ printf ("CLIENT/SERVER: Initialising WinSock @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Initialising Windows sockets interface...");
+ if (WSAStartup (MAKEWORD (1, 0), &data) != 0)
+ {
+ S9xNPSetError ("Call to init Windows sockets failed. Do you have WinSock2 installed?");
+ return (FALSE);
+ }
+ }
+#endif
+ return (TRUE);
+}
+
+void S9xNPDiscardHeartbeats ()
+{
+ // Discard any pending heartbeats and wait for any frame that is currently
+ // being emulated to complete.
+#ifdef NP_DEBUG
+ printf ("CLIENT: DiscardHeartbeats @%ld, finished @", S9xGetMilliTime () - START);
+ fflush (stdout);
+#endif
+
+#ifdef __WIN32__
+ while (WaitForSingleObject (GUI.ClientSemaphore, 200) == WAIT_OBJECT_0)
+ ;
+#endif
+
+#ifdef NP_DEBUG
+ printf ("%ld\n", S9xGetMilliTime () - START);
+#endif
+ NetPlay.Waiting4EmulationThread = FALSE;
+}
+
+void S9xNPSetAction (const char *action, bool8 force)
+{
+ if (force || !Settings.NetPlayServer)
+ {
+ strncpy (NetPlay.ActionMsg, action, NP_MAX_ACTION_LEN - 1);
+ NetPlay.ActionMsg [NP_MAX_ACTION_LEN - 1] = 0;
+#ifdef __WIN32__
+ PostMessage (GUI.hWnd, WM_USER, 0, 0);
+ Sleep (0);
+#endif
+ }
+}
+
+void S9xNPSetError (const char *error)
+{
+ strncpy (NetPlay.ErrorMsg, error, NP_MAX_ACTION_LEN - 1);
+ NetPlay.ErrorMsg [NP_MAX_ACTION_LEN - 1] = 0;
+#ifdef __WIN32
+ PostMessage (GUI.hWnd, WM_USER + 1, 0, 0);
+ Sleep (0);
+#endif
+}
+
+void S9xNPSetWarning (const char *warning)
+{
+ strncpy (NetPlay.WarningMsg, warning, NP_MAX_ACTION_LEN - 1);
+ NetPlay.WarningMsg [NP_MAX_ACTION_LEN - 1] = 0;
+#ifdef __WIN32__
+ PostMessage (GUI.hWnd, WM_USER + 2, 0, 0);
+ Sleep (0);
+#endif
+}
+#endif
+
+
diff --git a/source/netplay.h b/source/netplay.h
new file mode 100644
index 0000000..fe7c66a
--- /dev/null
+++ b/source/netplay.h
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _NETPLAY_H_
+#define _NETPLAY_H_
+
+/*
+ * Client to server joypad update
+ *
+ * magic 1
+ * sequence_no 1
+ * opcode 1
+ * joypad data 4
+ *
+ * Server to client joypad update
+ * magic 1
+ * sequence_no 1
+ * opcode 1 + num joypads (top 3 bits)
+ * joypad data 4 * n
+ */
+
+//#define NP_DEBUG 1
+
+#define NP_VERSION 10
+#define NP_JOYPAD_HIST_SIZE 120
+#define NP_DEFAULT_PORT 6096
+
+#define NP_MAX_CLIENTS 5
+
+#define NP_SERV_MAGIC 'S'
+#define NP_CLNT_MAGIC 'C'
+
+#define NP_CLNT_HELLO 0
+#define NP_CLNT_JOYPAD 1
+#define NP_CLNT_RESET 2
+#define NP_CLNT_PAUSE 3
+#define NP_CLNT_LOAD_ROM 4
+#define NP_CLNT_ROM_IMAGE 5
+#define NP_CLNT_FREEZE_FILE 6
+#define NP_CLNT_SRAM_DATA 7
+#define NP_CLNT_READY 8
+#define NP_CLNT_LOADED_ROM 9
+#define NP_CLNT_RECEIVED_ROM_IMAGE 10
+#define NP_CLNT_WAITING_FOR_ROM_IMAGE 11
+
+#define NP_SERV_HELLO 0
+#define NP_SERV_JOYPAD 1
+#define NP_SERV_RESET 2
+#define NP_SERV_PAUSE 3
+#define NP_SERV_LOAD_ROM 4
+#define NP_SERV_ROM_IMAGE 5
+#define NP_SERV_FREEZE_FILE 6
+#define NP_SERV_SRAM_DATA 7
+#define NP_SERV_READY 8
+
+struct SNPClient
+{
+ volatile uint8 SendSequenceNum;
+ volatile uint8 ReceiveSequenceNum;
+ volatile bool8 Connected;
+ volatile bool8 SaidHello;
+ volatile bool8 Paused;
+ volatile bool8 Ready;
+ int Socket;
+ char *ROMName;
+ char *HostName;
+ char *Who;
+};
+
+enum {
+ NP_SERVER_SEND_ROM_IMAGE,
+ NP_SERVER_SYNC_ALL,
+ NP_SERVER_SYNC_CLIENT,
+ NP_SERVER_SEND_FREEZE_FILE_ALL,
+ NP_SERVER_SEND_ROM_LOAD_REQUEST_ALL,
+ NP_SERVER_RESET_ALL,
+ NP_SERVER_SEND_SRAM_ALL,
+ NP_SERVER_SEND_SRAM
+};
+
+#define NP_MAX_TASKS 20
+
+struct NPServerTask
+{
+ uint32 Task;
+ void *Data;
+};
+
+struct SNPServer
+{
+ struct SNPClient Clients [NP_MAX_CLIENTS];
+ int NumClients;
+ volatile struct NPServerTask TaskQueue [NP_MAX_TASKS];
+ volatile uint32 TaskHead;
+ volatile uint32 TaskTail;
+ int Socket;
+ uint32 FrameTime;
+ uint32 FrameCount;
+ char ROMName [30];
+ uint32 Joypads [5];
+ bool8 ClientPaused;
+ uint32 Paused;
+ bool8 SendROMImageOnConnect;
+ bool8 SyncByReset;
+};
+
+#define NP_MAX_ACTION_LEN 200
+
+struct SNetPlay
+{
+ volatile uint8 MySequenceNum;
+ volatile uint8 ServerSequenceNum;
+ volatile bool8 Connected;
+ volatile bool8 Abort;
+ volatile uint8 Player;
+ volatile bool8 ClientsReady [NP_MAX_CLIENTS];
+ volatile bool8 ClientsPaused [NP_MAX_CLIENTS];
+ volatile bool8 Paused;
+ volatile bool8 PendingWait4Sync;
+ volatile uint8 PercentageComplete;
+ volatile bool8 Waiting4EmulationThread;
+ volatile bool8 Answer;
+#ifdef __WIN32__
+ HANDLE ReplyEvent;
+#endif
+ volatile int Socket;
+ char *ServerHostName;
+ char *ROMName;
+ int Port;
+ volatile uint32 JoypadWriteInd;
+ volatile uint32 JoypadReadInd;
+ uint32 Joypads [NP_JOYPAD_HIST_SIZE][NP_MAX_CLIENTS];
+ uint32 Frame [NP_JOYPAD_HIST_SIZE];
+ uint32 FrameCount;
+ uint32 MaxFrameSkip;
+ uint32 MaxBehindFrameCount;
+ char ActionMsg [NP_MAX_ACTION_LEN];
+ char ErrorMsg [NP_MAX_ACTION_LEN];
+ char WarningMsg [NP_MAX_ACTION_LEN];
+};
+
+extern "C" struct SNetPlay NetPlay;
+
+//
+// NETPLAY_CLIENT_HELLO message format:
+// header
+// frame_time (4)
+// ROMName (variable)
+
+#define WRITE_LONG(p, v) { \
+*((p) + 0) = (uint8) ((v) >> 24); \
+*((p) + 1) = (uint8) ((v) >> 16); \
+*((p) + 2) = (uint8) ((v) >> 8); \
+*((p) + 3) = (uint8) ((v) >> 0); \
+}
+
+#define READ_LONG(p) \
+((((uint8) *((p) + 0)) << 24) | \
+ (((uint8) *((p) + 1)) << 16) | \
+ (((uint8) *((p) + 2)) << 8) | \
+ (((uint8) *((p) + 3)) << 0))
+
+bool8 S9xNPConnectToServer (const char *server_name, int port,
+ const char *rom_name);
+bool8 S9xNPWaitForHeartBeat ();
+uint32 S9xNPGetJoypad (int which1);
+bool8 S9xNPSendJoypadUpdate (uint32 joypad);
+void S9xNPDisconnect ();
+bool8 S9xNPInitialise ();
+bool8 S9xNPSendData (int fd, const uint8 *data, int len);
+bool8 S9xNPGetData (int fd, uint8 *data, int len);
+
+void S9xNPSyncClients ();
+void S9xNPStepJoypadHistory ();
+
+void S9xNPResetJoypadReadPos ();
+bool8 S9xNPSendReady (uint8 op = NP_CLNT_READY);
+bool8 S9xNPSendPause (bool8 pause);
+void S9xNPReset ();
+void S9xNPSetAction (const char *action, bool8 force = FALSE);
+void S9xNPSetError (const char *error);
+void S9xNPSetWarning (const char *warning);
+void S9xNPDiscardHeartbeats ();
+void S9xNPServerQueueSendingFreezeFile (const char *filename);
+void S9xNPServerQueueSyncAll ();
+void S9xNPServerQueueSendingROMImage ();
+void S9xNPServerQueueSendingLoadROMRequest (const char *filename);
+
+void S9xNPServerAddTask (uint32 task, void *data);
+
+bool8 S9xNPStartServer (int port);
+void S9xNPStopServer ();
+#ifdef __WIN32__
+#define S9xGetMilliTime timeGetTime
+#else
+uint32 S9xGetMilliTime ();
+#endif
+#endif
+
diff --git a/source/obc1.cpp b/source/obc1.cpp
new file mode 100644
index 0000000..763e7cc
--- /dev/null
+++ b/source/obc1.cpp
@@ -0,0 +1,204 @@
+/****************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <string.h>
+#include "memmap.h"
+#include "obc1.h"
+
+static uint8 *OBC1_RAM = NULL;
+
+int OBC1_Address;
+int OBC1_BasePtr;
+int OBC1_Shift;
+
+extern "C"
+{
+uint8 GetOBC1 (uint16 Address)
+{
+ switch(Address) {
+ case 0x7ff0:
+ return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)];
+
+ case 0x7ff1:
+ return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1];
+
+ case 0x7ff2:
+ return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2];
+
+ case 0x7ff3:
+ return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3];
+
+ case 0x7ff4:
+ return OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200];
+ }
+
+ return OBC1_RAM[Address & 0x1fff];
+}
+
+void SetOBC1 (uint8 Byte, uint16 Address)
+{
+ switch(Address) {
+ case 0x7ff0:
+ {
+ OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)] = Byte;
+ break;
+ }
+
+ case 0x7ff1:
+ {
+ OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1] = Byte;
+ break;
+ }
+
+ case 0x7ff2:
+ {
+ OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2] = Byte;
+ break;
+ }
+
+ case 0x7ff3:
+ {
+ OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3] = Byte;
+ break;
+ }
+
+ case 0x7ff4:
+ {
+ unsigned char Temp;
+
+ Temp = OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200];
+ Temp = (Temp & ~(3 << OBC1_Shift)) | ((Byte & 3) << OBC1_Shift);
+ OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200] = Temp;
+ break;
+ }
+
+ case 0x7ff5:
+ {
+ if (Byte & 1)
+ OBC1_BasePtr = 0x1800;
+ else
+ OBC1_BasePtr = 0x1c00;
+
+ OBC1_RAM[0x1ff5] = Byte;
+ break;
+ }
+
+ case 0x7ff6:
+ {
+ OBC1_Address = Byte & 0x7f;
+ OBC1_Shift = (Byte & 3) << 1;
+ break;
+ }
+
+ default:
+ OBC1_RAM[Address & 0x1fff] = Byte;
+ break;
+ }
+}
+
+uint8 *GetBasePointerOBC1(uint32 Address)
+{
+ return Memory.FillRAM;
+}
+
+uint8 *GetMemPointerOBC1(uint32 Address)
+{
+ return (Memory.FillRAM + (Address & 0xffff));
+}
+
+void ResetOBC1()
+{
+ OBC1_Address = 0;
+ OBC1_BasePtr = 0x1c00;
+ OBC1_Shift = 0;
+ OBC1_RAM = &Memory.FillRAM[0x6000];
+
+ memset(OBC1_RAM, 0x00, 0x2000);
+}
+
+}
diff --git a/source/obc1.h b/source/obc1.h
new file mode 100644
index 0000000..82ce89f
--- /dev/null
+++ b/source/obc1.h
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _OBC1_H_
+#define _OBC1_H_
+
+START_EXTERN_C
+uint8 GetOBC1 (uint16 Address);
+void SetOBC1 (uint8 Byte, uint16 Address);
+uint8 *GetBasePointerOBC1(uint32 Address);
+uint8 *GetMemPointerOBC1(uint32 Address);
+void ResetOBC1();//bool8 full);
+END_EXTERN_C
+
+#endif
+
diff --git a/source/offsets.cpp b/source/offsets.cpp
new file mode 100644
index 0000000..3438488
--- /dev/null
+++ b/source/offsets.cpp
@@ -0,0 +1,421 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "65c816.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "apu.h"
+#include "cpuexec.h"
+#include "sa1.h"
+
+#ifndef S9xSTREAM
+#define S9xSTREAM stdout
+#endif
+
+#define OFFSET(N,F) \
+fprintf (S9xSTREAM, "#define " #N " CPU + %d\n", (int) &((struct SCPUState *) 0)->F);
+#define OFFSET2(N,F) \
+fprintf (S9xSTREAM, "#define " #N " Registers + %d\n", (int) &((struct SRegisters *) 0)->F);
+#define OFFSET3(F) \
+fprintf (S9xSTREAM, "#define " #F " Memory + %d\n", (int) &((class CMemory *) 0)->F);
+#define OFFSET4(N,F) \
+fprintf (S9xSTREAM, "#define " #N " APU + %d\n", (int) &((struct SAPU *) 0)->F);
+#define OFFSET5(N,F) \
+fprintf (S9xSTREAM, "#define " #N " IAPU + %d\n", (int) &((struct SIAPU *) 0)->F);
+#define OFFSET6(N,F) \
+fprintf (S9xSTREAM, "#define " #N " ICPU + %d\n", (int) &((struct SICPU *) 0)->F);
+#define OFFSET7(N,F) \
+fprintf (S9xSTREAM, "#define " #N " Settings + %d\n", (int) &((struct SSettings *) 0)->F);
+#define OFFSET8(N, F) \
+fprintf (S9xSTREAM, "#define " #N " APURegisters + %d\n", (int) &((struct SAPURegisters *) 0)->F);
+
+#define OFFSET9(N, F) \
+fprintf (S9xSTREAM, "#define " #N " PPU + %d\n", (int) &((struct SPPU *) 0)->F);
+#define OFFSET10(N, F) \
+fprintf (S9xSTREAM, "#define " #N " IPPU + %d\n", (int) &((struct InternalPPU *) 0)->F);
+#define OFFSET11(N, F) \
+fprintf (S9xSTREAM, "#define " #N " SA1 + %d\n", (int) &((struct SSA1 *) 0)->F);
+#define OFFSET12(N, F) \
+fprintf (S9xSTREAM, "#define " #N " SA1Registers + %d\n", (int) &((struct SSA1Registers *) 0)->F);
+
+int main (int /*argc*/, char ** /*argv*/)
+{
+ OFFSET(Flags,Flags)
+ OFFSET(BranchSkip,BranchSkip)
+ OFFSET(NMIActive,NMIActive)
+ OFFSET(IRQActive,IRQActive)
+ OFFSET(WaitingForInterrupt,WaitingForInterrupt)
+ OFFSET(InDMA,InDMA)
+ OFFSET(WhichEvent,WhichEvent)
+ OFFSET(PCS,PC)
+ OFFSET(PCBase,PCBase)
+ OFFSET(PCAtOpcodeStart,PCAtOpcodeStart)
+ OFFSET(WaitAddress,WaitAddress)
+ OFFSET(WaitCounter,WaitCounter)
+ OFFSET(Cycles,Cycles)
+ OFFSET(NextEvent,NextEvent)
+ OFFSET(V_Counter,V_Counter)
+ OFFSET(MemSpeed,MemSpeed)
+ OFFSET(MemSpeedx2,MemSpeedx2)
+ OFFSET(FastROMSpeed,FastROMSpeed)
+ OFFSET(AutoSaveTimer,AutoSaveTimer)
+ OFFSET(SRAMModified,SRAMModified)
+ OFFSET(NMITriggerPoint,NMITriggerPoint)
+ OFFSET(TriedInterleavedMode2,TriedInterleavedMode2)
+ OFFSET(BRKTriggered,BRKTriggered)
+ OFFSET(NMICycleCount,NMICycleCount)
+ OFFSET(IRQCycleCount,IRQCycleCount)
+
+ OFFSET2(PB,PB)
+ OFFSET2(DB,DB)
+ OFFSET2(PP,P.W)
+ OFFSET2(PL,P.W)
+ fprintf (S9xSTREAM, "#define PH PL + 1\n");
+ OFFSET2(AA,A.W)
+ OFFSET2(AL,A.W)
+ fprintf (S9xSTREAM, "#define AH AL + 1\n");
+ OFFSET2(DD,D.W)
+ OFFSET2(DL,D.W)
+ fprintf (S9xSTREAM, "#define DH DL + 1\n");
+ OFFSET2(SS,S.W)
+ OFFSET2(SL,S.W)
+ fprintf (S9xSTREAM, "#define SH SL + 1\n");
+ OFFSET2(XX,X.W)
+ OFFSET2(XL,X.W)
+ fprintf (S9xSTREAM, "#define XH XL + 1\n");
+ OFFSET2(YY,Y.W)
+ OFFSET2(YL,Y.W)
+ fprintf (S9xSTREAM, "#define YH YL + 1\n");
+ OFFSET2(PCR, PC)
+
+ OFFSET3(RAM)
+ OFFSET3(ROM)
+ OFFSET3(VRAM)
+ OFFSET3(SRAM)
+ OFFSET3(BWRAM)
+ OFFSET3(FillRAM)
+ OFFSET3(C4RAM)
+ OFFSET3(HiROM)
+ OFFSET3(LoROM)
+ OFFSET3(SRAMMask)
+ OFFSET3(SRAMSize)
+ OFFSET3(Map)
+ OFFSET3(WriteMap)
+ OFFSET3(MemorySpeed)
+ OFFSET3(BlockIsRAM)
+ OFFSET3(BlockIsROM)
+ OFFSET3(ROMFilename)
+
+ OFFSET5(APUPCS,PC)
+ OFFSET5(APURAM,RAM)
+ OFFSET5(APUExecuting,APUExecuting)
+ OFFSET5(APUDirectPage,DirectPage)
+ OFFSET5(APUBit,Bit)
+ OFFSET5(APUAddress,Address)
+ OFFSET5(APUWaitAddress1,WaitAddress1)
+ OFFSET5(APUWaitAddress2,WaitAddress2)
+ OFFSET5(APUWaitCounter,WaitCounter)
+ OFFSET5(APUShadowRAM,ShadowRAM)
+ OFFSET5(APUCachedSamples,CachedSamples)
+ OFFSET5(APU_Carry,_Carry)
+ OFFSET5(APU_Zero,_Zero)
+ OFFSET5(APU_Overflow,_Overflow)
+ OFFSET5(APUTimerErrorCounter,TimerErrorCounter)
+
+ OFFSET4(APUCycles,Cycles)
+ OFFSET4(APUShowROM,ShowROM)
+ OFFSET4(APUFlags,Flags)
+ OFFSET4(APUKeyedChannels,KeyedChannels)
+ OFFSET4(APUOutPorts,OutPorts)
+ OFFSET4(APUDSP,DSP)
+ OFFSET4(APUExtraRAM,ExtraRAM)
+ OFFSET4(APUTimer,Timer)
+ OFFSET4(APUTimerTarget,TimerTarget)
+ OFFSET4(APUTimerEnabled,TimerEnabled)
+ OFFSET4(TimerValueWritten,TimerValueWritten)
+
+ OFFSET6(CPUSpeed,Speed)
+ OFFSET6(CPUOpcodes,S9xOpcodes)
+ OFFSET6(_Carry,_Carry)
+ OFFSET6(_Zero,_Zero)
+ OFFSET6(_Negative,_Negative)
+ OFFSET6(_Overflow,_Overflow)
+ OFFSET6(ShiftedDB,ShiftedDB)
+ OFFSET6(ShiftedPB,ShiftedPB)
+ OFFSET6(CPUExecuting,CPUExecuting)
+ OFFSET6(Scanline,Scanline)
+ OFFSET6(Frame,Frame)
+
+ OFFSET7(APUEnabled,APUEnabled)
+ OFFSET7(Shutdown,Shutdown)
+ OFFSET7(SoundSkipMethod,SoundSkipMethod)
+ OFFSET7(H_Max,H_Max)
+ OFFSET7(HBlankStart,HBlankStart)
+ OFFSET7(CyclesPercentage,CyclesPercentage)
+ OFFSET7(DisableIRQ,DisableIRQ)
+ OFFSET7(Paused,Paused)
+ OFFSET7(PAL,PAL)
+ OFFSET7(SoundSync,SoundSync)
+ OFFSET7(SA1Enabled,SA1)
+ OFFSET7(SuperFXEnabled,SuperFX)
+
+ OFFSET8(ApuP,P)
+ OFFSET8(ApuYA,YA.W)
+ OFFSET8(ApuA,YA.B.A)
+ OFFSET8(ApuY,YA.B.Y)
+ OFFSET8(ApuX,X)
+ OFFSET8(ApuS,S)
+ OFFSET8(ApuPC,PC)
+ OFFSET8(APUPCR,PC)
+
+ OFFSET9(BGMode,BGMode)
+ OFFSET9(BG3Priority,BG3Priority)
+ OFFSET9(Brightness,Brightness)
+ OFFSET9(GHight,VMA.High)
+ OFFSET9(GInc,VMA.Increment)
+ OFFSET9(GAddress,VMA.Address)
+ OFFSET9(GMask1,VMA.Mask1)
+ OFFSET9(GFullGraphicCount,VMA.FullGraphicCount)
+ OFFSET9(GShift,VMA.Shift)
+ OFFSET9(CGFLIP,CGFLIP)
+ OFFSET9(CGDATA,CGDATA)
+ OFFSET9(FirstSprite,FirstSprite)
+ OFFSET9(LastSprite,LastSprite)
+ OFFSET9(OBJ,OBJ)
+ OFFSET9(OAMPriorityRotation,OAMPriorityRotation)
+ OFFSET9(OAMAddr,OAMAddr)
+ OFFSET9(OAMFlip,OAMFlip)
+ OFFSET9(OAMTileAddress,OAMTileAddress)
+ OFFSET9(IRQVBeamPos,IRQVBeamPos)
+ OFFSET9(IRQHBeamPos,IRQHBeamPos)
+ OFFSET9(VBeamPosLatched,VBeamPosLatched)
+ OFFSET9(HBeamPosLatched,HBeamPosLatched)
+ OFFSET9(HBeamFlip,HBeamFlip)
+ OFFSET9(VBeamFlip,VBeamFlip)
+ OFFSET9(HVBeamCounterLatched,HVBeamCounterLatched)
+ OFFSET9(MatrixA,MatrixA)
+ OFFSET9(MatrixB,MatrixB)
+ OFFSET9(MatrixC,MatrixC)
+ OFFSET9(MatrixD,MatrixD)
+ OFFSET9(CentreX,CentreX)
+ OFFSET9(CentreY,CentreY)
+ OFFSET9(Joypad1ButtonReadPos,Joypad1ButtonReadPos)
+ OFFSET9(Joypad2ButtonReadPos,Joypad2ButtonReadPos)
+ OFFSET9(CGADD,CGADD)
+ OFFSET9(FixedColourGreen,FixedColourGreen)
+ OFFSET9(FixedColourRed,FixedColourRed)
+ OFFSET9(FixedColourBlue,FixedColourBlue)
+ OFFSET9(SavedOAMAddr,SavedOAMAddr)
+ OFFSET9(ScreenHeight,ScreenHeight)
+ OFFSET9(WRAM,WRAM)
+ OFFSET9(BG_Forced,BG_Forced)
+ OFFSET9(ForcedBlanking,ForcedBlanking)
+ OFFSET9(OBJThroughMain,OBJThroughMain)
+ OFFSET9(OBJThroughSub,OBJThroughSub)
+ OFFSET9(OBJSizeSelect,OBJSizeSelect)
+ OFFSET9(OBJNameBase,OBJNameBase)
+ OFFSET9(OAMReadFlip,OAMReadFlip)
+ OFFSET9(OAMData,OAMData)
+ OFFSET9(VTimerEnabled,VTimerEnabled)
+ OFFSET9(HTimerEnabled,HTimerEnabled)
+ OFFSET9(HTimerPosition,HTimerPosition)
+ OFFSET9(Mosaic,Mosaic)
+ OFFSET9(BGMosaic,BGMosaic)
+ OFFSET9(Mode7HFlip,Mode7HFlip)
+ OFFSET9(Mode7VFlip,Mode7VFlip)
+ OFFSET9(Mode7Repeat,Mode7Repeat)
+ OFFSET9(Window1Left,Window1Left)
+ OFFSET9(Window1Right,Window1Right)
+ OFFSET9(Window2Left,Window2Left)
+ OFFSET9(Window2Right,Window2Right)
+ OFFSET9(ClipWindowOverlapLogic,ClipWindowOverlapLogic)
+ OFFSET9(ClipWindow1Enable,ClipWindow1Enable)
+ OFFSET9(ClipWindow2Enable,ClipWindow2Enable)
+ OFFSET9(ClipWindow1Inside,ClipWindow1Inside)
+ OFFSET9(ClipWindow2Inside,ClipWindow2Inside)
+ OFFSET9(RecomputeClipWindows,RecomputeClipWindows)
+ OFFSET9(CGFLIPRead,CGFLIPRead)
+ OFFSET9(OBJNameSelect,OBJNameSelect)
+ OFFSET9(Need16x8Mulitply,Need16x8Mulitply)
+ OFFSET9(Joypad3ButtonReadPos,Joypad3ButtonReadPos)
+ OFFSET9(MouseSpeed,MouseSpeed)
+ OFFSET9(RangeTimeOver,RangeTimeOver)
+
+ OFFSET10(ColorsChanged,ColorsChanged)
+ OFFSET10(HDMA,HDMA)
+ OFFSET10(HDMAStarted,HDMAStarted)
+ OFFSET10(MaxBrightness,MaxBrightness)
+ OFFSET10(LatchedBlanking,LatchedBlanking)
+ OFFSET10(OBJChanged,OBJChanged)
+ OFFSET10(RenderThisFrame,RenderThisFrame)
+ OFFSET10(SkippedFrames,SkippedFrames)
+ OFFSET10(FrameSkip,FrameSkip)
+ OFFSET10(TileCache,TileCache)
+ OFFSET10(TileCached,TileCached)
+#ifdef CORRECT_VRAM_READS
+ OFFSET10(VRAMReadBuffer,VRAMReadBuffer)
+#else
+ OFFSET10(FirstVRAMRead,FirstVRAMRead)
+#endif
+ OFFSET10(Interlace,Interlace)
+ OFFSET10(DoubleWidthPixels,DoubleWidthPixels)
+ OFFSET10(RenderedScreenHeight,RenderedScreenHeight)
+ OFFSET10(RenderedScreenWidth,RenderedScreenWidth)
+ OFFSET10(Red,Red)
+ OFFSET10(Green,Green)
+ OFFSET10(Blue,Blue)
+ OFFSET10(XB,XB)
+ OFFSET10(ScreenColors,ScreenColors)
+ OFFSET10(PreviousLine,PreviousLine)
+ OFFSET10(CurrentLine,CurrentLine)
+ OFFSET10(Joypads,Joypads)
+ OFFSET10(SuperScope,SuperScope)
+ OFFSET10(Mouse,Mouse)
+ OFFSET10(PrevMouseX,PrevMouseX)
+ OFFSET10(PrevMouseY,PrevMouseY)
+ OFFSET10(Clip,Clip)
+
+ OFFSET11(SA1Opcodes,S9xOpcodes)
+ OFFSET11(SA1_Carry,_Carry)
+ OFFSET11(SA1_Zero,_Zero)
+ OFFSET11(SA1_Negative,_Negative)
+ OFFSET11(SA1_Overflow,_Overflow)
+ OFFSET11(SA1CPUExecuting,CPUExecuting)
+ OFFSET11(SA1ShiftedPB,ShiftedPB)
+ OFFSET11(SA1ShiftedDB,ShiftedDB)
+ OFFSET11(SA1Flags,Flags)
+ OFFSET11(SA1Executing,Executing)
+ OFFSET11(SA1NMIActive,NMIActive)
+ OFFSET11(SA1IRQActive,IRQActive)
+ OFFSET11(SA1WaitingForInterrupt,WaitingForInterrupt)
+ OFFSET11(SA1PCS,PC)
+ OFFSET11(SA1PCBase,PCBase)
+ OFFSET11(SA1PCAtOpcodeStart,PCAtOpcodeStart)
+ OFFSET11(SA1WaitAddress,WaitAddress)
+ OFFSET11(SA1WaitCounter,WaitCounter)
+ OFFSET11(SA1WaitByteAddress1,WaitByteAddress1)
+ OFFSET11(SA1WaitByteAddress2,WaitByteAddress2)
+ OFFSET11(SA1BWRAM,BWRAM)
+ OFFSET11(SA1Map,Map)
+ OFFSET11(SA1WriteMap,WriteMap)
+ OFFSET11(SA1op1,op1)
+ OFFSET11(SA1op2,op2)
+ OFFSET11(SA1arithmetic_op,arithmetic_op)
+ OFFSET11(SA1sum,sum)
+ OFFSET11(SA1overflow,overflow)
+ OFFSET11(VirtualBitmapFormat,VirtualBitmapFormat)
+ OFFSET11(SA1_in_char_dma,in_char_dma)
+ OFFSET11(SA1variable_bit_pos,variable_bit_pos)
+
+ OFFSET12(SA1PB,PB)
+ OFFSET12(SA1DB,DB)
+ OFFSET12(SA1PP,P.W)
+ OFFSET12(SA1PL,P.W)
+ fprintf (S9xSTREAM, "#define SA1PH SA1PL + 1\n");
+ OFFSET12(SA1AA,A.W)
+ OFFSET12(SA1AL,A.W)
+ fprintf (S9xSTREAM, "#define SA1AH SA1AL + 1\n");
+ OFFSET12(SA1DD,D.W)
+ OFFSET12(SA1DL,D.W)
+ fprintf (S9xSTREAM, "#define SA1DH SA1DL + 1\n");
+ OFFSET12(SA1SS,S.W)
+ OFFSET12(SA1SL,S.W)
+ fprintf (S9xSTREAM, "#define SA1SH SA1SL + 1\n");
+ OFFSET12(SA1XX,X.W)
+ OFFSET12(SA1XL,X.W)
+ fprintf (S9xSTREAM, "#define SA1XH SA1XL + 1\n");
+ OFFSET12(SA1YY,Y.W)
+ OFFSET12(SA1YL,Y.W)
+ fprintf (S9xSTREAM, "#define SA1YH SA1YL + 1\n");
+ OFFSET12(SA1PCR, PC)
+
+ return (0);
+}
+
diff --git a/source/pixform.h b/source/pixform.h
new file mode 100644
index 0000000..45cf651
--- /dev/null
+++ b/source/pixform.h
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _PIXFORM_H_
+#define _PIXFORM_H_
+
+#ifdef GFX_MULTI_FORMAT
+
+enum { RGB565, RGB555, BGR565, BGR555, GBR565, GBR555, RGB5551 };
+
+#define BUILD_PIXEL(R,G,B) ((*GFX.BuildPixel) (R, G, B))
+#define BUILD_PIXEL2(R,G,B) ((*GFX.BuildPixel2) (R, G, B))
+#define DECOMPOSE_PIXEL(Pixel,R,G,B) ((*GFX.DecomposePixel) (Pixel, R,G,B))
+
+extern uint32 RED_LOW_BIT_MASK;
+extern uint32 GREEN_LOW_BIT_MASK;
+extern uint32 BLUE_LOW_BIT_MASK;
+extern uint32 RED_HI_BIT_MASK;
+extern uint32 GREEN_HI_BIT_MASK;
+extern uint32 BLUE_HI_BIT_MASK;
+extern uint32 MAX_RED;
+extern uint32 MAX_GREEN;
+extern uint32 MAX_BLUE;
+extern uint32 SPARE_RGB_BIT_MASK;
+extern uint32 GREEN_HI_BIT;
+extern uint32 RGB_LOW_BITS_MASK;
+extern uint32 RGB_HI_BITS_MASK;
+extern uint32 RGB_HI_BITS_MASKx2;
+extern uint32 RGB_REMOVE_LOW_BITS_MASK;
+extern uint32 FIRST_COLOR_MASK;
+extern uint32 SECOND_COLOR_MASK;
+extern uint32 THIRD_COLOR_MASK;
+extern uint32 ALPHA_BITS_MASK;
+extern uint32 FIRST_THIRD_COLOR_MASK;
+extern uint32 TWO_LOW_BITS_MASK;
+extern uint32 HIGH_BITS_SHIFTED_TWO_MASK;
+
+#endif
+
+/* RGB565 format */
+#define BUILD_PIXEL_RGB565(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) (B))
+#define BUILD_PIXEL2_RGB565(R,G,B) (((int) (R) << 11) | ((int) (G) << 5) | (int) (B))
+#define DECOMPOSE_PIXEL_RGB565(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = (PIX) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_RGB565 (1 << 5)
+
+#define MAX_RED_RGB565 31
+#define MAX_GREEN_RGB565 63
+#define MAX_BLUE_RGB565 31
+#define RED_LOW_BIT_MASK_RGB565 0x0800
+#define GREEN_LOW_BIT_MASK_RGB565 0x0020
+#define BLUE_LOW_BIT_MASK_RGB565 0x0001
+#define RED_HI_BIT_MASK_RGB565 0x8000
+#define GREEN_HI_BIT_MASK_RGB565 0x0400
+#define BLUE_HI_BIT_MASK_RGB565 0x0010
+#define FIRST_COLOR_MASK_RGB565 0xF800
+#define SECOND_COLOR_MASK_RGB565 0x07E0
+#define THIRD_COLOR_MASK_RGB565 0x001F
+#define ALPHA_BITS_MASK_RGB565 0x0000
+
+/* RGB555 format */
+#define BUILD_PIXEL_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B))
+#define BUILD_PIXEL2_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B))
+#define DECOMPOSE_PIXEL_RGB555(PIX,R,G,B) {(R) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (B) = (PIX) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_RGB555 (1 << 15)
+
+#define MAX_RED_RGB555 31
+#define MAX_GREEN_RGB555 31
+#define MAX_BLUE_RGB555 31
+#define RED_LOW_BIT_MASK_RGB555 0x0400
+#define GREEN_LOW_BIT_MASK_RGB555 0x0020
+#define BLUE_LOW_BIT_MASK_RGB555 0x0001
+#define RED_HI_BIT_MASK_RGB555 0x4000
+#define GREEN_HI_BIT_MASK_RGB555 0x0200
+#define BLUE_HI_BIT_MASK_RGB555 0x0010
+#define FIRST_COLOR_MASK_RGB555 0x7C00
+#define SECOND_COLOR_MASK_RGB555 0x03E0
+#define THIRD_COLOR_MASK_RGB555 0x001F
+#define ALPHA_BITS_MASK_RGB555 0x0000
+
+/* BGR565 format */
+#define BUILD_PIXEL_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 6) | (int) (R))
+#define BUILD_PIXEL2_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 5) | (int) (R))
+#define DECOMPOSE_PIXEL_BGR565(PIX,R,G,B) {(B) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_BGR565 (1 << 5)
+
+#define MAX_RED_BGR565 31
+#define MAX_GREEN_BGR565 63
+#define MAX_BLUE_BGR565 31
+#define RED_LOW_BIT_MASK_BGR565 0x0001
+#define GREEN_LOW_BIT_MASK_BGR565 0x0040
+#define BLUE_LOW_BIT_MASK_BGR565 0x0800
+#define RED_HI_BIT_MASK_BGR565 0x0010
+#define GREEN_HI_BIT_MASK_BGR565 0x0400
+#define BLUE_HI_BIT_MASK_BGR565 0x8000
+#define FIRST_COLOR_MASK_BGR565 0xF800
+#define SECOND_COLOR_MASK_BGR565 0x07E0
+#define THIRD_COLOR_MASK_BGR565 0x001F
+#define ALPHA_BITS_MASK_BGR565 0x0000
+
+/* BGR555 format */
+#define BUILD_PIXEL_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R))
+#define BUILD_PIXEL2_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R))
+#define DECOMPOSE_PIXEL_BGR555(PIX,R,G,B) {(B) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_BGR555 (1 << 15)
+
+#define MAX_RED_BGR555 31
+#define MAX_GREEN_BGR555 31
+#define MAX_BLUE_BGR555 31
+#define RED_LOW_BIT_MASK_BGR555 0x0001
+#define GREEN_LOW_BIT_MASK_BGR555 0x0020
+#define BLUE_LOW_BIT_MASK_BGR555 0x0400
+#define RED_HI_BIT_MASK_BGR555 0x0010
+#define GREEN_HI_BIT_MASK_BGR555 0x0200
+#define BLUE_HI_BIT_MASK_BGR555 0x4000
+#define FIRST_COLOR_MASK_BGR555 0x7C00
+#define SECOND_COLOR_MASK_BGR555 0x03E0
+#define THIRD_COLOR_MASK_BGR555 0x001F
+#define ALPHA_BITS_MASK_BGR555 0x0000
+
+/* GBR565 format */
+#define BUILD_PIXEL_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 6) | (int) (R))
+#define BUILD_PIXEL2_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 5) | (int) (R))
+#define DECOMPOSE_PIXEL_GBR565(PIX,R,G,B) {(G) = (PIX) >> 11; (B) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_GBR565 (1 << 5)
+
+#define MAX_RED_GBR565 31
+#define MAX_BLUE_GBR565 63
+#define MAX_GREEN_GBR565 31
+#define RED_LOW_BIT_MASK_GBR565 0x0001
+#define BLUE_LOW_BIT_MASK_GBR565 0x0040
+#define GREEN_LOW_BIT_MASK_GBR565 0x0800
+#define RED_HI_BIT_MASK_GBR565 0x0010
+#define BLUE_HI_BIT_MASK_GBR565 0x0400
+#define GREEN_HI_BIT_MASK_GBR565 0x8000
+#define FIRST_COLOR_MASK_GBR565 0xF800
+#define SECOND_COLOR_MASK_GBR565 0x07E0
+#define THIRD_COLOR_MASK_GBR565 0x001F
+#define ALPHA_BITS_MASK_GBR565 0x0000
+
+/* GBR555 format */
+#define BUILD_PIXEL_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R))
+#define BUILD_PIXEL2_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R))
+#define DECOMPOSE_PIXEL_GBR555(PIX,R,G,B) {(G) = (PIX) >> 10; (B) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_GBR555 (1 << 15)
+
+#define MAX_RED_GBR555 31
+#define MAX_BLUE_GBR555 31
+#define MAX_GREEN_GBR555 31
+#define RED_LOW_BIT_MASK_GBR555 0x0001
+#define BLUE_LOW_BIT_MASK_GBR555 0x0020
+#define GREEN_LOW_BIT_MASK_GBR555 0x0400
+#define RED_HI_BIT_MASK_GBR555 0x0010
+#define BLUE_HI_BIT_MASK_GBR555 0x0200
+#define GREEN_HI_BIT_MASK_GBR555 0x4000
+#define FIRST_COLOR_MASK_GBR555 0x7C00
+#define SECOND_COLOR_MASK_GBR555 0x03E0
+#define THIRD_COLOR_MASK_GBR555 0x001F
+#define ALPHA_BITS_MASK_GBR555 0x0000
+
+/* RGB5551 format */
+#define BUILD_PIXEL_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1)
+#define BUILD_PIXEL2_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1)
+#define DECOMPOSE_PIXEL_RGB5551(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = ((PIX) >> 1) & 0x1f; }
+#define SPARE_RGB_BIT_MASK_RGB5551 (1)
+
+#define MAX_RED_RGB5551 31
+#define MAX_GREEN_RGB5551 31
+#define MAX_BLUE_RGB5551 31
+#define RED_LOW_BIT_MASK_RGB5551 0x0800
+#define GREEN_LOW_BIT_MASK_RGB5551 0x0040
+#define BLUE_LOW_BIT_MASK_RGB5551 0x0002
+#define RED_HI_BIT_MASK_RGB5551 0x8000
+#define GREEN_HI_BIT_MASK_RGB5551 0x0400
+#define BLUE_HI_BIT_MASK_RGB5551 0x0020
+#define FIRST_COLOR_MASK_RGB5551 0xf800
+#define SECOND_COLOR_MASK_RGB5551 0x07c0
+#define THIRD_COLOR_MASK_RGB5551 0x003e
+#define ALPHA_BITS_MASK_RGB5551 0x0001
+
+#ifndef GFX_MULTI_FORMAT
+#define CONCAT(X,Y) X##Y
+
+/* C pre-processor needs a two stage macro define to enable it to concat
+ * to macro names together to form the name of another macro. */
+#define BUILD_PIXEL_D(F,R,G,B) CONCAT(BUILD_PIXEL_,F) (R,G,B)
+#define BUILD_PIXEL2_D(F,R,G,B) CONCAT(BUILD_PIXEL2_,F) (R,G,B)
+#define DECOMPOSE_PIXEL_D(F,PIX,R,G,B) CONCAT(DECOMPOSE_PIXEL_,F) (PIX,R,G,B)
+
+#define BUILD_PIXEL(R,G,B) BUILD_PIXEL_D(PIXEL_FORMAT,R,G,B)
+#define BUILD_PIXEL2(R,G,B) BUILD_PIXEL2_D(PIXEL_FORMAT,R,G,B)
+#define DECOMPOSE_PIXEL(PIX,R,G,B) DECOMPOSE_PIXEL_D(PIXEL_FORMAT,PIX,R,G,B)
+
+#define MAX_RED_D(F) CONCAT(MAX_RED_,F)
+#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F)
+#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F)
+#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F)
+#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F)
+#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F)
+#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F)
+#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F)
+#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F)
+#define FIRST_COLOR_MASK_D(F) CONCAT(FIRST_COLOR_MASK_,F)
+#define SECOND_COLOR_MASK_D(F) CONCAT(SECOND_COLOR_MASK_,F)
+#define THIRD_COLOR_MASK_D(F) CONCAT(THIRD_COLOR_MASK_,F)
+#define ALPHA_BITS_MASK_D(F) CONCAT(ALPHA_BITS_MASK_,F)
+
+#define MAX_RED MAX_RED_D(PIXEL_FORMAT)
+#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT)
+#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT)
+#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT)
+#define BLUE_LOW_BIT_MASK BLUE_LOW_BIT_MASK_D(PIXEL_FORMAT)
+#define GREEN_LOW_BIT_MASK GREEN_LOW_BIT_MASK_D(PIXEL_FORMAT)
+#define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT)
+#define BLUE_HI_BIT_MASK BLUE_HI_BIT_MASK_D(PIXEL_FORMAT)
+#define GREEN_HI_BIT_MASK GREEN_HI_BIT_MASK_D(PIXEL_FORMAT)
+#define FIRST_COLOR_MASK FIRST_COLOR_MASK_D(PIXEL_FORMAT)
+#define SECOND_COLOR_MASK SECOND_COLOR_MASK_D(PIXEL_FORMAT)
+#define THIRD_COLOR_MASK THIRD_COLOR_MASK_D(PIXEL_FORMAT)
+#define ALPHA_BITS_MASK ALPHA_BITS_MASK_D(PIXEL_FORMAT)
+
+#define GREEN_HI_BIT ((MAX_GREEN + 1) >> 1)
+#define RGB_LOW_BITS_MASK (RED_LOW_BIT_MASK | GREEN_LOW_BIT_MASK | \
+ BLUE_LOW_BIT_MASK)
+#define RGB_HI_BITS_MASK (RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \
+ BLUE_HI_BIT_MASK)
+#define RGB_HI_BITS_MASKx2 ((RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \
+ BLUE_HI_BIT_MASK) << 1)
+#define RGB_REMOVE_LOW_BITS_MASK (~RGB_LOW_BITS_MASK)
+#define FIRST_THIRD_COLOR_MASK (FIRST_COLOR_MASK | THIRD_COLOR_MASK)
+#define TWO_LOW_BITS_MASK (RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1))
+#define HIGH_BITS_SHIFTED_TWO_MASK (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \
+ ~TWO_LOW_BITS_MASK ) >> 2)
+#endif
+
+#endif
+
diff --git a/source/port.h b/source/port.h
new file mode 100644
index 0000000..ac241b6
--- /dev/null
+++ b/source/port.h
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _PORT_H_
+#define _PORT_H_
+
+#include <limits.h>
+
+#ifndef STORM
+#include <memory.h>
+#include <string.h>
+#else
+#include <strings.h>
+#include <clib/powerpc_protos.h>
+#endif
+
+#ifndef ACCEPT_SIZE_T
+#ifdef __WIN32__
+#define ACCEPT_SIZE_T int
+#else
+#define ACCEPT_SIZE_T unsigned int
+#endif
+#endif
+
+#include <sys/types.h>
+
+/* #define PIXEL_FORMAT RGB565 */
+#define PIXEL_FORMAT BGR555
+// #define GFX_MULTI_FORMAT
+
+#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
+
+#include "zlib.h"
+#define ZLIB
+#define EXECUTE_SUPERFX_PER_LINE
+#define SOUND
+#define VAR_CYCLES
+#define CPU_SHUTDOWN
+#define SPC700_SHUTDOWN
+#define PIXEL_FORMAT RGB555
+#define CHECK_SOUND()
+#define M_PI 3.14159265359
+#undef _MAX_PATH
+
+#undef DEBUGGER /* Apple Universal Headers sometimes #define DEBUGGER */
+#undef GFX_MULTI_FORMAT
+
+int strncasecmp(const char *s1, const char *s2, unsigned n);
+int strcasecmp(const char *s1, const char *s2 );
+
+#endif /* TARGET_OS_MAC */
+
+#ifndef NOASM
+#define USE_X86_ASM
+#endif
+
+#ifndef snes9x_types_defined
+#define snes9x_types_defined
+
+typedef unsigned char bool8;
+
+/* FIXME: Refactor this by moving out the BORLAND part and unifying typedefs */
+#ifndef __WIN32__
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+typedef unsigned int uint32;
+# ifdef __GNUC__ /* long long is not part of ISO C++ */
+__extension__
+# endif
+typedef long long int64;
+#else /* __WIN32__ */
+
+# ifdef __BORLANDC__
+# include <systypes.h>
+# else
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef signed char int8;
+typedef short int16;
+
+# ifndef WSAAPI
+/* winsock2.h typedefs int32 as well. */
+typedef long int32;
+
+# define PLAT_SOUND_BUFFER SoundBuffer
+# define RIGHTSHIFT_IS_SAR
+# endif
+
+typedef unsigned int uint32;
+
+# endif /* __BORLANDC__ */
+
+typedef __int64 int64;
+
+#endif /* __WIN32__ */
+#endif /* snes9x_types_defined */
+
+
+#include "pixform.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef STORM
+#define EXTERN_C
+#define START_EXTERN_C
+#define END_EXTERN_C
+#else
+#if defined(__cplusplus) || defined(c_plusplus)
+#define EXTERN_C extern "C"
+#define START_EXTERN_C extern "C" {
+#define END_EXTERN_C }
+#else
+#define EXTERN_C extern
+#define START_EXTERN_C
+#define END_EXTERN_C
+#endif
+#endif
+
+#ifndef __WIN32__
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#define _MAX_DIR PATH_MAX
+#define _MAX_DRIVE 1
+#define _MAX_FNAME PATH_MAX
+#define _MAX_EXT PATH_MAX
+#define _MAX_PATH PATH_MAX
+
+#define ZeroMemory(a,b) memset((a),0,(b))
+
+void _makepath (char *path, const char *drive, const char *dir,
+ const char *fname, const char *ext);
+void _splitpath (const char *path, char *drive, char *dir, char *fname,
+ char *ext);
+#else /* __WIN32__ */
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
+
+EXTERN_C void S9xGenerateSound ();
+
+#ifdef STORM
+EXTERN_C int soundsignal;
+EXTERN_C void MixSound(void);
+/* Yes, CHECK_SOUND is getting defined correctly! */
+#define CHECK_SOUND if (Settings.APUEnabled) if(SetSignalPPC(0L, soundsignal) & soundsignal) MixSound
+#else
+#define CHECK_SOUND()
+#endif
+
+#ifdef __DJGPP
+#define SLASH_STR "/"
+#define SLASH_CHAR '/'
+#else
+#define SLASH_STR "/"
+#define SLASH_CHAR '/'
+#endif
+
+/* Taken care of in signal.h on Linux.
+ * #ifdef __linux
+ * typedef void (*SignalHandler)(int);
+ * #define SIG_PF SignalHandler
+ * #endif
+ */
+
+/* If including signal.h, do it before snes9.h and port.h to avoid clashes. */
+#ifndef SIG_PF
+#define SIG_PF void(*)(int)
+#endif
+
+#if defined(__i386__) || defined(__i486__) || defined(__i586__) || \
+ defined(__WIN32__) || defined(__alpha__)
+#define LSB_FIRST
+#define FAST_LSB_WORD_ACCESS
+#else
+//#define MSB_FIRST
+#define LSB_FIRST
+//#define FAST_LSB_WORD_ACCESS
+#endif
+
+#ifdef __sun
+#define TITLE "Snes9X: Solaris"
+#endif
+
+#ifdef __linux
+#define TITLE "Snes9X: Linux"
+#endif
+
+#ifndef TITLE
+#define TITLE "Snes9x"
+#endif
+
+#ifdef STORM
+#define STATIC
+#define strncasecmp strnicmp
+#else
+#define STATIC static
+#endif
+
+#endif
+
diff --git a/source/ppu.cpp b/source/ppu.cpp
new file mode 100644
index 0000000..fc0bd51
--- /dev/null
+++ b/source/ppu.cpp
@@ -0,0 +1,3299 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "missing.h"
+#include "apu.h"
+#include "dma.h"
+#include "gfx.h"
+#include "display.h"
+#include "sa1.h"
+#include "netplay.h"
+#include "sdd1.h"
+#include "srtc.h"
+#include "spc7110.h"
+#include "movie.h"
+
+#ifndef ZSNES_FX
+#include "fxemu.h"
+#include "fxinst.h"
+extern struct FxInit_s SuperFX;
+#else
+EXTERN_C void S9xSuperFXWriteReg (uint8, uint32);
+EXTERN_C uint8 S9xSuperFXReadReg (uint32);
+#endif
+
+uint32 justifiers=0xFFFF00AA;
+uint8 in_bit=0;
+
+extern uint8 *HDMAMemPointers [8];
+
+static inline void S9xLatchCounters (bool force)
+{
+ if(!force && !(Memory.FillRAM[0x4213] & 0x80)) return;
+
+ // Latch h and v counters, like the gun
+#ifdef DEBUGGER
+ missing.h_v_latch = 1;
+#endif
+#if 0
+# ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+# endif
+#endif
+ PPU.HVBeamCounterLatched = 1;
+ PPU.VBeamPosLatched = (uint16) CPU.V_Counter;
+ PPU.HBeamPosLatched = (uint16) ((CPU.Cycles * SNES_HCOUNTER_MAX) / Settings.H_Max);
+
+ // Causes screen flicker for Yoshi's Island if uncommented
+ //CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);
+
+ Memory.FillRAM [0x213F] |= 0x40;
+}
+
+void S9xUpdateJustifiers();
+
+void S9xUpdateHTimer ()
+{
+ if (PPU.HTimerEnabled)
+ {
+#ifdef DEBUGGER
+ missing.hirq_pos = PPU.IRQHBeamPos;
+#endif
+ PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX;
+ if (PPU.HTimerPosition == Settings.H_Max ||
+ PPU.HTimerPosition == Settings.HBlankStart)
+ {
+ PPU.HTimerPosition--;
+ }
+
+ if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos)
+ {
+ if (PPU.HTimerPosition < CPU.Cycles)
+ {
+ // Missed the IRQ on this line already
+ if (CPU.WhichEvent == HBLANK_END_EVENT ||
+ CPU.WhichEvent == HTIMER_AFTER_EVENT)
+ {
+ CPU.WhichEvent = HBLANK_END_EVENT;
+ CPU.NextEvent = Settings.H_Max;
+ }
+ else
+ {
+ CPU.WhichEvent = HBLANK_START_EVENT;
+ CPU.NextEvent = Settings.HBlankStart;
+ }
+ }
+ else
+ {
+ if (CPU.WhichEvent == HTIMER_BEFORE_EVENT ||
+ CPU.WhichEvent == HBLANK_START_EVENT)
+ {
+ if (PPU.HTimerPosition > Settings.HBlankStart)
+ {
+ // HTimer was to trigger before h-blank start,
+ // now triggers after start of h-blank
+ CPU.NextEvent = Settings.HBlankStart;
+ CPU.WhichEvent = HBLANK_START_EVENT;
+ }
+ else
+ {
+ CPU.NextEvent = PPU.HTimerPosition;
+ CPU.WhichEvent = HTIMER_BEFORE_EVENT;
+ }
+ }
+ else
+ {
+ CPU.WhichEvent = HTIMER_AFTER_EVENT;
+ CPU.NextEvent = PPU.HTimerPosition;
+ }
+ }
+ }
+ }
+}
+
+void S9xFixColourBrightness ()
+{
+ IPPU.XB = mul_brightness [PPU.Brightness];
+ if (Settings.SixteenBit)
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ IPPU.Red [i] = IPPU.XB [PPU.CGDATA [i] & 0x1f];
+ IPPU.Green [i] = IPPU.XB [(PPU.CGDATA [i] >> 5) & 0x1f];
+ IPPU.Blue [i] = IPPU.XB [(PPU.CGDATA [i] >> 10) & 0x1f];
+ IPPU.ScreenColors [i] = BUILD_PIXEL (IPPU.Red [i], IPPU.Green [i],
+ IPPU.Blue [i]);
+ }
+ }
+}
+
+/******************************************************************************/
+/* S9xSetPPU() */
+/* This function sets a PPU Register to a specific byte */
+/******************************************************************************/
+void S9xSetPPU (uint8 Byte, uint16 Address)
+{
+// fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, Byte, Address);
+ if (Address <= 0x2183)
+ {
+ switch (Address)
+ {
+ case 0x2100:
+ // Brightness and screen blank bit
+ if (Byte != Memory.FillRAM [0x2100])
+ {
+ FLUSH_REDRAW ();
+ if (PPU.Brightness != (Byte & 0xF))
+ {
+ IPPU.ColorsChanged = TRUE;
+ IPPU.DirectColourMapsNeedRebuild = TRUE;
+ PPU.Brightness = Byte & 0xF;
+ S9xFixColourBrightness ();
+ if (PPU.Brightness > IPPU.MaxBrightness)
+ IPPU.MaxBrightness = PPU.Brightness;
+ }
+ if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
+ {
+ IPPU.ColorsChanged = TRUE;
+ PPU.ForcedBlanking = (Byte >> 7) & 1;
+ }
+ }
+ break;
+
+ case 0x2101:
+ // Sprite (OBJ) tile address
+ if (Byte != Memory.FillRAM [0x2101])
+ {
+ FLUSH_REDRAW ();
+ PPU.OBJNameBase = (Byte & 3) << 14;
+ PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13;
+ PPU.OBJSizeSelect = (Byte >> 5) & 7;
+ IPPU.OBJChanged = TRUE;
+ }
+ break;
+
+ case 0x2102:
+ // Sprite write address (low)
+ PPU.OAMAddr = ((Memory.FillRAM[0x2103]&1)<<8) | Byte;
+ PPU.OAMFlip = 2;
+ PPU.OAMReadFlip = 0;
+ PPU.SavedOAMAddr = PPU.OAMAddr;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+#ifdef DEBUGGER
+ missing.sprite_priority_rotation = 1;
+#endif
+ }
+ break;
+
+ case 0x2103:
+ // Sprite register write address (high), sprite priority rotation
+ // bit.
+ PPU.OAMAddr = ((Byte&1)<<8) | Memory.FillRAM[0x2102];
+
+ PPU.OAMPriorityRotation=(Byte & 0x80)? 1 : 0;
+ if (PPU.OAMPriorityRotation)
+ {
+ if (PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+#ifdef DEBUGGER
+ missing.sprite_priority_rotation = 1;
+#endif
+ }
+ } else {
+ if (PPU.FirstSprite != 0)
+ {
+ PPU.FirstSprite = 0;
+ IPPU.OBJChanged = TRUE;
+#ifdef DEBUGGER
+ missing.sprite_priority_rotation = 1;
+#endif
+ }
+ }
+ PPU.OAMFlip = 0;
+ PPU.OAMReadFlip = 0;
+ PPU.SavedOAMAddr = PPU.OAMAddr;
+ break;
+
+ case 0x2104:
+ // Sprite register write
+ REGISTER_2104(Byte);
+ break;
+
+ case 0x2105:
+ // Screen mode (0 - 7), background tile sizes and background 3
+ // priority
+ if (Byte != Memory.FillRAM [0x2105])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[0].BGSize = (Byte >> 4) & 1;
+ PPU.BG[1].BGSize = (Byte >> 5) & 1;
+ PPU.BG[2].BGSize = (Byte >> 6) & 1;
+ PPU.BG[3].BGSize = (Byte >> 7) & 1;
+ PPU.BGMode = Byte & 7;
+ // BJ: BG3Priority only takes effect if BGMode==1 and the bit is set
+ PPU.BG3Priority = ((Byte & 0x0f) == 0x09);
+#ifdef DEBUGGER
+ missing.modes[PPU.BGMode] = 1;
+#endif
+ if(PPU.BGMode==5||PPU.BGMode==6)
+ IPPU.Interlace = Memory.FillRAM[0x2133]&1;
+ }
+ break;
+
+ case 0x2106:
+ // Mosaic pixel size and enable
+ if (Byte != Memory.FillRAM [0x2106])
+ {
+ FLUSH_REDRAW ();
+#ifdef DEBUGGER
+ if ((Byte & 0xf0) && (Byte & 0x0f))
+ missing.mosaic = 1;
+#endif
+ PPU.Mosaic = (Byte >> 4) + 1;
+ PPU.BGMosaic [0] = (Byte & 1) && PPU.Mosaic > 1;
+ PPU.BGMosaic [1] = (Byte & 2) && PPU.Mosaic > 1;
+ PPU.BGMosaic [2] = (Byte & 4) && PPU.Mosaic > 1;
+ PPU.BGMosaic [3] = (Byte & 8) && PPU.Mosaic > 1;
+ }
+ break;
+ case 0x2107: // [BG0SC]
+ if (Byte != Memory.FillRAM [0x2107])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[0].SCSize = Byte & 3;
+ PPU.BG[0].SCBase = (Byte & 0x7c) << 8;
+ }
+ break;
+
+ case 0x2108: // [BG1SC]
+ if (Byte != Memory.FillRAM [0x2108])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[1].SCSize = Byte & 3;
+ PPU.BG[1].SCBase = (Byte & 0x7c) << 8;
+ }
+ break;
+
+ case 0x2109: // [BG2SC]
+ if (Byte != Memory.FillRAM [0x2109])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[2].SCSize = Byte & 3;
+ PPU.BG[2].SCBase = (Byte & 0x7c) << 8;
+ }
+ break;
+
+ case 0x210A: // [BG3SC]
+ if (Byte != Memory.FillRAM [0x210a])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[3].SCSize = Byte & 3;
+ PPU.BG[3].SCBase = (Byte & 0x7c) << 8;
+ }
+ break;
+
+ case 0x210B: // [BG01NBA]
+ if (Byte != Memory.FillRAM [0x210b])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[0].NameBase = (Byte & 7) << 12;
+ PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12;
+ }
+ break;
+
+ case 0x210C: // [BG23NBA]
+ if (Byte != Memory.FillRAM [0x210c])
+ {
+ FLUSH_REDRAW ();
+ PPU.BG[2].NameBase = (Byte & 7) << 12;
+ PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12;
+ }
+ break;
+
+
+ //This is the Theme Park fix - it appears all these registers
+ //share a previous byte value for setting them.
+
+ case 0x210D:
+ //TEST9 if(last_written != 0x210d) PPU.BGnxOFSbyte = 0;
+ PPU.BG[0].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[0].HOffset = %04x %d)\n", Byte, Address, PPU.BG[0].HOffset, CPU.V_Counter);
+ break;
+
+ case 0x210E:
+ PPU.BG[0].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[0].VOffset = %04x %d)\n", Byte, Address, PPU.BG[0].VOffset, CPU.V_Counter);
+ break;
+
+ case 0x210F:
+ PPU.BG[1].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[1].HOffset = %04x %d)\n", Byte, Address, PPU.BG[1].HOffset, CPU.V_Counter);
+ break;
+
+ case 0x2110:
+ PPU.BG[1].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[1].VOffset = %04x %d)\n", Byte, Address, PPU.BG[1].VOffset, CPU.V_Counter);
+ break;
+
+ case 0x2111:
+ PPU.BG[2].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[2].HOffset = %04x %d)\n", Byte, Address, PPU.BG[2].HOffset, CPU.V_Counter);
+ break;
+
+ case 0x2112:
+ PPU.BG[2].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[2].VOffset = %04x %d)\n", Byte, Address, PPU.BG[2].VOffset, CPU.V_Counter);
+ break;
+
+ case 0x2113:
+ PPU.BG[3].HOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[3].HOffset = %04x %d)\n", Byte, Address, PPU.BG[3].HOffset, CPU.V_Counter);
+ break;
+
+ case 0x2114:
+ PPU.BG[3].VOffset = (Byte<<8) | PPU.BGnxOFSbyte;
+ PPU.BGnxOFSbyte = Byte;
+ // fprintf(stderr, "%02x to %04x (PPU.BG[3].VOffset = %04x %d)\n", Byte, Address, PPU.BG[3].VOffset, CPU.V_Counter);
+ break;
+
+ //end Theme Park
+
+ case 0x2115:
+ // VRAM byte/word access flag and increment
+ PPU.VMA.High = (Byte & 0x80) == 0 ? FALSE : TRUE;
+ switch (Byte & 3)
+ {
+ case 0:
+ PPU.VMA.Increment = 1;
+ break;
+ case 1:
+ PPU.VMA.Increment = 32;
+ break;
+ case 2:
+ PPU.VMA.Increment = 128;
+ break;
+ case 3:
+ PPU.VMA.Increment = 128;
+ break;
+ }
+#ifdef DEBUGGER
+ if ((Byte & 3) != 0)
+ missing.vram_inc = Byte & 3;
+#endif
+ if (Byte & 0x0c)
+ {
+ static uint16 IncCount [4] = { 0, 32, 64, 128 };
+ static uint16 Shift [4] = { 0, 5, 6, 7 };
+#ifdef DEBUGGER
+ missing.vram_full_graphic_inc = (Byte & 0x0c) >> 2;
+#endif
+// PPU.VMA.Increment = 1;
+ uint8 i = (Byte & 0x0c) >> 2;
+ PPU.VMA.FullGraphicCount = IncCount [i];
+ PPU.VMA.Mask1 = IncCount [i] * 8 - 1;
+ PPU.VMA.Shift = Shift [i];
+ }
+ else
+ PPU.VMA.FullGraphicCount = 0;
+ break;
+
+ case 0x2116:
+ // VRAM read/write address (low)
+ PPU.VMA.Address &= 0xFF00;
+ PPU.VMA.Address |= Byte;
+#ifdef CORRECT_VRAM_READS
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 addr = PPU.VMA.Address;
+ uint32 rem = addr & PPU.VMA.Mask1;
+ uint32 address = (addr & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF));
+ } else
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff));
+#else
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ break;
+
+ case 0x2117:
+ // VRAM read/write address (high)
+ PPU.VMA.Address &= 0x00FF;
+ PPU.VMA.Address |= Byte << 8;
+#ifdef CORRECT_VRAM_READS
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 addr = PPU.VMA.Address;
+ uint32 rem = addr & PPU.VMA.Mask1;
+ uint32 address = (addr & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF));
+ } else
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff));
+#else
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ break;
+
+ case 0x2118:
+ // VRAM write data (low)
+#ifndef CORRECT_VRAM_READS
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ REGISTER_2118(Byte);
+ break;
+
+ case 0x2119:
+ // VRAM write data (high)
+#ifndef CORRECT_VRAM_READS
+ IPPU.FirstVRAMRead = TRUE;
+#endif
+ REGISTER_2119(Byte);
+ break;
+
+ case 0x211a:
+ // Mode 7 outside rotation area display mode and flipping
+ if (Byte != Memory.FillRAM [0x211a])
+ {
+ FLUSH_REDRAW ();
+ PPU.Mode7Repeat = Byte >> 6;
+ if (PPU.Mode7Repeat == 1)
+ PPU.Mode7Repeat = 0;
+ PPU.Mode7VFlip = (Byte & 2) >> 1;
+ PPU.Mode7HFlip = Byte & 1;
+ }
+ break;
+ case 0x211b:
+ // Mode 7 matrix A (low & high)
+ PPU.MatrixA = ((PPU.MatrixA >> 8) & 0xff) | (Byte << 8);
+ PPU.Need16x8Mulitply = TRUE;
+ break;
+ case 0x211c:
+ // Mode 7 matrix B (low & high)
+ PPU.MatrixB = ((PPU.MatrixB >> 8) & 0xff) | (Byte << 8);
+ PPU.Need16x8Mulitply = TRUE;
+ break;
+ case 0x211d:
+ // Mode 7 matrix C (low & high)
+ PPU.MatrixC = ((PPU.MatrixC >> 8) & 0xff) | (Byte << 8);
+ break;
+ case 0x211e:
+ // Mode 7 matrix D (low & high)
+ PPU.MatrixD = ((PPU.MatrixD >> 8) & 0xff) | (Byte << 8);
+ break;
+ case 0x211f:
+ // Mode 7 centre of rotation X (low & high)
+ PPU.CentreX = ((PPU.CentreX >> 8) & 0xff) | (Byte << 8);
+ break;
+ case 0x2120:
+ // Mode 7 centre of rotation Y (low & high)
+ PPU.CentreY = ((PPU.CentreY >> 8) & 0xff) | (Byte << 8);
+ break;
+
+ case 0x2121:
+ // CG-RAM address
+ PPU.CGFLIP = 0;
+ PPU.CGFLIPRead = 0;
+ PPU.CGADD = Byte;
+ break;
+
+ case 0x2122:
+ REGISTER_2122(Byte);
+ break;
+
+ case 0x2123:
+ // Window 1 and 2 enable for backgrounds 1 and 2
+ if (Byte != Memory.FillRAM [0x2123])
+ {
+ FLUSH_REDRAW ();
+ PPU.ClipWindow1Enable [0] = !!(Byte & 0x02);
+ PPU.ClipWindow1Enable [1] = !!(Byte & 0x20);
+ PPU.ClipWindow2Enable [0] = !!(Byte & 0x08);
+ PPU.ClipWindow2Enable [1] = !!(Byte & 0x80);
+ PPU.ClipWindow1Inside [0] = !(Byte & 0x01);
+ PPU.ClipWindow1Inside [1] = !(Byte & 0x10);
+ PPU.ClipWindow2Inside [0] = !(Byte & 0x04);
+ PPU.ClipWindow2Inside [1] = !(Byte & 0x40);
+ PPU.RecomputeClipWindows = TRUE;
+#ifdef DEBUGGER
+ if (Byte & 0x80)
+ missing.window2[1] = 1;
+ if (Byte & 0x20)
+ missing.window1[1] = 1;
+ if (Byte & 0x08)
+ missing.window2[0] = 1;
+ if (Byte & 0x02)
+ missing.window1[0] = 1;
+#endif
+ }
+ break;
+ case 0x2124:
+ // Window 1 and 2 enable for backgrounds 3 and 4
+ if (Byte != Memory.FillRAM [0x2124])
+ {
+ FLUSH_REDRAW ();
+ PPU.ClipWindow1Enable [2] = !!(Byte & 0x02);
+ PPU.ClipWindow1Enable [3] = !!(Byte & 0x20);
+ PPU.ClipWindow2Enable [2] = !!(Byte & 0x08);
+ PPU.ClipWindow2Enable [3] = !!(Byte & 0x80);
+ PPU.ClipWindow1Inside [2] = !(Byte & 0x01);
+ PPU.ClipWindow1Inside [3] = !(Byte & 0x10);
+ PPU.ClipWindow2Inside [2] = !(Byte & 0x04);
+ PPU.ClipWindow2Inside [3] = !(Byte & 0x40);
+ PPU.RecomputeClipWindows = TRUE;
+#ifdef DEBUGGER
+ if (Byte & 0x80)
+ missing.window2[3] = 1;
+ if (Byte & 0x20)
+ missing.window1[3] = 1;
+ if (Byte & 0x08)
+ missing.window2[2] = 1;
+ if (Byte & 0x02)
+ missing.window1[2] = 1;
+#endif
+ }
+ break;
+ case 0x2125:
+ // Window 1 and 2 enable for objects and colour window
+ if (Byte != Memory.FillRAM [0x2125])
+ {
+ FLUSH_REDRAW ();
+ PPU.ClipWindow1Enable [4] = !!(Byte & 0x02);
+ PPU.ClipWindow1Enable [5] = !!(Byte & 0x20);
+ PPU.ClipWindow2Enable [4] = !!(Byte & 0x08);
+ PPU.ClipWindow2Enable [5] = !!(Byte & 0x80);
+ PPU.ClipWindow1Inside [4] = !(Byte & 0x01);
+ PPU.ClipWindow1Inside [5] = !(Byte & 0x10);
+ PPU.ClipWindow2Inside [4] = !(Byte & 0x04);
+ PPU.ClipWindow2Inside [5] = !(Byte & 0x40);
+ PPU.RecomputeClipWindows = TRUE;
+#ifdef DEBUGGER
+ if (Byte & 0x80)
+ missing.window2[5] = 1;
+ if (Byte & 0x20)
+ missing.window1[5] = 1;
+ if (Byte & 0x08)
+ missing.window2[4] = 1;
+ if (Byte & 0x02)
+ missing.window1[4] = 1;
+#endif
+ }
+ break;
+ case 0x2126:
+ // Window 1 left position
+ if (Byte != Memory.FillRAM [0x2126])
+ {
+ FLUSH_REDRAW ();
+ PPU.Window1Left = Byte;
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x2127:
+ // Window 1 right position
+ if (Byte != Memory.FillRAM [0x2127])
+ {
+ FLUSH_REDRAW ();
+ PPU.Window1Right = Byte;
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x2128:
+ // Window 2 left position
+ if (Byte != Memory.FillRAM [0x2128])
+ {
+ FLUSH_REDRAW ();
+ PPU.Window2Left = Byte;
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x2129:
+ // Window 2 right position
+ if (Byte != Memory.FillRAM [0x2129])
+ {
+ FLUSH_REDRAW ();
+ PPU.Window2Right = Byte;
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x212a:
+ // Windows 1 & 2 overlap logic for backgrounds 1 - 4
+ if (Byte != Memory.FillRAM [0x212a])
+ {
+ FLUSH_REDRAW ();
+ PPU.ClipWindowOverlapLogic [0] = (Byte & 0x03);
+ PPU.ClipWindowOverlapLogic [1] = (Byte & 0x0c) >> 2;
+ PPU.ClipWindowOverlapLogic [2] = (Byte & 0x30) >> 4;
+ PPU.ClipWindowOverlapLogic [3] = (Byte & 0xc0) >> 6;
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x212b:
+ // Windows 1 & 2 overlap logic for objects and colour window
+ if (Byte != Memory.FillRAM [0x212b])
+ {
+ FLUSH_REDRAW ();
+ PPU.ClipWindowOverlapLogic [4] = Byte & 0x03;
+ PPU.ClipWindowOverlapLogic [5] = (Byte & 0x0c) >> 2;
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x212c:
+ // Main screen designation (backgrounds 1 - 4 and objects)
+ if (Byte != Memory.FillRAM [0x212c])
+ {
+ FLUSH_REDRAW ();
+ PPU.RecomputeClipWindows = TRUE;
+ Memory.FillRAM [Address] = Byte;
+ return;
+ }
+ break;
+ case 0x212d:
+ // Sub-screen designation (backgrounds 1 - 4 and objects)
+ if (Byte != Memory.FillRAM [0x212d])
+ {
+ FLUSH_REDRAW ();
+#ifdef DEBUGGER
+ if (Byte & 0x1f)
+ missing.subscreen = 1;
+#endif
+ PPU.RecomputeClipWindows = TRUE;
+ Memory.FillRAM [Address] = Byte;
+ return;
+ }
+ break;
+ case 0x212e:
+ // Window mask designation for main screen ?
+ if (Byte != Memory.FillRAM [0x212e])
+ {
+ FLUSH_REDRAW ();
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x212f:
+ // Window mask designation for sub-screen ?
+ if (Byte != Memory.FillRAM [0x212f])
+ {
+ FLUSH_REDRAW ();
+ PPU.RecomputeClipWindows = TRUE;
+ }
+ break;
+ case 0x2130:
+ // Fixed colour addition or screen addition
+ if (Byte != Memory.FillRAM [0x2130])
+ {
+ FLUSH_REDRAW ();
+ PPU.RecomputeClipWindows = TRUE;
+#ifdef DEBUGGER
+ if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7))
+ missing.direct = 1;
+#endif
+ }
+ break;
+ case 0x2131:
+ // Colour addition or subtraction select
+ if (Byte != Memory.FillRAM[0x2131])
+ {
+ FLUSH_REDRAW ();
+ // Backgrounds 1 - 4, objects and backdrop colour add/sub enable
+#ifdef DEBUGGER
+ if (Byte & 0x80)
+ {
+ // Subtract
+ if (Memory.FillRAM[0x2130] & 0x02)
+ missing.subscreen_sub = 1;
+ else
+ missing.fixed_colour_sub = 1;
+ }
+ else
+ {
+ // Addition
+ if (Memory.FillRAM[0x2130] & 0x02)
+ missing.subscreen_add = 1;
+ else
+ missing.fixed_colour_add = 1;
+ }
+#endif
+ Memory.FillRAM[0x2131] = Byte;
+ }
+ break;
+ case 0x2132:
+ if (Byte != Memory.FillRAM [0x2132])
+ {
+ FLUSH_REDRAW ();
+ // Colour data for fixed colour addition/subtraction
+ if (Byte & 0x80)
+ PPU.FixedColourBlue = Byte & 0x1f;
+ if (Byte & 0x40)
+ PPU.FixedColourGreen = Byte & 0x1f;
+ if (Byte & 0x20)
+ PPU.FixedColourRed = Byte & 0x1f;
+ }
+ break;
+ case 0x2133:
+ // Screen settings
+ if (Byte != Memory.FillRAM [0x2133])
+ {
+#ifdef DEBUGGER
+ if (Byte & 0x40)
+ missing.mode7_bgmode = 1;
+ if (Byte & 0x08)
+ missing.pseudo_512 = 1;
+#endif
+ if (Byte & 0x04)
+ {
+ PPU.ScreenHeight = SNES_HEIGHT_EXTENDED;
+ if(IPPU.DoubleHeightPixels)
+ IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1;
+ else
+ IPPU.RenderedScreenHeight = PPU.ScreenHeight;
+#ifdef DEBUGGER
+ missing.lines_239 = 1;
+#endif
+ }
+ else PPU.ScreenHeight = SNES_HEIGHT;
+
+#ifdef DEBUGGER
+ if (Byte & 0x02)
+ missing.sprite_double_height = 1;
+
+ if (Byte & 1)
+ missing.interlace = 1;
+#endif
+ //if((Byte & 1)&&(PPU.BGMode==5||PPU.BGMode==6))
+ //IPPU.Interlace=1;
+ if((Memory.FillRAM [0x2133] ^ Byte)&3)
+ {
+ FLUSH_REDRAW ();
+ if((Memory.FillRAM [0x2133] ^ Byte)&2)
+ IPPU.OBJChanged = TRUE;
+ if(PPU.BGMode==5||PPU.BGMode==6)
+ IPPU.Interlace = Byte&1;
+ IPPU.InterlaceSprites=0;
+ // IPPU.InterlaceSprites = (Byte&2)>>1;
+ }
+
+ }
+ break;
+ case 0x2134:
+ case 0x2135:
+ case 0x2136:
+ // Matrix 16bit x 8bit multiply result (read-only)
+ return;
+
+ case 0x2137:
+ // Software latch for horizontal and vertical timers (read-only)
+ return;
+ case 0x2138:
+ // OAM read data (read-only)
+ return;
+ case 0x2139:
+ case 0x213a:
+ // VRAM read data (read-only)
+ return;
+ case 0x213b:
+ // CG-RAM read data (read-only)
+ return;
+ case 0x213c:
+ case 0x213d:
+ // Horizontal and vertical (low/high) read counter (read-only)
+ return;
+ case 0x213e:
+ // PPU status (time over and range over)
+ return;
+ case 0x213f:
+ // NTSC/PAL select and field (read-only)
+ return;
+ case 0x2140: case 0x2141: case 0x2142: case 0x2143:
+ case 0x2144: case 0x2145: case 0x2146: case 0x2147:
+ case 0x2148: case 0x2149: case 0x214a: case 0x214b:
+ case 0x214c: case 0x214d: case 0x214e: case 0x214f:
+ case 0x2150: case 0x2151: case 0x2152: case 0x2153:
+ case 0x2154: case 0x2155: case 0x2156: case 0x2157:
+ case 0x2158: case 0x2159: case 0x215a: case 0x215b:
+ case 0x215c: case 0x215d: case 0x215e: case 0x215f:
+ case 0x2160: case 0x2161: case 0x2162: case 0x2163:
+ case 0x2164: case 0x2165: case 0x2166: case 0x2167:
+ case 0x2168: case 0x2169: case 0x216a: case 0x216b:
+ case 0x216c: case 0x216d: case 0x216e: case 0x216f:
+ case 0x2170: case 0x2171: case 0x2172: case 0x2173:
+ case 0x2174: case 0x2175: case 0x2176: case 0x2177:
+ case 0x2178: case 0x2179: case 0x217a: case 0x217b:
+ case 0x217c: case 0x217d: case 0x217e: case 0x217f:
+#ifdef SPCTOOL
+ _SPCInPB (Address & 3, Byte);
+#else
+ // CPU.Flags |= DEBUG_MODE_FLAG;
+ Memory.FillRAM [Address] = Byte;
+ IAPU.RAM [(Address & 3) + 0xf4] = Byte;
+#ifdef SPC700_SHUTDOWN
+ IAPU.APUExecuting = Settings.APUEnabled;
+ IAPU.WaitCounter++;
+#endif
+#endif // SPCTOOL
+ break;
+ case 0x2180:
+ REGISTER_2180(Byte);
+ break;
+ case 0x2181:
+ PPU.WRAM &= 0x1FF00;
+ PPU.WRAM |= Byte;
+ break;
+ case 0x2182:
+ PPU.WRAM &= 0x100FF;
+ PPU.WRAM |= Byte << 8;
+ break;
+ case 0x2183:
+ PPU.WRAM &= 0x0FFFF;
+ PPU.WRAM |= Byte << 16;
+ PPU.WRAM &= 0x1FFFF;
+ break;
+ }
+ }
+ else
+ {
+ if (Settings.SA1)
+ {
+ if (Address >= 0x2200 && Address <0x23ff)
+ S9xSetSA1 (Byte, Address);
+ else
+ Memory.FillRAM [Address] = Byte;
+
+ return;
+ }
+ else
+ // Dai Kaijyu Monogatari II
+ if (Address == 0x2801 && Settings.SRTC)
+ S9xSetSRTC (Byte, Address);
+ else
+ if (Address < 0x3000 || Address >= 0x3000 + 768)
+ {
+#ifdef DEBUGGER
+ missing.unknownppu_write = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf (String, "Unknown register write: $%02X->$%04X\n",
+ Byte, Address);
+ S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);
+ }
+#endif
+ }
+ else
+ {
+ if (!Settings.SuperFX)
+ {
+ return;
+ }
+
+#ifdef ZSNES_FX
+ Memory.FillRAM [Address] = Byte;
+ if (Address < 0x3040)
+ S9xSuperFXWriteReg (Byte, Address);
+#else
+ switch (Address)
+ {
+ case 0x3030:
+ if ((Memory.FillRAM [0x3030] ^ Byte) & FLG_G)
+ {
+ Memory.FillRAM [Address] = Byte;
+ // Go flag has been changed
+ if (Byte & FLG_G)
+ S9xSuperFXExec ();
+ else
+ FxFlushCache ();
+ }
+ else
+ Memory.FillRAM [Address] = Byte;
+ break;
+
+ case 0x3031:
+ Memory.FillRAM [Address] = Byte;
+ break;
+ case 0x3033:
+ Memory.FillRAM [Address] = Byte;
+ break;
+ case 0x3034:
+ Memory.FillRAM [Address] = Byte & 0x7f;
+ break;
+ case 0x3036:
+ Memory.FillRAM [Address] = Byte & 0x7f;
+ break;
+ case 0x3037:
+ Memory.FillRAM [Address] = Byte;
+ break;
+ case 0x3038:
+ Memory.FillRAM [Address] = Byte;
+ fx_dirtySCBR();
+ break;
+ case 0x3039:
+ Memory.FillRAM [Address] = Byte;
+ break;
+ case 0x303a:
+ Memory.FillRAM [Address] = Byte;
+ break;
+ case 0x303b:
+ break;
+ case 0x303c:
+ Memory.FillRAM [Address] = Byte;
+ fx_updateRamBank(Byte);
+ break;
+ case 0x303f:
+ Memory.FillRAM [Address] = Byte;
+ break;
+ case 0x301f:
+ Memory.FillRAM [Address] = Byte;
+ Memory.FillRAM [0x3000 + GSU_SFR] |= FLG_G;
+ S9xSuperFXExec ();
+ return;
+
+ default:
+ Memory.FillRAM[Address] = Byte;
+ if (Address >= 0x3100)
+ {
+ FxCacheWriteAccess (Address);
+ }
+ break;
+ }
+#endif
+ return;
+ }
+ }
+ Memory.FillRAM[Address] = Byte;
+
+}
+
+/******************************************************************************/
+/* S9xGetPPU() */
+/* This function retrieves a PPU Register */
+/******************************************************************************/
+uint8 S9xGetPPU (uint16 Address)
+{
+ uint8 byte = OpenBus;
+
+ if(Address<0x2100)//not a real PPU reg
+ return OpenBus; //treat as unmapped memory returning last byte on the bus
+ if (Address <= 0x2190)
+ {
+ switch (Address)
+ {
+ case 0x2100:
+ case 0x2101:
+ case 0x2102:
+ case 0x2103:
+ #ifdef DEBUGGER
+ missing.oam_address_read = 1;
+ #endif
+ return OpenBus;
+
+ case 0x2104:
+ case 0x2105:
+ case 0x2106:
+ return PPU.OpenBus1;
+ case 0x2107:
+ return OpenBus;
+ case 0x2108:
+ case 0x2109:
+ case 0x210a:
+ return PPU.OpenBus1;
+ case 0x210b:
+ case 0x210c:
+ case 0x210d:
+ case 0x210e:
+ case 0x210f:
+ case 0x2110:
+ case 0x2111:
+ case 0x2112:
+ case 0x2113:
+ missing.bg_offset_read = 1;
+ return OpenBus;
+
+ case 0x2114:
+#ifdef DEBUGGER
+ missing.bg_offset_read = 1;
+#endif
+ case 0x2115:
+ case 0x2116:
+ return PPU.OpenBus1;
+
+ case 0x2117:
+ return OpenBus;
+
+ case 0x2118:
+ case 0x2119:
+ case 0x211a:
+ return PPU.OpenBus1;
+
+ case 0x211b:
+ case 0x211c:
+ case 0x211d:
+ case 0x211e:
+ case 0x211f:
+ case 0x2120:
+#ifdef DEBUGGER
+ missing.matrix_read = 1;
+#endif
+ return OpenBus;
+
+ case 0x2121:
+ case 0x2122:
+ case 0x2123:
+ return OpenBus;
+
+ case 0x2124:
+ case 0x2125:
+ case 0x2126:
+ return PPU.OpenBus1;
+
+ case 0x2127:
+ return OpenBus;
+
+ case 0x2128:
+ case 0x2129:
+ case 0x212a:
+ return PPU.OpenBus1;
+
+ case 0x212b:
+ case 0x212c:
+ case 0x212d:
+ case 0x212e:
+ case 0x212f:
+ case 0x2130:
+ case 0x2131:
+ case 0x2132:
+ case 0x2133:
+ return OpenBus;
+
+ case 0x2134:
+ case 0x2135:
+ case 0x2136:
+ // 16bit x 8bit multiply read result.
+ if (PPU.Need16x8Mulitply)
+ {
+ int32 r = (int32) PPU.MatrixA * (int32) (PPU.MatrixB >> 8);
+
+ Memory.FillRAM[0x2134] = (uint8) r;
+ Memory.FillRAM[0x2135] = (uint8)(r >> 8);
+ Memory.FillRAM[0x2136] = (uint8)(r >> 16);
+ PPU.Need16x8Mulitply = FALSE;
+ }
+#ifdef DEBUGGER
+ missing.matrix_multiply = 1;
+#endif
+ return (PPU.OpenBus1 = Memory.FillRAM[Address]);
+ case 0x2137:
+ S9xLatchCounters(0);
+ return OpenBus;
+
+ case 0x2138:
+ // Read OAM (sprite) control data
+ if(PPU.OAMAddr&0x100){
+ if (!(PPU.OAMFlip&1))
+ {
+ byte = PPU.OAMData [(PPU.OAMAddr&0x10f) << 1];
+ }
+ else
+ {
+ byte = PPU.OAMData [((PPU.OAMAddr&0x10f) << 1) + 1];
+ PPU.OAMAddr=(PPU.OAMAddr+1)&0x1ff;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+#ifdef DEBUGGER
+ missing.sprite_priority_rotation = 1;
+#endif
+ }
+ }
+ } else {
+ if (!(PPU.OAMFlip&1))
+ {
+ byte = PPU.OAMData [PPU.OAMAddr << 1];
+ }
+ else
+ {
+ byte = PPU.OAMData [(PPU.OAMAddr << 1) + 1];
+ ++PPU.OAMAddr;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+#ifdef DEBUGGER
+ missing.sprite_priority_rotation = 1;
+#endif
+ }
+ }
+ }
+ PPU.OAMFlip ^= 1;
+#ifdef DEBUGGER
+ missing.oam_read = 1;
+#endif
+ return (PPU.OpenBus1 = byte);
+
+ case 0x2139:
+ // Read vram low byte
+#ifdef DEBUGGER
+ missing.vram_read = 1;
+#endif
+#ifdef CORRECT_VRAM_READS
+ byte = IPPU.VRAMReadBuffer & 0xff;
+ if (!PPU.VMA.High)
+ {
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 addr = PPU.VMA.Address;
+ uint32 rem = addr & PPU.VMA.Mask1;
+ uint32 address = (addr & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF));
+ } else
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff));
+ PPU.VMA.Address += PPU.VMA.Increment;
+ }
+#else
+ if (IPPU.FirstVRAMRead)
+ byte = Memory.VRAM[(PPU.VMA.Address << 1)&0xFFFF];
+ else
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 addr = PPU.VMA.Address - 1;
+ uint32 rem = addr & PPU.VMA.Mask1;
+ uint32 address = (addr & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
+ byte = Memory.VRAM [((address << 1) - 2) & 0xFFFF];
+ }
+ else
+ byte = Memory.VRAM[((PPU.VMA.Address << 1) - 2) & 0xffff];
+
+ if (!PPU.VMA.High)
+ {
+ PPU.VMA.Address += PPU.VMA.Increment;
+ IPPU.FirstVRAMRead = FALSE;
+ }
+#endif
+ PPU.OpenBus1 = byte;
+ break;
+ case 0x213A:
+ // Read vram high byte
+#ifdef DEBUGGER
+ missing.vram_read = 1;
+#endif
+#ifdef CORRECT_VRAM_READS
+ byte = (IPPU.VRAMReadBuffer>>8) & 0xff;
+ if (PPU.VMA.High)
+ {
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 addr = PPU.VMA.Address;
+ uint32 rem = addr & PPU.VMA.Mask1;
+ uint32 address = (addr & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF));
+ } else
+ IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff));
+ PPU.VMA.Address += PPU.VMA.Increment;
+ }
+#else
+ if (IPPU.FirstVRAMRead)
+ byte = Memory.VRAM[((PPU.VMA.Address << 1) + 1) & 0xffff];
+ else
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 addr = PPU.VMA.Address - 1;
+ uint32 rem = addr & PPU.VMA.Mask1;
+ uint32 address = (addr & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);
+ byte = Memory.VRAM [((address << 1) - 1) & 0xFFFF];
+ }
+ else
+ byte = Memory.VRAM[((PPU.VMA.Address << 1) - 1) & 0xFFFF];
+ if (PPU.VMA.High)
+ {
+ PPU.VMA.Address += PPU.VMA.Increment;
+ IPPU.FirstVRAMRead = FALSE;
+ }
+#endif
+ PPU.OpenBus1 = byte;
+ break;
+
+ case 0x213B:
+ // Read palette data
+#ifdef DEBUGGER
+ missing.cgram_read = 1;
+#endif
+ if (PPU.CGFLIPRead)
+ byte = PPU.CGDATA [PPU.CGADD++] >> 8;
+ else
+ byte = PPU.CGDATA [PPU.CGADD] & 0xff;
+
+ PPU.CGFLIPRead ^= 1;
+ return (PPU.OpenBus2 = byte);
+
+ case 0x213C:
+ // Horizontal counter value 0-339
+#ifdef DEBUGGER
+ missing.h_counter_read = 1;
+#endif
+ if (PPU.HBeamFlip)
+ byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01);
+ else
+ byte = (uint8)PPU.HBeamPosLatched;
+ PPU.OpenBus2 = byte;
+ PPU.HBeamFlip ^= 1;
+ break;
+
+ case 0x213D:
+ // Vertical counter value 0-262
+#ifdef DEBUGGER
+ missing.v_counter_read = 1;
+#endif
+ if (PPU.VBeamFlip)
+ byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01);
+ else
+ byte = (uint8)PPU.VBeamPosLatched;
+ PPU.OpenBus2 = byte;
+ PPU.VBeamFlip ^= 1;
+ break;
+
+ case 0x213E:
+ // PPU time and range over flags
+ FLUSH_REDRAW ();
+
+ //so far, 5c77 version is always 1.
+ return (PPU.OpenBus1 = (Model->_5C77 | PPU.RangeTimeOver));
+
+ case 0x213F:
+ // NTSC/PAL and which field flags
+ PPU.VBeamFlip = PPU.HBeamFlip = 0;
+ //neviksti found a 2 and a 3 here. SNEeSe uses a 3.
+ //XXX: field flags not emulated
+ return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)| Model->_5C78) | (~PPU.OpenBus2 & 0x20);
+
+ case 0x2140: case 0x2141: case 0x2142: case 0x2143:
+ case 0x2144: case 0x2145: case 0x2146: case 0x2147:
+ case 0x2148: case 0x2149: case 0x214a: case 0x214b:
+ case 0x214c: case 0x214d: case 0x214e: case 0x214f:
+ case 0x2150: case 0x2151: case 0x2152: case 0x2153:
+ case 0x2154: case 0x2155: case 0x2156: case 0x2157:
+ case 0x2158: case 0x2159: case 0x215a: case 0x215b:
+ case 0x215c: case 0x215d: case 0x215e: case 0x215f:
+ case 0x2160: case 0x2161: case 0x2162: case 0x2163:
+ case 0x2164: case 0x2165: case 0x2166: case 0x2167:
+ case 0x2168: case 0x2169: case 0x216a: case 0x216b:
+ case 0x216c: case 0x216d: case 0x216e: case 0x216f:
+ case 0x2170: case 0x2171: case 0x2172: case 0x2173:
+ case 0x2174: case 0x2175: case 0x2176: case 0x2177:
+ case 0x2178: case 0x2179: case 0x217a: case 0x217b:
+ case 0x217c: case 0x217d: case 0x217e: case 0x217f:
+#ifdef SPCTOOL
+ return ((uint8) _SPCOutP [Address & 3]);
+#else
+ // CPU.Flags |= DEBUG_MODE_FLAG;
+#ifdef SPC700_SHUTDOWN
+ IAPU.APUExecuting = Settings.APUEnabled;
+ IAPU.WaitCounter++;
+#endif
+ if (Settings.APUEnabled)
+ {
+#ifdef CPU_SHUTDOWN
+// CPU.WaitAddress = CPU.PCAtOpcodeStart;
+#endif
+ if (SNESGameFixes.APU_OutPorts_ReturnValueFix &&
+ Address >= 0x2140 && Address <= 0x2143 && !CPU.V_Counter)
+ {
+ return (uint8)((Address & 1) ? ((rand() & 0xff00) >> 8) :
+ (rand() & 0xff));
+ }
+
+ return (APU.OutPorts [Address & 3]);
+ }
+
+ switch (Settings.SoundSkipMethod)
+ {
+ case 0:
+ case 1:
+ CPU.BranchSkip = TRUE;
+ break;
+ case 2:
+ break;
+ case 3:
+ CPU.BranchSkip = TRUE;
+ break;
+ }
+ if ((Address & 3) < 2)
+ {
+ int r = rand ();
+ if (r & 2)
+ {
+ if (r & 4)
+ return ((Address & 3) == 1 ? 0xaa : 0xbb);
+ else
+ return ((r >> 3) & 0xff);
+ }
+ }
+ else
+ {
+ int r = rand ();
+ if (r & 2)
+ return ((r >> 3) & 0xff);
+ }
+ return (Memory.FillRAM[Address]);
+#endif // SPCTOOL
+
+ case 0x2180:
+ // Read WRAM
+#ifdef DEBUGGER
+ missing.wram_read = 1;
+#endif
+ byte = Memory.RAM [PPU.WRAM++];
+ PPU.WRAM &= 0x1FFFF;
+ break;
+ case 0x2181:
+ case 0x2182:
+ case 0x2183:
+ return OpenBus;
+
+ default:
+ return OpenBus;
+ }
+ }
+ else
+ {
+ if (Settings.SA1)
+ return (S9xGetSA1 (Address));
+
+ if (Address <= 0x2fff || Address >= 0x3000 + 768)
+ {
+ switch (Address)
+ {
+ case 0x21c2:
+ if(Model->_5C77 ==2)
+ return (0x20);
+
+ // fprintf(stderr, "Read from $21c2!\n");
+ return OpenBus;
+ case 0x21c3:
+ if(Model->_5C77 ==2)
+ return (0);
+ // fprintf(stderr, "Read from $21c3!\n");
+ return OpenBus;
+ case 0x2800:
+ // For Dai Kaijyu Monogatari II
+ if (Settings.SRTC)
+ return (S9xGetSRTC (Address));
+ /*FALL*/
+
+ default:
+#ifdef DEBUGGER
+ missing.unknownppu_read = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf (String, "Unknown register read: $%04X\n", Address);
+ S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);
+ }
+#endif
+ return OpenBus;
+ }
+ }
+
+ if (!Settings.SuperFX)
+ return OpenBus;
+#ifdef ZSNES_FX
+ if (Address < 0x3040)
+ byte = S9xSuperFXReadReg (Address);
+ else
+ byte = Memory.FillRAM [Address];
+
+#ifdef CPU_SHUTDOWN
+ if (Address == 0x3030)
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+#endif
+ if (Address == 0x3031)
+ CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE);
+#else
+ byte = Memory.FillRAM [Address];
+
+//if (Address != 0x3030 && Address != 0x3031)
+//printf ("%04x\n", Address);
+#ifdef CPU_SHUTDOWN
+ if (Address == 0x3030)
+ {
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+ }
+ else
+#endif
+ if (Address == 0x3031)
+ {
+ CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE);
+ Memory.FillRAM [0x3031] = byte & 0x7f;
+ }
+ return (byte);
+#endif
+ }
+// fprintf(stderr, "%03d: %02x from %04x\n", CPU.V_Counter, byte, Address);
+ return (byte);
+}
+
+/******************************************************************************/
+/* S9xSetCPU() */
+/* This function sets a CPU/DMA Register to a specific byte */
+/******************************************************************************/
+void S9xSetCPU (uint8 byte, uint16 Address)
+{
+ int d;
+// fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, byte, Address);
+
+ if (Address < 0x4200)
+ {
+ CPU.Cycles += ONE_CYCLE;
+ switch (Address)
+ {
+ case 0x4016:
+ // S9xReset reading of old-style joypads
+ if ((byte & 1) && !(Memory.FillRAM [Address] & 1))
+ {
+ PPU.Joypad1ButtonReadPos = 0;
+ PPU.Joypad2ButtonReadPos = 0;
+ PPU.Joypad3ButtonReadPos = 0;
+ }
+ break;
+ case 0x4017:
+ break;
+ default:
+#ifdef DEBUGGER
+ missing.unknowncpu_write = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf (String, "Unknown register register write: $%02X->$%04X\n",
+ byte, Address);
+ S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);
+ }
+#endif
+ break;
+ }
+ }
+ else
+ switch (Address)
+ {
+ case 0x4200:
+ // NMI, V & H IRQ and joypad reading enable flags
+ if (byte & 0x20)
+ {
+ //if(!SNESGameFixes.umiharakawaseFix && PPU.IRQVBeamPos==262) fprintf(stderr, "PPU.IRQVBeamPos = %d, CPU.V_Counter = %d\n", PPU.IRQVBeamPos, CPU.V_Counter);
+ if (!PPU.VTimerEnabled)
+ {
+#ifdef DEBUGGER
+ missing.virq = 1;
+ missing.virq_pos = PPU.IRQVBeamPos;
+#endif
+ PPU.VTimerEnabled = TRUE;
+ if (PPU.HTimerEnabled)
+ S9xUpdateHTimer ();
+ else
+ if (PPU.IRQVBeamPos == CPU.V_Counter)
+ S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
+ }
+ }
+ else
+ {
+ PPU.VTimerEnabled = FALSE;
+// if (SNESGameFixes.umiharakawaseFix)
+// byte &= ~0x20;
+ }
+
+ if (byte & 0x10)
+ {
+ if (!PPU.HTimerEnabled)
+ {
+#ifdef DEBUGGER
+ missing.hirq = 1;
+ missing.hirq_pos = PPU.IRQHBeamPos;
+#endif
+ PPU.HTimerEnabled = TRUE;
+ S9xUpdateHTimer ();
+ }
+ }
+ else
+ {
+ // No need to check for HTimer being disabled as the scanline
+ // event trigger code won't trigger an H-IRQ unless its enabled.
+ PPU.HTimerEnabled = FALSE;
+ PPU.HTimerPosition = Settings.H_Max + 1;
+ }
+ if (!Settings.DaffyDuck)
+ CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);
+
+ if ((byte & 0x80) &&
+ !(Memory.FillRAM [0x4200] & 0x80) &&
+ CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE &&
+ CPU.V_Counter <= PPU.ScreenHeight +
+ (SNESGameFixes.alienVSpredetorFix ? 25 : 15) && //jyam 15->25 alien vs predetor
+// Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling
+// NMIs again. The NMI routine crashes the CPU if it is called without the NMI
+// pending flag being set...
+ (Memory.FillRAM [0x4210] & 0x80) &&
+ !CPU.NMIActive)
+ {
+ CPU.Flags |= NMI_FLAG;
+ CPU.NMIActive = TRUE;
+ CPU.NMICycleCount = CPU.NMITriggerPoint;
+ }
+ break;
+ case 0x4201:
+ if((byte&0x80)==0 && (Memory.FillRAM[0x4213]&0x80)==0x80)
+ S9xLatchCounters(1);
+ Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = byte;
+ break;
+ case 0x4202:
+ // Multiplier (for multply)
+ break;
+ case 0x4203:
+ {
+ // Multiplicand
+ uint32 res = Memory.FillRAM[0x4202] * byte;
+
+ Memory.FillRAM[0x4216] = (uint8) res;
+ Memory.FillRAM[0x4217] = (uint8) (res >> 8);
+ break;
+ }
+ case 0x4204:
+ case 0x4205:
+ // Low and high muliplier (for divide)
+ break;
+ case 0x4206:
+ {
+ // Divisor
+ uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8);
+ uint16 div = byte ? a / byte : 0xffff;
+ uint16 rem = byte ? a % byte : a;
+
+ Memory.FillRAM[0x4214] = (uint8)div;
+ Memory.FillRAM[0x4215] = div >> 8;
+ Memory.FillRAM[0x4216] = (uint8)rem;
+ Memory.FillRAM[0x4217] = rem >> 8;
+ break;
+ }
+ case 0x4207:
+ d = PPU.IRQHBeamPos;
+ PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF00) | byte;
+
+ if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d)
+ S9xUpdateHTimer ();
+ break;
+
+ case 0x4208:
+ d = PPU.IRQHBeamPos;
+ PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF) | ((byte & 1) << 8);
+
+ if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d)
+ S9xUpdateHTimer ();
+
+ break;
+
+ case 0x4209:
+ d = PPU.IRQVBeamPos;
+ PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF00) | byte;
+#ifdef DEBUGGER
+ missing.virq_pos = PPU.IRQVBeamPos;
+#endif
+ if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d)
+ {
+ if (PPU.HTimerEnabled)
+ S9xUpdateHTimer ();
+ else
+ {
+ if (PPU.IRQVBeamPos == CPU.V_Counter)
+ S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
+ }
+ }
+ break;
+
+ case 0x420A:
+ d = PPU.IRQVBeamPos;
+ PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF) | ((byte & 1) << 8);
+#ifdef DEBUGGER
+ missing.virq_pos = PPU.IRQVBeamPos;
+#endif
+ if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d)
+ {
+ if (PPU.HTimerEnabled)
+ S9xUpdateHTimer ();
+ else
+ {
+ if (PPU.IRQVBeamPos == CPU.V_Counter)
+ S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
+ }
+ }
+ break;
+
+ case 0x420B:
+#ifdef DEBUGGER
+ missing.dma_this_frame = byte;
+ missing.dma_channels = byte;
+#endif
+ if ((byte & 0x01) != 0)
+ S9xDoDMA (0);
+ if ((byte & 0x02) != 0)
+ S9xDoDMA (1);
+ if ((byte & 0x04) != 0)
+ S9xDoDMA (2);
+ if ((byte & 0x08) != 0)
+ S9xDoDMA (3);
+ if ((byte & 0x10) != 0)
+ S9xDoDMA (4);
+ if ((byte & 0x20) != 0)
+ S9xDoDMA (5);
+ if ((byte & 0x40) != 0)
+ S9xDoDMA (6);
+ if ((byte & 0x80) != 0)
+ S9xDoDMA (7);
+ break;
+ case 0x420C:
+#ifdef DEBUGGER
+ missing.hdma_this_frame |= byte;
+ missing.hdma_channels |= byte;
+#endif
+ if (Settings.DisableHDMA)
+ byte = 0;
+ Memory.FillRAM[0x420c] = byte;
+ IPPU.HDMA = byte;
+ break;
+
+ case 0x420d:
+ // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +)
+ if ((byte & 1) != (Memory.FillRAM [0x420d] & 1))
+ {
+ if (byte & 1)
+ {
+ CPU.FastROMSpeed = ONE_CYCLE;
+#ifdef DEBUGGER
+ missing.fast_rom = 1;
+#endif
+ }
+ else CPU.FastROMSpeed = SLOW_ONE_CYCLE;
+
+ Memory.FixROMSpeed ();
+ }
+ break;
+
+ case 0x420e:
+ case 0x420f:
+ // --->>> Unknown
+ break;
+ case 0x4210:
+ // NMI ocurred flag (reset on read or write)
+ Memory.FillRAM[0x4210] = Model->_5A22;
+ return;
+ case 0x4211:
+ // IRQ ocurred flag (reset on read or write)
+ CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);
+ break;
+ case 0x4212:
+ // v-blank, h-blank and joypad being scanned flags (read-only)
+ case 0x4213:
+ // I/O Port (read-only)
+ case 0x4214:
+ case 0x4215:
+ // Quotent of divide (read-only)
+ case 0x4216:
+ case 0x4217:
+ // Multiply product (read-only)
+ return;
+ case 0x4218:
+ case 0x4219:
+ case 0x421a:
+ case 0x421b:
+ case 0x421c:
+ case 0x421d:
+ case 0x421e:
+ case 0x421f:
+ // Joypad values (read-only)
+ return;
+
+ case 0x4300:
+ case 0x4310:
+ case 0x4320:
+ case 0x4330:
+ case 0x4340:
+ case 0x4350:
+ case 0x4360:
+ case 0x4370:
+ d = (Address >> 4) & 0x7;
+ DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0;
+ DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0;
+ DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0;
+ DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0;
+ DMA[d].TransferMode = (byte & 7);
+ break;
+
+ case 0x4301:
+ case 0x4311:
+ case 0x4321:
+ case 0x4331:
+ case 0x4341:
+ case 0x4351:
+ case 0x4361:
+ case 0x4371:
+ DMA[((Address >> 4) & 0x7)].BAddress = byte;
+ break;
+
+ case 0x4302:
+ case 0x4312:
+ case 0x4322:
+ case 0x4332:
+ case 0x4342:
+ case 0x4352:
+ case 0x4362:
+ case 0x4372:
+ d = (Address >> 4) & 0x7;
+ DMA[d].AAddress &= 0xFF00;
+ DMA[d].AAddress |= byte;
+ break;
+
+ case 0x4303:
+ case 0x4313:
+ case 0x4323:
+ case 0x4333:
+ case 0x4343:
+ case 0x4353:
+ case 0x4363:
+ case 0x4373:
+ d = (Address >> 4) & 0x7;
+ DMA[d].AAddress &= 0xFF;
+ DMA[d].AAddress |= byte << 8;
+ break;
+
+ case 0x4304:
+ case 0x4314:
+ case 0x4324:
+ case 0x4334:
+ case 0x4344:
+ case 0x4354:
+ case 0x4364:
+ case 0x4374:
+ DMA[((Address >> 4) & 0x7)].ABank = byte;
+ HDMAMemPointers[((Address >> 4) & 0x7)]=NULL;
+
+ break;
+
+ case 0x4305:
+ case 0x4315:
+ case 0x4325:
+ case 0x4335:
+ case 0x4345:
+ case 0x4355:
+ case 0x4365:
+ case 0x4375:
+ d = (Address >> 4) & 0x7;
+ DMA[d].TransferBytes &= 0xFF00;
+ DMA[d].TransferBytes |= byte;
+ DMA[d].IndirectAddress &= 0xff00;
+ DMA[d].IndirectAddress |= byte;
+ HDMAMemPointers[d]=NULL;
+ break;
+
+ case 0x4306:
+ case 0x4316:
+ case 0x4326:
+ case 0x4336:
+ case 0x4346:
+ case 0x4356:
+ case 0x4366:
+ case 0x4376:
+ d = (Address >> 4) & 0x7;
+ DMA[d].TransferBytes &= 0xFF;
+ DMA[d].TransferBytes |= byte << 8;
+ DMA[d].IndirectAddress &= 0xff;
+ DMA[d].IndirectAddress |= byte << 8;
+ HDMAMemPointers[d]=NULL;
+ break;
+
+ case 0x4307:
+ case 0x4317:
+ case 0x4327:
+ case 0x4337:
+ case 0x4347:
+ case 0x4357:
+ case 0x4367:
+ case 0x4377:
+ DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte;
+ HDMAMemPointers[d]=NULL;
+ break;
+
+ case 0x4308:
+ case 0x4318:
+ case 0x4328:
+ case 0x4338:
+ case 0x4348:
+ case 0x4358:
+ case 0x4368:
+ case 0x4378:
+ d = (Address >> 4) & 7;
+ DMA[d].Address &= 0xff00;
+ DMA[d].Address |= byte;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x4309:
+ case 0x4319:
+ case 0x4329:
+ case 0x4339:
+ case 0x4349:
+ case 0x4359:
+ case 0x4369:
+ case 0x4379:
+ d = (Address >> 4) & 0x7;
+ DMA[d].Address &= 0xff;
+ DMA[d].Address |= byte << 8;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x430A:
+ case 0x431A:
+ case 0x432A:
+ case 0x433A:
+ case 0x434A:
+ case 0x435A:
+ case 0x436A:
+ case 0x437A:
+ d = (Address >> 4) & 0x7;
+ DMA[d].LineCount = byte & 0x7f;
+ DMA[d].Repeat = !(byte & 0x80);
+ break;
+
+ case 0x430F:
+ case 0x431F:
+ case 0x432F:
+ case 0x433F:
+ case 0x434F:
+ case 0x435F:
+ case 0x436F:
+ case 0x437F:
+ Address &= ~4; // Convert 43xF to 43xB
+ /* fall through */
+ case 0x430B:
+ case 0x431B:
+ case 0x432B:
+ case 0x433B:
+ case 0x434B:
+ case 0x435B:
+ case 0x436B:
+ case 0x437B:
+
+ // Unknown, but they seem to be RAM-ish
+ fprintf(stderr, "Write %02x to %04x!\n", byte, Address);
+ break;
+
+ //These registers are used by both the S-DD1 and the SPC7110
+ case 0x4800:
+ case 0x4801:
+ case 0x4802:
+ case 0x4803:
+ if(Settings.SPC7110)
+ S9xSetSPC7110(byte, Address);
+ //printf ("%02x->%04x\n", byte, Address);
+ break;
+
+ case 0x4804:
+ case 0x4805:
+ case 0x4806:
+ case 0x4807:
+ //printf ("%02x->%04x\n", byte, Address);
+ if(Settings.SPC7110)
+ S9xSetSPC7110(byte, Address);
+ else S9xSetSDD1MemoryMap (Address - 0x4804, byte & 7);
+ break;
+
+ //these are used by the SPC7110
+ case 0x4808:
+ case 0x4809:
+ case 0x480A:
+ case 0x480B:
+ case 0x480C:
+ case 0x4810:
+ case 0x4811:
+ case 0x4812:
+ case 0x4813:
+ case 0x4814:
+ case 0x4815:
+ case 0x4816:
+ case 0x4817:
+ case 0x4818:
+ case 0x481A:
+ case 0x4820:
+ case 0x4821:
+ case 0x4822:
+ case 0x4823:
+ case 0x4824:
+ case 0x4825:
+ case 0x4826:
+ case 0x4827:
+ case 0x4828:
+ case 0x4829:
+ case 0x482A:
+ case 0x482B:
+ case 0x482C:
+ case 0x482D:
+ case 0x482E:
+ case 0x482F:
+ case 0x4830:
+ case 0x4831:
+ case 0x4832:
+ case 0x4833:
+ case 0x4834:
+ case 0x4840:
+ case 0x4841:
+ case 0x4842:
+ if(Settings.SPC7110)
+ {
+ S9xSetSPC7110(byte, Address);
+ break;
+ }
+
+ default:
+#ifdef DEBUGGER
+ missing.unknowncpu_write = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf (String, "Unknown register write: $%02X->$%04X\n",
+ byte, Address);
+ S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);
+ }
+#endif
+ break;
+ }
+ Memory.FillRAM [Address] = byte;
+}
+
+/******************************************************************************/
+/* S9xGetCPU() */
+/* This function retrieves a CPU/DMA Register */
+/******************************************************************************/
+uint8 S9xGetCPU (uint16 Address)
+{
+ uint8 byte;
+// fprintf(stderr, "read from %04x\n", Address);
+
+ if (Address < 0x4200)
+ {
+ CPU.Cycles += ONE_CYCLE;
+ switch (Address)
+ {
+ case 0x4016:
+ {
+ if (Memory.FillRAM [0x4016] & 1)
+ {
+ if ((!Settings.SwapJoypads &&
+ IPPU.Controller == SNES_MOUSE_SWAPPED) ||
+ (Settings.SwapJoypads &&
+ IPPU.Controller == SNES_MOUSE))
+ {
+ if (++PPU.MouseSpeed [0] > 2)
+ PPU.MouseSpeed [0] = 0;
+ }
+ return (0);
+ }
+
+ int ind = Settings.SwapJoypads ? 1 : 0;
+ byte = IPPU.Joypads[ind] >> (PPU.Joypad1ButtonReadPos ^ 15);
+ PPU.Joypad1ButtonReadPos++;
+ return (byte & 1);
+ }
+ case 0x4017:
+ {
+ if (Memory.FillRAM [0x4016] & 1)
+ {
+ // MultiPlayer5 adaptor is only allowed to be plugged into port 2
+ switch (IPPU.Controller)
+ {
+ case SNES_MULTIPLAYER5:
+ return (2);
+ case SNES_MOUSE_SWAPPED:
+ if (Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2)
+ PPU.MouseSpeed [0] = 0;
+ break;
+
+ case SNES_MOUSE:
+ if (!Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2)
+ PPU.MouseSpeed [0] = 0;
+ break;
+ }
+ return (0x00);
+ }
+
+ int ind = Settings.SwapJoypads ? 0 : 1;
+
+ if (IPPU.Controller == SNES_MULTIPLAYER5)
+ {
+ if (Memory.FillRAM [0x4201] & 0x80)
+ {
+ byte = ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) |
+ (((IPPU.Joypads[2] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) << 1);
+ PPU.Joypad2ButtonReadPos++;
+ return (byte);
+ }
+ else
+ {
+ byte = ((IPPU.Joypads[3] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) |
+ (((IPPU.Joypads[4] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) << 1);
+ PPU.Joypad3ButtonReadPos++;
+ return (byte);
+ }
+ }
+ else if(IPPU.Controller ==SNES_JUSTIFIER || IPPU.Controller ==SNES_JUSTIFIER_2)
+ {
+ uint8 rv;
+ rv=(1&(justifiers>>in_bit));
+ in_bit++;
+ in_bit%=32;
+ return rv;
+ }
+ return ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos++ ^ 15)) & 1);
+ }
+ default:
+#ifdef DEBUGGER
+ missing.unknowncpu_read = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf (String, "Unknown register read: $%04X\n", Address);
+ S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);
+ }
+#endif
+ return OpenBus;
+
+ }
+// return (Memory.FillRAM [Address]);
+ }
+ else
+ switch (Address)
+ {
+ case 0x4200:
+ case 0x4201:
+ case 0x4202:
+ case 0x4203:
+ case 0x4204:
+ case 0x4205:
+ case 0x4206:
+ case 0x4207:
+ case 0x4208:
+ case 0x4209:
+ case 0x420a:
+ case 0x420b:
+ case 0x420c:
+ case 0x420d:
+ case 0x420e:
+ case 0x420f:
+ return OpenBus;
+
+ case 0x4210:
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+#endif
+ byte = Memory.FillRAM[0x4210];
+ Memory.FillRAM[0x4210] = Model->_5A22;
+ //SNEeSe returns 2 for 5A22 version.
+ return ((byte&0x80)|(OpenBus&0x70)|Model->_5A22);
+
+ case 0x4211:
+ byte = (CPU.IRQActive & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE)) ? 0x80 : 0;
+ // Super Robot Wars Ex ROM bug requires this.
+ byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0;
+ CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);
+
+ // Maybe? Register Scan indicated open bus...
+ byte |= OpenBus&0x3f;
+
+ return (byte);
+
+ case 0x4212:
+ // V-blank, h-blank and joypads being read flags (read-only)
+#ifdef CPU_SHUTDOWN
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
+#endif
+ return (REGISTER_4212()|(OpenBus&0x3E));
+
+ case 0x4213:
+ // I/O port input - returns 0 wherever $4201 is 0, and 1 elsewhere
+ // unless something else pulls it down (i.e. a gun)
+ return Memory.FillRAM[0x4213];
+
+ case 0x4214:
+ case 0x4215:
+ // Quotient of divide result
+ case 0x4216:
+ case 0x4217:
+ // Multiplcation result (for multiply) or remainder of
+ // divison.
+ return (Memory.FillRAM[Address]);
+ case 0x4218:
+ case 0x4219:
+ case 0x421a:
+ case 0x421b:
+ case 0x421c:
+ case 0x421d:
+ case 0x421e:
+ case 0x421f:
+ // Joypads 1-4 button and direction state.
+ return (Memory.FillRAM [Address]);
+
+ case 0x4300:
+ case 0x4310:
+ case 0x4320:
+ case 0x4330:
+ case 0x4340:
+ case 0x4350:
+ case 0x4360:
+ case 0x4370:
+ // DMA direction, address type, fixed flag,
+ return (Memory.FillRAM[Address]);
+
+ case 0x4301:
+ case 0x4311:
+ case 0x4321:
+ case 0x4331:
+ case 0x4341:
+ case 0x4351:
+ case 0x4361:
+ case 0x4371:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4302:
+ case 0x4312:
+ case 0x4322:
+ case 0x4332:
+ case 0x4342:
+ case 0x4352:
+ case 0x4362:
+ case 0x4372:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4303:
+ case 0x4313:
+ case 0x4323:
+ case 0x4333:
+ case 0x4343:
+ case 0x4353:
+ case 0x4363:
+ case 0x4373:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4304:
+ case 0x4314:
+ case 0x4324:
+ case 0x4334:
+ case 0x4344:
+ case 0x4354:
+ case 0x4364:
+ case 0x4374:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4305:
+ case 0x4315:
+ case 0x4325:
+ case 0x4335:
+ case 0x4345:
+ case 0x4355:
+ case 0x4365:
+ case 0x4375:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4306:
+ case 0x4316:
+ case 0x4326:
+ case 0x4336:
+ case 0x4346:
+ case 0x4356:
+ case 0x4366:
+ case 0x4376:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4307:
+ case 0x4317:
+ case 0x4327:
+ case 0x4337:
+ case 0x4347:
+ case 0x4357:
+ case 0x4367:
+ case 0x4377:
+ return (DMA[(Address >> 4) & 7].IndirectBank);
+
+ case 0x4308:
+ case 0x4318:
+ case 0x4328:
+ case 0x4338:
+ case 0x4348:
+ case 0x4358:
+ case 0x4368:
+ case 0x4378:
+ return (Memory.FillRAM[Address]);
+
+ case 0x4309:
+ case 0x4319:
+ case 0x4329:
+ case 0x4339:
+ case 0x4349:
+ case 0x4359:
+ case 0x4369:
+ case 0x4379:
+ return (Memory.FillRAM[Address]);
+
+ case 0x430A:
+ case 0x431A:
+ case 0x432A:
+ case 0x433A:
+ case 0x434A:
+ case 0x435A:
+ case 0x436A:
+ case 0x437A:
+ {
+ int d = (Address & 0x70) >> 4;
+ if (IPPU.HDMA & (1 << d))
+ {
+ return (DMA[d].LineCount);
+ }
+ return (Memory.FillRAM[Address]);
+ }
+
+ case 0x430F:
+ case 0x431F:
+ case 0x432F:
+ case 0x433F:
+ case 0x434F:
+ case 0x435F:
+ case 0x436F:
+ case 0x437F:
+ Address &= ~4; // Convert 43xF to 43xB
+ /* fall through */
+ case 0x430B:
+ case 0x431B:
+ case 0x432B:
+ case 0x433B:
+ case 0x434B:
+ case 0x435B:
+ case 0x436B:
+ case 0x437B:
+
+ // Unknown, but they seem to be RAM-ish
+ return (Memory.FillRAM[Address]);
+
+ default:
+#ifdef DEBUGGER
+ missing.unknowncpu_read = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf (String, "Unknown register read: $%04X\n", Address);
+ S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);
+ }
+
+#endif
+
+ if(Address>= 0x4800&&Settings.SPC7110)
+ return S9xGetSPC7110(Address);
+
+ if(Address>=0x4800&&Address<=0x4807&&Settings.SDD1)
+ {
+ return Memory.FillRAM[Address];
+ }
+
+ return OpenBus;
+ }
+// return (Memory.FillRAM[Address]);
+}
+
+void S9xResetPPU ()
+{
+ PPU.BGMode = 0;
+ PPU.BG3Priority = 0;
+ PPU.Brightness = 0;
+ PPU.VMA.High = 0;
+ PPU.VMA.Increment = 1;
+ PPU.VMA.Address = 0;
+ PPU.VMA.FullGraphicCount = 0;
+ PPU.VMA.Shift = 0;
+
+ for (uint8 B = 0; B != 4; B++)
+ {
+ PPU.BG[B].SCBase = 0;
+ PPU.BG[B].VOffset = 0;
+ PPU.BG[B].HOffset = 0;
+ PPU.BG[B].BGSize = 0;
+ PPU.BG[B].NameBase = 0;
+ PPU.BG[B].SCSize = 0;
+
+ PPU.ClipCounts[B] = 0;
+ PPU.ClipWindowOverlapLogic [B] = CLIP_OR;
+ PPU.ClipWindow1Enable[B] = FALSE;
+ PPU.ClipWindow2Enable[B] = FALSE;
+ PPU.ClipWindow1Inside[B] = TRUE;
+ PPU.ClipWindow2Inside[B] = TRUE;
+ }
+
+ PPU.ClipCounts[4] = 0;
+ PPU.ClipCounts[5] = 0;
+ PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR;
+ PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE;
+ PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE;
+ PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE;
+ PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE;
+
+ PPU.CGFLIP = 0;
+ int c;
+ for (c = 0; c < 256; c++)
+ {
+ IPPU.Red [c] = (c & 7) << 2;
+ IPPU.Green [c] = ((c >> 3) & 7) << 2;
+ IPPU.Blue [c] = ((c >> 6) & 2) << 3;
+ PPU.CGDATA [c] = IPPU.Red [c] | (IPPU.Green [c] << 5) |
+ (IPPU.Blue [c] << 10);
+ }
+
+ PPU.FirstSprite = 0;
+ PPU.LastSprite = 127;
+ for (int Sprite = 0; Sprite < 128; Sprite++)
+ {
+ PPU.OBJ[Sprite].HPos = 0;
+ PPU.OBJ[Sprite].VPos = 0;
+ PPU.OBJ[Sprite].VFlip = 0;
+ PPU.OBJ[Sprite].HFlip = 0;
+ PPU.OBJ[Sprite].Priority = 0;
+ PPU.OBJ[Sprite].Palette = 0;
+ PPU.OBJ[Sprite].Name = 0;
+ PPU.OBJ[Sprite].Size = 0;
+ }
+ PPU.OAMPriorityRotation = 0;
+ PPU.OAMWriteRegister = 0;
+ PPU.RangeTimeOver = 0;
+ PPU.OpenBus1 = 0;
+ PPU.OpenBus2 = 0;
+
+ PPU.OAMFlip = 0;
+ PPU.OAMTileAddress = 0;
+ PPU.OAMAddr = 0;
+ PPU.IRQVBeamPos = 0;
+ PPU.IRQHBeamPos = 0;
+ PPU.VBeamPosLatched = 0;
+ PPU.HBeamPosLatched = 0;
+
+ PPU.HBeamFlip = 0;
+ PPU.VBeamFlip = 0;
+ PPU.HVBeamCounterLatched = 0;
+
+ PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0;
+ PPU.CentreX = PPU.CentreY = 0;
+ PPU.Joypad1ButtonReadPos = 0;
+ PPU.Joypad2ButtonReadPos = 0;
+ PPU.Joypad3ButtonReadPos = 0;
+
+ PPU.CGADD = 0;
+ PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0;
+ PPU.SavedOAMAddr = 0;
+ PPU.ScreenHeight = SNES_HEIGHT;
+ PPU.WRAM = 0;
+ PPU.BG_Forced = 0;
+ PPU.ForcedBlanking = TRUE;
+ PPU.OBJThroughMain = FALSE;
+ PPU.OBJThroughSub = FALSE;
+ PPU.OBJSizeSelect = 0;
+ PPU.OBJNameSelect = 0;
+ PPU.OBJNameBase = 0;
+ PPU.OBJAddition = FALSE;
+ PPU.OAMReadFlip = 0;
+ PPU.BGnxOFSbyte = 0;
+ ZeroMemory (PPU.OAMData, 512 + 32);
+
+ PPU.VTimerEnabled = FALSE;
+ PPU.HTimerEnabled = FALSE;
+ PPU.HTimerPosition = Settings.H_Max + 1;
+ PPU.Mosaic = 0;
+ PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE;
+ PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE;
+ PPU.Mode7HFlip = FALSE;
+ PPU.Mode7VFlip = FALSE;
+ PPU.Mode7Repeat = 0;
+ PPU.Window1Left = 1;
+ PPU.Window1Right = 0;
+ PPU.Window2Left = 1;
+ PPU.Window2Right = 0;
+ PPU.RecomputeClipWindows = TRUE;
+ PPU.CGFLIPRead = 0;
+ PPU.Need16x8Mulitply = FALSE;
+ PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0;
+
+ IPPU.ColorsChanged = TRUE;
+ IPPU.HDMA = 0;
+ IPPU.HDMAStarted = FALSE;
+ IPPU.MaxBrightness = 0;
+ IPPU.LatchedBlanking = 0;
+ IPPU.OBJChanged = TRUE;
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.DirectColourMapsNeedRebuild = TRUE;
+ IPPU.FrameCount = 0;
+ IPPU.RenderedFramesCount = 0;
+ IPPU.DisplayedRenderedFrameCount = 0;
+ IPPU.SkippedFrames = 0;
+ IPPU.FrameSkip = 0;
+ ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES);
+ ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES);
+ ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES);
+#ifdef CORRECT_VRAM_READS
+ IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better?
+#else
+ IPPU.FirstVRAMRead = FALSE;
+#endif
+ IPPU.Interlace = FALSE;
+ IPPU.InterlaceSprites = FALSE;
+ IPPU.DoubleWidthPixels = FALSE;
+ IPPU.DoubleHeightPixels = FALSE;
+ IPPU.RenderedScreenWidth = SNES_WIDTH;
+ IPPU.RenderedScreenHeight = SNES_HEIGHT;
+ IPPU.XB = NULL;
+ for (c = 0; c < 256; c++)
+ IPPU.ScreenColors [c] = c;
+ S9xFixColourBrightness ();
+ IPPU.PreviousLine = IPPU.CurrentLine = 0;
+ IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0;
+ IPPU.Joypads[3] = IPPU.Joypads[4] = 0;
+ IPPU.SuperScope = 0;
+ IPPU.Mouse[0] = IPPU.Mouse[1] = 0;
+ IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2;
+ IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2;
+
+ if (Settings.ControllerOption == 0)
+ IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1;
+ else
+ IPPU.Controller = Settings.ControllerOption - 1;
+ S9xNextController ();
+
+ for (c = 0; c < 2; c++)
+ memset (&IPPU.Clip [c], 0, sizeof (struct ClipData));
+
+ if (Settings.MouseMaster)
+ {
+ S9xProcessMouse (0);
+ S9xProcessMouse (1);
+ }
+ for (c = 0; c < 0x8000; c += 0x100)
+ {
+ if ( !Settings.SuperFX )
+ {
+ memset (&Memory.FillRAM [c], c >> 8, 0x100);
+ }
+ else if ( (unsigned)c < 0x3000 || (unsigned)c >= 0x3300 )
+ {
+ /* Don't overwrite SFX pvRegisters at 0x3000-0x32FF,
+ * they were set in FxReset.
+ */
+ memset (&Memory.FillRAM [c], c >> 8, 0x100);
+ }
+ }
+
+ ZeroMemory (&Memory.FillRAM [0x2100], 0x100);
+ ZeroMemory (&Memory.FillRAM [0x4200], 0x100);
+ ZeroMemory (&Memory.FillRAM [0x4000], 0x100);
+ // For BS Suttehakkun 2...
+ ZeroMemory (&Memory.FillRAM [0x1000], 0x1000);
+
+ Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF;
+}
+
+void S9xSoftResetPPU ()
+{
+ PPU.BGMode = 0;
+ PPU.BG3Priority = 0;
+ PPU.Brightness = 0;
+ PPU.VMA.High = 0;
+ PPU.VMA.Increment = 1;
+ PPU.VMA.Address = 0;
+ PPU.VMA.FullGraphicCount = 0;
+ PPU.VMA.Shift = 0;
+
+ for (uint8 B = 0; B != 4; B++)
+ {
+ PPU.BG[B].SCBase = 0;
+ PPU.BG[B].VOffset = 0;
+ PPU.BG[B].HOffset = 0;
+ PPU.BG[B].BGSize = 0;
+ PPU.BG[B].NameBase = 0;
+ PPU.BG[B].SCSize = 0;
+
+ PPU.ClipCounts[B] = 0;
+ PPU.ClipWindowOverlapLogic [B] = CLIP_OR;
+ PPU.ClipWindow1Enable[B] = FALSE;
+ PPU.ClipWindow2Enable[B] = FALSE;
+ PPU.ClipWindow1Inside[B] = TRUE;
+ PPU.ClipWindow2Inside[B] = TRUE;
+ }
+
+ PPU.ClipCounts[4] = 0;
+ PPU.ClipCounts[5] = 0;
+ PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR;
+ PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE;
+ PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE;
+ PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE;
+ PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE;
+
+ PPU.CGFLIP = 0;
+ int c;
+ for (c = 0; c < 256; c++)
+ {
+ IPPU.Red [c] = (c & 7) << 2;
+ IPPU.Green [c] = ((c >> 3) & 7) << 2;
+ IPPU.Blue [c] = ((c >> 6) & 2) << 3;
+ PPU.CGDATA [c] = IPPU.Red [c] | (IPPU.Green [c] << 5) |
+ (IPPU.Blue [c] << 10);
+ }
+
+ PPU.FirstSprite = 0;
+ PPU.LastSprite = 127;
+ for (int Sprite = 0; Sprite < 128; Sprite++)
+ {
+ PPU.OBJ[Sprite].HPos = 0;
+ PPU.OBJ[Sprite].VPos = 0;
+ PPU.OBJ[Sprite].VFlip = 0;
+ PPU.OBJ[Sprite].HFlip = 0;
+ PPU.OBJ[Sprite].Priority = 0;
+ PPU.OBJ[Sprite].Palette = 0;
+ PPU.OBJ[Sprite].Name = 0;
+ PPU.OBJ[Sprite].Size = 0;
+ }
+ PPU.OAMPriorityRotation = 0;
+ PPU.OAMWriteRegister = 0;
+ PPU.RangeTimeOver = 0;
+ PPU.OpenBus1 = 0;
+ PPU.OpenBus2 = 0;
+
+ PPU.OAMFlip = 0;
+ PPU.OAMTileAddress = 0;
+ PPU.OAMAddr = 0;
+ PPU.IRQVBeamPos = 0;
+ PPU.IRQHBeamPos = 0;
+ PPU.VBeamPosLatched = 0;
+ PPU.HBeamPosLatched = 0;
+
+ PPU.HBeamFlip = 0;
+ PPU.VBeamFlip = 0;
+ PPU.HVBeamCounterLatched = 0;
+
+ PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0;
+ PPU.CentreX = PPU.CentreY = 0;
+// PPU.Joypad1ButtonReadPos = 0;
+// PPU.Joypad2ButtonReadPos = 0;
+// PPU.Joypad3ButtonReadPos = 0;
+ PPU.CGADD = 0;
+ PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0;
+ PPU.SavedOAMAddr = 0;
+ PPU.ScreenHeight = SNES_HEIGHT;
+ PPU.WRAM = 0;
+ PPU.BG_Forced = 0;
+ PPU.ForcedBlanking = TRUE;
+ PPU.OBJThroughMain = FALSE;
+ PPU.OBJThroughSub = FALSE;
+ PPU.OBJSizeSelect = 0;
+ PPU.OBJNameSelect = 0;
+ PPU.OBJNameBase = 0;
+ PPU.OBJAddition = FALSE;
+ PPU.OAMReadFlip = 0;
+ PPU.BGnxOFSbyte = 0;
+ ZeroMemory (PPU.OAMData, 512 + 32);
+
+ PPU.VTimerEnabled = FALSE;
+ PPU.HTimerEnabled = FALSE;
+ PPU.HTimerPosition = Settings.H_Max + 1;
+ PPU.Mosaic = 0;
+ PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE;
+ PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE;
+ PPU.Mode7HFlip = FALSE;
+ PPU.Mode7VFlip = FALSE;
+ PPU.Mode7Repeat = 0;
+ PPU.Window1Left = 1;
+ PPU.Window1Right = 0;
+ PPU.Window2Left = 1;
+ PPU.Window2Right = 0;
+ PPU.RecomputeClipWindows = TRUE;
+ PPU.CGFLIPRead = 0;
+ PPU.Need16x8Mulitply = FALSE;
+ PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0;
+
+ IPPU.ColorsChanged = TRUE;
+ IPPU.HDMA = 0;
+ IPPU.HDMAStarted = FALSE;
+ IPPU.MaxBrightness = 0;
+ IPPU.LatchedBlanking = 0;
+ IPPU.OBJChanged = TRUE;
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.DirectColourMapsNeedRebuild = TRUE;
+ IPPU.FrameCount = 0;
+ IPPU.RenderedFramesCount = 0;
+ IPPU.DisplayedRenderedFrameCount = 0;
+ IPPU.SkippedFrames = 0;
+ IPPU.FrameSkip = 0;
+ ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES);
+ ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES);
+ ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES);
+#ifdef CORRECT_VRAM_READS
+ IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better?
+#else
+ IPPU.FirstVRAMRead = FALSE;
+#endif
+ IPPU.Interlace = FALSE;
+ IPPU.InterlaceSprites = FALSE;
+ IPPU.DoubleWidthPixels = FALSE;
+ IPPU.DoubleHeightPixels = FALSE;
+ IPPU.RenderedScreenWidth = SNES_WIDTH;
+ IPPU.RenderedScreenHeight = SNES_HEIGHT;
+ IPPU.XB = NULL;
+ for (c = 0; c < 256; c++)
+ IPPU.ScreenColors [c] = c;
+ S9xFixColourBrightness ();
+ IPPU.PreviousLine = IPPU.CurrentLine = 0;
+// IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0;
+// IPPU.Joypads[3] = IPPU.Joypads[4] = 0;
+// IPPU.SuperScope = 0;
+// IPPU.Mouse[0] = IPPU.Mouse[1] = 0;
+// IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2;
+// IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2;
+
+ if (Settings.ControllerOption == 0)
+ IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1;
+ else
+ IPPU.Controller = Settings.ControllerOption - 1;
+ S9xNextController ();
+
+ for (c = 0; c < 2; c++)
+ memset (&IPPU.Clip [c], 0, sizeof (struct ClipData));
+
+ if (Settings.MouseMaster)
+ {
+ S9xProcessMouse (0);
+ S9xProcessMouse (1);
+ }
+ for (c = 0; c < 0x8000; c += 0x100)
+ memset (&Memory.FillRAM [c], c >> 8, 0x100);
+
+ ZeroMemory (&Memory.FillRAM [0x2100], 0x100);
+ ZeroMemory (&Memory.FillRAM [0x4200], 0x100);
+ ZeroMemory (&Memory.FillRAM [0x4000], 0x100);
+ // For BS Suttehakkun 2...
+ ZeroMemory (&Memory.FillRAM [0x1000], 0x1000);
+
+ Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF;
+}
+
+void S9xProcessMouse (int which1)
+{
+ int x, y;
+ uint32 buttons;
+
+ if ((IPPU.Controller == SNES_MOUSE || IPPU.Controller == SNES_MOUSE_SWAPPED) && S9xReadMousePosition (which1, x, y, buttons))
+ {
+ int delta_x, delta_y;
+#define MOUSE_SIGNATURE 0x1
+ IPPU.Mouse [which1] = MOUSE_SIGNATURE |
+ (PPU.MouseSpeed [which1] << 4) |
+ ((buttons & 1) << 6) | ((buttons & 2) << 6);
+
+ delta_x = x - IPPU.PrevMouseX[which1];
+ delta_y = y - IPPU.PrevMouseY[which1];
+
+ if (delta_x > 63)
+ {
+ delta_x = 63;
+ IPPU.PrevMouseX[which1] += 63;
+ }
+ else
+ if (delta_x < -63)
+ {
+ delta_x = -63;
+ IPPU.PrevMouseX[which1] -= 63;
+ }
+ else
+ IPPU.PrevMouseX[which1] = x;
+
+ if (delta_y > 63)
+ {
+ delta_y = 63;
+ IPPU.PrevMouseY[which1] += 63;
+ }
+ else
+ if (delta_y < -63)
+ {
+ delta_y = -63;
+ IPPU.PrevMouseY[which1] -= 63;
+ }
+ else
+ IPPU.PrevMouseY[which1] = y;
+
+ if (delta_x < 0)
+ {
+ delta_x = -delta_x;
+ IPPU.Mouse [which1] |= (delta_x | 0x80) << 16;
+ }
+ else
+ IPPU.Mouse [which1] |= delta_x << 16;
+
+ if (delta_y < 0)
+ {
+ delta_y = -delta_y;
+ IPPU.Mouse [which1] |= (delta_y | 0x80) << 24;
+ }
+ else
+ IPPU.Mouse [which1] |= delta_y << 24;
+
+ if (IPPU.Controller == SNES_MOUSE_SWAPPED)
+ IPPU.Joypads [0] = IPPU.Mouse [which1];
+ else
+ IPPU.Joypads [1] = IPPU.Mouse [which1];
+ }
+}
+
+void ProcessSuperScope ()
+{
+ int x, y;
+ uint32 buttons;
+
+ if (IPPU.Controller == SNES_SUPERSCOPE &&
+ S9xReadSuperScopePosition (x, y, buttons))
+ {
+#define SUPERSCOPE_SIGNATURE 0x00ff
+ uint32 scope;
+
+ scope = SUPERSCOPE_SIGNATURE | ((buttons & 1) << (7 + 8)) |
+ ((buttons & 2) << (5 + 8)) | ((buttons & 4) << (3 + 8)) |
+ ((buttons & 8) << (1 + 8));
+ if(Memory.FillRAM[0x4201]&0x80){
+ x+=40;
+ if (x > 295)
+ x = 295;
+ if (x < 40)
+ x = 40;
+ if (y > PPU.ScreenHeight - 1)
+ y = PPU.ScreenHeight - 1;
+ if (y < 0)
+ y = 0;
+
+ PPU.VBeamPosLatched = (uint16) (y + 1);
+ PPU.HBeamPosLatched = (uint16) x;
+ PPU.HVBeamCounterLatched = TRUE;
+ Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78;
+ }
+ IPPU.Joypads [1] = scope;
+ }
+}
+
+void S9xNextController ()
+{
+ switch (IPPU.Controller)
+ {
+ case SNES_MULTIPLAYER5:
+ IPPU.Controller = SNES_JOYPAD;
+ break;
+ case SNES_JOYPAD:
+ if (Settings.MouseMaster)
+ {
+ IPPU.Controller = SNES_MOUSE_SWAPPED;
+ break;
+ }
+ case SNES_MOUSE_SWAPPED:
+ if (Settings.MouseMaster)
+ {
+ IPPU.Controller = SNES_MOUSE;
+ break;
+ }
+ case SNES_MOUSE:
+ if (Settings.SuperScopeMaster)
+ {
+ IPPU.Controller = SNES_SUPERSCOPE;
+ break;
+ }
+ case SNES_SUPERSCOPE:
+ if (Settings.JustifierMaster)
+ {
+ IPPU.Controller = SNES_JUSTIFIER;
+ break;
+ }
+ case SNES_JUSTIFIER:
+ if(Settings.JustifierMaster)
+ {
+ IPPU.Controller=SNES_JUSTIFIER_2;
+ break;
+ }
+ case SNES_JUSTIFIER_2:
+ if(Settings.MultiPlayer5Master)
+ {
+ IPPU.Controller=SNES_MULTIPLAYER5;
+ break;
+ }
+ default:
+ IPPU.Controller = SNES_JOYPAD;
+ break;
+ }
+}
+
+void S9xUpdateJustifiers()
+{
+ static bool last_p1;
+ in_bit=0;
+// static int p1count;
+ justifiers=0xFFFF00AA;
+
+ bool offscreen=JustifierOffscreen();
+
+ JustifierButtons(justifiers);
+// if(p1count==32)
+// {
+ last_p1=!last_p1;
+// p1count=0;
+// }
+// p1count++;
+
+ if(!last_p1)
+ justifiers|=0x1000;
+
+ int x,y;
+ uint32 buttons;
+
+ if(Memory.FillRAM[0x4201]&0x80)
+ {
+
+ S9xReadSuperScopePosition(x,y,buttons);
+
+ x+=40;
+ if (x > 295)
+ x = 295;
+ if (x < 40)
+ x = 40;
+ if (y > PPU.ScreenHeight - 1)
+ y = PPU.ScreenHeight - 1;
+ if (y < 0)
+ y = 0;
+
+ if(last_p1)
+ {
+
+ PPU.HVBeamCounterLatched = FALSE;
+ Memory.FillRAM [0x213F] = Model->_5C78;
+
+ //process latch as Justifier 2
+ if(Settings.SecondJustifier)
+ {
+ if(IPPU.Controller==SNES_JUSTIFIER_2)
+ {
+ if(!offscreen)
+ {
+
+ PPU.VBeamPosLatched = (uint16) (y + 1);
+ PPU.HBeamPosLatched = (uint16) x;
+ PPU.HVBeamCounterLatched = TRUE;
+ Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78;
+ }
+ }
+ }
+ }
+ else
+ {
+
+ PPU.HVBeamCounterLatched = FALSE;
+ Memory.FillRAM [0x213F] = Model->_5C78;
+
+ //emulate player 1.
+ if(IPPU.Controller==SNES_JUSTIFIER)
+ {
+ if(!offscreen)
+ {
+ PPU.VBeamPosLatched = (uint16) (y + 1);
+ PPU.HBeamPosLatched = (uint16) x;
+ PPU.HVBeamCounterLatched = TRUE;
+ Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78;
+ }
+ }
+ }
+
+ //needs restructure
+ if(!offscreen)
+ {
+
+ if((!last_p1&&IPPU.Controller==SNES_JUSTIFIER)||(last_p1&&IPPU.Controller==SNES_JUSTIFIER_2))
+ {
+ PPU.VBeamPosLatched = (uint16) (y + 1);
+ PPU.HBeamPosLatched = (uint16) x;
+ PPU.HVBeamCounterLatched = TRUE;
+ Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78;
+ }
+ else
+ {
+ PPU.HVBeamCounterLatched = FALSE;
+ Memory.FillRAM [0x213F] = Model->_5C78;
+
+ }
+ }
+ else
+ {
+ PPU.HVBeamCounterLatched = FALSE;
+ Memory.FillRAM [0x213F] = Model->_5C78;
+ }
+ }
+}
+
+void S9xUpdateJoypads ()
+{
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ IPPU.Joypads [i] = S9xReadJoypad (i);
+ }
+
+// S9xMovieUpdate();
+
+ for (i = 0; i < 5; i++)
+ {
+ if (IPPU.Joypads [i] & SNES_LEFT_MASK)
+ IPPU.Joypads [i] &= ~SNES_RIGHT_MASK;
+ if (IPPU.Joypads [i] & SNES_UP_MASK)
+ IPPU.Joypads [i] &= ~SNES_DOWN_MASK;
+ }
+
+ // BJ: This is correct behavior AFAICT (used to be Touhaiden hack)
+ if (IPPU.Controller == SNES_JOYPAD || IPPU.Controller == SNES_MULTIPLAYER5)
+ {
+ for (i = 0; i < 5; i++)
+ {
+ if (IPPU.Joypads [i])
+ IPPU.Joypads [i] |= 0xffff0000;
+ }
+ }
+
+ // Read mouse position if enabled
+ if (Settings.MouseMaster)
+ {
+ for (i = 0; i < 2; i++)
+ S9xProcessMouse (i);
+ }
+
+ // Read SuperScope if enabled
+ if (Settings.SuperScopeMaster)
+ ProcessSuperScope ();
+
+ if (Memory.FillRAM [0x4200] & 1)
+ {
+ PPU.Joypad1ButtonReadPos = 16;
+ if (Memory.FillRAM [0x4201] & 0x80)
+ {
+ PPU.Joypad2ButtonReadPos = 16;
+ PPU.Joypad3ButtonReadPos = 0;
+ }
+ else
+ {
+ PPU.Joypad2ButtonReadPos = 0;
+ PPU.Joypad3ButtonReadPos = 16;
+ }
+ int ind = Settings.SwapJoypads ? 1 : 0;
+
+ Memory.FillRAM [0x4218] = (uint8) IPPU.Joypads [ind];
+ Memory.FillRAM [0x4219] = (uint8) (IPPU.Joypads [ind] >> 8);
+ Memory.FillRAM [0x421a] = (uint8) IPPU.Joypads [ind ^ 1];
+ Memory.FillRAM [0x421b] = (uint8) (IPPU.Joypads [ind ^ 1] >> 8);
+ if (Memory.FillRAM [0x4201] & 0x80)
+ {
+ Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [ind];
+ Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads [ind] >> 8);
+ Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [2];
+ Memory.FillRAM [0x421f] = (uint8) (IPPU.Joypads [2] >> 8);
+ }
+ else
+ {
+ Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [3];
+ Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads [3] >> 8);
+ Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [4];
+ Memory.FillRAM [0x421f] = (uint8) (IPPU.Joypads [4] >> 8);
+ }
+ }
+ if(Settings.Justifier||Settings.SecondJustifier)
+ {
+ Memory.FillRAM [0x421a] = 0x0E;
+ Memory.FillRAM [0x421b] = 0;
+ S9xUpdateJustifiers();
+ }
+
+}
+
+#ifndef ZSNES_FX
+void S9xSuperFXExec ()
+{
+#if 1
+ if (Settings.SuperFX)
+ {
+ if ((Memory.FillRAM [0x3000 + GSU_SFR] & FLG_G) &&
+ (Memory.FillRAM [0x3000 + GSU_SCMR] & 0x18) == 0x18)
+ {
+ if (!Settings.WinterGold||Settings.StarfoxHack)
+ FxEmulate (~0);
+ else
+ FxEmulate ((Memory.FillRAM [0x3000 + GSU_CLSR] & 1) ? 700 : 350);
+ int GSUStatus = Memory.FillRAM [0x3000 + GSU_SFR] |
+ (Memory.FillRAM [0x3000 + GSU_SFR + 1] << 8);
+ if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ)
+ {
+ // Trigger a GSU IRQ.
+ S9xSetIRQ (GSU_IRQ_SOURCE);
+ }
+ }
+ }
+#else
+ uint32 tmp = (Memory.FillRAM[0x3034] << 16) + *(uint16 *) &Memory.FillRAM [0x301e];
+
+#if 0
+ if (tmp == 0x018428)
+ {
+ *(uint16 *) &SRAM [0x0064] = 0xbc00;
+ *(uint16 *) &SRAM [0x002c] = 0x8000;
+ }
+#endif
+ if (tmp == -1)//0x018428) //0x01bfc3) //0x09edaf) //-1) //0x57edaf)
+ {
+ while (Memory.FillRAM [0x3030] & 0x20)
+ {
+ int i;
+ int32 vError;
+ uint8 avReg[0x40];
+ char tmp[128];
+ uint8 vPipe;
+ uint8 vColr;
+ uint8 vPor;
+
+ FxPipeString (tmp);
+ /* Make the string 32 chars long */
+ if(strlen(tmp) < 32) { memset(&tmp[strlen(tmp)],' ',32-strlen(tmp)); tmp[32] = 0; }
+
+ /* Copy registers (so we can see if any changed) */
+ vColr = FxGetColorRegister();
+ vPor = FxGetPlotOptionRegister();
+ memcpy(avReg,SuperFX.pvRegisters,0x40);
+
+ /* Print the pipe string */
+ printf(tmp);
+
+ /* Execute the instruction in the pipe */
+ vPipe = FxPipe();
+ vError = FxEmulate(1);
+
+ /* Check if any registers changed (and print them if they did) */
+ for(i=0; i<16; i++)
+ {
+ uint32 a = 0;
+ uint32 r1 = ((uint32)avReg[i*2]) | (((uint32)avReg[(i*2)+1])<<8);
+ uint32 r2 = (uint32)(SuperFX.pvRegisters[i*2]) | (((uint32)SuperFX.pvRegisters[(i*2)+1])<<8);
+ if(i==15)
+ a = OPCODE_BYTES(vPipe);
+ if(((r1+a)&0xffff) != r2)
+ printf(" r%d=$%04x",i,r2);
+ }
+ {
+ /* Check SFR */
+ uint32 r1 = ((uint32)avReg[0x30]) | (((uint32)avReg[0x31])<<8);
+ uint32 r2 = (uint32)(SuperFX.pvRegisters[0x30]) | (((uint32)SuperFX.pvRegisters[0x31])<<8);
+ if((r1&(1<<1)) != (r2&(1<<1)))
+ printf(" Z=%d",(uint32)(!!(r2&(1<<1))));
+ if((r1&(1<<2)) != (r2&(1<<2)))
+ printf(" CY=%d",(uint32)(!!(r2&(1<<2))));
+ if((r1&(1<<3)) != (r2&(1<<3)))
+ printf(" S=%d",(uint32)(!!(r2&(1<<3))));
+ if((r1&(1<<4)) != (r2&(1<<4)))
+ printf(" OV=%d",(uint32)(!!(r2&(1<<4))));
+ if((r1&(1<<5)) != (r2&(1<<5)))
+ printf(" G=%d",(uint32)(!!(r2&(1<<5))));
+ if((r1&(1<<6)) != (r2&(1<<6)))
+ printf(" R=%d",(uint32)(!!(r2&(1<<6))));
+ if((r1&(1<<8)) != (r2&(1<<8)))
+ printf(" ALT1=%d",(uint32)(!!(r2&(1<<8))));
+ if((r1&(1<<9)) != (r2&(1<<9)))
+ printf(" ALT2=%d",(uint32)(!!(r2&(1<<9))));
+ if((r1&(1<<10)) != (r2&(1<<10)))
+ printf(" IL=%d",(uint32)(!!(r2&(1<<10))));
+ if((r1&(1<<11)) != (r2&(1<<11)))
+ printf(" IH=%d",(uint32)(!!(r2&(1<<11))));
+ if((r1&(1<<12)) != (r2&(1<<12)))
+ printf(" B=%d",(uint32)(!!(r2&(1<<12))));
+ if((r1&(1<<15)) != (r2&(1<<15)))
+ printf(" IRQ=%d",(uint32)(!!(r2&(1<<15))));
+ }
+ {
+ /* Check PBR */
+ uint32 r1 = ((uint32)avReg[0x34]);
+ uint32 r2 = (uint32)(SuperFX.pvRegisters[0x34]);
+ if(r1 != r2)
+ printf(" PBR=$%02x",r2);
+ }
+ {
+ /* Check ROMBR */
+ uint32 r1 = ((uint32)avReg[0x36]);
+ uint32 r2 = (uint32)(SuperFX.pvRegisters[0x36]);
+ if(r1 != r2)
+ printf(" ROMBR=$%02x",r2);
+ }
+ {
+ /* Check RAMBR */
+ uint32 r1 = ((uint32)avReg[0x3c]);
+ uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3c]);
+ if(r1 != r2)
+ printf(" RAMBR=$%02x",r2);
+ }
+ {
+ /* Check CBR */
+ uint32 r1 = ((uint32)avReg[0x3e]) | (((uint32)avReg[0x3f])<<8);
+ uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3e]) | (((uint32)SuperFX.pvRegisters[0x3f])<<8);
+ if(r1 != r2)
+ printf(" CBR=$%04x",r2);
+ }
+ {
+ /* Check COLR */
+ if(vColr != FxGetColorRegister())
+ printf(" COLR=$%02x",FxGetColorRegister());
+ }
+ {
+ /* Check POR */
+ if(vPor != FxGetPlotOptionRegister())
+ printf(" POR=$%02x",FxGetPlotOptionRegister());
+ }
+ printf ("\n");
+ }
+ S9xExit ();
+ }
+ else
+ {
+ uint32 t = (Memory.FillRAM [0x3034] << 16) +
+ (Memory.FillRAM [0x301f] << 8) +
+ (Memory.FillRAM [0x301e] << 0);
+
+printf ("%06x: %d\n", t, FxEmulate (2000000));
+// FxEmulate (2000000);
+ }
+#if 0
+ if (!(CPU.Flags & TRACE_FLAG))
+ {
+ static int z = 1;
+ if (z == 0)
+ {
+ extern FILE *trace;
+ CPU.Flags |= TRACE_FLAG;
+ trace = fopen ("trace.log", "wb");
+ }
+ else
+ z--;
+ }
+#endif
+ Memory.FillRAM [0x3030] &= ~0x20;
+ if (Memory.FillRAM [0x3031] & 0x80)
+ {
+ S9xSetIRQ (GSU_IRQ_SOURCE);
+ }
+#endif
+}
+#endif
+
diff --git a/source/ppu.h b/source/ppu.h
new file mode 100644
index 0000000..99dde34
--- /dev/null
+++ b/source/ppu.h
@@ -0,0 +1,633 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _PPU_H_
+#define _PPU_H_
+
+#define FIRST_VISIBLE_LINE 1
+
+extern uint8 GetBank;
+extern uint16 SignExtend [2];
+
+#define TILE_2BIT 0
+#define TILE_4BIT 1
+#define TILE_8BIT 2
+
+#define MAX_2BIT_TILES 4096
+#define MAX_4BIT_TILES 2048
+#define MAX_8BIT_TILES 1024
+
+#define PPU_H_BEAM_IRQ_SOURCE (1 << 0)
+#define PPU_V_BEAM_IRQ_SOURCE (1 << 1)
+#define GSU_IRQ_SOURCE (1 << 2)
+#define SA1_IRQ_SOURCE (1 << 7)
+#define SA1_DMA_IRQ_SOURCE (1 << 5)
+
+struct ClipData {
+ uint32 Count [6];
+ uint32 Left [6][6];
+ uint32 Right [6][6];
+};
+
+struct InternalPPU {
+ bool8 ColorsChanged;
+ uint8 HDMA;
+ bool8 HDMAStarted;
+ uint8 MaxBrightness;
+ bool8 LatchedBlanking;
+ bool8 OBJChanged;
+ bool8 RenderThisFrame;
+ bool8 DirectColourMapsNeedRebuild;
+ uint32 FrameCount;
+ uint32 RenderedFramesCount;
+ uint32 DisplayedRenderedFrameCount;
+ uint32 SkippedFrames;
+ uint32 FrameSkip;
+ uint8 *TileCache [3];
+ uint8 *TileCached [3];
+#ifdef CORRECT_VRAM_READS
+ uint16 VRAMReadBuffer;
+#else
+ bool8 FirstVRAMRead;
+#endif
+ bool8 DoubleHeightPixels;
+ bool8 Interlace;
+ bool8 InterlaceSprites;
+ bool8 DoubleWidthPixels;
+ int RenderedScreenHeight;
+ int RenderedScreenWidth;
+ uint32 Red [256];
+ uint32 Green [256];
+ uint32 Blue [256];
+ uint8 *XB;
+ uint16 ScreenColors [256];
+ int PreviousLine;
+ int CurrentLine;
+ int Controller;
+ uint32 Joypads[5];
+ uint32 SuperScope;
+ uint32 Mouse[2];
+ int PrevMouseX[2];
+ int PrevMouseY[2];
+ struct ClipData Clip [2];
+};
+
+struct SOBJ
+{
+ short HPos;
+ uint16 VPos;
+ uint16 Name;
+ uint8 VFlip;
+ uint8 HFlip;
+ uint8 Priority;
+ uint8 Palette;
+ uint8 Size;
+};
+
+struct SPPU {
+ uint8 BGMode;
+ uint8 BG3Priority;
+ uint8 Brightness;
+
+ struct {
+ bool8 High;
+ uint8 Increment;
+ uint16 Address;
+ uint16 Mask1;
+ uint16 FullGraphicCount;
+ uint16 Shift;
+ } VMA;
+
+ struct {
+ uint16 SCBase;
+ uint16 VOffset;
+ uint16 HOffset;
+ uint8 BGSize;
+ uint16 NameBase;
+ uint16 SCSize;
+ } BG [4];
+
+ bool8 CGFLIP;
+ uint16 CGDATA [256];
+ uint8 FirstSprite;
+ uint8 LastSprite;
+ struct SOBJ OBJ [128];
+ uint8 OAMPriorityRotation;
+ uint16 OAMAddr;
+ uint8 RangeTimeOver;
+
+ uint8 OAMFlip;
+ uint16 OAMTileAddress;
+ uint16 IRQVBeamPos;
+ uint16 IRQHBeamPos;
+ uint16 VBeamPosLatched;
+ uint16 HBeamPosLatched;
+
+ uint8 HBeamFlip;
+ uint8 VBeamFlip;
+ uint8 HVBeamCounterLatched;
+
+ short MatrixA;
+ short MatrixB;
+ short MatrixC;
+ short MatrixD;
+ short CentreX;
+ short CentreY;
+ uint8 Joypad1ButtonReadPos;
+ uint8 Joypad2ButtonReadPos;
+
+ uint8 CGADD;
+ uint8 FixedColourRed;
+ uint8 FixedColourGreen;
+ uint8 FixedColourBlue;
+ uint16 SavedOAMAddr;
+ uint16 ScreenHeight;
+ uint32 WRAM;
+ uint8 BG_Forced;
+ bool8 ForcedBlanking;
+ bool8 OBJThroughMain;
+ bool8 OBJThroughSub;
+ uint8 OBJSizeSelect;
+ uint16 OBJNameBase;
+ bool8 OBJAddition;
+ uint8 OAMReadFlip;
+ uint8 OAMData [512 + 32];
+ bool8 VTimerEnabled;
+ bool8 HTimerEnabled;
+ short HTimerPosition;
+ uint8 Mosaic;
+ bool8 BGMosaic [4];
+ bool8 Mode7HFlip;
+ bool8 Mode7VFlip;
+ uint8 Mode7Repeat;
+ uint8 Window1Left;
+ uint8 Window1Right;
+ uint8 Window2Left;
+ uint8 Window2Right;
+ uint8 ClipCounts [6];
+ uint8 ClipWindowOverlapLogic [6];
+ uint8 ClipWindow1Enable [6];
+ uint8 ClipWindow2Enable [6];
+ bool8 ClipWindow1Inside [6];
+ bool8 ClipWindow2Inside [6];
+ bool8 RecomputeClipWindows;
+ uint8 CGFLIPRead;
+ uint16 OBJNameSelect;
+ bool8 Need16x8Mulitply;
+ uint8 Joypad3ButtonReadPos;
+ uint8 MouseSpeed[2];
+
+ // XXX Do these need to be added to snapshot.cpp?
+ uint16 OAMWriteRegister;
+ uint8 BGnxOFSbyte;
+ uint8 OpenBus1;
+ uint8 OpenBus2;
+};
+
+#define CLIP_OR 0
+#define CLIP_AND 1
+#define CLIP_XOR 2
+#define CLIP_XNOR 3
+
+struct SDMA {
+ bool8 TransferDirection;
+ bool8 AAddressFixed;
+ bool8 AAddressDecrement;
+ uint8 TransferMode;
+
+ uint8 ABank;
+ uint16 AAddress;
+ uint16 Address;
+ uint8 BAddress;
+
+ // General DMA only:
+ uint16 TransferBytes;
+
+ // H-DMA only:
+ bool8 HDMAIndirectAddressing;
+ uint16 IndirectAddress;
+ uint8 IndirectBank;
+ uint8 Repeat;
+ uint8 LineCount;
+ uint8 FirstLine;
+};
+
+START_EXTERN_C
+void S9xUpdateScreen ();
+void S9xResetPPU ();
+void S9xSoftResetPPU ();
+void S9xFixColourBrightness ();
+void S9xUpdateJoypads ();
+void S9xProcessMouse(int which1);
+void S9xSuperFXExec ();
+
+void S9xSetPPU (uint8 Byte, uint16 Address);
+uint8 S9xGetPPU (uint16 Address);
+void S9xSetCPU (uint8 Byte, uint16 Address);
+uint8 S9xGetCPU (uint16 Address);
+
+void S9xInitC4 ();
+void S9xSetC4 (uint8 Byte, uint16 Address);
+uint8 S9xGetC4 (uint16 Address);
+void S9xSetC4RAM (uint8 Byte, uint16 Address);
+uint8 S9xGetC4RAM (uint16 Address);
+
+extern struct SPPU PPU;
+extern struct SDMA DMA [8];
+extern struct InternalPPU IPPU;
+END_EXTERN_C
+
+#include "gfx.h"
+#include "memmap.h"
+
+typedef struct{
+ uint8 _5C77;
+ uint8 _5C78;
+ uint8 _5A22;
+} SnesModel;
+
+START_EXTERN_C
+extern SnesModel* Model;
+extern SnesModel M1SNES;
+extern SnesModel M2SNES;
+END_EXTERN_C
+
+#define MAX_5C77_VERSION 0x01
+#define MAX_5C78_VERSION 0x03
+#define MAX_5A22_VERSION 0x02
+
+STATIC inline uint8 REGISTER_4212()
+{
+ GetBank = 0;
+ if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE &&
+ CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3)
+ GetBank = 1;
+
+ GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0;
+ if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE)
+ GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */
+
+ return (GetBank);
+}
+
+STATIC inline void FLUSH_REDRAW ()
+{
+ if (IPPU.PreviousLine != IPPU.CurrentLine)
+ S9xUpdateScreen ();
+}
+
+STATIC inline void REGISTER_2104 (uint8 byte)
+{
+ if (PPU.OAMAddr & 0x100)
+ {
+ int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1);
+ if (byte != PPU.OAMData [addr]){
+ FLUSH_REDRAW ();
+ PPU.OAMData [addr] = byte;
+ IPPU.OBJChanged = TRUE;
+
+ // X position high bit, and sprite size (x4)
+ struct SOBJ *pObj = &PPU.OBJ [(addr & 0x1f) * 4];
+
+ pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1];
+ pObj++->Size = byte & 2;
+ pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1];
+ pObj++->Size = byte & 8;
+ pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1];
+ pObj++->Size = byte & 32;
+ pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1];
+ pObj->Size = byte & 128;
+ }
+ PPU.OAMFlip ^= 1;
+ if(!(PPU.OAMFlip & 1)){
+ ++PPU.OAMAddr;
+ PPU.OAMAddr &= 0x1ff;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+ }
+ } else {
+ if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE;
+ }
+ } else if(!(PPU.OAMFlip & 1)){
+ PPU.OAMWriteRegister &= 0xff00;
+ PPU.OAMWriteRegister |= byte;
+ PPU.OAMFlip |= 1;
+ if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE;
+ } else {
+ PPU.OAMWriteRegister &= 0x00ff;
+ uint8 lowbyte = (uint8)(PPU.OAMWriteRegister);
+ uint8 highbyte = byte;
+ PPU.OAMWriteRegister |= byte << 8;
+
+ int addr = (PPU.OAMAddr << 1);
+
+ if (lowbyte != PPU.OAMData [addr] ||
+ highbyte != PPU.OAMData [addr+1])
+ {
+ FLUSH_REDRAW ();
+ PPU.OAMData [addr] = lowbyte;
+ PPU.OAMData [addr+1] = highbyte;
+ IPPU.OBJChanged = TRUE;
+ if (addr & 2)
+ {
+ // Tile
+ PPU.OBJ[addr = PPU.OAMAddr >> 1].Name = PPU.OAMWriteRegister & 0x1ff;
+
+ // priority, h and v flip.
+ PPU.OBJ[addr].Palette = (highbyte >> 1) & 7;
+ PPU.OBJ[addr].Priority = (highbyte >> 4) & 3;
+ PPU.OBJ[addr].HFlip = (highbyte >> 6) & 1;
+ PPU.OBJ[addr].VFlip = (highbyte >> 7) & 1;
+ }
+ else
+ {
+ // X position (low)
+ PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00;
+ PPU.OBJ[addr].HPos |= lowbyte;
+
+ // Sprite Y position
+ PPU.OBJ[addr].VPos = highbyte;
+ }
+ }
+ PPU.OAMFlip &= ~1;
+ ++PPU.OAMAddr;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+ }
+ }
+
+ Memory.FillRAM [0x2104] = byte;
+}
+
+STATIC inline void REGISTER_2118 (uint8 Byte)
+{
+ uint32 address;
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;
+ address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff;
+ Memory.VRAM [address] = Byte;
+ }
+ else
+ {
+ Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte;
+ }
+ IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;
+ IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;
+ IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;
+ if (!PPU.VMA.High)
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceVRAM && !CPU.InDMA)
+ {
+ printf ("VRAM write byte: $%04X (%d,%d)\n", PPU.VMA.Address,
+ Memory.FillRAM[0x2115] & 3,
+ (Memory.FillRAM [0x2115] & 0x0c) >> 2);
+ }
+#endif
+ PPU.VMA.Address += PPU.VMA.Increment;
+ }
+// Memory.FillRAM [0x2118] = Byte;
+}
+
+STATIC inline void REGISTER_2118_tile (uint8 Byte)
+{
+ uint32 address;
+ uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;
+ address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff;
+ Memory.VRAM [address] = Byte;
+ IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;
+ IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;
+ IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;
+ if (!PPU.VMA.High)
+ PPU.VMA.Address += PPU.VMA.Increment;
+// Memory.FillRAM [0x2118] = Byte;
+}
+
+STATIC inline void REGISTER_2118_linear (uint8 Byte)
+{
+ uint32 address;
+ Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte;
+ IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;
+ IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;
+ IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;
+ if (!PPU.VMA.High)
+ PPU.VMA.Address += PPU.VMA.Increment;
+// Memory.FillRAM [0x2118] = Byte;
+}
+
+STATIC inline void REGISTER_2119 (uint8 Byte)
+{
+ uint32 address;
+ if (PPU.VMA.FullGraphicCount)
+ {
+ uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;
+ address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF;
+ Memory.VRAM [address] = Byte;
+ }
+ else
+ {
+ Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte;
+ }
+ IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;
+ IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;
+ IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;
+ if (PPU.VMA.High)
+ {
+#ifdef DEBUGGER
+ if (Settings.TraceVRAM && !CPU.InDMA)
+ {
+ printf ("VRAM write word: $%04X (%d,%d)\n", PPU.VMA.Address,
+ Memory.FillRAM[0x2115] & 3,
+ (Memory.FillRAM [0x2115] & 0x0c) >> 2);
+ }
+#endif
+ PPU.VMA.Address += PPU.VMA.Increment;
+ }
+// Memory.FillRAM [0x2119] = Byte;
+}
+
+STATIC inline void REGISTER_2119_tile (uint8 Byte)
+{
+ uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;
+ uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) +
+ (rem >> PPU.VMA.Shift) +
+ ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF;
+ Memory.VRAM [address] = Byte;
+ IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;
+ IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;
+ IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;
+ if (PPU.VMA.High)
+ PPU.VMA.Address += PPU.VMA.Increment;
+// Memory.FillRAM [0x2119] = Byte;
+}
+
+STATIC inline void REGISTER_2119_linear (uint8 Byte)
+{
+ uint32 address;
+ Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte;
+ IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;
+ IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;
+ IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;
+ if (PPU.VMA.High)
+ PPU.VMA.Address += PPU.VMA.Increment;
+// Memory.FillRAM [0x2119] = Byte;
+}
+
+STATIC inline void REGISTER_2122(uint8 Byte)
+{
+ // CG-RAM (palette) write
+
+ if (PPU.CGFLIP)
+ {
+ if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8))
+ {
+ if (Settings.SixteenBit)
+ FLUSH_REDRAW ();
+ PPU.CGDATA[PPU.CGADD] &= 0x00FF;
+ PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8;
+ IPPU.ColorsChanged = TRUE;
+ if (Settings.SixteenBit)
+ {
+ IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f];
+ IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f];
+ IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD],
+ IPPU.Green [PPU.CGADD],
+ IPPU.Blue [PPU.CGADD]);
+ }
+ }
+ PPU.CGADD++;
+ }
+ else
+ {
+ if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff))
+ {
+ if (Settings.SixteenBit)
+ FLUSH_REDRAW ();
+ PPU.CGDATA[PPU.CGADD] &= 0x7F00;
+ PPU.CGDATA[PPU.CGADD] |= Byte;
+ IPPU.ColorsChanged = TRUE;
+ if (Settings.SixteenBit)
+ {
+ IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f];
+ IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f];
+ IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD],
+ IPPU.Green [PPU.CGADD],
+ IPPU.Blue [PPU.CGADD]);
+ }
+ }
+ }
+ PPU.CGFLIP ^= 1;
+// Memory.FillRAM [0x2122] = Byte;
+}
+
+STATIC inline void REGISTER_2180(uint8 Byte)
+{
+ Memory.RAM[PPU.WRAM++] = Byte;
+ PPU.WRAM &= 0x1FFFF;
+ Memory.FillRAM [0x2180] = Byte;
+}
+
+
+//Platform specific input functions used by PPU.CPP
+void JustifierButtons(uint32&);
+bool JustifierOffscreen();
+
+#endif
+
diff --git a/source/problems.txt b/source/problems.txt
new file mode 100644
index 0000000..293df59
--- /dev/null
+++ b/source/problems.txt
@@ -0,0 +1,459 @@
+o FIXED: Aladdin: Mode 7 tile 0 corruption. bug in my delay-by-one-word read
+ V-RAM code.
+o FIXED: Missing sprites on Captain Commando (all negative x coords) - only
+ on asm version, but now...
+o FIXED: Flashing screen on Captain Commando.
+o FIXED: Super Street Fighter 2 won't respond to joy-pad controls.
+o FIXED: Final Fantasy V - text windows are partially hidden - background
+ priority-per tile problem. - needed dual-windowing AND/OR logic mode.
+o FIXED: Tinytoons uses Mode 7 priority per pixel.
+o FIXED: Formation Soccer seems to need transparent mode 7 graphics and sprites
+ behind background.
+o FIXED: Super Aleste has corrupted sprites on title screen.
+o FIXED: Junk on backgrounds of Battle Clash. sub-screen subtract.
+o FIXED: Total Carnage scrolling text is off by a couple of lines, h-dma problem.
+o FIXED: Puzzle Bobble says "this ROM is not designed for you snes".
+o FIXED: Sensible Soccer Mode 0 problems (colours).
+o FIXED: Cannon Fodder shows signs of H-DMA problems when showing mission
+ title screen.
+o FIXED: Alien vs Predator: sprites messed up and screen flashing (screen
+ flashing done on purpose).
+o FIXED: ffmq might require MVN/MVP to always use a 16-bit accumulator.
+o FIXED: Battle Toads crashes after player selection.
+o Mode 5 graphics on snestest.smc Controller Test are corrupt - offset per
+ tile not implemented. NO - H-512 mode not implemented!
+o FIXED: snestest.smc locked up on Electronics test - IRQ never cleared.
+o FIXED: Formation Soccer is doing DMA from a bad area of RAM to V-RAM -
+ needed SPC700 emulation.
+o FIXED: Pacman crashes and problems with sprites on title screen - v-ram
+ reading problem.
+o FIXED: New FF5 graphics problems on title screen.
+o FIXED: MS-DOS machine with single joystick doesn't work.
+o FIXED: Seiken 3 locks up - first in a IRQ loop (its never cleared) then waiting
+ for sound CPU.
+o FIXED: Metriod 3 has a corrupted screen and locks up.
+o FIXED: Mechawarrior 3050 has major problems - corrupt screen, extreamly slow frame
+ time, etc., etc. - needs SetByte and GetByte CPU push code. - So does
+ Weapon Lord!
+o FIXED: **Weapon Lord uses PCALL and TCALL in SPC-700 code **
+o FIXED: Another World is transfering a lot of data using DAM to VRAM and $2180.
+o FIXED: Soulblazer has minor h-dma glitches on vertical background scrolling.
+o FIXED: Secret of the Stars no go - Sound cpu wait problem.
+o FIXED: With reseting IRQ in place in v-line != h-irq-line Battle Toads: Double
+ Dragon works, but Spawn doesn't.
+o FIXED: Memory map problem with Donald Duck (corrupt ROM image).
+o FIXED: Comsmo Puzzle and Yuu Yuu all show "V-RAM increment" type
+ problems (problem was with reading V-RAM).
+o FIXED: Some games rewrite the sprite registers during a frame.
+o FIXED: ILLUSION has horrible sound... (sample decode routine had a bug).
+o FIXED: Find out why graphics are all squashed up on sensi soccer/ bman with old
+ old tile drawing code...
+o FIXED: IRQ wobble on Aladdin at top of screen - causes occational palette flash.
+o FIXED: 7th Saga, Actraiser2 and Addams Family causes a core dump on exit.
+o FIXED: aleste.smc has sprite display problems on title screen on tile-based redraw
+ code.
+o INFO: DKC3 crashes itself if V-RAM isn't filled with zeros!
+o FIXED:Tazmania has stopped working - missing IRQ. Adding a field to
+ Settings moved a variable being used in asm code.
+o FIXED: Castleviana 5 and Sparkster use DMA address decrement to update sprites.
+o FIXED: X-Men has some sprite glitches - but only on tile based redraw code -
+ it blanks the screen early and then DMAs new spite tile data before the
+ usual end of frame.
+o FIXED: Super Punchout shows corrupt knockout timer when H-DMA is enabled.
+ (was triggering H-DMA during a frame) - only trigger H-DMA during v-blank or
+ h-blank, otherwise write to register is ignored.
+o SOUND: Clayfighter, Tazmania, Madden 94-97, NHL 96-97, and WeaponLord
+ all spool sound samples into APU RAM using H-DMA!
+o FIXED: ASM version bug: SOUND: Super Punchout has lots of sound repeat problems.
+o FIXED: DMA? problems on background 3 in SMW.
+o FIXED: Weapon Lord hangs on player selection screen (waiting for SPC700?).
+o FIXED: Killer Instinct shows BG3 on title screen when it shouldn't.
+o FIXED: Blank screen on Rock 'n' Roll Racing - DMA problem.
+o FIXED: SFC Bastard has offset problems on Mode 7 graphics on title screen.
+o FIXED: SOUND: SFC Bastard (bastardy.smc) locks with sound enabled.
+o FIXED: GANBARE GOEMON 2 (sf16232a.078) requires SavedOAMAddr to be set in
+ OAMAddr after end of frame (at max v_counter?).
+o FIXED: SuperOffroad: The Baj has screen flash/timing problems during game -
+ skipping IRQs ? - It was reseting the H-IRQ position so another IRQ would
+ occur on the scanline it was already on.
+o FIXED: R-TYPE 3 has missing scrolling "space" background during game.
+ (location $54 contains $10, needs to contain $11) - not a bug, when run on a
+ real SNES the background is missing as well.
+o FIXED: Toy Story plays sample that walks off end of memory - was causing
+ emulator crashes.
+o FIXED: Bubsy has corrupt graphics - it required register $4210 bit 7 to
+ trigger at the end of h-blank of line 224, not at the start.
+o FIXED: Jurrassic Park locks with sound enabled. (Corrupt ROM image).
+o FIXED: Q*Bert 3 has major graphics problems after 3rd level or locks. With -h 120
+ and VAR_CYCLES game has corrupt graphics, otherwise it crashes. - ROM image
+ is corrupt as same thing happens on a real SNES.
+o FIXED: Evo - Chapter 1 title page shown on two backgrounds at same time -
+ not bug just sub-screen addition being used.
+o FIXED: Ghosts and Ghouls needs H-DMA to be enabled if register is written after
+ start of frame - Super Punchout needs the opposite... -
+ only start H-DMA if enable register written to during v-blank or h-blank.
+o Exhaust Heat might require scanline drawing just before H-DMA rather than
+ at end of h-blank.
+o FIXED: Exhaust Heat has mode 7 offset problems. v0.24 accidentally fixed the problem
+ but now its back again.
+o FIXED: Goal locks at start with sound enabled. - The SPC700 seems to need to
+ start executing instructions before the 65c816 so it has initialised $2140
+ to $BBAA before the '816 checks for that value.
+o FIXED: Final Fight 3 crashes with BRK instruction. - corrupt ROM.
+o FIXED: T2 - has problems with clip windows.
+o Robocop v Terminator: screen flashes like Alien vs Predator.
+o FIXED:Nhl97 crashes - sound APU problem ?
+o FIXED: Nhl97 now doesn't crash, instead the game won't start after the teams have
+ been chosen.
+o FIXED: Shadow Run shows sprite-sprite priority problems.
+o Alien vs Predator uses colour subtraction on sprites but only on palettes 6-7?
+ (Collect cloaking device, second object).
+o NMI might need to be delayed to end of line.
+o JanjYu Gakuen 2 looks at bit 6 of $4211 - might need to show source of
+ IRQ - $40 for V-IRQ and $20 for H-IRQ?
+o FIXED: Sunset riders has repeated background problems(?) - could be sub-screen
+ addition/subtraction. Colour palette changes during game.
+o Priority on snestest.smc Character Test are incorrect.
+o Clay Fighter 2 writes to $3007-8 and reads from $3211-4.
+o FIXED: Shien The Blade Chase tests bit 0 of $4200 until it goes 0 - reading
+ $4200 must reflect joypad reading status. No, actually $4200 is open bus.
+o FIXED: NBAJam (not Tournament Edition) has an odd memory map - accesses
+ code at $3Dxxxx. (corrupt ROM image).
+o Super Bases Loaded uses Mode 5 and the background offset mode.
+o FIXED: Super Bases Loaded 2 has an odd memory map: writes to $E00000 and reads from
+ $E04000! (DSP1 chip)
+o PilotWings uses a DSP.
+o FIXED: Return Of Double Dragon needs -FL -ss 1 -o.
+o FIXED: Tazmania is rewriting the colour palette just before the end of the frame.
+ Shows up a a flashing screen. Uses software not DMA.
+o FIXED: Actraiser2 has screen flash/timing problems. Was rewriting H-DMA
+ start addresses during a frame - real SNES seems to ignore these.
+o Actraiser2 uses mode 7 fixed colour palette mode - "32K" mode.
+o FIXED: Agmawo locks at start. corrupt ROM - looks to be only first part of a
+ multi-part ROM on the CD.
+o FIXED: Alfred Chicken needs -FL.
+o Mighty Max and Addams Family 2 are very slow with sound enabled.
+o Williams Arcade Classics plays sound samples by varying the volume level
+ using the gain control...
+o FIXED:Zoop: Sound works initially but then stops during game.
+o FIXED:Lion King locks up with sound enabled...
+o Sparkster has lots of sound repeat problems.
+o FIXED: Killer Instinct shows corruption at top of screen during the actual fight.
+ Seems to need sub-screen emulation turned on.
+o Look into passing mask into StartHDMA so the routine only resets DMA
+ channels with the bit set in the bit mask.
+o FIXED: RPM racing uses mode 5 512x512.
+o FIXED: Biker Mice From Mars (sfbiker) needs -N and flipped layering '8'.
+o FIXED: Mario and Wario (sfmarwar.smc) needs a mouse.
+o Battle Toads: Double Dragon needs the -h parameter set to 100.
+o FIXED: SF8752.smc has sprites problems when using tile-redraw code.
+o FIXED: NHL '97 does a JMP $4320 in bank $87 - $4320 is a register area in that
+ bank.
+o FIXED: Chuck Rock has corrupted sprites on the title screen.
+o FIXED: War of the Gems crashes with a STP instruction - bug in asm version of
+ CPU core - appears when status register spliting was added. Snap6.
+ If IRQ pending after returning from an NMI then incorrect status pushed
+ onto stack.
+o Adventures of Batman & Robin (bat.smc) has really slow music on title
+ screen with SPC700 shutdown enabled.
+o Return of the Jedi has lots of sound problems.
+o WORMS has vertical offset problems on BG1 when displaying life bar at top
+ of screen.
+o FIXED: Street Racer has corrupt sprites on the player select screen.
+o FIXED: Super Bases Loaded 1 uses Mode 5 (512x224) on intro.
+o INFO: Batman Forever uses sub-screen addition with bg's being on both the main
+ screen and sub-screen.
+o INFO: Intro of Beavis and Butthead uses sub-screen addition with bg's being on
+ both the main screen and sub-screen.
+o INFO: ebreaker.smc bg's on both main and sub-screen.
+o Big Sky Trooper's music is very slow.
+o FIXED: Bomberman 4 needs -FH.
+o FIXED: Captain Commando is interleaved.
+o FIXED: Crystal Bean locks at start and is interleaved. - corrupt ROM image.
+o Jim Power (jimp.smc) has scrolling/H-DMA problems on the intro.
+o FIXED: Ogre Battle has fixed colour subtract problems on the main screen.
+o pacman and Jim Power intro seem to rely on maximum number of sprites on a
+ scanline at once to hide unwanted sprites.
+o FIXED: Pacman 2 has scrolling/H-DMA problems during the game.
+o FIXED: Power Drive (snk_powd.smc) uses 512x448 on intro.
+o FIXED: SKI PARADISE (skiparad.fig) uses mode 7 priority per pixel
+o The Magical Quest (smmouse.smc) has an intro with bad raster glitches - uses
+ exact CPU timing!
+o FIXED: Madden 96 needs -FH and has new Antherox intro.
+o FIXED: College Slam (collslam.1 on CD) thinks non-standard controllers are
+ connected. It writes $12 and $02 to $4016.
+o The sound on Speedy Gonzales sounds out of tune - seems to vary the
+ frequency a lot - first low byte then the high byte.
+o Stargate has sound clicks on channels 5 and 6 on title page.
+o FIXED: Ranman1/2 Part 1 (ranma121.smc) crashes SPC700 at start up - looks like a
+ 65c816 addressing mode/instruction bug! - corrupt ROM image.
+o Speedy Gonzales starts a long DMA to $2180 at v-line 1 with the screen not
+ blanked.
+o FIXED: acc-elf.smc works on v0.1 but crashes with a STP instruction in v0.24.
+o FIXED: FLYING HERO BUGYURU flyhero.smc does not work and image is odd size so code
+ doesn't detect header and remove it.
+o FIXED: Yaiba (lmk_yaib.smc) locks waiting for an interrupt to occur to no interrupts
+ are enabled.
+o CORRUPT ROM: Rise of the Robots does a long DMA to V-RAM during in the NMI handler -
+ it might require the DMA to automatically stop when H-DMA starts if the
+ screen is not blanked.
+o FIXED: Andrew Agassi Tennis has missing sprites - only writes to low byte
+ of sprite write address register. Writing to low byte must clear hi-byte as
+ well.
+o FIXED: Bonkers locks sound enabled. SPC700 code expected KOFF DSP register
+ to return value just written.
+o Mario Kart has odd graphic windows settings when first started.
+o FIXED: Street Racer has odd size sprites and has missing tiles when displayed.
+o FIXED: ASM 65c816, Aladdin keeps warping to other side of screen on first level.
+o The Great Circus Mystery (circusmystery.smc) doesn't work.
+o James Pond 2 gets stuck waiting for SPC700 to respond after first title
+ screen. works on v0.24.
+o Mario All stars - Super Mario 2 uses mode 2 (offset per tile) but with
+ height 64 on bg #2. Black screen.
+o FIXED: Chrono Trigger uses mode 2 with width 64 for wavey 'Trigger' text. Text
+ should scroll onto screen, it doesn't. It does if width 64 is disabled,
+ but it starts on the screen first. - bug with not wrapping Quot variable
+ with mode 2 width 64.
+o Tetris Attack uses screen screen height of 64 on offset-per-tile mode 2.
+o Batman forever might show that if OBJs are on both the main and sub-screens
+ and colour addition is enabled, then only OBjs with palette numbers
+ 4 or greater take part in colour addition and are not displayed on the
+ sub-screen.
+o FIXED: CPUShutdown causes problems for ROMs that wait for h-blank using $4212
+ during the v-blank period - Reschedule doesn't enable HBLANK_START_EVENT
+ during the v-blank period so the cycle skipping code doesn't wake up the
+ CPU until h-blank end.
+o FIXED: Putty Squad seems to use wrong palette for each tile when mosaic effect
+ is being used - could be only the ROM so far with 16x16 pixels tiles and
+ mosaic effect.
+o FIXED: Mortal Kombat 1 restarts level when once the 'fight' message has disappeared.
+ - 0.31 has problems.
+ - 13-03-98 problems.
+ - 1-4-98 problems.
+ Problem with asm code only and intermittent.
+o FIXED: Clay fighter has problems with colour window when the game starts and the
+ game locks up anyway. ... but still sound repeat problems.
+o FIXED: VAMPIRES KISS has corrupt, flashing OBJs and some v-ram problems,
+ no problems in 0.41. Problem not dma, ppu, or cpuexec.
+ - Problem was H-DMA was being started inside v-blank period.
+o FIXED: VAMPIRES KISS has tile glitches on bg#2 during game - not present in
+ 0.41. H-DMA?
+o FIXED: Contra 3 has clip window problems resulting in black screen, only
+ OBJs can be seen when game first starts.
+o FIXED: YUUYUU TOKUBETUHEN (yuyut.smc) has missing OBJs when screen is split -
+ it enables both clip windows on OBJ and sets the combination mode to
+ AND but both clip windows only overlap a few pixels so the OBJs are not
+ displayed. - bug in window code, needed to flip the logic window
+ combination mode because the window area add already been flipped.
+o Multiple colour add/sub and clip window bugs with Killer Instinct.
+o T2: Arcade Game displays multi-coloured blocks of tiles when a mode 3
+ screen is being displayed. Screen shown when game-over.
+o Bomberman 5 flickers on title screen when H-DMA is enabled.
+o FIXED: XOR window clip code is producing bands that overlap.
+o TOKIMEKI MEMORIAL (tokmemor.smc) uses hi-res., mosasic effect and fixed
+ colour addition.
+o FIXED: TOKIMEKI MEMORIAL (tokmemor.smc) displays corrupted sprites - every other
+ group of four pixels is missing.
+o RPM racing (hi-res. interlace) displays blank screen with 8-bit renderer.
+o FIXED: Lufia I locks is shutdown is enabled. Asm only.
+o FIXED: The SPC700 in Universal Solider locks if shutdown is enabled. Asm only.
+o FIXED: Disabling the Multi Player 5 switches controller 1 to a mouse !
+o FIXED: Top Gear 3000 - DSP1? game, though ROM header doesn't mention it.
+ Bug in ROM header detection code.
+o FIXED: Lost Vikings II locks after title screen - works in 0.24.
+o Lost Vikings locks or resets on all versions.
+o Uniracers enables sub-screen addition on bg # 2 but with nothing on the
+ the sub-screen. Should it be either the fixed colour or back-drop
+ colour get added instead?
+o Wile E's Revenge has missing music, and very quite sound. Also displays
+ rotated mode 7 character picture during titles.
+o Pilot Wings tries to set up a V-IRQ to happen on the line its already on,
+ uses IRQ to switch to mode 7. -h 120 fixes problem. Cycle timing must be
+ off.
+o Top Gear 3000 sits in a loop waiting for the H-DMA line count register
+ to reach a particular value - it never does because its not emulated yet!
+o Theme Park starts a rather crummy tune then crashes. Hacker intro?
+o Killer Instinct has a one-pixel wide bright line part way down screen
+ on orcid practice level - colour window invert bug?
+o Killer Instinct bg #1 is hidding some transparency effects and the
+ fighter's sprite shadows on some levels.
+o Batman - revenge of the joker locks at start - waiting for SPC700 which
+ has hit a stop instruction.
+o Eye of the Beholder has strange mouse pointer movement problems when SNES
+ mouse emulation is enabled.
+o FIXED: Daffy duck has lots of scrolling glitches on background parallax effects -
+ timing problems? Missing NMI - ROM kept turning NMI enable flag on and off.
+o Aero the AcroBat 2 might wait until a bit in $420B (h-dma enable) clears -
+ does reading that register indicate H-DMA channels in progress?
+o Ardy Lightfoot and Oblix both flash the sprite of the main character
+ on and off every other frame, should they do this or is it a bug?
+o FIXED: Firemen locks at start waiting for SPC700. Human game, needs -ratio 3.
+o Jim Power has a one pixel wide bright line down one side of screen on the
+ level map screen.
+o Lots of missing sound effects in Home Alone 2.
+o Missing sound effects in Earth Worm Jim 2.
+o Captain America has single pixel high line corruption through some of its
+ tiles.
+o NHL STANLEY CUP locks at start waiting for the SPC700 - works with sound
+ disabled.
+o Sailor Moon has colour window problems during intro of game.
+o Sailor Moon R screen flashes black during game. -h 102 fixes.
+o Tile corruption on Super Pang on 3rd level+ - only on DOS port.
+o Mighty Max uses colour window on main screen to clip background colour
+ palette changes - except its not working on Snes9x.
+o FIXED: Battle Toads: Battlemanics crashes during intro - ROM's NMI handler does not
+ switch index registers to 16-bit before pushing them onto the stack, but
+ always switches them to 16-bit mode when restoring them.
+ NMI timing problem.
+o FIXED: Contra 3 has missing fire effects when bomber plane drops bombs - use
+ freeze-game to see. - Colour window is fully clipping the sub-screen and
+ the fire effects are only on the sub-screen.
+ - colour window invert bug.
+o FIXED: Illusion of Gaia uses sub-screen subtraction with half flag during game
+ select. Also, uses colour window to cut a hole in the main-screen,
+ should the sub-screen be visible at this point? Only two backgrounds are
+ being displayed, one on the main-screen and one on the sub-screen and
+ the sub-screen is not being added to the background only the background on
+ the main-screen.
+o FIXED: Gun force uses background #2 to display horizontal bullets fired from
+ player, but they are displayed offset from the main firing them. H-DMA transfer
+ size array was not set for the mirrored channels.
+o FIXED: Empire Strikes Back needs -ratio 5 to work.
+o Empire Strikes Back: The Hoth battle stage uses mode 7, priority per pixel
+ and part of the graphics are missing.
+o FIXED: llusion of Gaia menu on the first screen should be on a dark background.
+ ZSNES gets it correct.
+o DOS port can't load some ROMs from CD. NLKE has same problem. Allegro?
+ ZSNES loads most of them fine.
+o -frametime option is broken.
+o Jap version of Tetris Attack might have a scrolling bug on the title screen.
+o FIXED: Commodore 64 emulator doesn't work with asm CPU core - works fine with
+ C code.
+o FIXED: Chrono Trigger: crash bug in clipping code - use snapshot F6 and press 's'.
+ Corrupts stack causing crash.
+o FIXED: Toy Story only updates screen every-other frame and woody flashes
+ continuously. (Woody flashing is due to hacked ROM)
+ Toy Story requires NMI to happen immediately after a WAI instruction.
+o Toy Story has garbled sound output just before game starts. DOS port only.
+o FIXED: Tales of Phantasia executes across a 0x8000 boundary and either side of
+ the boundary are at different offsets into the ROM. Causes a crash.
+o RPM Racing doesn't display correctly when interpolation and 16-bit screen
+ mode. X11 port. Works when full-screen X.
+o FIXED: Itchy & Scratchy has sprite corruption on the one of the title screens.
+ Problem appeared between v0.4 and v0.41.
+o Start screen on Chase HQ is corrupt. v0.24 has same problem.
+o FIXED: King of the Rally has missing music on the car-feature selection screen.
+ Works in v1.00. Requires DP+X addresses to wrap in zero page.
+o FIXED: (again) Lufia I locks is shutdown is enabled waiting for SPC700.
+ made the SPC700 wake up if the 65c816 reads from the one of the 4 comm ports.
+ The SPC700 used to only wake up when the 65c816 wrote to the ports.
+o WWF-Arcade crashes - calls a subroutine at address $EE758D which only
+ contains zeros at that address. Memory map bug?
+o WWF-Super Wrestlemania and WWF-Raw both seem to display junk background
+ layers - the ROM enables the layers but does not set up any background data.
+o WWF-Super Wrestlemania crashes just before the game starts. Memory map bug?
+o FIXED: Ninja Warriors has missing graphics on the title screen - V-IRQ problem?
+ Problem appears after v1.16. Didn't like H-IRQ triggering on the same line
+ if the H-IRQ position register was updated.
+o Yoshi's Island might show there's an 'off-by-one' bug in the clip window code
+ when it pops up a message box.
+o Tazmania has ticking on the sound during the initial title music.
+o SuperScope 6 has a repeating gun-fire sound on the initial aim screen.
+ Channel volume is set to gain mode.
+o Stargate sometimes has a slight click sound at the end of each rapid soft
+ beep when the start button is pressed on the title page. Channel 6 is the
+ problem, has attack rate of 10ms, decay 1200ms, infinate sustain and a
+ sustain level of 5.
+o Kirby Superstar - SA-1 game? YEP!
+o The Lion King: under sound test, continue long song contains some odd
+ sounding notes. Is a particular type of sample not being decoded correctly?
+o Clicks on the title music of Madden 98.
+o Bugs Bunny has sound repeat problems when Bugs kicks a dog. - not a problem,
+ just needs -envx.
+o Bugs Bunny has junk snow characters on bg #1.
+o Airwolf hacker intro is very corrupt - corrupt ROM?
+o FIXED:Pac-in-time title music sounds a lot worse with new envelope sound code in
+ 1.17. The game requires samples to be keyed on without being keyed off first.
+o DOREMI Fantasy milon uses decay exponential volume envelope on the notes at
+ the end of the title music - they seem to take too long to decay.
+o Winter Gold causes ZSNES Super FX code to overwrite the static data after its
+ allocation - was causing the X library to crash since that was the .o after
+ linked after zsnes.o.
+o FIXED: Micromachines 2 has continuing engine noise problem when race is over -
+ sound channel 7 is in sustain mode with time period set to infinite.
+ - must have updated ADSR parameters as the it was in progress.
+o DONE: Check Micromachines on real SNES - does the Ocean logo shear at the start?
+ If it doesn't it could be a bug in the mode 7 code - the same problem that
+ affects battle racers. - Does the same thing on a real SNES.
+o FIXED: LAMBORGHINI AMERICAN has lots of missing music notes -
+ uses bent-line inc with attack rate of infinite?
+ - S9xSetEnvRate thought that the channel was silent and hence the number of
+ volume steps was 0 so erate was always being set to 0.
+o Slight clicking on the sound of Wild Snake - not sound sync or interpolation
+ bug.
+o FIXED: Zoop locks up at the end of each level playing random sound data on one
+ channel and the main SNES CPU seems to be waiting for the sound channel to
+ finish. - ENVX should return zero when channel is in gain mode.
+o Battle Racers might have missing music during the race.
+o Tactics Ogre has missing music and ROM locks up if you visit the sound menu.
+o FIXED: Dragon Quest 5: the monsters disappear during fight sequences when the
+ fireball is used (freeze file 004).
+ - H-DMA needs to continue for one extra line, e.g. for screen height of
+ 239 H-DMA needs to run from line 0 to line 239, inclusive.
+o Stargate sound click problem during some music - makes large changes to
+ channel volume levels while the sound is still playing, but other problems
+ seem to be causing the click.
+o Super Air Diver 2, Pilotwings and SD Racing DSP all suffer from the same
+ shear DSP1 emulation bug. Bug in op 0x02/0x1a/0x0a to do with viewing angle
+ and rotation.
+o Super Air Diver 1 locks at start waiting for sound CPU.
+o FIXED: Ballz generates unknown DSP1 command 2f and 0f then locks up on title
+ screen. Implemented new Ops
+o FIXED: Highway Battle 2 generates unknown DSP1 command 2f and lots of different
+ unknown DSP1 commands during play. The mode 7 screen is all messed up. Hacked game,
+ but the DSP routines were inaccurate.
+o FIXED: Dungenon Master generates lots of unknown DSP1 commands errors. It's DSP-2.
+o F1 Roc 2 isn't a DSP1 - uses some form of custom chip.
+o F1 Roc 2 has graphic window clip problems with the clip code.
+o Vertical mouse movement on Eye of the Beholder is very erratic.
+o BT IN BATTLEMANIACS has slight sound click problems during the opening music.
+o Bomberman 5 - sound test, music 22 doesn't sound correct. Sounds different on
+ three different versions 1.00, 1.16 and 1.18.
+o FIXED: Sprite priority bug on title screen of ILLUSION OF GAIA.
+o FIXED: James Pond 2 - random horizontal sprite movement between two places, seems
+ OK in 1.11 (only slight bug with battery level) but broken in 1.16. Sprite code relies
+ on funky behavior.
+o Jigsaw Party objects to multi-player 5 emulation, game won't start with it
+ enabled.
+o FIXED: The ROM load code thinks Eek The Cat is in interleave format, it isn't.
+o FIXED: Primal Rage v1.20 - major graphics problem problems, not in v1.19.
+o FIXED: Mario Kart - single player mode, pressing select to use rear view mirror
+ results in corrupt graphics. - inverse of an empty colour window should be
+ whole screen.
+o FIXED:Missing logo from FF5 start up screen. - mode 7 was always using
+ main-screen z-buffer.
+o FIXED: Something is zeroing the ZSNES SfxnRamBanks variable in Yoshi's Island,
+ allowing the code to set junk values in the ROMBR register which in turn
+ can cause an illegal memory access when the Super FX tries to access its RAM.
+ - ZSNES code bug.
+o FIXED: Background scrolling glitches on Stargate.
+ - skipping NMIs. Stopped NMI retriggering in same screen.
+o Metal Combat - in the title screen speech the '93 of the 1993 words get cut
+ off earily
+o POWER RANGERS FIGHT during the game the score area breaks up and scrolls when
+ it shouldn't and there is corruption in the character graphics.
+o FIXED: Maui Mallard doesn't show the water background layer correctly.
+
+o Seiken 3 3dfx type screen breakup bug in windows port with 'sal mode
+ enabled.
+o FIXED: RexRonanExperimentalSurgeonUSA layering problem in title screens.
+ - wasn't wrapping V-RAM addresses for screen (bg) locations.
+o PANIC BOMBER WORLD locks up on title screen
+o Doom segfaults after splash screen if i386 core is used on Linux.
+o Doom hangs when shooting a barrel if C++ core is used on Linux.
+o Cu On Pa locks up at the player select screen - input not handled. Timing?
+o Madara 2 menus should have a blue window clipped out - hi-res clipping behavior?
+o Shin Megami Tensei fusion screen - corrupt graphics - $2105 seems to be getting set
+ to 0 instead of 9.
+o Dragon Ball Z - Super Butoden 2 (J) 1.1 - flashing graphics at the start of
+ a fight and then later if the screen gets splitted.
diff --git a/source/sa1.cpp b/source/sa1.cpp
new file mode 100644
index 0000000..39b08bb
--- /dev/null
+++ b/source/sa1.cpp
@@ -0,0 +1,943 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "ppu.h"
+#include "cpuexec.h"
+
+#include "sa1.h"
+
+static void S9xSA1CharConv2 ();
+static void S9xSA1DMA ();
+static void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift);
+
+void S9xSA1Init ()
+{
+ SA1.NMIActive = FALSE;
+ SA1.IRQActive = FALSE;
+ SA1.WaitingForInterrupt = FALSE;
+ SA1.Waiting = FALSE;
+ SA1.Flags = 0;
+ SA1.Executing = FALSE;
+ memset (&Memory.FillRAM [0x2200], 0, 0x200);
+ Memory.FillRAM [0x2200] = 0x20;
+ Memory.FillRAM [0x2220] = 0x00;
+ Memory.FillRAM [0x2221] = 0x01;
+ Memory.FillRAM [0x2222] = 0x02;
+ Memory.FillRAM [0x2223] = 0x03;
+ Memory.FillRAM [0x2228] = 0xff;
+ SA1.op1 = 0;
+ SA1.op2 = 0;
+ SA1.arithmetic_op = 0;
+ SA1.sum = 0;
+ SA1.overflow = FALSE;
+ SA1.S9xOpcodes=NULL;
+}
+
+void S9xSA1Reset ()
+{
+ SA1Registers.PB = 0;
+ SA1Registers.PC = Memory.FillRAM [0x2203] |
+ (Memory.FillRAM [0x2204] << 8);
+ SA1Registers.D.W = 0;
+ SA1Registers.DB = 0;
+ SA1Registers.SH = 1;
+ SA1Registers.SL = 0xFF;
+ SA1Registers.XH = 0;
+ SA1Registers.YH = 0;
+ SA1Registers.P.W = 0;
+
+ SA1.ShiftedPB = 0;
+ SA1.ShiftedDB = 0;
+ SA1SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation);
+ SA1ClearFlags (Decimal);
+
+ SA1.WaitingForInterrupt = FALSE;
+ SA1.PC = NULL;
+ SA1.PCBase = NULL;
+ S9xSA1SetPCBase (SA1Registers.PC);
+ SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
+
+ S9xSA1UnpackStatus();
+ S9xSA1FixCycles ();
+ SA1.Executing = TRUE;
+ SA1.BWRAM = Memory.SRAM;
+ Memory.FillRAM [0x2225] = 0;
+}
+
+void S9xSA1SetBWRAMMemMap (uint8 val)
+{
+ int c;
+
+ if (val & 0x80)
+ {
+ for (c = 0; c < 0x400; c += 16)
+ {
+ SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2;
+ SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2;
+ SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2;
+ SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2;
+ }
+ SA1.BWRAM = Memory.SRAM + (val & 0x7f) * 0x2000 / 4;
+ }
+ else
+ {
+ for (c = 0; c < 0x400; c += 16)
+ {
+ SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM;
+ SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM;
+ SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM;
+ SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM;
+ }
+ SA1.BWRAM = Memory.SRAM + (val & 7) * 0x2000;
+ }
+}
+
+void S9xFixSA1AfterSnapshotLoad ()
+{
+ SA1.ShiftedPB = (uint32) SA1Registers.PB << 16;
+ SA1.ShiftedDB = (uint32) SA1Registers.DB << 16;
+
+ S9xSA1SetPCBase (SA1.ShiftedPB + SA1Registers.PC);
+ S9xSA1UnpackStatus ();
+ S9xSA1FixCycles ();
+ SA1.VirtualBitmapFormat = (Memory.FillRAM [0x223f] & 0x80) ? 2 : 4;
+ Memory.BWRAM = Memory.SRAM + (Memory.FillRAM [0x2224] & 7) * 0x2000;
+ S9xSA1SetBWRAMMemMap (Memory.FillRAM [0x2225]);
+
+ SA1.Waiting = (Memory.FillRAM [0x2200] & 0x60) != 0;
+ SA1.Executing = !SA1.Waiting;
+}
+
+uint8 S9xSA1GetByte (uint32 address)
+{
+ uint8 *GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ return (*(GetAddress + (address & 0xffff)));
+
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_PPU:
+ return (S9xGetSA1 (address & 0xffff));
+ case CMemory::MAP_LOROM_SRAM:
+ case CMemory::MAP_SA1RAM:
+ return (*(Memory.SRAM + (address & 0xffff)));
+ case CMemory::MAP_BWRAM:
+ return (*(SA1.BWRAM + ((address & 0x7fff) - 0x6000)));
+ case CMemory::MAP_BWRAM_BITMAP:
+ address -= 0x600000;
+ if (SA1.VirtualBitmapFormat == 2)
+ return ((Memory.SRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3);
+ else
+ return ((Memory.SRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15);
+ case CMemory::MAP_BWRAM_BITMAP2:
+ address = (address & 0xffff) - 0x6000;
+ if (SA1.VirtualBitmapFormat == 2)
+ return ((SA1.BWRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3);
+ else
+ return ((SA1.BWRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15);
+
+ case CMemory::MAP_DEBUG:
+ default:
+#ifdef DEBUGGER
+// printf ("R(B) %06x\n", address);
+#endif
+ return OpenBus;
+ }
+}
+
+uint16 S9xSA1GetWord (uint32 address)
+{
+ OpenBus = S9xSA1GetByte (address);
+ return (OpenBus | (S9xSA1GetByte (address + 1) << 8));
+}
+
+void S9xSA1SetByte (uint8 byte, uint32 address)
+{
+ uint8 *Setaddress = SA1.WriteMap [(address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+
+ if (Setaddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+ *(Setaddress + (address & 0xffff)) = byte;
+ return;
+ }
+
+ switch ((int) Setaddress)
+ {
+ case CMemory::MAP_PPU:
+ S9xSetSA1 (byte, address & 0xffff);
+ return;
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ *(Memory.SRAM + (address & 0xffff)) = byte;
+ return;
+ case CMemory::MAP_BWRAM:
+ *(SA1.BWRAM + ((address & 0x7fff) - 0x6000)) = byte;
+ return;
+ case CMemory::MAP_BWRAM_BITMAP:
+ address -= 0x600000;
+ if (SA1.VirtualBitmapFormat == 2)
+ {
+ uint8 *ptr = &Memory.SRAM [(address >> 2) & 0xffff];
+ *ptr &= ~(3 << ((address & 3) << 1));
+ *ptr |= (byte & 3) << ((address & 3) << 1);
+ }
+ else
+ {
+ uint8 *ptr = &Memory.SRAM [(address >> 1) & 0xffff];
+ *ptr &= ~(15 << ((address & 1) << 2));
+ *ptr |= (byte & 15) << ((address & 1) << 2);
+ }
+ break;
+ case CMemory::MAP_BWRAM_BITMAP2:
+ address = (address & 0xffff) - 0x6000;
+ if (SA1.VirtualBitmapFormat == 2)
+ {
+ uint8 *ptr = &SA1.BWRAM [(address >> 2) & 0xffff];
+ *ptr &= ~(3 << ((address & 3) << 1));
+ *ptr |= (byte & 3) << ((address & 3) << 1);
+ }
+ else
+ {
+ uint8 *ptr = &SA1.BWRAM [(address >> 1) & 0xffff];
+ *ptr &= ~(15 << ((address & 1) << 2));
+ *ptr |= (byte & 15) << ((address & 1) << 2);
+ }
+ default:
+ return;
+ }
+}
+
+void S9xSA1SetWord (uint16 Word, uint32 address)
+{
+ S9xSA1SetByte ((uint8) Word, address);
+ S9xSA1SetByte ((uint8) (Word >> 8), address + 1);
+}
+
+void S9xSA1SetPCBase (uint32 address)
+{
+ uint8 *GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK];
+ if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
+ {
+ SA1.PCBase = GetAddress;
+ SA1.PC = GetAddress + (address & 0xffff);
+ return;
+ }
+
+ switch ((int) GetAddress)
+ {
+ case CMemory::MAP_PPU:
+ SA1.PCBase = Memory.FillRAM - 0x2000;
+ SA1.PC = SA1.PCBase + (address & 0xffff);
+ return;
+
+ case CMemory::MAP_CPU:
+ SA1.PCBase = Memory.FillRAM - 0x4000;
+ SA1.PC = SA1.PCBase + (address & 0xffff);
+ return;
+
+ case CMemory::MAP_DSP:
+ SA1.PCBase = Memory.FillRAM - 0x6000;
+ SA1.PC = SA1.PCBase + (address & 0xffff);
+ return;
+
+ case CMemory::MAP_SA1RAM:
+ case CMemory::MAP_LOROM_SRAM:
+ SA1.PCBase = Memory.SRAM;
+ SA1.PC = SA1.PCBase + (address & 0xffff);
+ return;
+
+ case CMemory::MAP_BWRAM:
+ SA1.PCBase = SA1.BWRAM - 0x6000;
+ SA1.PC = SA1.PCBase + (address & 0xffff);
+ return;
+ case CMemory::MAP_HIROM_SRAM:
+ SA1.PCBase = Memory.SRAM - 0x6000;
+ SA1.PC = SA1.PCBase + (address & 0xffff);
+ return;
+
+ case CMemory::MAP_DEBUG:
+#ifdef DEBUGGER
+ printf ("SBP %06x\n", address);
+#endif
+
+ default:
+ case CMemory::MAP_NONE:
+ SA1.PCBase = Memory.RAM;
+ SA1.PC = Memory.RAM + (address & 0xffff);
+ return;
+ }
+}
+
+void S9xSA1ExecuteDuringSleep ()
+{
+#if 0
+ if (SA1.Executing)
+ {
+ while (CPU.Cycles < CPU.NextEvent)
+ {
+ S9xSA1MainLoop ();
+ CPU.Cycles += TWO_CYCLES * 2;
+ }
+ }
+#endif
+}
+
+void S9xSetSA1MemMap (uint32 which1, uint8 map)
+{
+ int c;
+ int start = which1 * 0x100 + 0xc00;
+ int start2 = which1 * 0x200;
+
+ if (which1 >= 2)
+ start2 += 0x400;
+
+ for (c = 0; c < 0x100; c += 16)
+ {
+ uint8 *block = &Memory.ROM [(map & 7) * 0x100000 + (c << 12)];
+ int i;
+
+ for (i = c; i < c + 16; i++)
+ Memory.Map [start + i] = SA1.Map [start + i] = block;
+ }
+
+ for (c = 0; c < 0x200; c += 16)
+ {
+ uint8 *block = &Memory.ROM [(map & 7) * 0x100000 + (c << 11) - 0x8000];
+ int i;
+
+ for (i = c + 8; i < c + 16; i++)
+ Memory.Map [start2 + i] = SA1.Map [start2 + i] = block;
+ }
+}
+
+uint8 S9xGetSA1 (uint32 address)
+{
+// printf ("R: %04x\n", address);
+ switch (address)
+ {
+ case 0x2300:
+ return ((uint8) ((Memory.FillRAM [0x2209] & 0x5f) |
+ (CPU.IRQActive & (SA1_IRQ_SOURCE | SA1_DMA_IRQ_SOURCE))));
+ case 0x2301:
+ return ((Memory.FillRAM [0x2200] & 0xf) |
+ (Memory.FillRAM [0x2301] & 0xf0));
+ case 0x2306:
+ return ((uint8) SA1.sum);
+ case 0x2307:
+ return ((uint8) (SA1.sum >> 8));
+ case 0x2308:
+ return ((uint8) (SA1.sum >> 16));
+ case 0x2309:
+ return ((uint8) (SA1.sum >> 24));
+ case 0x230a:
+ return ((uint8) (SA1.sum >> 32));
+ case 0x230c:
+ return (Memory.FillRAM [0x230c]);
+ case 0x230d:
+ {
+ uint8 byte = Memory.FillRAM [0x230d];
+
+ if (Memory.FillRAM [0x2258] & 0x80)
+ {
+ S9xSA1ReadVariableLengthData (TRUE, FALSE);
+ }
+ return (byte);
+ }
+ default:
+ printf ("R: %04x\n", address);
+ break;
+ }
+ return (Memory.FillRAM [address]);
+}
+
+void S9xSetSA1 (uint8 byte, uint32 address)
+{
+//printf ("W: %02x -> %04x\n", byte, address);
+ switch (address)
+ {
+ case 0x2200:
+ SA1.Waiting = (byte & 0x60) != 0;
+// SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes;
+
+ if (!(byte & 0x20) && (Memory.FillRAM [0x2200] & 0x20))
+ {
+ S9xSA1Reset ();
+ }
+ if (byte & 0x80)
+ {
+ Memory.FillRAM [0x2301] |= 0x80;
+ if (Memory.FillRAM [0x220a] & 0x80)
+ {
+ SA1.Flags |= IRQ_PENDING_FLAG;
+ SA1.IRQActive |= SNES_IRQ_SOURCE;
+ SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes;
+ }
+ }
+ if (byte & 0x10)
+ {
+ Memory.FillRAM [0x2301] |= 0x10;
+#ifdef DEBUGGER
+ printf ("###SA1 NMI\n");
+#endif
+ if (Memory.FillRAM [0x220a] & 0x10)
+ {
+ }
+ }
+ break;
+
+ case 0x2201:
+ if (((byte ^ Memory.FillRAM [0x2201]) & 0x80) &&
+ (Memory.FillRAM [0x2300] & byte & 0x80))
+ {
+ S9xSetIRQ (SA1_IRQ_SOURCE);
+ }
+ if (((byte ^ Memory.FillRAM [0x2201]) & 0x20) &&
+ (Memory.FillRAM [0x2300] & byte & 0x20))
+ {
+ S9xSetIRQ (SA1_DMA_IRQ_SOURCE);
+ }
+ break;
+ case 0x2202:
+ if (byte & 0x80)
+ {
+ Memory.FillRAM [0x2300] &= ~0x80;
+ S9xClearIRQ (SA1_IRQ_SOURCE);
+ }
+ if (byte & 0x20)
+ {
+ Memory.FillRAM [0x2300] &= ~0x20;
+ S9xClearIRQ (SA1_DMA_IRQ_SOURCE);
+ }
+ break;
+ case 0x2203:
+// printf ("SA1 reset vector: %04x\n", byte | (Memory.FillRAM [0x2204] << 8));
+ break;
+ case 0x2204:
+// printf ("SA1 reset vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2203]);
+ break;
+
+ case 0x2205:
+// printf ("SA1 NMI vector: %04x\n", byte | (Memory.FillRAM [0x2206] << 8));
+ break;
+ case 0x2206:
+// printf ("SA1 NMI vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2205]);
+ break;
+
+ case 0x2207:
+// printf ("SA1 IRQ vector: %04x\n", byte | (Memory.FillRAM [0x2208] << 8));
+ break;
+ case 0x2208:
+// printf ("SA1 IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2207]);
+ break;
+
+ case 0x2209:
+ Memory.FillRAM [0x2209] = byte;
+ if (byte & 0x80)
+ Memory.FillRAM [0x2300] |= 0x80;
+
+ if (byte & Memory.FillRAM [0x2201] & 0x80)
+ {
+ S9xSetIRQ (SA1_IRQ_SOURCE);
+ }
+ break;
+ case 0x220a:
+ if (((byte ^ Memory.FillRAM [0x220a]) & 0x80) &&
+ (Memory.FillRAM [0x2301] & byte & 0x80))
+ {
+ SA1.Flags |= IRQ_PENDING_FLAG;
+ SA1.IRQActive |= SNES_IRQ_SOURCE;
+// SA1.Executing = !SA1.Waiting;
+ }
+ if (((byte ^ Memory.FillRAM [0x220a]) & 0x40) &&
+ (Memory.FillRAM [0x2301] & byte & 0x40))
+ {
+ SA1.Flags |= IRQ_PENDING_FLAG;
+ SA1.IRQActive |= TIMER_IRQ_SOURCE;
+// SA1.Executing = !SA1.Waiting;
+ }
+ if (((byte ^ Memory.FillRAM [0x220a]) & 0x20) &&
+ (Memory.FillRAM [0x2301] & byte & 0x20))
+ {
+ SA1.Flags |= IRQ_PENDING_FLAG;
+ SA1.IRQActive |= DMA_IRQ_SOURCE;
+// SA1.Executing = !SA1.Waiting;
+ }
+ if (((byte ^ Memory.FillRAM [0x220a]) & 0x10) &&
+ (Memory.FillRAM [0x2301] & byte & 0x10))
+ {
+#ifdef DEBUGGER
+ printf ("###SA1 NMI\n");
+#endif
+ }
+ break;
+ case 0x220b:
+ if (byte & 0x80)
+ {
+ SA1.IRQActive &= ~SNES_IRQ_SOURCE;
+ Memory.FillRAM [0x2301] &= ~0x80;
+ }
+ if (byte & 0x40)
+ {
+ SA1.IRQActive &= ~TIMER_IRQ_SOURCE;
+ Memory.FillRAM [0x2301] &= ~0x40;
+ }
+ if (byte & 0x20)
+ {
+ SA1.IRQActive &= ~DMA_IRQ_SOURCE;
+ Memory.FillRAM [0x2301] &= ~0x20;
+ }
+ if (byte & 0x10)
+ {
+ // Clear NMI
+ Memory.FillRAM [0x2301] &= ~0x10;
+ }
+ if (!SA1.IRQActive)
+ SA1.Flags &= ~IRQ_PENDING_FLAG;
+ break;
+ case 0x220c:
+// printf ("SNES NMI vector: %04x\n", byte | (Memory.FillRAM [0x220d] << 8));
+ break;
+ case 0x220d:
+// printf ("SNES NMI vector: %04x\n", (byte << 8) | Memory.FillRAM [0x220c]);
+ break;
+
+ case 0x220e:
+// printf ("SNES IRQ vector: %04x\n", byte | (Memory.FillRAM [0x220f] << 8));
+ break;
+ case 0x220f:
+// printf ("SNES IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM [0x220e]);
+ break;
+
+ case 0x2210:
+#if 0
+ printf ("Timer %s\n", (byte & 0x80) ? "linear" : "HV");
+ printf ("Timer H-IRQ %s\n", (byte & 1) ? "enabled" : "disabled");
+ printf ("Timer V-IRQ %s\n", (byte & 2) ? "enabled" : "disabled");
+#endif
+ break;
+ case 0x2211:
+ printf ("Timer reset\n");
+ break;
+ case 0x2212:
+ printf ("H-Timer %04x\n", byte | (Memory.FillRAM [0x2213] << 8));
+ break;
+ case 0x2213:
+ printf ("H-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2212]);
+ break;
+ case 0x2214:
+ printf ("V-Timer %04x\n", byte | (Memory.FillRAM [0x2215] << 8));
+ break;
+ case 0x2215:
+ printf ("V-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2214]);
+ break;
+ case 0x2220:
+ case 0x2221:
+ case 0x2222:
+ case 0x2223:
+ S9xSetSA1MemMap (address - 0x2220, byte);
+// printf ("MMC: %02x\n", byte);
+ break;
+ case 0x2224:
+// printf ("BWRAM image SNES %02x -> 0x6000\n", byte);
+ Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000;
+ break;
+ case 0x2225:
+// printf ("BWRAM image SA1 %02x -> 0x6000 (%02x)\n", byte, Memory.FillRAM [address]);
+ if (byte != Memory.FillRAM [address])
+ S9xSA1SetBWRAMMemMap (byte);
+ break;
+ case 0x2226:
+// printf ("BW-RAM SNES write %s\n", (byte & 0x80) ? "enabled" : "disabled");
+ break;
+ case 0x2227:
+// printf ("BW-RAM SA1 write %s\n", (byte & 0x80) ? "enabled" : "disabled");
+ break;
+
+ case 0x2228:
+// printf ("BW-RAM write protect area %02x\n", byte);
+ break;
+ case 0x2229:
+// printf ("I-RAM SNES write protect area %02x\n", byte);
+ break;
+ case 0x222a:
+// printf ("I-RAM SA1 write protect area %02x\n", byte);
+ break;
+ case 0x2230:
+#if 0
+ printf ("SA1 DMA %s\n", (byte & 0x80) ? "enabled" : "disabled");
+ printf ("DMA priority %s\n", (byte & 0x40) ? "DMA" : "SA1");
+ printf ("DMA %s\n", (byte & 0x20) ? "char conv" : "normal");
+ printf ("DMA type %s\n", (byte & 0x10) ? "BW-RAM -> I-RAM" : "SA1 -> I-RAM");
+ printf ("DMA distination %s\n", (byte & 4) ? "BW-RAM" : "I-RAM");
+ printf ("DMA source %s\n", DMAsource [byte & 3]);
+#endif
+ break;
+ case 0x2231:
+ if (byte & 0x80)
+ SA1.in_char_dma = FALSE;
+#if 0
+ printf ("CHDEND %s\n", (byte & 0x80) ? "complete" : "incomplete");
+ printf ("DMA colour mode %d\n", byte & 3);
+ printf ("virtual VRAM width %d\n", (byte >> 2) & 7);
+#endif
+ break;
+ case 0x2232:
+ case 0x2233:
+ case 0x2234:
+ Memory.FillRAM [address] = byte;
+#if 0
+ printf ("DMA source start %06x\n",
+ Memory.FillRAM [0x2232] | (Memory.FillRAM [0x2233] << 8) |
+ (Memory.FillRAM [0x2234] << 16));
+#endif
+ break;
+ case 0x2235:
+ Memory.FillRAM [address] = byte;
+ break;
+ case 0x2236:
+ Memory.FillRAM [address] = byte;
+ if ((Memory.FillRAM [0x2230] & 0xa4) == 0x80)
+ {
+ // Normal DMA to I-RAM
+ S9xSA1DMA ();
+ }
+ else
+ if ((Memory.FillRAM [0x2230] & 0xb0) == 0xb0)
+ {
+ Memory.FillRAM [0x2300] |= 0x20;
+ if (Memory.FillRAM [0x2201] & 0x20)
+ S9xSetIRQ (SA1_DMA_IRQ_SOURCE);
+ SA1.in_char_dma = TRUE;
+ }
+ break;
+ case 0x2237:
+ Memory.FillRAM [address] = byte;
+ if ((Memory.FillRAM [0x2230] & 0xa4) == 0x84)
+ {
+ // Normal DMA to BW-RAM
+ S9xSA1DMA ();
+ }
+#if 0
+ printf ("DMA dest address %06x\n",
+ Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8) |
+ (Memory.FillRAM [0x2237] << 16));
+#endif
+ break;
+ case 0x2238:
+ case 0x2239:
+ Memory.FillRAM [address] = byte;
+#if 0
+ printf ("DMA length %04x\n",
+ Memory.FillRAM [0x2238] | (Memory.FillRAM [0x2239] << 8));
+#endif
+ break;
+ case 0x223f:
+ SA1.VirtualBitmapFormat = (byte & 0x80) ? 2 : 4;
+ //printf ("virtual VRAM depth %d\n", (byte & 0x80) ? 2 : 4);
+ break;
+
+ case 0x2240: case 0x2241: case 0x2242: case 0x2243:
+ case 0x2244: case 0x2245: case 0x2246: case 0x2247:
+ case 0x2248: case 0x2249: case 0x224a: case 0x224b:
+ case 0x224c: case 0x224d: case 0x224e:
+#if 0
+ if (!(SA1.Flags & TRACE_FLAG))
+ {
+ TraceSA1 ();
+ Trace ();
+ }
+#endif
+ Memory.FillRAM [address] = byte;
+ break;
+
+ case 0x224f:
+ Memory.FillRAM [address] = byte;
+ if ((Memory.FillRAM [0x2230] & 0xb0) == 0xa0)
+ {
+ // Char conversion 2 DMA enabled
+ memmove (&Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000] + SA1.in_char_dma * 16,
+ &Memory.FillRAM [0x2240], 16);
+ SA1.in_char_dma = (SA1.in_char_dma + 1) & 7;
+ if ((SA1.in_char_dma & 3) == 0)
+ {
+ S9xSA1CharConv2 ();
+ }
+ }
+ break;
+ case 0x2250:
+ if (byte & 2)
+ SA1.sum = 0;
+ SA1.arithmetic_op = byte & 3;
+ break;
+
+ case 0x2251:
+ SA1.op1 = (SA1.op1 & 0xff00) | byte;
+ break;
+ case 0x2252:
+ SA1.op1 = (SA1.op1 & 0xff) | (byte << 8);
+ break;
+ case 0x2253:
+ SA1.op2 = (SA1.op2 & 0xff00) | byte;
+ break;
+ case 0x2254:
+ SA1.op2 = (SA1.op2 & 0xff) | (byte << 8);
+ switch (SA1.arithmetic_op)
+ {
+ case 0: // multiply
+ SA1.sum = SA1.op1 * SA1.op2;
+ break;
+ case 1: // divide
+ if (SA1.op2 == 0)
+ SA1.sum = SA1.op1 << 16;
+ else
+ {
+ SA1.sum = (SA1.op1 / (int) ((uint16) SA1.op2)) |
+ ((SA1.op1 % (int) ((uint16) SA1.op2)) << 16);
+ }
+ break;
+ case 2:
+ default: // cumulative sum
+ SA1.sum += SA1.op1 * SA1.op2;
+ if (SA1.sum & ((int64) 0xffffff << 32))
+ SA1.overflow = TRUE;
+ break;
+ }
+ break;
+ case 0x2258: // Variable bit-field length/auto inc/start.
+ Memory.FillRAM [0x2258] = byte;
+ S9xSA1ReadVariableLengthData (TRUE, FALSE);
+ return;
+ case 0x2259:
+ case 0x225a:
+ case 0x225b: // Variable bit-field start address
+ Memory.FillRAM [address] = byte;
+ // XXX: ???
+ SA1.variable_bit_pos = 0;
+ S9xSA1ReadVariableLengthData (FALSE, TRUE);
+ return;
+ default:
+// printf ("W: %02x->%04x\n", byte, address);
+ break;
+ }
+ if (address >= 0x2200 && address <= 0x22ff)
+ Memory.FillRAM [address] = byte;
+}
+
+static void S9xSA1CharConv2 ()
+{
+ uint32 dest = Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8);
+ uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1;
+ int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 :
+ (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2;
+ int bytes_per_char = 8 * depth;
+ uint8 *p = &Memory.FillRAM [0x3000] + dest + offset * bytes_per_char;
+ uint8 *q = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000] + offset * 64;
+
+ switch (depth)
+ {
+ case 2:
+ break;
+ case 4:
+ break;
+ case 8:
+ for (int l = 0; l < 8; l++, q += 8)
+ {
+ for (int b = 0; b < 8; b++)
+ {
+ uint8 r = *(q + b);
+ *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1);
+ *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1);
+ *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1);
+ *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1);
+ *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1);
+ *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1);
+ *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1);
+ *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1);
+ }
+ p += 2;
+ }
+ break;
+ }
+}
+
+static void S9xSA1DMA ()
+{
+ uint32 src = Memory.FillRAM [0x2232] |
+ (Memory.FillRAM [0x2233] << 8) |
+ (Memory.FillRAM [0x2234] << 16);
+ uint32 dst = Memory.FillRAM [0x2235] |
+ (Memory.FillRAM [0x2236] << 8) |
+ (Memory.FillRAM [0x2237] << 16);
+ uint32 len = Memory.FillRAM [0x2238] |
+ (Memory.FillRAM [0x2239] << 8);
+
+ uint8 *s;
+ uint8 *d;
+
+ switch (Memory.FillRAM [0x2230] & 3)
+ {
+ case 0: // ROM
+ s = SA1.Map [(src >> MEMMAP_SHIFT) & MEMMAP_MASK];
+ if (s >= (uint8 *) CMemory::MAP_LAST)
+ s += (src & 0xffff);
+ else
+ s = Memory.ROM + (src & 0xffff);
+ break;
+ case 1: // BW-RAM
+ src &= Memory.SRAMMask;
+ len &= Memory.SRAMMask;
+ s = Memory.SRAM + src;
+ break;
+ default:
+ case 2:
+ src &= 0x3ff;
+ len &= 0x3ff;
+ s = &Memory.FillRAM [0x3000] + src;
+ break;
+ }
+
+ if (Memory.FillRAM [0x2230] & 4)
+ {
+ dst &= Memory.SRAMMask;
+ len &= Memory.SRAMMask;
+ d = Memory.SRAM + dst;
+ }
+ else
+ {
+ dst &= 0x3ff;
+ len &= 0x3ff;
+ d = &Memory.FillRAM [0x3000] + dst;
+ }
+ memmove (d, s, len);
+ Memory.FillRAM [0x2301] |= 0x20;
+
+ if (Memory.FillRAM [0x220a] & 0x20)
+ {
+ SA1.Flags |= IRQ_PENDING_FLAG;
+ SA1.IRQActive |= DMA_IRQ_SOURCE;
+// SA1.Executing = !SA1.Waiting;
+ }
+}
+
+void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift)
+{
+ uint32 addr = Memory.FillRAM [0x2259] |
+ (Memory.FillRAM [0x225a] << 8) |
+ (Memory.FillRAM [0x225b] << 16);
+ uint8 shift = Memory.FillRAM [0x2258] & 15;
+
+ if (no_shift)
+ shift = 0;
+ else
+ if (shift == 0)
+ shift = 16;
+
+ uint8 s = shift + SA1.variable_bit_pos;
+
+ if (s >= 16)
+ {
+ addr += (s >> 4) << 1;
+ s &= 15;
+ }
+ uint32 data = S9xSA1GetWord (addr) |
+ (S9xSA1GetWord (addr + 2) << 16);
+
+ data >>= s;
+ Memory.FillRAM [0x230c] = (uint8) data;
+ Memory.FillRAM [0x230d] = (uint8) (data >> 8);
+ if (inc)
+ {
+ SA1.variable_bit_pos = (SA1.variable_bit_pos + shift) & 15;
+ Memory.FillRAM [0x2259] = (uint8) addr;
+ Memory.FillRAM [0x225a] = (uint8) (addr >> 8);
+ Memory.FillRAM [0x225b] = (uint8) (addr >> 16);
+ }
+}
+
diff --git a/source/sa1.h b/source/sa1.h
new file mode 100644
index 0000000..21353d5
--- /dev/null
+++ b/source/sa1.h
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _sa1_h_
+#define _sa1_h_
+
+#include "memmap.h"
+
+struct SSA1Registers {
+ uint8 PB;
+ uint8 DB;
+ pair P;
+ pair A;
+ pair D;
+ pair S;
+ pair X;
+ pair Y;
+ uint16 PC;
+};
+
+struct SSA1 {
+ struct SOpcodes *S9xOpcodes;
+ uint8 _Carry;
+ uint8 _Zero;
+ uint8 _Negative;
+ uint8 _Overflow;
+ bool8 CPUExecuting;
+ uint32 ShiftedPB;
+ uint32 ShiftedDB;
+ uint32 Flags;
+ bool8 Executing;
+ bool8 NMIActive;
+ bool8 IRQActive;
+ bool8 WaitingForInterrupt;
+ bool8 Waiting;
+// uint8 WhichEvent;
+ uint8 *PC;
+ uint8 *PCBase;
+ uint8 *BWRAM;
+ uint8 *PCAtOpcodeStart;
+ uint8 *WaitAddress;
+ uint32 WaitCounter;
+ uint8 *WaitByteAddress1;
+ uint8 *WaitByteAddress2;
+// long Cycles;
+// long NextEvent;
+// long V_Counter;
+ uint8 *Map [MEMMAP_NUM_BLOCKS];
+ uint8 *WriteMap [MEMMAP_NUM_BLOCKS];
+ int16 op1;
+ int16 op2;
+ int arithmetic_op;
+ int64 sum;
+ bool8 overflow;
+ uint8 VirtualBitmapFormat;
+ bool8 in_char_dma;
+ uint8 variable_bit_pos;
+};
+
+#define SA1CheckZero() (SA1._Zero == 0)
+#define SA1CheckCarry() (SA1._Carry)
+#define SA1CheckIRQ() (SA1Registers.PL & IRQ)
+#define SA1CheckDecimal() (SA1Registers.PL & Decimal)
+#define SA1CheckIndex() (SA1Registers.PL & IndexFlag)
+#define SA1CheckMemory() (SA1Registers.PL & MemoryFlag)
+#define SA1CheckOverflow() (SA1._Overflow)
+#define SA1CheckNegative() (SA1._Negative & 0x80)
+#define SA1CheckEmulation() (SA1Registers.P.W & Emulation)
+
+#define SA1ClearFlags(f) (SA1Registers.P.W &= ~(f))
+#define SA1SetFlags(f) (SA1Registers.P.W |= (f))
+#define SA1CheckFlag(f) (SA1Registers.PL & (f))
+
+
+START_EXTERN_C
+uint8 S9xSA1GetByte (uint32);
+uint16 S9xSA1GetWord (uint32);
+void S9xSA1SetByte (uint8, uint32);
+void S9xSA1SetWord (uint16, uint32);
+void S9xSA1SetPCBase (uint32);
+uint8 S9xGetSA1 (uint32);
+void S9xSetSA1 (uint8, uint32);
+
+extern struct SOpcodes S9xSA1OpcodesM1X1 [256];
+extern struct SOpcodes S9xSA1OpcodesM1X0 [256];
+extern struct SOpcodes S9xSA1OpcodesM0X1 [256];
+extern struct SOpcodes S9xSA1OpcodesM0X0 [256];
+extern struct SSA1Registers SA1Registers;
+extern struct SSA1 SA1;
+
+void S9xSA1MainLoop ();
+void S9xSA1Init ();
+void S9xFixSA1AfterSnapshotLoad ();
+void S9xSA1ExecuteDuringSleep ();
+END_EXTERN_C
+
+#define SNES_IRQ_SOURCE (1 << 7)
+#define TIMER_IRQ_SOURCE (1 << 6)
+#define DMA_IRQ_SOURCE (1 << 5)
+
+STATIC inline void S9xSA1UnpackStatus()
+{
+ SA1._Zero = (SA1Registers.PL & Zero) == 0;
+ SA1._Negative = (SA1Registers.PL & Negative);
+ SA1._Carry = (SA1Registers.PL & Carry);
+ SA1._Overflow = (SA1Registers.PL & Overflow) >> 6;
+}
+
+STATIC inline void S9xSA1PackStatus()
+{
+ SA1Registers.PL &= ~(Zero | Negative | Carry | Overflow);
+ SA1Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) |
+ (SA1._Negative & 0x80) | (SA1._Overflow << 6);
+}
+
+STATIC inline void S9xSA1FixCycles ()
+{
+ if (SA1CheckEmulation ())
+ SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
+ else
+ if (SA1CheckMemory ())
+ {
+ if (SA1CheckIndex ())
+ SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
+ else
+ SA1.S9xOpcodes = S9xSA1OpcodesM1X0;
+ }
+ else
+ {
+ if (SA1CheckIndex ())
+ SA1.S9xOpcodes = S9xSA1OpcodesM0X1;
+ else
+ SA1.S9xOpcodes = S9xSA1OpcodesM0X0;
+ }
+}
+#endif
+
diff --git a/source/sa1cpu.cpp b/source/sa1cpu.cpp
new file mode 100644
index 0000000..1532f57
--- /dev/null
+++ b/source/sa1cpu.cpp
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "cpuexec.h"
+
+#include "sa1.h"
+#define CPU SA1
+#define ICPU SA1
+#define Registers SA1Registers
+#define S9xGetByte S9xSA1GetByte
+#define S9xGetWord S9xSA1GetWord
+#define S9xSetByte S9xSA1SetByte
+#define S9xSetWord S9xSA1SetWord
+#define S9xSetPCBase S9xSA1SetPCBase
+#define S9xOpcodesM1X1 S9xSA1OpcodesM1X1
+#define S9xOpcodesM1X0 S9xSA1OpcodesM1X0
+#define S9xOpcodesM0X1 S9xSA1OpcodesM0X1
+#define S9xOpcodesM0X0 S9xSA1OpcodesM0X0
+#define S9xOpcodesE1 S9xSA1OpcodesE1
+#define S9xOpcode_IRQ S9xSA1Opcode_IRQ
+#define S9xOpcode_NMI S9xSA1Opcode_NMI
+#define S9xUnpackStatus S9xSA1UnpackStatus
+#define S9xPackStatus S9xSA1PackStatus
+#define S9xFixCycles S9xSA1FixCycles
+#define Immediate8 SA1Immediate8
+#define Immediate16 SA1Immediate16
+#define Relative SA1Relative
+#define RelativeLong SA1RelativeLong
+#define AbsoluteIndexedIndirect SA1AbsoluteIndexedIndirect
+#define AbsoluteIndirectLong SA1AbsoluteIndirectLong
+#define AbsoluteIndirect SA1AbsoluteIndirect
+#define Absolute SA1Absolute
+#define AbsoluteLong SA1AbsoluteLong
+#define Direct SA1Direct
+#define DirectIndirectIndexed SA1DirectIndirectIndexed
+#define DirectIndirectIndexedLong SA1DirectIndirectIndexedLong
+#define DirectIndexedIndirect SA1DirectIndexedIndirect
+#define DirectIndexedX SA1DirectIndexedX
+#define DirectIndexedY SA1DirectIndexedY
+#define AbsoluteIndexedX SA1AbsoluteIndexedX
+#define AbsoluteIndexedY SA1AbsoluteIndexedY
+#define AbsoluteLongIndexedX SA1AbsoluteLongIndexedX
+#define DirectIndirect SA1DirectIndirect
+#define DirectIndirectLong SA1DirectIndirectLong
+#define StackRelative SA1StackRelative
+#define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed
+
+//#undef CPU_SHUTDOWN
+#undef VAR_CYCLES
+#define SA1_OPCODES
+
+#include "cpuops.cpp"
+
+void S9xSA1MainLoop ()
+{
+ int i;
+
+#if 0
+ if (SA1.Flags & NMI_FLAG)
+ {
+ SA1.Flags &= ~NMI_FLAG;
+ if (SA1.WaitingForInterrupt)
+ {
+ SA1.WaitingForInterrupt = FALSE;
+ SA1.PC++;
+ }
+ S9xSA1Opcode_NMI ();
+ }
+#endif
+ if (SA1.Flags & IRQ_PENDING_FLAG)
+ {
+ if (SA1.IRQActive)
+ {
+ if (SA1.WaitingForInterrupt)
+ {
+ SA1.WaitingForInterrupt = FALSE;
+ SA1.PC++;
+ }
+ if (!SA1CheckFlag (IRQ))
+ S9xSA1Opcode_IRQ ();
+ }
+ else
+ SA1.Flags &= ~IRQ_PENDING_FLAG;
+ }
+#ifdef DEBUGGER
+ if (SA1.Flags & TRACE_FLAG)
+ {
+ for (i = 0; i < 3 && SA1.Executing; i++)
+ {
+ S9xSA1Trace ();
+#ifdef CPU_SHUTDOWN
+ SA1.PCAtOpcodeStart = SA1.PC;
+#endif
+ (*SA1.S9xOpcodes [*SA1.PC++].S9xOpcode) ();
+ }
+ }
+ else
+#endif
+ for (i = 0; i < 3 && SA1.Executing; i++)
+ {
+#ifdef CPU_SHUTDOWN
+ SA1.PCAtOpcodeStart = SA1.PC;
+#endif
+ (*SA1.S9xOpcodes [*SA1.PC++].S9xOpcode) ();
+ }
+}
+
diff --git a/source/sar.h b/source/sar.h
new file mode 100644
index 0000000..c5e34f4
--- /dev/null
+++ b/source/sar.h
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _SAR_H_
+#define _SAR_H_
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "port.h"
+
+#ifndef snes9x_types_defined
+#include "9xtypes.h"
+#endif
+
+#ifdef RIGHTSHIFT_IS_SAR
+#define SAR(b, n) ((b)>>(n))
+#else
+
+static inline int8 SAR(const int8 b, const int n){
+#ifndef RIGHTSHIFT_INT8_IS_SAR
+ if(b<0) return (b>>n)|(-1<<(8-n));
+#endif
+ return b>>n;
+}
+
+static inline int16 SAR(const int16 b, const int n){
+#ifndef RIGHTSHIFT_INT16_IS_SAR
+ if(b<0) return (b>>n)|(-1<<(16-n));
+#endif
+ return b>>n;
+}
+
+static inline int32 SAR(const int32 b, const int n){
+#ifndef RIGHTSHIFT_INT32_IS_SAR
+ if(b<0) return (b>>n)|(-1<<(32-n));
+#endif
+ return b>>n;
+}
+
+static inline int64 SAR(const int64 b, const int n){
+#ifndef RIGHTSHIFT_INT64_IS_SAR
+ if(b<0) return (b>>n)|(-1<<(64-n));
+#endif
+ return b>>n;
+}
+
+#endif
+
+#endif
+
diff --git a/source/screenshot.cpp b/source/screenshot.cpp
new file mode 100644
index 0000000..f33b240
--- /dev/null
+++ b/source/screenshot.cpp
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+#include <stdio.h>
+
+#ifndef __WIN32__
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "display.h"
+#include "gfx.h"
+#include "ppu.h"
+#include "screenshot.h"
+
+bool8 S9xDoScreenshot(int width, int height){
+#ifdef HAVE_LIBPNG
+ FILE *fp;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_color_8 sig_bit;
+ png_color pngpal[256];
+ int imgwidth;
+ int imgheight;
+ const char *fname=S9xGetFilenameInc(".png");
+
+ Settings.TakeScreenshot=FALSE;
+
+ if((fp=fopen(fname, "wb"))==NULL){
+ perror("Screenshot failed");
+ return FALSE;
+ }
+
+ png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if(!png_ptr){
+ fclose(fp);
+ unlink(fname);
+ return FALSE;
+ }
+ info_ptr=png_create_info_struct(png_ptr);
+ if(!info_ptr){
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ fclose(fp);
+ unlink(fname);
+ return FALSE;
+ }
+
+ if(setjmp(png_jmpbuf(png_ptr))){
+ perror("Screenshot: setjmp");
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(fp);
+ unlink(fname);
+ return FALSE;
+ }
+
+ imgwidth=width;
+ imgheight=height;
+ if(Settings.StretchScreenshots==1){
+ if(width<=256 && height>SNES_HEIGHT_EXTENDED) imgwidth=width<<1;
+ if(width>256 && height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1;
+ } else if(Settings.StretchScreenshots==2){
+ if(width<=256) imgwidth=width<<1;
+ if(height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1;
+ }
+
+ png_init_io(png_ptr, fp);
+ if(!Settings.SixteenBit){
+ // BJ: credit sanmaiwashi for the idea to do palettized pngs, and to
+ // S9xSetPalette in x11.cpp for how to calculate the RGB values
+ int b=IPPU.MaxBrightness*140;
+ for(int i=0; i<256; i++){
+ pngpal[i].red = (PPU.CGDATA[i] & 0x1f)*b>>8;
+ pngpal[i].green = ((PPU.CGDATA[i] >> 5) & 0x1f)*b>>8;
+ pngpal[i].blue = ((PPU.CGDATA[i] >> 10) & 0x1f)*b>>8;
+ }
+ png_set_PLTE(png_ptr, info_ptr, pngpal, 256);
+ }
+ png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8,
+ (Settings.SixteenBit?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_PALETTE),
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ if(Settings.SixteenBit){
+ /* 5 bits per color */
+ sig_bit.red=5;
+ sig_bit.green=5;
+ sig_bit.blue=5;
+ png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, &sig_bit);
+ }
+
+ png_write_info(png_ptr, info_ptr);
+
+ png_set_packing(png_ptr);
+
+ png_byte *row_pointer=new png_byte [png_get_rowbytes(png_ptr, info_ptr)];
+ uint8 *screen=GFX.Screen;
+ for(int y=0; y<height; y++, screen+=GFX.Pitch){
+ png_byte *rowpix = row_pointer;
+ for(int x=0; x<width; x++){
+ if(Settings.SixteenBit){
+ uint32 r, g, b;
+ DECOMPOSE_PIXEL((*(uint16 *)(screen+2*x)), r, g, b);
+ *(rowpix++) = r;
+ *(rowpix++) = g;
+ *(rowpix++) = b;
+ if(imgwidth!=width){
+ *(rowpix++) = r;
+ *(rowpix++) = g;
+ *(rowpix++) = b;
+ }
+ } else {
+ *(rowpix++)=*(uint8 *)(screen+x);
+ if(imgwidth!=width)
+ *(rowpix++)=*(uint8 *)(screen+x);
+ }
+ }
+ png_write_row(png_ptr, row_pointer);
+ if(imgheight!=height)
+ png_write_row(png_ptr, row_pointer);
+ }
+
+ delete [] row_pointer;
+
+ png_write_end(png_ptr, info_ptr);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ fclose(fp);
+ fprintf(stderr, "%s saved.\n", fname);
+ return TRUE;
+#else
+ perror("Screenshot support not available (libpng was not found at build time)");
+ return FALSE;
+#endif
+}
+
diff --git a/source/screenshot.h b/source/screenshot.h
new file mode 100644
index 0000000..ce44e42
--- /dev/null
+++ b/source/screenshot.h
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef SCREENSHOT_H
+#define SCREENSHOT_H
+
+bool8 S9xDoScreenshot(int width, int height);
+
+#endif
+
diff --git a/source/sdd1.cpp b/source/sdd1.cpp
new file mode 100644
index 0000000..7dc6f4a
--- /dev/null
+++ b/source/sdd1.cpp
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "ppu.h"
+#include "sdd1.h"
+#include "display.h"
+
+#ifdef __linux
+#include <unistd.h>
+#endif
+
+void S9xSetSDD1MemoryMap (uint32 bank, uint32 value)
+{
+ bank = 0xc00 + bank * 0x100;
+ value = value * 1024 * 1024;
+
+ int c;
+
+ for (c = 0; c < 0x100; c += 16)
+ {
+ uint8 *block = &Memory.ROM [value + (c << 12)];
+ int i;
+
+ for (i = c; i < c + 16; i++)
+ Memory.Map [i + bank] = block;
+ }
+}
+
+void S9xResetSDD1 ()
+{
+ memset (&Memory.FillRAM [0x4800], 0, 4);
+ for (int i = 0; i < 4; i++)
+ {
+ Memory.FillRAM [0x4804 + i] = i;
+ S9xSetSDD1MemoryMap (i, i);
+ }
+}
+
+void S9xSDD1PostLoadState ()
+{
+ for (int i = 0; i < 4; i++)
+ S9xSetSDD1MemoryMap (i, Memory.FillRAM [0x4804 + i]);
+}
+
+static int S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2)
+{
+ uint8 *b1 = (uint8 *) p1;
+ uint8 *b2 = (uint8 *) p2;
+ uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2);
+ uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2);
+
+ return (a1 - a2);
+}
+
+void S9xSDD1SaveLoggedData ()
+{
+ if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev)
+ {
+ qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8,
+ S9xCompareSDD1LoggedDataEntries);
+
+ FILE *fs = fopen (S9xGetFilename (".dat"), "wb");
+
+ if (fs)
+ {
+ fwrite (Memory.SDD1LoggedData, 8,
+ Memory.SDD1LoggedDataCount, fs);
+ fclose (fs);
+#if defined(__linux)
+ chown (S9xGetFilename (".dat"), getuid (), getgid ());
+#endif
+ }
+ Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount;
+ }
+}
+
+void S9xSDD1LoadLoggedData ()
+{
+ FILE *fs = fopen (S9xGetFilename (".dat"), "rb");
+
+ Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0;
+
+ if (fs)
+ {
+ int c = fread (Memory.SDD1LoggedData, 8,
+ MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs);
+
+ if (c != EOF)
+ Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c;
+ fclose (fs);
+ }
+}
+
diff --git a/source/sdd1.h b/source/sdd1.h
new file mode 100644
index 0000000..15c97ae
--- /dev/null
+++ b/source/sdd1.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef _SDD1_H_
+#define _SDD1_H_
+void S9xSetSDD1MemoryMap (uint32 bank, uint32 value);
+void S9xResetSDD1 ();
+void S9xSDD1PostLoadState ();
+void S9xSDD1SaveLoggedData ();
+void S9xSDD1LoadLoggedData ();
+#endif
+
diff --git a/source/sdd1emu.cpp b/source/sdd1emu.cpp
new file mode 100644
index 0000000..bc32b43
--- /dev/null
+++ b/source/sdd1emu.cpp
@@ -0,0 +1,414 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+/* S-DD1 decompressor
+ *
+ * Based on code and documentation by Andreas Naive, who deserves a great deal
+ * of thanks and credit for figuring this out.
+ *
+ * Andreas says:
+ * The author is greatly indebted with The Dumper, without whose help and
+ * patience providing him with real S-DD1 data the research had never been
+ * possible. He also wish to note that in the very beggining of his research,
+ * Neviksti had done some steps in the right direction. By last, the author is
+ * indirectly indebted to all the people that worked and contributed in the
+ * S-DD1 issue in the past.
+ */
+
+#include <string.h>
+#include "port.h"
+#include "sdd1emu.h"
+
+static int valid_bits;
+static uint16 in_stream;
+static uint8 *in_buf;
+static uint8 bit_ctr[8];
+static uint8 context_states[32];
+static int context_MPS[32];
+static int bitplane_type;
+static int high_context_bits;
+static int low_context_bits;
+static int prev_bits[8];
+
+static struct {
+ uint8 code_size;
+ uint8 MPS_next;
+ uint8 LPS_next;
+} evolution_table[] = {
+ /* 0 */ { 0,25,25},
+ /* 1 */ { 0, 2, 1},
+ /* 2 */ { 0, 3, 1},
+ /* 3 */ { 0, 4, 2},
+ /* 4 */ { 0, 5, 3},
+ /* 5 */ { 1, 6, 4},
+ /* 6 */ { 1, 7, 5},
+ /* 7 */ { 1, 8, 6},
+ /* 8 */ { 1, 9, 7},
+ /* 9 */ { 2,10, 8},
+ /* 10 */ { 2,11, 9},
+ /* 11 */ { 2,12,10},
+ /* 12 */ { 2,13,11},
+ /* 13 */ { 3,14,12},
+ /* 14 */ { 3,15,13},
+ /* 15 */ { 3,16,14},
+ /* 16 */ { 3,17,15},
+ /* 17 */ { 4,18,16},
+ /* 18 */ { 4,19,17},
+ /* 19 */ { 5,20,18},
+ /* 20 */ { 5,21,19},
+ /* 21 */ { 6,22,20},
+ /* 22 */ { 6,23,21},
+ /* 23 */ { 7,24,22},
+ /* 24 */ { 7,24,23},
+ /* 25 */ { 0,26, 1},
+ /* 26 */ { 1,27, 2},
+ /* 27 */ { 2,28, 4},
+ /* 28 */ { 3,29, 8},
+ /* 29 */ { 4,30,12},
+ /* 30 */ { 5,31,16},
+ /* 31 */ { 6,32,18},
+ /* 32 */ { 7,24,22}
+};
+
+static uint8 run_table[128] = {
+ 128, 64, 96, 32, 112, 48, 80, 16, 120, 56, 88, 24, 104, 40, 72,
+ 8, 124, 60, 92, 28, 108, 44, 76, 12, 116, 52, 84, 20, 100, 36,
+ 68, 4, 126, 62, 94, 30, 110, 46, 78, 14, 118, 54, 86, 22, 102,
+ 38, 70, 6, 122, 58, 90, 26, 106, 42, 74, 10, 114, 50, 82, 18,
+ 98, 34, 66, 2, 127, 63, 95, 31, 111, 47, 79, 15, 119, 55, 87,
+ 23, 103, 39, 71, 7, 123, 59, 91, 27, 107, 43, 75, 11, 115, 51,
+ 83, 19, 99, 35, 67, 3, 125, 61, 93, 29, 109, 45, 77, 13, 117,
+ 53, 85, 21, 101, 37, 69, 5, 121, 57, 89, 25, 105, 41, 73, 9,
+ 113, 49, 81, 17, 97, 33, 65, 1
+};
+
+static inline uint8 GetCodeword(int bits){
+ uint8 tmp;
+
+ if(!valid_bits){
+ in_stream|=*(in_buf++);
+ valid_bits=8;
+ }
+ in_stream<<=1;
+ valid_bits--;
+ in_stream^=0x8000;
+ if(in_stream&0x8000) return 0x80+(1<<bits);
+ tmp=(in_stream>>8) | (0x7f>>bits);
+ in_stream<<=bits;
+ valid_bits-=bits;
+ if(valid_bits<0){
+ in_stream |= (*(in_buf++))<<(-valid_bits);
+ valid_bits+=8;
+ }
+ return run_table[tmp];
+}
+
+static inline uint8 GolombGetBit(int code_size){
+ if(!bit_ctr[code_size]) bit_ctr[code_size]=GetCodeword(code_size);
+ bit_ctr[code_size]--;
+ if(bit_ctr[code_size]==0x80){
+ bit_ctr[code_size]=0;
+ return 2; /* secret code for 'last zero'. ones are always last. */
+ }
+ return (bit_ctr[code_size]==0)?1:0;
+}
+
+static inline uint8 ProbGetBit(uint8 context){
+ uint8 state=context_states[context];
+ uint8 bit=GolombGetBit(evolution_table[state].code_size);
+
+ if(bit&1){
+ context_states[context]=evolution_table[state].LPS_next;
+ if(state<2){
+ context_MPS[context]^=1;
+ return context_MPS[context]; /* just inverted, so just return it */
+ } else{
+ return context_MPS[context]^1; /* we know bit is 1, so use a constant */
+ }
+ } else if(bit){
+ context_states[context]=evolution_table[state].MPS_next;
+ /* zero here, zero there, no difference so drop through. */
+ }
+ return context_MPS[context]; /* we know bit is 0, so don't bother xoring */
+}
+
+static inline uint8 GetBit(uint8 cur_bitplane){
+ uint8 bit;
+
+ bit=ProbGetBit(((cur_bitplane&1)<<4)
+ | ((prev_bits[cur_bitplane]&high_context_bits)>>5)
+ | (prev_bits[cur_bitplane]&low_context_bits));
+
+ prev_bits[cur_bitplane] <<= 1;
+ prev_bits[cur_bitplane] |= bit;
+ return bit;
+}
+
+void SDD1_decompress(uint8 *out, uint8 *in, int len){
+ uint8 bit, i, plane;
+ uint8 byte1, byte2;
+
+ if(len==0) len=0x10000;
+
+ bitplane_type=in[0]>>6;
+
+ switch(in[0]&0x30){
+ case 0x00:
+ high_context_bits=0x01c0;
+ low_context_bits =0x0001;
+ break;
+ case 0x10:
+ high_context_bits=0x0180;
+ low_context_bits =0x0001;
+ break;
+ case 0x20:
+ high_context_bits=0x00c0;
+ low_context_bits =0x0001;
+ break;
+ case 0x30:
+ high_context_bits=0x0180;
+ low_context_bits =0x0003;
+ break;
+ }
+
+ in_stream=(in[0]<<11) | (in[1]<<3);
+ valid_bits=5;
+ in_buf=in+2;
+ memset(bit_ctr, 0, sizeof(bit_ctr));
+ memset(context_states, 0, sizeof(context_states));
+ memset(context_MPS, 0, sizeof(context_MPS));
+ memset(prev_bits, 0, sizeof(prev_bits));
+
+ switch(bitplane_type){
+ case 0:
+ while(1) {
+ for(byte1=byte2=0, bit=0x80; bit; bit>>=1){
+ if(GetBit(0)) byte1 |= bit;
+ if(GetBit(1)) byte2 |= bit;
+ }
+ *(out++)=byte1;
+ if(!--len) return;
+ *(out++)=byte2;
+ if(!--len) return;
+ }
+ break;
+ case 1:
+ i=plane=0;
+ while(1) {
+ for(byte1=byte2=0, bit=0x80; bit; bit>>=1){
+ if(GetBit(plane)) byte1 |= bit;
+ if(GetBit(plane+1)) byte2 |= bit;
+ }
+ *(out++)=byte1;
+ if(!--len) return;
+ *(out++)=byte2;
+ if(!--len) return;
+ if(!(i+=32)) plane = (plane+2)&7;
+ }
+ break;
+ case 2:
+ i=plane=0;
+ while(1) {
+ for(byte1=byte2=0, bit=0x80; bit; bit>>=1){
+ if(GetBit(plane)) byte1 |= bit;
+ if(GetBit(plane+1)) byte2 |= bit;
+ }
+ *(out++)=byte1;
+ if(!--len) return;
+ *(out++)=byte2;
+ if(!--len) return;
+ if(!(i+=32)) plane ^= 2;
+ }
+ break;
+ case 3:
+ do {
+ for(byte1=plane=0, bit=1; bit; bit<<=1, plane++){
+ if(GetBit(plane)) byte1 |= bit;
+ }
+ *(out++)=byte1;
+ } while(--len);
+ break;
+ }
+}
+
+static uint8 cur_plane;
+static uint8 num_bits;
+static uint8 next_byte;
+
+void SDD1_init(uint8 *in){
+ bitplane_type=in[0]>>6;
+
+ switch(in[0]&0x30){
+ case 0x00:
+ high_context_bits=0x01c0;
+ low_context_bits =0x0001;
+ break;
+ case 0x10:
+ high_context_bits=0x0180;
+ low_context_bits =0x0001;
+ break;
+ case 0x20:
+ high_context_bits=0x00c0;
+ low_context_bits =0x0001;
+ break;
+ case 0x30:
+ high_context_bits=0x0180;
+ low_context_bits =0x0003;
+ break;
+ }
+
+ in_stream=(in[0]<<11) | (in[1]<<3);
+ valid_bits=5;
+ in_buf=in+2;
+ memset(bit_ctr, 0, sizeof(bit_ctr));
+ memset(context_states, 0, sizeof(context_states));
+ memset(context_MPS, 0, sizeof(context_MPS));
+ memset(prev_bits, 0, sizeof(prev_bits));
+
+ cur_plane=0;
+ num_bits=0;
+}
+
+uint8 SDD1_get_byte(void){
+ uint8 bit;
+ uint8 byte=0;
+
+ switch(bitplane_type){
+ case 0:
+ num_bits+=16;
+ if(num_bits&16){
+ next_byte=0;
+ for(bit=0x80; bit; bit>>=1){
+ if(GetBit(0)) byte |= bit;
+ if(GetBit(1)) next_byte |= bit;
+ }
+ return byte;
+ } else {
+ return next_byte;
+ }
+
+ case 1:
+ num_bits+=16;
+ if(num_bits&16){
+ next_byte=0;
+ for(bit=0x80; bit; bit>>=1){
+ if(GetBit(cur_plane)) byte |= bit;
+ if(GetBit(cur_plane+1)) next_byte |= bit;
+ }
+ return byte;
+ } else {
+ if(!num_bits) cur_plane = (cur_plane+2)&7;
+ return next_byte;
+ }
+
+ case 2:
+ num_bits+=16;
+ if(num_bits&16){
+ next_byte=0;
+ for(bit=0x80; bit; bit>>=1){
+ if(GetBit(cur_plane)) byte |= bit;
+ if(GetBit(cur_plane+1)) next_byte |= bit;
+ }
+ return byte;
+ } else {
+ if(!num_bits) cur_plane ^= 2;
+ return next_byte;
+ }
+
+ case 3:
+ for(cur_plane=0, bit=1; bit; bit<<=1, cur_plane++){
+ if(GetBit(cur_plane)) byte |= bit;
+ }
+ return byte;
+
+ default:
+ /* should never happen */
+ return 0;
+ }
+}
+
diff --git a/source/sdd1emu.h b/source/sdd1emu.h
new file mode 100644
index 0000000..829ac4a
--- /dev/null
+++ b/source/sdd1emu.h
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef SDD1EMU_H
+#define SDD1EMU_H
+
+/* for START_EXTERN_C/END_EXTERN_C */
+#include "port.h"
+
+START_EXTERN_C
+
+void SDD1_decompress(uint8 *out, uint8 *in, int output_length);
+
+void SDD1_init(uint8 *in);
+uint8 SDD1_get_byte(void);
+
+END_EXTERN_C
+
+#endif
diff --git a/source/server.cpp b/source/server.cpp
new file mode 100644
index 0000000..4eb384e
--- /dev/null
+++ b/source/server.cpp
@@ -0,0 +1,1303 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifdef NETPLAY_SUPPORT
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <memory.h>
+#include <sys/types.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifndef __WIN32__
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+#ifdef __WIN32__
+
+#include <winsock.h>
+#include <process.h>
+#define ioctl ioctlsocket
+#define close closesocket
+#define read(a,b,c) recv(a, b, c, 0)
+#define write(a,b,c) send(a, b, c, 0)
+#define gettimeofday(a,b) S9xGetTimeOfDay (a)
+#define exit(a) _endthread()
+void S9xGetTimeOfDay (struct timeval *n);
+#else
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+
+#ifdef __SVR4
+#include <sys/stropts.h>
+#endif
+
+#endif // !__WIN32__
+
+#include "snes9x.h"
+#include "netplay.h"
+#include "memmap.h"
+#include "snapshot.h"
+
+#define NP_ONE_CLIENT 1
+
+struct SNPServer NPServer;
+
+extern unsigned long START;
+
+void S9xNPSendToAllClients (uint8 *data, int len);
+bool8 S9xNPLoadFreezeFile (const char *fname, uint8 *&data, uint32 &len);
+void S9xNPSendFreezeFile (int c, uint8 *data, uint32 len);
+void S9xNPNoClientReady (int start_index = NP_ONE_CLIENT);
+void S9xNPRecomputePause ();
+void S9xNPWaitForEmulationToComplete ();
+void S9xNPSendROMImageToAllClients ();
+bool8 S9xNPSendROMImageToClient (int client);
+void S9xNPSendSRAMToClient (int c);
+void S9xNPSendSRAMToAllClients ();
+void S9xNPSyncClient (int);
+void S9xNPSendROMLoadRequest (const char *filename);
+void S9xNPSendFreezeFileToAllClients (const char *filename);
+void S9xNPStopServer ();
+
+void S9xNPShutdownClient (int c, bool8 report_error = FALSE)
+{
+ if (NPServer.Clients [c].Connected)
+ {
+ NPServer.Clients [c].Connected = FALSE;
+ NPServer.Clients [c].SaidHello = FALSE;
+
+ close (NPServer.Clients [c].Socket);
+#ifdef NP_DEBUG
+ printf ("SERVER: Player %d disconnecting @%ld\n", c + 1, S9xGetMilliTime () - START);
+#endif
+ if (report_error)
+ {
+ sprintf (NetPlay.ErrorMsg,
+ "Player %d on '%s' has disconnected.", c + 1,
+ NPServer.Clients [c].HostName);
+ S9xNPSetError (NetPlay.ErrorMsg);
+ }
+
+ if (NPServer.Clients [c].HostName)
+ {
+ free ((char *) NPServer.Clients [c].HostName);
+ NPServer.Clients [c].HostName = NULL;
+ }
+ if (NPServer.Clients [c].ROMName)
+ {
+ free ((char *) NPServer.Clients [c].ROMName);
+ NPServer.Clients [c].ROMName = NULL;
+ }
+ if (NPServer.Clients [c].Who)
+ {
+ free ((char *) NPServer.Clients [c].Who);
+ NPServer.Clients [c].Who = NULL;
+ }
+ NPServer.Joypads [c] = 0;
+ NPServer.NumClients--;
+ S9xNPRecomputePause ();
+ }
+}
+
+static bool8 S9xNPSGetData (int socket, uint8 *data, int length)
+{
+ int len = length;
+ uint8 *ptr = data;
+
+ do
+ {
+ int num_bytes = len;
+
+ // Read the data in small chunks, allowing this thread to spot an
+ // abort request from another thread.
+ if (num_bytes > 512)
+ num_bytes = 512;
+
+ int got = read (socket, (char *) ptr, num_bytes);
+ if (got < 0)
+ {
+ if (errno == EINTR
+#ifdef EAGAIN
+ || errno == EAGAIN
+#endif
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+#ifdef WSAEWOULDBLOCK
+ || errno == WSAEWOULDBLOCK
+#endif
+ )
+ continue;
+#ifdef WSAEMSGSIZE
+ if (errno != WSAEMSGSIZE)
+ return (FALSE);
+ else
+ {
+ got = num_bytes;
+#ifdef NP_DEBUG
+ printf ("SERVER: WSAEMSGSIZE, actual bytes %d while receiving data @%d\n", got, S9xGetMilliTime () - START);
+#endif
+ }
+#else
+ return (FALSE);
+#endif
+ }
+ else
+ if (got == 0)
+ return (FALSE);
+
+ len -= got;
+ ptr += got;
+ } while (len > 0);
+
+ return (TRUE);
+}
+
+static bool8 S9xNPSSendData (int fd, const uint8 *data, int length)
+{
+ int Percent = 0;
+ int len = length;
+ int chunk = length / 50;
+
+ if (chunk < 1024)
+ chunk = 1024;
+
+ do
+ {
+ int num_bytes = len;
+
+ // Write the data in small chunks, allowing this thread to spot an
+ // abort request from another thread.
+ if (num_bytes > chunk)
+ num_bytes = chunk;
+
+ int sent;
+ sent = write (fd, (char *) data, len);
+
+ if (sent < 0)
+ {
+ if (errno == EINTR
+#ifdef EAGAIN
+ || errno == EAGAIN
+#endif
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+ )
+ {
+#ifdef NP_DEBUG
+ printf ("SERVER: EINTR, EAGAIN or EWOULDBLOCK while sending data @%ld\n", S9xGetMilliTime () - START);
+#endif
+ continue;
+ }
+ return (FALSE);
+ }
+ else
+ if (sent == 0)
+ return (FALSE);
+ len -= sent;
+ data += sent;
+ if (length > 1024)
+ {
+ Percent = (uint8) (((length - len) * 100) / length);
+#ifdef __WIN32__
+ PostMessage (GUI.hWnd, WM_USER, Percent, Percent);
+ Sleep (0);
+#endif
+ }
+ } while (len > 0);
+
+ return (TRUE);
+}
+
+void S9xNPSendHeartBeat ()
+{
+ int len = 3;
+ uint8 data [3 + 4 * 5];
+ uint8 *ptr = data;
+ int n;
+
+ for (n = NP_MAX_CLIENTS - 1; n >= 0; n--)
+ {
+ if (NPServer.Clients [n].SaidHello)
+ break;
+ }
+
+ if (n >= 0)
+ {
+ bool8 Paused = NPServer.Paused != 0;
+
+ NPServer.FrameCount++;
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = 0; // Individual client sequence number will get placed here
+ *ptr++ = NP_SERV_JOYPAD | (n << 6) | ((Paused != 0) << 5);
+
+ WRITE_LONG (ptr, NPServer.FrameCount);
+ len += 4;
+ ptr += 4;
+
+ int i;
+
+ for (i = 0; i <= n; i++)
+ {
+ WRITE_LONG (ptr, NPServer.Joypads [i]);
+ len += 4;
+ ptr += 4;
+ }
+
+ S9xNPSendToAllClients (data, len);
+ }
+}
+
+void S9xNPSendToAllClients (uint8 *data, int len)
+{
+ int i;
+
+ for (i = 0; i < NP_MAX_CLIENTS; i++)
+ {
+ if (NPServer.Clients [i].SaidHello)
+ {
+ data [1] = NPServer.Clients [i].SendSequenceNum++;
+ if (!S9xNPSSendData (NPServer.Clients [i].Socket, data, len))
+ S9xNPShutdownClient (i, TRUE);
+ }
+ }
+}
+
+void S9xNPProcessClient (int c)
+{
+ uint8 header [7];
+ uint8 *data;
+ uint32 len;
+ uint8 *ptr;
+
+ if (!S9xNPSGetData (NPServer.Clients [c].Socket, header, 7))
+ {
+ S9xNPSetWarning ("SERVER: Failed to get message header from client.\n");
+ S9xNPShutdownClient (c, TRUE);
+ return;
+ }
+ if (header [0] != NP_CLNT_MAGIC)
+ {
+ S9xNPSetWarning ("SERVER: Bad header magic value received from client.\n");
+ S9xNPShutdownClient (c, TRUE);
+ return;
+ }
+
+ if (header [1] != NPServer.Clients [c].ReceiveSequenceNum)
+ {
+#ifdef NP_DEBUG
+ printf ("SERVER: Messages lost from '%s', expected %d, got %d\n",
+ NPServer.Clients [c].HostName ?
+ NPServer.Clients [c].HostName : "Unknown",
+ NPServer.Clients [c].ReceiveSequenceNum,
+ header [1]);
+#endif
+ sprintf (NetPlay.WarningMsg,
+ "SERVER: Messages lost from '%s', expected %d, got %d\n",
+ NPServer.Clients [c].HostName ?
+ NPServer.Clients [c].HostName : "Unknown",
+ NPServer.Clients [c].ReceiveSequenceNum,
+ header [1]);
+ NPServer.Clients [c].ReceiveSequenceNum = header [1] + 1;
+ S9xNPSetWarning (NetPlay.WarningMsg);
+ }
+ else
+ NPServer.Clients [c].ReceiveSequenceNum++;
+
+ len = READ_LONG (&header [3]);
+
+ switch (header [2] & 0x3f)
+ {
+ case NP_CLNT_HELLO:
+#ifdef NP_DEBUG
+ printf ("SERVER: Got HELLO from client @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("Got HELLO from client...", TRUE);
+ if (len > 0x10000)
+ {
+ S9xNPSetWarning ("SERVER: Client HELLO message length error.");
+ S9xNPShutdownClient (c, TRUE);
+ return;
+ }
+ data = new uint8 [len - 7];
+ if (!S9xNPSGetData (NPServer.Clients [c].Socket, data, len - 7))
+ {
+ S9xNPSetWarning ("SERVER: Failed to get HELLO message content from client.");
+ S9xNPShutdownClient (c, TRUE);
+ return;
+ }
+
+ if (NPServer.NumClients <= NP_ONE_CLIENT)
+ {
+ NPServer.FrameTime = READ_LONG (data);
+ strncpy (NPServer.ROMName, (char *) &data [4], 29);
+ NPServer.ROMName [29] = 0;
+ }
+
+ NPServer.Clients [c].ROMName = strdup ((char *) &data [4]);
+#ifdef NP_DEBUG
+ printf ("SERVER: Client is playing: %s, Frame Time: %d @%ld\n", data + 4, READ_LONG (data), S9xGetMilliTime () - START);
+#endif
+
+ NPServer.Clients [c].SendSequenceNum = 0;
+
+ len = 7 + 1 + 1 + 4 + strlen (NPServer.ROMName) + 1;
+
+ delete data;
+ ptr = data = new uint8 [len];
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = NPServer.Clients [c].SendSequenceNum++;
+
+ if (NPServer.SendROMImageOnConnect &&
+ NPServer.NumClients > NP_ONE_CLIENT)
+ *ptr++ = NP_SERV_HELLO | 0x80;
+ else
+ *ptr++ = NP_SERV_HELLO;
+ WRITE_LONG (ptr, len);
+ ptr += 4;
+ *ptr++ = NP_VERSION;
+ *ptr++ = c + 1;
+ WRITE_LONG (ptr, NPServer.FrameCount);
+ ptr += 4;
+ strcpy ((char *) ptr, NPServer.ROMName);
+
+#ifdef NP_DEBUG
+ printf ("SERVER: Sending welcome information to client @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("SERVER: Sending welcome information to new client...", TRUE);
+ if (!S9xNPSSendData (NPServer.Clients [c].Socket, data, len))
+ {
+ S9xNPSetWarning ("SERVER: Failed to send welcome message to client.");
+ S9xNPShutdownClient (c, TRUE);
+ return;
+ }
+ delete data;
+#ifdef NP_DEBUG
+ printf ("SERVER: Waiting for a response from the client @%ld...\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("SERVER: Waiting for a response from the client...", TRUE);
+ break;
+
+ case NP_CLNT_LOADED_ROM:
+#ifdef NP_DEBUG
+ printf ("SERVER: Client %d loaded requested ROM @%ld...\n", c, S9xGetMilliTime () - START);
+#endif
+ NPServer.Clients [c].SaidHello = TRUE;
+ NPServer.Clients [c].Ready = FALSE;
+ NPServer.Clients [c].Paused = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPWaitForEmulationToComplete ();
+
+ if (NPServer.SyncByReset)
+ {
+ S9xNPServerAddTask (NP_SERVER_SEND_SRAM, (void *) c);
+ S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0);
+ }
+ else
+ S9xNPServerAddTask (NP_SERVER_SYNC_CLIENT, (void *) c);
+ break;
+
+ case NP_CLNT_RECEIVED_ROM_IMAGE:
+#ifdef NP_DEBUG
+ printf ("SERVER: Client %d received ROM image @%ld...\n", c, S9xGetMilliTime () - START);
+#endif
+ NPServer.Clients [c].SaidHello = TRUE;
+ NPServer.Clients [c].Ready = FALSE;
+ NPServer.Clients [c].Paused = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPWaitForEmulationToComplete ();
+
+ if (NPServer.SyncByReset)
+ {
+ S9xNPServerAddTask (NP_SERVER_SEND_SRAM, (void *) c);
+ S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0);
+ }
+ else
+ S9xNPServerAddTask (NP_SERVER_SYNC_CLIENT, (void *) c);
+
+ break;
+
+ case NP_CLNT_WAITING_FOR_ROM_IMAGE:
+#ifdef NP_DEBUG
+ printf ("SERVER: Client %d waiting for ROM image @%ld...\n", c, S9xGetMilliTime () - START);
+#endif
+ NPServer.Clients [c].SaidHello = TRUE;
+ NPServer.Clients [c].Ready = FALSE;
+ NPServer.Clients [c].Paused = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPSendROMImageToClient (c);
+ break;
+
+ case NP_CLNT_READY:
+#ifdef NP_DEBUG
+ printf ("SERVER: Client %d ready @%ld...\n", c, S9xGetMilliTime () - START);
+#endif
+ if (NPServer.Clients [c].SaidHello)
+ {
+ NPServer.Clients [c].Paused = FALSE;
+ NPServer.Clients [c].Ready = TRUE;
+
+ S9xNPRecomputePause ();
+ break;
+ }
+ NPServer.Clients [c].SaidHello = TRUE;
+ NPServer.Clients [c].Ready = TRUE;
+ NPServer.Clients [c].Paused = FALSE;
+ S9xNPRecomputePause ();
+
+//printf ("SERVER: SaidHello = TRUE, SeqNum = %d @%d\n", NPServer.Clients [c].SendSequenceNum, S9xGetMilliTime () - START);
+ if (NPServer.NumClients > NP_ONE_CLIENT)
+ {
+ if (!NPServer.SendROMImageOnConnect)
+ {
+ S9xNPWaitForEmulationToComplete ();
+
+ if (NPServer.SyncByReset)
+ {
+ S9xNPServerAddTask (NP_SERVER_SEND_SRAM, (void *) c);
+ S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0);
+ }
+ else
+ S9xNPServerAddTask (NP_SERVER_SYNC_CLIENT, (void *) c);
+ }
+ }
+ else
+ {
+ NPServer.Clients [c].Ready = TRUE;
+ S9xNPRecomputePause ();
+ }
+ break;
+ case NP_CLNT_JOYPAD:
+ NPServer.Joypads [c] = len;
+ break;
+ case NP_CLNT_PAUSE:
+#ifdef NP_DEBUG
+ printf ("SERVER: Client %d Paused: %s @%ld\n", c, (header [2] & 0x80) ? "YES" : "NO", S9xGetMilliTime () - START);
+#endif
+ NPServer.Clients [c].Paused = (header [2] & 0x80) != 0;
+ if (NPServer.Clients [c].Paused)
+ sprintf (NetPlay.WarningMsg, "SERVER: Client %d has paused.", c + 1);
+ else
+ sprintf (NetPlay.WarningMsg, "SERVER: Client %d has resumed.", c + 1);
+ S9xNPSetWarning (NetPlay.WarningMsg);
+ S9xNPRecomputePause ();
+ break;
+ }
+}
+
+void S9xNPAcceptClient (int Listen, bool8 block)
+{
+ struct sockaddr_in remote_address;
+ struct linger val2;
+ struct hostent *host;
+ int new_fd;
+ int i;
+
+#ifdef NP_DEBUG
+ printf ("SERVER: attempting to accept new client connection @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("SERVER: Attempting to accept client connection...", TRUE);
+ memset (&remote_address, 0, sizeof (remote_address));
+ ACCEPT_SIZE_T len = sizeof (remote_address);
+
+ new_fd = accept (Listen, (struct sockaddr *)&remote_address, &len);
+
+ S9xNPSetAction ("Setting socket options...", TRUE);
+ val2.l_onoff = 1;
+ val2.l_linger = 0;
+ if (setsockopt (new_fd, SOL_SOCKET, SO_LINGER,
+ (char *) &val2, sizeof (val2)) < 0)
+ {
+ S9xNPSetError ("Setting socket options failed.");
+ close (new_fd);
+ return;
+ }
+
+ for (i = 0; i < NP_MAX_CLIENTS; i++)
+ {
+ if (!NPServer.Clients [i].Connected)
+ {
+ NPServer.NumClients++;
+ NPServer.Clients [i].Socket = new_fd;
+ NPServer.Clients [i].SendSequenceNum = 0;
+ NPServer.Clients [i].ReceiveSequenceNum = 0;
+ NPServer.Clients [i].Connected = TRUE;
+ NPServer.Clients [i].SaidHello = FALSE;
+ NPServer.Clients [i].Paused = FALSE;
+ NPServer.Clients [i].Ready = FALSE;
+ NPServer.Clients [i].ROMName = NULL;
+ NPServer.Clients [i].HostName = NULL;
+ NPServer.Clients [i].Who = NULL;
+ break;
+ }
+ }
+
+ if (i >= NP_MAX_CLIENTS)
+ {
+ S9xNPSetError ("SERVER: Maximum number of NetPlay Clients have already connected.");
+ close (new_fd);
+ return;
+ }
+
+ if (remote_address.sin_family == AF_INET)
+ {
+#ifdef NP_DEBUG
+ printf ("SERVER: Looking up new client's hostname @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("SERVER: Looking up new client's hostname...", TRUE);
+ host = gethostbyaddr ((char *) &remote_address.sin_addr,
+ sizeof (remote_address.sin_addr), AF_INET);
+
+ if (host)
+ {
+#ifdef NP_DEBUG
+ printf ("SERVER: resolved new client's hostname (%s) @%ld\n", host->h_name, S9xGetMilliTime () - START);
+#endif
+ sprintf (NetPlay.WarningMsg, "SERVER: Player %d on %s has connected.", i + 1, host->h_name);
+ NPServer.Clients [i].HostName = strdup (host->h_name);
+ }
+ else
+ {
+ char *ip = inet_ntoa (remote_address.sin_addr);
+ if (ip)
+ NPServer.Clients [i].HostName = strdup (ip);
+#ifdef NP_DEBUG
+ printf ("SERVER: couldn't resolve new client's hostname (%s) @%ld\n", ip ? ip : "Unknown", S9xGetMilliTime () - START);
+#endif
+ sprintf (NetPlay.WarningMsg, "SERVER: Player %d on %s has connected.", i + 1, ip ? ip : "Unknown");
+ }
+ S9xNPSetWarning (NetPlay.WarningMsg);
+ }
+#ifdef NP_DEBUG
+ printf ("SERVER: waiting for HELLO message from new client @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPSetAction ("SERVER: Waiting for HELLO message from new client...");
+}
+
+static bool8 server_continue = TRUE;
+
+static bool8 S9xNPServerInit (int port)
+{
+ struct sockaddr_in address;
+ int i;
+ int val;
+
+ if (!S9xNPInitialise ())
+ return (FALSE);
+
+ for (i = 0; i < NP_MAX_CLIENTS; i++)
+ {
+ NPServer.Clients [i].SendSequenceNum = 0;
+ NPServer.Clients [i].ReceiveSequenceNum = 0;
+ NPServer.Clients [i].Connected = FALSE;
+ NPServer.Clients [i].SaidHello = FALSE;
+ NPServer.Clients [i].Paused = FALSE;
+ NPServer.Clients [i].Ready = FALSE;
+ NPServer.Clients [i].Socket = 0;
+ NPServer.Clients [i].ROMName = NULL;
+ NPServer.Clients [i].HostName = NULL;
+ NPServer.Clients [i].Who = NULL;
+ NPServer.Joypads [i] = 0;
+ }
+
+ NPServer.NumClients = 0;
+ NPServer.FrameCount = 0;
+
+#ifdef NP_DEBUG
+ printf ("SERVER: Creating socket @%ld\n", S9xGetMilliTime () - START);
+#endif
+ if ((NPServer.Socket = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ S9xNPSetError ("NetPlay Server: Can't create listening socket.");
+ return (FALSE);
+ }
+
+ val = 1;
+ setsockopt (NPServer.Socket, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&val, sizeof (val));
+
+ memset (&address, 0, sizeof (address));
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = htonl (INADDR_ANY);
+ address.sin_port = htons (port);
+
+#ifdef NP_DEBUG
+ printf ("SERVER: Binding socket to address and port @%ld\n", S9xGetMilliTime () - START);
+#endif
+ if (bind (NPServer.Socket, (struct sockaddr *) &address, sizeof (address)) < 0)
+ {
+ S9xNPSetError ("NetPlay Server: Can't bind socket to port number.\nPort already in use?");
+ return (FALSE);
+ }
+
+#ifdef NP_DEBUG
+ printf ("SERVER: Getting socket to listen @%ld\n", S9xGetMilliTime () - START);
+#endif
+ if (listen (NPServer.Socket, NP_MAX_CLIENTS) < 0)
+ {
+ S9xNPSetError ("NetPlay Server: Can't get new socket to listen.");
+ return (FALSE);
+ }
+
+#ifdef NP_DEBUG
+ printf ("SERVER: Init complete @%ld\n", S9xGetMilliTime () - START);
+#endif
+ return (TRUE);
+}
+
+void S9xNPServerLoop (void *)
+{
+#ifdef __WIN32__
+ BOOL success = FALSE;
+#else
+ bool8 success = FALSE;
+#endif
+
+ while (server_continue)
+ {
+ fd_set read_fds;
+ struct timeval timeout;
+ int res;
+ int i;
+
+ int max_fd = NPServer.Socket;
+
+#ifdef __WIN32__
+ Sleep (0);
+#endif
+
+ if (success && !Settings.Paused && !Settings.StopEmulation &&
+ !Settings.ForcedPause && !NPServer.Paused)
+ {
+ S9xNPSendHeartBeat ();
+ }
+
+ do
+ {
+ FD_ZERO (&read_fds);
+ FD_SET (NPServer.Socket, &read_fds);
+ for (i = 0; i < NP_MAX_CLIENTS; i++)
+ {
+ if (NPServer.Clients [i].Connected)
+ {
+ FD_SET (NPServer.Clients [i].Socket, &read_fds);
+ if (NPServer.Clients [i].Socket > max_fd)
+ max_fd = NPServer.Clients [i].Socket;
+ }
+ }
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1000;
+ res = select (max_fd + 1, &read_fds, NULL, NULL, &timeout);
+
+ if (res > 0)
+ {
+ if (FD_ISSET (NPServer.Socket, &read_fds))
+ S9xNPAcceptClient (NPServer.Socket, FALSE);
+
+ for (i = 0; i < NP_MAX_CLIENTS; i++)
+ {
+ if (NPServer.Clients [i].Connected &&
+ FD_ISSET (NPServer.Clients [i].Socket, &read_fds))
+ {
+ S9xNPProcessClient (i);
+ }
+ }
+ }
+ } while (res > 0);
+
+#ifdef __WIN32__
+ success = WaitForSingleObject (GUI.ServerTimerSemaphore, 200) == WAIT_OBJECT_0;
+#endif
+
+ while (NPServer.TaskHead != NPServer.TaskTail)
+ {
+ void *task_data = NPServer.TaskQueue [NPServer.TaskHead].Data;
+
+#if defined(NP_DEBUG) && NP_DEBUG == 2
+ printf ("SERVER: task %d @%ld\n", NPServer.TaskQueue [NPServer.TaskHead].Task, S9xGetMilliTime () - START);
+#endif
+
+ switch (NPServer.TaskQueue [NPServer.TaskHead].Task)
+ {
+ case NP_SERVER_SEND_ROM_IMAGE:
+ S9xNPSendROMImageToAllClients ();
+ break;
+ case NP_SERVER_SYNC_CLIENT:
+ NPServer.Clients [(int) task_data].Ready = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPSyncClient ((int) task_data);
+ break;
+ case NP_SERVER_SYNC_ALL:
+ S9xNPSyncClients ();
+ break;
+ case NP_SERVER_SEND_FREEZE_FILE_ALL:
+ S9xNPSendFreezeFileToAllClients ((char *) task_data);
+ free ((char *) task_data);
+ break;
+ case NP_SERVER_SEND_ROM_LOAD_REQUEST_ALL:
+ S9xNPSendROMLoadRequest ((char *) task_data);
+ free ((char *) task_data);
+ break;
+ case NP_SERVER_RESET_ALL:
+ S9xNPNoClientReady (0);
+ S9xNPWaitForEmulationToComplete ();
+ S9xNPSetAction ("SERVER: Sending RESET to all clients...", TRUE);
+#ifdef NP_DEBUG
+ printf ("SERVER: Sending RESET to all clients @%ld\n", S9xGetMilliTime () - START);
+#endif
+ {
+ uint8 reset [7];
+ uint8 *ptr;
+
+ ptr = reset;
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = 0;
+ *ptr++ = NP_SERV_RESET;
+ WRITE_LONG (ptr, NPServer.FrameCount);
+ S9xNPSendToAllClients (reset, 7);
+ }
+ break;
+ case NP_SERVER_SEND_SRAM:
+ NPServer.Clients [(int) task_data].Ready = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPWaitForEmulationToComplete ();
+ S9xNPSendSRAMToClient ((int) task_data);
+ break;
+
+ case NP_SERVER_SEND_SRAM_ALL:
+ S9xNPNoClientReady ();
+ S9xNPWaitForEmulationToComplete ();
+ S9xNPSendSRAMToAllClients ();
+ break;
+
+ default:
+ S9xNPSetError ("SERVER: *** Unknown task ***\n");
+ break;
+ }
+ NPServer.TaskHead = (NPServer.TaskHead + 1) % NP_MAX_TASKS;
+ }
+ }
+#ifdef NP_DEBUG
+ printf ("SERVER: Server thread exiting @%ld\n", S9xGetMilliTime () - START);
+#endif
+ S9xNPStopServer ();
+}
+
+bool8 S9xNPStartServer (int port)
+{
+ static int p;
+
+#ifdef NP_DEBUG
+ printf ("SERVER: Starting server on port %d @%ld\n", port, S9xGetMilliTime () - START);
+#endif
+ p = port;
+ server_continue = TRUE;
+ if (S9xNPServerInit (port))
+#ifdef __WIN32__
+ return (_beginthread (S9xNPServerLoop, 0, &p) != ~0);
+#else
+ return (TRUE);
+#endif
+
+ return (FALSE);
+}
+
+void S9xNPStopServer ()
+{
+#ifdef NP_DEBUG
+ printf ("SERVER: Stopping server @%ld\n", S9xGetMilliTime () - START);
+#endif
+ server_continue = FALSE;
+ close (NPServer.Socket);
+
+ for (int i = 0; i < NP_MAX_CLIENTS; i++)
+ {
+ if (NPServer.Clients [i].Connected)
+ {
+ close (NPServer.Clients [i].Socket);
+ NPServer.Clients [i].Connected = FALSE;
+ NPServer.Clients [i].SaidHello = FALSE;
+ }
+ }
+}
+
+#ifdef __WIN32__
+void S9xGetTimeOfDay (struct timeval *n)
+{
+ unsigned long t = S9xGetMilliTime ();
+
+ n->tv_sec = t / 1000;
+ n->tv_usec = (t % 1000) * 1000;
+}
+#endif
+
+void S9xNPSendROMImageToAllClients ()
+{
+ S9xNPNoClientReady ();
+ S9xNPWaitForEmulationToComplete ();
+
+ int c;
+
+ for (c = NP_ONE_CLIENT; c < NP_MAX_CLIENTS; c++)
+ {
+ if (NPServer.Clients [c].SaidHello)
+ S9xNPSendROMImageToClient (c);
+ }
+
+ if (NPServer.SyncByReset)
+ {
+ S9xNPServerAddTask (NP_SERVER_SEND_SRAM_ALL, 0);
+ S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0);
+ }
+ else
+ S9xNPSyncClient (-1);
+}
+
+bool8 S9xNPSendROMImageToClient (int c)
+{
+#ifdef NP_DEBUG
+ printf ("SERVER: Sending ROM image to player %d @%ld\n", c + 1, S9xGetMilliTime () - START);
+#endif
+ sprintf (NetPlay.ActionMsg, "Sending ROM image to player %d...", c + 1);
+ S9xNPSetAction (NetPlay.ActionMsg, TRUE);
+
+ uint8 header [7 + 1 + 4];
+ uint8 *ptr = header;
+ int len = sizeof (header) + Memory.CalculatedSize +
+ strlen (Memory.ROMFilename) + 1;
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = NPServer.Clients [c].SendSequenceNum++;
+ *ptr++ = NP_SERV_ROM_IMAGE;
+ WRITE_LONG (ptr, len);
+ ptr += 4;
+ *ptr++ = Memory.HiROM;
+ WRITE_LONG (ptr, Memory.CalculatedSize);
+
+ if (!S9xNPSSendData (NPServer.Clients [c].Socket, header, sizeof (header)) ||
+ !S9xNPSSendData (NPServer.Clients [c].Socket, Memory.ROM,
+ Memory.CalculatedSize) ||
+ !S9xNPSSendData (NPServer.Clients [c].Socket, (uint8 *) Memory.ROMFilename,
+ strlen (Memory.ROMFilename) + 1))
+ {
+ S9xNPShutdownClient (c, TRUE);
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+void S9xNPSyncClients ()
+{
+ S9xNPNoClientReady ();
+ S9xNPSyncClient (-1);
+}
+
+void S9xNPSyncClient (int client)
+{
+#ifdef HAVE_MKSTEMP
+ char fname[] = "/tmp/snes9x_fztmpXXXXXX";
+#else
+ char fname [L_tmpnam];
+#endif
+
+ S9xNPWaitForEmulationToComplete ();
+
+ S9xNPSetAction ("SERVER: Freezing game...", TRUE);
+#ifdef HAVE_MKSTEMP
+ if ( (mkstemp(fname) < 0) && S9xFreezeGame(fname) )
+#else
+ if ( tmpnam(fname) && S9xFreezeGame(fname) )
+#endif
+ {
+ uint8 *data;
+ uint32 len;
+
+ S9xNPSetAction ("SERVER: Loading freeze file...", TRUE);
+ if (S9xNPLoadFreezeFile (fname, data, len))
+ {
+ int c;
+
+ if (client < 0)
+ {
+ for (c = NP_ONE_CLIENT; c < NP_MAX_CLIENTS; c++)
+ {
+ if (NPServer.Clients [c].SaidHello)
+ {
+ NPServer.Clients [client].Ready = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPSendFreezeFile (c, data, len);
+ }
+ }
+ }
+ else
+ {
+ NPServer.Clients [client].Ready = FALSE;
+ S9xNPRecomputePause ();
+ S9xNPSendFreezeFile (client, data, len);
+ }
+ delete data;
+ }
+ remove (fname);
+ }
+}
+
+bool8 S9xNPLoadFreezeFile (const char *fname, uint8 *&data, uint32 &len)
+{
+ FILE *ff;
+
+ if ((ff = fopen (fname, "rb")))
+ {
+ fseek (ff, 0, SEEK_END);
+ len = ftell (ff);
+ fseek (ff, 0, SEEK_SET);
+
+ data = new uint8 [len];
+ bool8 ok = (fread (data, 1, len, ff) == len);
+ fclose (ff);
+
+ return (ok);
+ }
+ return (FALSE);
+}
+
+void S9xNPSendFreezeFile (int c, uint8 *data, uint32 len)
+{
+#ifdef NP_DEBUG
+ printf ("SERVER: Sending freeze file to player %d @%ld\n", c + 1, S9xGetMilliTime () - START);
+#endif
+
+ sprintf (NetPlay.ActionMsg, "SERVER: Sending freeze-file to player %d...", c + 1);
+ S9xNPSetAction (NetPlay.ActionMsg, TRUE);
+ uint8 header [7 + 4];
+ uint8 *ptr = header;
+
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = NPServer.Clients [c].SendSequenceNum++;
+ *ptr++ = NP_SERV_FREEZE_FILE;
+ WRITE_LONG (ptr, len + 7 + 4);
+ ptr += 4;
+ WRITE_LONG (ptr, NPServer.FrameCount);
+
+ if (!S9xNPSSendData (NPServer.Clients [c].Socket, header, 7 + 4) ||
+ !S9xNPSSendData (NPServer.Clients [c].Socket, data, len))
+ {
+ S9xNPShutdownClient (c, TRUE);
+ }
+}
+
+void S9xNPRecomputePause ()
+{
+ int c;
+
+ for (c = 0; c < NP_MAX_CLIENTS; c++)
+ {
+ if (NPServer.Clients [c].SaidHello &&
+ (!NPServer.Clients [c].Ready || NPServer.Clients [c].Paused))
+ {
+#if defined(NP_DEBUG) && NP_DEBUG == 2
+ printf ("SERVER: Paused because of client %d (%d,%d) @%ld\n", c, NPServer.Clients [c].Ready, NPServer.Clients [c].Paused, S9xGetMilliTime () - START);
+#endif
+ NPServer.Paused = TRUE;
+ return;
+ }
+ }
+#if defined(NP_DEBUG) && NP_DEBUG == 2
+ printf ("SERVER: not paused @%ld\n", S9xGetMilliTime () - START);
+#endif
+ NPServer.Paused = FALSE;
+}
+
+void S9xNPNoClientReady (int start_index)
+{
+ int c;
+
+ for (c = start_index; c < NP_MAX_CLIENTS; c++)
+ NPServer.Clients [c].Ready = FALSE;
+ S9xNPRecomputePause ();
+}
+
+void S9xNPSendROMLoadRequest (const char *filename)
+{
+ S9xNPNoClientReady ();
+
+ int len = 7 + strlen (filename) + 1;
+ uint8 *data = new uint8 [len];
+ uint8 *ptr = data;
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = 0;
+ *ptr++ = NP_SERV_LOAD_ROM;
+ WRITE_LONG (ptr, len);
+ ptr += 4;
+ strcpy ((char *) ptr, filename);
+
+ for (int i = NP_ONE_CLIENT; i < NP_MAX_CLIENTS; i++)
+ {
+ if (NPServer.Clients [i].SaidHello)
+ {
+#ifdef NP_DEBUG
+ printf ("SERVER: Sending load ROM requesting to player %d @%ld\n", i + 1, S9xGetMilliTime () - START);
+#endif
+ sprintf (NetPlay.WarningMsg, "SERVER: sending ROM load request to player %d...", i + 1);
+ S9xNPSetAction (NetPlay.WarningMsg, TRUE);
+ data [1] = NPServer.Clients [i].SendSequenceNum++;
+ if (!S9xNPSSendData (NPServer.Clients [i].Socket, data, len))
+ {
+ S9xNPShutdownClient (i, TRUE);
+ }
+ }
+ }
+ delete data;
+}
+
+void S9xNPSendSRAMToAllClients ()
+{
+ int i;
+
+ for (i = NP_ONE_CLIENT; i < NP_MAX_CLIENTS; i++)
+ {
+ if (NPServer.Clients [i].SaidHello)
+ S9xNPSendSRAMToClient (i);
+ }
+}
+
+void S9xNPSendSRAMToClient (int c)
+{
+#ifdef NP_DEBUG
+ printf ("SERVER: Sending S-RAM data to player %d @%ld\n", c + 1, S9xGetMilliTime () - START);
+#endif
+ uint8 sram [7];
+ int SRAMSize = Memory.SRAMSize ?
+ (1 << (Memory.SRAMSize + 3)) * 128 : 0;
+ if (SRAMSize > 0x10000)
+ SRAMSize = 0x10000;
+ int len = 7 + SRAMSize;
+
+ sprintf (NetPlay.ActionMsg, "SERVER: Sending S-RAM to player %d...", c + 1);
+ S9xNPSetAction (NetPlay.ActionMsg, TRUE);
+
+ uint8 *ptr = sram;
+ *ptr++ = NP_SERV_MAGIC;
+ *ptr++ = NPServer.Clients [c].SendSequenceNum++;
+ *ptr++ = NP_SERV_SRAM_DATA;
+ WRITE_LONG (ptr, len);
+ if (!S9xNPSSendData (NPServer.Clients [c].Socket,
+ sram, sizeof (sram)) ||
+ (len > 7 &&
+ !S9xNPSSendData (NPServer.Clients [c].Socket,
+ ::SRAM, len - 7)))
+ {
+ S9xNPShutdownClient (c, TRUE);
+ }
+}
+
+void S9xNPSendFreezeFileToAllClients (const char *filename)
+{
+ uint8 *data;
+ uint32 len;
+
+ if (NPServer.NumClients > NP_ONE_CLIENT && S9xNPLoadFreezeFile (filename, data, len))
+ {
+ S9xNPNoClientReady ();
+
+ for (int c = NP_ONE_CLIENT; c < NP_MAX_CLIENTS; c++)
+ {
+ if (NPServer.Clients [c].SaidHello)
+ S9xNPSendFreezeFile (c, data, len);
+ }
+ delete data;
+ }
+}
+
+void S9xNPServerAddTask (uint32 task, void *data)
+{
+ NPServer.TaskQueue [NPServer.TaskTail].Task = task;
+ NPServer.TaskQueue [NPServer.TaskTail].Data = data;
+
+ NPServer.TaskTail = (NPServer.TaskTail + 1) % NP_MAX_TASKS;
+}
+
+void S9xNPReset ()
+{
+ S9xNPNoClientReady (0);
+ S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0);
+}
+
+void S9xNPWaitForEmulationToComplete ()
+{
+#ifdef NP_DEBUG
+ printf ("SERVER: WaitForEmulationToComplete start @%ld\n", S9xGetMilliTime () - START);
+#endif
+
+ while (!NetPlay.PendingWait4Sync && NetPlay.Connected &&
+ !Settings.ForcedPause && !Settings.StopEmulation &&
+ !Settings.Paused)
+ {
+#ifdef __WIN32__
+ Sleep (40);
+#endif
+ }
+#ifdef NP_DEBUG
+ printf ("SERVER: WaitForEmulationToComplete end @%ld\n", S9xGetMilliTime () - START);
+#endif
+}
+
+void S9xNPServerQueueSyncAll ()
+{
+ if (Settings.NetPlay && Settings.NetPlayServer &&
+ NPServer.NumClients > NP_ONE_CLIENT)
+ {
+ S9xNPNoClientReady ();
+ S9xNPDiscardHeartbeats ();
+ S9xNPServerAddTask (NP_SERVER_SYNC_ALL, 0);
+ }
+}
+
+void S9xNPServerQueueSendingROMImage ()
+{
+ if (Settings.NetPlay && Settings.NetPlayServer &&
+ NPServer.NumClients > NP_ONE_CLIENT)
+ {
+ S9xNPNoClientReady ();
+ S9xNPDiscardHeartbeats ();
+ S9xNPServerAddTask (NP_SERVER_SEND_ROM_IMAGE, 0);
+ }
+}
+
+void S9xNPServerQueueSendingFreezeFile (const char *filename)
+{
+ if (Settings.NetPlay && Settings.NetPlayServer &&
+ NPServer.NumClients > NP_ONE_CLIENT)
+ {
+ S9xNPNoClientReady ();
+ S9xNPDiscardHeartbeats ();
+ S9xNPServerAddTask (NP_SERVER_SEND_FREEZE_FILE_ALL,
+ (void *) strdup (filename));
+ }
+}
+
+void S9xNPServerQueueSendingLoadROMRequest (const char *filename)
+{
+ if (Settings.NetPlay && Settings.NetPlayServer &&
+ NPServer.NumClients > NP_ONE_CLIENT)
+ {
+ S9xNPNoClientReady ();
+ S9xNPDiscardHeartbeats ();
+ S9xNPServerAddTask (NP_SERVER_SEND_ROM_LOAD_REQUEST_ALL,
+ (void *) strdup (filename));
+ }
+}
+
+#ifndef __WIN32__
+uint32 S9xGetMilliTime ()
+{
+ static bool8 first = TRUE;
+ static long start_sec;
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ if (first)
+ {
+ start_sec = tv.tv_sec;
+ first = FALSE;
+ }
+ return ((uint32) ((tv.tv_sec - start_sec) * 1000 + tv.tv_usec / 1000));
+}
+#endif
+#endif
+
diff --git a/source/seta.cpp b/source/seta.cpp
new file mode 100644
index 0000000..4e7d208
--- /dev/null
+++ b/source/seta.cpp
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "seta.h"
+
+void (*SetSETA)(uint32, uint8)=&S9xSetST010;
+uint8 (*GetSETA)(uint32)=&S9xGetST010;
+
+extern "C"{
+uint8 S9xGetSetaDSP(uint32 Address)
+{
+ return GetSETA(Address);
+}
+
+void S9xSetSetaDSP(uint8 Byte, uint32 Address)
+{
+ SetSETA(Address, Byte);
+}
+}
+
diff --git a/source/seta.h b/source/seta.h
new file mode 100644
index 0000000..f857636
--- /dev/null
+++ b/source/seta.h
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+#ifndef NO_SETA
+#ifndef _seta_h
+#define _seta_h
+
+#include "port.h"
+
+#define ST_010 0x01
+#define ST_011 0x02
+#define ST_018 0x03
+
+
+extern "C"
+{
+uint8 S9xGetSetaDSP(uint32 Address);
+void S9xSetSetaDSP(uint8 byte,uint32 Address);
+uint8 S9xGetST018(uint32 Address);
+void S9xSetST018(uint8 Byte, uint32 Address);
+
+uint8 S9xGetST010(uint32 Address);
+void S9xSetST010(uint32 Address, uint8 Byte);
+uint8 S9xGetST011(uint32 Address);
+void S9xSetST011(uint32 Address, uint8 Byte);
+}
+
+extern void (*SetSETA)(uint32, uint8);
+extern uint8 (*GetSETA)(uint32);
+
+typedef struct SETA_ST010_STRUCT
+{
+ uint8 input_params[16];
+ uint8 output_params[16];
+ uint8 op_reg;
+ uint8 execute;
+ bool8 control_enable;
+} ST010_Regs;
+
+typedef struct SETA_ST011_STRUCT
+{
+ bool8 waiting4command;
+ uint8 status;
+ uint8 command;
+ uint32 in_count;
+ uint32 in_index;
+ uint32 out_count;
+ uint32 out_index;
+ uint8 parameters [512];
+ uint8 output [512];
+} ST011_Regs;
+
+typedef struct SETA_ST018_STRUCT
+{
+ bool8 waiting4command;
+ uint8 status;
+ uint8 part_command;
+ uint8 pass;
+ uint32 command;
+ uint32 in_count;
+ uint32 in_index;
+ uint32 out_count;
+ uint32 out_index;
+ uint8 parameters [512];
+ uint8 output [512];
+} ST018_Regs;
+
+#endif
+#endif
+
diff --git a/source/seta010.cpp b/source/seta010.cpp
new file mode 100644
index 0000000..13eab8a
--- /dev/null
+++ b/source/seta010.cpp
@@ -0,0 +1,750 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "seta.h"
+#include "memmap.h"
+
+// Mode 7 scaling constants for all raster lines
+const int16 ST010_M7Scale[176] = {
+ 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3,
+ 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b,
+ 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8,
+ 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6,
+ 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5,
+ 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d,
+ 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c,
+ 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e,
+ 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063,
+ 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a,
+ 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052,
+ 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c,
+ 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047,
+ 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042,
+ 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e,
+ 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a,
+ 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037,
+ 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034,
+ 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031,
+ 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f,
+ 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d,
+ 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b
+};
+
+// H-DMA hack
+bool seta_hack;
+
+//temporary Op04 requirement
+#include <math.h>
+
+#ifndef PI
+#define PI 3.1415926535897932384626433832795
+#endif
+
+ST010_Regs ST010;
+
+uint8 S9xGetST010(uint32 Address)
+{
+ if(!(Address&0x80000))
+ return 0x80;
+
+ if((Address&0xFFF)==0x20)
+ return ST010.op_reg;
+ if ((Address&0xFFF)==0x21)
+ return ST010.execute;
+ return Memory.SRAM[Address&Memory.SRAMMask];
+}
+
+const int16 ST010_SinTable[256] = {
+ 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2,
+ 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
+ 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a,
+ 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842,
+ 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6,
+ 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504,
+ 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3,
+ 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5,
+ 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d,
+ 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b,
+ 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23,
+ 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3,
+ 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4,
+ 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df,
+ 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b,
+ 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324,
+ 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2,
+ -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
+ -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a,
+ -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
+ -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6,
+ -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504,
+ -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3,
+ -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5,
+ -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d,
+ -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b,
+ -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23,
+ -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3,
+ -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3,
+ -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de,
+ -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b,
+ -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324};
+
+const unsigned char ST010_ArcTan[32][32] = {
+ { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+ { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
+ 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf},
+ { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb,
+ 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd},
+ { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8,
+ 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc},
+ { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5,
+ 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb},
+ { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
+ 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9},
+ { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0,
+ 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8},
+ { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae,
+ 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7},
+ { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac,
+ 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5},
+ { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa,
+ 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4},
+ { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8,
+ 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3},
+ { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6,
+ 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2},
+ { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1},
+ { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3,
+ 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0},
+ { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1,
+ 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf},
+ { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0,
+ 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae},
+ { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad},
+ { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d,
+ 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac},
+ { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c,
+ 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab},
+ { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b,
+ 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa},
+ { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a,
+ 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9},
+ { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99,
+ 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8},
+ { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98,
+ 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7},
+ { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98,
+ 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6},
+ { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5},
+ { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4},
+ { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95,
+ 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4},
+ { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95,
+ 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3},
+ { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94,
+ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2},
+ { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
+ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1},
+ { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93,
+ 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1},
+ { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
+ 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0}};
+
+short ST010_Sin(short Theta)
+{
+ return ST010_SinTable[(Theta >> 8) & 0xff];
+}
+
+short ST010_Cos(short Theta)
+{
+ return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff];
+}
+
+void ST010_OP01(short x0, short y0, short &x1, short &y1, short &Quadrant, short &Theta)
+{
+ if ((x0 < 0) && (y0 < 0))
+ {
+ x1 = -x0;
+ y1 = -y0;
+ Quadrant = -0x8000;
+ }
+ else if (x0 < 0)
+ {
+ x1 = y0;
+ y1 = -x0;
+ Quadrant = -0x4000;
+ }
+ else if (y0 < 0)
+ {
+ x1 = -y0;
+ y1 = x0;
+ Quadrant = 0x4000;
+ }
+ else
+ {
+ x1 = x0;
+ y1 = y0;
+ Quadrant = 0x0000;
+ }
+
+ while ((x1 > 0x1f) || (y1 > 0x1f))
+ {
+ if (x1 > 1) x1 >>= 1;
+ if (y1 > 1) y1 >>= 1;
+ }
+
+ if (y1 == 0) Quadrant += 0x4000;
+
+ Theta = (ST010_ArcTan[y1][x1] << 8) ^ Quadrant;
+}
+
+void ST010_Scale(short Multiplier, short X0, short Y0, int &X1, int &Y1)
+{
+ X1 = X0 * Multiplier << 1;
+ Y1 = Y0 * Multiplier << 1;
+}
+
+void ST010_Multiply(short Multiplicand, short Multiplier, int &Product)
+{
+ Product = Multiplicand * Multiplier << 1;
+}
+
+void ST010_Rotate(short Theta, short X0, short Y0, short &X1, short &Y1)
+{
+ X1 = (Y0 * ST010_Sin(Theta) >> 15) + (X0 * ST010_Cos(Theta) >> 15);
+ Y1 = (Y0 * ST010_Cos(Theta) >> 15) - (X0 * ST010_Sin(Theta) >> 15);
+}
+
+void SETA_Distance(short Y0, short X0, short &Distance)
+{
+ if (X0 < 0) X0 = -X0;
+ if (Y0 < 0) Y0 = -Y0;
+ Distance = ((X0 * 0x7af0) + 0x4000) >> 15;
+}
+
+void ST010_SortDrivers(uint16 Positions, uint16 Places[32], uint16 Drivers[32])
+{
+ bool Sorted;
+ uint16 Temp;
+
+ if (Positions > 1)
+ do {
+ Sorted = true;
+ for (int i = 0; i < Positions - 1; i++)
+ if (Places[i] < Places[i + 1])
+ {
+ Temp = Places[i + 1];
+ Places[i + 1] = Places[i];
+ Places[i] = Temp;
+
+ Temp = Drivers[i + 1];
+ Drivers[i + 1] = Drivers[i];
+ Drivers[i] = Temp;
+
+ Sorted = false;
+ }
+ Positions--;
+ } while (!Sorted);
+}
+
+#define ST010_WORD(offset) (Memory.SRAM[offset + 1] << 8) | Memory.SRAM[offset]
+
+void S9xSetST010(uint32 Address, uint8 Byte)
+{
+ if(!(Address&0x80000))
+ {
+ ST010.control_enable=TRUE;
+ return;
+ }
+ //printf("Write %06X:%02X\n", Address, Byte);
+
+ if((Address &0xFFF) ==0x20 && ST010.control_enable)
+ ST010.op_reg=Byte;
+ if((Address &0xFFF) ==0x21 && ST010.control_enable)
+ ST010.execute=Byte;
+ else Memory.SRAM[Address&Memory.SRAMMask]=Byte;
+
+ if(ST010.execute&0x80)
+ {
+ switch(ST010.op_reg)
+ {
+ // Sorts Driver Placements
+ //
+ // Input
+ // 0x0024-0x0025 : Positions
+ // 0x0040-0x007f : Places
+ // 0x0080-0x00ff : Drivers
+ // Output
+ // 0x0040-0x007f : Places
+ // 0x0080-0x00ff : Drivers
+ //
+ case 0x02:
+ {
+#ifdef FAST_LSB_WORD_ACCESS
+ ST010_SortDrivers(*(short*)&SRAM[0x0024], (uint16*) (SRAM + 0x0040), (uint16*) (SRAM + 0x0080));
+#else
+ uint16 Places[32];
+ uint16 Positions = ST010_WORD(0x0024);
+ int Pos, Offset;
+
+ Offset = 0;
+
+ for (Pos = 0; Pos < Positions; Pos++)
+ {
+ Places[Pos] = ST010_WORD(0x0040 + Offset);
+ Offset += 2;
+ }
+
+ ST010_SortDrivers(Positions, Places, (uint16*) (SRAM + 0x0080));
+
+ Offset = 0;
+
+ for (Pos = 0; Pos < Positions; Pos++)
+ {
+ SRAM[0x0040 + Offset]=(uint8)(Places[Pos]);
+ SRAM[0x0041 + Offset]=(uint8)(Places[Pos] >> 8);
+ Offset += 2;
+ }
+#endif
+ break;
+
+ }
+
+ // Two Dimensional Coordinate Scale
+ //
+ // Input
+ // 0x0000-0x0001 : X0 (signed)
+ // 0x0002-0x0003 : Y0 (signed)
+ // 0x0004-0x0005 : Multiplier (signed)
+ // Output
+ // 0x0010-0x0013 : X1 (signed)
+ // 0x0014-0x0017 : Y1 (signed)
+ //
+ case 0x03:
+ {
+#ifdef FAST_LSB_WORD_ACCESS
+ ST010_Scale(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002],
+ (int&) Memory.SRAM[0x0010], (int&) Memory.SRAM[0x0014]);
+#else
+ int x1, y1;
+
+ ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1);
+
+ Memory.SRAM[0x0010]=(uint8)(x1);
+ Memory.SRAM[0x0011]=(uint8)(x1 >> 8);
+ Memory.SRAM[0x0012]=(uint8)(x1 >> 16);
+ Memory.SRAM[0x0013]=(uint8)(x1 >> 24);
+ Memory.SRAM[0x0014]=(uint8)(y1);
+ Memory.SRAM[0x0015]=(uint8)(y1 >> 8);
+ Memory.SRAM[0x0016]=(uint8)(y1 >> 16);
+ Memory.SRAM[0x0017]=(uint8)(y1 >> 24);
+#endif
+ break;
+ }
+
+ // 16-bit Multiplication
+ //
+ // Input
+ // 0x0000-0x0001 : Multiplcand (signed)
+ // 0x0002-0x0003 : Multiplier (signed)
+ // Output
+ // 0x0010-0x0013 : Product (signed)
+ //
+ case 0x06:
+ {
+#ifdef FAST_LSB_WORD_ACCESS
+ ST010_Multiply(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], (int&) Memory.SRAM[0x0010]);
+#else
+ int Product;
+
+ ST010_Multiply(ST010_WORD(0x0000), ST010_WORD(0x0002), Product);
+
+ Memory.SRAM[0x0010]=(uint8)(Product);
+ Memory.SRAM[0x0011]=(uint8)(Product >> 8);
+ Memory.SRAM[0x0012]=(uint8)(Product >> 16);
+ Memory.SRAM[0x0013]=(uint8)(Product >> 24);
+#endif
+ break;
+ }
+
+ // Mode 7 Raster Data Calculation
+ //
+ // Input
+ // 0x0000-0x0001 : Angle (signed)
+ // Output
+ // 0x00f0-0x024f : Mode 7 Matrix A
+ // 0x0250-0x03af : Mode 7 Matrix B
+ // 0x03b0-0x050f : Mode 7 Matrix C
+ // 0x0510-0x066f : Mode 7 Matrix D
+ //
+ case 0x07:
+ {
+ int16 data;
+ int32 offset = 0;
+ int16 Theta = ST010_WORD(0x0000);
+
+ for (int32 line = 0; line < 176; line++)
+ {
+ // Calculate Mode 7 Matrix A/D data
+ data = ST010_M7Scale[line] * ST010_Cos(Theta) >> 15;
+
+ Memory.SRAM[0x00f0 + offset]=(uint8)(data);
+ Memory.SRAM[0x00f1 + offset]=(uint8)(data >> 8);
+ Memory.SRAM[0x0510 + offset]=(uint8)(data);
+ Memory.SRAM[0x0511 + offset]=(uint8)(data >> 8);
+
+ // Calculate Mode 7 Matrix B/C data
+ data = ST010_M7Scale[line] * ST010_Sin(Theta) >> 15;
+
+ Memory.SRAM[0x0250 + offset]=(uint8)(data);
+ Memory.SRAM[0x0251 + offset]=(uint8)(data >> 8);
+
+ if (data) data = ~data;
+
+ Memory.SRAM[0x03b0 + offset]=(uint8)(data);
+ Memory.SRAM[0x03b1 + offset]=(uint8)(data >> 8);
+
+ offset += 2;
+ }
+
+ // Shift Angle for use with Lookup table
+ Memory.SRAM[0x00] = Memory.SRAM[0x01];
+ Memory.SRAM[0x01] = 0x00;
+
+ break;
+ }
+
+ // Two dimensional Coordinate Rotation
+ //
+ // Input
+ // 0x0000-0x0001 : X0 (signed)
+ // 0x0002-0x0003 : Y0 (signed)
+ // 0x0004-0x0005 : Angle (signed)
+ // Output
+ // 0x0010-0x0011 : X1 (signed)
+ // 0x0012-0x0013 : Y1 (signed)
+ //
+ case 0x08:
+ {
+#ifdef FAST_LSB_WORD_ACCESS
+ ST010_Rotate(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002],
+ (short&) Memory.SRAM[0x0010], (short&) Memory.SRAM[0x0012]);
+#else
+ short x1, y1;
+
+ ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1);
+
+ Memory.SRAM[0x0010]=(uint8)(x1);
+ Memory.SRAM[0x0011]=(uint8)(x1 >> 8);
+ Memory.SRAM[0x0012]=(uint8)(y1);
+ Memory.SRAM[0x0013]=(uint8)(y1 >> 8);
+#endif
+ break;
+ }
+
+ // Input
+ // 0x0000-0x0001 : DX (signed)
+ // 0x0002-0x0003 : DY (signed)
+ // Output
+ // 0x0010-0x0011 : Angle (signed)
+ //
+ case 0x01:
+ {
+ Memory.SRAM[0x0006] = Memory.SRAM[0x0002];
+ Memory.SRAM[0x0007] = Memory.SRAM[0x0003];
+
+#ifdef FAST_LSB_WORD_ACCESS
+ ST010_OP01(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002],
+ (short&) Memory.SRAM[0x0000], (short&) Memory.SRAM[0x0002],
+ (short&) Memory.SRAM[0x0004], (short&) Memory.SRAM[0x0010]);
+#else
+ short x1, y1, Quadrant, Theta;
+
+ ST010_OP01(ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1, Quadrant, Theta);
+
+ Memory.SRAM[0x0000]=(uint8)(x1);
+ Memory.SRAM[0x0001]=(uint8)(x1 >> 8);
+ Memory.SRAM[0x0002]=(uint8)(y1);
+ Memory.SRAM[0x0003]=(uint8)(y1 >> 8);
+ Memory.SRAM[0x0004]=(uint8)(Quadrant);
+ Memory.SRAM[0x0005]=(uint8)(Quadrant >> 8);
+ Memory.SRAM[0x0010]=(uint8)(Theta);
+ Memory.SRAM[0x0011]=(uint8)(Theta >> 8);
+#endif
+ break;
+ }
+
+ // calculate the vector length of (x,y)
+ case 0x04:
+ {
+ int16 square, x,y;
+#ifdef FAST_LSB_WORD_ACCESS
+ x=*((int16*)Memory.SRAM);
+ y=*((int16*)&Memory.SRAM[2]);
+#else
+ x=Memory.SRAM[0]|(Memory.SRAM[1]<<8);
+ y=Memory.SRAM[2]|(Memory.SRAM[3]<<8);
+#endif
+ square=(int16)sqrt((double)(y*y+x*x));
+ //SETA_Distance( x,y,square );
+
+#ifdef FAST_LSB_WORD_ACCESS
+ *((int16*)&Memory.SRAM[0x10])=square;
+#else
+ Memory.SRAM[0x10]=(uint8)(square);
+ Memory.SRAM[0x11]=(uint8)(square>>8);
+#endif
+ break;
+ }
+
+ // calculate AI orientation based on specific guidelines
+ case 0x05:
+ {
+ int dx,dy;
+ int16 a1,b1,c1;
+ uint16 o1;
+
+ bool wrap=false;
+
+ // target (x,y) coordinates
+ int16 ypos_max = ST010_WORD(0x00C0);
+ int16 xpos_max = ST010_WORD(0x00C2);
+
+ // current coordinates and direction
+ int32 ypos = SRAM[0xC4]|(SRAM[0xC5]<<8)|(SRAM[0xC6]<<16)|(SRAM[0xC7]<<24);
+ int32 xpos = SRAM[0xC8]|(SRAM[0xC9]<<8)|(SRAM[0xCA]<<16)|(SRAM[0xCB]<<24);
+ uint16 rot = SRAM[0xCC]|(SRAM[0xCD]<<8);
+
+ // physics
+ uint16 speed = ST010_WORD(0x00D4);
+ uint16 accel = ST010_WORD(0x00D6);
+ uint16 speed_max = ST010_WORD(0x00D8);
+
+ // special condition acknowledgment
+ int16 system = ST010_WORD(0x00DA);
+ int16 flags = ST010_WORD(0x00DC);
+
+ // new target coordinates
+ int16 ypos_new = ST010_WORD(0x00DE);
+ int16 xpos_new = ST010_WORD(0x00E0);
+
+ // mask upper bit
+ xpos_new &= 0x7FFF;
+
+ // get the current distance
+ dx = xpos_max-(xpos>>16);
+ dy = ypos_max-(ypos>>16);
+
+ // quirk: clear and move in9
+ SRAM[0xD2]=0xFF;
+ SRAM[0xD3]=0xFF;
+ SRAM[0xDA]=0;
+ SRAM[0xDB]=0;
+
+ // grab the target angle
+ ST010_OP01(dy,dx,a1,b1,c1,(int16 &)o1);
+
+ // check for wrapping
+ //if((o1<0x6000 && rot>0xA000) ||
+ // (rot<0x6000 && o1>0xA000))
+ //if(o1<rot)
+ if(abs(o1-rot)>0x8000)
+ {
+ o1+=0x8000;
+ rot+=0x8000;
+ wrap=true;
+ }
+ //o1=0x0000;
+ //rot=0xFF00;
+
+ uint16 old_speed;
+
+ old_speed = speed;
+
+ // special case
+ if(abs(o1-rot)==0x8000)
+ {
+ speed = 0x100;
+ }
+ // slow down for sharp curves
+ else if(abs(o1-rot)>=0x1000)
+ {
+ uint32 slow = abs(o1-rot);
+ slow >>= 4; // scaling
+ speed -= slow;
+ }
+ // otherwise accelerate
+ else
+ {
+ speed += accel;
+ if(speed > speed_max)
+ {
+ // clip speed
+ speed = speed_max;
+ }
+ }
+
+ // prevent negative/positive overflow
+ if(abs(old_speed-speed)>0x8000) {
+ if(old_speed<speed) speed=0;
+ else speed=0xff00;
+ }
+
+ // adjust direction by so many degrees
+ // be careful of negative adjustments
+ if( (o1>rot && (o1-rot)>0x80) ||
+ (o1<rot && (rot-o1)>=0x80) )
+ {
+ if(o1<rot) rot-=0x280;
+ else if(o1>rot) rot+=0x280;
+ }
+
+ // turn off wrapping
+ if(wrap) rot-=0x8000;
+
+ // now check the distances (store for later)
+ dx = (xpos_max<<16)-xpos;
+ dy = (ypos_max<<16)-ypos;
+ dx>>=16;
+ dy>>=16;
+
+ // if we're in so many units of the target, signal it
+ if( ( system && (dy<=6 && dy>=-8) && (dx<=126 && dx>=-128)) ||
+ (!system && (dx<=6 && dx>=-8) && (dy<=126 && dy>=-128)) )
+ {
+ // announce our new destination and flag it
+ xpos_max = xpos_new&0x7FFF;
+ ypos_max = ypos_new;
+ flags |= 0x08;
+ }
+
+ // update position
+ xpos -= (ST010_Cos(rot) * 0x400 >> 15) * (speed >> 8) << 1;
+ ypos -= (ST010_Sin(rot) * 0x400 >> 15) * (speed >> 8) << 1;
+
+ // quirk: mask upper byte
+ xpos &= 0x1FFFFFFF;
+ ypos &= 0x1FFFFFFF;
+
+ SRAM[0x00C0]=(uint8)(ypos_max);
+ SRAM[0x00C1]=(uint8)(ypos_max >> 8);
+ SRAM[0x00C2]=(uint8)(xpos_max);
+ SRAM[0x00C3]=(uint8)(xpos_max >> 8);
+ SRAM[0x00C4]=(uint8)(ypos);
+ SRAM[0x00C5]=(uint8)(ypos >> 8);
+ SRAM[0x00C6]=(uint8)(ypos >> 16);
+ SRAM[0x00C7]=(uint8)(ypos >> 24);
+ SRAM[0x00C8]=(uint8)(xpos);
+ SRAM[0x00C9]=(uint8)(xpos >> 8);
+ SRAM[0x00CA]=(uint8)(xpos >> 16);
+ SRAM[0x00CB]=(uint8)(xpos >> 24);
+ SRAM[0x00CC]=(uint8)(rot);
+ SRAM[0x00CD]=(uint8)(rot >> 8);
+ SRAM[0x00D4]=(uint8)(speed);
+ SRAM[0x00D5]=(uint8)(speed >> 8);
+ SRAM[0x00DC]=(uint8)(flags);
+ SRAM[0x00DD]=(uint8)(flags >> 8);
+
+ break;
+ }
+
+ default:
+ printf("Unknown Op\n");
+ break;
+ }
+
+ // lower signal: op processed
+ ST010.op_reg=0;
+ ST010.execute=0;
+ }
+}
+
diff --git a/source/seta011.cpp b/source/seta011.cpp
new file mode 100644
index 0000000..b8fd213
--- /dev/null
+++ b/source/seta011.cpp
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <stdio.h>
+#include "seta.h"
+#include "memmap.h"
+
+ST011_Regs ST011;
+
+// shougi playboard
+uint8 board[9][9];
+
+// debug
+static int line = 0;
+
+uint8 S9xGetST011(uint32 Address)
+{
+ uint8 t;
+ uint16 address = (uint16) Address & 0xFFFF;
+
+ // line counter
+ line++;
+
+ // status check
+ if (address == 0x01)
+ {
+ t = 0xFF;
+ }
+ // read directly from s-ram
+ else
+ {
+ t = Memory.SRAM[address];
+ }
+
+ // debug
+// if(address<0x150)
+// printf( "ST011 R: %06X %02X\n", Address, t);
+
+ return t;
+}
+
+void S9xSetST011(uint32 Address, uint8 Byte)
+{
+ uint16 address = (uint16) Address & 0xFFFF;
+ static bool reset = false;
+
+ // debug
+ line++;
+
+ if(!reset)
+ {
+ // bootup values
+ ST011.waiting4command = true;
+ reset = true;
+ }
+
+ // debug
+// if(address<0x150)
+// printf( "ST011 W: %06X %02X\n", Address, Byte );
+
+ Memory.SRAM[address]=Byte;
+
+ // op commands/data goes through this address
+ if(address==0x00)
+ {
+ // check for new commands
+ if (ST011.waiting4command)
+ {
+ ST011.waiting4command = false;
+ ST011.command = Byte;
+ ST011.in_index = 0;
+ ST011.out_index = 0;
+ switch(ST011.command)
+ {
+ case 0x01: ST011.in_count = 12*10+8; break;
+ case 0x02: ST011.in_count = 4; break;
+ case 0x04: ST011.in_count = 0; break;
+ case 0x05: ST011.in_count = 0; break;
+ case 0x06: ST011.in_count = 0; break;
+ case 0x07: ST011.in_count = 0; break;
+ case 0x0E: ST011.in_count = 0; break;
+ default: ST011.waiting4command=true; break;
+ }
+ }
+ else
+ {
+ ST011.parameters [ST011.in_index] = Byte;
+ ST011.in_index++;
+ }
+ }
+
+ if (ST011.in_count==ST011.in_index)
+ {
+ // Actually execute the command
+ ST011.waiting4command = true;
+ ST011.out_index = 0;
+ switch (ST011.command)
+ {
+ // unknown: download playboard
+ case 0x01:
+ {
+ // 9x9 board data: top to bottom, left to right
+ // Values represent piece types and ownership
+ for( int lcv=0; lcv<9; lcv++ )
+ memcpy( board[lcv], ST011.parameters+lcv*10, 9*1 );
+ }
+ break;
+
+ // unknown
+ case 0x02: break;
+
+ // unknown
+ case 0x04:
+ {
+ // outputs
+ Memory.SRAM[0x12C] = 0x00;
+ //Memory.SRAM[0x12D] = 0x00;
+ Memory.SRAM[0x12E] = 0x00;
+ }
+ break;
+
+ // unknown
+ case 0x05:
+ {
+ // outputs
+ Memory.SRAM[0x12C] = 0x00;
+ //Memory.SRAM[0x12D] = 0x00;
+ Memory.SRAM[0x12E] = 0x00;
+ }
+ break;
+
+ // unknown
+ case 0x06: break;
+ case 0x07: break;
+
+ // unknown
+ case 0x0E:
+ {
+ // outputs
+ Memory.SRAM[0x12C] = 0x00;
+ Memory.SRAM[0x12D] = 0x00;
+ }
+ break;
+ }
+ }
+}
+
diff --git a/source/seta018.cpp b/source/seta018.cpp
new file mode 100644
index 0000000..f0b00e1
--- /dev/null
+++ b/source/seta018.cpp
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "seta.h"
+#include "memmap.h"
+
+ST018_Regs ST018;
+
+static int line; // line counter
+
+extern "C"{
+uint8 S9xGetST018(uint32 Address)
+{
+ uint8 t;
+ uint16 address = (uint16) Address & 0xFFFF;
+
+ line++;
+
+ // these roles may be flipped
+ // op output
+ if (address == 0x3804)
+ {
+ if (ST018.out_count)
+ {
+ t = (uint8) ST018.output [ST018.out_index];
+ ST018.out_index++;
+ if (ST018.out_count==ST018.out_index)
+ ST018.out_count=0;
+ }
+ else
+ t = 0x81;
+ }
+ // status register
+ else if (address == 0x3800)
+ t = ST018.status;
+
+ printf( "ST018 R: %06X %02X\n", Address, t);
+
+ return t;
+}
+
+void S9xSetST018(uint8 Byte, uint32 Address)
+{
+ uint16 address = (uint16) Address&0xFFFF;
+ static bool reset = false;
+
+ printf( "ST018 W: %06X %02X\n", Address, Byte );
+
+ line++;
+
+ if (!reset)
+ {
+ // bootup values
+ ST018.waiting4command = true;
+ ST018.part_command = 0;
+ reset = true;
+ }
+
+ Memory.SRAM[address]=Byte;
+
+ // default status for now
+ ST018.status = 0x00;
+
+ // op data goes through this address
+ if (address==0x3804)
+ {
+ // check for new commands: 3 bytes length
+ if(ST018.waiting4command && ST018.part_command==2)
+ {
+ ST018.waiting4command = false;
+ ST018.command <<= 8;
+ ST018.command |= Byte;
+ ST018.in_index = 0;
+ ST018.out_index = 0;
+ ST018.part_command = 0; // 3-byte commands
+ ST018.pass = 0; // data streams into the chip
+ switch(ST018.command & 0xFFFFFF)
+ {
+ case 0x0100: ST018.in_count = 0; break;
+ case 0xFF00: ST018.in_count = 0; break;
+ default: ST018.waiting4command = true; break;
+ }
+ }
+ else if(ST018.waiting4command)
+ {
+ // 3-byte commands
+ ST018.part_command++;
+ ST018.command <<= 8;
+ ST018.command |= Byte;
+ }
+ }
+ // extra parameters
+ else if (address==0x3802)
+ {
+ ST018.parameters[ST018.in_index] = Byte;
+ ST018.in_index++;
+ }
+
+ if (ST018.in_count==ST018.in_index)
+ {
+ // Actually execute the command
+ ST018.waiting4command = true;
+ ST018.in_index = 0;
+ ST018.out_index = 0;
+ switch (ST018.command)
+ {
+ // hardware check?
+ case 0x0100:
+ ST018.waiting4command = false;
+ ST018.pass++;
+ if (ST018.pass==1)
+ {
+ ST018.in_count = 1;
+ ST018.out_count = 2;
+
+ // Overload's research
+ ST018.output[0x00] = 0x81;
+ ST018.output[0x01] = 0x81;
+ }
+ else
+ {
+ //ST018.in_count = 1;
+ ST018.out_count = 3;
+
+ // no reason to change this
+ //ST018.output[0x00] = 0x81;
+ //ST018.output[0x01] = 0x81;
+ ST018.output[0x02] = 0x81;
+
+ // done processing requests
+ if (ST018.pass==3)
+ ST018.waiting4command = true;
+ }
+ break;
+
+ // unknown: feels like a security detection
+ // format identical to 0x0100
+ case 0xFF00:
+ ST018.waiting4command = false;
+ ST018.pass++;
+ if (ST018.pass==1)
+ {
+ ST018.in_count = 1;
+ ST018.out_count = 2;
+
+ // Overload's research
+ ST018.output[0x00] = 0x81;
+ ST018.output[0x01] = 0x81;
+ }
+ else
+ {
+ static int a=0;
+
+ //ST018.in_count = 1;
+ ST018.out_count = 3;
+
+ // no reason to change this
+ //ST018.output[0x00] = 0x81;
+ //ST018.output[0x01] = 0x81;
+ ST018.output[0x02] = 0x81;
+
+ // done processing requests
+ if (ST018.pass==3)
+ ST018.waiting4command = true;
+ }
+ break;
+ }
+ }
+}
+}
+
diff --git a/source/sfc.mk b/source/sfc.mk
new file mode 100644
index 0000000..dccdd3b
--- /dev/null
+++ b/source/sfc.mk
@@ -0,0 +1,83 @@
+# sfc.mk
+
+SRC += $(SFCDIR)/c4.cpp \
+ $(SFCDIR)/c4emu.cpp \
+ $(SFCDIR)/cheats.cpp \
+ $(SFCDIR)/cheats2.cpp \
+ $(SFCDIR)/clip.cpp \
+ $(SFCDIR)/cpu.cpp \
+ $(SFCDIR)/cpuexec.cpp \
+ $(SFCDIR)/cpuops.cpp \
+ $(SFCDIR)/data.cpp \
+ $(SFCDIR)/dma.cpp \
+ $(SFCDIR)/dsp1.cpp \
+ $(SFCDIR)/fxdbg.cpp \
+ $(SFCDIR)/fxemu.cpp \
+ $(SFCDIR)/fxinst.cpp \
+ $(SFCDIR)/gfx.cpp \
+ $(SFCDIR)/globals.cpp \
+ $(SFCDIR)/memmap.cpp \
+ $(SFCDIR)/ppu.cpp \
+ $(SFCDIR)/sa1.cpp \
+ $(SFCDIR)/sa1cpu.cpp \
+ $(SFCDIR)/sdd1.cpp \
+ $(SFCDIR)/sdd1emu.cpp \
+ $(SFCDIR)/snapshot.cpp \
+ $(SFCDIR)/snes9x.cpp \
+ $(SFCDIR)/srtc.cpp \
+ $(SFCDIR)/tile.cpp \
+ $(SFCDIR)/apu.cpp \
+ $(SFCDIR)/spc700.cpp \
+ $(SFCDIR)/soundux.cpp \
+ $(SFCDIR)/apudebug.cpp \
+ $(SFCDIR)/debug.cpp \
+ $(SFCDIR)/snaporig.cpp \
+ $(SFCDIR)/movie.cpp \
+ $(SFCDIR)/screenshot.cpp \
+ $(SFCDIR)/spc7110.cpp \
+ $(SFCDIR)/obc1.cpp \
+ $(SFCDIR)/seta.cpp \
+ $(SFCDIR)/seta010.cpp \
+ $(SFCDIR)/seta011.cpp \
+ $(SFCDIR)/seta018.cpp \
+ $(SFCDIR)/loadzip.cpp \
+ $(SFCDIR)/nds/charsets.c \
+ $(SFCDIR)/nds/entry.cpp \
+ $(SFCDIR)/nds/displaymodes.cpp\
+ $(SFCDIR)/nds/bitmap.c \
+ $(SFCDIR)/nds/bdf_font.c \
+ $(SFCDIR)/nds/draw.c \
+ $(SFCDIR)/nds/gui.c \
+ $(SFCDIR)/nds/ds2_main.c \
+ $(SFCDIR)/nds/gcheat.c \
+ $(SFCDIR)/nds/cheats3.cpp \
+ $(SFCDIR)/unzip/explode.c \
+ $(SFCDIR)/unzip/unreduce.c \
+ $(SFCDIR)/unzip/unshrink.c \
+ $(SFCDIR)/unzip/unzip.c \
+
+
+
+CFLAGS += -I$(SFCDIR) -I$(SFCDIR)/nds -I$(SFCDIR)/unzip\
+ -DSPC700_C \
+ -DEXECUTE_SUPERFX_PER_LINE \
+ -DSDD1_DECOMP \
+ -DVAR_CYCLES \
+ -DCPU_SHUTDOWN \
+ -DSPC700_SHUTDOWN \
+ -DNO_INLINE_SET_GET \
+ -DNOASM -DHAVE_MKSTEMP \
+ '-DACCEPT_SIZE_T=size_t' \
+ -DUNZIP_SUPPORT \
+
+VPATH += $(SFCDIR) $(SFCDIR)/nds $(SFCDIR)/unzip
+
+
+
+# $(NETPLAYDEFINES) \
+# $(UNZIPDEFINES) \
+
+
+
+
+
diff --git a/source/snaporig.cpp b/source/snaporig.cpp
new file mode 100644
index 0000000..090c378
--- /dev/null
+++ b/source/snaporig.cpp
@@ -0,0 +1,465 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+
+#if defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#include "snapshot.h"
+#include "snaporig.h"
+#include "memmap.h"
+#include "snes9x.h"
+#include "65c816.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "display.h"
+#include "apu.h"
+#include "soundux.h"
+
+struct SOrigPPU OrigPPU;
+struct SOrigDMA OrigDMA [8];
+struct SOrigRegisters OrigRegisters;
+struct SOrigCPUState OrigCPU;
+struct SOrigAPU OrigAPU;
+SOrigSoundData OrigSoundData;
+struct SOrigAPURegisters OrigAPURegisters;
+char ROMFilename [1025];
+
+static int ReadOrigSnapshot (STREAM);
+
+bool8 S9xLoadOrigSnapshot (const char *filename)
+{
+ FILE* fp;
+
+ fp = fopen(filename, "r");
+ if(NULL == fp)
+ return (FALSE);
+
+ int result;
+ if ((result = ReadOrigSnapshot (fp)) != SUCCESS)
+ {
+ fclose(fp);
+ return (FALSE);
+ }
+
+ fclose(fp);
+ return (TRUE);
+}
+
+static int ReadBlock (const char *key, void *block, int max_len, STREAM snap)
+{
+ char buffer [20];
+ int len = 0;
+ int rem = 0;
+
+ if (READ_STREAM (buffer, 11, snap) != 11 ||
+ strncmp (buffer, key, 4) != 0 ||
+ (len = atoi (&buffer [4])) == 0)
+ return (WRONG_FORMAT);
+
+ if (len > max_len)
+ {
+ rem = len - max_len;
+ len = max_len;
+ }
+ if (READ_STREAM (block, len, snap) != len)
+ return (WRONG_FORMAT);
+
+ if (rem)
+ {
+ char *junk = new char [rem];
+ READ_STREAM (junk, rem, snap);
+ delete[] junk;
+ }
+
+ return (SUCCESS);
+}
+
+static int ReadOrigSnapshot (STREAM snap)
+{
+ char buffer [_MAX_PATH];
+ char rom_filename [_MAX_PATH];
+ int result;
+ int i;
+ int j;
+
+ int version;
+ int len = strlen (ORIG_SNAPSHOT_MAGIC) + 1 + 4 + 1;
+ if (READ_STREAM (buffer, len, snap) != len)
+ return (WRONG_FORMAT);
+ if (strncmp (buffer, ORIG_SNAPSHOT_MAGIC, strlen (ORIG_SNAPSHOT_MAGIC)) != 0)
+ return (WRONG_FORMAT);
+ if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > ORIG_SNAPSHOT_VERSION)
+ return (WRONG_VERSION);
+
+ if ((result = ReadBlock ("NAM:", rom_filename, _MAX_PATH, snap)) != SUCCESS)
+ return (result);
+
+ if ((result = ReadBlock ("HiR:", buffer, 0x41, snap)) != SUCCESS)
+ return (result);
+
+ if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 &&
+ strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0)
+ {
+ S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME,
+ "Current loaded ROM image doesn't match that required by freeze-game file.");
+ }
+
+ S9xReset ();
+ S9xSetSoundMute (TRUE);
+ if ((result = ReadBlock ("CPU:", &OrigCPU, sizeof (OrigCPU), snap)) != SUCCESS)
+ return (result);
+ OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old;
+ Memory.FixROMSpeed ();
+ if (version == 3)
+ {
+ OrigCPU.Cycles = OrigCPU.Cycles_old;
+ OrigCPU.NextEvent = OrigCPU.NextEvent_old;
+ OrigCPU.V_Counter = OrigCPU.V_Counter_old;
+ OrigCPU.MemSpeed = OrigCPU.MemSpeed_old;
+ OrigCPU.MemSpeedx2 = OrigCPU.MemSpeedx2_old;
+ OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old;
+ }
+ CPU.Flags = OrigCPU.Flags;
+ CPU.BranchSkip = OrigCPU.BranchSkip;
+ CPU.NMIActive = OrigCPU.NMIActive;
+ CPU.IRQActive = OrigCPU.IRQActive;
+ CPU.WaitingForInterrupt = OrigCPU.WaitingForInterrupt;
+ CPU.WhichEvent = OrigCPU.WhichEvent;
+ CPU.Cycles = OrigCPU.Cycles;
+ CPU.NextEvent = OrigCPU.NextEvent;
+ CPU.V_Counter = OrigCPU.V_Counter;
+ CPU.MemSpeed = OrigCPU.MemSpeed;
+ CPU.MemSpeedx2 = OrigCPU.MemSpeedx2;
+ CPU.FastROMSpeed = OrigCPU.FastROMSpeed;
+
+ if ((result = ReadBlock ("REG:", &OrigRegisters, sizeof (OrigRegisters), snap)) != SUCCESS)
+ return (result);
+
+ Registers = *(struct SRegisters *) &OrigRegisters;
+
+ if ((result = ReadBlock ("PPU:", &OrigPPU, sizeof (OrigPPU), snap)) != SUCCESS)
+ return (result);
+
+ if (version == 2)
+ {
+ OrigPPU.OBJNameSelect = OrigPPU.OBJNameSelect_old << 13;
+ OrigPPU.OBJNameBase <<= 1;
+ OrigPPU.OBJNameSelect <<= 13;
+ }
+ PPU.BGMode = OrigPPU.BGMode;
+ PPU.BG3Priority = OrigPPU.BG3Priority;
+ PPU.Brightness = OrigPPU.Brightness;
+
+ PPU.VMA.High = OrigPPU.VMA.High;
+ PPU.VMA.Increment = OrigPPU.VMA.Increment;
+ PPU.VMA.Address = OrigPPU.VMA.Address;
+ PPU.VMA.Mask1 = OrigPPU.VMA.Mask1;
+ PPU.VMA.FullGraphicCount = OrigPPU.VMA.FullGraphicCount;
+ PPU.VMA.Shift = OrigPPU.VMA.Shift;
+
+ for (i = 0; i < 4; i++)
+ {
+ PPU.BG[i].SCBase = OrigPPU.BG[i].SCBase;
+ PPU.BG[i].VOffset = OrigPPU.BG[i].VOffset;
+ PPU.BG[i].HOffset = OrigPPU.BG[i].HOffset;
+ PPU.BG[i].BGSize = OrigPPU.BG[i].BGSize;
+ PPU.BG[i].NameBase = OrigPPU.BG[i].NameBase;
+ PPU.BG[i].SCSize = OrigPPU.BG[i].SCSize;
+ }
+
+ PPU.CGFLIP = OrigPPU.CGFLIP;
+ for (i = 0; i < 256; i++)
+ PPU.CGDATA [i] = OrigPPU.CGDATA [i];
+ PPU.FirstSprite = OrigPPU.FirstSprite;
+ for (i = 0; i < 128; i++)
+ {
+ PPU.OBJ[i].HPos = OrigPPU.OBJ [i].HPos;
+ PPU.OBJ[i].VPos = OrigPPU.OBJ [i].VPos;
+ PPU.OBJ[i].Name = OrigPPU.OBJ [i].Name;
+ PPU.OBJ[i].VFlip = OrigPPU.OBJ [i].VFlip;
+ PPU.OBJ[i].HFlip = OrigPPU.OBJ [i].HFlip;
+ PPU.OBJ[i].Priority = OrigPPU.OBJ [i].Priority;
+ PPU.OBJ[i].Palette = OrigPPU.OBJ [i].Palette;
+ PPU.OBJ[i].Size = OrigPPU.OBJ [i].Size;
+ }
+ PPU.OAMPriorityRotation = OrigPPU.OAMPriorityRotation;
+ PPU.OAMAddr = OrigPPU.OAMAddr;
+
+ PPU.OAMFlip = OrigPPU.OAMFlip;
+ PPU.OAMTileAddress = OrigPPU.OAMTileAddress;
+ PPU.IRQVBeamPos = OrigPPU.IRQVBeamPos;
+ PPU.IRQHBeamPos = OrigPPU.IRQHBeamPos;
+ PPU.VBeamPosLatched = OrigPPU.VBeamPosLatched;
+ PPU.HBeamPosLatched = OrigPPU.HBeamPosLatched;
+
+ PPU.HBeamFlip = OrigPPU.HBeamFlip;
+ PPU.VBeamFlip = OrigPPU.VBeamFlip;
+ PPU.HVBeamCounterLatched = OrigPPU.HVBeamCounterLatched;
+
+ PPU.MatrixA = OrigPPU.MatrixA;
+ PPU.MatrixB = OrigPPU.MatrixB;
+ PPU.MatrixC = OrigPPU.MatrixC;
+ PPU.MatrixD = OrigPPU.MatrixD;
+ PPU.CentreX = OrigPPU.CentreX;
+ PPU.CentreY = OrigPPU.CentreY;
+ PPU.Joypad1ButtonReadPos = OrigPPU.Joypad1ButtonReadPos;
+ PPU.Joypad2ButtonReadPos = OrigPPU.Joypad2ButtonReadPos;
+ PPU.Joypad3ButtonReadPos = OrigPPU.Joypad3ButtonReadPos;
+
+ PPU.CGADD = OrigPPU.CGADD;
+ PPU.FixedColourRed = OrigPPU.FixedColourRed;
+ PPU.FixedColourGreen = OrigPPU.FixedColourGreen;
+ PPU.FixedColourBlue = OrigPPU.FixedColourBlue;
+ PPU.SavedOAMAddr = OrigPPU.SavedOAMAddr;
+ PPU.ScreenHeight = OrigPPU.ScreenHeight;
+ PPU.WRAM = OrigPPU.WRAM;
+ PPU.ForcedBlanking = OrigPPU.ForcedBlanking;
+ PPU.OBJNameSelect = OrigPPU.OBJNameSelect;
+ PPU.OBJSizeSelect = OrigPPU.OBJSizeSelect;
+ PPU.OBJNameBase = OrigPPU.OBJNameBase;
+ PPU.OAMReadFlip = OrigPPU.OAMReadFlip;
+ memmove (PPU.OAMData, OrigPPU.OAMData, sizeof (PPU.OAMData));
+ PPU.VTimerEnabled = OrigPPU.VTimerEnabled;
+ PPU.HTimerEnabled = OrigPPU.HTimerEnabled;
+ PPU.HTimerPosition = OrigPPU.HTimerPosition;
+ PPU.Mosaic = OrigPPU.Mosaic;
+ memmove (PPU.BGMosaic, OrigPPU.BGMosaic, sizeof (PPU.BGMosaic));
+ PPU.Mode7HFlip = OrigPPU.Mode7HFlip;
+ PPU.Mode7VFlip = OrigPPU.Mode7VFlip;
+ PPU.Mode7Repeat = OrigPPU.Mode7Repeat;
+ PPU.Window1Left = OrigPPU.Window1Left;
+ PPU.Window1Right = OrigPPU.Window1Right;
+ PPU.Window2Left = OrigPPU.Window2Left;
+ PPU.Window2Right = OrigPPU.Window2Right;
+ for (i = 0; i < 6; i++)
+ {
+ PPU.ClipWindowOverlapLogic [i] = OrigPPU.ClipWindowOverlapLogic [i];
+ PPU.ClipWindow1Enable [i] = OrigPPU.ClipWindow1Enable [i];
+ PPU.ClipWindow2Enable [i] = OrigPPU.ClipWindow2Enable [i];
+ PPU.ClipWindow1Inside [i] = OrigPPU.ClipWindow1Inside [i];
+ PPU.ClipWindow2Inside [i] = OrigPPU.ClipWindow2Inside [i];
+ }
+ PPU.CGFLIPRead = OrigPPU.CGFLIPRead;
+ PPU.Need16x8Mulitply = OrigPPU.Need16x8Mulitply;
+
+ IPPU.ColorsChanged = TRUE;
+ IPPU.OBJChanged = TRUE;
+ S9xFixColourBrightness ();
+ IPPU.RenderThisFrame = FALSE;
+
+ if ((result = ReadBlock ("DMA:", OrigDMA, sizeof (OrigDMA), snap)) != SUCCESS)
+ return (result);
+
+ for (i = 0; i < 8; i++)
+ {
+ DMA[i].TransferDirection = OrigDMA[i].TransferDirection;
+ DMA[i].AAddressFixed = OrigDMA[i].AAddressFixed;
+ DMA[i].AAddressDecrement = OrigDMA[i].AAddressDecrement;
+ DMA[i].TransferMode = OrigDMA[i].TransferMode;
+ DMA[i].ABank = OrigDMA[i].ABank;
+ DMA[i].AAddress = OrigDMA[i].AAddress;
+ DMA[i].Address = OrigDMA[i].Address;
+ DMA[i].BAddress = OrigDMA[i].BAddress;
+ DMA[i].TransferBytes = OrigDMA[i].TransferBytes;
+ DMA[i].HDMAIndirectAddressing = OrigDMA[i].HDMAIndirectAddressing;
+ DMA[i].IndirectAddress = OrigDMA[i].IndirectAddress;
+ DMA[i].IndirectBank = OrigDMA[i].IndirectBank;
+ DMA[i].Repeat = OrigDMA[i].Repeat;
+ DMA[i].LineCount = OrigDMA[i].LineCount;
+ DMA[i].FirstLine = OrigDMA[i].FirstLine;
+ }
+
+ if ((result = ReadBlock ("VRA:", Memory.VRAM, 0x10000, snap)) != SUCCESS)
+ return (result);
+ if ((result = ReadBlock ("RAM:", Memory.RAM, 0x20000, snap)) != SUCCESS)
+ return (result);
+ if ((result = ReadBlock ("SRA:", ::SRAM, 0x10000, snap)) != SUCCESS)
+ return (result);
+ if ((result = ReadBlock ("FIL:", Memory.FillRAM, 0x8000, snap)) != SUCCESS)
+ return (result);
+ if (ReadBlock ("APU:", &OrigAPU, sizeof (OrigAPU), snap) == SUCCESS)
+ {
+ APU = *(struct SAPU *) &OrigAPU;
+
+ if ((result = ReadBlock ("ARE:", &OrigAPURegisters,
+ sizeof (OrigAPURegisters), snap)) != SUCCESS)
+ return (result);
+ APURegisters = *(struct SAPURegisters *) &OrigAPURegisters;
+ if ((result = ReadBlock ("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS)
+ return (result);
+ if ((result = ReadBlock ("SOU:", &OrigSoundData,
+ sizeof (SOrigSoundData), snap)) != SUCCESS)
+ return (result);
+
+ SoundData.master_volume_left = OrigSoundData.master_volume_left;
+ SoundData.master_volume_right = OrigSoundData.master_volume_right;
+ SoundData.echo_volume_left = OrigSoundData.echo_volume_left;
+ SoundData.echo_volume_right = OrigSoundData.echo_volume_right;
+ SoundData.echo_enable = OrigSoundData.echo_enable;
+ SoundData.echo_feedback = OrigSoundData.echo_feedback;
+ SoundData.echo_ptr = OrigSoundData.echo_ptr;
+ SoundData.echo_buffer_size = OrigSoundData.echo_buffer_size;
+ SoundData.echo_write_enabled = OrigSoundData.echo_write_enabled;
+ SoundData.echo_channel_enable = OrigSoundData.echo_channel_enable;
+ SoundData.pitch_mod = OrigSoundData.pitch_mod;
+
+ for (i = 0; i < 3; i++)
+ SoundData.dummy [i] = OrigSoundData.dummy [i];
+ for (i = 0; i < NUM_CHANNELS; i++)
+ {
+ SoundData.channels [i].state = OrigSoundData.channels [i].state;
+ SoundData.channels [i].type = OrigSoundData.channels [i].type;
+ SoundData.channels [i].volume_left = OrigSoundData.channels [i].volume_left;
+ SoundData.channels [i].volume_right = OrigSoundData.channels [i].volume_right;
+ SoundData.channels [i].hertz = OrigSoundData.channels [i].frequency;
+ SoundData.channels [i].count = OrigSoundData.channels [i].count;
+ SoundData.channels [i].loop = OrigSoundData.channels [i].loop;
+ SoundData.channels [i].envx = OrigSoundData.channels [i].envx;
+ SoundData.channels [i].left_vol_level = OrigSoundData.channels [i].left_vol_level;
+ SoundData.channels [i].right_vol_level = OrigSoundData.channels [i].right_vol_level;
+ SoundData.channels [i].envx_target = OrigSoundData.channels [i].envx_target;
+ SoundData.channels [i].env_error = OrigSoundData.channels [i].env_error;
+ SoundData.channels [i].erate = OrigSoundData.channels [i].erate;
+ SoundData.channels [i].direction = OrigSoundData.channels [i].direction;
+ SoundData.channels [i].attack_rate = OrigSoundData.channels [i].attack_rate;
+ SoundData.channels [i].decay_rate = OrigSoundData.channels [i].decay_rate;
+ SoundData.channels [i].sustain_rate = OrigSoundData.channels [i].sustain_rate;
+ SoundData.channels [i].release_rate = OrigSoundData.channels [i].release_rate;
+ SoundData.channels [i].sustain_level = OrigSoundData.channels [i].sustain_level;
+ SoundData.channels [i].sample = OrigSoundData.channels [i].sample;
+ for (j = 0; j < 16; j++)
+ SoundData.channels [i].decoded [j] = OrigSoundData.channels [i].decoded [j];
+
+ for (j = 0; j < 2; j++)
+ SoundData.channels [i].previous [j] = OrigSoundData.channels [i].previous [j];
+
+ SoundData.channels [i].sample_number = OrigSoundData.channels [i].sample_number;
+ SoundData.channels [i].last_block = OrigSoundData.channels [i].last_block;
+ SoundData.channels [i].needs_decode = OrigSoundData.channels [i].needs_decode;
+ SoundData.channels [i].block_pointer = OrigSoundData.channels [i].block_pointer;
+ SoundData.channels [i].sample_pointer = OrigSoundData.channels [i].sample_pointer;
+ SoundData.channels [i].mode = OrigSoundData.channels [i].mode;
+ }
+
+ S9xSetSoundMute (FALSE);
+ IAPU.PC = IAPU.RAM + APURegisters.PC;
+ S9xAPUUnpackStatus ();
+ if (APUCheckDirectPage ())
+ IAPU.DirectPage = IAPU.RAM + 0x100;
+ else
+ IAPU.DirectPage = IAPU.RAM;
+ Settings.APUEnabled = TRUE;
+ IAPU.APUExecuting = TRUE;
+ }
+ else
+ {
+ Settings.APUEnabled = FALSE;
+ IAPU.APUExecuting = FALSE;
+ S9xSetSoundMute (TRUE);
+ }
+ S9xFixSoundAfterSnapshotLoad ();
+ ICPU.ShiftedPB = Registers.PB << 16;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ S9xSetPCBase (ICPU.ShiftedPB + Registers.PC);
+ S9xUnpackStatus ();
+ S9xFixCycles ();
+ S9xReschedule ();
+
+ return (SUCCESS);
+}
+
diff --git a/source/snaporig.h b/source/snaporig.h
new file mode 100644
index 0000000..a796c08
--- /dev/null
+++ b/source/snaporig.h
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _SNAPORIG_H_
+#define _SNAPORIG_H_
+
+#define ORIG_SNAPSHOT_MAGIC "#!snes96"
+#define ORIG_SNAPSHOT_VERSION 4
+
+EXTERN_C bool8 S9xLoadOrigSnapshot (const char *filename);
+
+struct SOrigCPUState{
+ uint32 Flags;
+ short Cycles_old;
+ short NextEvent_old;
+ uint8 CurrentFrame;
+ uint8 FastROMSpeed_old_old;
+ uint16 V_Counter_old;
+ bool8 BranchSkip;
+ bool8 NMIActive;
+ bool8 IRQActive;
+ bool8 WaitingForInterrupt;
+ bool8 InDMA;
+ uint8 WhichEvent;
+ uint8 *PC;
+ uint8 *PCBase;
+ uint16 MemSpeed_old;
+ uint16 MemSpeedx2_old;
+ uint16 FastROMSpeed_old;
+ bool8 FastDP;
+ uint8 *PCAtOpcodeStart;
+ uint8 *WaitAddress;
+ uint32 WaitCounter;
+ long Cycles;
+ long NextEvent;
+ long V_Counter;
+ long MemSpeed;
+ long MemSpeedx2;
+ long FastROMSpeed;
+};
+
+struct SOrigAPU
+{
+ uint32 Cycles;
+ bool8 ShowROM;
+ uint8 Flags;
+ uint8 KeyedChannels;
+ uint8 OutPorts [4];
+ uint8 DSP [0x80];
+ uint8 ExtraRAM [64];
+ uint16 Timer [3];
+ uint16 TimerTarget [3];
+ bool8 TimerEnabled [3];
+ bool8 TimerValueWritten [3];
+};
+
+typedef union
+{
+#ifdef LSB_FIRST
+ struct { uint8 A, Y; } B;
+#else
+ struct { uint8 Y, A; } B;
+#endif
+ uint16 W;
+} OrigYAndA;
+
+struct SOrigAPURegisters{
+ uint8 P;
+ OrigYAndA YA;
+ uint8 X;
+ uint8 S;
+ uint16 PC;
+};
+
+#define ORIG_MAX_BUFFER_SIZE (1024 * 4)
+#define NUM_CHANNELS 8
+
+typedef struct {
+ int state;
+ int type;
+ short volume_left;
+ short volume_right;
+ int frequency;
+ int count;
+ signed short wave [ORIG_MAX_BUFFER_SIZE];
+ bool8 loop;
+ int envx;
+ short left_vol_level;
+ short right_vol_level;
+ short envx_target;
+ unsigned long int env_error;
+ unsigned long erate;
+ int direction;
+ unsigned long attack_rate;
+ unsigned long decay_rate;
+ unsigned long sustain_rate;
+ unsigned long release_rate;
+ unsigned long sustain_level;
+ signed short sample;
+ signed short decoded [16];
+ signed short previous [2];
+ uint16 sample_number;
+ bool8 last_block;
+ bool8 needs_decode;
+ uint32 block_pointer;
+ uint32 sample_pointer;
+ int *echo_buf_ptr;
+ int mode;
+ uint32 dummy [8];
+} OrigChannel;
+
+typedef struct
+{
+ short master_volume_left;
+ short master_volume_right;
+ short echo_volume_left;
+ short echo_volume_right;
+ int echo_enable;
+ int echo_feedback;
+ int echo_ptr;
+ int echo_buffer_size;
+ int echo_write_enabled;
+ int echo_channel_enable;
+ int pitch_mod;
+ // Just incase they are needed in the future, for snapshot compatibility.
+ uint32 dummy [3];
+ OrigChannel channels [NUM_CHANNELS];
+} SOrigSoundData;
+
+struct SOrigOBJ
+{
+ short HPos;
+ uint16 VPos;
+ uint16 Name;
+ uint8 VFlip;
+ uint8 HFlip;
+ uint8 Priority;
+ uint8 Palette;
+ uint8 Size;
+ uint8 Prev;
+ uint8 Next;
+};
+
+struct SOrigPPU {
+ uint8 BGMode;
+ uint8 BG3Priority;
+ uint8 Brightness;
+
+ struct {
+ bool8 High;
+ uint8 Increment;
+ uint16 Address;
+ uint16 Mask1;
+ uint16 FullGraphicCount;
+ uint16 Shift;
+ } VMA;
+
+ struct {
+ uint8 TileSize;
+ uint16 TileAddress;
+ uint8 Width;
+ uint8 Height;
+ uint16 SCBase;
+ uint16 VOffset;
+ uint16 HOffset;
+ bool8 ThroughMain;
+ bool8 ThroughSub;
+ uint8 BGSize;
+ uint16 NameBase;
+ uint16 SCSize;
+ bool8 Addition;
+ } BG [4];
+
+ bool8 CGFLIP;
+ uint16 CGDATA [256];
+ uint8 FirstSprite;
+ uint8 LastSprite;
+ struct SOrigOBJ OBJ [129];
+ uint8 OAMPriorityRotation;
+ uint16 OAMAddr;
+
+ uint8 OAMFlip;
+ uint16 OAMTileAddress;
+ uint16 IRQVBeamPos;
+ uint16 IRQHBeamPos;
+ uint16 VBeamPosLatched;
+ uint16 HBeamPosLatched;
+
+ uint8 HBeamFlip;
+ uint8 VBeamFlip;
+ uint8 HVBeamCounterLatched;
+
+ short MatrixA;
+ short MatrixB;
+ short MatrixC;
+ short MatrixD;
+ short CentreX;
+ short CentreY;
+ uint8 Joypad1ButtonReadPos;
+ uint8 Joypad2ButtonReadPos;
+
+ uint8 CGADD;
+ uint8 FixedColourRed;
+ uint8 FixedColourGreen;
+ uint8 FixedColourBlue;
+ uint16 SavedOAMAddr;
+ uint16 ScreenHeight;
+ uint32 WRAM;
+ uint8 BG_Forced;
+ bool8 ForcedBlanking;
+ bool8 OBJThroughMain;
+ bool8 OBJThroughSub;
+ uint8 OBJSizeSelect;
+ uint8 OBJNameSelect_old;
+ uint16 OBJNameBase;
+ bool8 OBJAddition;
+ uint8 OAMReadFlip;
+ uint8 OAMData [512 + 32];
+ bool8 VTimerEnabled;
+ bool8 HTimerEnabled;
+ short HTimerPosition;
+ uint8 Mosaic;
+ bool8 BGMosaic [4];
+ bool8 Mode7HFlip;
+ bool8 Mode7VFlip;
+ uint8 Mode7Repeat;
+ uint8 Window1Left;
+ uint8 Window1Right;
+ uint8 Window2Left;
+ uint8 Window2Right;
+ uint8 ClipCounts [6];
+ uint8 ClipLeftEdges [3][6];
+ uint8 ClipRightEdges [3][6];
+ uint8 ClipWindowOverlapLogic [6];
+ uint8 ClipWindow1Enable [6];
+ uint8 ClipWindow2Enable [6];
+ bool8 ClipWindow1Inside [6];
+ bool8 ClipWindow2Inside [6];
+ bool8 RecomputeClipWindows;
+ uint8 CGFLIPRead;
+ uint16 OBJNameSelect;
+ bool8 Need16x8Mulitply;
+ uint8 Joypad3ButtonReadPos;
+ uint8 MouseSpeed[2];
+};
+
+struct SOrigDMA {
+ bool8 TransferDirection;
+ bool8 AAddressFixed;
+ bool8 AAddressDecrement;
+ uint8 TransferMode;
+
+ uint8 ABank;
+ uint16 AAddress;
+ uint16 Address;
+ uint8 BAddress;
+
+ // General DMA only:
+ uint16 TransferBytes;
+
+ // H-DMA only:
+ bool8 HDMAIndirectAddressing;
+ uint16 IndirectAddress;
+ uint8 IndirectBank;
+ uint8 Repeat;
+ uint8 LineCount;
+ uint8 FirstLine;
+ bool8 JustStarted;
+};
+
+typedef union
+{
+#ifdef LSB_FIRST
+ struct { uint8 l,h; } B;
+#else
+ struct { uint8 h,l; } B;
+#endif
+ uint16 W;
+} OrigPair;
+
+struct SOrigRegisters{
+ uint8 PB;
+ uint8 DB;
+ OrigPair P;
+ OrigPair A;
+ OrigPair D;
+ OrigPair S;
+ OrigPair X;
+ OrigPair Y;
+ uint16 PC;
+};
+
+#endif
+
diff --git a/source/snapshot.cpp b/source/snapshot.cpp
new file mode 100644
index 0000000..fda8d62
--- /dev/null
+++ b/source/snapshot.cpp
@@ -0,0 +1,1824 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+
+#if defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#include "snapshot.h"
+#include "snaporig.h"
+#include "memmap.h"
+#include "snes9x.h"
+#include "65c816.h"
+#include "ppu.h"
+#include "cpuexec.h"
+#include "display.h"
+#include "apu.h"
+#include "soundux.h"
+#include "sa1.h"
+#include "srtc.h"
+#include "sdd1.h"
+#include "spc7110.h"
+#include "movie.h"
+
+extern uint8 *SRAM;
+
+#ifdef ZSNES_FX
+START_EXTERN_C
+void S9xSuperFXPreSaveState ();
+void S9xSuperFXPostSaveState ();
+void S9xSuperFXPostLoadState ();
+END_EXTERN_C
+#endif
+
+bool8 S9xUnfreezeZSNES (const char *filename);
+
+typedef struct {
+ int offset;
+ int size;
+ int type;
+} FreezeData;
+
+enum {
+ INT_V, uint8_ARRAY_V, uint16_ARRAY_V, uint32_ARRAY_V
+};
+
+#define Offset(field,structure) \
+((int) (((char *) (&(((structure)NULL)->field))) - ((char *) NULL)))
+
+#define COUNT(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0]))
+
+struct SnapshotMovieInfo
+{
+ uint32 MovieInputDataSize;
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SnapshotMovieInfo *)
+
+static FreezeData SnapMovie [] = {
+ {OFFSET (MovieInputDataSize), 4, INT_V},
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SCPUState *)
+
+static FreezeData SnapCPU [] = {
+ {OFFSET (Flags), 4, INT_V},
+ {OFFSET (BranchSkip), 1, INT_V},
+ {OFFSET (NMIActive), 1, INT_V},
+ {OFFSET (IRQActive), 1, INT_V},
+ {OFFSET (WaitingForInterrupt), 1, INT_V},
+ {OFFSET (WhichEvent), 1, INT_V},
+ {OFFSET (Cycles), 4, INT_V},
+ {OFFSET (NextEvent), 4, INT_V},
+ {OFFSET (V_Counter), 4, INT_V},
+ {OFFSET (MemSpeed), 4, INT_V},
+ {OFFSET (MemSpeedx2), 4, INT_V},
+ {OFFSET (FastROMSpeed), 4, INT_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SRegisters *)
+
+static FreezeData SnapRegisters [] = {
+ {OFFSET (PB), 1, INT_V},
+ {OFFSET (DB), 1, INT_V},
+ {OFFSET (P.W), 2, INT_V},
+ {OFFSET (A.W), 2, INT_V},
+ {OFFSET (D.W), 2, INT_V},
+ {OFFSET (S.W), 2, INT_V},
+ {OFFSET (X.W), 2, INT_V},
+ {OFFSET (Y.W), 2, INT_V},
+ {OFFSET (PC), 2, INT_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SPPU *)
+
+static FreezeData SnapPPU [] = {
+ {OFFSET (BGMode), 1, INT_V},
+ {OFFSET (BG3Priority), 1, INT_V},
+ {OFFSET (Brightness), 1, INT_V},
+ {OFFSET (VMA.High), 1, INT_V},
+ {OFFSET (VMA.Increment), 1, INT_V},
+ {OFFSET (VMA.Address), 2, INT_V},
+ {OFFSET (VMA.Mask1), 2, INT_V},
+ {OFFSET (VMA.FullGraphicCount), 2, INT_V},
+ {OFFSET (VMA.Shift), 2, INT_V},
+ {OFFSET (BG[0].SCBase), 2, INT_V},
+ {OFFSET (BG[0].VOffset), 2, INT_V},
+ {OFFSET (BG[0].HOffset), 2, INT_V},
+ {OFFSET (BG[0].BGSize), 1, INT_V},
+ {OFFSET (BG[0].NameBase), 2, INT_V},
+ {OFFSET (BG[0].SCSize), 2, INT_V},
+
+ {OFFSET (BG[1].SCBase), 2, INT_V},
+ {OFFSET (BG[1].VOffset), 2, INT_V},
+ {OFFSET (BG[1].HOffset), 2, INT_V},
+ {OFFSET (BG[1].BGSize), 1, INT_V},
+ {OFFSET (BG[1].NameBase), 2, INT_V},
+ {OFFSET (BG[1].SCSize), 2, INT_V},
+
+ {OFFSET (BG[2].SCBase), 2, INT_V},
+ {OFFSET (BG[2].VOffset), 2, INT_V},
+ {OFFSET (BG[2].HOffset), 2, INT_V},
+ {OFFSET (BG[2].BGSize), 1, INT_V},
+ {OFFSET (BG[2].NameBase), 2, INT_V},
+ {OFFSET (BG[2].SCSize), 2, INT_V},
+
+ {OFFSET (BG[3].SCBase), 2, INT_V},
+ {OFFSET (BG[3].VOffset), 2, INT_V},
+ {OFFSET (BG[3].HOffset), 2, INT_V},
+ {OFFSET (BG[3].BGSize), 1, INT_V},
+ {OFFSET (BG[3].NameBase), 2, INT_V},
+ {OFFSET (BG[3].SCSize), 2, INT_V},
+
+ {OFFSET (CGFLIP), 1, INT_V},
+ {OFFSET (CGDATA), 256, uint16_ARRAY_V},
+ {OFFSET (FirstSprite), 1, INT_V},
+#define O(N) \
+ {OFFSET (OBJ[N].HPos), 2, INT_V}, \
+ {OFFSET (OBJ[N].VPos), 2, INT_V}, \
+ {OFFSET (OBJ[N].Name), 2, INT_V}, \
+ {OFFSET (OBJ[N].VFlip), 1, INT_V}, \
+ {OFFSET (OBJ[N].HFlip), 1, INT_V}, \
+ {OFFSET (OBJ[N].Priority), 1, INT_V}, \
+ {OFFSET (OBJ[N].Palette), 1, INT_V}, \
+ {OFFSET (OBJ[N].Size), 1, INT_V}
+
+ O( 0), O( 1), O( 2), O( 3), O( 4), O( 5), O( 6), O( 7),
+ O( 8), O( 9), O( 10), O( 11), O( 12), O( 13), O( 14), O( 15),
+ O( 16), O( 17), O( 18), O( 19), O( 20), O( 21), O( 22), O( 23),
+ O( 24), O( 25), O( 26), O( 27), O( 28), O( 29), O( 30), O( 31),
+ O( 32), O( 33), O( 34), O( 35), O( 36), O( 37), O( 38), O( 39),
+ O( 40), O( 41), O( 42), O( 43), O( 44), O( 45), O( 46), O( 47),
+ O( 48), O( 49), O( 50), O( 51), O( 52), O( 53), O( 54), O( 55),
+ O( 56), O( 57), O( 58), O( 59), O( 60), O( 61), O( 62), O( 63),
+ O( 64), O( 65), O( 66), O( 67), O( 68), O( 69), O( 70), O( 71),
+ O( 72), O( 73), O( 74), O( 75), O( 76), O( 77), O( 78), O( 79),
+ O( 80), O( 81), O( 82), O( 83), O( 84), O( 85), O( 86), O( 87),
+ O( 88), O( 89), O( 90), O( 91), O( 92), O( 93), O( 94), O( 95),
+ O( 96), O( 97), O( 98), O( 99), O(100), O(101), O(102), O(103),
+ O(104), O(105), O(106), O(107), O(108), O(109), O(110), O(111),
+ O(112), O(113), O(114), O(115), O(116), O(117), O(118), O(119),
+ O(120), O(121), O(122), O(123), O(124), O(125), O(126), O(127),
+#undef O
+ {OFFSET (OAMPriorityRotation), 1, INT_V},
+ {OFFSET (OAMAddr), 2, INT_V},
+ {OFFSET (OAMFlip), 1, INT_V},
+ {OFFSET (OAMTileAddress), 2, INT_V},
+ {OFFSET (IRQVBeamPos), 2, INT_V},
+ {OFFSET (IRQHBeamPos), 2, INT_V},
+ {OFFSET (VBeamPosLatched), 2, INT_V},
+ {OFFSET (HBeamPosLatched), 2, INT_V},
+ {OFFSET (HBeamFlip), 1, INT_V},
+ {OFFSET (VBeamFlip), 1, INT_V},
+ {OFFSET (HVBeamCounterLatched), 1, INT_V},
+ {OFFSET (MatrixA), 2, INT_V},
+ {OFFSET (MatrixB), 2, INT_V},
+ {OFFSET (MatrixC), 2, INT_V},
+ {OFFSET (MatrixD), 2, INT_V},
+ {OFFSET (CentreX), 2, INT_V},
+ {OFFSET (CentreY), 2, INT_V},
+ {OFFSET (Joypad1ButtonReadPos), 1, INT_V},
+ {OFFSET (Joypad2ButtonReadPos), 1, INT_V},
+ {OFFSET (Joypad3ButtonReadPos), 1, INT_V},
+ {OFFSET (CGADD), 1, INT_V},
+ {OFFSET (FixedColourRed), 1, INT_V},
+ {OFFSET (FixedColourGreen), 1, INT_V},
+ {OFFSET (FixedColourBlue), 1, INT_V},
+ {OFFSET (SavedOAMAddr), 2, INT_V},
+ {OFFSET (ScreenHeight), 2, INT_V},
+ {OFFSET (WRAM), 4, INT_V},
+ {OFFSET (ForcedBlanking), 1, INT_V},
+ {OFFSET (OBJNameSelect), 2, INT_V},
+ {OFFSET (OBJSizeSelect), 1, INT_V},
+ {OFFSET (OBJNameBase), 2, INT_V},
+ {OFFSET (OAMReadFlip), 1, INT_V},
+ {OFFSET (VTimerEnabled), 1, INT_V},
+ {OFFSET (HTimerEnabled), 1, INT_V},
+ {OFFSET (HTimerPosition), 2, INT_V},
+ {OFFSET (Mosaic), 1, INT_V},
+ {OFFSET (Mode7HFlip), 1, INT_V},
+ {OFFSET (Mode7VFlip), 1, INT_V},
+ {OFFSET (Mode7Repeat), 1, INT_V},
+ {OFFSET (Window1Left), 1, INT_V},
+ {OFFSET (Window1Right), 1, INT_V},
+ {OFFSET (Window2Left), 1, INT_V},
+ {OFFSET (Window2Right), 1, INT_V},
+#define O(N) \
+ {OFFSET (ClipWindowOverlapLogic[N]), 1, INT_V}, \
+ {OFFSET (ClipWindow1Enable[N]), 1, INT_V}, \
+ {OFFSET (ClipWindow2Enable[N]), 1, INT_V}, \
+ {OFFSET (ClipWindow1Inside[N]), 1, INT_V}, \
+ {OFFSET (ClipWindow2Inside[N]), 1, INT_V}
+
+ O(0), O(1), O(2), O(3), O(4), O(5),
+
+#undef O
+
+ {OFFSET (CGFLIPRead), 1, INT_V},
+ {OFFSET (Need16x8Mulitply), 1, INT_V},
+ {OFFSET (BGMosaic), 4, uint8_ARRAY_V},
+ {OFFSET (OAMData), 512 + 32, uint8_ARRAY_V},
+ {OFFSET (Need16x8Mulitply), 1, INT_V},
+ {OFFSET (MouseSpeed), 2, uint8_ARRAY_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SDMA *)
+
+static FreezeData SnapDMA [] = {
+#define O(N) \
+ {OFFSET (TransferDirection) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (AAddressFixed) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (AAddressDecrement) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (TransferMode) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (ABank) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (AAddress) + N * sizeof (struct SDMA), 2, INT_V}, \
+ {OFFSET (Address) + N * sizeof (struct SDMA), 2, INT_V}, \
+ {OFFSET (BAddress) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (TransferBytes) + N * sizeof (struct SDMA), 2, INT_V}, \
+ {OFFSET (HDMAIndirectAddressing) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (IndirectAddress) + N * sizeof (struct SDMA), 2, INT_V}, \
+ {OFFSET (IndirectBank) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (Repeat) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (LineCount) + N * sizeof (struct SDMA), 1, INT_V}, \
+ {OFFSET (FirstLine) + N * sizeof (struct SDMA), 1, INT_V}
+
+ O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7)
+#undef O
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SAPU *)
+
+static FreezeData SnapAPU [] = {
+ {OFFSET (Cycles), 4, INT_V},
+ {OFFSET (ShowROM), 1, INT_V},
+ {OFFSET (Flags), 1, INT_V},
+ {OFFSET (KeyedChannels), 1, INT_V},
+ {OFFSET (OutPorts), 4, uint8_ARRAY_V},
+ {OFFSET (DSP), 0x80, uint8_ARRAY_V},
+ {OFFSET (ExtraRAM), 64, uint8_ARRAY_V},
+ {OFFSET (Timer), 3, uint16_ARRAY_V},
+ {OFFSET (TimerTarget), 3, uint16_ARRAY_V},
+ {OFFSET (TimerEnabled), 3, uint8_ARRAY_V},
+ {OFFSET (TimerValueWritten), 3, uint8_ARRAY_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SAPURegisters *)
+
+static FreezeData SnapAPURegisters [] = {
+ {OFFSET (P), 1, INT_V},
+ {OFFSET (YA.W), 2, INT_V},
+ {OFFSET (X), 1, INT_V},
+ {OFFSET (S), 1, INT_V},
+ {OFFSET (PC), 2, INT_V},
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,SSoundData *)
+
+static FreezeData SnapSoundData [] = {
+ {OFFSET (master_volume_left), 2, INT_V},
+ {OFFSET (master_volume_right), 2, INT_V},
+ {OFFSET (echo_volume_left), 2, INT_V},
+ {OFFSET (echo_volume_right), 2, INT_V},
+ {OFFSET (echo_enable), 4, INT_V},
+ {OFFSET (echo_feedback), 4, INT_V},
+ {OFFSET (echo_ptr), 4, INT_V},
+ {OFFSET (echo_buffer_size), 4, INT_V},
+ {OFFSET (echo_write_enabled), 4, INT_V},
+ {OFFSET (echo_channel_enable), 4, INT_V},
+ {OFFSET (pitch_mod), 4, INT_V},
+ {OFFSET (dummy), 3, uint32_ARRAY_V},
+#define O(N) \
+ {OFFSET (channels [N].state), 4, INT_V}, \
+ {OFFSET (channels [N].type), 4, INT_V}, \
+ {OFFSET (channels [N].volume_left), 2, INT_V}, \
+ {OFFSET (channels [N].volume_right), 2, INT_V}, \
+ {OFFSET (channels [N].hertz), 4, INT_V}, \
+ {OFFSET (channels [N].count), 4, INT_V}, \
+ {OFFSET (channels [N].loop), 1, INT_V}, \
+ {OFFSET (channels [N].envx), 4, INT_V}, \
+ {OFFSET (channels [N].left_vol_level), 2, INT_V}, \
+ {OFFSET (channels [N].right_vol_level), 2, INT_V}, \
+ {OFFSET (channels [N].envx_target), 2, INT_V}, \
+ {OFFSET (channels [N].env_error), 4, INT_V}, \
+ {OFFSET (channels [N].erate), 4, INT_V}, \
+ {OFFSET (channels [N].direction), 4, INT_V}, \
+ {OFFSET (channels [N].attack_rate), 4, INT_V}, \
+ {OFFSET (channels [N].decay_rate), 4, INT_V}, \
+ {OFFSET (channels [N].sustain_rate), 4, INT_V}, \
+ {OFFSET (channels [N].release_rate), 4, INT_V}, \
+ {OFFSET (channels [N].sustain_level), 4, INT_V}, \
+ {OFFSET (channels [N].sample), 2, INT_V}, \
+ {OFFSET (channels [N].decoded), 16, uint16_ARRAY_V}, \
+ {OFFSET (channels [N].previous16), 2, uint16_ARRAY_V}, \
+ {OFFSET (channels [N].sample_number), 2, INT_V}, \
+ {OFFSET (channels [N].last_block), 1, INT_V}, \
+ {OFFSET (channels [N].needs_decode), 1, INT_V}, \
+ {OFFSET (channels [N].block_pointer), 4, INT_V}, \
+ {OFFSET (channels [N].sample_pointer), 4, INT_V}, \
+ {OFFSET (channels [N].mode), 4, INT_V}
+
+ O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7)
+#undef O
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SSA1Registers *)
+
+static FreezeData SnapSA1Registers [] = {
+ {OFFSET (PB), 1, INT_V},
+ {OFFSET (DB), 1, INT_V},
+ {OFFSET (P.W), 2, INT_V},
+ {OFFSET (A.W), 2, INT_V},
+ {OFFSET (D.W), 2, INT_V},
+ {OFFSET (S.W), 2, INT_V},
+ {OFFSET (X.W), 2, INT_V},
+ {OFFSET (Y.W), 2, INT_V},
+ {OFFSET (PC), 2, INT_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SSA1 *)
+
+static FreezeData SnapSA1 [] = {
+ {OFFSET (Flags), 4, INT_V},
+ {OFFSET (NMIActive), 1, INT_V},
+ {OFFSET (IRQActive), 1, INT_V},
+ {OFFSET (WaitingForInterrupt), 1, INT_V},
+ {OFFSET (op1), 2, INT_V},
+ {OFFSET (op2), 2, INT_V},
+ {OFFSET (arithmetic_op), 4, INT_V},
+ {OFFSET (sum), 8, INT_V},
+ {OFFSET (overflow), 1, INT_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SPC7110EmuVars *)
+
+static FreezeData SnapSPC7110 [] = {
+ {OFFSET (reg4800), 1, INT_V},
+ {OFFSET (reg4801), 1, INT_V},
+ {OFFSET (reg4802), 1, INT_V},
+ {OFFSET (reg4803), 1, INT_V},
+ {OFFSET (reg4804), 1, INT_V},
+ {OFFSET (reg4805), 1, INT_V},
+ {OFFSET (reg4806), 1, INT_V},
+ {OFFSET (reg4807), 1, INT_V},
+ {OFFSET (reg4808), 1, INT_V},
+ {OFFSET (reg4809), 1, INT_V},
+ {OFFSET (reg480A), 1, INT_V},
+ {OFFSET (reg480B), 1, INT_V},
+ {OFFSET (reg480C), 1, INT_V},
+ {OFFSET (reg4811), 1, INT_V},
+ {OFFSET (reg4812), 1, INT_V},
+ {OFFSET (reg4813), 1, INT_V},
+ {OFFSET (reg4814), 1, INT_V},
+ {OFFSET (reg4815), 1, INT_V},
+ {OFFSET (reg4816), 1, INT_V},
+ {OFFSET (reg4817), 1, INT_V},
+ {OFFSET (reg4818), 1, INT_V},
+ {OFFSET (reg4820), 1, INT_V},
+ {OFFSET (reg4821), 1, INT_V},
+ {OFFSET (reg4822), 1, INT_V},
+ {OFFSET (reg4823), 1, INT_V},
+ {OFFSET (reg4824), 1, INT_V},
+ {OFFSET (reg4825), 1, INT_V},
+ {OFFSET (reg4826), 1, INT_V},
+ {OFFSET (reg4827), 1, INT_V},
+ {OFFSET (reg4828), 1, INT_V},
+ {OFFSET (reg4829), 1, INT_V},
+ {OFFSET (reg482A), 1, INT_V},
+ {OFFSET (reg482B), 1, INT_V},
+ {OFFSET (reg482C), 1, INT_V},
+ {OFFSET (reg482D), 1, INT_V},
+ {OFFSET (reg482E), 1, INT_V},
+ {OFFSET (reg482F), 1, INT_V},
+ {OFFSET (reg4830), 1, INT_V},
+ {OFFSET (reg4831), 1, INT_V},
+ {OFFSET (reg4832), 1, INT_V},
+ {OFFSET (reg4833), 1, INT_V},
+ {OFFSET (reg4834), 1, INT_V},
+ {OFFSET (reg4840), 1, INT_V},
+ {OFFSET (reg4841), 1, INT_V},
+ {OFFSET (reg4842), 1, INT_V},
+ {OFFSET (AlignBy), 1, INT_V},
+ {OFFSET (written), 1, INT_V},
+ {OFFSET (offset_add), 1, INT_V},
+ {OFFSET (DataRomOffset), 4, INT_V},
+ {OFFSET (DataRomSize), 4, INT_V},
+ {OFFSET (bank50Internal), 4, INT_V},
+ {OFFSET (bank50), 0x10000, uint8_ARRAY_V}
+};
+
+#undef OFFSET
+#define OFFSET(f) Offset(f,struct SPC7110RTC *)
+
+static FreezeData SnapS7RTC [] = {
+ {OFFSET (reg), 16, uint8_ARRAY_V},
+ {OFFSET (index), 2, INT_V},
+ {OFFSET (control), 1, INT_V},
+ {OFFSET (init), 1, INT_V},
+ {OFFSET (last_used),4,INT_V}
+};
+
+static char ROMFilename [_MAX_PATH];
+//static char SnapshotFilename [_MAX_PATH];
+
+void FreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields,
+ int num_fields);
+void FreezeBlock (STREAM stream, char *name, uint8 *block, int size);
+
+int UnfreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields,
+ int num_fields);
+int UnfreezeBlock (STREAM stream, char *name, uint8 *block, int size);
+
+int UnfreezeStructCopy (STREAM stream, char *name, uint8** block, FreezeData *fields, int num_fields);
+
+void UnfreezeStructFromCopy (void *base, FreezeData *fields, int num_fields, uint8* block);
+
+int UnfreezeBlockCopy (STREAM stream, char *name, uint8** block, int size);
+
+bool8 Snapshot (const char *filename)
+{
+ return (S9xFreezeGame (filename));
+}
+
+bool8 S9xFreezeGame (const char *filename)
+{
+ STREAM stream = NULL;
+
+ FILE* fp;
+ fp = fopen(filename, "w");
+ if(NULL == fp)
+ return (FALSE);
+
+ fseek(fp, 4, SEEK_SET); //Valid data offset 4 bytes
+ S9xFreezeToStream (fp);
+ fclose(fp);
+#if 0 //Not support moive now
+ if(S9xMovieActive())
+ {
+ sprintf(String, "Movie snapshot %s", S9xBasename (filename));
+ S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String);
+ }
+ else
+ {
+ sprintf(String, "Saved %s", S9xBasename (filename));
+ S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String);
+ }
+#endif
+ return (TRUE);
+}
+
+bool8 S9xLoadSnapshot (const char *filename)
+{
+ return (S9xUnfreezeGame (filename));
+}
+
+bool8 S9xUnfreezeGame (const char *filename)
+{
+ if (S9xLoadOrigSnapshot (filename))
+ return (TRUE);
+
+ if (S9xUnfreezeZSNES (filename))
+ return (TRUE);
+
+ FILE* fp;
+ fp = fopen(filename, "r");
+ if(NULL == fp)
+ return (FALSE);
+
+ fseek(fp, 4, SEEK_SET); //Valid data offset 4 bytes
+
+ int result;
+ if ((result = S9xUnfreezeFromStream (fp)) != SUCCESS)
+ {
+#if 0
+ switch (result)
+ {
+ case WRONG_FORMAT:
+ S9xMessage (S9X_ERROR, S9X_WRONG_FORMAT,
+ "File not in Snes9x freeze format");
+ break;
+ case WRONG_VERSION:
+ S9xMessage (S9X_ERROR, S9X_WRONG_VERSION,
+ "Incompatable Snes9x freeze file format version");
+ break;
+ case WRONG_MOVIE_SNAPSHOT:
+ S9xMessage (S9X_ERROR, S9X_WRONG_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_WRONG_MOVIE);
+ break;
+ case NOT_A_MOVIE_SNAPSHOT:
+ S9xMessage (S9X_ERROR, S9X_NOT_A_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_NOT_MOVIE);
+ break;
+ default:
+ case FILE_NOT_FOUND:
+ sprintf (String, "ROM image \"%s\" for freeze file not found",
+ ROMFilename);
+ S9xMessage (S9X_ERROR, S9X_ROM_NOT_FOUND, String);
+ break;
+ }
+#endif
+ fclose(fp);
+ return (FALSE);
+ }
+#if 0 //Not support movie now
+ if(!S9xMovieActive())
+ {
+ sprintf(String, "Loaded %s", S9xBasename (filename));
+ S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String);
+ }
+#endif
+ fclose(fp);
+ return (TRUE);
+}
+
+void S9xFreezeToStream (STREAM stream)
+{
+ char buffer [1024];
+ int i;
+
+ S9xSetSoundMute (TRUE);
+#ifdef ZSNES_FX
+ if (Settings.SuperFX)
+ S9xSuperFXPreSaveState ();
+#endif
+
+ S9xUpdateRTC();
+ S9xSRTCPreSaveState ();
+
+ for (i = 0; i < 8; i++)
+ {
+ SoundData.channels [i].previous16 [0] = (int16) SoundData.channels [i].previous [0];
+ SoundData.channels [i].previous16 [1] = (int16) SoundData.channels [i].previous [1];
+ }
+ sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
+ WRITE_STREAM (buffer, strlen (buffer), stream);
+ sprintf (buffer, "NAM:%06d:%s%c", strlen (Memory.ROMFilename) + 1,
+ Memory.ROMFilename, 0);
+ WRITE_STREAM (buffer, strlen (buffer) + 1, stream);
+ FreezeStruct (stream, "CPU", &CPU, SnapCPU, COUNT (SnapCPU));
+ FreezeStruct (stream, "REG", &Registers, SnapRegisters, COUNT (SnapRegisters));
+ FreezeStruct (stream, "PPU", &PPU, SnapPPU, COUNT (SnapPPU));
+ FreezeStruct (stream, "DMA", DMA, SnapDMA, COUNT (SnapDMA));
+
+ // RAM and VRAM
+ FreezeBlock (stream, "VRA", Memory.VRAM, 0x10000);
+ FreezeBlock (stream, "RAM", Memory.RAM, 0x20000);
+ FreezeBlock (stream, "SRA", ::SRAM, 0x20000);
+ FreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000);
+ if (Settings.APUEnabled)
+ {
+ // APU
+ FreezeStruct (stream, "APU", &APU, SnapAPU, COUNT (SnapAPU));
+ FreezeStruct (stream, "ARE", &APURegisters, SnapAPURegisters,
+ COUNT (SnapAPURegisters));
+ FreezeBlock (stream, "ARA", IAPU.RAM, 0x10000);
+ FreezeStruct (stream, "SOU", &SoundData, SnapSoundData,
+ COUNT (SnapSoundData));
+ }
+ if (Settings.SA1)
+ {
+ SA1Registers.PC = SA1.PC - SA1.PCBase;
+ S9xSA1PackStatus ();
+ FreezeStruct (stream, "SA1", &SA1, SnapSA1, COUNT (SnapSA1));
+ FreezeStruct (stream, "SAR", &SA1Registers, SnapSA1Registers,
+ COUNT (SnapSA1Registers));
+ }
+
+ if (Settings.SPC7110)
+ {
+ FreezeStruct (stream, "SP7", &s7r, SnapSPC7110, COUNT (SnapSPC7110));
+ }
+ if(Settings.SPC7110RTC)
+ {
+ FreezeStruct (stream, "RTC", &rtc_f9, SnapS7RTC, COUNT (SnapS7RTC));
+ }
+
+ if (S9xMovieActive ())
+ {
+ uint8* movie_freeze_buf;
+ uint32 movie_freeze_size;
+
+ S9xMovieFreeze(&movie_freeze_buf, &movie_freeze_size);
+ if(movie_freeze_buf)
+ {
+ struct SnapshotMovieInfo mi;
+ mi.MovieInputDataSize = movie_freeze_size;
+ FreezeStruct (stream, "MOV", &mi, SnapMovie, COUNT (SnapMovie));
+ FreezeBlock (stream, "MID", movie_freeze_buf, movie_freeze_size);
+ delete [] movie_freeze_buf;
+ }
+ }
+
+ S9xSetSoundMute (FALSE);
+#ifdef ZSNES_FX
+ if (Settings.SuperFX)
+ S9xSuperFXPostSaveState ();
+#endif
+}
+
+int S9xUnfreezeFromStream (STREAM stream)
+{
+ char buffer [_MAX_PATH + 1];
+ char rom_filename [_MAX_PATH + 1];
+ int result;
+
+ int version;
+ int len = strlen (SNAPSHOT_MAGIC) + 1 + 4 + 1;
+ if (READ_STREAM (buffer, len, stream) != len)
+ return (WRONG_FORMAT);
+ if (strncmp (buffer, SNAPSHOT_MAGIC, strlen (SNAPSHOT_MAGIC)) != 0)
+ return (WRONG_FORMAT);
+ if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION)
+ return (WRONG_VERSION);
+
+ if ((result = UnfreezeBlock (stream, "NAM", (uint8 *) rom_filename, _MAX_PATH)) != SUCCESS)
+ return (result);
+
+ if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 &&
+ strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0)
+ {
+ S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME,
+ "Current loaded ROM image doesn't match that required by freeze-game file.");
+ }
+
+// ## begin load ##
+ uint8* local_cpu = NULL;
+ uint8* local_registers = NULL;
+ uint8* local_ppu = NULL;
+ uint8* local_dma = NULL;
+ uint8* local_vram = NULL;
+ uint8* local_ram = NULL;
+ uint8* local_sram = NULL;
+ uint8* local_fillram = NULL;
+ uint8* local_apu = NULL;
+ uint8* local_apu_registers = NULL;
+ uint8* local_apu_ram = NULL;
+ uint8* local_apu_sounddata = NULL;
+ uint8* local_sa1 = NULL;
+ uint8* local_sa1_registers = NULL;
+ uint8* local_spc = NULL;
+ uint8* local_spc_rtc = NULL;
+ uint8* local_movie_data = NULL;
+
+ do
+ {
+ if ((result = UnfreezeStructCopy (stream, "CPU", &local_cpu, SnapCPU, COUNT (SnapCPU))) != SUCCESS)
+ break;
+ if ((result = UnfreezeStructCopy (stream, "REG", &local_registers, SnapRegisters, COUNT (SnapRegisters))) != SUCCESS)
+ break;
+ if ((result = UnfreezeStructCopy (stream, "PPU", &local_ppu, SnapPPU, COUNT (SnapPPU))) != SUCCESS)
+ break;
+ if ((result = UnfreezeStructCopy (stream, "DMA", &local_dma, SnapDMA, COUNT (SnapDMA))) != SUCCESS)
+ break;
+ if ((result = UnfreezeBlockCopy (stream, "VRA", &local_vram, 0x10000)) != SUCCESS)
+ break;
+ if ((result = UnfreezeBlockCopy (stream, "RAM", &local_ram, 0x20000)) != SUCCESS)
+ break;
+ if ((result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x20000)) != SUCCESS)
+ break;
+ if ((result = UnfreezeBlockCopy (stream, "FIL", &local_fillram, 0x8000)) != SUCCESS)
+ break;
+ if (UnfreezeStructCopy (stream, "APU", &local_apu, SnapAPU, COUNT (SnapAPU)) == SUCCESS)
+ {
+ if ((result = UnfreezeStructCopy (stream, "ARE", &local_apu_registers, SnapAPURegisters, COUNT (SnapAPURegisters))) != SUCCESS)
+ break;
+ if ((result = UnfreezeBlockCopy (stream, "ARA", &local_apu_ram, 0x10000)) != SUCCESS)
+ break;
+ if ((result = UnfreezeStructCopy (stream, "SOU", &local_apu_sounddata, SnapSoundData, COUNT (SnapSoundData))) != SUCCESS)
+ break;
+ }
+ if ((result = UnfreezeStructCopy (stream, "SA1", &local_sa1, SnapSA1, COUNT(SnapSA1))) == SUCCESS)
+ {
+ if ((result = UnfreezeStructCopy (stream, "SAR", &local_sa1_registers, SnapSA1Registers, COUNT (SnapSA1Registers))) != SUCCESS)
+ break;
+ }
+
+ if ((result = UnfreezeStructCopy (stream, "SP7", &local_spc, SnapSPC7110, COUNT(SnapSPC7110))) != SUCCESS)
+ {
+ if(Settings.SPC7110)
+ break;
+ }
+ if ((result = UnfreezeStructCopy (stream, "RTC", &local_spc_rtc, SnapS7RTC, COUNT (SnapS7RTC))) != SUCCESS)
+ {
+ if(Settings.SPC7110RTC)
+ break;
+ }
+
+ if (S9xMovieActive ())
+ {
+ SnapshotMovieInfo mi;
+ if ((result = UnfreezeStruct (stream, "MOV", &mi, SnapMovie, COUNT(SnapMovie))) != SUCCESS)
+ {
+ result = NOT_A_MOVIE_SNAPSHOT;
+ break;
+ }
+
+ if ((result = UnfreezeBlockCopy (stream, "MID", &local_movie_data, mi.MovieInputDataSize)) != SUCCESS)
+ {
+ result = NOT_A_MOVIE_SNAPSHOT;
+ break;
+ }
+
+ if (!S9xMovieUnfreeze(local_movie_data, mi.MovieInputDataSize))
+ {
+ result = WRONG_MOVIE_SNAPSHOT;
+ break;
+ }
+ }
+
+ result=SUCCESS;
+
+ } while(false);
+// ## end load ##
+
+ if (result == SUCCESS)
+ {
+ uint32 old_flags = CPU.Flags;
+ uint32 sa1_old_flags = SA1.Flags;
+ S9xReset ();
+ S9xSetSoundMute (TRUE);
+
+ UnfreezeStructFromCopy (&CPU, SnapCPU, COUNT (SnapCPU), local_cpu);
+ UnfreezeStructFromCopy (&Registers, SnapRegisters, COUNT (SnapRegisters), local_registers);
+ UnfreezeStructFromCopy (&PPU, SnapPPU, COUNT (SnapPPU), local_ppu);
+ UnfreezeStructFromCopy (DMA, SnapDMA, COUNT (SnapDMA), local_dma);
+ memcpy (Memory.VRAM, local_vram, 0x10000);
+ memcpy (Memory.RAM, local_ram, 0x20000);
+ memcpy (::SRAM, local_sram, 0x20000);
+ memcpy (Memory.FillRAM, local_fillram, 0x8000);
+ if(local_apu)
+ {
+ UnfreezeStructFromCopy (&APU, SnapAPU, COUNT (SnapAPU), local_apu);
+ UnfreezeStructFromCopy (&APURegisters, SnapAPURegisters, COUNT (SnapAPURegisters), local_apu_registers);
+ memcpy (IAPU.RAM, local_apu_ram, 0x10000);
+ UnfreezeStructFromCopy (&SoundData, SnapSoundData, COUNT (SnapSoundData), local_apu_sounddata);
+ }
+ if(local_sa1)
+ {
+ UnfreezeStructFromCopy (&SA1, SnapSA1, COUNT (SnapSA1), local_sa1);
+ UnfreezeStructFromCopy (&SA1Registers, SnapSA1Registers, COUNT (SnapSA1Registers), local_sa1_registers);
+ }
+ if(local_spc)
+ {
+ UnfreezeStructFromCopy (&s7r, SnapSPC7110, COUNT (SnapSPC7110), local_spc);
+ }
+ if(local_spc_rtc)
+ {
+ UnfreezeStructFromCopy (&rtc_f9, SnapS7RTC, COUNT (SnapS7RTC), local_spc_rtc);
+ }
+
+ Memory.FixROMSpeed ();
+ CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG |
+ SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG);
+
+ IPPU.ColorsChanged = TRUE;
+ IPPU.OBJChanged = TRUE;
+ CPU.InDMA = FALSE;
+ S9xFixColourBrightness ();
+ IPPU.RenderThisFrame = FALSE;
+
+ if (local_apu)
+ {
+ S9xSetSoundMute (FALSE);
+ IAPU.PC = IAPU.RAM + APURegisters.PC;
+ S9xAPUUnpackStatus ();
+ if (APUCheckDirectPage ())
+ IAPU.DirectPage = IAPU.RAM + 0x100;
+ else
+ IAPU.DirectPage = IAPU.RAM;
+ Settings.APUEnabled = TRUE;
+ IAPU.APUExecuting = TRUE;
+ }
+ else
+ {
+ Settings.APUEnabled = FALSE;
+ IAPU.APUExecuting = FALSE;
+ S9xSetSoundMute (TRUE);
+ }
+
+ if (local_sa1)
+ {
+ S9xFixSA1AfterSnapshotLoad ();
+ SA1.Flags |= sa1_old_flags & (TRACE_FLAG);
+ }
+
+ if (local_spc_rtc)
+ {
+ S9xUpdateRTC();
+ }
+
+ S9xFixSoundAfterSnapshotLoad ();
+
+ uint8 hdma_byte = Memory.FillRAM[0x420c];
+ S9xSetCPU(hdma_byte, 0x420c);
+
+ if(!Memory.FillRAM[0x4213]){
+ // most likely an old savestate
+ Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201];
+ if(!Memory.FillRAM[0x4213])
+ Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201]=0xFF;
+ }
+
+ ICPU.ShiftedPB = Registers.PB << 16;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ S9xSetPCBase (ICPU.ShiftedPB + Registers.PC);
+ S9xUnpackStatus ();
+ S9xFixCycles ();
+// S9xReschedule (); // <-- this causes desync when recording or playing movies
+
+#ifdef ZSNES_FX
+ if (Settings.SuperFX)
+ S9xSuperFXPostLoadState ();
+#endif
+
+ S9xSRTCPostLoadState ();
+ if (Settings.SDD1)
+ S9xSDD1PostLoadState ();
+ }
+
+ if (local_cpu) delete [] local_cpu;
+ if (local_registers) delete [] local_registers;
+ if (local_ppu) delete [] local_ppu;
+ if (local_dma) delete [] local_dma;
+ if (local_vram) delete [] local_vram;
+ if (local_ram) delete [] local_ram;
+ if (local_sram) delete [] local_sram;
+ if (local_fillram) delete [] local_fillram;
+ if (local_apu) delete [] local_apu;
+ if (local_apu_registers) delete [] local_apu_registers;
+ if (local_apu_ram) delete [] local_apu_ram;
+ if (local_apu_sounddata) delete [] local_apu_sounddata;
+ if (local_sa1) delete [] local_sa1;
+ if (local_sa1_registers) delete [] local_sa1_registers;
+ if (local_spc) delete [] local_spc;
+ if (local_spc_rtc) delete [] local_spc_rtc;
+ if (local_movie_data) delete [] local_movie_data;
+
+ return (result);
+}
+
+int FreezeSize (int size, int type)
+{
+ switch (type)
+ {
+ case uint16_ARRAY_V:
+ return (size * 2);
+ case uint32_ARRAY_V:
+ return (size * 4);
+ default:
+ return (size);
+ }
+}
+
+void FreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields,
+ int num_fields)
+{
+ // Work out the size of the required block
+ int len = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < num_fields; i++)
+ {
+ if (fields [i].offset + FreezeSize (fields [i].size,
+ fields [i].type) > len)
+ len = fields [i].offset + FreezeSize (fields [i].size,
+ fields [i].type);
+ }
+
+ uint8 *block = new uint8 [len];
+ uint8 *ptr = block;
+ uint16 word;
+ uint32 dword;
+ int64 qword;
+
+ // Build the block ready to be streamed out
+ for (i = 0; i < num_fields; i++)
+ {
+ switch (fields [i].type)
+ {
+ case INT_V:
+ switch (fields [i].size)
+ {
+ case 1:
+ *ptr++ = *((uint8 *) base + fields [i].offset);
+ break;
+ case 2:
+ word = *((uint16 *) ((uint8 *) base + fields [i].offset));
+ *ptr++ = (uint8) (word >> 8);
+ *ptr++ = (uint8) word;
+ break;
+ case 4:
+ dword = *((uint32 *) ((uint8 *) base + fields [i].offset));
+ *ptr++ = (uint8) (dword >> 24);
+ *ptr++ = (uint8) (dword >> 16);
+ *ptr++ = (uint8) (dword >> 8);
+ *ptr++ = (uint8) dword;
+ break;
+ case 8:
+ qword = *((int64 *) ((uint8 *) base + fields [i].offset));
+ *ptr++ = (uint8) (qword >> 56);
+ *ptr++ = (uint8) (qword >> 48);
+ *ptr++ = (uint8) (qword >> 40);
+ *ptr++ = (uint8) (qword >> 32);
+ *ptr++ = (uint8) (qword >> 24);
+ *ptr++ = (uint8) (qword >> 16);
+ *ptr++ = (uint8) (qword >> 8);
+ *ptr++ = (uint8) qword;
+ break;
+ }
+ break;
+ case uint8_ARRAY_V:
+ memmove (ptr, (uint8 *) base + fields [i].offset, fields [i].size);
+ ptr += fields [i].size;
+ break;
+ case uint16_ARRAY_V:
+ for (j = 0; j < fields [i].size; j++)
+ {
+ word = *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2));
+ *ptr++ = (uint8) (word >> 8);
+ *ptr++ = (uint8) word;
+ }
+ break;
+ case uint32_ARRAY_V:
+ for (j = 0; j < fields [i].size; j++)
+ {
+ dword = *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4));
+ *ptr++ = (uint8) (dword >> 24);
+ *ptr++ = (uint8) (dword >> 16);
+ *ptr++ = (uint8) (dword >> 8);
+ *ptr++ = (uint8) dword;
+ }
+ break;
+ }
+ }
+
+ FreezeBlock (stream, name, block, len);
+ delete[] block;
+}
+
+void FreezeBlock (STREAM stream, char *name, uint8 *block, int size)
+{
+ char buffer [512];
+ sprintf (buffer, "%s:%06d:", name, size);
+ WRITE_STREAM (buffer, strlen (buffer), stream);
+ WRITE_STREAM ((char*)block, size, stream);
+
+}
+
+int UnfreezeStruct (STREAM stream, char *name, void *base, FreezeData *fields,
+ int num_fields)
+{
+ // Work out the size of the required block
+ int len = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < num_fields; i++)
+ {
+ if (fields [i].offset + FreezeSize (fields [i].size,
+ fields [i].type) > len)
+ len = fields [i].offset + FreezeSize (fields [i].size,
+ fields [i].type);
+ }
+
+ uint8 *block = new uint8 [len];
+ uint8 *ptr = block;
+ uint16 word;
+ uint32 dword;
+ int64 qword;
+ int result;
+
+ if ((result = UnfreezeBlock (stream, name, block, len)) != SUCCESS)
+ {
+ delete block;
+ return (result);
+ }
+
+ // Unpack the block of data into a C structure
+ for (i = 0; i < num_fields; i++)
+ {
+ switch (fields [i].type)
+ {
+ case INT_V:
+ switch (fields [i].size)
+ {
+ case 1:
+ *((uint8 *) base + fields [i].offset) = *ptr++;
+ break;
+ case 2:
+ word = *ptr++ << 8;
+ word |= *ptr++;
+ *((uint16 *) ((uint8 *) base + fields [i].offset)) = word;
+ break;
+ case 4:
+ dword = *ptr++ << 24;
+ dword |= *ptr++ << 16;
+ dword |= *ptr++ << 8;
+ dword |= *ptr++;
+ *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword;
+ break;
+ case 8:
+ qword = (int64) *ptr++ << 56;
+ qword |= (int64) *ptr++ << 48;
+ qword |= (int64) *ptr++ << 40;
+ qword |= (int64) *ptr++ << 32;
+ qword |= (int64) *ptr++ << 24;
+ qword |= (int64) *ptr++ << 16;
+ qword |= (int64) *ptr++ << 8;
+ qword |= (int64) *ptr++;
+ *((int64 *) ((uint8 *) base + fields [i].offset)) = qword;
+ break;
+ }
+ break;
+ case uint8_ARRAY_V:
+ memmove ((uint8 *) base + fields [i].offset, ptr, fields [i].size);
+ ptr += fields [i].size;
+ break;
+ case uint16_ARRAY_V:
+ for (j = 0; j < fields [i].size; j++)
+ {
+ word = *ptr++ << 8;
+ word |= *ptr++;
+ *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word;
+ }
+ break;
+ case uint32_ARRAY_V:
+ for (j = 0; j < fields [i].size; j++)
+ {
+ dword = *ptr++ << 24;
+ dword |= *ptr++ << 16;
+ dword |= *ptr++ << 8;
+ dword |= *ptr++;
+ *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword;
+ }
+ break;
+ }
+ }
+
+ delete [] block;
+ return (result);
+}
+
+int UnfreezeBlock (STREAM stream, char *name, uint8 *block, int size)
+{
+ char buffer [20];
+ int len = 0;
+ int rem = 0;
+ int rew_len;
+ if (READ_STREAM (buffer, 11, stream) != 11 ||
+ strncmp (buffer, name, 3) != 0 || buffer [3] != ':' ||
+ (len = atoi (&buffer [4])) == 0)
+ {
+ REVERT_STREAM(stream, FIND_STREAM(stream)-11, 0);
+ return (WRONG_FORMAT);
+ }
+
+ if (len > size)
+ {
+ rem = len - size;
+ len = size;
+ }
+ if ((rew_len=READ_STREAM ((char*)block, len, stream)) != len)
+ {
+ REVERT_STREAM(stream, FIND_STREAM(stream)-11-rew_len, 0);
+ return (WRONG_FORMAT);
+ }
+ if (rem)
+ {
+ char *junk = new char [rem];
+ READ_STREAM (junk, rem, stream);
+ delete [] junk;
+ }
+
+ return (SUCCESS);
+}
+
+int UnfreezeStructCopy (STREAM stream, char *name, uint8** block, FreezeData *fields, int num_fields)
+{
+ // Work out the size of the required block
+ int len = 0;
+ int i;
+
+ for (i = 0; i < num_fields; i++)
+ {
+ if (fields [i].offset + FreezeSize (fields [i].size,
+ fields [i].type) > len)
+ len = fields [i].offset + FreezeSize (fields [i].size,
+ fields [i].type);
+ }
+
+ return (UnfreezeBlockCopy (stream, name, block, len));
+}
+
+void UnfreezeStructFromCopy (void *base, FreezeData *fields, int num_fields, uint8* block)
+{
+ int i;
+ int j;
+ uint8 *ptr = block;
+ uint16 word;
+ uint32 dword;
+ int64 qword;
+
+ // Unpack the block of data into a C structure
+ for (i = 0; i < num_fields; i++)
+ {
+ switch (fields [i].type)
+ {
+ case INT_V:
+ switch (fields [i].size)
+ {
+ case 1:
+ *((uint8 *) base + fields [i].offset) = *ptr++;
+ break;
+ case 2:
+ word = *ptr++ << 8;
+ word |= *ptr++;
+ *((uint16 *) ((uint8 *) base + fields [i].offset)) = word;
+ break;
+ case 4:
+ dword = *ptr++ << 24;
+ dword |= *ptr++ << 16;
+ dword |= *ptr++ << 8;
+ dword |= *ptr++;
+ *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword;
+ break;
+ case 8:
+ qword = (int64) *ptr++ << 56;
+ qword |= (int64) *ptr++ << 48;
+ qword |= (int64) *ptr++ << 40;
+ qword |= (int64) *ptr++ << 32;
+ qword |= (int64) *ptr++ << 24;
+ qword |= (int64) *ptr++ << 16;
+ qword |= (int64) *ptr++ << 8;
+ qword |= (int64) *ptr++;
+ *((int64 *) ((uint8 *) base + fields [i].offset)) = qword;
+ break;
+ }
+ break;
+ case uint8_ARRAY_V:
+ memmove ((uint8 *) base + fields [i].offset, ptr, fields [i].size);
+ ptr += fields [i].size;
+ break;
+ case uint16_ARRAY_V:
+ for (j = 0; j < fields [i].size; j++)
+ {
+ word = *ptr++ << 8;
+ word |= *ptr++;
+ *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word;
+ }
+ break;
+ case uint32_ARRAY_V:
+ for (j = 0; j < fields [i].size; j++)
+ {
+ dword = *ptr++ << 24;
+ dword |= *ptr++ << 16;
+ dword |= *ptr++ << 8;
+ dword |= *ptr++;
+ *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword;
+ }
+ break;
+ }
+ }
+}
+
+int UnfreezeBlockCopy (STREAM stream, char *name, uint8** block, int size)
+{
+ *block = new uint8 [size];
+ int result;
+
+ if ((result = UnfreezeBlock (stream, name, *block, size)) != SUCCESS)
+ {
+ delete [] (*block);
+ *block = NULL;
+ return (result);
+ }
+
+ return (result);
+}
+
+extern uint8 spc_dump_dsp[0x100];
+
+bool8 S9xSPCDump (const char *filename)
+{
+ return (FALSE);
+#if 0
+ static uint8 header [] = {
+ 'S', 'N', 'E', 'S', '-', 'S', 'P', 'C', '7', '0', '0', ' ',
+ 'S', 'o', 'u', 'n', 'd', ' ', 'F', 'i', 'l', 'e', ' ',
+ 'D', 'a', 't', 'a', ' ', 'v', '0', '.', '3', '0', 26, 26, 26
+ };
+ static uint8 version = {
+ 0x1e
+ };
+
+ FILE *fs;
+
+ S9xSetSoundMute (TRUE);
+
+ if (!(fs = fopen (filename, "wb")))
+ return (FALSE);
+
+ // The SPC file format:
+ // 0000: header: 'SNES-SPC700 Sound File Data v0.30',26,26,26
+ // 0036: version: $1e
+ // 0037: SPC700 PC:
+ // 0039: SPC700 A:
+ // 0040: SPC700 X:
+ // 0041: SPC700 Y:
+ // 0042: SPC700 P:
+ // 0043: SPC700 S:
+ // 0044: Reserved: 0, 0, 0, 0
+ // 0048: Title of game: 32 bytes
+ // 0000: Song name: 32 bytes
+ // 0000: Name of dumper: 32 bytes
+ // 0000: Comments: 32 bytes
+ // 0000: Date of SPC dump: 4 bytes
+ // 0000: Fade out time in milliseconds: 4 bytes
+ // 0000: Fade out length in milliseconds: 2 bytes
+ // 0000: Default channel enables: 1 bytes
+ // 0000: Emulator used to dump .SPC files: 1 byte, 1 == ZSNES
+ // 0000: Reserved: 36 bytes
+ // 0256: SPC700 RAM: 64K
+ // ----: DSP Registers: 256 bytes
+
+ if (fwrite (header, sizeof (header), 1, fs) != 1 ||
+ fputc (version, fs) == EOF ||
+ fseek (fs, 37, SEEK_SET) == EOF ||
+ fputc (APURegisters.PC & 0xff, fs) == EOF ||
+ fputc (APURegisters.PC >> 8, fs) == EOF ||
+ fputc (APURegisters.YA.B.A, fs) == EOF ||
+ fputc (APURegisters.X, fs) == EOF ||
+ fputc (APURegisters.YA.B.Y, fs) == EOF ||
+ fputc (APURegisters.P, fs) == EOF ||
+ fputc (APURegisters.S, fs) == EOF ||
+ fseek (fs, 256, SEEK_SET) == EOF ||
+ fwrite (IAPU.RAM, 0x10000, 1, fs) != 1 ||
+ fwrite (spc_dump_dsp, 1, 256, fs) != 256 ||
+ fwrite (APU.ExtraRAM, 64, 1, fs) != 1 ||
+ fclose (fs) < 0)
+ {
+ S9xSetSoundMute (FALSE);
+ return (FALSE);
+ }
+ S9xSetSoundMute (FALSE);
+ return (TRUE);
+#endif
+}
+
+bool8 S9xUnfreezeZSNES (const char *filename)
+{
+ FILE *fs;
+ uint8 t [4000];
+
+ if (!(fs = fopen (filename, "rb")))
+ return (FALSE);
+
+ if (fread ((char*)t, 64, 1, fs) == 1 &&
+ strncmp ((char *) t, "ZSNES Save State File V0.6", 26) == 0)
+ {
+ S9xReset ();
+ S9xSetSoundMute (TRUE);
+
+ // 28 Curr cycle
+ CPU.V_Counter = READ_WORD (&t [29]);
+ // 33 instrset
+ Settings.APUEnabled = t [36];
+
+ // 34 bcycpl cycles per scanline
+ // 35 cycphb cyclers per hblank
+
+ Registers.A.W = READ_WORD (&t [41]);
+ Registers.DB = t [43];
+ Registers.PB = t [44];
+ Registers.S.W = READ_WORD (&t [45]);
+ Registers.D.W = READ_WORD (&t [47]);
+ Registers.X.W = READ_WORD (&t [49]);
+ Registers.Y.W = READ_WORD (&t [51]);
+ Registers.P.W = READ_WORD (&t [53]);
+ Registers.PC = READ_WORD (&t [55]);
+
+ fread ((char*)t, 1, 8, fs);
+ fread ((char*)t, 1, 3019, fs);
+ S9xSetCPU (t [2], 0x4200);
+ Memory.FillRAM [0x4210] = t [3];
+ PPU.IRQVBeamPos = READ_WORD (&t [4]);
+ PPU.IRQHBeamPos = READ_WORD (&t [2527]);
+ PPU.Brightness = t [6];
+ PPU.ForcedBlanking = t [8] >> 7;
+
+ int i;
+ for (i = 0; i < 544; i++)
+ S9xSetPPU (t [0464 + i], 0x2104);
+
+ PPU.OBJNameBase = READ_WORD (&t [9]);
+ PPU.OBJNameSelect = READ_WORD (&t [13]) - PPU.OBJNameBase;
+ switch (t [18])
+ {
+ case 4:
+ if (t [17] == 1)
+ PPU.OBJSizeSelect = 0;
+ else
+ PPU.OBJSizeSelect = 6;
+ break;
+ case 16:
+ if (t [17] == 1)
+ PPU.OBJSizeSelect = 1;
+ else
+ PPU.OBJSizeSelect = 3;
+ break;
+ default:
+ case 64:
+ if (t [17] == 1)
+ PPU.OBJSizeSelect = 2;
+ else
+ if (t [17] == 4)
+ PPU.OBJSizeSelect = 4;
+ else
+ PPU.OBJSizeSelect = 5;
+ break;
+ }
+ PPU.OAMAddr = READ_WORD (&t [25]);
+ PPU.SavedOAMAddr = READ_WORD (&t [27]);
+ PPU.FirstSprite = t [29];
+ PPU.BGMode = t [30];
+ PPU.BG3Priority = t [31];
+ PPU.BG[0].BGSize = (t [32] >> 0) & 1;
+ PPU.BG[1].BGSize = (t [32] >> 1) & 1;
+ PPU.BG[2].BGSize = (t [32] >> 2) & 1;
+ PPU.BG[3].BGSize = (t [32] >> 3) & 1;
+ PPU.Mosaic = t [33] + 1;
+ PPU.BGMosaic [0] = (t [34] & 1) != 0;
+ PPU.BGMosaic [1] = (t [34] & 2) != 0;
+ PPU.BGMosaic [2] = (t [34] & 4) != 0;
+ PPU.BGMosaic [3] = (t [34] & 8) != 0;
+ PPU.BG [0].SCBase = READ_WORD (&t [35]) >> 1;
+ PPU.BG [1].SCBase = READ_WORD (&t [37]) >> 1;
+ PPU.BG [2].SCBase = READ_WORD (&t [39]) >> 1;
+ PPU.BG [3].SCBase = READ_WORD (&t [41]) >> 1;
+ PPU.BG [0].SCSize = t [67];
+ PPU.BG [1].SCSize = t [68];
+ PPU.BG [2].SCSize = t [69];
+ PPU.BG [3].SCSize = t [70];
+ PPU.BG[0].NameBase = READ_WORD (&t [71]) >> 1;
+ PPU.BG[1].NameBase = READ_WORD (&t [73]) >> 1;
+ PPU.BG[2].NameBase = READ_WORD (&t [75]) >> 1;
+ PPU.BG[3].NameBase = READ_WORD (&t [77]) >> 1;
+ PPU.BG[0].HOffset = READ_WORD (&t [79]);
+ PPU.BG[1].HOffset = READ_WORD (&t [81]);
+ PPU.BG[2].HOffset = READ_WORD (&t [83]);
+ PPU.BG[3].HOffset = READ_WORD (&t [85]);
+ PPU.BG[0].VOffset = READ_WORD (&t [89]);
+ PPU.BG[1].VOffset = READ_WORD (&t [91]);
+ PPU.BG[2].VOffset = READ_WORD (&t [93]);
+ PPU.BG[3].VOffset = READ_WORD (&t [95]);
+ PPU.VMA.Increment = READ_WORD (&t [97]) >> 1;
+ PPU.VMA.High = t [99];
+#ifndef CORRECT_VRAM_READS
+ IPPU.FirstVRAMRead = t [100];
+#endif
+ S9xSetPPU (t [2512], 0x2115);
+ PPU.VMA.Address = READ_DWORD (&t [101]);
+ for (i = 0; i < 512; i++)
+ S9xSetPPU (t [1488 + i], 0x2122);
+
+ PPU.CGADD = (uint8) READ_WORD (&t [105]);
+ Memory.FillRAM [0x212c] = t [108];
+ Memory.FillRAM [0x212d] = t [109];
+ PPU.ScreenHeight = READ_WORD (&t [111]);
+ Memory.FillRAM [0x2133] = t [2526];
+ Memory.FillRAM [0x4202] = t [113];
+ Memory.FillRAM [0x4204] = t [114];
+ Memory.FillRAM [0x4205] = t [115];
+ Memory.FillRAM [0x4214] = t [116];
+ Memory.FillRAM [0x4215] = t [117];
+ Memory.FillRAM [0x4216] = t [118];
+ Memory.FillRAM [0x4217] = t [119];
+ PPU.VBeamPosLatched = READ_WORD (&t [122]);
+ PPU.HBeamPosLatched = READ_WORD (&t [120]);
+ PPU.Window1Left = t [127];
+ PPU.Window1Right = t [128];
+ PPU.Window2Left = t [129];
+ PPU.Window2Right = t [130];
+ S9xSetPPU (t [131] | (t [132] << 4), 0x2123);
+ S9xSetPPU (t [133] | (t [134] << 4), 0x2124);
+ S9xSetPPU (t [135] | (t [136] << 4), 0x2125);
+ S9xSetPPU (t [137], 0x212a);
+ S9xSetPPU (t [138], 0x212b);
+ S9xSetPPU (t [139], 0x212e);
+ S9xSetPPU (t [140], 0x212f);
+ S9xSetPPU (t [141], 0x211a);
+ PPU.MatrixA = READ_WORD (&t [142]);
+ PPU.MatrixB = READ_WORD (&t [144]);
+ PPU.MatrixC = READ_WORD (&t [146]);
+ PPU.MatrixD = READ_WORD (&t [148]);
+ PPU.CentreX = READ_WORD (&t [150]);
+ PPU.CentreY = READ_WORD (&t [152]);
+ // JoyAPos t[154]
+ // JoyBPos t[155]
+ Memory.FillRAM [0x2134] = t [156]; // Matrix mult
+ Memory.FillRAM [0x2135] = t [157]; // Matrix mult
+ Memory.FillRAM [0x2136] = t [158]; // Matrix mult
+ PPU.WRAM = READ_DWORD (&t [161]);
+
+ for (i = 0; i < 128; i++)
+ S9xSetCPU (t [165 + i], 0x4300 + i);
+
+ if (t [294])
+ CPU.IRQActive |= PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE;
+
+ S9xSetCPU (t [296], 0x420c);
+ // hdmadata t[297] + 8 * 19
+ PPU.FixedColourRed = t [450];
+ PPU.FixedColourGreen = t [451];
+ PPU.FixedColourBlue = t [452];
+ S9xSetPPU (t [454], 0x2130);
+ S9xSetPPU (t [455], 0x2131);
+ // vraminctype ...
+
+ fread ((char*)Memory.RAM, 1, 128 * 1024, fs);
+ fread ((char*)Memory.VRAM, 1, 64 * 1024, fs);
+
+ if (Settings.APUEnabled)
+ {
+ // SNES SPC700 RAM (64K)
+ fread ((char*)IAPU.RAM, 1, 64 * 1024, fs);
+
+ // Junk 16 bytes
+ fread ((char*)t, 1, 16, fs);
+
+ // SNES SPC700 state and internal ZSNES SPC700 emulation state
+ fread ((char*)t, 1, 304, fs);
+
+ APURegisters.PC = READ_DWORD (&t [0]);
+ APURegisters.YA.B.A = t [4];
+ APURegisters.X = t [8];
+ APURegisters.YA.B.Y = t [12];
+ APURegisters.P = t [16];
+ APURegisters.S = t [24];
+
+ APU.Cycles = READ_DWORD (&t [32]);
+ APU.ShowROM = (IAPU.RAM [0xf1] & 0x80) != 0;
+ APU.OutPorts [0] = t [36];
+ APU.OutPorts [1] = t [37];
+ APU.OutPorts [2] = t [38];
+ APU.OutPorts [3] = t [39];
+
+ APU.TimerEnabled [0] = (t [40] & 1) != 0;
+ APU.TimerEnabled [1] = (t [40] & 2) != 0;
+ APU.TimerEnabled [2] = (t [40] & 4) != 0;
+ S9xSetAPUTimer (0xfa, t [41]);
+ S9xSetAPUTimer (0xfb, t [42]);
+ S9xSetAPUTimer (0xfc, t [43]);
+ APU.Timer [0] = t [44];
+ APU.Timer [1] = t [45];
+ APU.Timer [2] = t [46];
+
+ memmove (APU.ExtraRAM, &t [48], 64);
+
+ // Internal ZSNES sound DSP state
+ fread (t, 1, 1068, fs);
+
+ // SNES sound DSP register values
+ fread (t, 1, 256, fs);
+
+ uint8 saved = IAPU.RAM [0xf2];
+
+ for (i = 0; i < 128; i++)
+ {
+ switch (i)
+ {
+ case APU_KON:
+ case APU_KOFF:
+ break;
+ case APU_FLG:
+ t [i] &= ~APU_SOFT_RESET;
+ default:
+ IAPU.RAM [0xf2] = i;
+ S9xSetAPUDSP (t [i]);
+ break;
+ }
+ }
+ IAPU.RAM [0xf2] = APU_KON;
+ S9xSetAPUDSP (t [APU_KON]);
+ IAPU.RAM [0xf2] = saved;
+
+ S9xSetSoundMute (FALSE);
+ IAPU.PC = IAPU.RAM + APURegisters.PC;
+ S9xAPUUnpackStatus ();
+ if (APUCheckDirectPage ())
+ IAPU.DirectPage = IAPU.RAM + 0x100;
+ else
+ IAPU.DirectPage = IAPU.RAM;
+ Settings.APUEnabled = TRUE;
+ IAPU.APUExecuting = TRUE;
+ }
+ else
+ {
+ Settings.APUEnabled = FALSE;
+ IAPU.APUExecuting = FALSE;
+ S9xSetSoundMute (TRUE);
+ }
+
+ if (Settings.SuperFX)
+ {
+ fread (::SRAM, 1, 64 * 1024, fs);
+ fseek (fs, 64 * 1024, SEEK_CUR);
+ fread (Memory.FillRAM + 0x7000, 1, 692, fs);
+ }
+ if (Settings.SA1)
+ {
+ fread (t, 1, 2741, fs);
+ S9xSetSA1 (t [4], 0x2200); // Control
+ S9xSetSA1 (t [12], 0x2203); // ResetV low
+ S9xSetSA1 (t [13], 0x2204); // ResetV hi
+ S9xSetSA1 (t [14], 0x2205); // NMI low
+ S9xSetSA1 (t [15], 0x2206); // NMI hi
+ S9xSetSA1 (t [16], 0x2207); // IRQ low
+ S9xSetSA1 (t [17], 0x2208); // IRQ hi
+ S9xSetSA1 (((READ_DWORD (&t [28]) - (4096*1024-0x6000))) >> 13, 0x2224);
+ S9xSetSA1 (t [36], 0x2201);
+ S9xSetSA1 (t [41], 0x2209);
+
+ SA1Registers.A.W = READ_DWORD (&t [592]);
+ SA1Registers.X.W = READ_DWORD (&t [596]);
+ SA1Registers.Y.W = READ_DWORD (&t [600]);
+ SA1Registers.D.W = READ_DWORD (&t [604]);
+ SA1Registers.DB = t [608];
+ SA1Registers.PB = t [612];
+ SA1Registers.S.W = READ_DWORD (&t [616]);
+ SA1Registers.PC = READ_DWORD (&t [636]);
+ SA1Registers.P.W = t [620] | (t [624] << 8);
+
+ memmove (&Memory.FillRAM [0x3000], t + 692, 2 * 1024);
+
+ fread (::SRAM, 1, 64 * 1024, fs);
+ fseek (fs, 64 * 1024, SEEK_CUR);
+ S9xFixSA1AfterSnapshotLoad ();
+ }
+ if(Settings.SPC7110)
+ {
+ uint32 temp;
+ fread(&s7r.bank50, 1,0x10000, fs);
+
+ //NEWSYM SPCMultA, dd 0 4820-23
+ fread(&temp, 1, 4, fs);
+
+ s7r.reg4820=temp&(0x0FF);
+ s7r.reg4821=(temp>>8)&(0x0FF);
+ s7r.reg4822=(temp>>16)&(0x0FF);
+ s7r.reg4823=(temp>>24)&(0x0FF);
+
+ //NEWSYM SPCMultB, dd 0 4824-5
+ fread(&temp, 1,4,fs);
+ s7r.reg4824=temp&(0x0FF);
+ s7r.reg4825=(temp>>8)&(0x0FF);
+
+
+ //NEWSYM SPCDivEnd, dd 0 4826-7
+ fread(&temp, 1,4,fs);
+ s7r.reg4826=temp&(0x0FF);
+ s7r.reg4827=(temp>>8)&(0x0FF);
+
+ //NEWSYM SPCMulRes, dd 0 4828-B
+ fread(&temp, 1, 4, fs);
+
+ s7r.reg4828=temp&(0x0FF);
+ s7r.reg4829=(temp>>8)&(0x0FF);
+ s7r.reg482A=(temp>>16)&(0x0FF);
+ s7r.reg482B=(temp>>24)&(0x0FF);
+
+ //NEWSYM SPCDivRes, dd 0 482C-D
+ fread(&temp, 1,4,fs);
+ s7r.reg482C=temp&(0x0FF);
+ s7r.reg482D=(temp>>8)&(0x0FF);
+
+ //NEWSYM SPC7110BankA, dd 020100h 4831-3
+ fread(&temp, 1, 4, fs);
+
+ s7r.reg4831=temp&(0x0FF);
+ s7r.reg4832=(temp>>8)&(0x0FF);
+ s7r.reg4833=(temp>>16)&(0x0FF);
+
+ //NEWSYM SPC7110RTCStat, dd 0 4840,init,command, index
+ fread(&temp, 1, 4, fs);
+
+ s7r.reg4840=temp&(0x0FF);
+
+//NEWSYM SPC7110RTC, db 00,00,00,00,00,00,01,00,01,00,00,00,00,00,0Fh,00
+fread(&temp, 1, 4, fs);
+if(Settings.SPC7110RTC)
+{
+ rtc_f9.reg[0]=temp&(0x0FF);
+ rtc_f9.reg[1]=(temp>>8)&(0x0FF);
+ rtc_f9.reg[2]=(temp>>16)&(0x0FF);
+ rtc_f9.reg[3]=(temp>>24)&(0x0FF);
+}
+fread(&temp, 1, 4, fs);
+if(Settings.SPC7110RTC)
+{
+ rtc_f9.reg[4]=temp&(0x0FF);
+ rtc_f9.reg[5]=(temp>>8)&(0x0FF);
+ rtc_f9.reg[6]=(temp>>16)&(0x0FF);
+ rtc_f9.reg[7]=(temp>>24)&(0x0FF);
+}
+fread(&temp, 1, 4, fs);
+if(Settings.SPC7110RTC)
+{
+ rtc_f9.reg[8]=temp&(0x0FF);
+ rtc_f9.reg[9]=(temp>>8)&(0x0FF);
+ rtc_f9.reg[10]=(temp>>16)&(0x0FF);
+ rtc_f9.reg[11]=(temp>>24)&(0x0FF);
+}
+fread(&temp, 1, 4, fs);
+if(Settings.SPC7110RTC)
+{
+ rtc_f9.reg[12]=temp&(0x0FF);
+ rtc_f9.reg[13]=(temp>>8)&(0x0FF);
+ rtc_f9.reg[14]=(temp>>16)&(0x0FF);
+ rtc_f9.reg[15]=(temp>>24)&(0x0FF);
+}
+//NEWSYM SPC7110RTCB, db 00,00,00,00,00,00,01,00,01,00,00,00,00,01,0Fh,06
+fread(&temp, 1, 4, fs);
+fread(&temp, 1, 4, fs);
+fread(&temp, 1, 4, fs);
+fread(&temp, 1, 4, fs);
+
+//NEWSYM SPCROMPtr, dd 0 4811-4813
+ fread(&temp, 1, 4, fs);
+
+ s7r.reg4811=temp&(0x0FF);
+ s7r.reg4812=(temp>>8)&(0x0FF);
+ s7r.reg4813=(temp>>16)&(0x0FF);
+//NEWSYM SPCROMtoI, dd SPCROMPtr
+ fread(&temp, 1, 4, fs);
+//NEWSYM SPCROMAdj, dd 0 4814-5
+ fread(&temp, 1, 4, fs);
+ s7r.reg4814=temp&(0x0FF);
+ s7r.reg4815=(temp>>8)&(0x0FF);
+//NEWSYM SPCROMInc, dd 0 4816-7
+ fread(&temp, 1, 4, fs);
+ s7r.reg4816=temp&(0x0FF);
+ s7r.reg4817=(temp>>8)&(0x0FF);
+//NEWSYM SPCROMCom, dd 0 4818
+fread(&temp, 1, 4, fs);
+
+ s7r.reg4818=temp&(0x0FF);
+//NEWSYM SPCCompPtr, dd 0 4801-4804 (+b50i) if"manual"
+ fread(&temp, 1, 4, fs);
+
+ //do table check
+
+ s7r.reg4801=temp&(0x0FF);
+ s7r.reg4802=(temp>>8)&(0x0FF);
+ s7r.reg4803=(temp>>16)&(0x0FF);
+ s7r.reg4804=(temp>>24)&(0x0FF);
+///NEWSYM SPCDecmPtr, dd 0 4805-6 +b50i
+ fread(&temp, 1, 4, fs);
+ s7r.reg4805=temp&(0x0FF);
+ s7r.reg4806=(temp>>8)&(0x0FF);
+//NEWSYM SPCCompCounter, dd 0 4809-A
+ fread(&temp, 1, 4, fs);
+ s7r.reg4809=temp&(0x0FF);
+ s7r.reg480A=(temp>>8)&(0x0FF);
+//NEWSYM SPCCompCommand, dd 0 480B
+fread(&temp, 1, 4, fs);
+
+ s7r.reg480B=temp&(0x0FF);
+//NEWSYM SPCCheckFix, dd 0 written(if 1, then set writtne to max value!)
+fread(&temp, 1, 4, fs);
+(temp&(0x0FF))?s7r.written=0x1F:s7r.written=0x00;
+//NEWSYM SPCSignedVal, dd 0 482E
+fread(&temp, 1, 4, fs);
+
+ s7r.reg482E=temp&(0x0FF);
+
+ }
+ fclose (fs);
+
+ Memory.FixROMSpeed ();
+ IPPU.ColorsChanged = TRUE;
+ IPPU.OBJChanged = TRUE;
+ CPU.InDMA = FALSE;
+ S9xFixColourBrightness ();
+ IPPU.RenderThisFrame = FALSE;
+
+ S9xFixSoundAfterSnapshotLoad ();
+ ICPU.ShiftedPB = Registers.PB << 16;
+ ICPU.ShiftedDB = Registers.DB << 16;
+ S9xSetPCBase (ICPU.ShiftedPB + Registers.PC);
+ S9xUnpackStatus ();
+ S9xFixCycles ();
+ S9xReschedule ();
+#ifdef ZSNES_FX
+ if (Settings.SuperFX)
+ S9xSuperFXPostLoadState ();
+#endif
+ return (TRUE);
+ }
+ fclose (fs);
+ return (FALSE);
+}
+
diff --git a/source/snapshot.h b/source/snapshot.h
new file mode 100644
index 0000000..1843bfe
--- /dev/null
+++ b/source/snapshot.h
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _SNAPSHOT_H_
+#define _SNAPSHOT_H_
+
+#include <stdio.h>
+#include "snes9x.h"
+
+#define SNAPSHOT_MAGIC "#!snes9x"
+#define SNAPSHOT_VERSION 1
+
+#define SUCCESS 1
+#define WRONG_FORMAT (-1)
+#define WRONG_VERSION (-2)
+#define FILE_NOT_FOUND (-3)
+#define WRONG_MOVIE_SNAPSHOT (-4)
+#define NOT_A_MOVIE_SNAPSHOT (-5)
+
+START_EXTERN_C
+bool8 S9xFreezeGame (const char *filename);
+bool8 S9xUnfreezeGame (const char *filename);
+bool8 Snapshot (const char *filename);
+bool8 S9xLoadSnapshot (const char *filename);
+bool8 S9xSPCDump (const char *filename);
+void S9xFreezeToStream (STREAM);
+int S9xUnfreezeFromStream (STREAM);
+END_EXTERN_C
+
+#endif
+
diff --git a/source/snes9x.cpp b/source/snes9x.cpp
new file mode 100644
index 0000000..fd0ee0e
--- /dev/null
+++ b/source/snes9x.cpp
@@ -0,0 +1,808 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "snes9x.h"
+#include "memmap.h"
+#include "display.h"
+#include "cheats.h"
+
+#ifdef DEBUGGER
+extern FILE *trace;
+#endif
+
+void S9xUsage ()
+{
+ S9xMessage (S9X_INFO, S9X_USAGE, "snes9x: S9xUsage: snes9x <options> <rom image filename>\n\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "Where <options> can be:\n");
+
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-cycles or -h <num> Percentage of CPU cycles to execute every scan line (default 90)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-frameskip or -f <num> Screen update frame skip rate (default 2)\n");
+ S9xExtraUsage ();
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-hirom or -fh or -hr Force Hi-ROM memory map, useful for hacked ROM images.\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-lorom or -fl or -lr Force Lo-ROM memory map, useful for hacked ROM images.\n");
+ //FIXME: -old bsolete?
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-old or -o Enable old-style SNES joypad emulation\n");
+ //FIXME: -noold obsolete?
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-noold or -no Disbale old-style SNES joypad emulation\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-soundskip or -ss <num> Sound CPU skip-waiting method, 0 - 3 (default 0)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-sound or -s Enable digital sound output (default: enabled)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nosound or -ns Disable digital sound output\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-soundquality or -r <num> Sound sample playback rate/quality, 0-7 (default 4)\n");
+
+#ifdef __sgi
+/* BS: changed the sample rate values to match the IRIX options */
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+ 0 - off, 1 - 8192, 2 - 11025, 3 - 16000,\n\
+ 4 - 22050 (default), 5 - 32000, 6 - 44100,\n\
+ 7 - 48000\n");
+#else
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+ 0 - off, 1 - 8192, 2 - 11025, 3 - 16500,\n\
+ 4 - 22050 (default), 5 - 29300, 6 - 36600,\n\
+ 7 - 44000\n");
+#endif
+
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-stereo Enable stereo sound (default: mono sound)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-mono Enable mono sound (default: mono sound)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-buffersize or -B Sound playback buffer size (default auto for playback rate)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nospeedhacks or -N Disable some internal speed ups that break a few ROMs\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-speedhacks or -SH Enable some internal speed ups that break a few ROMs\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-loadsnapshot or -l <filename>\n\
+ Load saved game position snapshot file & required ROM\n\
+ image.\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-swapjoypads or -s Swap joypad 1 and 2 around\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-pal or -p Fool ROM into thinking that this is a PAL SNES system\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-ntsc or -n Fool ROM into thinking that this is a NTCS SNES system\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-interleaved or -i ROM image is in interleaved format.\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-interleaved2 or -i2 ROM image is in interleaved 2 format\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-interleavedgd24 or -gd24 ROM image is in Game Doctor 24 Mbit format\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nohdma or -H Disable H-DMA emulation (default: enabled)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-hdma or -NH Enable H-DMA emulation (default: enabled)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-layering or -L Swap some background priority levels - helps some games\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-graphicwindows Enable graphic window effects (default: enabled)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nographicwindows or -nw Disable graphic window effects (default: enabled)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nopatch Disable IPS autopatching\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nocheat Disable the cheat system\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-cheat Enables the cheat system\n");
+#ifdef DEBUGGER
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-noirq or -I Disable processor IRQ (for debugging)\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-debug or -d Enter debug mode once ROM has loaded\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-trace or -t Trace CPU instructions to file (WARNING: file gets very large!)\n");
+#endif
+
+#ifdef JOYSTICK_SUPPORT
+#ifdef __linux
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-joydevX /dev/jsY Use joystick device /dev/jsY for emulation of gamepad X\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-joymapX 0 1 2 3 4 5 6 7 Joystick buttons which should be assigned to gamepad X - A B X Y TL TR Start and Select\n");
+#else
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-four or -4 Single standard PC joystick has four buttons\n");
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-six or -6 Single standard PC joystick has six buttons\n");
+#endif
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+-nojoy or -j Disable joystick support\n");
+#endif
+
+ S9xMessage (S9X_INFO, S9X_USAGE, "\
+\nROM image needs to be in Super MagiCom (*.smc), Super FamiCom (*.sfc),\n\
+*.fig, or split (*.1, *.2, or sf32527a, sf32527b, etc) format and can be\n\
+compressed with gzip or compress.\n");
+
+ exit (1);
+}
+
+#ifdef STORM
+extern int dofps;
+extern int hicolor;
+extern int secondjoy;
+extern int minimal;
+int prelude=0;
+extern int unit;
+#endif
+
+char *S9xParseArgs (char **argv, int argc)
+{
+ char *rom_filename = NULL;
+
+ for (int i = 1; i < argc; i++)
+ {
+ if (*argv[i] == '-')
+ {
+ if (strcasecmp (argv [i], "--selftest") == 0)
+ {
+ // FIXME: Probable missuse of S9X_USAGE
+ // FIXME: Actual tests. But at least this checks for coredumps.
+ S9xMessage (S9X_INFO, S9X_USAGE, "Running selftest ...");
+ S9xMessage (S9X_INFO, S9X_USAGE, "snes9x started:\t[OK]");
+ S9xMessage (S9X_INFO, S9X_USAGE, "All tests ok.");
+ exit(0);
+ }
+ if (strcasecmp (argv [i], "-so") == 0 ||
+ strcasecmp (argv [i], "-sound") == 0)
+ {
+ Settings.NextAPUEnabled = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-ns") == 0 ||
+ strcasecmp (argv [i], "-nosound") == 0)
+ {
+ Settings.NextAPUEnabled = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-soundskip") == 0 ||
+ strcasecmp (argv [i], "-sk") == 0)
+ {
+ if (i + 1 < argc)
+ Settings.SoundSkipMethod = atoi (argv [++i]);
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-ra") == 0 ||
+ strcasecmp (argv [i], "-ratio") == 0)
+ {
+ if ((i + 1) < argc)
+ {
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-h") == 0 ||
+ strcasecmp (argv [i], "-cycles") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ int p = atoi (argv [++i]);
+ if (p > 0 && p < 200)
+ Settings.CyclesPercentage = p;
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-nh") == 0 ||
+ strcasecmp (argv [i], "-nohdma") == 0)
+ {
+ Settings.DisableHDMA = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-ha") == 0 ||
+ strcasecmp (argv [i], "-hdma") == 0)
+ {
+ Settings.DisableHDMA = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-n") == 0 ||
+ strcasecmp (argv [i], "-nospeedhacks") == 0)
+ {
+ Settings.ShutdownMaster = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-sh") == 0 ||
+ strcasecmp (argv [i], "-speedhacks") == 0)
+ {
+ Settings.ShutdownMaster = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-p") == 0 ||
+ strcasecmp (argv [i], "-pal") == 0)
+ {
+ Settings.ForcePAL = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-n") == 0 ||
+ strcasecmp (argv [i], "-ntsc") == 0)
+ {
+ Settings.ForceNTSC = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-f") == 0 ||
+ strcasecmp (argv [i], "-frameskip") == 0)
+ {
+ if (i + 1 < argc)
+ Settings.SkipFrames = atoi (argv [++i]) + 1;
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-fh") == 0 ||
+ strcasecmp (argv [i], "-hr") == 0 ||
+ strcasecmp (argv [i], "-hirom") == 0)
+ Settings.ForceHiROM = TRUE;
+ else if (strcasecmp (argv [i], "-fl") == 0 ||
+ strcasecmp (argv [i], "-lr") == 0 ||
+ strcasecmp (argv [i], "-lorom") == 0)
+ Settings.ForceLoROM = TRUE;
+ else if (strcasecmp (argv [i], "-hd") == 0 ||
+ strcasecmp (argv [i], "-header") == 0 ||
+ strcasecmp (argv [i], "-he") == 0)
+ {
+ Settings.ForceHeader = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-nhd") == 0 ||
+ strcasecmp (argv [i], "-noheader") == 0)
+ {
+ Settings.ForceNoHeader = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-bs") == 0)
+ {
+ Settings.BS = TRUE;
+ }
+#ifdef DEBUGGER
+ else if (strcasecmp (argv [i], "-d") == 0 ||
+ strcasecmp (argv [i], "-debug") == 0)
+ {
+ CPU.Flags |= DEBUG_MODE_FLAG;
+ }
+ else if (strcasecmp (argv [i], "-t") == 0 ||
+ strcasecmp (argv [i], "-trace") == 0)
+ {
+ trace = fopen ("trace.log", "wb");
+ CPU.Flags |= TRACE_FLAG;
+ }
+#endif
+ else if (strcasecmp (argv [i], "-L") == 0 ||
+ strcasecmp (argv [i], "-layering") == 0)
+ Settings.BGLayering = TRUE;
+ else if (strcasecmp (argv [i], "-nl") == 0 ||
+ strcasecmp (argv [i], "-nolayering") == 0)
+ Settings.BGLayering = FALSE;
+ else if (strcasecmp (argv [i], "-O") == 0 ||
+ strcasecmp (argv [i], "-tileredraw") == 0)
+ {
+ }
+ else if (strcasecmp (argv [i], "-no") == 0 ||
+ strcasecmp (argv [i], "-lineredraw") == 0)
+ {
+ }
+ else if (strcasecmp (argv [i], "-tr") == 0 ||
+ strcasecmp (argv [i], "-transparency") == 0)
+ {
+ Settings.ForceTransparency = TRUE;
+ Settings.ForceNoTransparency = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-nt") == 0 ||
+ strcasecmp (argv [i], "-notransparency") == 0)
+ {
+ Settings.ForceNoTransparency = TRUE;
+ Settings.ForceTransparency = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-hi") == 0 ||
+ strcasecmp (argv [i], "-hires") == 0)
+ {
+ Settings.SupportHiRes = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-16") == 0 ||
+ strcasecmp (argv [i], "-sixteen") == 0)
+ {
+ Settings.SixteenBit = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-displayframerate") == 0 ||
+ strcasecmp (argv [i], "-dfr") == 0)
+ {
+ Settings.DisplayFrameRate = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-s") == 0 ||
+ strcasecmp (argv [i], "-swapjoypads") == 0 ||
+ strcasecmp (argv [i], "-sw") == 0)
+ Settings.SwapJoypads = TRUE;
+ else if (strcasecmp (argv [i], "-i") == 0 ||
+ strcasecmp (argv [i], "-interleaved") == 0)
+ Settings.ForceInterleaved = TRUE;
+ else if (strcasecmp (argv [i], "-i2") == 0 ||
+ strcasecmp (argv [i], "-interleaved2") == 0)
+ Settings.ForceInterleaved2=TRUE;
+ else if (strcasecmp (argv [i], "-gd24") == 0 ||
+ strcasecmp (argv [i], "-interleavedgd24") == 0)
+ Settings.ForceInterleaveGD24 = TRUE;
+ else if (strcasecmp (argv [i], "-ni") == 0 ||
+ strcasecmp (argv [i], "-nointerleave") == 0)
+ Settings.ForceNotInterleaved = TRUE;
+ else if (strcasecmp (argv [i], "-noirq") == 0)
+ Settings.DisableIRQ = TRUE;
+ else if (strcasecmp (argv [i], "-nw") == 0 ||
+ strcasecmp (argv [i], "-nowindows") == 0)
+ {
+ Settings.DisableGraphicWindows = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-nopatch") == 0)
+ {
+ Settings.NoPatch=TRUE;
+ }
+ else if (strcasecmp (argv [i], "-nocheat") == 0)
+ {
+ Settings.ApplyCheats=FALSE;
+ }
+ else if (strcasecmp (argv [i], "-cheat") == 0)
+ {
+ Settings.ApplyCheats=TRUE;
+ }
+ else if (strcasecmp (argv [i], "-windows") == 0)
+ {
+ Settings.DisableGraphicWindows = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-aidoshm") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ Settings.AIDOShmId = atoi (argv [++i]);
+ fprintf(stderr, "Snes9X running in AIDO mode. shmid: %d\n",
+ Settings.AIDOShmId);
+ } else
+ S9xUsage ();
+ }
+#ifdef DEBUG_MAXCOUNT
+ else if (strcasecmp (argv [i], "-maxcount") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ Settings.MaxCount = atol (argv [++i]);
+ fprintf(stderr, "Running for a maximum of %d loops.\n",
+ Settings.MaxCount);
+ } else
+ S9xUsage ();
+ }
+#endif
+ else if (strcasecmp (argv [i], "-im7") == 0)
+ {
+ Settings.Mode7Interpolate = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-gg") == 0 ||
+ strcasecmp (argv [i], "-gamegenie") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ uint32 address;
+ uint8 byte;
+ const char *error;
+ if ((error = S9xGameGenieToRaw (argv [++i], address, byte)) == NULL)
+ S9xAddCheat (TRUE, FALSE, address, byte);
+ else
+ S9xMessage (S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR,
+ error);
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-ar") == 0 ||
+ strcasecmp (argv [i], "-actionreplay") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ uint32 address;
+ uint8 byte;
+ const char *error;
+ if ((error = S9xProActionReplayToRaw (argv [++i], address, byte)) == NULL)
+ S9xAddCheat (TRUE, FALSE, address, byte);
+ else
+ S9xMessage (S9X_ERROR, S9X_ACTION_REPLY_CODE_ERROR,
+ error);
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-gf") == 0 ||
+ strcasecmp (argv [i], "-goldfinger") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ uint32 address;
+ uint8 bytes [3];
+ bool8 sram;
+ uint8 num_bytes;
+ const char *error;
+ if ((error = S9xGoldFingerToRaw (argv [++i], address, sram,
+ num_bytes, bytes)) == NULL)
+ {
+ for (int c = 0; c < num_bytes; c++)
+ S9xAddCheat (TRUE, FALSE, address + c, bytes [c]);
+ }
+ else
+ S9xMessage (S9X_ERROR, S9X_GOLD_FINGER_CODE_ERROR,
+ error);
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv[i], "-ft") == 0 ||
+ strcasecmp (argv [i], "-frametime") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ double ft;
+ if (sscanf (argv [++i], "%lf", &ft) == 1)
+ {
+#ifdef __WIN32__
+ Settings.FrameTimePAL = (int32) (ft * 1000);
+ Settings.FrameTimeNTSC = (int32) (ft * 1000);
+#else
+ Settings.FrameTimePAL = (int32) ft;
+ Settings.FrameTimeNTSC = (int32) ft;
+#endif
+
+ }
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-e") == 0 ||
+ strcasecmp (argv [i], "-echo") == 0)
+ Settings.DisableSoundEcho = FALSE;
+ else if (strcasecmp (argv [i], "-ne") == 0 ||
+ strcasecmp (argv [i], "-noecho") == 0)
+ Settings.DisableSoundEcho = TRUE;
+ else if (strcasecmp (argv [i], "-r") == 0 ||
+ strcasecmp (argv [i], "-soundquality") == 0 ||
+ strcasecmp (argv [i], "-sq") == 0)
+ {
+ if (i + 1 < argc)
+ Settings.SoundPlaybackRate = atoi (argv [++i]) & 7;
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-stereo") == 0 ||
+ strcasecmp (argv [i], "-st") == 0)
+ {
+ Settings.Stereo = TRUE;
+ Settings.APUEnabled = TRUE;
+ Settings.NextAPUEnabled = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-mono") == 0)
+ {
+ Settings.Stereo = FALSE;
+ Settings.NextAPUEnabled = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-envx") == 0 ||
+ strcasecmp (argv [i], "-ex") == 0)
+ {
+ Settings.SoundEnvelopeHeightReading = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-nosamplecaching") == 0 ||
+ strcasecmp (argv [i], "-nsc") == 0 ||
+ strcasecmp (argv [i], "-nc") == 0)
+ {
+ Settings.DisableSampleCaching = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-nomastervolume") == 0 ||
+ strcasecmp (argv [i], "-nmv") == 0)
+ {
+ Settings.DisableMasterVolume = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-soundsync") == 0 ||
+ strcasecmp (argv [i], "-sy") == 0)
+ {
+ Settings.SoundSync = TRUE;
+ Settings.SoundEnvelopeHeightReading = TRUE;
+ Settings.InterpolatedSound = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-soundsync2") == 0 ||
+ strcasecmp (argv [i], "-sy2") == 0)
+ {
+ Settings.SoundSync = 2;
+ Settings.SoundEnvelopeHeightReading = TRUE;
+ Settings.InterpolatedSound = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-interpolatedsound") == 0 ||
+ strcasecmp (argv [i], "-is") == 0)
+ {
+ Settings.InterpolatedSound = TRUE;
+ }
+#ifdef USE_THREADS
+ else if (strcasecmp (argv [i], "-threadsound") == 0 ||
+ strcasecmp (argv [i], "-ts") == 0)
+ {
+ Settings.ThreadSound = TRUE;
+ }
+#endif
+ else if (strcasecmp (argv [i], "-alt") == 0 ||
+ strcasecmp (argv [i], "-altsampledecode") == 0)
+ {
+ Settings.AltSampleDecode = 1;
+ }
+ else if (strcasecmp (argv [i], "-fix") == 0)
+ {
+ Settings.FixFrequency = 1;
+ }
+ else if (strcasecmp (argv [i], "-nosuperfx") == 0 ||
+ strcasecmp (argv [i], "-nosfx") == 0)
+ Settings.ForceNoSuperFX = TRUE;
+ else if (strcasecmp (argv [i], "-superfx") == 0 ||
+ strcasecmp (argv [i], "-sfx") == 0)
+ Settings.ForceSuperFX = TRUE;
+ else if (strcasecmp (argv [i], "-dsp1") == 0)
+ Settings.ForceDSP1 = TRUE;
+ else if (strcasecmp (argv [i], "-nodsp1") == 0)
+ Settings.ForceNoDSP1 = TRUE;
+ else if (strcasecmp (argv [i], "-nomultiplayer5") == 0 ||
+ strcasecmp (argv [i], "-nmp") == 0)
+ Settings.MultiPlayer5 = FALSE;
+ else if (strcasecmp (argv [i], "-multiplayer5") == 0 ||
+ strcasecmp (argv [i], "-mp") == 0)
+ {
+ Settings.MultiPlayer5 = TRUE;
+ Settings.ControllerOption = SNES_MULTIPLAYER5;
+ }
+ else if (strcasecmp (argv [i], "-mouse") == 0 ||
+ strcasecmp (argv [i], "-mo") == 0)
+ {
+ Settings.ControllerOption = SNES_MOUSE_SWAPPED;
+ Settings.Mouse = TRUE;
+ }
+ else if (strcasecmp (argv [i], "-nomouse") == 0 ||
+ strcasecmp (argv [i], "-nm") == 0)
+ {
+ Settings.Mouse = FALSE;
+ }
+ else if (strcasecmp (argv [i], "-superscope") == 0 ||
+ strcasecmp (argv [i], "-ss") == 0)
+ {
+ Settings.SuperScope = TRUE;
+ Settings.ControllerOption = SNES_SUPERSCOPE;
+ }
+ else if (strcasecmp (argv [i], "-nosuperscope") == 0 ||
+ strcasecmp (argv [i], "-nss") == 0)
+ {
+ Settings.SuperScope = FALSE;
+ }
+#ifdef NETPLAY_SUPPORT
+ else if (strcasecmp (argv [i], "-port") == 0 ||
+ strcasecmp (argv [i], "-po") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ Settings.NetPlay = TRUE;
+ Settings.Port = -atoi (argv [++i]);
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-server") == 0 ||
+ strcasecmp (argv [i], "-srv") == 0)
+ {
+ if (i + 1 < argc)
+ {
+ Settings.NetPlay = TRUE;
+ strncpy (Settings.ServerName, argv [++i], 127);
+ Settings.ServerName [127] = 0;
+ }
+ else
+ S9xUsage ();
+ }
+ else if (strcasecmp (argv [i], "-net") == 0)
+ {
+ Settings.NetPlay = TRUE;
+ }
+#endif
+#ifdef STORM
+ else if (strcasecmp(argv[i],"-nosecondjoy")==0){secondjoy=0;}
+ else if (strcasecmp(argv[i],"-showfps")==0){dofps=1;}
+ else if (strcasecmp(argv[i],"-hicolor")==0){hicolor=1;}
+ else if (strcasecmp(argv[i],"-minimal")==0){minimal=1;printf("Keyboard with exception of ESC switched off!\n");}
+ else if (strcasecmp(argv[i],"-ahiunit")==0)
+ {
+ if (i+1<argc)
+ {
+ fprintf(stderr,"AHI Unit set to: Unit %i\n",atoi(argv[++i]));
+ unit=atoi(argv[++i]);
+ }
+ }
+#endif
+
+ else
+ S9xParseArg (argv, i, argc);
+ }
+ else
+ rom_filename = argv [i];
+ }
+
+ return (rom_filename);
+}
+
+#if 0
+//static char* fgets(char *buffer, int num, FILE *stream)
+char* fgets(char *buffer, int num, FILE *stream)
+{
+ int m;
+ char *s;
+
+// printf("In fgets\n");
+
+ if(num <= 0)
+ return (NULL);
+
+ num--;
+ m= fread(buffer, 1, num, stream);
+ *(buffer +m) = '\0';
+
+// printf("fread= %s\n", buffer);
+
+ if(m == 0)
+ return (NULL);
+
+ s = strchr(buffer, '\n');
+
+ if(m < num) //at the end of file
+ {
+ if(s == NULL)
+ return (buffer);
+
+ *(++s)= '\0'; //string include '\n'
+ m -= s - buffer;
+ fseek(stream, -m, SEEK_CUR);//fix fread pointer
+ return (buffer);
+ }
+ else
+ {
+ if(s)
+ {
+ *(++s)= '\0'; //string include '\n'
+ m -= s - buffer;
+ fseek(stream, -m, SEEK_CUR);//fix fread pointer
+ }
+
+ return (buffer);
+ }
+}
+#endif
+
+void S9xParseCheatsFile (const char *rom_filename)
+{
+ FILE *f;
+ char dir [_MAX_DIR];
+ char drive [_MAX_DRIVE];
+ char name [_MAX_FNAME];
+ char ext [_MAX_EXT];
+ char fname [_MAX_PATH];
+ char buf [80];
+ uint32 address;
+ uint8 byte;
+ uint8 bytes [3];
+ bool8 sram;
+ uint8 num_bytes;
+ const char *error;
+ char *p;
+
+ _splitpath (rom_filename, drive, dir, name, ext);
+ _makepath (fname, drive, dir, name, "pat");
+
+ if ((f = fopen(fname, "r")) != NULL)
+ {
+ while(fgets(buf, 80, f) != NULL)
+ {
+ if ((p = strrchr (buf, '\n')) != NULL)
+ *p = '\0';
+ if (((error = S9xGameGenieToRaw (buf, address, byte)) == NULL) ||
+ ((error = S9xProActionReplayToRaw (buf, address, byte)) == NULL))
+ {
+ S9xAddCheat (TRUE, FALSE, address, byte);
+ }
+ else
+ if ((error = S9xGoldFingerToRaw (buf, address, sram,
+ num_bytes, bytes)) == NULL)
+ {
+ for (int c = 0; c < num_bytes; c++)
+ S9xAddCheat (TRUE, FALSE, address + c, bytes [c]);
+ }
+ else
+ S9xMessage (S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, error);
+ }
+ fclose(f);
+ }
+}
+
diff --git a/source/snes9x.h b/source/snes9x.h
new file mode 100644
index 0000000..61281aa
--- /dev/null
+++ b/source/snes9x.h
@@ -0,0 +1,431 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _SNES9X_H_
+#define _SNES9X_H_
+
+#define VERSION "1.43-dev"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "fs_api.h"
+#include "ds2_malloc.h"
+
+extern "C" {
+extern int cprintf(const char *fmt, ...);
+}
+
+#ifdef __WIN32__
+#include "..\wsnes9x.h"
+#include "..\zlib\zlib.h"
+#endif
+
+#include "language.h"
+
+#include "port.h"
+#include "65c816.h"
+#include "messages.h"
+
+#define ROM_NAME_LEN 23
+
+#ifdef ZLIB
+#ifndef __WIN32__
+#include "zlib.h"
+#endif
+#define STREAM gzFile
+#define READ_STREAM(p,l,s) gzread (s,p,l)
+#define WRITE_STREAM(p,l,s) gzwrite (s,p,l)
+#define OPEN_STREAM(f,m) gzopen (f,m)
+#define REOPEN_STREAM(f,m) gzdopen (f,m)
+#define FIND_STREAM(f) gztell(f)
+#define REVERT_STREAM(f,o,s) gzseek(f,o,s)
+#define CLOSE_STREAM(s) gzclose (s)
+#else
+#define STREAM FILE*
+#define READ_STREAM(p,l,s) fread (p,1,l,s)
+#define WRITE_STREAM(p,l,s) fwrite (p,1,l,s)
+#define OPEN_STREAM(f,m) fopen (f,m)
+#define REOPEN_STREAM(f,m) fdopen (f,m)
+#define FIND_STREAM(f) ftell(f)
+#define REVERT_STREAM(f,o,s) fseek(f,o,s)
+#define CLOSE_STREAM(s) fclose (s)
+#endif
+
+
+/* SNES screen width and height */
+#define SNES_WIDTH 256
+#define SNES_HEIGHT 224
+#define SNES_HEIGHT_EXTENDED 239
+#define IMAGE_WIDTH (Settings.SupportHiRes ? SNES_WIDTH * 2 : SNES_WIDTH)
+#define IMAGE_HEIGHT (Settings.SupportHiRes ? SNES_HEIGHT_EXTENDED * 2 : SNES_HEIGHT_EXTENDED)
+
+#define SNES_MAX_NTSC_VCOUNTER 262
+#define SNES_MAX_PAL_VCOUNTER 312
+#define SNES_HCOUNTER_MAX 342
+#define SPC700_TO_65C816_RATIO 2
+#define AUTO_FRAMERATE 200
+
+/* NTSC master clock signal 21.47727MHz
+ * PPU: master clock / 4
+ * 1 / PPU clock * 342 -> 63.695us
+ * 63.695us / (1 / 3.579545MHz) -> 228 cycles per scanline
+ * From Earth Worm Jim: APU executes an average of 65.14285714 cycles per
+ * scanline giving an APU clock speed of 1.022731096MHz */
+
+/* PAL master clock signal 21.28137MHz
+ * PPU: master clock / 4
+ * 1 / PPU clock * 342 -> 64.281us
+ * 64.281us / (1 / 3.546895MHz) -> 228 cycles per scanline. */
+
+#define SNES_SCANLINE_TIME (63.695e-6)
+#define SNES_CLOCK_SPEED (3579545)
+
+#define SNES_CLOCK_LEN (1.0 / SNES_CLOCK_SPEED)
+
+#define SNES_CYCLES_PER_SCANLINE ((uint32) ((SNES_SCANLINE_TIME / SNES_CLOCK_LEN) * 6 + 0.5))
+
+#define ONE_CYCLE 6
+#define SLOW_ONE_CYCLE 8
+#define TWO_CYCLES 12
+
+
+#define SNES_TR_MASK (1 << 4)
+#define SNES_TL_MASK (1 << 5)
+#define SNES_X_MASK (1 << 6)
+#define SNES_A_MASK (1 << 7)
+#define SNES_RIGHT_MASK (1 << 8)
+#define SNES_LEFT_MASK (1 << 9)
+#define SNES_DOWN_MASK (1 << 10)
+#define SNES_UP_MASK (1 << 11)
+#define SNES_START_MASK (1 << 12)
+#define SNES_SELECT_MASK (1 << 13)
+#define SNES_Y_MASK (1 << 14)
+#define SNES_B_MASK (1 << 15)
+
+enum {
+ SNES_MULTIPLAYER5,
+ SNES_JOYPAD,
+ SNES_MOUSE_SWAPPED,
+ SNES_MOUSE,
+ SNES_SUPERSCOPE,
+ SNES_JUSTIFIER,
+ SNES_JUSTIFIER_2,
+ SNES_MAX_CONTROLLER_OPTIONS
+};
+
+#define DEBUG_MODE_FLAG (1 << 0)
+#define TRACE_FLAG (1 << 1)
+#define SINGLE_STEP_FLAG (1 << 2)
+#define BREAK_FLAG (1 << 3)
+#define SCAN_KEYS_FLAG (1 << 4)
+#define SAVE_SNAPSHOT_FLAG (1 << 5)
+#define DELAYED_NMI_FLAG (1 << 6)
+#define NMI_FLAG (1 << 7)
+#define PROCESS_SOUND_FLAG (1 << 8)
+#define FRAME_ADVANCE_FLAG (1 << 9)
+#define DELAYED_NMI_FLAG2 (1 << 10)
+#define IRQ_PENDING_FLAG (1 << 11)
+
+struct SCPUState{
+ uint32 Flags;
+ bool8 BranchSkip;
+ bool8 NMIActive;
+ bool8 IRQActive;
+ bool8 WaitingForInterrupt;
+ bool8 InDMA;
+ uint8 WhichEvent;
+ uint8 *PC;
+ uint8 *PCBase;
+ uint8 *PCAtOpcodeStart;
+ uint8 *WaitAddress;
+ uint32 WaitCounter;
+ long Cycles;
+ long NextEvent;
+ long V_Counter;
+ long MemSpeed;
+ long MemSpeedx2;
+ long FastROMSpeed;
+ uint32 AutoSaveTimer;
+ bool8 SRAMModified;
+ uint32 NMITriggerPoint;
+ bool8 BRKTriggered;
+ bool8 TriedInterleavedMode2;
+ uint32 NMICycleCount;
+ uint32 IRQCycleCount;
+#ifdef DEBUG_MAXCOUNT
+ unsigned long GlobalLoopCount;
+#endif
+};
+
+#define HBLANK_START_EVENT 0
+#define HBLANK_END_EVENT 1
+#define HTIMER_BEFORE_EVENT 2
+#define HTIMER_AFTER_EVENT 3
+#define NO_EVENT 4
+
+struct SSettings{
+ /* CPU options */
+ bool8 APUEnabled;
+ bool8 Shutdown;
+ uint8 SoundSkipMethod;
+ long H_Max;
+ long HBlankStart;
+ long CyclesPercentage;
+ bool8 DisableIRQ;
+ bool8 Paused;
+ bool8 ForcedPause;
+ bool8 StopEmulation;
+ bool8 FrameAdvance;
+
+ /* Tracing options */
+ bool8 TraceDMA;
+ bool8 TraceHDMA;
+ bool8 TraceVRAM;
+ bool8 TraceUnknownRegisters;
+ bool8 TraceDSP;
+
+ /* Joystick options */
+ bool8 SwapJoypads;
+ bool8 JoystickEnabled;
+
+ /* ROM timing options (see also H_Max above) */
+ bool8 ForcePAL;
+ bool8 ForceNTSC;
+ bool8 PAL;
+ uint32 FrameTimePAL;
+ uint32 FrameTimeNTSC;
+ uint32 FrameTime;
+ uint32 SkipFrames;
+
+ /* ROM image options */
+ bool8 ForceLoROM;
+ bool8 ForceHiROM;
+ bool8 ForceHeader;
+ bool8 ForceNoHeader;
+ bool8 ForceInterleaved;
+ bool8 ForceInterleaved2;
+ bool8 ForceNotInterleaved;
+
+ /* Peripherial options */
+ bool8 ForceSuperFX;
+ bool8 ForceNoSuperFX;
+ bool8 ForceDSP1;
+ bool8 ForceNoDSP1;
+ bool8 ForceSA1;
+ bool8 ForceNoSA1;
+ bool8 ForceC4;
+ bool8 ForceNoC4;
+ bool8 ForceSDD1;
+ bool8 ForceNoSDD1;
+ bool8 MultiPlayer5;
+ bool8 Mouse;
+ bool8 SuperScope;
+ bool8 SRTC;
+ uint32 ControllerOption;
+
+ bool8 ShutdownMaster;
+ bool8 MultiPlayer5Master;
+ bool8 SuperScopeMaster;
+ bool8 MouseMaster;
+ bool8 SuperFX;
+ bool8 DSP1Master;
+ bool8 SA1;
+ bool8 C4;
+ bool8 SDD1;
+ bool8 SPC7110;
+ bool8 SPC7110RTC;
+ bool8 OBC1;
+ /* Sound options */
+ uint32 SoundPlaybackRate;
+ bool8 TraceSoundDSP;
+ bool8 Stereo;
+ bool8 ReverseStereo;
+ bool8 SixteenBitSound;
+ int SoundBufferSize;
+ int SoundMixInterval;
+ bool8 SoundEnvelopeHeightReading;
+ bool8 DisableSoundEcho;
+ bool8 DisableSampleCaching;
+ bool8 DisableMasterVolume;
+ bool8 SoundSync;
+ bool8 InterpolatedSound;
+ bool8 ThreadSound;
+ bool8 Mute;
+ bool8 NextAPUEnabled;
+ uint8 AltSampleDecode;
+ bool8 FixFrequency;
+
+ /* Graphics options */
+ bool8 SixteenBit;
+ bool8 Transparency;
+ bool8 SupportHiRes;
+ bool8 Mode7Interpolate;
+
+ /* SNES graphics options */
+ bool8 BGLayering;
+ bool8 DisableGraphicWindows;
+ bool8 ForceTransparency;
+ bool8 ForceNoTransparency;
+ bool8 DisableHDMA;
+ bool8 DisplayFrameRate;
+ bool8 DisableRangeTimeOver; /* XXX: unused */
+
+ /* Others */
+ bool8 NetPlay;
+ bool8 NetPlayServer;
+ char ServerName [128];
+ int Port;
+ bool8 GlideEnable;
+ bool8 OpenGLEnable;
+ int32 AutoSaveDelay; /* Time in seconds before S-RAM auto-saved if modified. */
+ bool8 ApplyCheats;
+ bool8 TurboMode;
+ uint32 TurboSkipFrames;
+ uint32 AutoMaxSkipFrames;
+
+/* Fixes for individual games */
+ bool8 StarfoxHack;
+ bool8 WinterGold;
+ bool8 BS; /* Japanese Satellite System games. */
+ bool8 DaffyDuck;
+ uint8 APURAMInitialValue;
+ bool8 SampleCatchup;
+ bool8 JustifierMaster;
+ bool8 Justifier;
+ bool8 SecondJustifier;
+ int8 SETA;
+ bool8 TakeScreenshot;
+ int8 StretchScreenshots;
+ uint16 DisplayColor;
+ int SoundDriver;
+ int AIDOShmId;
+ bool8 SDD1Pack;
+ bool8 NoPatch;
+ bool8 ForceInterleaveGD24;
+#ifdef DEBUG_MAXCOUNT
+ unsigned int MaxCount;
+#endif
+};
+
+struct SSNESGameFixes
+{
+ uint8 alienVSpredetorFix;
+ uint8 APU_OutPorts_ReturnValueFix;
+ uint8 SoundEnvelopeHeightReading2;
+ uint8 SRAMInitialValue;
+ uint8 Uniracers;
+ bool8 EchoOnlyOutput;
+};
+
+START_EXTERN_C
+extern struct SSettings Settings;
+extern struct SCPUState CPU;
+extern struct SSNESGameFixes SNESGameFixes;
+extern char String [513];
+
+void S9xExit ();
+void S9xMessage (int type, int number, const char *message);
+void S9xLoadSDD1Data ();
+END_EXTERN_C
+
+enum {
+ PAUSE_NETPLAY_CONNECT = (1 << 0),
+ PAUSE_TOGGLE_FULL_SCREEN = (1 << 1),
+ PAUSE_EXIT = (1 << 2),
+ PAUSE_MENU = (1 << 3),
+ PAUSE_INACTIVE_WINDOW = (1 << 4),
+ PAUSE_WINDOW_ICONISED = (1 << 5),
+ PAUSE_RESTORE_GUI = (1 << 6),
+ PAUSE_FREEZE_FILE = (1 << 7)
+};
+void S9xSetPause (uint32 mask);
+void S9xClearPause (uint32 mask);
+
+#endif
+
diff --git a/source/sound.cpp b/source/sound.cpp
new file mode 100644
index 0000000..e69a1fb
--- /dev/null
+++ b/source/sound.cpp
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <devices/ahi.h>
+#include <exec/exec.h>
+#include <proto/ahi.h>
+#include <proto/dos.h>
+#include <proto/exec.h>
+#include <clib/ahippc_protos.h>
+#include <stdio.h>
+
+#define EQ ==
+#define MINBUFFLEN 10000
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "snes9x.h"
+#include "soundux.h"
+
+extern SoundStatus so;
+
+extern int AudioOpen(unsigned long freq, unsigned long bufsize, unsigned long bitrate, unsigned long stereo);
+extern void AudioClose(void);
+
+extern int OpenPrelude(ULONG Type, ULONG DefaultFreq, ULONG MinBuffSize);
+extern void ClosePrelude(void);
+
+extern int SoundSignal;
+unsigned long DoubleBuffer;
+//extern struct AHISampleInfo Sample0;
+//extern struct AHISampleInfo Sample1;
+//extern unsigned long BufferSize;
+
+struct Library *AHIPPCBase;
+struct Library *AHIBase;
+struct MsgPort *AHImp=NULL;
+struct AHIRequest *AHIio=NULL;
+BYTE AHIDevice=-1;
+
+struct AHIData *AHIData;
+
+unsigned long Frequency = 0;
+//unsigned long BufferSize = 0;
+unsigned long BitRate = 0;
+unsigned long Stereo = 0;
+//unsigned long AHIError = 9;
+
+BYTE InternSignal=-1;
+
+int mixsamples;
+extern int prelude;
+
+#define REALSIZE (BitRate*Stereo)
+
+struct AHIAudioModeRequester *req=NULL;
+struct AHIAudioCtrl *actrl=NULL;
+
+ULONG BufferLen=NULL;
+
+
+/* this really should be dynamically allocated... */
+#undef MAX_BUFFER_SIZE
+#define MAX_BUFFER_SIZE 65536
+#define MIN_BUFFER_SIZE 65536
+
+#define MODE_MONO 0
+#define MODE_STEREO 1
+
+#define QUAL_8BIT 8
+#define QUAL_16BIT 16
+
+
+int test=0;
+int test2=0;
+
+int AudioOpen(unsigned long freq, unsigned long minbufsize, unsigned long bitrate, unsigned long stereo)
+{
+ ULONG Type;
+
+ Frequency = freq;
+
+ so.playback_rate = Frequency;
+
+ if(stereo) so.stereo = TRUE;
+ else so.stereo = FALSE;
+
+ switch(bitrate)
+ {
+ case 8:
+ so.sixteen_bit = FALSE;
+ BitRate=1;
+ if(stereo)
+ {
+ Stereo=2;
+ Type = AHIST_S8S;
+ }
+ else
+ {
+ Stereo=1;
+ Type = AHIST_M8S;
+ }
+
+ break;
+
+ default: //defaulting to 16bit, because it means it won't crash atleast
+ case QUAL_16BIT:
+ so.sixteen_bit = TRUE;
+ BitRate=2;
+ if(stereo)
+ {
+ Stereo=2;
+ Type = AHIST_S16S;
+ }
+ else
+ {
+ Stereo=1;
+ Type = AHIST_M16S;
+ }
+ break;
+ }
+
+ if(prelude) prelude = OpenPrelude(Type, freq, minbufsize);
+
+
+ if(prelude) return 1; else printf("Defaulting to AHI...\n");
+
+ /* only 1 channel right? */
+ /* NOTE: The buffersize will not always be what you requested
+ * it finds the minimun AHI requires and then rounds it up to
+ * nearest 32 bytes. Check AHIData->BufferSize or Samples[n].something_Length
+ */
+ if(AHIData = OpenAHI(1, Type, AHI_INVALID_ID, AHI_DEFAULT_FREQ, 0, minbufsize))
+ {
+ printf("AHI opened\n");
+ printf("BuffSize %d\n", AHIData->BufferSize);
+ }
+ else
+ {
+ printf("AHI failed to open: %d\n", AHIData);
+ return 0;
+ }
+
+ so.buffer_size = AHIData->BufferSize; // in bytes
+ if (so.buffer_size > MAX_BUFFER_SIZE) so.buffer_size = MAX_BUFFER_SIZE;
+
+ /* Lots of useful fields in the AHIData struct, have a look */
+ AHIBase = AHIData->AHIBase;
+ actrl = AHIData->AudioCtrl;
+ Frequency = AHIData->MixingFreq;
+
+ printf("signal %ld\n", AHIData->SoundFuncSignal);
+
+ Wait(AHIData->SoundFuncSignal);
+
+ /* I don't think it should start playing until there is something
+ * In the buffer, however to set off the SoundFunc it should
+ * probably go through the buffer at least once, just silently.
+ */
+ AHI_SetFreq(0, Frequency, actrl, AHISF_IMM);
+
+ Wait(AHIData->SoundFuncSignal);
+
+ AHI_SetVol(0, 0x10000, 0x8000, actrl, AHISF_IMM);
+
+ mixsamples=AHIData->BufferSamples;
+
+ SoundSignal = AHIData->SoundFuncSignal;
+
+ return 1;
+}
+
+void AudioClose( void )
+{
+ if(prelude) ClosePrelude();
+ else ;//CloseAHI(AHIData);
+}
+
+
+#include <wbstartup.h>
+
+extern int main(int argc, char **argv);
+
+void wbmain(struct WBStartup * argmsg)
+{
+ char argv[1][]={"WarpSNES"};
+ int argc=1;
+ main(argc,(char **)argv);
+}
+
+
diff --git a/source/soundux.cpp b/source/soundux.cpp
new file mode 100644
index 0000000..b6ff440
--- /dev/null
+++ b/source/soundux.cpp
@@ -0,0 +1,2030 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifdef __DJGPP__
+#include <allegro.h>
+#undef TRUE
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#define CLIP16(v) \
+ if ((v) < -32768) \
+ (v) = -32768; \
+ else \
+ if ((v) > 32767) \
+(v) = 32767
+
+#define CLIP16_latch(v,l) \
+ if ((v) < -32768) \
+{ (v) = -32768; (l)++; }\
+ else \
+ if ((v) > 32767) \
+{ (v) = 32767; (l)++; }
+
+#define CLIP24(v) \
+ if ((v) < -8388608) \
+ (v) = -8388608; \
+ else \
+ if ((v) > 8388607) \
+(v) = 8388607
+
+#define CLIP8(v) \
+ if ((v) < -128) \
+ (v) = -128; \
+ else \
+ if ((v) > 127) \
+(v) = 127
+
+#include "snes9x.h"
+#include "soundux.h"
+#include "apu.h"
+#include "memmap.h"
+#include "cpuexec.h"
+
+extern int Echo [24000];
+extern int DummyEchoBuffer [SOUND_BUFFER_SIZE];
+extern int MixBuffer [SOUND_BUFFER_SIZE];
+extern int EchoBuffer [SOUND_BUFFER_SIZE];
+extern int FilterTaps [8];
+extern unsigned long Z;
+extern int Loop [16];
+
+extern long FilterValues[4][2];
+extern int NoiseFreq [32];
+
+#undef ABS
+#define ABS(a) ((a) < 0 ? -(a) : (a))
+
+#define FIXED_POINT 0x10000UL
+#define FIXED_POINT_REMAINDER 0xffffUL
+#define FIXED_POINT_SHIFT 16
+
+#define VOL_DIV8 0x8000
+#define VOL_DIV16 0x0080
+#define ENVX_SHIFT 24
+
+extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);
+extern "C" void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *);
+
+// F is channel's current frequency and M is the 16-bit modulation waveform
+// from the previous channel multiplied by the current envelope volume level.
+#define PITCH_MOD(F,M) ((F) * ((((unsigned long) (M)) + 0x800000) >> 16) >> 7)
+//#define PITCH_MOD(F,M) ((F) * ((((M) & 0x7fffff) >> 14) + 1) >> 8)
+
+#define LAST_SAMPLE 0xffffff
+#define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)
+
+STATIC inline uint8 *S9xGetSampleAddress (int sample_number)
+{
+ uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff);
+ return (IAPU.RAM + addr);
+}
+
+void S9xAPUSetEndOfSample (int i, Channel *ch)
+{
+ ch->state = SOUND_SILENT;
+ ch->mode = MODE_NONE;
+ APU.DSP [APU_ENDX] |= 1 << i;
+ APU.DSP [APU_KON] &= ~(1 << i);
+ APU.DSP [APU_KOFF] &= ~(1 << i);
+ APU.KeyedChannels &= ~(1 << i);
+}
+#ifdef __DJGPP
+END_OF_FUNCTION (S9xAPUSetEndOfSample)
+#endif
+
+void S9xAPUSetEndX (int ch)
+{
+ APU.DSP [APU_ENDX] |= 1 << ch;
+}
+#ifdef __DJGPP
+END_OF_FUNCTION (S9xAPUSetEndX)
+#endif
+
+void S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target)
+{
+ ch->envx_target = target;
+
+ if (rate == ~0UL)
+ {
+ ch->direction = 0;
+ rate = 0;
+ }
+ else
+ ch->direction = direction;
+
+ static int steps [] =
+ {
+ // 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238
+ 0, 64, 619, 619, 128, 1, 64, 55, 64, 619
+ };
+
+ if (rate == 0 || so.playback_rate == 0)
+ ch->erate = 0;
+ else
+ {
+ ch->erate = (unsigned long)
+ (((int64) FIXED_POINT * 1000 * steps [ch->state]) /
+ (rate * so.playback_rate));
+ }
+}
+
+#ifdef __DJGPP
+END_OF_FUNCTION(S9xSetEnvRate);
+#endif
+
+void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction,
+ int target)
+{
+ S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target);
+}
+
+#ifdef __DJGPP
+END_OF_FUNCTION(S9xSetEnvelopeRate);
+#endif
+
+void S9xSetSoundVolume (int channel, short volume_left, short volume_right)
+{
+ Channel *ch = &SoundData.channels[channel];
+ if (!so.stereo)
+ volume_left = (ABS(volume_right) + ABS(volume_left)) / 2;
+
+ ch->volume_left = volume_left;
+ ch->volume_right = volume_right;
+ ch-> left_vol_level = (ch->envx * volume_left) / 128;
+ ch->right_vol_level = (ch->envx * volume_right) / 128;
+}
+
+void S9xSetMasterVolume (short volume_left, short volume_right)
+{
+ if (Settings.DisableMasterVolume || SNESGameFixes.EchoOnlyOutput)
+ {
+ SoundData.master_volume_left = 127;
+ SoundData.master_volume_right = 127;
+ SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
+ }
+ else
+ {
+ if (!so.stereo)
+ volume_left = (ABS (volume_right) + ABS (volume_left)) / 2;
+ SoundData.master_volume_left = volume_left;
+ SoundData.master_volume_right = volume_right;
+ SoundData.master_volume [Settings.ReverseStereo] = volume_left;
+ SoundData.master_volume [1 ^ Settings.ReverseStereo] = volume_right;
+ }
+}
+
+void S9xSetEchoVolume (short volume_left, short volume_right)
+{
+ if (!so.stereo)
+ volume_left = (ABS (volume_right) + ABS (volume_left)) / 2;
+ SoundData.echo_volume_left = volume_left;
+ SoundData.echo_volume_right = volume_right;
+ SoundData.echo_volume [Settings.ReverseStereo] = volume_left;
+ SoundData.echo_volume [1 ^ Settings.ReverseStereo] = volume_right;
+}
+
+void S9xSetEchoEnable (uint8 byte)
+{
+ SoundData.echo_channel_enable = byte;
+ if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho)
+ byte = 0;
+ if (byte && !SoundData.echo_enable)
+ {
+ memset (Echo, 0, sizeof (Echo));
+ memset (Loop, 0, sizeof (Loop));
+ }
+
+ SoundData.echo_enable = byte;
+ for (int i = 0; i < 8; i++)
+ {
+ if (byte & (1 << i))
+ SoundData.channels [i].echo_buf_ptr = EchoBuffer;
+ else
+ SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer;
+ }
+}
+
+void S9xSetEchoFeedback (int feedback)
+{
+ CLIP8(feedback);
+ SoundData.echo_feedback = feedback;
+}
+
+void S9xSetEchoDelay (int delay)
+{
+ SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000;
+ if (so.stereo)
+ SoundData.echo_buffer_size <<= 1;
+ if (SoundData.echo_buffer_size)
+ SoundData.echo_ptr %= SoundData.echo_buffer_size;
+ else
+ SoundData.echo_ptr = 0;
+ S9xSetEchoEnable (APU.DSP [APU_EON]);
+}
+
+void S9xSetEchoWriteEnable (uint8 byte)
+{
+ SoundData.echo_write_enabled = byte;
+ S9xSetEchoDelay (APU.DSP [APU_EDL] & 15);
+}
+
+void S9xSetFrequencyModulationEnable (uint8 byte)
+{
+ SoundData.pitch_mod = byte & ~1;
+}
+
+void S9xSetSoundKeyOff (int channel)
+{
+ Channel *ch = &SoundData.channels[channel];
+
+ if (ch->state != SOUND_SILENT)
+ {
+ ch->state = SOUND_RELEASE;
+ ch->mode = MODE_RELEASE;
+ S9xSetEnvRate (ch, 8, -1, 0);
+ }
+}
+
+void S9xFixSoundAfterSnapshotLoad ()
+{
+ SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20);
+ SoundData.echo_channel_enable = APU.DSP [APU_EON];
+ S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
+ S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]);
+
+ S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]);
+ S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]);
+ S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]);
+ S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]);
+ S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]);
+ S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]);
+ S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]);
+ S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]);
+ for (int i = 0; i < 8; i++)
+ {
+ SoundData.channels[i].needs_decode = TRUE;
+ S9xSetSoundFrequency (i, SoundData.channels[i].hertz);
+ SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT;
+ SoundData.channels [i].next_sample = 0;
+ SoundData.channels [i].interpolate = 0;
+ SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];
+ SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];
+ }
+ SoundData.master_volume [Settings.ReverseStereo] = SoundData.master_volume_left;
+ SoundData.master_volume [1 ^ Settings.ReverseStereo] = SoundData.master_volume_right;
+ SoundData.echo_volume [Settings.ReverseStereo] = SoundData.echo_volume_left;
+ SoundData.echo_volume [1 ^ Settings.ReverseStereo] = SoundData.echo_volume_right;
+ IAPU.Scanline = 0;
+}
+
+void S9xSetFilterCoefficient (int tap, int value)
+{
+ FilterTaps [tap & 7] = value;
+ SoundData.no_filter = (FilterTaps [0] == 127 || FilterTaps [0] == 0) &&
+ FilterTaps [1] == 0 &&
+ FilterTaps [2] == 0 &&
+ FilterTaps [3] == 0 &&
+ FilterTaps [4] == 0 &&
+ FilterTaps [5] == 0 &&
+ FilterTaps [6] == 0 &&
+ FilterTaps [7] == 0;
+}
+
+void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate,
+ int sustain_rate, int sustain_level, int release_rate)
+{
+ SoundData.channels[channel].attack_rate = attack_rate;
+ SoundData.channels[channel].decay_rate = decay_rate;
+ SoundData.channels[channel].sustain_rate = sustain_rate;
+ SoundData.channels[channel].release_rate = release_rate;
+ SoundData.channels[channel].sustain_level = sustain_level + 1;
+
+ switch (SoundData.channels[channel].state)
+ {
+ case SOUND_ATTACK:
+ S9xSetEnvelopeRate (channel, attack_rate, 1, 127);
+ break;
+
+ case SOUND_DECAY:
+ S9xSetEnvelopeRate (channel, decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3);
+ break;
+ case SOUND_SUSTAIN:
+ S9xSetEnvelopeRate (channel, sustain_rate, -1, 0);
+ break;
+ }
+}
+
+void S9xSetEnvelopeHeight (int channel, int level)
+{
+ Channel *ch = &SoundData.channels[channel];
+
+ ch->envx = level;
+ ch->envxx = level << ENVX_SHIFT;
+
+ ch->left_vol_level = (level * ch->volume_left) / 128;
+ ch->right_vol_level = (level * ch->volume_right) / 128;
+
+ if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)
+ {
+ S9xAPUSetEndOfSample (channel, ch);
+ }
+}
+
+int S9xGetEnvelopeHeight (int channel)
+{
+ if ((Settings.SoundEnvelopeHeightReading ||
+ SNESGameFixes.SoundEnvelopeHeightReading2) &&
+ SoundData.channels[channel].state != SOUND_SILENT &&
+ SoundData.channels[channel].state != SOUND_GAIN)
+ {
+ return (SoundData.channels[channel].envx);
+ }
+
+ //siren fix from XPP
+ if (SNESGameFixes.SoundEnvelopeHeightReading2 &&
+ SoundData.channels[channel].state != SOUND_SILENT)
+ {
+ return (SoundData.channels[channel].envx);
+ }
+
+ return (0);
+}
+
+#if 1
+void S9xSetSoundSample (int, uint16)
+{
+}
+#else
+void S9xSetSoundSample (int channel, uint16 sample_number)
+{
+ register Channel *ch = &SoundData.channels[channel];
+
+ if (ch->state != SOUND_SILENT &&
+ sample_number != ch->sample_number)
+ {
+ int keep = ch->state;
+ ch->state = SOUND_SILENT;
+ ch->sample_number = sample_number;
+ ch->loop = FALSE;
+ ch->needs_decode = TRUE;
+ ch->last_block = FALSE;
+ ch->previous [0] = ch->previous[1] = 0;
+ uint8 *dir = S9xGetSampleAddress (sample_number);
+ ch->block_pointer = READ_WORD (dir);
+ ch->sample_pointer = 0;
+ ch->state = keep;
+ }
+}
+#endif
+
+void S9xSetSoundFrequency (int channel, int hertz)
+{
+ if (so.playback_rate)
+ {
+ if (SoundData.channels[channel].type == SOUND_NOISE)
+ hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f];
+ SoundData.channels[channel].frequency = (int)
+ (((int64) hertz * FIXED_POINT) / so.playback_rate);
+ if (Settings.FixFrequency)
+ {
+ SoundData.channels[channel].frequency =
+ (unsigned long) ((double) SoundData.channels[channel].frequency * 0.980);
+ }
+ }
+}
+
+void S9xSetSoundHertz (int channel, int hertz)
+{
+ SoundData.channels[channel].hertz = hertz;
+ S9xSetSoundFrequency (channel, hertz);
+}
+
+void S9xSetSoundType (int channel, int type_of_sound)
+{
+ SoundData.channels[channel].type = type_of_sound;
+}
+
+bool8 S9xSetSoundMute (bool8 mute)
+{
+ bool8 old = so.mute_sound;
+ so.mute_sound = mute;
+ return (old);
+}
+
+void AltDecodeBlock (Channel *ch)
+{
+ if (ch->block_pointer >= 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
+ return;
+ }
+ signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
+
+ unsigned char filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+#if (defined (USE_X86_ASM) && (defined (__i386__) || defined (__i486__) ||\
+ defined (__i586__) || defined (__WIN32__) || defined (__DJGPP)))
+ int16 *raw = ch->block = ch->decoded;
+
+ if (Settings.AltSampleDecode == 1)
+ DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);
+ else
+ DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);
+#else
+ int32 out;
+ unsigned char shift;
+ signed char sample1, sample2;
+ unsigned int i;
+
+ compressed++;
+ signed short *raw = ch->block = ch->decoded;
+
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+ shift = filter >> 4;
+
+ switch ((filter >> 2) & 3)
+ {
+ case 0:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+ *raw++ = ((int32) sample1 << shift);
+ *raw++ = ((int32) sample2 << shift);
+ }
+ prev1 = *(raw - 2);
+ prev0 = *(raw - 1);
+ break;
+ case 1:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+ prev0 = (int16) prev0;
+ *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);
+ prev1 = (int16) prev1;
+ *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);
+ }
+ break;
+ case 2:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+
+ out = (sample1 << shift) - prev1 + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
+ (prev0 >> 4);
+
+ out = (sample2 << shift) - prev1 + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -
+ (prev0 >> 4);
+ }
+ break;
+ case 3:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ sample2 >>= 4;
+ sample1 >>= 4;
+ out = (sample1 << shift);
+
+ out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
+ (prev0 >> 4) - (prev1 >> 6);
+
+ out = (sample2 << shift);
+ out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);
+ prev1 = (int16) prev0;
+ prev0 &= ~3;
+ *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) -
+ (prev0 >> 4) - (prev1 >> 6);
+ }
+ break;
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
+#endif
+
+ ch->block_pointer += 9;
+}
+
+void AltDecodeBlock2 (Channel *ch)
+{
+ int32 out;
+ unsigned char filter;
+ unsigned char shift;
+ signed char sample1, sample2;
+ unsigned char i;
+
+ if (ch->block_pointer > 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ memset ((void *) ch->decoded, 0, sizeof (int16) * 16);
+ return;
+ }
+
+ signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
+
+ filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+ compressed++;
+ signed short *raw = ch->block = ch->decoded;
+
+ shift = filter >> 4;
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+
+ if(shift > 12)
+ shift -= 4;
+
+ switch ((filter >> 2) & 3)
+ {
+ case 0:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+
+ out = (int32)(sample1 << shift);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+
+ out = (int32)(sample2 << shift);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+ }
+ break;
+ case 1:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ out = (int32)(sample1 << shift);
+ out += (int32)((double)prev0 * 15/16);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+
+ out = (int32)(sample2 << shift);
+ out += (int32)((double)prev0 * 15/16);
+
+ prev1 = prev0;
+ prev0 = out;
+ CLIP16(out);
+ *raw++ = (int16)out;
+ }
+ break;
+ case 2:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+
+ out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
+
+ prev1 = prev0;
+ prev0 = (int16)out;
+ *raw++ = (int16)out;
+
+ out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8;
+
+ prev1 = prev0;
+ prev0 = (int16)out;
+ *raw++ = (int16)out;
+ }
+ break;
+
+ case 3:
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ out = (int32)(sample1 << shift);
+ out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
+
+ prev1 = prev0;
+ prev0 = out;
+
+ CLIP16(out);
+ *raw++ = (int16)out;
+
+ out = (int32)(sample2 << shift);
+ out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16);
+
+ prev1 = prev0;
+ prev0 = out;
+
+ CLIP16(out);
+ *raw++ = (int16)out;
+ }
+ break;
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
+ ch->block_pointer += 9;
+}
+
+void DecodeBlock (Channel *ch)
+{
+ int32 out;
+ unsigned char filter;
+ unsigned char shift;
+ signed char sample1, sample2;
+ unsigned char i;
+ bool invalid_header;
+
+ if (Settings.AltSampleDecode)
+ {
+ if (Settings.AltSampleDecode < 3)
+ AltDecodeBlock (ch);
+ else
+ AltDecodeBlock2 (ch);
+ return;
+ }
+ if (ch->block_pointer > 0x10000 - 9)
+ {
+ ch->last_block = TRUE;
+ ch->loop = FALSE;
+ ch->block = ch->decoded;
+ return;
+ }
+ signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];
+
+ filter = *compressed;
+ if ((ch->last_block = filter & 1))
+ ch->loop = (filter & 2) != 0;
+
+ compressed++;
+ signed short *raw = ch->block = ch->decoded;
+
+ // Seperate out the header parts used for decoding
+
+ shift = filter >> 4;
+
+ // Header validity check: if range(shift) is over 12, ignore
+ // all bits of the data for that block except for the sign bit of each
+ invalid_header = !(shift < 0xD);
+
+ filter = filter&0x0c;
+
+ int32 prev0 = ch->previous [0];
+ int32 prev1 = ch->previous [1];
+
+ for (i = 8; i != 0; i--)
+ {
+ sample1 = *compressed++;
+ sample2 = sample1 << 4;
+ //Sample 2 = Bottom Nibble, Sign Extended.
+ sample2 >>= 4;
+ //Sample 1 = Top Nibble, shifted down and Sign Extended.
+ sample1 >>= 4;
+ if (invalid_header) { sample1>>=3; sample2>>=3; }
+
+ for (int nybblesmp = 0; nybblesmp<2; nybblesmp++){
+ out=(((nybblesmp) ? sample2 : sample1) << shift);
+ out >>= 1;
+
+ switch(filter)
+ {
+ case 0x00:
+ // Method0 - [Smp]
+ break;
+
+ case 0x04:
+ // Method1 - [Delta]+[Smp-1](15/16)
+ out+=(prev0>>1)+((-prev0)>>5);
+ break;
+
+ case 0x08:
+ // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16)
+ out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5);
+ break;
+
+ default:
+ // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16)
+ out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4);
+ break;
+
+ }
+ CLIP16(out);
+ *raw++ = (signed short)(out<<1);
+ prev1=(signed short)prev0;
+ prev0=(signed short)(out<<1);
+ }
+ }
+ ch->previous [0] = prev0;
+ ch->previous [1] = prev1;
+
+ ch->block_pointer += 9;
+}
+
+
+void MixStereo (int sample_count)
+{
+ static int wave[SOUND_BUFFER_SIZE];
+
+ int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON];
+
+ for (uint32 J = 0; J < NUM_CHANNELS; J++)
+ {
+ int32 VL, VR;
+ Channel *ch = &SoundData.channels[J];
+ unsigned long freq0 = ch->frequency;
+
+ if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
+ continue;
+
+// freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux
+ freq0 = freq0 * 985/1000;
+
+ bool8 mod = pitch_mod & (1 << J);
+
+ if (ch->needs_decode)
+ {
+ DecodeBlock(ch);
+ ch->needs_decode = FALSE;
+ ch->sample = ch->block[0];
+ ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
+ if (ch->sample_pointer == 0)
+ ch->sample_pointer = 1;
+ if (ch->sample_pointer > SOUND_DECODE_LENGTH)
+ ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
+
+ ch->next_sample=ch->block[ch->sample_pointer];
+ ch->interpolate = 0;
+
+ if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
+ ch->interpolate = ((ch->next_sample - ch->sample) *
+ (long) freq0) / (long) FIXED_POINT;
+ }
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+
+ for (uint32 I = 0; I < (uint32) sample_count; I += 2)
+ {
+ unsigned long freq = freq0;
+
+ if (mod)
+ freq = PITCH_MOD(freq, wave [I / 2]);
+
+ ch->env_error += ch->erate;
+ if (ch->env_error >= FIXED_POINT)
+ {
+ uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
+
+ switch (ch->state)
+ {
+ case SOUND_ATTACK:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_DECAY;
+ if (ch->sustain_level != 8)
+ {
+ S9xSetEnvRate (ch, ch->decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * ch->sustain_level)
+ >> 3);
+ break;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
+ }
+ break;
+
+ case SOUND_DECAY:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= ch->envx_target)
+ {
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto stereo_exit;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
+ }
+ break;
+
+ case SOUND_SUSTAIN:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_RELEASE:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_INCREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate (ch, 0, -1, 0);
+ }
+ break;
+
+ case SOUND_INCREASE_BENT_LINE:
+ if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
+ {
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ }
+ else
+ {
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ }
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate (ch, 0, -1, 0);
+ }
+ break;
+
+ case SOUND_DECREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx -= step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_DECREASE_EXPONENTIAL:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto stereo_exit;
+ }
+ break;
+
+ case SOUND_GAIN:
+ S9xSetEnvRate (ch, 0, -1, 0);
+ break;
+ }
+ ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
+ ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+ }
+
+ ch->count += freq;
+ if (ch->count >= FIXED_POINT)
+ {
+ VL = ch->count >> FIXED_POINT_SHIFT;
+ ch->sample_pointer += VL;
+ ch->count &= FIXED_POINT_REMAINDER;
+
+ ch->sample = ch->next_sample;
+ if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
+ {
+ if (JUST_PLAYED_LAST_SAMPLE(ch))
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto stereo_exit;
+ }
+ do
+ {
+ ch->sample_pointer -= SOUND_DECODE_LENGTH;
+ if (ch->last_block)
+ {
+ if (!ch->loop)
+ {
+ ch->sample_pointer = LAST_SAMPLE;
+ ch->next_sample = ch->sample;
+ break;
+ }
+ else
+ {
+ S9xAPUSetEndX (J);
+ ch->last_block = FALSE;
+ uint8 *dir = S9xGetSampleAddress (ch->sample_number);
+ ch->block_pointer = READ_WORD(dir + 2);
+ }
+ }
+ DecodeBlock (ch);
+ } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
+ if (!JUST_PLAYED_LAST_SAMPLE (ch))
+ ch->next_sample = ch->block [ch->sample_pointer];
+ }
+ else
+ ch->next_sample = ch->block [ch->sample_pointer];
+
+ if (ch->type == SOUND_SAMPLE)
+ {
+ if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
+ {
+ ch->interpolate = ((ch->next_sample - ch->sample) *
+ (long) freq) / (long) FIXED_POINT;
+ ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) *
+ (long) (ch->count)) / (long) FIXED_POINT));
+ }
+ else
+ ch->interpolate = 0;
+ }
+ else
+ {
+ for (;VL > 0; VL--)
+ if ((so.noise_gen <<= 1) & 0x80000000L)
+ so.noise_gen ^= 0x0040001L;
+ ch->sample = (so.noise_gen << 17) >> 17;
+ ch->interpolate = 0;
+ }
+
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+ }
+ else
+ {
+ if (ch->interpolate)
+ {
+ int32 s = (int32) ch->sample + ch->interpolate;
+
+ CLIP16(s);
+ ch->sample = (int16) s;
+ VL = (ch->sample * ch-> left_vol_level) / 128;
+ VR = (ch->sample * ch->right_vol_level) / 128;
+ }
+ }
+
+ if (pitch_mod & (1 << (J + 1)))
+ wave [I / 2] = ch->sample * ch->envx;
+
+ MixBuffer [I ^ Settings.ReverseStereo] += VL;
+ MixBuffer [I + (1 ^ Settings.ReverseStereo)] += VR;
+ ch->echo_buf_ptr [I ^ Settings.ReverseStereo] += VL;
+ ch->echo_buf_ptr [I + (1 ^ Settings.ReverseStereo)] += VR;
+ }
+stereo_exit: ;
+ }
+}
+
+#ifdef __DJGPP
+END_OF_FUNCTION(MixStereo);
+#endif
+
+void MixMono (int sample_count)
+{
+ static int wave[SOUND_BUFFER_SIZE];
+
+ int pitch_mod = SoundData.pitch_mod & (~APU.DSP[APU_NON]);
+
+ for (uint32 J = 0; J < NUM_CHANNELS; J++)
+ {
+ Channel *ch = &SoundData.channels[J];
+ unsigned long freq0 = ch->frequency;
+
+ if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))
+ continue;
+
+ // freq0 = (unsigned long) ((double) freq0 * 0.985);
+
+ bool8 mod = pitch_mod & (1 << J);
+
+ if (ch->needs_decode)
+ {
+ DecodeBlock(ch);
+ ch->needs_decode = FALSE;
+ ch->sample = ch->block[0];
+ ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;
+ if (ch->sample_pointer == 0)
+ ch->sample_pointer = 1;
+ if (ch->sample_pointer > SOUND_DECODE_LENGTH)
+ ch->sample_pointer = SOUND_DECODE_LENGTH - 1;
+ ch->next_sample = ch->block[ch->sample_pointer];
+ ch->interpolate = 0;
+
+ if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)
+ ch->interpolate = ((ch->next_sample - ch->sample) *
+ (long) freq0) / (long) FIXED_POINT;
+ }
+ int32 V = (ch->sample * ch->left_vol_level) / 128;
+
+ for (uint32 I = 0; I < (uint32) sample_count; I++)
+ {
+ unsigned long freq = freq0;
+
+ if (mod)
+ freq = PITCH_MOD(freq, wave [I]);
+
+ ch->env_error += ch->erate;
+ if (ch->env_error >= FIXED_POINT)
+ {
+ uint32 step = ch->env_error >> FIXED_POINT_SHIFT;
+
+ switch (ch->state)
+ {
+ case SOUND_ATTACK:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_DECAY;
+ if (ch->sustain_level != 8)
+ {
+ S9xSetEnvRate (ch, ch->decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * ch->sustain_level)
+ >> 3);
+ break;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
+ }
+ break;
+
+ case SOUND_DECAY:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= ch->envx_target)
+ {
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto mono_exit;
+ }
+ ch->state = SOUND_SUSTAIN;
+ S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
+ }
+ break;
+
+ case SOUND_SUSTAIN:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_RELEASE:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_INCREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate (ch, 0, -1, 0);
+ }
+ break;
+
+ case SOUND_INCREASE_BENT_LINE:
+ if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)
+ {
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ }
+ else
+ {
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx += step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ }
+
+ if (ch->envx >= 126)
+ {
+ ch->envx = 127;
+ ch->envxx = 127 << ENVX_SHIFT;
+ ch->state = SOUND_GAIN;
+ ch->mode = MODE_GAIN;
+ S9xSetEnvRate (ch, 0, -1, 0);
+ }
+ break;
+
+ case SOUND_DECREASE_LINEAR:
+ ch->env_error &= FIXED_POINT_REMAINDER;
+ ch->envx -= step << 1;
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_DECREASE_EXPONENTIAL:
+ while (ch->env_error >= FIXED_POINT)
+ {
+ ch->envxx = (ch->envxx >> 8) * 255;
+ ch->env_error -= FIXED_POINT;
+ }
+ ch->envx = ch->envxx >> ENVX_SHIFT;
+ if (ch->envx <= 0)
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto mono_exit;
+ }
+ break;
+
+ case SOUND_GAIN:
+ S9xSetEnvRate (ch, 0, -1, 0);
+ break;
+ }
+ ch->left_vol_level = (ch->envx * ch->volume_left) / 128;
+ V = (ch->sample * ch->left_vol_level) / 128;
+ }
+
+ ch->count += freq;
+ if (ch->count >= FIXED_POINT)
+ {
+ V = ch->count >> FIXED_POINT_SHIFT;
+ ch->sample_pointer += V;
+ ch->count &= FIXED_POINT_REMAINDER;
+
+ ch->sample = ch->next_sample;
+ if (ch->sample_pointer >= SOUND_DECODE_LENGTH)
+ {
+ if (JUST_PLAYED_LAST_SAMPLE(ch))
+ {
+ S9xAPUSetEndOfSample (J, ch);
+ goto mono_exit;
+ }
+ do
+ {
+ ch->sample_pointer -= SOUND_DECODE_LENGTH;
+ if (ch->last_block)
+ {
+ if (!ch->loop)
+ {
+ ch->sample_pointer = LAST_SAMPLE;
+ ch->next_sample = ch->sample;
+ break;
+ }
+ else
+ {
+ ch->last_block = FALSE;
+ uint8 *dir = S9xGetSampleAddress (ch->sample_number);
+ ch->block_pointer = READ_WORD(dir + 2);
+ S9xAPUSetEndX (J);
+ }
+ }
+ DecodeBlock (ch);
+ } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);
+ if (!JUST_PLAYED_LAST_SAMPLE (ch))
+ ch->next_sample = ch->block [ch->sample_pointer];
+ }
+ else
+ ch->next_sample = ch->block [ch->sample_pointer];
+
+ if (ch->type == SOUND_SAMPLE)
+ {
+ if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)
+ {
+ ch->interpolate = ((ch->next_sample - ch->sample) *
+ (long) freq) / (long) FIXED_POINT;
+ ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) *
+ (long) (ch->count)) / (long) FIXED_POINT));
+ }
+ else
+ ch->interpolate = 0;
+ }
+ else
+ {
+ for (;V > 0; V--)
+ if ((so.noise_gen <<= 1) & 0x80000000L)
+ so.noise_gen ^= 0x0040001L;
+ ch->sample = (so.noise_gen << 17) >> 17;
+ ch->interpolate = 0;
+ }
+ V = (ch->sample * ch-> left_vol_level) / 128;
+ }
+ else
+ {
+ if (ch->interpolate)
+ {
+ int32 s = (int32) ch->sample + ch->interpolate;
+
+ CLIP16(s);
+ ch->sample = (int16) s;
+ V = (ch->sample * ch-> left_vol_level) / 128;
+ }
+ }
+
+ MixBuffer [I] += V;
+ ch->echo_buf_ptr [I] += V;
+
+ if (pitch_mod & (1 << (J + 1)))
+ wave [I] = ch->sample * ch->envx;
+ }
+mono_exit: ;
+ }
+}
+#ifdef __DJGPP
+END_OF_FUNCTION(MixMono);
+#endif
+
+#ifdef __sun
+extern uint8 int2ulaw (int);
+#endif
+
+// For backwards compatibility with older port specific code
+void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
+{
+ S9xMixSamples (buffer+byte_offset, sample_count);
+}
+#ifdef __DJGPP
+END_OF_FUNCTION(S9xMixSamplesO);
+#endif
+
+void S9xMixSamples (uint8 *buffer, int sample_count)
+{
+ int J;
+ int I;
+
+ if (!so.mute_sound)
+ {
+ memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));
+ if (SoundData.echo_enable)
+ memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0]));
+
+ if (so.stereo)
+ MixStereo (sample_count);
+ else
+ MixMono (sample_count);
+ }
+
+ /* Mix and convert waveforms */
+ if (so.sixteen_bit)
+ {
+ int byte_count = sample_count << 1;
+
+ // 16-bit sound
+ if (so.mute_sound)
+ {
+ memset (buffer, 0, byte_count);
+ }
+ else
+ {
+ if (SoundData.echo_enable && SoundData.echo_buffer_size)
+ {
+ if (so.stereo)
+ {
+ // 16-bit stereo sound with echo enabled ...
+ if (SoundData.no_filter)
+ {
+ // ... but no filter defined.
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1] +
+ E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
+
+ CLIP16(I);
+ ((signed short *) buffer)[J] = I;
+ }
+ }
+ else
+ {
+ // ... with filter defined.
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 15] = E;
+ E = E * FilterTaps [0];
+ E += Loop [(Z - 2) & 15] * FilterTaps [1];
+ E += Loop [(Z - 4) & 15] * FilterTaps [2];
+ E += Loop [(Z - 6) & 15] * FilterTaps [3];
+ E += Loop [(Z - 8) & 15] * FilterTaps [4];
+ E += Loop [(Z - 10) & 15] * FilterTaps [5];
+ E += Loop [(Z - 12) & 15] * FilterTaps [6];
+ E += Loop [(Z - 14) & 15] * FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1] +
+ E * SoundData.echo_volume [J & 1]) / VOL_DIV16;
+
+ CLIP16(I);
+ ((signed short *) buffer)[J] = I;
+ }
+ }
+ }
+ else
+ {
+ // 16-bit mono sound with echo enabled...
+ if (SoundData.no_filter)
+ {
+ // ... no filter defined
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [0] +
+ E * SoundData.echo_volume [0]) / VOL_DIV16;
+ CLIP16(I);
+ ((signed short *) buffer)[J] = I;
+ }
+ }
+ else
+ {
+ // ... with filter defined
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 7] = E;
+ E = E * FilterTaps [0];
+ E += Loop [(Z - 1) & 7] * FilterTaps [1];
+ E += Loop [(Z - 2) & 7] * FilterTaps [2];
+ E += Loop [(Z - 3) & 7] * FilterTaps [3];
+ E += Loop [(Z - 4) & 7] * FilterTaps [4];
+ E += Loop [(Z - 5) & 7] * FilterTaps [5];
+ E += Loop [(Z - 6) & 7] * FilterTaps [6];
+ E += Loop [(Z - 7) & 7] * FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] * SoundData.master_volume [0] +
+ E * SoundData.echo_volume [0]) / VOL_DIV16;
+ CLIP16(I);
+ ((signed short *) buffer)[J] = I;
+ }
+ }
+ }
+ }
+ else
+ {
+ // 16-bit mono or stereo sound, no echo
+ for (J = 0; J < sample_count; J++)
+ {
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1]) / VOL_DIV16;
+
+ CLIP16(I);
+ ((signed short *) buffer)[J] = I;
+ }
+ }
+ }
+ }
+ else
+ {
+ // 8-bit sound
+ if (so.mute_sound)
+ {
+ memset (buffer, 128, sample_count);
+ }
+ else
+#ifdef __sun
+ if (so.encoded)
+ {
+ for (J = 0; J < sample_count; J++)
+ {
+ I = (MixBuffer [J] * SoundData.master_volume_left) / VOL_DIV16;
+ CLIP16(I);
+ buffer[J] = int2ulaw (I);
+ }
+ }
+ else
+#endif
+ {
+ if (SoundData.echo_enable && SoundData.echo_buffer_size)
+ {
+ if (so.stereo)
+ {
+ // 8-bit stereo sound with echo enabled...
+ if (SoundData.no_filter)
+ {
+ // ... but no filter
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1] +
+ E * SoundData.echo_volume [J & 1]) / VOL_DIV8;
+ CLIP8(I);
+ buffer [J] = I + 128;
+ }
+ }
+ else
+ {
+ // ... with filter
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 15] = E;
+ E = E * FilterTaps [0];
+ E += Loop [(Z - 2) & 15] * FilterTaps [1];
+ E += Loop [(Z - 4) & 15] * FilterTaps [2];
+ E += Loop [(Z - 6) & 15] * FilterTaps [3];
+ E += Loop [(Z - 8) & 15] * FilterTaps [4];
+ E += Loop [(Z - 10) & 15] * FilterTaps [5];
+ E += Loop [(Z - 12) & 15] * FilterTaps [6];
+ E += Loop [(Z - 14) & 15] * FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1] +
+ E * SoundData.echo_volume [J & 1]) / VOL_DIV8;
+ CLIP8(I);
+ buffer [J] = I + 128;
+ }
+ }
+ }
+ else
+ {
+ // 8-bit mono sound with echo enabled...
+ if (SoundData.no_filter)
+ {
+ // ... but no filter.
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] * SoundData.master_volume [0] +
+ E * SoundData.echo_volume [0]) / VOL_DIV8;
+ CLIP8(I);
+ buffer [J] = I + 128;
+ }
+ }
+ else
+ {
+ // ... with filter.
+ for (J = 0; J < sample_count; J++)
+ {
+ int E = Echo [SoundData.echo_ptr];
+
+ Loop [(Z - 0) & 7] = E;
+ E = E * FilterTaps [0];
+ E += Loop [(Z - 1) & 7] * FilterTaps [1];
+ E += Loop [(Z - 2) & 7] * FilterTaps [2];
+ E += Loop [(Z - 3) & 7] * FilterTaps [3];
+ E += Loop [(Z - 4) & 7] * FilterTaps [4];
+ E += Loop [(Z - 5) & 7] * FilterTaps [5];
+ E += Loop [(Z - 6) & 7] * FilterTaps [6];
+ E += Loop [(Z - 7) & 7] * FilterTaps [7];
+ E /= 128;
+ Z++;
+
+ Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +
+ EchoBuffer [J];
+
+ if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)
+ SoundData.echo_ptr = 0;
+
+ I = (MixBuffer [J] * SoundData.master_volume [0] +
+ E * SoundData.echo_volume [0]) / VOL_DIV8;
+ CLIP8(I);
+ buffer [J] = I + 128;
+ }
+ }
+ }
+ }
+ else
+ {
+ // 8-bit mono or stereo sound, no echo
+ for (J = 0; J < sample_count; J++)
+ {
+ I = (MixBuffer [J] *
+ SoundData.master_volume [J & 1]) / VOL_DIV8;
+ CLIP8(I);
+ buffer [J] = I + 128;
+ }
+ }
+ }
+ }
+}
+
+#ifdef __DJGPP
+END_OF_FUNCTION(S9xMixSamples);
+#endif
+
+void S9xResetSound (bool8 full)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ SoundData.channels[i].state = SOUND_SILENT;
+ SoundData.channels[i].mode = MODE_NONE;
+ SoundData.channels[i].type = SOUND_SAMPLE;
+ SoundData.channels[i].volume_left = 0;
+ SoundData.channels[i].volume_right = 0;
+ SoundData.channels[i].hertz = 0;
+ SoundData.channels[i].count = 0;
+ SoundData.channels[i].loop = FALSE;
+ SoundData.channels[i].envx_target = 0;
+ SoundData.channels[i].env_error = 0;
+ SoundData.channels[i].erate = 0;
+ SoundData.channels[i].envx = 0;
+ SoundData.channels[i].envxx = 0;
+ SoundData.channels[i].left_vol_level = 0;
+ SoundData.channels[i].right_vol_level = 0;
+ SoundData.channels[i].direction = 0;
+ SoundData.channels[i].attack_rate = 0;
+ SoundData.channels[i].decay_rate = 0;
+ SoundData.channels[i].sustain_rate = 0;
+ SoundData.channels[i].release_rate = 0;
+ SoundData.channels[i].sustain_level = 0;
+ SoundData.echo_ptr = 0;
+ SoundData.echo_feedback = 0;
+ SoundData.echo_buffer_size = 1;
+ }
+ FilterTaps [0] = 127;
+ FilterTaps [1] = 0;
+ FilterTaps [2] = 0;
+ FilterTaps [3] = 0;
+ FilterTaps [4] = 0;
+ FilterTaps [5] = 0;
+ FilterTaps [6] = 0;
+ FilterTaps [7] = 0;
+ so.mute_sound = TRUE;
+ so.noise_gen = 1;
+ so.sound_switch = 255;
+ so.samples_mixed_so_far = 0;
+ so.play_position = 0;
+ so.err_counter = 0;
+
+ if (full)
+ {
+ SoundData.master_volume_left = 0;
+ SoundData.master_volume_right = 0;
+ SoundData.echo_volume_left = 0;
+ SoundData.echo_volume_right = 0;
+ SoundData.echo_enable = 0;
+ SoundData.echo_write_enabled = 0;
+ SoundData.echo_channel_enable = 0;
+ SoundData.pitch_mod = 0;
+ SoundData.dummy[0] = 0;
+ SoundData.dummy[1] = 0;
+ SoundData.dummy[2] = 0;
+ SoundData.master_volume[0] = 0;
+ SoundData.master_volume[1] = 0;
+ SoundData.echo_volume[0] = 0;
+ SoundData.echo_volume[1] = 0;
+ SoundData.noise_hertz = 0;
+ }
+
+ SoundData.master_volume_left = 127;
+ SoundData.master_volume_right = 127;
+ SoundData.master_volume [0] = SoundData.master_volume [1] = 127;
+ if (so.playback_rate)
+ so.err_rate = (uint32) (FIXED_POINT * SNES_SCANLINE_TIME / (1.0 / so.playback_rate));
+ else
+ so.err_rate = 0;
+ SoundData.no_filter = TRUE;
+}
+
+void S9xSetPlaybackRate (uint32 playback_rate)
+{
+ so.playback_rate = playback_rate;
+ so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate));
+ S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);
+ for (int i = 0; i < 8; i++)
+ S9xSetSoundFrequency (i, SoundData.channels [i].hertz);
+}
+
+bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size)
+{
+ so.sound_fd = -1;
+ so.sound_switch = 255;
+
+ so.playback_rate = 0;
+ so.buffer_size = 0;
+ so.stereo = stereo;
+ so.sixteen_bit = Settings.SixteenBitSound;
+ so.encoded = FALSE;
+
+ S9xResetSound (TRUE);
+
+ if (!(mode & 7))
+ return (1);
+
+ S9xSetSoundMute (TRUE);
+ if (!S9xOpenSoundDevice (mode, stereo, buffer_size))
+ {
+#ifdef NOSOUND
+ S9xMessage (S9X_WARNING, S9X_SOUND_NOT_BUILT,
+ "No sound support compiled in");
+#else
+ S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED,
+ "Sound device open failed");
+#endif
+ return (0);
+ }
+
+ return (1);
+}
+
+bool8 S9xSetSoundMode (int channel, int mode)
+{
+ Channel *ch = &SoundData.channels[channel];
+
+ switch (mode)
+ {
+ case MODE_RELEASE:
+ if (ch->mode != MODE_NONE)
+ {
+ ch->mode = MODE_RELEASE;
+ return (TRUE);
+ }
+ break;
+
+ case MODE_DECREASE_LINEAR:
+ case MODE_DECREASE_EXPONENTIAL:
+ case MODE_GAIN:
+ if (ch->mode != MODE_RELEASE)
+ {
+ ch->mode = mode;
+ if (ch->state != SOUND_SILENT)
+ ch->state = mode;
+
+ return (TRUE);
+ }
+ break;
+
+ case MODE_INCREASE_LINEAR:
+ case MODE_INCREASE_BENT_LINE:
+ if (ch->mode != MODE_RELEASE)
+ {
+ ch->mode = mode;
+ if (ch->state != SOUND_SILENT)
+ ch->state = mode;
+
+ return (TRUE);
+ }
+ break;
+
+ case MODE_ADSR:
+ if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR)
+ {
+ ch->mode = mode;
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+void S9xSetSoundControl (int sound_switch)
+{
+ so.sound_switch = sound_switch;
+}
+
+void S9xPlaySample (int channel)
+{
+ Channel *ch = &SoundData.channels[channel];
+
+ ch->state = SOUND_SILENT;
+ ch->mode = MODE_NONE;
+ ch->envx = 0;
+ ch->envxx = 0;
+
+ S9xFixEnvelope (channel,
+ APU.DSP [APU_GAIN + (channel << 4)],
+ APU.DSP [APU_ADSR1 + (channel << 4)],
+ APU.DSP [APU_ADSR2 + (channel << 4)]);
+
+ ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10];
+ if (APU.DSP [APU_NON] & (1 << channel))
+ ch->type = SOUND_NOISE;
+ else
+ ch->type = SOUND_SAMPLE;
+
+ S9xSetSoundFrequency (channel, ch->hertz);
+ ch->loop = FALSE;
+ ch->needs_decode = TRUE;
+ ch->last_block = FALSE;
+ ch->previous [0] = ch->previous[1] = 0;
+ uint8 *dir = S9xGetSampleAddress (ch->sample_number);
+ ch->block_pointer = READ_WORD (dir);
+ ch->sample_pointer = 0;
+ ch->env_error = 0;
+ ch->next_sample = 0;
+ ch->interpolate = 0;
+ switch (ch->mode)
+ {
+ case MODE_ADSR:
+ if (ch->attack_rate == 0)
+ {
+ if (ch->decay_rate == 0 || ch->sustain_level == 8)
+ {
+ ch->state = SOUND_SUSTAIN;
+ ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3;
+ S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);
+ }
+ else
+ {
+ ch->state = SOUND_DECAY;
+ ch->envx = MAX_ENVELOPE_HEIGHT;
+ S9xSetEnvRate (ch, ch->decay_rate, -1,
+ (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3);
+ }
+ ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;
+ ch->right_vol_level = (ch->envx * ch->volume_right) / 128;
+ }
+ else
+ {
+ ch->state = SOUND_ATTACK;
+ ch->envx = 0;
+ ch->left_vol_level = 0;
+ ch->right_vol_level = 0;
+ S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT);
+ }
+ ch->envxx = ch->envx << ENVX_SHIFT;
+ break;
+
+ case MODE_GAIN:
+ ch->state = SOUND_GAIN;
+ break;
+
+ case MODE_INCREASE_LINEAR:
+ ch->state = SOUND_INCREASE_LINEAR;
+ break;
+
+ case MODE_INCREASE_BENT_LINE:
+ ch->state = SOUND_INCREASE_BENT_LINE;
+ break;
+
+ case MODE_DECREASE_LINEAR:
+ ch->state = SOUND_DECREASE_LINEAR;
+ break;
+
+ case MODE_DECREASE_EXPONENTIAL:
+ ch->state = SOUND_DECREASE_EXPONENTIAL;
+ break;
+
+ default:
+ break;
+ }
+
+ S9xFixEnvelope (channel,
+ APU.DSP [APU_GAIN + (channel << 4)],
+ APU.DSP [APU_ADSR1 + (channel << 4)],
+ APU.DSP [APU_ADSR2 + (channel << 4)]);
+}
+
+
diff --git a/source/soundux.h b/source/soundux.h
new file mode 100644
index 0000000..9892dcf
--- /dev/null
+++ b/source/soundux.h
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _SOUND_H_
+#define _SOUND_H_
+
+enum { SOUND_SAMPLE = 0, SOUND_NOISE, SOUND_EXTRA_NOISE, SOUND_MUTE };
+enum { SOUND_SILENT, SOUND_ATTACK, SOUND_DECAY, SOUND_SUSTAIN,
+ SOUND_RELEASE, SOUND_GAIN, SOUND_INCREASE_LINEAR,
+ SOUND_INCREASE_BENT_LINE, SOUND_DECREASE_LINEAR,
+ SOUND_DECREASE_EXPONENTIAL};
+
+enum { MODE_NONE = SOUND_SILENT, MODE_ADSR, MODE_RELEASE = SOUND_RELEASE,
+ MODE_GAIN, MODE_INCREASE_LINEAR, MODE_INCREASE_BENT_LINE,
+ MODE_DECREASE_LINEAR, MODE_DECREASE_EXPONENTIAL};
+
+#define MAX_ENVELOPE_HEIGHT 127
+#define ENVELOPE_SHIFT 7
+#define MAX_VOLUME 127
+#define VOLUME_SHIFT 7
+#define VOL_DIV 128
+#define SOUND_DECODE_LENGTH 16
+
+#define NUM_CHANNELS 8
+#define SOUND_BUFFER_SIZE (1024 * 16)
+#define MAX_BUFFER_SIZE SOUND_BUFFER_SIZE
+#define SOUND_BUFFER_SIZE_MASK (SOUND_BUFFER_SIZE - 1)
+
+#define SOUND_BUFS 4
+
+#ifdef __sgi
+# include <audio.h>
+#endif /* __sgi */
+
+typedef struct {
+ int sound_fd;
+ int sound_switch;
+ int playback_rate;
+ int buffer_size;
+ int noise_gen;
+ bool8 mute_sound;
+ int stereo;
+ bool8 sixteen_bit;
+ bool8 encoded;
+#ifdef __sun
+ int last_eof;
+#endif
+#ifdef __sgi
+ ALport al_port;
+#endif /* __sgi */
+ int32 samples_mixed_so_far;
+ int32 play_position;
+ uint32 err_counter;
+ uint32 err_rate;
+} SoundStatus;
+
+EXTERN_C volatile SoundStatus so;
+
+typedef struct {
+ int state;
+ int type;
+ short volume_left;
+ short volume_right;
+ uint32 hertz;
+ uint32 frequency;
+ uint32 count;
+ bool8 loop;
+ int envx;
+ short left_vol_level;
+ short right_vol_level;
+ short envx_target;
+ unsigned long int env_error;
+ unsigned long erate;
+ int direction;
+ unsigned long attack_rate;
+ unsigned long decay_rate;
+ unsigned long sustain_rate;
+ unsigned long release_rate;
+ unsigned long sustain_level;
+ signed short sample;
+ signed short decoded [16];
+ signed short previous16 [2];
+ signed short *block;
+ uint16 sample_number;
+ bool8 last_block;
+ bool8 needs_decode;
+ uint32 block_pointer;
+ uint32 sample_pointer;
+ int *echo_buf_ptr;
+ int mode;
+ int32 envxx;
+ signed short next_sample;
+ int32 interpolate;
+ int32 previous [2];
+ // Just incase they are needed in the future, for snapshot compatibility.
+ uint32 dummy [8];
+// unsigned short last_valid_header;
+} Channel;
+
+typedef struct
+{
+ short master_volume_left;
+ short master_volume_right;
+ short echo_volume_left;
+ short echo_volume_right;
+ int echo_enable;
+ int echo_feedback;
+ int echo_ptr;
+ int echo_buffer_size;
+ int echo_write_enabled;
+ int echo_channel_enable;
+ int pitch_mod;
+ // Just incase they are needed in the future, for snapshot compatibility.
+ uint32 dummy [3];
+ Channel channels [NUM_CHANNELS];
+ bool8 no_filter;
+ int master_volume [2];
+ int echo_volume [2];
+ int noise_hertz;
+} SSoundData;
+
+EXTERN_C SSoundData SoundData;
+
+void S9xSetSoundVolume (int channel, short volume_left, short volume_right);
+void S9xSetSoundFrequency (int channel, int hertz);
+void S9xSetSoundHertz (int channel, int hertz);
+void S9xSetSoundType (int channel, int type_of_sound);
+void S9xSetMasterVolume (short master_volume_left, short master_volume_right);
+void S9xSetEchoVolume (short echo_volume_left, short echo_volume_right);
+void S9xSetSoundControl (int sound_switch);
+bool8 S9xSetSoundMute (bool8 mute);
+void S9xSetEnvelopeHeight (int channel, int height);
+void S9xSetSoundADSR (int channel, int attack, int decay, int sustain,
+ int sustain_level, int release);
+void S9xSetSoundKeyOff (int channel);
+void S9xSetSoundDecayMode (int channel);
+void S9xSetSoundAttachMode (int channel);
+void S9xSoundStartEnvelope (Channel *);
+void S9xSetSoundSample (int channel, uint16 sample_number);
+void S9xSetEchoFeedback (int echo_feedback);
+void S9xSetEchoEnable (uint8 byte);
+void S9xSetEchoDelay (int byte);
+void S9xSetEchoWriteEnable (uint8 byte);
+void S9xSetFilterCoefficient (int tap, int value);
+void S9xSetFrequencyModulationEnable (uint8 byte);
+void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction,
+ int target);
+bool8 S9xSetSoundMode (int channel, int mode);
+int S9xGetEnvelopeHeight (int channel);
+void S9xResetSound (bool8 full);
+void S9xFixSoundAfterSnapshotLoad ();
+void S9xPlaybackSoundSetting (int channel);
+void S9xPlaySample (int channel);
+void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2);
+void S9xStartSample (int channel);
+
+EXTERN_C void S9xMixSamples (uint8 *buffer, int sample_count);
+EXTERN_C void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset);
+bool8 S9xOpenSoundDevice (int, bool8, int);
+void S9xSetPlaybackRate (uint32 rate);
+#endif
+
diff --git a/source/spc.cpp b/source/spc.cpp
new file mode 100644
index 0000000..c12c831
--- /dev/null
+++ b/source/spc.cpp
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+void S9xSPCDump (const char *filename)
+{
+ FILE *fs;
+
+ bool8 read_only = FALSE;
+ char def [PATH_MAX];
+ char title [PATH_MAX];
+ char drive [_MAX_DRIVE];
+ char dir [_MAX_DIR];
+ char ext [_MAX_EXT];
+
+ S9xSetSoundMute (TRUE);
+
+#if 0
+ _splitpath (Memory.ROMFilename, drive, dir, def, ext);
+ strcat (def, ".spc");
+ sprintf (title, "%s SPC filename",
+ read_only ? "Select load" : "Choose save");
+ const char *filename;
+
+ filename = S9xSelectFilename (def, ".", "spc", title);
+#endif
+
+ fs = fopen (filename, "wb");
+ fputs ("SNES-SPC700 Sound File Data 0.10", fs);
+ fseek (fs, 37, SEEK_SET);
+ fwrite (&APURegisters.PC, 2, 1, fs);
+
+ fputc (APURegisters.YA.B.A, fs);
+ fputc (APURegisters.X, fs);
+ fputc (APURegisters.YA.B.Y, fs);
+ fputc (APURegisters.P, fs);
+ fputc (APURegisters.S - 0x100, fs); // ???
+ fseek (fs, 256, SEEK_SET);
+
+ fwrite (IAPU.RAM, 1, 65536, fs);
+
+ fwrite (APU.DSP, 1, 192, fs);
+ fwrite (APU.ExtraRAM, 1, 64, fs);
+
+ fclose (fs);
+
+ S9xSetSoundMute (FALSE);
+}
+
diff --git a/source/spc700.cpp b/source/spc700.cpp
new file mode 100644
index 0000000..fe13ae8
--- /dev/null
+++ b/source/spc700.cpp
@@ -0,0 +1,2565 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "snes9x.h"
+#include "spc700.h"
+#include "memmap.h"
+#include "display.h"
+#include "cpuexec.h"
+#include "apu.h"
+
+// SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB.
+
+#ifdef NO_INLINE_SET_GET
+uint8 S9xAPUGetByteZ (uint8 address);
+uint8 S9xAPUGetByte (uint32 address);
+void S9xAPUSetByteZ (uint8, uint8 address);
+void S9xAPUSetByte (uint8, uint32 address);
+
+#else
+#undef INLINE
+#define INLINE inline
+#include "apumem.h"
+#endif
+
+START_EXTERN_C
+extern uint8 Work8;
+extern uint16 Work16;
+extern uint32 Work32;
+extern signed char Int8;
+extern short Int16;
+extern long Int32;
+extern short Int16;
+extern uint8 W1;
+extern uint8 W2;
+
+END_EXTERN_C
+
+#define OP1 (*(IAPU.PC + 1))
+#define OP2 (*(IAPU.PC + 2))
+
+#ifdef SPC700_SHUTDOWN
+#define APUShutdown() \
+ if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \
+ { \
+ if (IAPU.WaitCounter == 0) \
+ { \
+ if (!ICPU.CPUExecuting) \
+ APU.Cycles = CPU.Cycles = CPU.NextEvent; \
+ else \
+ IAPU.APUExecuting = FALSE; \
+ } \
+ else \
+ if (IAPU.WaitCounter >= 2) \
+ IAPU.WaitCounter = 1; \
+ else \
+ IAPU.WaitCounter--; \
+ }
+#else
+#define APUShutdown()
+#endif
+
+#define APUSetZN8(b)\
+ IAPU._Zero = (b);
+
+#define APUSetZN16(w)\
+ IAPU._Zero = ((w) != 0) | ((w) >> 8);
+
+void STOP (char *s)
+{
+ char buffer[100];
+
+#ifdef DEBUGGER
+ S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
+#endif
+
+ sprintf (String, "Sound CPU in unknown state executing %s at %04X\n%s\n", s, IAPU.PC - IAPU.RAM, buffer);
+ S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String);
+ APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE;
+ IAPU.APUExecuting = FALSE;
+
+#ifdef DEBUGGER
+ CPU.Flags |= DEBUG_MODE_FLAG;
+#else
+ S9xExit ();
+#endif
+}
+
+#define TCALL(n)\
+{\
+ PushW (IAPU.PC - IAPU.RAM + 1); \
+ IAPU.PC = IAPU.RAM + (APU.ExtraRAM [((15 - n) << 1)] + \
+ (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \
+}
+
+// XXX: HalfCarry - BJ fixed?
+#define SBC(a,b)\
+Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\
+IAPU._Carry = Int16 >= 0;\
+if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\
+ APUSetOverflow ();\
+else \
+ APUClearOverflow (); \
+APUSetHalfCarry ();\
+if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\
+ APUClearHalfCarry ();\
+(a) = (uint8) Int16;\
+APUSetZN8 ((uint8) Int16);
+
+// XXX: HalfCarry - BJ fixed?
+#define ADC(a,b)\
+Work16 = (a) + (b) + APUCheckCarry();\
+IAPU._Carry = Work16 >= 0x100; \
+if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\
+ APUSetOverflow ();\
+else \
+ APUClearOverflow (); \
+APUClearHalfCarry ();\
+if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\
+ APUSetHalfCarry ();\
+(a) = (uint8) Work16;\
+APUSetZN8 ((uint8) Work16);
+
+#define CMP(a,b)\
+Int16 = (short) (a) - (short) (b);\
+IAPU._Carry = Int16 >= 0;\
+APUSetZN8 ((uint8) Int16);
+
+#define ASL(b)\
+ IAPU._Carry = ((b) & 0x80) != 0; \
+ (b) <<= 1;\
+ APUSetZN8 (b);
+#define LSR(b)\
+ IAPU._Carry = (b) & 1;\
+ (b) >>= 1;\
+ APUSetZN8 (b);
+#define ROL(b)\
+ Work16 = ((b) << 1) | APUCheckCarry (); \
+ IAPU._Carry = Work16 >= 0x100; \
+ (b) = (uint8) Work16; \
+ APUSetZN8 (b);
+#define ROR(b)\
+ Work16 = (b) | ((uint16) APUCheckCarry () << 8); \
+ IAPU._Carry = (uint8) Work16 & 1; \
+ Work16 >>= 1; \
+ (b) = (uint8) Work16; \
+ APUSetZN8 (b);
+
+#define Push(b)\
+ *(IAPU.RAM + 0x100 + APURegisters.S) = b;\
+ APURegisters.S--;
+
+#define Pop(b)\
+ APURegisters.S++;\
+ (b) = *(IAPU.RAM + 0x100 + APURegisters.S);
+
+#ifdef FAST_LSB_WORD_ACCESS
+#define PushW(w)\
+ *(uint16 *) (IAPU.RAM + 0xff + APURegisters.S) = w;\
+ APURegisters.S -= 2;
+#define PopW(w)\
+ APURegisters.S += 2;\
+ w = *(uint16 *) (IAPU.RAM + 0xff + APURegisters.S);
+#else
+#define PushW(w)\
+ *(IAPU.RAM + 0xff + APURegisters.S) = w;\
+ *(IAPU.RAM + 0x100 + APURegisters.S) = (w >> 8);\
+ APURegisters.S -= 2;
+#define PopW(w)\
+ APURegisters.S += 2; \
+ (w) = *(IAPU.RAM + 0xff + APURegisters.S) + (*(IAPU.RAM + 0x100 + APURegisters.S) << 8);
+#endif
+
+#define Relative()\
+ Int8 = OP1;\
+ Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8;
+
+#define Relative2()\
+ Int8 = OP2;\
+ Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8;
+
+#ifdef FAST_LSB_WORD_ACCESS
+#define IndexedXIndirect()\
+ IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + APURegisters.X) & 0xff));
+
+#define Absolute()\
+ IAPU.Address = *(uint16 *) (IAPU.PC + 1);
+
+#define AbsoluteX()\
+ IAPU.Address = *(uint16 *) (IAPU.PC + 1) + APURegisters.X;
+
+#define AbsoluteY()\
+ IAPU.Address = *(uint16 *) (IAPU.PC + 1) + APURegisters.YA.B.Y;
+
+#define MemBit()\
+ IAPU.Address = *(uint16 *) (IAPU.PC + 1);\
+ IAPU.Bit = (uint8)(IAPU.Address >> 13);\
+ IAPU.Address &= 0x1fff;
+
+#define IndirectIndexedY()\
+ IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + APURegisters.YA.B.Y;
+#else
+#define IndexedXIndirect()\
+ IAPU.Address = *(IAPU.DirectPage + ((OP1 + APURegisters.X) & 0xff)) + \
+ (*(IAPU.DirectPage + ((OP1 + APURegisters.X + 1) & 0xff)) << 8);
+#define Absolute()\
+ IAPU.Address = OP1 + (OP2 << 8);
+
+#define AbsoluteX()\
+ IAPU.Address = OP1 + (OP2 << 8) + APURegisters.X;
+
+#define AbsoluteY()\
+ IAPU.Address = OP1 + (OP2 << 8) + APURegisters.YA.B.Y;
+
+#define MemBit()\
+ IAPU.Address = OP1 + (OP2 << 8);\
+ IAPU.Bit = (int8) (IAPU.Address >> 13);\
+ IAPU.Address &= 0x1fff;
+
+#define IndirectIndexedY()\
+ IAPU.Address = *(IAPU.DirectPage + OP1) + \
+ (*(IAPU.DirectPage + OP1 + 1) << 8) + \
+ APURegisters.YA.B.Y;
+#endif
+
+void Apu00 ()
+{
+// NOP
+ IAPU.PC++;
+}
+
+void Apu01 () { TCALL (0) }
+
+void Apu11 () { TCALL (1) }
+
+void Apu21 () { TCALL (2) }
+
+void Apu31 () { TCALL (3) }
+
+void Apu41 () { TCALL (4) }
+
+void Apu51 () { TCALL (5) }
+
+void Apu61 () { TCALL (6) }
+
+void Apu71 () { TCALL (7) }
+
+void Apu81 () { TCALL (8) }
+
+void Apu91 () { TCALL (9) }
+
+void ApuA1 () { TCALL (10) }
+
+void ApuB1 () { TCALL (11) }
+
+void ApuC1 () { TCALL (12) }
+
+void ApuD1 () { TCALL (13) }
+
+void ApuE1 () { TCALL (14) }
+
+void ApuF1 () { TCALL (15) }
+
+void Apu3F () // CALL absolute
+{
+ Absolute ();
+ // 0xB6f for Star Fox 2
+ PushW (IAPU.PC + 3 - IAPU.RAM);
+ IAPU.PC = IAPU.RAM + IAPU.Address;
+}
+
+void Apu4F () // PCALL $XX
+{
+ Work8 = OP1;
+ PushW (IAPU.PC + 2 - IAPU.RAM);
+ IAPU.PC = IAPU.RAM + 0xff00 + Work8;
+}
+
+#define SET(b) \
+S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \
+IAPU.PC += 2
+
+void Apu02 ()
+{
+ SET (0);
+}
+
+void Apu22 ()
+{
+ SET (1);
+}
+
+void Apu42 ()
+{
+ SET (2);
+}
+
+void Apu62 ()
+{
+ SET (3);
+}
+
+void Apu82 ()
+{
+ SET (4);
+}
+
+void ApuA2 ()
+{
+ SET (5);
+}
+
+void ApuC2 ()
+{
+ SET (6);
+}
+
+void ApuE2 ()
+{
+ SET (7);
+}
+
+#define CLR(b) \
+S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \
+IAPU.PC += 2;
+
+void Apu12 ()
+{
+ CLR (0);
+}
+
+void Apu32 ()
+{
+ CLR (1);
+}
+
+void Apu52 ()
+{
+ CLR (2);
+}
+
+void Apu72 ()
+{
+ CLR (3);
+}
+
+void Apu92 ()
+{
+ CLR (4);
+}
+
+void ApuB2 ()
+{
+ CLR (5);
+}
+
+void ApuD2 ()
+{
+ CLR (6);
+}
+
+void ApuF2 ()
+{
+ CLR (7);
+}
+
+#define BBS(b) \
+Work8 = OP1; \
+Relative2 (); \
+if (S9xAPUGetByteZ (Work8) & (1 << (b))) \
+{ \
+ IAPU.PC = IAPU.RAM + (uint16) Int16; \
+ APU.Cycles += IAPU.TwoCycles; \
+} \
+else \
+ IAPU.PC += 3
+
+void Apu03 ()
+{
+ BBS (0);
+}
+
+void Apu23 ()
+{
+ BBS (1);
+}
+
+void Apu43 ()
+{
+ BBS (2);
+}
+
+void Apu63 ()
+{
+ BBS (3);
+}
+
+void Apu83 ()
+{
+ BBS (4);
+}
+
+void ApuA3 ()
+{
+ BBS (5);
+}
+
+void ApuC3 ()
+{
+ BBS (6);
+}
+
+void ApuE3 ()
+{
+ BBS (7);
+}
+
+#define BBC(b) \
+Work8 = OP1; \
+Relative2 (); \
+if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \
+{ \
+ IAPU.PC = IAPU.RAM + (uint16) Int16; \
+ APU.Cycles += IAPU.TwoCycles; \
+} \
+else \
+ IAPU.PC += 3
+
+void Apu13 ()
+{
+ BBC (0);
+}
+
+void Apu33 ()
+{
+ BBC (1);
+}
+
+void Apu53 ()
+{
+ BBC (2);
+}
+
+void Apu73 ()
+{
+ BBC (3);
+}
+
+void Apu93 ()
+{
+ BBC (4);
+}
+
+void ApuB3 ()
+{
+ BBC (5);
+}
+
+void ApuD3 ()
+{
+ BBC (6);
+}
+
+void ApuF3 ()
+{
+ BBC (7);
+}
+
+void Apu04 ()
+{
+// OR A,dp
+ APURegisters.YA.B.A |= S9xAPUGetByteZ (OP1);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu05 ()
+{
+// OR A,abs
+ Absolute ();
+ APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu06 ()
+{
+// OR A,(X)
+ APURegisters.YA.B.A |= S9xAPUGetByteZ (APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu07 ()
+{
+// OR A,(dp+X)
+ IndexedXIndirect ();
+ APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu08 ()
+{
+// OR A,#00
+ APURegisters.YA.B.A |= OP1;
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu09 ()
+{
+// OR dp(dest),dp(src)
+ Work8 = S9xAPUGetByteZ (OP1);
+ Work8 |= S9xAPUGetByteZ (OP2);
+ S9xAPUSetByteZ (Work8, OP2);
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu14 ()
+{
+// OR A,dp+X
+ APURegisters.YA.B.A |= S9xAPUGetByteZ (OP1 + APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu15 ()
+{
+// OR A,abs+X
+ AbsoluteX ();
+ APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu16 ()
+{
+// OR A,abs+Y
+ AbsoluteY ();
+ APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu17 ()
+{
+// OR A,(dp)+Y
+ IndirectIndexedY ();
+ APURegisters.YA.B.A |= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu18 ()
+{
+// OR dp,#00
+ Work8 = OP1;
+ Work8 |= S9xAPUGetByteZ (OP2);
+ S9xAPUSetByteZ (Work8, OP2);
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu19 ()
+{
+// OR (X),(Y)
+ Work8 = S9xAPUGetByteZ (APURegisters.X) | S9xAPUGetByteZ (APURegisters.YA.B.Y);
+ APUSetZN8 (Work8);
+ S9xAPUSetByteZ (Work8, APURegisters.X);
+ IAPU.PC++;
+}
+
+void Apu0A ()
+{
+// OR1 C,membit
+ MemBit ();
+ if (!APUCheckCarry ())
+ {
+ if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
+ APUSetCarry ();
+ }
+ IAPU.PC += 3;
+}
+
+void Apu2A ()
+{
+// OR1 C,not membit
+ MemBit ();
+ if (!APUCheckCarry ())
+ {
+ if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
+ APUSetCarry ();
+ }
+ IAPU.PC += 3;
+}
+
+void Apu4A ()
+{
+// AND1 C,membit
+ MemBit ();
+ if (APUCheckCarry ())
+ {
+ if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
+ APUClearCarry ();
+ }
+ IAPU.PC += 3;
+}
+
+void Apu6A ()
+{
+// AND1 C, not membit
+ MemBit ();
+ if (APUCheckCarry ())
+ {
+ if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
+ APUClearCarry ();
+ }
+ IAPU.PC += 3;
+}
+
+void Apu8A ()
+{
+// EOR1 C, membit
+ MemBit ();
+ if (APUCheckCarry ())
+ {
+ if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
+ APUClearCarry ();
+ }
+ else
+ {
+ if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
+ APUSetCarry ();
+ }
+ IAPU.PC += 3;
+}
+
+void ApuAA ()
+{
+// MOV1 C,membit
+ MemBit ();
+ if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
+ APUSetCarry ();
+ else
+ APUClearCarry ();
+ IAPU.PC += 3;
+}
+
+void ApuCA ()
+{
+// MOV1 membit,C
+ MemBit ();
+ if (APUCheckCarry ())
+ {
+ S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address);
+ }
+ else
+ {
+ S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address);
+ }
+ IAPU.PC += 3;
+}
+
+void ApuEA ()
+{
+// NOT1 membit
+ MemBit ();
+ S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void Apu0B ()
+{
+// ASL dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ ASL (Work8);
+ S9xAPUSetByteZ (Work8, OP1);
+ IAPU.PC += 2;
+}
+
+void Apu0C ()
+{
+// ASL abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ASL (Work8);
+ S9xAPUSetByte (Work8, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void Apu1B ()
+{
+// ASL dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ ASL (Work8);
+ S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void Apu1C ()
+{
+// ASL A
+ ASL (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu0D ()
+{
+// PUSH PSW
+ S9xAPUPackStatus ();
+ Push (APURegisters.P);
+ IAPU.PC++;
+}
+
+void Apu2D ()
+{
+// PUSH A
+ Push (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu4D ()
+{
+// PUSH X
+ Push (APURegisters.X);
+ IAPU.PC++;
+}
+
+void Apu6D ()
+{
+// PUSH Y
+ Push (APURegisters.YA.B.Y);
+ IAPU.PC++;
+}
+
+void Apu8E ()
+{
+// POP PSW
+ Pop (APURegisters.P);
+ S9xAPUUnpackStatus ();
+ if (APUCheckDirectPage ())
+ IAPU.DirectPage = IAPU.RAM + 0x100;
+ else
+ IAPU.DirectPage = IAPU.RAM;
+ IAPU.PC++;
+}
+
+void ApuAE ()
+{
+// POP A
+ Pop (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuCE ()
+{
+// POP X
+ Pop (APURegisters.X);
+ IAPU.PC++;
+}
+
+void ApuEE ()
+{
+// POP Y
+ Pop (APURegisters.YA.B.Y);
+ IAPU.PC++;
+}
+
+void Apu0E ()
+{
+// TSET1 abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ S9xAPUSetByte (Work8 | APURegisters.YA.B.A, IAPU.Address);
+ Work8 &= APURegisters.YA.B.A;
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu4E ()
+{
+// TCLR1 abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ S9xAPUSetByte (Work8 & ~APURegisters.YA.B.A, IAPU.Address);
+ Work8 &= APURegisters.YA.B.A;
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu0F ()
+{
+// BRK
+
+#if 0
+ STOP ("BRK");
+#else
+ PushW (IAPU.PC + 1 - IAPU.RAM);
+ S9xAPUPackStatus ();
+ Push (APURegisters.P);
+ APUSetBreak ();
+ APUClearInterrupt ();
+// XXX:Where is the BRK vector ???
+ IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8);
+#endif
+}
+
+void ApuEF ()
+{
+// SLEEP
+ // XXX: sleep
+ // STOP ("SLEEP");
+ IAPU.APUExecuting = FALSE;
+ IAPU.PC++;
+}
+
+void ApuFF ()
+{
+// STOP
+ // STOP ("STOP");
+ IAPU.APUExecuting = FALSE;
+ IAPU.PC++;
+}
+
+void Apu10 ()
+{
+// BPL
+ Relative ();
+ if (!APUCheckNegative ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void Apu30 ()
+{
+// BMI
+ Relative ();
+ if (APUCheckNegative ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void Apu90 ()
+{
+// BCC
+ Relative ();
+ if (!APUCheckCarry ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void ApuB0 ()
+{
+// BCS
+ Relative ();
+ if (APUCheckCarry ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void ApuD0 ()
+{
+// BNE
+ Relative ();
+ if (!APUCheckZero ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void ApuF0 ()
+{
+// BEQ
+ Relative ();
+ if (APUCheckZero ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void Apu50 ()
+{
+// BVC
+ Relative ();
+ if (!APUCheckOverflow ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void Apu70 ()
+{
+// BVS
+ Relative ();
+ if (APUCheckOverflow ())
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void Apu2F ()
+{
+// BRA
+ Relative ();
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+}
+
+void Apu80 ()
+{
+// SETC
+ APUSetCarry ();
+ IAPU.PC++;
+}
+
+void ApuED ()
+{
+// NOTC
+ IAPU._Carry ^= 1;
+ IAPU.PC++;
+}
+
+void Apu40 ()
+{
+// SETP
+ APUSetDirectPage ();
+ IAPU.DirectPage = IAPU.RAM + 0x100;
+ IAPU.PC++;
+}
+
+void Apu1A ()
+{
+// DECW dp
+ Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
+ Work16--;
+ S9xAPUSetByteZ ((uint8) Work16, OP1);
+ S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
+ APUSetZN16 (Work16);
+ IAPU.PC += 2;
+}
+
+void Apu5A ()
+{
+// CMPW YA,dp
+ Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
+ Int32 = (long) APURegisters.YA.W - (long) Work16;
+ IAPU._Carry = Int32 >= 0;
+ APUSetZN16 ((uint16) Int32);
+ IAPU.PC += 2;
+}
+
+void Apu3A ()
+{
+// INCW dp
+ Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
+ Work16++;
+ S9xAPUSetByteZ ((uint8) Work16, OP1);
+ S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
+ APUSetZN16 (Work16);
+ IAPU.PC += 2;
+}
+
+// XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW?
+void Apu7A ()
+{
+// ADDW YA,dp
+ Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
+ Work32 = (uint32) APURegisters.YA.W + Work16;
+ IAPU._Carry = Work32 >= 0x10000;
+ if (~(APURegisters.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000)
+ APUSetOverflow ();
+ else
+ APUClearOverflow ();
+ APUClearHalfCarry ();
+ if((APURegisters.YA.W ^ Work16 ^ (uint16) Work32) & 0x10)
+ APUSetHalfCarry ();
+ APURegisters.YA.W = (uint16) Work32;
+ APUSetZN16 (APURegisters.YA.W);
+ IAPU.PC += 2;
+}
+
+// XXX: BJ: i think the old HalfCarry behavior was wrong...
+// XXX: Or is it between bits 7 and 8 for ADDW/SUBW?
+void Apu9A ()
+{
+// SUBW YA,dp
+ Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
+ Int32 = (long) APURegisters.YA.W - (long) Work16;
+ APUClearHalfCarry ();
+ IAPU._Carry = Int32 >= 0;
+ if (((APURegisters.YA.W ^ Work16) & 0x8000) &&
+ ((APURegisters.YA.W ^ (uint16) Int32) & 0x8000))
+ APUSetOverflow ();
+ else
+ APUClearOverflow ();
+ if (((APURegisters.YA.W ^ Work16) & 0x0080) &&
+ ((APURegisters.YA.W ^ (uint16) Int32) & 0x0080))
+ APUSetHalfCarry ();
+ APUSetHalfCarry ();
+ if((APURegisters.YA.W ^ Work16 ^ (uint16) Work32) & 0x10)
+ APUClearHalfCarry ();
+ APURegisters.YA.W = (uint16) Int32;
+ APUSetZN16 (APURegisters.YA.W);
+ IAPU.PC += 2;
+}
+
+void ApuBA ()
+{
+// MOVW YA,dp
+ APURegisters.YA.B.A = S9xAPUGetByteZ (OP1);
+ APURegisters.YA.B.Y = S9xAPUGetByteZ (OP1 + 1);
+ APUSetZN16 (APURegisters.YA.W);
+ IAPU.PC += 2;
+}
+
+void ApuDA ()
+{
+// MOVW dp,YA
+ S9xAPUSetByteZ (APURegisters.YA.B.A, OP1);
+ S9xAPUSetByteZ (APURegisters.YA.B.Y, OP1 + 1);
+ IAPU.PC += 2;
+}
+
+void Apu64 ()
+{
+// CMP A,dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu65 ()
+{
+// CMP A,abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu66 ()
+{
+// CMP A,(X)
+ Work8 = S9xAPUGetByteZ (APURegisters.X);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC++;
+}
+
+void Apu67 ()
+{
+// CMP A,(dp+X)
+ IndexedXIndirect ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu68 ()
+{
+// CMP A,#00
+ Work8 = OP1;
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu69 ()
+{
+// CMP dp(dest), dp(src)
+ W1 = S9xAPUGetByteZ (OP1);
+ Work8 = S9xAPUGetByteZ (OP2);
+ CMP (Work8, W1);
+ IAPU.PC += 3;
+}
+
+void Apu74 ()
+{
+// CMP A, dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu75 ()
+{
+// CMP A,abs+X
+ AbsoluteX ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu76 ()
+{
+// CMP A, abs+Y
+ AbsoluteY ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu77 ()
+{
+// CMP A,(dp)+Y
+ IndirectIndexedY ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu78 ()
+{
+// CMP dp,#00
+ Work8 = OP1;
+ W1 = S9xAPUGetByteZ (OP2);
+ CMP (W1, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu79 ()
+{
+// CMP (X),(Y)
+ W1 = S9xAPUGetByteZ (APURegisters.X);
+ Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y);
+ CMP (W1, Work8);
+ IAPU.PC++;
+}
+
+void Apu1E ()
+{
+// CMP X,abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.X, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu3E ()
+{
+// CMP X,dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ CMP (APURegisters.X, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuC8 ()
+{
+// CMP X,#00
+ CMP (APURegisters.X, OP1);
+ IAPU.PC += 2;
+}
+
+void Apu5E ()
+{
+// CMP Y,abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ CMP (APURegisters.YA.B.Y, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu7E ()
+{
+// CMP Y,dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ CMP (APURegisters.YA.B.Y, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuAD ()
+{
+// CMP Y,#00
+ Work8 = OP1;
+ CMP (APURegisters.YA.B.Y, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu1F ()
+{
+// JMP (abs+X)
+ Absolute ();
+ IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + APURegisters.X) +
+ (S9xAPUGetByte (IAPU.Address + APURegisters.X + 1) << 8);
+// XXX: HERE:
+ // APU.Flags |= TRACE_FLAG;
+}
+
+void Apu5F ()
+{
+// JMP abs
+ Absolute ();
+ IAPU.PC = IAPU.RAM + IAPU.Address;
+}
+
+void Apu20 ()
+{
+// CLRP
+ APUClearDirectPage ();
+ IAPU.DirectPage = IAPU.RAM;
+ IAPU.PC++;
+}
+
+void Apu60 ()
+{
+// CLRC
+ APUClearCarry ();
+ IAPU.PC++;
+}
+
+void ApuE0 ()
+{
+// CLRV
+ APUClearHalfCarry ();
+ APUClearOverflow ();
+ IAPU.PC++;
+}
+
+void Apu24 ()
+{
+// AND A,dp
+ APURegisters.YA.B.A &= S9xAPUGetByteZ (OP1);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu25 ()
+{
+// AND A,abs
+ Absolute ();
+ APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu26 ()
+{
+// AND A,(X)
+ APURegisters.YA.B.A &= S9xAPUGetByteZ (APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu27 ()
+{
+// AND A,(dp+X)
+ IndexedXIndirect ();
+ APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu28 ()
+{
+// AND A,#00
+ APURegisters.YA.B.A &= OP1;
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu29 ()
+{
+// AND dp(dest),dp(src)
+ Work8 = S9xAPUGetByteZ (OP1);
+ Work8 &= S9xAPUGetByteZ (OP2);
+ S9xAPUSetByteZ (Work8, OP2);
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu34 ()
+{
+// AND A,dp+X
+ APURegisters.YA.B.A &= S9xAPUGetByteZ (OP1 + APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu35 ()
+{
+// AND A,abs+X
+ AbsoluteX ();
+ APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu36 ()
+{
+// AND A,abs+Y
+ AbsoluteY ();
+ APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu37 ()
+{
+// AND A,(dp)+Y
+ IndirectIndexedY ();
+ APURegisters.YA.B.A &= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu38 ()
+{
+// AND dp,#00
+ Work8 = OP1;
+ Work8 &= S9xAPUGetByteZ (OP2);
+ S9xAPUSetByteZ (Work8, OP2);
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu39 ()
+{
+// AND (X),(Y)
+ Work8 = S9xAPUGetByteZ (APURegisters.X) & S9xAPUGetByteZ (APURegisters.YA.B.Y);
+ APUSetZN8 (Work8);
+ S9xAPUSetByteZ (Work8, APURegisters.X);
+ IAPU.PC++;
+}
+
+void Apu2B ()
+{
+// ROL dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ ROL (Work8);
+ S9xAPUSetByteZ (Work8, OP1);
+ IAPU.PC += 2;
+}
+
+void Apu2C ()
+{
+// ROL abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ROL (Work8);
+ S9xAPUSetByte (Work8, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void Apu3B ()
+{
+// ROL dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ ROL (Work8);
+ S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void Apu3C ()
+{
+// ROL A
+ ROL (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu2E ()
+{
+// CBNE dp,rel
+ Work8 = OP1;
+ Relative2 ();
+
+ if (S9xAPUGetByteZ (Work8) != APURegisters.YA.B.A)
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 3;
+}
+
+void ApuDE ()
+{
+// CBNE dp+X,rel
+ Work8 = OP1 + APURegisters.X;
+ Relative2 ();
+
+ if (S9xAPUGetByteZ (Work8) != APURegisters.YA.B.A)
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ APUShutdown ();
+ }
+ else
+ IAPU.PC += 3;
+}
+
+void Apu3D ()
+{
+// INC X
+ APURegisters.X++;
+ APUSetZN8 (APURegisters.X);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC++;
+}
+
+void ApuFC ()
+{
+// INC Y
+ APURegisters.YA.B.Y++;
+ APUSetZN8 (APURegisters.YA.B.Y);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC++;
+}
+
+void Apu1D ()
+{
+// DEC X
+ APURegisters.X--;
+ APUSetZN8 (APURegisters.X);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC++;
+}
+
+void ApuDC ()
+{
+// DEC Y
+ APURegisters.YA.B.Y--;
+ APUSetZN8 (APURegisters.YA.B.Y);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC++;
+}
+
+void ApuAB ()
+{
+// INC dp
+ Work8 = S9xAPUGetByteZ (OP1) + 1;
+ S9xAPUSetByteZ (Work8, OP1);
+ APUSetZN8 (Work8);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC += 2;
+}
+
+void ApuAC ()
+{
+// INC abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address) + 1;
+ S9xAPUSetByte (Work8, IAPU.Address);
+ APUSetZN8 (Work8);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC += 3;
+}
+
+void ApuBB ()
+{
+// INC dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) + 1;
+ S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);
+ APUSetZN8 (Work8);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC += 2;
+}
+
+void ApuBC ()
+{
+// INC A
+ APURegisters.YA.B.A++;
+ APUSetZN8 (APURegisters.YA.B.A);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC++;
+}
+
+void Apu8B ()
+{
+// DEC dp
+ Work8 = S9xAPUGetByteZ (OP1) - 1;
+ S9xAPUSetByteZ (Work8, OP1);
+ APUSetZN8 (Work8);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC += 2;
+}
+
+void Apu8C ()
+{
+// DEC abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address) - 1;
+ S9xAPUSetByte (Work8, IAPU.Address);
+ APUSetZN8 (Work8);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC += 3;
+}
+
+void Apu9B ()
+{
+// DEC dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X) - 1;
+ S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);
+ APUSetZN8 (Work8);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC += 2;
+}
+
+void Apu9C ()
+{
+// DEC A
+ APURegisters.YA.B.A--;
+ APUSetZN8 (APURegisters.YA.B.A);
+
+#ifdef SPC700_SHUTDOWN
+ IAPU.WaitCounter++;
+#endif
+
+ IAPU.PC++;
+}
+
+void Apu44 ()
+{
+// EOR A,dp
+ APURegisters.YA.B.A ^= S9xAPUGetByteZ (OP1);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu45 ()
+{
+// EOR A,abs
+ Absolute ();
+ APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu46 ()
+{
+// EOR A,(X)
+ APURegisters.YA.B.A ^= S9xAPUGetByteZ (APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu47 ()
+{
+// EOR A,(dp+X)
+ IndexedXIndirect ();
+ APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu48 ()
+{
+// EOR A,#00
+ APURegisters.YA.B.A ^= OP1;
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu49 ()
+{
+// EOR dp(dest),dp(src)
+ Work8 = S9xAPUGetByteZ (OP1);
+ Work8 ^= S9xAPUGetByteZ (OP2);
+ S9xAPUSetByteZ (Work8, OP2);
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu54 ()
+{
+// EOR A,dp+X
+ APURegisters.YA.B.A ^= S9xAPUGetByteZ (OP1 + APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu55 ()
+{
+// EOR A,abs+X
+ AbsoluteX ();
+ APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu56 ()
+{
+// EOR A,abs+Y
+ AbsoluteY ();
+ APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void Apu57 ()
+{
+// EOR A,(dp)+Y
+ IndirectIndexedY ();
+ APURegisters.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void Apu58 ()
+{
+// EOR dp,#00
+ Work8 = OP1;
+ Work8 ^= S9xAPUGetByteZ (OP2);
+ S9xAPUSetByteZ (Work8, OP2);
+ APUSetZN8 (Work8);
+ IAPU.PC += 3;
+}
+
+void Apu59 ()
+{
+// EOR (X),(Y)
+ Work8 = S9xAPUGetByteZ (APURegisters.X) ^ S9xAPUGetByteZ (APURegisters.YA.B.Y);
+ APUSetZN8 (Work8);
+ S9xAPUSetByteZ (Work8, APURegisters.X);
+ IAPU.PC++;
+}
+
+void Apu4B ()
+{
+// LSR dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ LSR (Work8);
+ S9xAPUSetByteZ (Work8, OP1);
+ IAPU.PC += 2;
+}
+
+void Apu4C ()
+{
+// LSR abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ LSR (Work8);
+ S9xAPUSetByte (Work8, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void Apu5B ()
+{
+// LSR dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ LSR (Work8);
+ S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void Apu5C ()
+{
+// LSR A
+ LSR (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu7D ()
+{
+// MOV A,X
+ APURegisters.YA.B.A = APURegisters.X;
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuDD ()
+{
+// MOV A,Y
+ APURegisters.YA.B.A = APURegisters.YA.B.Y;
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu5D ()
+{
+// MOV X,A
+ APURegisters.X = APURegisters.YA.B.A;
+ APUSetZN8 (APURegisters.X);
+ IAPU.PC++;
+}
+
+void ApuFD ()
+{
+// MOV Y,A
+ APURegisters.YA.B.Y = APURegisters.YA.B.A;
+ APUSetZN8 (APURegisters.YA.B.Y);
+ IAPU.PC++;
+}
+
+void Apu9D ()
+{
+//MOV X,SP
+ APURegisters.X = APURegisters.S;
+ APUSetZN8 (APURegisters.X);
+ IAPU.PC++;
+}
+
+void ApuBD ()
+{
+// MOV SP,X
+ APURegisters.S = APURegisters.X;
+ IAPU.PC++;
+}
+
+void Apu6B ()
+{
+// ROR dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ ROR (Work8);
+ S9xAPUSetByteZ (Work8, OP1);
+ IAPU.PC += 2;
+}
+
+void Apu6C ()
+{
+// ROR abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ROR (Work8);
+ S9xAPUSetByte (Work8, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void Apu7B ()
+{
+// ROR dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ ROR (Work8);
+ S9xAPUSetByteZ (Work8, OP1 + APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void Apu7C ()
+{
+// ROR A
+ ROR (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu6E ()
+{
+// DBNZ dp,rel
+ Work8 = OP1;
+ Relative2 ();
+ W1 = S9xAPUGetByteZ (Work8) - 1;
+ S9xAPUSetByteZ (W1, Work8);
+ if (W1 != 0)
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ }
+ else
+ IAPU.PC += 3;
+}
+
+void ApuFE ()
+{
+// DBNZ Y,rel
+ Relative ();
+ APURegisters.YA.B.Y--;
+ if (APURegisters.YA.B.Y != 0)
+ {
+ IAPU.PC = IAPU.RAM + (uint16) Int16;
+ APU.Cycles += IAPU.TwoCycles;
+ }
+ else
+ IAPU.PC += 2;
+}
+
+void Apu6F ()
+{
+// RET
+ PopW (APURegisters.PC);
+ IAPU.PC = IAPU.RAM + APURegisters.PC;
+}
+
+void Apu7F ()
+{
+// RETI
+ // STOP ("RETI");
+ Pop (APURegisters.P);
+ S9xAPUUnpackStatus ();
+ PopW (APURegisters.PC);
+ IAPU.PC = IAPU.RAM + APURegisters.PC;
+}
+
+void Apu84 ()
+{
+// ADC A,dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu85 ()
+{
+// ADC A, abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu86 ()
+{
+// ADC A,(X)
+ Work8 = S9xAPUGetByteZ (APURegisters.X);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC++;
+}
+
+void Apu87 ()
+{
+// ADC A,(dp+X)
+ IndexedXIndirect ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu88 ()
+{
+// ADC A,#00
+ Work8 = OP1;
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu89 ()
+{
+// ADC dp(dest),dp(src)
+ Work8 = S9xAPUGetByteZ (OP1);
+ W1 = S9xAPUGetByteZ (OP2);
+ ADC (W1, Work8);
+ S9xAPUSetByteZ (W1, OP2);
+ IAPU.PC += 3;
+}
+
+void Apu94 ()
+{
+// ADC A,dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu95 ()
+{
+// ADC A, abs+X
+ AbsoluteX ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu96 ()
+{
+// ADC A, abs+Y
+ AbsoluteY ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void Apu97 ()
+{
+// ADC A, (dp)+Y
+ IndirectIndexedY ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ ADC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void Apu98 ()
+{
+// ADC dp,#00
+ Work8 = OP1;
+ W1 = S9xAPUGetByteZ (OP2);
+ ADC (W1, Work8);
+ S9xAPUSetByteZ (W1, OP2);
+ IAPU.PC += 3;
+}
+
+void Apu99 ()
+{
+// ADC (X),(Y)
+ W1 = S9xAPUGetByteZ (APURegisters.X);
+ Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y);
+ ADC (W1, Work8);
+ S9xAPUSetByteZ (W1, APURegisters.X);
+ IAPU.PC++;
+}
+
+void Apu8D ()
+{
+// MOV Y,#00
+ APURegisters.YA.B.Y = OP1;
+ APUSetZN8 (APURegisters.YA.B.Y);
+ IAPU.PC += 2;
+}
+
+void Apu8F ()
+{
+// MOV dp,#00
+ Work8 = OP1;
+ S9xAPUSetByteZ (Work8, OP2);
+ IAPU.PC += 3;
+}
+
+void Apu9E ()
+{
+// DIV YA,X
+ if (APURegisters.X == 0)
+ {
+ APUSetOverflow ();
+ APURegisters.YA.B.Y = 0xff;
+ APURegisters.YA.B.A = 0xff;
+ }
+ else
+ {
+ APUClearOverflow ();
+ Work8 = APURegisters.YA.W / APURegisters.X;
+ APURegisters.YA.B.Y = APURegisters.YA.W % APURegisters.X;
+ APURegisters.YA.B.A = Work8;
+ }
+// XXX How should Overflow, Half Carry, Zero and Negative flags be set??
+ // APUSetZN16 (APURegisters.YA.W);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void Apu9F ()
+{
+// XCN A
+ APURegisters.YA.B.A = (APURegisters.YA.B.A >> 4) | (APURegisters.YA.B.A << 4);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuA4 ()
+{
+// SBC A, dp
+ Work8 = S9xAPUGetByteZ (OP1);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuA5 ()
+{
+// SBC A, abs
+ Absolute ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void ApuA6 ()
+{
+// SBC A, (X)
+ Work8 = S9xAPUGetByteZ (APURegisters.X);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC++;
+}
+
+void ApuA7 ()
+{
+// SBC A,(dp+X)
+ IndexedXIndirect ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuA8 ()
+{
+// SBC A,#00
+ Work8 = OP1;
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuA9 ()
+{
+// SBC dp(dest), dp(src)
+ Work8 = S9xAPUGetByteZ (OP1);
+ W1 = S9xAPUGetByteZ (OP2);
+ SBC (W1, Work8);
+ S9xAPUSetByteZ (W1, OP2);
+ IAPU.PC += 3;
+}
+
+void ApuB4 ()
+{
+// SBC A, dp+X
+ Work8 = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuB5 ()
+{
+// SBC A,abs+X
+ AbsoluteX ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void ApuB6 ()
+{
+// SBC A,abs+Y
+ AbsoluteY ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 3;
+}
+
+void ApuB7 ()
+{
+// SBC A,(dp)+Y
+ IndirectIndexedY ();
+ Work8 = S9xAPUGetByte (IAPU.Address);
+ SBC (APURegisters.YA.B.A, Work8);
+ IAPU.PC += 2;
+}
+
+void ApuB8 ()
+{
+// SBC dp,#00
+ Work8 = OP1;
+ W1 = S9xAPUGetByteZ (OP2);
+ SBC (W1, Work8);
+ S9xAPUSetByteZ (W1, OP2);
+ IAPU.PC += 3;
+}
+
+void ApuB9 ()
+{
+// SBC (X),(Y)
+ W1 = S9xAPUGetByteZ (APURegisters.X);
+ Work8 = S9xAPUGetByteZ (APURegisters.YA.B.Y);
+ SBC (W1, Work8);
+ S9xAPUSetByteZ (W1, APURegisters.X);
+ IAPU.PC++;
+}
+
+void ApuAF ()
+{
+// MOV (X)+, A
+ S9xAPUSetByteZ (APURegisters.YA.B.A, APURegisters.X++);
+ IAPU.PC++;
+}
+
+void ApuBE ()
+{
+// DAS
+ if ((APURegisters.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry())
+ {
+ APURegisters.YA.B.A -= 6;
+ }
+ if (APURegisters.YA.B.A > 0x9f || !IAPU._Carry)
+ {
+ APURegisters.YA.B.A -= 0x60;
+ APUClearCarry ();
+ }
+ else { APUSetCarry (); }
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuBF ()
+{
+// MOV A,(X)+
+ APURegisters.YA.B.A = S9xAPUGetByteZ (APURegisters.X++);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuC0 ()
+{
+// DI
+ APUClearInterrupt ();
+ IAPU.PC++;
+}
+
+void ApuA0 ()
+{
+// EI
+ APUSetInterrupt ();
+ IAPU.PC++;
+}
+
+void ApuC4 ()
+{
+// MOV dp,A
+ S9xAPUSetByteZ (APURegisters.YA.B.A, OP1);
+ IAPU.PC += 2;
+}
+
+void ApuC5 ()
+{
+// MOV abs,A
+ Absolute ();
+ S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void ApuC6 ()
+{
+// MOV (X), A
+ S9xAPUSetByteZ (APURegisters.YA.B.A, APURegisters.X);
+ IAPU.PC++;
+}
+
+void ApuC7 ()
+{
+// MOV (dp+X),A
+ IndexedXIndirect ();
+ S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address);
+ IAPU.PC += 2;
+}
+
+void ApuC9 ()
+{
+// MOV abs,X
+ Absolute ();
+ S9xAPUSetByte (APURegisters.X, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void ApuCB ()
+{
+// MOV dp,Y
+ S9xAPUSetByteZ (APURegisters.YA.B.Y, OP1);
+ IAPU.PC += 2;
+}
+
+void ApuCC ()
+{
+// MOV abs,Y
+ Absolute ();
+ S9xAPUSetByte (APURegisters.YA.B.Y, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void ApuCD ()
+{
+// MOV X,#00
+ APURegisters.X = OP1;
+ APUSetZN8 (APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void ApuCF ()
+{
+// MUL YA
+ APURegisters.YA.W = (uint16) APURegisters.YA.B.A * APURegisters.YA.B.Y;
+ APUSetZN16 (APURegisters.YA.W);
+ IAPU.PC++;
+}
+
+void ApuD4 ()
+{
+// MOV dp+X, A
+ S9xAPUSetByteZ (APURegisters.YA.B.A, OP1 + APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void ApuD5 ()
+{
+// MOV abs+X,A
+ AbsoluteX ();
+ S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void ApuD6 ()
+{
+// MOV abs+Y,A
+ AbsoluteY ();
+ S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address);
+ IAPU.PC += 3;
+}
+
+void ApuD7 ()
+{
+// MOV (dp)+Y,A
+ IndirectIndexedY ();
+ S9xAPUSetByte (APURegisters.YA.B.A, IAPU.Address);
+ IAPU.PC += 2;
+}
+
+void ApuD8 ()
+{
+// MOV dp,X
+ S9xAPUSetByteZ (APURegisters.X, OP1);
+ IAPU.PC += 2;
+}
+
+void ApuD9 ()
+{
+// MOV dp+Y,X
+ S9xAPUSetByteZ (APURegisters.X, OP1 + APURegisters.YA.B.Y);
+ IAPU.PC += 2;
+}
+
+void ApuDB ()
+{
+// MOV dp+X,Y
+ S9xAPUSetByteZ (APURegisters.YA.B.Y, OP1 + APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void ApuDF ()
+{
+// DAA
+ if ((APURegisters.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry())
+ {
+ if(APURegisters.YA.B.A > 0xf0) APUSetCarry ();
+ APURegisters.YA.B.A += 6;
+ //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc...
+ }
+ //else { APUClearHalfCarry (); } ditto as above
+ if (APURegisters.YA.B.A > 0x9f || IAPU._Carry)
+ {
+ APURegisters.YA.B.A += 0x60;
+ APUSetCarry ();
+ }
+ else { APUClearCarry (); }
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuE4 ()
+{
+// MOV A, dp
+ APURegisters.YA.B.A = S9xAPUGetByteZ (OP1);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void ApuE5 ()
+{
+// MOV A,abs
+ Absolute ();
+ APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void ApuE6 ()
+{
+// MOV A,(X)
+ APURegisters.YA.B.A = S9xAPUGetByteZ (APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC++;
+}
+
+void ApuE7 ()
+{
+// MOV A,(dp+X)
+ IndexedXIndirect ();
+ APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void ApuE8 ()
+{
+// MOV A,#00
+ APURegisters.YA.B.A = OP1;
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void ApuE9 ()
+{
+// MOV X, abs
+ Absolute ();
+ APURegisters.X = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.X);
+ IAPU.PC += 3;
+}
+
+void ApuEB ()
+{
+// MOV Y,dp
+ APURegisters.YA.B.Y = S9xAPUGetByteZ (OP1);
+ APUSetZN8 (APURegisters.YA.B.Y);
+ IAPU.PC += 2;
+}
+
+void ApuEC ()
+{
+// MOV Y,abs
+ Absolute ();
+ APURegisters.YA.B.Y = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.Y);
+ IAPU.PC += 3;
+}
+
+void ApuF4 ()
+{
+// MOV A, dp+X
+ APURegisters.YA.B.A = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void ApuF5 ()
+{
+// MOV A, abs+X
+ AbsoluteX ();
+ APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void ApuF6 ()
+{
+// MOV A, abs+Y
+ AbsoluteY ();
+ APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 3;
+}
+
+void ApuF7 ()
+{
+// MOV A, (dp)+Y
+ IndirectIndexedY ();
+ APURegisters.YA.B.A = S9xAPUGetByte (IAPU.Address);
+ APUSetZN8 (APURegisters.YA.B.A);
+ IAPU.PC += 2;
+}
+
+void ApuF8 ()
+{
+// MOV X,dp
+ APURegisters.X = S9xAPUGetByteZ (OP1);
+ APUSetZN8 (APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void ApuF9 ()
+{
+// MOV X,dp+Y
+ APURegisters.X = S9xAPUGetByteZ (OP1 + APURegisters.YA.B.Y);
+ APUSetZN8 (APURegisters.X);
+ IAPU.PC += 2;
+}
+
+void ApuFA ()
+{
+// MOV dp(dest),dp(src)
+ S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2);
+ IAPU.PC += 3;
+}
+
+void ApuFB ()
+{
+// MOV Y,dp+X
+ APURegisters.YA.B.Y = S9xAPUGetByteZ (OP1 + APURegisters.X);
+ APUSetZN8 (APURegisters.YA.B.Y);
+ IAPU.PC += 2;
+}
+
+#ifdef NO_INLINE_SET_GET
+#undef INLINE
+#define INLINE
+#include "apumem.h"
+#endif
+
+void (*S9xApuOpcodes[256]) (void) =
+{
+ Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07,
+ Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F,
+ Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17,
+ Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F,
+ Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27,
+ Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F,
+ Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37,
+ Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F,
+ Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47,
+ Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F,
+ Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57,
+ Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F,
+ Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67,
+ Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F,
+ Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77,
+ Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F,
+ Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87,
+ Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F,
+ Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97,
+ Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F,
+ ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7,
+ ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF,
+ ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7,
+ ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF,
+ ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7,
+ ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF,
+ ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7,
+ ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF,
+ ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7,
+ ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF,
+ ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7,
+ ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF
+};
+
diff --git a/source/spc700.h b/source/spc700.h
new file mode 100644
index 0000000..3d09fee
--- /dev/null
+++ b/source/spc700.h
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _SPC700_H_
+#define _SPC700_H_
+
+#ifdef SPCTOOL
+#define NO_CHANNEL_STRUCT
+#include "spctool/dsp.h"
+#include "spctool/spc700.h"
+#include "spctool/soundmod.h"
+#endif
+
+#define Carry 1
+#define Zero 2
+#define Interrupt 4
+#define HalfCarry 8
+#define BreakFlag 16
+#define DirectPageFlag 32
+#define Overflow 64
+#define Negative 128
+
+#define APUClearCarry() (IAPU._Carry = 0)
+#define APUSetCarry() (IAPU._Carry = 1)
+#define APUSetInterrupt() (APURegisters.P |= Interrupt)
+#define APUClearInterrupt() (APURegisters.P &= ~Interrupt)
+#define APUSetHalfCarry() (APURegisters.P |= HalfCarry)
+#define APUClearHalfCarry() (APURegisters.P &= ~HalfCarry)
+#define APUSetBreak() (APURegisters.P |= BreakFlag)
+#define APUClearBreak() (APURegisters.P &= ~BreakFlag)
+#define APUSetDirectPage() (APURegisters.P |= DirectPageFlag)
+#define APUClearDirectPage() (APURegisters.P &= ~DirectPageFlag)
+#define APUSetOverflow() (IAPU._Overflow = 1)
+#define APUClearOverflow() (IAPU._Overflow = 0)
+
+#define APUCheckZero() (IAPU._Zero == 0)
+#define APUCheckCarry() (IAPU._Carry)
+#define APUCheckInterrupt() (APURegisters.P & Interrupt)
+#define APUCheckHalfCarry() (APURegisters.P & HalfCarry)
+#define APUCheckBreak() (APURegisters.P & BreakFlag)
+#define APUCheckDirectPage() (APURegisters.P & DirectPageFlag)
+#define APUCheckOverflow() (IAPU._Overflow)
+#define APUCheckNegative() (IAPU._Zero & 0x80)
+
+#define APUClearFlags(f) (APURegisters.P &= ~(f))
+#define APUSetFlags(f) (APURegisters.P |= (f))
+#define APUCheckFlag(f) (APURegisters.P & (f))
+
+typedef union
+{
+#ifdef LSB_FIRST
+ struct { uint8 A, Y; } B;
+#else
+ struct { uint8 Y, A; } B;
+#endif
+ uint16 W;
+} YAndA;
+
+struct SAPURegisters{
+ uint8 P;
+ YAndA YA;
+ uint8 X;
+ uint8 S;
+ uint16 PC;
+};
+
+EXTERN_C struct SAPURegisters APURegisters;
+
+// Needed by ILLUSION OF GAIA
+//#define ONE_APU_CYCLE 14
+#define ONE_APU_CYCLE 21
+
+// Needed by all games written by the software company called Human
+//#define ONE_APU_CYCLE_HUMAN 17
+#define ONE_APU_CYCLE_HUMAN 21
+
+// 1.953us := 1.024065.54MHz
+
+#ifdef SPCTOOL
+EXTERN_C int32 ESPC (int32);
+
+#define APU_EXECUTE() \
+{ \
+ int32 l = (CPU.Cycles - APU.Cycles) / 14; \
+ if (l > 0) \
+ { \
+ l -= _EmuSPC(l); \
+ APU.Cycles += l * 14; \
+ } \
+}
+
+#else
+
+#ifdef DEBUGGER
+#define APU_EXECUTE1() \
+{ \
+ if (APU.Flags & TRACE_FLAG) \
+ S9xTraceAPU ();\
+ APU.Cycles += S9xAPUCycles [*IAPU.PC]; \
+ (*S9xApuOpcodes[*IAPU.PC]) (); \
+}
+#else
+#define APU_EXECUTE1() \
+{ \
+ APU.Cycles += S9xAPUCycles [*IAPU.PC]; \
+ (*S9xApuOpcodes[*IAPU.PC]) (); \
+}
+#endif
+
+#define APU_EXECUTE() \
+if (IAPU.APUExecuting) \
+{\
+ while (APU.Cycles <= CPU.Cycles) \
+ APU_EXECUTE1(); \
+}
+#endif
+
+#endif
+
diff --git a/source/spc7110.cpp b/source/spc7110.cpp
new file mode 100644
index 0000000..970b214
--- /dev/null
+++ b/source/spc7110.cpp
@@ -0,0 +1,2312 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+//#define SPC7110_DEBUG
+
+#include "spc7110.h"
+#include "memmap.h"
+#include <time.h>
+#include <sys/stat.h>
+
+//Windows includes
+#ifdef __WIN32__
+#ifndef _XBOX // chdir and getcwd not supported on Xbox hardware
+#include <direct.h>
+#define chdir _chdir
+#define getcwd _getcwd
+#endif
+#define FREEZEFOLDER GUI.FreezeFileDir
+//zinx suggested this, for *nix compatibility
+#define PATH_MAX MAX_PATH
+#else // Unix
+#include "display.h"
+#include <limits.h>
+#include <unistd.h>
+#define FREEZEFOLDER S9xGetSnapshotDirectory ()
+#endif
+
+extern "C" const char *S9xGetFilename (const char *);
+extern "C" char *osd_GetPackDir();
+//really not needed, but usually MS adds the _ to POSIX functions,
+//while *nix doesn't, so this was to "un-M$" the function.
+#define splitpath _splitpath
+
+//not much headroom, but FEOEZ has 41 tables, I think, and SPL4 has 38.
+#define MAX_TABLES 48
+
+//default to using 5 megs of RAM for method 3 caching.
+uint16 cacheMegs=5;
+
+//using function pointers to initialize cache management
+void (*CleanUp7110)(void)=NULL;
+void (*LoadUp7110)(char*)=&SPC7110Load;
+void (*Copy7110)(void)=NULL;
+
+//size and offset of the pack data
+//offset and size of reads from pack
+typedef struct SPC7110DecompressionLocationStruct
+{
+ uint32 offset;
+ uint32 size;
+ uint16 used_offset;
+ uint16 used_len;
+} Data7110;
+
+//this maps an index.bin table to the decompression pack
+typedef struct SPC7110DecompressionIndexStruct
+{
+ int table;
+ bool is_file;
+ Data7110 location[256];
+} Index7110;
+
+//this contains all the data for the decompression pack.
+typedef struct SPC7110DecompressionPackStructure
+{
+ uint8* binfiles[MAX_TABLES];
+ Index7110 tableEnts[MAX_TABLES];
+ int last_table;
+ int idx;
+ uint8 last_idx;
+ uint16 last_offset;
+} Pack7110;
+
+
+char pfold[9]; //hack variable for log naming (each game makes a different log)
+Pack7110* decompack=NULL; //decompression pack uses a fair chunk of RAM, so dynalloc it.
+SPC7110Regs s7r; //SPC7110 registers, about 33KB
+S7RTC rtc_f9; //FEOEZ (and Shounen Jump no SHou) RTC
+void S9xUpdateRTC (); //S-RTC function hacked to work with the RTC
+
+//Emulate power on state
+void S9xSpc7110Init()
+{
+ s7r.DataRomOffset=0x00100000;//handy constant!
+ s7r.DataRomSize=Memory.CalculatedSize-s7r.DataRomOffset;
+ s7r.reg4800=0;
+ s7r.reg4801=0;
+ s7r.reg4802=0;
+ s7r.reg4803=0;
+ s7r.reg4804=0;
+ s7r.reg4805=0;
+ s7r.reg4806=0;
+ s7r.reg4807=0;
+ s7r.reg4808=0;
+ s7r.reg4809=0;
+ s7r.reg480A=0;
+ s7r.reg480B=0;
+ s7r.reg480C=0;
+ s7r.reg4811=0;
+ s7r.reg4812=0;
+ s7r.reg4813=0;
+ s7r.reg4814=0;
+ s7r.reg4815=0;
+ s7r.reg4816=0;
+ s7r.reg4817=0;
+ s7r.reg4818=0;
+ s7r.reg4820=0;
+ s7r.reg4821=0;
+ s7r.reg4822=0;
+ s7r.reg4823=0;
+ s7r.reg4824=0;
+ s7r.reg4825=0;
+ s7r.reg4826=0;
+ s7r.reg4827=0;
+ s7r.reg4828=0;
+ s7r.reg4829=0;
+ s7r.reg482A=0;
+ s7r.reg482B=0;
+ s7r.reg482C=0;
+ s7r.reg482D=0;
+ s7r.reg482E=0;
+ s7r.reg482F=0;
+ s7r.reg4830=0;
+ s7r.reg4831=0;
+ s7r.reg4832=1;
+ s7r.reg4833=2;
+ s7r.reg4834=0;
+ s7r.reg4840=0;
+ s7r.reg4841=0;
+ s7r.reg4842=0;
+ s7r.written=0;
+ s7r.offset_add=0;
+ s7r.AlignBy=1;
+
+ (*LoadUp7110)(osd_GetPackDir());
+
+ if(Settings.SPC7110RTC)
+ Settings.TurboMode=false;
+
+ s7r.bank50Internal=0;
+ memset(s7r.bank50,0x00,DECOMP_BUFFER_SIZE);
+}
+
+
+//full cache decompression routine (memcpy) Method 1
+void MovePackData()
+{
+ //log the last entry
+ Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]);
+ if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)s7r.bank50Internal))
+ {
+ log->used_len=s7r.bank50Internal;
+ log->used_offset=decompack->last_offset;
+ }
+
+ //set up for next logging
+ decompack->last_offset=(s7r.reg4805)|(s7r.reg4806<<8);
+
+ decompack->last_idx=s7r.reg4804;
+
+ //start decompression
+ int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801;
+
+ //the table is a offset multiplier byte and a big-endian pointer
+ int j= 4*s7r.reg4804;
+ j+=s7r.DataRomOffset;
+ j+=table;
+
+ //set proper offsetting.
+ if(s7r.reg480B==0)
+ s7r.AlignBy=0;
+ else
+ {
+ switch(ROM[j])
+ {
+ case 0x03:
+ s7r.AlignBy=8;
+ break;
+ case 0x01:
+ s7r.AlignBy=2;
+ break;
+ case 0x02:
+ s7r.AlignBy=4;
+ break;
+ case 0x00:
+ default:
+ s7r.AlignBy=1;
+ break;
+ }
+ }
+ //note that we are still setting up for the next log.
+ decompack->last_offset*=s7r.AlignBy;
+ decompack->last_offset%=DECOMP_BUFFER_SIZE;
+
+ //find the table
+ if(table!=decompack->last_table)
+ {
+ int i=0;
+ while(i<MAX_TABLES&&decompack->tableEnts[i].table!=table)
+ i++;
+ if(i==MAX_TABLES)
+ {
+#ifdef _XBOX
+ FILE* fp=fopen("T:\\sp7err.out","a");
+#else
+ FILE* fp=fopen("sp7err.out","a");
+#endif
+
+// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804);
+ fclose(fp);
+ return;
+ }
+ decompack->idx=i;
+ decompack->last_table=table;
+ }
+
+ //copy data
+ if(decompack->binfiles[decompack->idx])
+ {
+ memcpy(s7r.bank50,
+ &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]),
+ decompack->tableEnts[decompack->idx].location[s7r.reg4804].size);
+ }
+}
+
+
+//this is similar to the last function, but it keeps the last 5 accessed files open,
+// and reads the data directly. Method 2
+void ReadPackData()
+{
+ static int table_age_2;
+ static int table_age_3;
+ static int table_age_4;
+ static int table_age_5;
+
+ int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801;
+
+ if(table==0)
+ {
+ table_age_2=table_age_3=table_age_4=table_age_5=MAX_TABLES;
+ return;
+ }
+
+ if(table_age_2==0&&table_age_3==0&&table_age_4==0&&table_age_5==0)
+ table_age_2=table_age_3=table_age_4=table_age_5=MAX_TABLES;
+ Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]);
+ if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)s7r.bank50Internal))
+ {
+ log->used_len=s7r.bank50Internal;
+ log->used_offset=decompack->last_offset;
+ }
+
+ decompack->last_offset=(s7r.reg4805)|(s7r.reg4806<<8);
+
+ decompack->last_idx=s7r.reg4804;
+
+ int j= 4*s7r.reg4804;
+ j+=s7r.DataRomOffset;
+ j+=table;
+
+ if(s7r.reg480B==0)
+ s7r.AlignBy=0;
+ else
+ {
+ switch(ROM[j])
+ {
+ case 0x03:
+ s7r.AlignBy=8;
+ break;
+ case 0x01:
+ s7r.AlignBy=2;
+ break;
+ case 0x02:
+ s7r.AlignBy=4;
+ break;
+ case 0x00:
+ default:
+ s7r.AlignBy=1;
+ break;
+ }
+ }
+ decompack->last_offset*=s7r.AlignBy;
+ decompack->last_offset%=DECOMP_BUFFER_SIZE;
+ if(table!=decompack->last_table)
+ {
+ int i=0;
+ while(i<MAX_TABLES&&decompack->tableEnts[i].table!=table)
+ i++;
+ if(i==MAX_TABLES)
+ {
+ FILE* fp=fopen("sp7err.out","a");
+// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804);
+ fclose(fp);
+ return;
+ }
+ if(i!= table_age_2 && i!= table_age_3 && i!= table_age_4 && i!= table_age_5)
+ {
+ if(table_age_5!=MAX_TABLES&&decompack->binfiles[table_age_5])
+ {
+ fclose((FILE*)(decompack->binfiles[table_age_5]));
+ (decompack->binfiles[table_age_5])=NULL;
+ }
+ table_age_5=table_age_4;
+ table_age_4=table_age_3;
+ table_age_3=table_age_2;
+ table_age_2=decompack->idx;
+ char name[PATH_MAX];
+ //open file
+ char drive [_MAX_DRIVE + 1];
+ char dir [_MAX_DIR + 1];
+ char fname [_MAX_FNAME + 1];
+ char ext [_MAX_EXT + 1];
+ if (strlen (FREEZEFOLDER))
+ {
+ //splitpath (Memory.ROMFilename, drive, dir, fname, ext);
+ strcpy (name, FREEZEFOLDER);
+ strcat (name, "/");
+ }
+ else
+ {
+ splitpath (Memory.ROMFilename, drive, dir, fname, ext);
+ strcpy(name, drive);
+ //strcat(filename, "\\");
+ strcat(name, dir);
+ }
+ strcat(name, pfold);
+ char bfname[11];
+ sprintf(bfname, "%06X.bin", table);
+ strcat(name, "/");
+ strcat(name, bfname);
+ decompack->binfiles[i]=(uint8*)fopen(name, "rb");
+ }
+ else
+ {
+ //fix tables in this case
+ if(table_age_5==i)
+ {
+ table_age_5=table_age_4;
+ table_age_4=table_age_3;
+ table_age_3=table_age_2;
+ table_age_2=decompack->idx;
+ }
+ if(table_age_4==i)
+ {
+ table_age_4=table_age_3;
+ table_age_3=table_age_2;
+ table_age_2=decompack->idx;
+ }
+ if(table_age_3==i)
+ {
+ table_age_3=table_age_2;
+ table_age_2=decompack->idx;
+ }
+ if(table_age_2==i)
+ {
+ table_age_2=decompack->idx;
+ }
+ }
+ decompack->idx=i;
+ decompack->last_table=table;
+ }
+ //do read here.
+ if(decompack->binfiles[decompack->idx])
+ {
+ fseek((FILE*)(decompack->binfiles[decompack->idx]), decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0);
+ fread(s7r.bank50,1, (decompack->tableEnts[decompack->idx].location[s7r.reg4804].size), (FILE*)(decompack->binfiles[decompack->idx]));
+ }
+}
+
+//Cache Method 3: some entries are cached, others are file handles.
+//use is_file to distinguish.
+void GetPackData()
+{
+ Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]);
+ if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)s7r.bank50Internal))
+ {
+ log->used_len=s7r.bank50Internal;
+ log->used_offset=decompack->last_offset;
+ }
+
+ decompack->last_offset=(s7r.reg4805)|(s7r.reg4806<<8);
+
+ decompack->last_idx=s7r.reg4804;
+ int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801;
+
+ int j= 4*s7r.reg4804;
+ j+=s7r.DataRomOffset;
+ j+=table;
+
+ if(s7r.reg480B==0)
+ s7r.AlignBy=0;
+ else
+ {
+ switch(ROM[j])
+ {
+ case 0x03:
+ s7r.AlignBy=8;
+ break;
+ case 0x01:
+ s7r.AlignBy=2;
+ break;
+ case 0x02:
+ s7r.AlignBy=4;
+ break;
+ case 0x00:
+ default:
+ s7r.AlignBy=1;
+ break;
+ }
+ }
+ decompack->last_offset*=s7r.AlignBy;
+ decompack->last_offset%=DECOMP_BUFFER_SIZE;
+ if(table!=decompack->last_table)
+ {
+ int i=0;
+ while(i<MAX_TABLES&&decompack->tableEnts[i].table!=table)
+ i++;
+ if(i==MAX_TABLES)
+ {
+ FILE* fp=fopen("sp7err.out","a");
+// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804);
+ fclose(fp);
+ return;
+ }
+ decompack->idx=i;
+ decompack->last_table=table;
+ }
+ if(decompack->binfiles[decompack->idx])
+ {
+ if(decompack->tableEnts[decompack->idx].is_file)
+ {
+ fseek((FILE*)decompack->binfiles[decompack->idx], decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0);
+ fread(s7r.bank50,1, (decompack->tableEnts[decompack->idx].location[s7r.reg4804].size), (FILE*)(decompack->binfiles[decompack->idx]));
+ }
+ else
+ {
+ memcpy(s7r.bank50,
+ &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]),
+ decompack->tableEnts[decompack->idx].location[s7r.reg4804].size);
+ }
+ }
+}
+
+extern "C"{
+//reads SPC7110 and RTC registers.
+uint8 S9xGetSPC7110(uint16 Address)
+{
+#ifdef SPC7110_DEBUG
+ printf("%04X read\n", Address);
+#endif
+ switch (Address)
+ {
+ //decompressed data read port. decrements 4809-A (with wrap)
+ //4805-6 is the offset into the bank
+ //AlignBy is set (afaik) at decompression time, and is the offset multiplier
+ //bank50internal is an internal pointer to the actual byte to read.
+ //so you read from offset*multiplier + bank50internal
+ //the offset registers cannot be incremented due to the offset multiplier.
+ case 0x4800:
+ {
+ unsigned short count=s7r.reg4809|(s7r.reg480A<<8);
+ uint32 i, j;
+ j=(s7r.reg4805|(s7r.reg4806<<8));
+ j*=s7r.AlignBy;
+ i=j;
+ if(count >0)
+ count--;
+ else count = 0xFFFF;
+ s7r.reg4809=0x00ff&count;
+ s7r.reg480A=(0xff00&count)>>8;
+ i+=s7r.bank50Internal;
+ i%=DECOMP_BUFFER_SIZE;
+ s7r.reg4800=s7r.bank50[i];
+
+ s7r.bank50Internal++;
+ s7r.bank50Internal%=DECOMP_BUFFER_SIZE;
+#ifdef SPC7110_DEBUG
+ printf("Returned %02X\n", s7r.reg4800);
+#endif
+ }
+ return s7r.reg4800;
+ //table register low
+ case 0x4801: return s7r.reg4801;
+ //table register middle
+ case 0x4802: return s7r.reg4802;
+ //table register high
+ case 0x4803: return s7r.reg4803;
+ //index of pointer in table (each entry is 4 bytes)
+ case 0x4804: return s7r.reg4804;
+ //offset register low
+ case 0x4805: return s7r.reg4805;
+ //offset register high
+ case 0x4806: return s7r.reg4806;
+ //DMA channel (not that I see this usually set,
+ //regardless of what channel DMA is on)
+ case 0x4807: return s7r.reg4807;
+ //C r/w option, unknown, defval:00 is what Dark Force says
+ //afaict, Snes9x doesn't use this at all.
+ case 0x4808: return s7r.reg4808;
+ //C-Length low
+ //counts down the number of bytes left to read from the decompression buffer.
+ //this is set by the ROM, and wraps on bounds.
+ case 0x4809: return s7r.reg4809;
+ //C Length high
+ case 0x480A: return s7r.reg480A;
+ //Offset enable.
+ //if this is zero, 4805-6 are useless. Emulated by setting AlignBy to 0
+ case 0x480B:
+ return s7r.reg480B;
+ //decompression finished: just emulated by switching each read.
+ case 0x480C:
+ s7r.reg480C^=0x80;
+ return s7r.reg480C^0x80;
+
+ //Data access port
+ //reads from the data ROM (anywhere over the first 8 mbits
+ //behavior is complex, will document later,
+ //possibly missing cases, because of the number of switches in play
+ case 0x4810:
+ if(s7r.written==0)
+ return 0;
+ if((s7r.written&0x07)==0x07)
+ {
+ uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811;
+ i%=s7r.DataRomSize;
+ if(s7r.reg4818&0x02)
+ {
+ if(s7r.reg4818&0x08)
+ {
+ signed short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ i+=r4814;
+ r4814++;
+ s7r.reg4815=(uint8)(r4814>>8);
+ s7r.reg4814=(uint8)(r4814&0x00FF);
+ }
+ else
+ {
+ unsigned short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ i+=r4814;
+ if(r4814!=0xFFFF)
+ r4814++;
+ else r4814=0;
+ s7r.reg4815=(uint8)(r4814>>8);
+ s7r.reg4814=(uint8)(r4814&0x00FF);
+
+ }
+ }
+ i+=s7r.DataRomOffset;
+ uint8 tmp=ROM[i];
+ i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811;
+
+ if(s7r.reg4818&0x02)
+ {
+ }
+ else if(s7r.reg4818&0x01)
+ {
+ if(s7r.reg4818&0x04)
+ {
+ signed short inc;
+ inc=(s7r.reg4817<<8)|s7r.reg4816;
+
+ if(!(s7r.reg4818&0x10))
+ i+=inc;
+ else
+ {
+ if(s7r.reg4818&0x08)
+ {
+ signed short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ r4814+=inc;
+ s7r.reg4815=(r4814&0xFF00)>>8;
+ s7r.reg4814=r4814&0xFF;
+ }
+ else
+ {
+ unsigned short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ r4814+=inc;
+ s7r.reg4815=(r4814&0xFF00)>>8;
+ s7r.reg4814=r4814&0xFF;
+
+ }
+ }
+ //is signed
+ }
+ else
+ {
+ uint16 inc;
+ inc=(s7r.reg4817<<8)|s7r.reg4816;
+ if(!(s7r.reg4818&0x10))
+ i+=inc;
+ else
+ {
+ if(s7r.reg4818&0x08)
+ {
+ signed short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ r4814+=inc;
+ s7r.reg4815=(r4814&0xFF00)>>8;
+ s7r.reg4814=r4814&0xFF;
+ }
+ else
+ {
+ unsigned short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ r4814+=inc;
+ s7r.reg4815=(r4814&0xFF00)>>8;
+ s7r.reg4814=r4814&0xFF;
+
+ }
+ }
+ }
+ }
+ else
+ {
+ if(!(s7r.reg4818&0x10))
+ i+=1;
+ else
+ {
+ if(s7r.reg4818&0x08)
+ {
+ signed short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ r4814+=1;
+ s7r.reg4815=(r4814&0xFF00)>>8;
+ s7r.reg4814=r4814&0xFF;
+ }
+ else
+ {
+ unsigned short r4814;
+ r4814=(s7r.reg4815<<8)|s7r.reg4814;
+ r4814+=1;
+ s7r.reg4815=(r4814&0xFF00)>>8;
+ s7r.reg4814=r4814&0xFF;
+
+ }
+ }
+ }
+
+#ifdef SPC7110_DEBUG
+ printf("Returned %02X\n", tmp);
+#endif
+
+ i%=s7r.DataRomSize;
+ s7r.reg4811=i&0x00FF;
+ s7r.reg4812=(i&0x00FF00)>>8;
+ s7r.reg4813=((i&0xFF0000)>>16);
+ return tmp;
+ }
+ else return 0;
+ //direct read address low
+ case 0x4811: return s7r.reg4811;
+ //direct read address middle
+ case 0x4812: return s7r.reg4812;
+ //direct read access high
+ case 0x4813: return s7r.reg4813;
+ //read adjust low
+ case 0x4814: return s7r.reg4814;
+ //read adjust high
+ case 0x4815: return s7r.reg4815;
+ //read increment low
+ case 0x4816: return s7r.reg4816;
+ //read increment high
+ case 0x4817: return s7r.reg4817;
+ //Data ROM command mode
+ //essentially, this controls the insane code of $4810 and $481A
+ case 0x4818: return s7r.reg4818;
+ //read after adjust port
+ //what this does, besides more nasty stuff like 4810,
+ //I don't know. Just assume it is a different implementation of $4810,
+ //if it helps your sanity
+ case 0x481A:
+ if(s7r.written==0x1F)
+ {
+ uint32 i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811);
+ if(s7r.reg4818&0x08)
+ {
+ short adj;
+ adj=((short)(s7r.reg4815<<8))|s7r.reg4814;
+ i+=adj;
+ }
+ else
+ {
+ uint16 adj;
+ adj=(s7r.reg4815<<8)|s7r.reg4814;
+ i+=adj;
+ }
+
+ i%=s7r.DataRomSize;
+ i+=s7r.DataRomOffset;
+ uint8 tmp=ROM[i];
+ i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811);
+ if(0x60==(s7r.reg4818&0x60))
+ {
+ i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811);
+
+ if(!(s7r.reg4818&0x10))
+ {
+ if(s7r.reg4818&0x08)
+ {
+ short adj;
+ adj=((short)(s7r.reg4815<<8))|s7r.reg4814;
+ i+=adj;
+ }
+ else
+ {
+ uint16 adj;
+ adj=(s7r.reg4815<<8)|s7r.reg4814;
+ i+=adj;
+ }
+ i%=s7r.DataRomSize;
+ s7r.reg4811=i&0x00FF;
+ s7r.reg4812=(i&0x00FF00)>>8;
+ s7r.reg4813=((i&0xFF0000)>>16);
+ }
+ else
+ {
+ if(s7r.reg4818&0x08)
+ {
+ short adj;
+ adj=((short)(s7r.reg4815<<8))|s7r.reg4814;
+ adj+=adj;
+ s7r.reg4815=(adj&0xFF00)>>8;
+ s7r.reg4814=adj&0xFF;
+ }
+ else
+ {
+ uint16 adj;
+ adj=(s7r.reg4815<<8)|s7r.reg4814;
+ adj+=adj;
+ s7r.reg4815=(adj&0xFF00)>>8;
+ s7r.reg4814=adj&0xFF;
+ }
+ }
+ }
+#ifdef SPC7110_DEBUG
+ printf("Returned %02X\n", tmp);
+#endif
+ return tmp;
+ }
+ else return 0;
+
+ //multiplicand low or dividend lowest
+ case 0x4820: return s7r.reg4820;
+ //multiplicand high or divdend lower
+ case 0x4821: return s7r.reg4821;
+ //dividend higher
+ case 0x4822: return s7r.reg4822;
+ //dividend highest
+ case 0x4823: return s7r.reg4823;
+ //multiplier low
+ case 0x4824: return s7r.reg4824;
+ //multiplier high
+ case 0x4825: return s7r.reg4825;
+ //divisor low
+ case 0x4826: return s7r.reg4826;
+ //divisor high
+ case 0x4827: return s7r.reg4827;
+
+ //result lowest
+ case 0x4828:
+ return s7r.reg4828;
+ //result lower
+ case 0x4829:
+ return s7r.reg4829;
+ //result higher
+ case 0x482A:
+ return s7r.reg482A;
+ //result highest
+ case 0x482B:
+ return s7r.reg482B;
+ //remainder (division) low
+ case 0x482C: return s7r.reg482C;
+ //remainder (division) high
+ case 0x482D: return s7r.reg482D;
+ //signed/unsigned
+ case 0x482E: return s7r.reg482E;
+ //finished flag, emulated as an on-read toggle.
+ case 0x482F:
+ if(s7r.reg482F)
+ {
+ s7r.reg482F=0;
+ return 0x80;
+ }
+ return 0;
+ break;
+
+ //SRAM toggle
+ case 0x4830:
+ return s7r.reg4830;
+ //DX bank mapping
+ case 0x4831:
+ return s7r.reg4831;
+ //EX bank mapping
+ case 0x4832:
+ return s7r.reg4832;
+ //FX bank mapping
+ case 0x4833:
+ return s7r.reg4833;
+ //SRAM mapping? We have no clue!
+ case 0x4834:
+ return s7r.reg4834;
+//RTC enable
+ case 0x4840:
+ if(!Settings.SPC7110RTC)
+ return Address>>8;
+ return s7r.reg4840;
+//command/index/value of RTC (essentially, zero unless we're in read mode
+ case 0x4841:
+ if(!Settings.SPC7110RTC)
+ return Address>>8;
+ if(rtc_f9.init)
+ {
+ S9xUpdateRTC();
+ uint8 tmp=rtc_f9.reg[rtc_f9.index];
+ rtc_f9.index++;
+ rtc_f9.index%=0x10;
+#ifdef SPC7110_DEBUG
+ printf("$4841 returned %02X\n", tmp);
+#endif
+ return tmp;
+ }
+ else return 0;
+//RTC done flag
+ case 0x4842:
+ if(!Settings.SPC7110RTC)
+ return Address>>8;
+ s7r.reg4842^=0x80;
+ return s7r.reg4842^0x80;
+ default:
+#ifdef SPC7110_DEBUG
+ printf("Access to Reg %04X\n", Address);
+#endif
+ return 0x00;
+ }
+}
+}
+void S9xSetSPC7110 (uint8 data, uint16 Address)
+{
+#ifdef SPC7110_DEBUG
+ printf("%04X written to, value %02X\n", Address, data);
+#endif
+ switch(Address)
+ {
+//Writes to $4800 are undefined.
+
+ //table low, middle, and high.
+ case 0x4801:
+ s7r.reg4801=data;
+ break;
+ case 0x4802:
+ s7r.reg4802=data;
+ break;
+ case 0x4803:
+ s7r.reg4803=data;
+ break;
+
+ //table index (4 byte entries, bigendian with a multiplier byte)
+ case 0x4804:
+ s7r.reg4804=data;
+ break;
+
+ //offset low
+ case 0x4805:
+ s7r.reg4805=data;
+ break;
+
+ //offset high, starts decompression
+ case 0x4806:
+ s7r.reg4806=data;
+ (*Copy7110)();
+ s7r.bank50Internal=0;
+ s7r.reg480C&=0x7F;
+ break;
+
+ //DMA channel register (Is it used??)
+ case 0x4807:
+ s7r.reg4807=data;
+ break;
+
+ //C r/w? I have no idea. If you get weird values written here before a bug,
+ //The Dumper should probably be contacted about running a test.
+ case 0x4808:
+ s7r.reg4808=data;
+ break;
+
+ //C-Length low
+ case 0x4809:
+ s7r.reg4809=data;
+ break;
+ //C-Length high
+ case 0x480A:
+ s7r.reg480A=data;
+ break;
+
+ //Offset enable
+ case 0x480B:
+ {
+ s7r.reg480B=data;
+ int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801;
+
+ int j= 4*s7r.reg4804;
+ j+=s7r.DataRomOffset;
+ j+=table;
+
+ if(s7r.reg480B==0)
+ s7r.AlignBy=0;
+ else
+ {
+ switch(ROM[j])
+ {
+ case 0x03:
+ s7r.AlignBy=8;
+ break;
+ case 0x01:
+ s7r.AlignBy=2;
+ break;
+ case 0x02:
+ s7r.AlignBy=4;
+ break;
+ case 0x00:
+ default:
+ s7r.AlignBy=1;
+ break;
+ }
+ }
+// s7r.decomp_set=true;
+ }
+ break;
+//$4810 is probably read only.
+
+ //Data port address low
+ case 0x4811:
+ s7r.reg4811=data;
+ s7r.written|=0x01;
+ break;
+
+ //data port address middle
+ case 0x4812:
+ s7r.reg4812=data;
+ s7r.written|=0x02;
+ break;
+
+ //data port address high
+ case 0x4813:
+ s7r.reg4813=data;
+ s7r.written|=0x04;
+ break;
+
+ //data port adjust low (has a funky immediate increment mode)
+ case 0x4814:
+ s7r.reg4814=data;
+ if(s7r.reg4818&0x02)
+ {
+ if((s7r.reg4818&0x20)&&!(s7r.reg4818&0x40))
+ {
+ s7r.offset_add|=0x01;
+ if(s7r.offset_add==3)
+ {
+ if(s7r.reg4818&0x10)
+ {
+ }
+ else
+ {
+ uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811;
+ if(s7r.reg4818&0x08)
+ {
+ i+=(signed char)s7r.reg4814;
+ }
+ else
+ {
+ i+=s7r.reg4814;
+ }
+ i%=s7r.DataRomSize;
+ s7r.reg4811=i&0x00FF;
+ s7r.reg4812=(i&0x00FF00)>>8;
+ s7r.reg4813=((i&0xFF0000)>>16);
+ }
+ }
+ }
+ else if((s7r.reg4818&0x40)&&!(s7r.reg4818&0x20))
+ {
+ s7r.offset_add|=0x01;
+ if(s7r.offset_add==3)
+ {
+ if(s7r.reg4818&0x10)
+ {
+ }
+ else
+ {
+ uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811;
+ if(s7r.reg4818&0x08)
+ {
+ short adj;
+ adj=((short)(s7r.reg4815<<8))|s7r.reg4814;
+ i+=adj;
+ }
+ else
+ {
+ uint16 adj;
+ adj=(s7r.reg4815<<8)|s7r.reg4814;
+ i+=adj;
+ }
+ i%=s7r.DataRomSize;
+ s7r.reg4811=i&0x00FF;
+ s7r.reg4812=(i&0x00FF00)>>8;
+ s7r.reg4813=((i&0xFF0000)>>16);
+ }
+ }
+
+ }
+ }
+
+ s7r.written|=0x08;
+ break;
+
+ //data port adjust high (has a funky immediate increment mode)
+ case 0x4815:
+ s7r.reg4815=data;
+ if(s7r.reg4818&0x02)
+ {
+ if(s7r.reg4818&0x20&&!(s7r.reg4818&0x40))
+ {
+ s7r.offset_add|=0x02;
+ if(s7r.offset_add==3)
+ {
+ if(s7r.reg4818&0x10)
+ {
+ }
+ else
+ {
+ uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811;
+
+ if(s7r.reg4818&0x08)
+ {
+ i+=(signed char)s7r.reg4814;
+ }
+ else
+ {
+ i+=s7r.reg4814;
+ }
+ i%=s7r.DataRomSize;
+ s7r.reg4811=i&0x00FF;
+ s7r.reg4812=(i&0x00FF00)>>8;
+ s7r.reg4813=((i&0xFF0000)>>16);
+ }
+ }
+ }
+ else if(s7r.reg4818&0x40&&!(s7r.reg4818&0x20))
+ {
+ s7r.offset_add|=0x02;
+ if(s7r.offset_add==3)
+ {
+ if(s7r.reg4818&0x10)
+ {
+ }
+ else
+ {
+ uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811;
+ if(s7r.reg4818&0x08)
+ {
+ short adj;
+ adj=((short)(s7r.reg4815<<8))|s7r.reg4814;
+ i+=adj;
+ }
+ else
+ {
+ uint16 adj;
+ adj=(s7r.reg4815<<8)|s7r.reg4814;
+ i+=adj;
+ }
+ i%=s7r.DataRomSize;
+ s7r.reg4811=i&0x00FF;
+ s7r.reg4812=(i&0x00FF00)>>8;
+ s7r.reg4813=((i&0xFF0000)>>16);
+ }
+ }
+ }
+ }
+ s7r.written|=0x10;
+ break;
+ //data port increment low
+ case 0x4816:
+ s7r.reg4816=data;
+ break;
+ //data port increment high
+ case 0x4817:
+ s7r.reg4817=data;
+ break;
+
+ //data port mode switches
+ //note that it starts inactive.
+ case 0x4818:
+ if((s7r.written&0x18)!=0x18)
+ break;
+ s7r.offset_add=0;
+ s7r.reg4818=data;
+ break;
+
+ //multiplicand low or dividend lowest
+ case 0x4820:
+ s7r.reg4820=data;
+ break;
+ //multiplicand high or dividend lower
+ case 0x4821:
+ s7r.reg4821=data;
+ break;
+ //dividend higher
+ case 0x4822:
+ s7r.reg4822=data;
+ break;
+ //dividend highest
+ case 0x4823:
+ s7r.reg4823=data;
+ break;
+ //multiplier low
+ case 0x4824:
+ s7r.reg4824=data;
+ break;
+ //multiplier high (triggers operation)
+ case 0x4825:
+ s7r.reg4825=data;
+ if(s7r.reg482E&0x01)
+ {
+ int mul;
+ short m1=(short)((s7r.reg4824)|(s7r.reg4825<<8));
+ short m2=(short)((s7r.reg4820)|(s7r.reg4821<<8));
+
+ mul=m1*m2;
+ s7r.reg4828=(uint8)(mul&0x000000FF);
+ s7r.reg4829=(uint8)((mul&0x0000FF00)>>8);
+ s7r.reg482A=(uint8)((mul&0x00FF0000)>>16);
+ s7r.reg482B=(uint8)((mul&0xFF000000)>>24);
+ }
+ else
+ {
+ uint32 mul;
+ uint16 m1=(uint16)((s7r.reg4824)|(s7r.reg4825<<8));
+ uint16 m2=(uint16)((s7r.reg4820)|(s7r.reg4821<<8));
+
+ mul=m1*m2;
+ s7r.reg4828=(uint8)(mul&0x000000FF);
+ s7r.reg4829=(uint8)((mul&0x0000FF00)>>8);
+ s7r.reg482A=(uint8)((mul&0x00FF0000)>>16);
+ s7r.reg482B=(uint8)((mul&0xFF000000)>>24);
+ }
+ s7r.reg482F=0x80;
+ break;
+ //divisor low
+ case 0x4826:
+ s7r.reg4826=data;
+ break;
+ //divisor high (triggers operation)
+ case 0x4827:
+ s7r.reg4827=data;
+ if(s7r.reg482E&0x01)
+ {
+ int quotient;
+ short remainder;
+ int dividend=(int)(s7r.reg4820|(s7r.reg4821<<8)|(s7r.reg4822<<16)|(s7r.reg4823<<24));
+ short divisor=(short)(s7r.reg4826|(s7r.reg4827<<8));
+ if(divisor != 0)
+ {
+ quotient=(int)(dividend/divisor);
+ remainder=(short)(dividend%divisor);
+ }
+ else
+ {
+ quotient=0;
+ remainder=dividend&0x0000FFFF;
+ }
+ s7r.reg4828=(uint8)(quotient&0x000000FF);
+ s7r.reg4829=(uint8)((quotient&0x0000FF00)>>8);
+ s7r.reg482A=(uint8)((quotient&0x00FF0000)>>16);
+ s7r.reg482B=(uint8)((quotient&0xFF000000)>>24);
+ s7r.reg482C=(uint8)remainder&0x00FF;
+ s7r.reg482D=(uint8)((remainder&0xFF00)>>8);
+ }
+ else
+ {
+ uint32 quotient;
+ uint16 remainder;
+ uint32 dividend=(uint32)(s7r.reg4820|(s7r.reg4821<<8)|(s7r.reg4822<<16)|(s7r.reg4823<<24));
+ uint16 divisor=(uint16)(s7r.reg4826|(s7r.reg4827<<8));
+ if(divisor != 0)
+ {
+ quotient=(uint32)(dividend/divisor);
+ remainder=(uint16)(dividend%divisor);
+ }
+ else
+ {
+ quotient=0;
+ remainder=dividend&0x0000FFFF;
+ }
+ s7r.reg4828=(uint8)(quotient&0x000000FF);
+ s7r.reg4829=(uint8)((quotient&0x0000FF00)>>8);
+ s7r.reg482A=(uint8)((quotient&0x00FF0000)>>16);
+ s7r.reg482B=(uint8)((quotient&0xFF000000)>>24);
+ s7r.reg482C=(uint8)remainder&0x00FF;
+ s7r.reg482D=(uint8)((remainder&0xFF00)>>8);
+ }
+ s7r.reg482F=0x80;
+ break;
+ //result registers are possibly read-only
+
+ //reset: writes here nuke the whole math unit
+ //Zero indicates unsigned math, resets with non-zero values turn on signed math
+ case 0x482E:
+ s7r.reg4820=s7r.reg4821=s7r.reg4822=s7r.reg4823=s7r.reg4824=s7r.reg4825=s7r.reg4826=s7r.reg4827=s7r.reg4828=s7r.reg4829=s7r.reg482A=s7r.reg482B=s7r.reg482C=s7r.reg482D=0;
+ s7r.reg482E=data;
+ break;
+
+ //math status register possibly read only
+
+ //SRAM toggle
+ case 0x4830:
+ Memory.SPC7110Sram(data);
+ s7r.reg4830=data;
+ break;
+ //Bank DX mapping
+ case 0x4831:
+ s7r.reg4831=data;
+ break;
+ //Bank EX mapping
+ case 0x4832:
+ s7r.reg4832=data;
+ break;
+ //Bank FX mapping
+ case 0x4833:
+ s7r.reg4833=data;
+ break;
+ //S-RAM mapping? who knows?
+ case 0x4834:
+ s7r.reg4834=data;
+ break;
+ //RTC Toggle
+ case 0x4840:
+ if(0==data)
+ {
+ S9xUpdateRTC();
+ // rtc_f9.init=false;
+ // rtc_f9.index=-1;
+ }
+ if(data&0x01)
+ {
+ s7r.reg4842=0x80;
+ //rtc_f9.last_used=time(NULL);//????
+ rtc_f9.init=false;
+ rtc_f9.index=-1;
+ }
+ s7r.reg4840=data;
+ break;
+ //RTC init/command/index register
+ case 0x4841:
+ if(rtc_f9.init)
+ {
+ if(-1==rtc_f9.index)
+ {
+ rtc_f9.index=data&0x0F;
+ break;
+ }
+ if(rtc_f9.control==0x0C)
+ {
+ rtc_f9.index=data&0x0F;
+ s7r.reg4842=0x80;
+ rtc_f9.last_used=time(NULL);
+ }
+ else
+ {
+
+ if(0x0D==rtc_f9.index)
+ {
+ if(data&0x08)
+ {
+ if(rtc_f9.reg[1]<3)
+ {
+ S9xUpdateRTC();
+ rtc_f9.reg[0]=0;
+ rtc_f9.reg[1]=0;
+ rtc_f9.last_used=time(NULL);
+ }
+ else
+ {
+ S9xUpdateRTC();
+ rtc_f9.reg[0]=0;
+ rtc_f9.reg[1]=0;
+ rtc_f9.last_used=time(NULL)-60;
+ S9xUpdateRTC();
+ rtc_f9.last_used=time(NULL);
+ }
+ data&=0x07;
+ }
+ if(rtc_f9.reg[0x0D]&0x01)
+ {
+ if(!(data%2))
+ {
+ rtc_f9.reg[rtc_f9.index&0x0F]=data;
+ rtc_f9.last_used=time(NULL)-1;
+ S9xUpdateRTC();
+ rtc_f9.last_used=time(NULL);
+ }
+ }
+ }
+ if(0x0F==rtc_f9.index)
+ {
+ if(data&0x01&&!(rtc_f9.reg[0x0F]&0x01))
+ {
+ S9xUpdateRTC();
+ rtc_f9.reg[0]=0;
+ rtc_f9.reg[1]=0;
+ rtc_f9.last_used=time(NULL);
+ }
+ if(data&0x02&&!(rtc_f9.reg[0x0F]&0x02))
+ {
+ S9xUpdateRTC();
+ rtc_f9.last_used=time(NULL);
+ }
+ }
+ rtc_f9.reg[rtc_f9.index&0x0F]=data;
+ s7r.reg4842=0x80;
+ rtc_f9.index=(rtc_f9.index+1)%0x10;
+ }
+ }
+ else
+ {
+ if(data==0x03||data==0x0C)
+ {
+ rtc_f9.init=true;
+ rtc_f9.control=data;
+ rtc_f9.index=-1;
+ }
+ }
+ break;
+ //writes to RTC status register aren't expected to be meaningful
+ default:
+ Address-=0x4800;
+ break;
+ //16 BIT MULTIPLIER: ($FF00) high byte, defval:00
+ }
+}
+extern "C"{
+//emulate the SPC7110's ability to remap banks Dx, Ex, and Fx.
+uint8 S9xGetSPC7110Byte(uint32 Address)
+{
+ uint32 i;
+ switch((Address&0x00F00000)>>16)
+ {
+ case 0xD0:
+ i=s7r.reg4831*0x00100000;
+ break;
+ case 0xE0:
+ i=s7r.reg4832*0x00100000;
+ break;
+ case 0xF0:
+ i=s7r.reg4833*0x00100000;
+ break;
+ default:i=0;
+ }
+ i+=Address&0x000FFFFF;
+ i+=s7r.DataRomOffset;
+ return ROM[i];
+}
+}
+/**********************************************************************************************/
+/* S9xSRTCDaysInMonth() */
+/* Return the number of days in a specific month for a certain year */
+/* copied directly for RTC functionality, separated in case of incompatibilities */
+/**********************************************************************************************/
+int S9xRTCDaysInMonth( int month, int year )
+{
+ int mdays;
+
+ switch ( month )
+ {
+ case 2:
+ if ( ( year % 4 == 0 ) ) // DKJM2 only uses 199x - 22xx
+ mdays = 29;
+ else
+ mdays = 28;
+ break;
+
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ mdays = 30;
+ break;
+
+ default: // months 1,3,5,7,8,10,12
+ mdays = 31;
+ break;
+ }
+
+ return mdays;
+}
+
+
+#define DAYTICKS (60*60*24)
+#define HOURTICKS (60*60)
+#define MINUTETICKS 60
+
+
+/**********************************************************************************************/
+/* S9xUpdateRTC() */
+/* Advance the RTC time */
+/**********************************************************************************************/
+
+void S9xUpdateRTC ()
+{
+ time_t cur_systime;
+ long time_diff;
+
+ // Keep track of game time by computing the number of seconds that pass on the system
+ // clock and adding the same number of seconds to the RTC clock structure.
+
+ if (rtc_f9.init && 0==(rtc_f9.reg[0x0D]&0x01) && 0==(rtc_f9.reg[0x0F]&0x03))
+ {
+ cur_systime = time (NULL);
+
+ // This method assumes one time_t clock tick is one second
+ // which should work on PCs and GNU systems.
+ // If your tick interval is different adjust the
+ // DAYTICK, HOURTICK, and MINUTETICK defines
+
+ time_diff = (long) (cur_systime - rtc_f9.last_used);
+ rtc_f9.last_used = cur_systime;
+
+ if ( time_diff > 0 )
+ {
+ int seconds;
+ int minutes;
+ int hours;
+ int days;
+ int month;
+ int year;
+ int temp_days;
+
+ int year_hundreds;
+ int year_tens;
+ int year_ones;
+
+
+ if ( time_diff > DAYTICKS )
+ {
+ days = time_diff / DAYTICKS;
+ time_diff = time_diff - days * DAYTICKS;
+ }
+ else
+ {
+ days = 0;
+ }
+
+ if ( time_diff > HOURTICKS )
+ {
+ hours = time_diff / HOURTICKS;
+ time_diff = time_diff - hours * HOURTICKS;
+ }
+ else
+ {
+ hours = 0;
+ }
+
+ if ( time_diff > MINUTETICKS )
+ {
+ minutes = time_diff / MINUTETICKS;
+ time_diff = time_diff - minutes * MINUTETICKS;
+ }
+ else
+ {
+ minutes = 0;
+ }
+
+ if ( time_diff > 0 )
+ {
+ seconds = time_diff;
+ }
+ else
+ {
+ seconds = 0;
+ }
+
+
+ seconds += (rtc_f9.reg[1]*10 + rtc_f9.reg[0]);
+ if ( seconds >= 60 )
+ {
+ seconds -= 60;
+ minutes += 1;
+ }
+
+ minutes += (rtc_f9.reg[3]*10 + rtc_f9.reg[2]);
+ if ( minutes >= 60 )
+ {
+ minutes -= 60;
+ hours += 1;
+ }
+
+ hours += (rtc_f9.reg[5]*10 + rtc_f9.reg[4]);
+ if ( hours >= 24 )
+ {
+ hours -= 24;
+ days += 1;
+ }
+
+ year = rtc_f9.reg[11]*10 + rtc_f9.reg[10];
+ year += ( 1900 );
+ month = rtc_f9.reg[8]+10*rtc_f9.reg[9];
+ rtc_f9.reg[12]+=days;
+ days += (rtc_f9.reg[7]*10 + rtc_f9.reg[6]);
+ if ( days > 0 )
+ {
+ while ( days > (temp_days = S9xRTCDaysInMonth( month, year )) )
+ {
+ days -= temp_days;
+ month += 1;
+ if ( month > 12 )
+ {
+ year += 1;
+ month = 1;
+ }
+ }
+ }
+
+ year_tens = year % 100;
+ year_ones = year_tens % 10;
+ year_tens /= 10;
+ year_hundreds = (year - 1000) / 100;
+
+ rtc_f9.reg[0] = seconds % 10;
+ rtc_f9.reg[1] = seconds / 10;
+ rtc_f9.reg[2] = minutes % 10;
+ rtc_f9.reg[3] = minutes / 10;
+ rtc_f9.reg[4] = hours % 10;
+ rtc_f9.reg[5] = hours / 10;
+ rtc_f9.reg[6] = days % 10;
+ rtc_f9.reg[7] = days / 10;
+ rtc_f9.reg[8] = month%10;
+ rtc_f9.reg[9] = month /10;
+ rtc_f9.reg[10] = year_ones;
+ rtc_f9.reg[11] = year_tens;
+ rtc_f9.reg[12] %= 7;
+ return;
+ }
+ }
+}
+extern "C"{
+
+//allows DMA from the ROM (is this even possible on the SPC7110?
+uint8* Get7110BasePtr(uint32 Address)
+{
+ uint32 i;
+ switch((Address&0x00F00000)>>16)
+ {
+ case 0xD0:
+ i=s7r.reg4831*0x100000;
+ break;
+ case 0xE0:
+ i=s7r.reg4832*0x100000;
+ break;
+ case 0xF0:
+ i=s7r.reg4833*0x100000;
+ break;
+ default:i=0;
+ }
+ i+=Address&0x000F0000;
+ return &ROM[i];
+}
+//end extern
+}
+
+//loads the index into memory.
+//index.bin is little-endian
+//format index (1)-table(3)-file offset(4)-length(4)
+bool Load7110Index(char* filename)
+{
+ FILE* fp;
+ uint8 buffer[12];
+ int table=0;
+ uint8 index=0;
+ uint32 offset=0;
+ uint32 size=0;
+ int i=0;
+ fp=fopen(filename, "rb");
+ if(NULL==fp)
+ return false;
+
+ int f_len;
+ //do
+ while(1)
+ {
+ i=0;
+ f_len= fread(buffer, 1, 12,fp);
+ if(f_len < 12) break;
+
+ table=(buffer[3]<<16)|(buffer[2]<<8)|buffer[1];
+ index=buffer[0];
+ offset=(buffer[7]<<24)|(buffer[6]<<16)|(buffer[5]<<8)|buffer[4];
+ size=(buffer[11]<<24)|(buffer[10]<<16)|(buffer[9]<<8)|buffer[8];
+ while(i<MAX_TABLES&&decompack->tableEnts[i].table!=table&&decompack->tableEnts[i].table!=0)
+ i++;
+ if(i==MAX_TABLES)
+ return false;
+ //added
+ decompack->tableEnts[i].table=table;
+ //-----
+ decompack->tableEnts[i].location[index].offset=offset;
+ decompack->tableEnts[i].location[index].size=size;
+ decompack->tableEnts[i].location[index].used_len=0;
+ decompack->tableEnts[i].location[index].used_offset=0;
+
+ }
+ //while(!feof(fp));
+ fclose(fp);
+ return true;
+}
+
+
+//Cache 1 load function
+void SPC7110Load(char* dirname)
+{
+ char temp_path[PATH_MAX];
+ int i=0;
+
+ decompack=new Pack7110;
+
+#ifndef _XBOX
+ getcwd(temp_path,PATH_MAX);
+#endif
+
+ ZeroMemory(decompack, sizeof(Pack7110));
+
+#ifndef _XBOX
+ if(-1==chdir(dirname))
+ {
+ S9xMessage(0,0,"Graphics Pack not found!");
+ }
+#endif
+
+#ifndef _XBOX
+ Load7110Index("index.bin");
+#else
+ // D:\\ is always app.path in Xbox
+ Load7110Index("d:\\index.bin");
+#endif
+
+ for(i=0;i<MAX_TABLES;i++)
+ {
+ if(decompack->tableEnts[i].table!=0)
+ {
+ char binname[PATH_MAX];
+#ifndef _XBOX
+ sprintf(binname,"%06X.bin",decompack->tableEnts[i].table);
+#else
+ sprintf(binname,"%s%06X.bin",filename,decompack->tableEnts[i].table);
+#endif
+ struct stat buf;
+ if(-1!=stat(binname, &buf))
+ decompack->binfiles[i]=new uint8[buf.st_size];
+ FILE* fp=fopen(binname, "rb");
+ if(fp)
+ {
+ fread(decompack->binfiles[i],buf.st_size,1,fp);
+ fclose(fp);
+ }
+ }
+ }
+
+#ifndef _XBOX
+ chdir(temp_path);
+#endif
+
+ Copy7110=&MovePackData;
+ CleanUp7110=&Del7110Gfx;
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED);
+ #endif
+#endif
+}
+
+//Cache 2 load function
+void SPC7110Open(char* dirname)
+{
+ char temp_path[PATH_MAX];
+ int i=0;
+
+ decompack=new Pack7110;
+
+#ifndef _XBOX
+ getcwd(temp_path,PATH_MAX);
+#endif
+
+ ZeroMemory(decompack, sizeof(Pack7110));
+
+#ifndef _XBOX
+ if(-1==chdir(dirname))
+ {
+ S9xMessage(0,0,"Graphics Pack not found!");
+ }
+#endif
+
+#ifndef _XBOX
+ Load7110Index("index.bin");
+#else
+ // D:\\ is always app.path in Xbox
+ Load7110Index("d:\\index.bin");
+#endif
+
+ for (i=0; i<MAX_TABLES; i++)
+ decompack->binfiles[i]=NULL;
+
+ ReadPackData();
+
+#ifndef _XBOX
+ chdir(temp_path);
+#endif
+
+ Copy7110=&ReadPackData;
+ CleanUp7110=&Close7110Gfx;
+
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED);
+ #endif
+#endif
+}
+
+//Cache 3's load function
+void SPC7110Grab(char* dirname)
+{
+ char temp_path[PATH_MAX];
+ int i=0;
+
+ decompack=new Pack7110;
+
+#ifndef _XBOX
+ getcwd(temp_path,PATH_MAX);
+#endif
+
+ int32 buffer_size=1024*1024*cacheMegs;//*some setting
+
+ ZeroMemory(decompack, sizeof(Pack7110));
+#ifndef _XBOX
+
+ if(-1==chdir(dirname))
+ {
+ S9xMessage(0,0,"Graphics Pack not found!");
+ }
+#endif
+
+#ifndef _XBOX
+ Load7110Index("index.bin");
+#else
+ // D:\\ is always app.path in Xbox
+ Load7110Index("d:\\index.bin");
+#endif
+
+ for(i=0;i<MAX_TABLES;i++)
+ {
+ if(decompack->tableEnts[i].table!=0)
+ {
+ char binname[PATH_MAX];
+#ifndef _XBOX
+ sprintf(binname,"%06X.bin",decompack->tableEnts[i].table);
+#else
+ sprintf(binname,"%s%06X.bin",filename,decompack->tableEnts[i].table);
+#endif
+ struct stat buf;
+//add load/no load calculations here
+ if(-1!=stat(binname, &buf))
+ {
+ if(buf.st_size<buffer_size)
+ decompack->binfiles[i]=new uint8[buf.st_size];
+ FILE* fp=fopen(binname, "rb");
+ //use them here
+ if(fp)
+ {
+ if(buf.st_size<buffer_size)
+ {
+ fread(decompack->binfiles[i],buf.st_size,1,fp);
+ fclose(fp);
+ buffer_size-=buf.st_size;
+ decompack->tableEnts[i].is_file=false;
+ }
+ else
+ {
+ decompack->binfiles[i]=(uint8*)fp;
+ decompack->tableEnts[i].is_file=true;
+ }
+ }
+ }
+ }
+ }
+
+#ifndef _XBOX
+ chdir(temp_path);
+#endif
+
+ Copy7110=&GetPackData;
+ CleanUp7110=&Drop7110Gfx;
+
+
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED);
+ #endif
+#endif
+}
+
+//Cache 1 clean up function
+void Del7110Gfx()
+{
+ int i;
+ if(Settings.SPC7110)
+ {
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED);
+ #endif
+#endif
+ Do7110Logging();
+ }
+ for(i=0;i<MAX_TABLES;i++)
+ {
+ if(decompack->binfiles[i]!=NULL)
+ {
+ delete []decompack->binfiles[i];
+ decompack->binfiles[i]=NULL;
+ }
+ }
+ Settings.SPC7110=false;
+ Settings.SPC7110RTC=false;
+ if(NULL!=decompack)
+ delete decompack;
+ decompack=NULL;
+ CleanUp7110=NULL;
+ Copy7110=NULL;
+}
+
+//Cache2 cleanup function
+void Close7110Gfx()
+{
+ int i;
+ if(Settings.SPC7110)
+ {
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED);
+ #endif
+#endif
+ Do7110Logging();
+ }
+ for(i=0;i<MAX_TABLES;i++)
+ {
+ if(decompack->binfiles[i]!=NULL)
+ {
+ fclose((FILE*)decompack->binfiles[i]);
+ decompack->binfiles[i]=NULL;
+ }
+ }
+ Settings.SPC7110=false;
+ Settings.SPC7110RTC=false;
+ if(NULL!=decompack)
+ delete decompack;
+ decompack=NULL;
+ CleanUp7110=NULL;
+ Copy7110=NULL;
+}
+
+//cache 3's clean-up code
+void Drop7110Gfx()
+{
+ int i;
+ if(Settings.SPC7110)
+ {
+#ifdef __WIN32__
+ #ifndef _XBOX
+ EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED);
+ #endif
+#endif
+ Do7110Logging();
+ }
+ for(i=0;i<MAX_TABLES;i++)
+ {
+ if(decompack->binfiles[i]!=NULL)
+ {
+ if(decompack->tableEnts[i].is_file)
+ {
+ fclose((FILE*)decompack->binfiles[i]);
+ decompack->binfiles[i]=NULL;
+ }
+ else
+ {
+ delete []decompack->binfiles[i];
+ decompack->binfiles[i]=NULL;
+ }
+ }
+ }
+ Settings.SPC7110=false;
+ Settings.SPC7110RTC=false;
+ if(NULL!=decompack)
+ delete decompack;
+ decompack=NULL;
+ CleanUp7110=NULL;
+ Copy7110=NULL;
+}
+
+//emulate a reset.
+void S9xSpc7110Reset()
+{
+ s7r.reg4800=0;
+ s7r.reg4801=0;
+ s7r.reg4802=0;
+ s7r.reg4803=0;
+ s7r.reg4804=0;
+ s7r.reg4805=0;
+ s7r.reg4806=0;
+ s7r.reg4807=0;
+ s7r.reg4808=0;
+ s7r.reg4809=0;
+ s7r.reg480A=0;
+ s7r.reg480B=0;
+ s7r.reg480C=0;
+ s7r.reg4811=0;
+ s7r.reg4812=0;
+ s7r.reg4813=0;
+ s7r.reg4814=0;
+ s7r.reg4815=0;
+ s7r.reg4816=0;
+ s7r.reg4817=0;
+ s7r.reg4818=0;
+ s7r.reg4820=0;
+ s7r.reg4821=0;
+ s7r.reg4822=0;
+ s7r.reg4823=0;
+ s7r.reg4824=0;
+ s7r.reg4825=0;
+ s7r.reg4826=0;
+ s7r.reg4827=0;
+ s7r.reg4828=0;
+ s7r.reg4829=0;
+ s7r.reg482A=0;
+ s7r.reg482B=0;
+ s7r.reg482C=0;
+ s7r.reg482D=0;
+ s7r.reg482E=0;
+ s7r.reg482F=0;
+ s7r.reg4830=0;
+ s7r.reg4831=0;
+ s7r.reg4832=1;
+ s7r.reg4833=2;
+ s7r.reg4834=0;
+ s7r.reg4840=0;
+ s7r.reg4841=0;
+ s7r.reg4842=0;
+ s7r.written=0;
+ s7r.offset_add=0;
+ s7r.AlignBy=1;
+ s7r.bank50Internal=0;
+ memset(s7r.bank50,0x00,DECOMP_BUFFER_SIZE);
+}
+
+
+//outputs a cumulative log for the game.
+//there's nothing really weird here, just
+//reading the old log, and writing a new one.
+//note the logs are explicitly little-endian, not host byte order.
+void Do7110Logging()
+{
+ uint8 ent_temp;
+ FILE* flog;
+ int entries=0;
+
+ if(Settings.SPC7110)
+ {
+ //flush last read into logging
+ (*Copy7110)();
+
+ if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\spl4-sp7.dat","rb");
+#else
+ flog=fopen("spl4-sp7.dat","rb");
+#endif
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\smht-sp7.dat","rb");
+#else
+ flog=fopen("smht-sp7.dat","rb");
+#endif
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\feoezsp7.dat","rb");
+#else
+ flog=fopen("feoezsp7.dat","rb");
+#endif
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\sjumpsp7.dat","rb");
+#else
+ flog=fopen("sjumpsp7.dat","rb");
+#endif
+ }
+ else
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\misc-sp7.dat","rb");
+#else
+ flog=fopen("misc-sp7.dat","rb");
+#endif
+ }
+
+ if(flog)
+ {
+ uint8 buffer[8];
+ int table=0;
+ uint16 offset=0;
+ uint16 length=0;
+ fseek(flog, 35,0);
+
+ int f_len;
+ //do
+ while(1)
+ {
+ int i=0;
+ Data7110 *log=NULL;
+ f_len= fread(buffer, 1, 8, flog);
+ if(f_len < 8) break;
+
+ table=buffer[0]|(buffer[1]<<8)|(buffer[2]<<16);
+ offset=buffer[6]|(buffer[7]<<8);
+ length=buffer[4]|(buffer[5]<<8);
+ while(i<MAX_TABLES&&log==NULL)
+ {
+ if(decompack->tableEnts[i].table==table)
+ {
+ log=&(decompack->tableEnts[i].location[(buffer[3])]);
+ if((log->used_offset+log->used_len)<(offset+length))
+ {
+ log->used_offset=offset;
+ log->used_len=length;
+ }
+ }
+ i++;
+ }
+ }
+ //while(!feof(flog));
+ fclose(flog);
+ }
+
+
+ if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21))
+ {
+#ifdef _XBOX // cwd could be the dvd-rom, so write to T:\\ which is storage region for each title
+ flog=fopen("T:\\spl4-sp7.dat","wb");
+#else
+ flog=fopen("spl4-sp7.dat","wb");
+#endif
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\smht-sp7.dat","wb");
+#else
+ flog=fopen("smht-sp7.dat","wb");
+#endif
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\feoezsp7.dat","wb");
+#else
+ flog=fopen("feoezsp7.dat","wb");
+#endif
+ }
+ else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21))
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\sjumpsp7.dat","wb");
+#else
+ flog=fopen("sjumpsp7.dat","wb");
+#endif
+ }
+ else
+ {
+#ifdef _XBOX
+ flog=fopen("T:\\misc-sp7.dat","wb");
+#else
+ flog=fopen("misc-sp7.dat","wb");
+#endif
+ }
+ //count entries
+ if(flog)
+ {
+ int j=0;
+ int temp=0;
+ for(j=0;j<MAX_TABLES;j++)
+ {
+ for(int k=0;k<256;k++)
+ {
+ if(decompack->tableEnts[j].location[k].used_len!=0)
+ entries++;
+ }
+ }
+ ent_temp=entries&0xFF;
+ fwrite(&ent_temp,1,1,flog);
+ ent_temp=(entries>>8)&0xFF;
+ fwrite(&ent_temp,1,1,flog);
+ ent_temp=(entries>>16)&0xFF;
+ fwrite(&ent_temp,1,1,flog);
+ ent_temp=(entries>>24)&0xFF;
+ fwrite(&ent_temp,1,1,flog);
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+
+ ent_temp=0;
+ fwrite(&ent_temp,1,1,flog);
+ ent_temp=0;
+ fwrite(&ent_temp,1,1,flog);
+ ent_temp=0;
+ fwrite(&ent_temp,1,1,flog);
+
+ for(j=0;j<MAX_TABLES;j++)
+ {
+ for(int k=0;k<256;k++)
+ {
+ if(decompack->tableEnts[j].location[k].used_len!=0)
+ {
+ ent_temp=decompack->tableEnts[j].table&0xFF;
+ fwrite(&ent_temp,1,1,flog);//801
+ ent_temp=(decompack->tableEnts[j].table>>8)&0xFF;;
+ fwrite(&ent_temp,1,1,flog);//802
+ ent_temp=(decompack->tableEnts[j].table>>16)&0xFF;;
+ fwrite(&ent_temp,1,1,flog);//803
+ ent_temp=k&0xFF;
+ fwrite(&ent_temp,1,1,flog);//804
+ ent_temp=decompack->tableEnts[j].location[k].used_len&0xFF;
+ fwrite(&ent_temp,1,1,flog);//lsb of
+ ent_temp=(decompack->tableEnts[j].location[k].used_len>>8)&0xFF;
+ fwrite(&ent_temp,1,1,flog);//msb of
+ ent_temp=(decompack->tableEnts[j].location[k].used_offset)&0xFF;
+ fwrite(&ent_temp,1,1,flog);//lsb of
+ ent_temp=(decompack->tableEnts[j].location[k].used_offset>>8)&0xFF;
+ fwrite(&ent_temp,1,1,flog);//msb of
+ }
+ }
+ }
+ fwrite(&temp,1,4,flog);
+ fwrite(&temp,1,4,flog);
+ fclose(flog);
+ }
+ }
+}
+bool8 S9xSaveSPC7110RTC (S7RTC *rtc_f9)
+{
+ FILE* fp;
+
+ if((fp=fopen(S9xGetFilename(".rtc"), "wb"))==NULL)
+ return (FALSE);
+ int i=0;
+ uint8 temp=0;
+ for (i=0;i<16;i++)
+ fwrite(&rtc_f9->reg[i],1,1,fp);
+ temp=rtc_f9->index&0x00FF;
+ fwrite(&temp,1,1,fp);
+ temp=(rtc_f9->index)>>8;
+ fwrite(&temp,1,1,fp);
+ temp=(uint8)rtc_f9->control;
+ fwrite(&temp,1,1,fp);
+ temp=(uint8)rtc_f9->init;
+ fwrite(&temp,1,1,fp);
+ temp=rtc_f9->last_used&0x00FF;
+ fwrite(&temp,1,1,fp);
+ temp=(rtc_f9->last_used>>8)&0x00FF;
+ fwrite(&temp,1,1,fp);
+ temp=(rtc_f9->last_used>>16)&0x00FF;
+ fwrite(&temp,1,1,fp);
+ temp=(rtc_f9->last_used>>24)&0x00FF;;
+ fwrite(&temp,1,1,fp);
+ fclose(fp);
+ return (TRUE);
+}
+
+bool8 S9xLoadSPC7110RTC (S7RTC *rtc_f9)
+{
+ FILE* fp;
+
+ if((fp=fopen(S9xGetFilename(".rtc"), "rb"))==NULL)
+ return (FALSE);
+ for (int i=0; i<16;i++)
+ {
+ fread(&(rtc_f9->reg[i]),1,1,fp);
+ }
+ uint8 temp=0;
+ fread(&temp,1,1,fp);
+ rtc_f9->index=temp;
+ fread(&temp,1,1,fp);
+ rtc_f9->index|=(temp<<8);
+ fread(&rtc_f9->control,1,1,fp);
+ fread(&rtc_f9->init,1,1,fp);
+
+ fread(&temp,1,1,fp);
+ rtc_f9->last_used=temp;
+ fread(&temp,1,1,fp);
+ rtc_f9->last_used|=(temp<<8);
+ fread(&temp,1,1,fp);
+ rtc_f9->last_used|=(temp<<16);
+ fread(&temp,1,1,fp);
+ rtc_f9->last_used|=(temp<<24);
+ fclose(fp);
+ return (TRUE);
+}
+
diff --git a/source/spc7110.h b/source/spc7110.h
new file mode 100644
index 0000000..48368f5
--- /dev/null
+++ b/source/spc7110.h
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _spc7110_h
+#define _spc7110_h
+#include "port.h"
+
+#define DECOMP_BUFFER_SIZE 0x10000
+
+extern void (*LoadUp7110)(char*);
+extern void (*CleanUp7110)(void);
+extern void (*Copy7110)(void);
+
+extern uint16 cacheMegs;
+
+void Del7110Gfx(void);
+void Close7110Gfx(void);
+void Drop7110Gfx(void);
+extern "C"{
+uint8 S9xGetSPC7110(uint16 Address);
+uint8 S9xGetSPC7110Byte(uint32 Address);
+uint8* Get7110BasePtr(uint32);
+}
+void S9xSetSPC7110 (uint8 data, uint16 Address);
+void S9xSpc7110Init();
+uint8* Get7110BasePtr(uint32);
+void S9xSpc7110Reset();
+void S9xUpdateRTC ();
+void Do7110Logging();
+int S9xRTCDaysInMonth( int month, int year );
+
+//These are platform-dependant functions, but should work on
+//most systems that use GNU compilers, and on Win32.
+void SPC7110Load(char*);
+void SPC7110Open(char*);
+void SPC7110Grab(char*);
+
+typedef struct SPC7110RTC
+{
+ unsigned char reg[16];
+ short index;
+ uint8 control;
+ bool init;
+ time_t last_used;
+} S7RTC;
+
+typedef struct SPC7110EmuVars
+{
+ unsigned char reg4800;
+ unsigned char reg4801;
+ unsigned char reg4802;
+ unsigned char reg4803;
+ unsigned char reg4804;
+ unsigned char reg4805;
+ unsigned char reg4806;
+ unsigned char reg4807;
+ unsigned char reg4808;
+ unsigned char reg4809;
+ unsigned char reg480A;
+ unsigned char reg480B;
+ unsigned char reg480C;
+ unsigned char reg4811;
+ unsigned char reg4812;
+ unsigned char reg4813;
+ unsigned char reg4814;
+ unsigned char reg4815;
+ unsigned char reg4816;
+ unsigned char reg4817;
+ unsigned char reg4818;
+ unsigned char reg4820;
+ unsigned char reg4821;
+ unsigned char reg4822;
+ unsigned char reg4823;
+ unsigned char reg4824;
+ unsigned char reg4825;
+ unsigned char reg4826;
+ unsigned char reg4827;
+ unsigned char reg4828;
+ unsigned char reg4829;
+ unsigned char reg482A;
+ unsigned char reg482B;
+ unsigned char reg482C;
+ unsigned char reg482D;
+ unsigned char reg482E;
+ unsigned char reg482F;
+ unsigned char reg4830;
+ unsigned char reg4831;
+ unsigned char reg4832;
+ unsigned char reg4833;
+ unsigned char reg4834;
+ unsigned char reg4840;
+ unsigned char reg4841;
+ unsigned char reg4842;
+ uint8 AlignBy;
+ uint8 written;
+ uint8 offset_add;
+ uint32 DataRomOffset;
+ uint32 DataRomSize;
+ uint32 bank50Internal;
+ uint8 bank50[DECOMP_BUFFER_SIZE];
+
+} SPC7110Regs;
+extern SPC7110Regs s7r;
+extern S7RTC rtc_f9;
+// These are defined in spc7110.cpp
+bool8 S9xSaveSPC7110RTC (S7RTC *rtc_f9);
+bool8 S9xLoadSPC7110RTC (S7RTC *rtc_f9);
+
+#endif
+
diff --git a/source/spccycles.cpp b/source/spccycles.cpp
new file mode 100644
index 0000000..3cb572e
--- /dev/null
+++ b/source/spccycles.cpp
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+
+static uint8 spc700cycles [256] =
+{
+ /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */
+ /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
+ /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
+ /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
+ /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
+ /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
+ /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
+ /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
+ /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
+ /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
+ /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
+ /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
+ /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
+ /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
+ /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3,
+ /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
+ /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
+};
+
diff --git a/source/spctool.cpp b/source/spctool.cpp
new file mode 100644
index 0000000..011498c
--- /dev/null
+++ b/source/spctool.cpp
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "snes9x.h"
+#include "spctool/dsp.h"
+#include "spctool/spc700.h"
+#include "spctool/soundmod.h"
+#include "apu.h"
+
+bool8 S9xOpenSoundDevice (int, bool8, int);
+
+void S9xSetPlaybackRate (uint32 rate)
+{
+ DOpt SmpOpt;
+
+ SmpOpt.Smp8bit=false;
+ SmpOpt.SmpMono=false;
+ SmpOpt.IntType=IntC;
+ SmpOpt.OldBRE=false;
+ SmpOpt.MixRout=1;
+ SetSPUOpt (rate, SmpOpt);
+
+// so.playback_rate = playback_rate;
+// so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate));
+ }
+
+bool8 S9xSetSoundMute (bool8 mute)
+{
+ return (TRUE);
+}
+
+START_EXTERN_C
+bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size)
+{
+ if (!(mode & 7))
+ return (TRUE);
+
+ S9xSetSoundMute (TRUE);
+ if (!S9xOpenSoundDevice (mode, stereo, buffer_size))
+ {
+ S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED,
+ "Sound device open failed");
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+void TraceSPC (unsigned char *PC, unsigned short YA, unsigned char X,
+ SPCFlags PS, unsigned char *SP)
+{
+ APURegisters.YA.W = YA;
+ APURegisters.X = X;
+ APURegisters.S = SP - IAPU.RAM;
+ IAPU.PC = PC;
+ IAPU._Carry = PS.C;
+ IAPU._Zero = !PS.Z | (PS.N << 7);
+ IAPU._Overflow = PS.V;
+ APURegisters.P = *(uint8 *) &PS;
+ S9xTraceAPU ();
+}
+
+bool8 S9xInitAPU ()
+{
+ void *SPCBase; //Base pointer and aligned pointer to SPC RAM
+
+ SPCBase=malloc(131072); //Allocate memory for SPC RAM
+ memset(SPCBase, 0, 131072);
+
+ IAPU.RAM=(uint8 *) InitSPU(SPCBase); //Initialize SPU w/ ptr to SPC RAM (Call only once)
+
+ S9xSetPlaybackRate (22050);
+ ResetSPU(20); //Reset SPU with pre-amp level of 30
+// _SetSPCDbg(TraceSPC); //Install debug handler
+ return (TRUE);
+}
+
+void S9xResetAPU ()
+{
+ ResetSPU(20);
+ IAPU.RAM [0xf1] = 0x80;
+ _FixSPC (0xffc0, 0, 0, 0, 0, 0xff);
+// FixDSP ();
+}
+
+extern "C" void EDSP (uint8 *, int32);
+
+void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
+{
+// _EmuDSP (buffer + byte_offset, sample_count / 2);
+
+ EDSP (buffer + byte_offset, sample_count / 2);
+#if 0
+for (int i = 0; i < 32; i++)
+printf ("%02x,", *(buffer + byte_offset + i));
+printf ("\n");
+#endif
+}
+END_EXTERN_C
+
+void S9xFixSoundAfterSnapshotLoad ()
+{
+}
+
+void S9xSetSoundControl (int)
+{
+}
+
+#ifdef DEBUGGER
+START_EXTERN_C
+void S9xDeinitAPU ()
+{
+}
+
+END_EXTERN_C
+#endif
+
diff --git a/source/srtc.cpp b/source/srtc.cpp
new file mode 100644
index 0000000..48add97
--- /dev/null
+++ b/source/srtc.cpp
@@ -0,0 +1,577 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include <string.h>
+#include "snes9x.h"
+#include "srtc.h"
+#include "memmap.h"
+
+/*** The format of the rtc_data structure is:
+
+Index Description Range (nibble)
+----- -------------- ---------------------------------------
+
+ 0 Seconds low 0-9
+ 1 Seconds high 0-5
+
+ 2 Minutes low 0-9
+ 3 Minutes high 0-5
+
+ 4 Hour low 0-9
+ 5 Hour high 0-2
+
+ 6 Day low 0-9
+ 7 Day high 0-3
+
+ 8 Month 1-C (0xC is December, 12th month)
+
+ 9 Year ones 0-9
+ A Year tens 0-9
+ B Year High 9-B (9=19xx, A=20xx, B=21xx)
+
+ C Day of week 0-6 (0=Sunday, 1=Monday,...,6=Saturday)
+
+***/
+
+SRTC_DATA rtc;
+
+
+static int month_keys[12] = { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 };
+
+
+/*********************************************************************************************
+ *
+ * Note, if you are doing a save state for this game:
+ *
+ * On save:
+ *
+ * Call S9xUpdateSrtcTime and save the rtc data structure.
+ *
+ * On load:
+ *
+ * restore the rtc data structure
+ * rtc.system_timestamp = time (NULL);
+ *
+ *
+ *********************************************************************************************/
+
+
+void S9xResetSRTC ()
+{
+ rtc.index = -1;
+ rtc.mode = MODE_READ;
+}
+
+void S9xHardResetSRTC ()
+{
+ ZeroMemory (&rtc, sizeof (rtc));
+ rtc.index = -1;
+ rtc.mode = MODE_READ;
+ rtc.count_enable = FALSE;
+ rtc.needs_init = TRUE;
+
+ // Get system timestamp
+ rtc.system_timestamp = time (NULL);
+}
+
+/**********************************************************************************************/
+/* S9xSRTCComputeDayOfWeek() */
+/* Return 0-6 for Sunday-Saturday */
+/**********************************************************************************************/
+unsigned int S9xSRTCComputeDayOfWeek ()
+{
+ unsigned year = rtc.data[10]*10 + rtc.data[9];
+ unsigned month = rtc.data[8];
+ unsigned day = rtc.data[7]*10 + rtc.data[6];
+ unsigned day_of_week;
+
+ year += (rtc.data[11] - 9) * 100;
+
+ // Range check the month for valid array indicies
+ if ( month > 12 )
+ month = 1;
+
+ day_of_week = year + (year / 4) + month_keys[month-1] + day - 1;
+
+ if(( year % 4 == 0 ) && ( month <= 2 ) )
+ day_of_week--;
+
+ day_of_week %= 7;
+
+ return day_of_week;
+}
+
+
+/**********************************************************************************************/
+/* S9xSRTCDaysInMonth() */
+/* Return the number of days in a specific month for a certain year */
+/**********************************************************************************************/
+int S9xSRTCDaysInMmonth( int month, int year )
+{
+ int mdays;
+
+ switch ( month )
+ {
+ case 2:
+ if ( ( year % 4 == 0 ) ) // DKJM2 only uses 199x - 22xx
+ mdays = 29;
+ else
+ mdays = 28;
+ break;
+
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ mdays = 30;
+ break;
+
+ default: // months 1,3,5,7,8,10,12
+ mdays = 31;
+ break;
+ }
+
+ return mdays;
+}
+
+
+#define DAYTICKS (60*60*24)
+#define HOURTICKS (60*60)
+#define MINUTETICKS 60
+
+
+/**********************************************************************************************/
+/* S9xUpdateSrtcTime() */
+/* Advance the S-RTC time if counting is enabled */
+/**********************************************************************************************/
+void S9xUpdateSrtcTime ()
+{
+ time_t cur_systime;
+ long time_diff;
+
+ // Keep track of game time by computing the number of seconds that pass on the system
+ // clock and adding the same number of seconds to the S-RTC clock structure.
+ // I originally tried using mktime and localtime library functions to keep track
+ // of time but some of the GNU time functions fail when the year goes to 2099
+ // (and maybe less) and this would have caused a bug with DKJM2 so I'm doing
+ // it this way to get around that problem.
+
+ // Note: Dai Kaijyu Monogatari II only allows dates in the range 1996-21xx.
+
+ if (rtc.count_enable && !rtc.needs_init)
+ {
+ cur_systime = time (NULL);
+
+ // This method assumes one time_t clock tick is one second
+ // which should work on PCs and GNU systems.
+ // If your tick interval is different adjust the
+ // DAYTICK, HOURTICK, and MINUTETICK defines
+
+ time_diff = (long) (cur_systime - rtc.system_timestamp);
+ rtc.system_timestamp = cur_systime;
+
+ if ( time_diff > 0 )
+ {
+ int seconds;
+ int minutes;
+ int hours;
+ int days;
+ int month;
+ int year;
+ int temp_days;
+
+ int year_hundreds;
+ int year_tens;
+ int year_ones;
+
+
+ if ( time_diff > DAYTICKS )
+ {
+ days = time_diff / DAYTICKS;
+ time_diff = time_diff - days * DAYTICKS;
+ }
+ else
+ {
+ days = 0;
+ }
+
+ if ( time_diff > HOURTICKS )
+ {
+ hours = time_diff / HOURTICKS;
+ time_diff = time_diff - hours * HOURTICKS;
+ }
+ else
+ {
+ hours = 0;
+ }
+
+ if ( time_diff > MINUTETICKS )
+ {
+ minutes = time_diff / MINUTETICKS;
+ time_diff = time_diff - minutes * MINUTETICKS;
+ }
+ else
+ {
+ minutes = 0;
+ }
+
+ if ( time_diff > 0 )
+ {
+ seconds = time_diff;
+ }
+ else
+ {
+ seconds = 0;
+ }
+
+
+ seconds += (rtc.data[1]*10 + rtc.data[0]);
+ if ( seconds >= 60 )
+ {
+ seconds -= 60;
+ minutes += 1;
+ }
+
+ minutes += (rtc.data[3]*10 + rtc.data[2]);
+ if ( minutes >= 60 )
+ {
+ minutes -= 60;
+ hours += 1;
+ }
+
+ hours += (rtc.data[5]*10 + rtc.data[4]);
+ if ( hours >= 24 )
+ {
+ hours -= 24;
+ days += 1;
+ }
+
+ if ( days > 0 )
+ {
+ year = rtc.data[10]*10 + rtc.data[9];
+ year += ( 1000 + rtc.data[11] * 100 );
+
+ month = rtc.data[8];
+ days += (rtc.data[7]*10 + rtc.data[6]);
+ while ( days > (temp_days = S9xSRTCDaysInMmonth( month, year )) )
+ {
+ days -= temp_days;
+ month += 1;
+ if ( month > 12 )
+ {
+ year += 1;
+ month = 1;
+ }
+ }
+
+ year_tens = year % 100;
+ year_ones = year_tens % 10;
+ year_tens /= 10;
+ year_hundreds = (year - 1000) / 100;
+
+ rtc.data[6] = days % 10;
+ rtc.data[7] = days / 10;
+ rtc.data[8] = month;
+ rtc.data[9] = year_ones;
+ rtc.data[10] = year_tens;
+ rtc.data[11] = year_hundreds;
+ rtc.data[12] = S9xSRTCComputeDayOfWeek ();
+ }
+
+ rtc.data[0] = seconds % 10;
+ rtc.data[1] = seconds / 10;
+ rtc.data[2] = minutes % 10;
+ rtc.data[3] = minutes / 10;
+ rtc.data[4] = hours % 10;
+ rtc.data[5] = hours / 10;
+
+ return;
+ }
+ }
+}
+
+
+/**********************************************************************************************/
+/* S9xSetSRTC() */
+/* This function sends data to the S-RTC used in Dai Kaijyu Monogatari II */
+/**********************************************************************************************/
+void S9xSetSRTC (uint8 data, uint16 Address)
+{
+
+ data &= 0x0F; // Data is only 4-bits, mask out unused bits.
+
+ if( data >= 0xD )
+ {
+ // It's an RTC command
+
+ switch ( data )
+ {
+ case 0xD:
+ rtc.mode = MODE_READ;
+ rtc.index = -1;
+ break;
+
+ case 0xE:
+ rtc.mode = MODE_COMMAND;
+ break;
+
+ default:
+ // Ignore the write if it's an 0xF ???
+ // Probably should switch back to read mode -- but this
+ // sequence never occurs in DKJM2
+ break;
+ }
+
+ return;
+ }
+
+ if ( rtc.mode == MODE_LOAD_RTC )
+ {
+ if ( (rtc.index >= 0) || (rtc.index < MAX_RTC_INDEX) )
+ {
+ rtc.data[rtc.index++] = data;
+
+ if ( rtc.index == MAX_RTC_INDEX )
+ {
+ // We have all the data for the RTC load
+
+ rtc.system_timestamp = time (NULL); // Get local system time
+
+ // Get the day of the week
+ rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek ();
+
+ // Start RTC counting again
+ rtc.count_enable = TRUE;
+ rtc.needs_init = FALSE;
+ }
+
+ return;
+ }
+ else
+ {
+ // Attempting to write too much data
+ // error(); // ignore??
+ }
+ }
+ else if ( rtc.mode == MODE_COMMAND )
+ {
+ switch( data )
+ {
+ case COMMAND_CLEAR_RTC:
+ // Disable RTC counter
+ rtc.count_enable = FALSE;
+
+ ZeroMemory (rtc.data, MAX_RTC_INDEX+1);
+ rtc.index = -1;
+ rtc.mode = MODE_COMMAND_DONE;
+ break;
+
+ case COMMAND_LOAD_RTC:
+ // Disable RTC counter
+ rtc.count_enable = FALSE;
+
+ rtc.index = 0; // Setup for writing
+ rtc.mode = MODE_LOAD_RTC;
+ break;
+
+ default:
+ rtc.mode = MODE_COMMAND_DONE;
+ // unrecognized command - need to implement.
+ }
+
+ return;
+ }
+ else
+ {
+ if ( rtc.mode == MODE_READ )
+ {
+ // Attempting to write while in read mode. Ignore.
+ }
+
+ if ( rtc.mode == MODE_COMMAND_DONE )
+ {
+ // Maybe this isn't an error. Maybe we should kick off
+ // a new E command. But is this valid?
+ }
+ }
+}
+
+/**********************************************************************************************/
+/* S9xGetSRTC() */
+/* This function retrieves data from the S-RTC */
+/**********************************************************************************************/
+uint8 S9xGetSRTC (uint16 Address)
+{
+ if ( rtc.mode == MODE_READ )
+ {
+ if ( rtc.index < 0 )
+ {
+ S9xUpdateSrtcTime (); // Only update it if the game reads it
+ rtc.index++;
+ return ( 0x0f ); // Send start marker.
+ }
+ else if (rtc.index > MAX_RTC_INDEX)
+ {
+ rtc.index = -1; // Setup for next set of reads
+ return ( 0x0f ); // Data done marker.
+ }
+ else
+ {
+ // Feed out the data
+ return rtc.data[rtc.index++];
+ }
+ }
+ else
+ {
+ return 0x0;
+ }
+}
+
+void S9xSRTCPreSaveState ()
+{
+ if (Settings.SRTC)
+ {
+ S9xUpdateSrtcTime ();
+
+ int s = Memory.SRAMSize ?
+ (1 << (Memory.SRAMSize + 3)) * 128 : 0;
+ if (s > 0x20000)
+ s = 0x20000;
+
+ SRAM [s + 0] = rtc.needs_init;
+ SRAM [s + 1] = rtc.count_enable;
+ memmove (&SRAM [s + 2], rtc.data, MAX_RTC_INDEX + 1);
+ SRAM [s + 3 + MAX_RTC_INDEX] = rtc.index;
+ SRAM [s + 4 + MAX_RTC_INDEX] = rtc.mode;
+
+#ifdef LSB_FIRST
+ memmove (&SRAM [s + 5 + MAX_RTC_INDEX], &rtc.system_timestamp, 8);
+#else
+ SRAM [s + 5 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 0);
+ SRAM [s + 6 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 8);
+ SRAM [s + 7 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 16);
+ SRAM [s + 8 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 24);
+ SRAM [s + 9 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 32);
+ SRAM [s + 10 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 40);
+ SRAM [s + 11 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 48);
+ SRAM [s + 12 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 56);
+#endif
+ }
+}
+
+void S9xSRTCPostLoadState ()
+{
+ if (Settings.SRTC)
+ {
+ int s = Memory.SRAMSize ?
+ (1 << (Memory.SRAMSize + 3)) * 128 : 0;
+ if (s > 0x20000)
+ s = 0x20000;
+
+ rtc.needs_init = SRAM [s + 0];
+ rtc.count_enable = SRAM [s + 1];
+ memmove (rtc.data, &SRAM [s + 2], MAX_RTC_INDEX + 1);
+ rtc.index = SRAM [s + 3 + MAX_RTC_INDEX];
+ rtc.mode = SRAM [s + 4 + MAX_RTC_INDEX];
+
+#ifdef LSB_FIRST
+ memmove (&rtc.system_timestamp, &SRAM [s + 5 + MAX_RTC_INDEX], 8);
+#else
+ rtc.system_timestamp |= (SRAM [s + 5 + MAX_RTC_INDEX] << 0);
+ rtc.system_timestamp |= (SRAM [s + 6 + MAX_RTC_INDEX] << 8);
+ rtc.system_timestamp |= (SRAM [s + 7 + MAX_RTC_INDEX] << 16);
+ rtc.system_timestamp |= (SRAM [s + 8 + MAX_RTC_INDEX] << 24);
+ rtc.system_timestamp |= (SRAM [s + 9 + MAX_RTC_INDEX] << 32);
+ rtc.system_timestamp |= (SRAM [s + 10 + MAX_RTC_INDEX] << 40);
+ rtc.system_timestamp |= (SRAM [s + 11 + MAX_RTC_INDEX] << 48);
+ rtc.system_timestamp |= (SRAM [s + 12 + MAX_RTC_INDEX] << 56);
+#endif
+ S9xUpdateSrtcTime ();
+ }
+}
+
diff --git a/source/srtc.h b/source/srtc.h
new file mode 100644
index 0000000..4ee24b0
--- /dev/null
+++ b/source/srtc.h
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _srtc_h_
+#define _srtc_h_
+
+#include <time.h>
+
+#define MAX_RTC_INDEX 0xC
+
+#define MODE_READ 0
+#define MODE_LOAD_RTC 1
+#define MODE_COMMAND 2
+#define MODE_COMMAND_DONE 3
+
+#define COMMAND_LOAD_RTC 0
+#define COMMAND_CLEAR_RTC 4
+
+
+/*** The format of the rtc_data structure is:
+
+Index Description Range (nibble)
+----- -------------- ---------------------------------------
+
+ 0 Seconds low 0-9
+ 1 Seconds high 0-5
+
+ 2 Minutes low 0-9
+ 3 Minutes high 0-5
+
+ 4 Hour low 0-9
+ 5 Hour high 0-2
+
+ 6 Day low 0-9
+ 7 Day high 0-3
+
+ 8 Month 1-C (0xC is December, 12th month)
+
+ 9 Year ones 0-9
+ A Year tens 0-9
+ B Year High 9-B (9=19xx, A=20xx, B=21xx)
+
+ C Day of week 0-6 (0=Sunday, 1=Monday,...,6=Saturday)
+
+***/
+
+typedef struct
+{
+ bool8 needs_init;
+ bool8 count_enable; // Does RTC mark time or is it frozen
+ uint8 data [MAX_RTC_INDEX+1];
+ int8 index;
+ uint8 mode;
+
+ time_t system_timestamp; // Of latest RTC load time
+ uint32 pad;
+} SRTC_DATA;
+
+extern SRTC_DATA rtc;
+
+void S9xUpdateSrtcTime ();
+void S9xSetSRTC (uint8 data, uint16 Address);
+uint8 S9xGetSRTC (uint16 Address);
+void S9xSRTCPreSaveState ();
+void S9xSRTCPostLoadState ();
+void S9xResetSRTC ();
+void S9xHardResetSRTC ();
+
+#define SRTC_SRAM_PAD (4 + 8 + 1 + MAX_RTC_INDEX)
+
+#endif // _srtc_h
+
diff --git a/source/tile.cpp b/source/tile.cpp
new file mode 100644
index 0000000..27e61f0
--- /dev/null
+++ b/source/tile.cpp
@@ -0,0 +1,1175 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#include "snes9x.h"
+
+#include "memmap.h"
+#include "ppu.h"
+#include "display.h"
+#include "gfx.h"
+#include "tile.h"
+
+extern uint32 HeadMask [4];
+extern uint32 TailMask [5];
+
+uint8 ConvertTile (uint8 *pCache, uint32 TileAddr)
+{
+ register uint8 *tp = &Memory.VRAM[TileAddr];
+ uint32 *p = (uint32 *) pCache;
+ uint32 non_zero = 0;
+ uint8 line;
+
+ switch (BG.BitShift)
+ {
+ case 8:
+ for (line = 8; line != 0; line--, tp += 2)
+ {
+ uint32 p1 = 0;
+ uint32 p2 = 0;
+ register uint8 pix;
+
+ if ((pix = *(tp + 0)))
+ {
+ p1 |= odd_high[0][pix >> 4];
+ p2 |= odd_low[0][pix & 0xf];
+ }
+ if ((pix = *(tp + 1)))
+ {
+ p1 |= even_high[0][pix >> 4];
+ p2 |= even_low[0][pix & 0xf];
+ }
+ if ((pix = *(tp + 16)))
+ {
+ p1 |= odd_high[1][pix >> 4];
+ p2 |= odd_low[1][pix & 0xf];
+ }
+ if ((pix = *(tp + 17)))
+ {
+ p1 |= even_high[1][pix >> 4];
+ p2 |= even_low[1][pix & 0xf];
+ }
+ if ((pix = *(tp + 32)))
+ {
+ p1 |= odd_high[2][pix >> 4];
+ p2 |= odd_low[2][pix & 0xf];
+ }
+ if ((pix = *(tp + 33)))
+ {
+ p1 |= even_high[2][pix >> 4];
+ p2 |= even_low[2][pix & 0xf];
+ }
+ if ((pix = *(tp + 48)))
+ {
+ p1 |= odd_high[3][pix >> 4];
+ p2 |= odd_low[3][pix & 0xf];
+ }
+ if ((pix = *(tp + 49)))
+ {
+ p1 |= even_high[3][pix >> 4];
+ p2 |= even_low[3][pix & 0xf];
+ }
+ *p++ = p1;
+ *p++ = p2;
+ non_zero |= p1 | p2;
+ }
+ break;
+
+ case 4:
+ for (line = 8; line != 0; line--, tp += 2)
+ {
+ uint32 p1 = 0;
+ uint32 p2 = 0;
+ register uint8 pix;
+ if ((pix = *(tp + 0)))
+ {
+ p1 |= odd_high[0][pix >> 4];
+ p2 |= odd_low[0][pix & 0xf];
+ }
+ if ((pix = *(tp + 1)))
+ {
+ p1 |= even_high[0][pix >> 4];
+ p2 |= even_low[0][pix & 0xf];
+ }
+ if ((pix = *(tp + 16)))
+ {
+ p1 |= odd_high[1][pix >> 4];
+ p2 |= odd_low[1][pix & 0xf];
+ }
+ if ((pix = *(tp + 17)))
+ {
+ p1 |= even_high[1][pix >> 4];
+ p2 |= even_low[1][pix & 0xf];
+ }
+ *p++ = p1;
+ *p++ = p2;
+ non_zero |= p1 | p2;
+ }
+ break;
+
+ case 2:
+ for (line = 8; line != 0; line--, tp += 2)
+ {
+ uint32 p1 = 0;
+ uint32 p2 = 0;
+ register uint8 pix;
+ if ((pix = *(tp + 0)))
+ {
+ p1 |= odd_high[0][pix >> 4];
+ p2 |= odd_low[0][pix & 0xf];
+ }
+ if ((pix = *(tp + 1)))
+ {
+ p1 |= even_high[0][pix >> 4];
+ p2 |= even_low[0][pix & 0xf];
+ }
+ *p++ = p1;
+ *p++ = p2;
+ non_zero |= p1 | p2;
+ }
+ break;
+ }
+ return (non_zero ? TRUE : BLANK_TILE);
+}
+
+inline void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ Screen [N] = (uint8) GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ Screen [N] = (uint8) GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = (uint8) GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = (uint8) GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = Screen [GFX.RealPitch + N * 2] = \
+ Screen [GFX.RealPitch + N * 2 + 1] = (uint8) GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = Depth [GFX.RealPitch + N * 2] = \
+ Depth [GFX.RealPitch + N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = Screen [GFX.RealPitch + N * 2] = \
+ Screen [GFX.RealPitch + N * 2 + 1] = (uint8) GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = Depth [GFX.RealPitch + N * 2] = \
+ Depth [GFX.RealPitch + N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS, WRITE_4PIXELS_FLIPPED, 4)
+}
+
+void DrawClippedTile (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS, WRITE_4PIXELS_FLIPPED, 4)
+}
+
+void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELSx2, WRITE_4PIXELS_FLIPPEDx2, 8)
+}
+
+void DrawClippedTilex2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELSx2, WRITE_4PIXELS_FLIPPEDx2, 8)
+}
+
+void DrawTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELSx2x2, WRITE_4PIXELS_FLIPPEDx2x2, 8)
+}
+
+void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELSx2x2, WRITE_4PIXELS_FLIPPEDx2x2, 8)
+}
+
+void DrawLargePixel (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint8 *sp = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+ uint8 pixel;
+#define PLOT_PIXEL(screen, pixel) (pixel)
+
+ RENDER_TILE_LARGE (((uint8) GFX.ScreenColors [pixel]), PLOT_PIXEL)
+}
+
+inline void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = \
+ Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = \
+ Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \
+ { \
+ Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = \
+ Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.ScreenColors [Pixel]; \
+ Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = \
+ Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+#undef FN
+}
+
+void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4)
+}
+
+void DrawClippedTile16 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4)
+}
+
+void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8)
+}
+
+void DrawClippedTile16x2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8)
+}
+
+void DrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8)
+}
+
+void DrawClippedTile16x2x2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8)
+}
+
+void DrawLargePixel16 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint16 *sp = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+ uint16 pixel;
+
+ RENDER_TILE_LARGE (GFX.ScreenColors [pixel], PLOT_PIXEL)
+}
+
+inline void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N]); \
+ else \
+ Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N]); \
+ else \
+ Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N])); \
+ else \
+ Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N])); \
+ else \
+ Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N]); \
+ else \
+ Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N]); \
+ else \
+ Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N]); \
+ else \
+ Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ if (SubDepth [N]) \
+ { \
+ if (SubDepth [N] != 1) \
+ Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \
+ Screen [GFX.Delta + N]); \
+ else \
+ Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ } \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+
+void DrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4)
+}
+
+void DrawClippedTile16Add (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4)
+}
+
+void DrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4)
+}
+
+void DrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4)
+}
+
+void DrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4)
+}
+
+void DrawClippedTile16Sub (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4)
+}
+
+void DrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4)
+}
+
+void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4)
+}
+
+inline void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ if (SubDepth [N] == 1) \
+ Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour)); \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel];\
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ if (SubDepth [N] == 1) \
+ Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour)); \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel];\
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \
+ { \
+ if (SubDepth [N] == 1) \
+ Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+inline void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels)
+{
+ uint32 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint8 *SubDepth = GFX.SubZBuffer + Offset;
+
+#define FN(N) \
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \
+ { \
+ if (SubDepth [N] == 1) \
+ Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \
+ GFX.FixedColour); \
+ else \
+ Screen [N] = GFX.ScreenColors [Pixel]; \
+ Depth [N] = GFX.Z2; \
+ }
+
+ FN(0)
+ FN(1)
+ FN(2)
+ FN(3)
+
+#undef FN
+}
+
+void DrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_ADDF1_2, WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4)
+}
+
+void DrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADDF1_2,
+ WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4)
+}
+
+void DrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_SUBF1_2, WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4)
+}
+
+void DrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUBF1_2,
+ WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4)
+}
+
+void DrawLargePixel16Add (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint16 *sp = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint16 pixel;
+
+#define LARGE_ADD_PIXEL(s, p) \
+(Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \
+ COLOR_ADD (p, *(s + GFX.Delta)) : \
+ COLOR_ADD (p, GFX.FixedColour)) \
+ : p)
+
+ RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_ADD_PIXEL)
+}
+
+void DrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint16 *sp = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint16 pixel;
+
+#define LARGE_ADD_PIXEL1_2(s, p) \
+((uint16) (Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \
+ COLOR_ADD1_2 (p, *(s + GFX.Delta)) : \
+ COLOR_ADD (p, GFX.FixedColour)) \
+ : p))
+
+ RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_ADD_PIXEL1_2)
+}
+
+void DrawLargePixel16Sub (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint16 *sp = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint16 pixel;
+
+#define LARGE_SUB_PIXEL(s, p) \
+(Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \
+ COLOR_SUB (p, *(s + GFX.Delta)) : \
+ COLOR_SUB (p, GFX.FixedColour)) \
+ : p)
+
+ RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_SUB_PIXEL)
+}
+
+void DrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Pixels,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint16 *sp = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.ZBuffer + Offset;
+ uint16 pixel;
+
+#define LARGE_SUB_PIXEL1_2(s, p) \
+(Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \
+ COLOR_SUB1_2 (p, *(s + GFX.Delta)) : \
+ COLOR_SUB (p, GFX.FixedColour)) \
+ : p)
+
+ RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_SUB_PIXEL1_2)
+}
+
diff --git a/source/tile.h b/source/tile.h
new file mode 100644
index 0000000..f5b4d85
--- /dev/null
+++ b/source/tile.h
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
+
+ (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
+ Jerremy Koot (jkoot@snes9x.com)
+
+ (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
+
+ (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
+ funkyass (funkyass@spam.shaw.ca),
+ Joel Yliluoma (http://iki.fi/bisqwit/)
+ Kris Bleakley (codeviolation@hotmail.com),
+ Matthew Kendora,
+ Nach (n-a-c-h@users.sourceforge.net),
+ Peter Bortas (peter@bortas.org) and
+ zones (kasumitokoduck@yahoo.com)
+
+ C4 x86 assembler and some C emulation code
+ (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
+ _Demo_ (_demo_@zsnes.com), and Nach
+
+ C4 C++ code
+ (c) Copyright 2003 Brad Jorsch
+
+ DSP-1 emulator code
+ (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
+ John Weidman, neviksti (neviksti@hotmail.com),
+ Kris Bleakley, Andreas Naive
+
+ DSP-2 emulator code
+ (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
+ Lord Nightmare (lord_nightmare@users.sourceforge.net
+
+ OBC1 emulator code
+ (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
+ Kris Bleakley
+ Ported from x86 assembler to C by sanmaiwashi
+
+ SPC7110 and RTC C++ emulator code
+ (c) Copyright 2002 Matthew Kendora with research by
+ zsKnight, John Weidman, and Dark Force
+
+ S-DD1 C emulator code
+ (c) Copyright 2003 Brad Jorsch with research by
+ Andreas Naive and John Weidman
+
+ S-RTC C emulator code
+ (c) Copyright 2001 John Weidman
+
+ ST010 C++ emulator code
+ (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
+
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+
+ Super FX C emulator code
+ (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
+
+
+ SH assembler code partly based on x86 assembler code
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
+
+ Specific ports contains the works of other authors. See headers in
+ individual files.
+
+ Snes9x homepage: http://www.snes9x.com
+
+ Permission to use, copy, modify and distribute Snes9x in both binary and
+ source form, for non-commercial purposes, is hereby granted without fee,
+ providing that this license information and copyright notice appear with
+ all copies and any derived work.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event shall the authors be held liable for any damages
+ arising from the use of this software.
+
+ Snes9x is freeware for PERSONAL USE only. Commercial users should
+ seek permission of the copyright holders first. Commercial use includes
+ charging money for Snes9x or software derived from Snes9x.
+
+ The copyright holders request that bug fixes and improvements to the code
+ should be forwarded to them so everyone can benefit from the modifications
+ in future versions.
+
+ Super NES and Super Nintendo Entertainment System are trademarks of
+ Nintendo Co., Limited and its subsidiary companies.
+*******************************************************************************/
+#ifndef _TILE_H_
+#define _TILE_H_
+
+#define TILE_PREAMBLE \
+ uint8 *pCache; \
+\
+ uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \
+ if ((Tile & 0x1ff) >= 256) \
+ TileAddr += BG.NameSelect; \
+\
+ TileAddr &= 0xffff; \
+\
+ uint32 TileNumber; \
+ pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \
+\
+ if (!BG.Buffered [TileNumber]) \
+ BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \
+\
+ if (BG.Buffered [TileNumber] == BLANK_TILE) \
+ return; \
+\
+ register uint32 l; \
+ if (BG.DirectColourMode) \
+ { \
+ if (IPPU.DirectColourMapsNeedRebuild) \
+ S9xBuildDirectColourMaps (); \
+ GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \
+ } \
+ else \
+ GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];
+
+#define RENDER_TILE(NORMAL, FLIPPED, N) \
+ if (!(Tile & (V_FLIP | H_FLIP))) \
+ { \
+ bp = pCache + StartLine; \
+ for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \
+ { \
+ if (*(uint32 *) bp) \
+ NORMAL (Offset, bp); \
+ if (*(uint32 *) (bp + 4)) \
+ NORMAL (Offset + N, bp + 4); \
+ } \
+ } \
+ else \
+ if (!(Tile & V_FLIP)) \
+ { \
+ bp = pCache + StartLine; \
+ for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \
+ { \
+ if (*(uint32 *) (bp + 4)) \
+ FLIPPED (Offset, bp + 4); \
+ if (*(uint32 *) bp) \
+ FLIPPED (Offset + N, bp); \
+ } \
+ } \
+ else \
+ if (Tile & H_FLIP) \
+ { \
+ bp = pCache + 56 - StartLine; \
+ for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \
+ { \
+ if (*(uint32 *) (bp + 4)) \
+ FLIPPED (Offset, bp + 4); \
+ if (*(uint32 *) bp) \
+ FLIPPED (Offset + N, bp); \
+ } \
+ } \
+ else \
+ { \
+ bp = pCache + 56 - StartLine; \
+ for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \
+ { \
+ if (*(uint32 *) bp) \
+ NORMAL (Offset, bp); \
+ if (*(uint32 *) (bp + 4)) \
+ NORMAL (Offset + N, bp + 4); \
+ } \
+ }
+
+#define TILE_CLIP_PREAMBLE \
+ uint32 dd; \
+ uint32 d1; \
+ uint32 d2; \
+\
+ if (StartPixel < 4) \
+ { \
+ d1 = HeadMask [StartPixel]; \
+ if (StartPixel + Width < 4) \
+ d1 &= TailMask [StartPixel + Width]; \
+ } \
+ else \
+ d1 = 0; \
+\
+ if (StartPixel + Width > 4) \
+ { \
+ if (StartPixel > 4) \
+ d2 = HeadMask [StartPixel - 4]; \
+ else \
+ d2 = 0xffffffff; \
+\
+ d2 &= TailMask [(StartPixel + Width - 4)]; \
+ } \
+ else \
+ d2 = 0;
+
+
+#define RENDER_CLIPPED_TILE(NORMAL, FLIPPED, N) \
+ if (!(Tile & (V_FLIP | H_FLIP))) \
+ { \
+ bp = pCache + StartLine; \
+ for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \
+ { \
+ if ((dd = (*(uint32 *) bp) & d1)) \
+ NORMAL (Offset, (uint8 *) &dd); \
+ if ((dd = (*(uint32 *) (bp + 4)) & d2)) \
+ NORMAL (Offset + N, (uint8 *) &dd); \
+ } \
+ } \
+ else \
+ if (!(Tile & V_FLIP)) \
+ { \
+ bp = pCache + StartLine; \
+ SWAP_DWORD (d1); \
+ SWAP_DWORD (d2); \
+ for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \
+ { \
+ if ((dd = *(uint32 *) (bp + 4) & d1)) \
+ FLIPPED (Offset, (uint8 *) &dd); \
+ if ((dd = *(uint32 *) bp & d2)) \
+ FLIPPED (Offset + N, (uint8 *) &dd); \
+ } \
+ } \
+ else \
+ if (Tile & H_FLIP) \
+ { \
+ bp = pCache + 56 - StartLine; \
+ SWAP_DWORD (d1); \
+ SWAP_DWORD (d2); \
+ for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \
+ { \
+ if ((dd = *(uint32 *) (bp + 4) & d1)) \
+ FLIPPED (Offset, (uint8 *) &dd); \
+ if ((dd = *(uint32 *) bp & d2)) \
+ FLIPPED (Offset + N, (uint8 *) &dd); \
+ } \
+ } \
+ else \
+ { \
+ bp = pCache + 56 - StartLine; \
+ for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \
+ { \
+ if ((dd = (*(uint32 *) bp) & d1)) \
+ NORMAL (Offset, (uint8 *) &dd); \
+ if ((dd = (*(uint32 *) (bp + 4)) & d2)) \
+ NORMAL (Offset + N, (uint8 *) &dd); \
+ } \
+ }
+
+#define RENDER_TILE_LARGE(PIXEL, FUNCTION) \
+ if (!(Tile & (V_FLIP | H_FLIP))) \
+ { \
+ if ((pixel = *(pCache + StartLine + StartPixel))) \
+ { \
+ pixel = PIXEL; \
+ for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \
+ { \
+ for (int z = Pixels - 1; z >= 0; z--) \
+ if (GFX.Z1 > Depth [z]) \
+ { \
+ sp [z] = FUNCTION(sp + z, pixel); \
+ Depth [z] = GFX.Z2; \
+ }\
+ } \
+ } \
+ } \
+ else \
+ if (!(Tile & V_FLIP)) \
+ { \
+ StartPixel = 7 - StartPixel; \
+ if ((pixel = *(pCache + StartLine + StartPixel))) \
+ { \
+ pixel = PIXEL; \
+ for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \
+ { \
+ for (int z = Pixels - 1; z >= 0; z--) \
+ if (GFX.Z1 > Depth [z]) \
+ { \
+ sp [z] = FUNCTION(sp + z, pixel); \
+ Depth [z] = GFX.Z2; \
+ }\
+ } \
+ } \
+ } \
+ else \
+ if (Tile & H_FLIP) \
+ { \
+ StartPixel = 7 - StartPixel; \
+ if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \
+ { \
+ pixel = PIXEL; \
+ for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \
+ { \
+ for (int z = Pixels - 1; z >= 0; z--) \
+ if (GFX.Z1 > Depth [z]) \
+ { \
+ sp [z] = FUNCTION(sp + z, pixel); \
+ Depth [z] = GFX.Z2; \
+ }\
+ } \
+ } \
+ } \
+ else \
+ { \
+ if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \
+ { \
+ pixel = PIXEL; \
+ for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \
+ { \
+ for (int z = Pixels - 1; z >= 0; z--) \
+ if (GFX.Z1 > Depth [z]) \
+ { \
+ sp [z] = FUNCTION(sp + z, pixel); \
+ Depth [z] = GFX.Z2; \
+ }\
+ } \
+ } \
+ }
+#endif
+
diff --git a/source/unicode.c b/source/unicode.c
new file mode 100644
index 0000000..46e1de8
--- /dev/null
+++ b/source/unicode.c
@@ -0,0 +1,1854 @@
+/* unofficial gameplaySP kai
+ *
+ * Copyright (C) 2007 NJ
+ * Copyright (C) 2007 takka <takka@tfact.net>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/unistd.h>
+
+#define ERR (0)
+
+static const unsigned short _00[0x100] =
+{
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67,
+ 0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f,
+ 0xff70, 0xff71, 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77,
+ 0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f,
+ 0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87,
+ 0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f,
+ 0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97,
+ 0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _81[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3000, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a, 0xff1b,
+ 0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8, 0xff3e,
+ 0xffe3, 0xff3f, 0x30fd, 0x30fe, 0x309d, 0x309e, 0x3003, 0x4edd,
+ 0x3005, 0x3006, 0x3007, 0x30fc, 0x2015, 0x2010, 0xff0f, 0xff3c,
+ 0xff5e, 0x2225, 0xff5c, 0x2026, 0x2025, 0x2018, 0x2019, 0x201c,
+ 0x201d, 0xff08, 0xff09, 0x3014, 0x3015, 0xff3b, 0xff3d, 0xff5b,
+ 0xff5d, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e,
+ 0x300f, 0x3010, 0x3011, 0xff0b, 0xff0d, 0x00b1, 0x00d7, 0x0000,
+ 0x00f7, 0xff1d, 0x2260, 0xff1c, 0xff1e, 0x2266, 0x2267, 0x221e,
+ 0x2234, 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xffe5,
+ 0xff04, 0xffe0, 0xffe1, 0xff05, 0xff03, 0xff06, 0xff0a, 0xff20,
+ 0x00a7, 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, 0x25c6,
+ 0x25a1, 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x203b, 0x3012,
+ 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283, 0x222a, 0x2229,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2227, 0x2228, 0xffe2, 0x21d2, 0x21d4, 0x2200, 0x2203, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2220, 0x22a5, 0x2312, 0x2202, 0x2207, 0x2261,
+ 0x2252, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, 0x2235, 0x222b,
+ 0x222c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x212b, 0x2030, 0x266f, 0x266d, 0x266a, 0x2020, 0x2021, 0x00b6,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x25ef, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _82[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff10,
+ 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18,
+ 0xff19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28,
+ 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30,
+ 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38,
+ 0xff39, 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47,
+ 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f,
+ 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57,
+ 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3041,
+ 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049,
+ 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, 0x3051,
+ 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059,
+ 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, 0x3061,
+ 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069,
+ 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, 0x3071,
+ 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079,
+ 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, 0x3081,
+ 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, 0x3089,
+ 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, 0x3091,
+ 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _83[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8,
+ 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0,
+ 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8,
+ 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0,
+ 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8,
+ 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0,
+ 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8,
+ 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x0000,
+ 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7,
+ 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef,
+ 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0391,
+ 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399,
+ 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1,
+ 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03b1,
+ 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9,
+ 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1,
+ 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _84[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416,
+ 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426,
+ 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e,
+ 0x042f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436,
+ 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x0000,
+ 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
+ 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d,
+ 0x044e, 0x044f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2500,
+ 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, 0x2524,
+ 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, 0x2517,
+ 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, 0x2528,
+ 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _87[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f,
+ 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, 0x2163,
+ 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x0000, 0x3349,
+ 0x3314, 0x3322, 0x334d, 0x3318, 0x3327, 0x3303, 0x3336, 0x3351,
+ 0x3357, 0x330d, 0x3326, 0x3323, 0x332b, 0x334a, 0x333b, 0x339c,
+ 0x339d, 0x339e, 0x338e, 0x338f, 0x33c4, 0x33a1, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x337b, 0x0000,
+ 0x301d, 0x301f, 0x2116, 0x33cd, 0x2121, 0x32a4, 0x32a5, 0x32a6,
+ 0x32a7, 0x32a8, 0x3231, 0x3232, 0x3239, 0x337e, 0x337d, 0x337c,
+ 0x2252, 0x2261, 0x222b, 0x222e, 0x2211, 0x221a, 0x22a5, 0x2220,
+ 0x221f, 0x22bf, 0x2235, 0x2229, 0x222a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _88[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e9c,
+ 0x5516, 0x5a03, 0x963f, 0x54c0, 0x611b, 0x6328, 0x59f6, 0x9022,
+ 0x8475, 0x831c, 0x7a50, 0x60aa, 0x63e1, 0x6e25, 0x65ed, 0x8466,
+ 0x82a6, 0x9bf5, 0x6893, 0x5727, 0x65a1, 0x6271, 0x5b9b, 0x59d0,
+ 0x867b, 0x98f4, 0x7d62, 0x7dbe, 0x9b8e, 0x6216, 0x7c9f, 0x88b7,
+ 0x5b89, 0x5eb5, 0x6309, 0x6697, 0x6848, 0x95c7, 0x978d, 0x674f,
+ 0x4ee5, 0x4f0a, 0x4f4d, 0x4f9d, 0x5049, 0x56f2, 0x5937, 0x59d4,
+ 0x5a01, 0x5c09, 0x60df, 0x610f, 0x6170, 0x6613, 0x6905, 0x70ba,
+ 0x754f, 0x7570, 0x79fb, 0x7dad, 0x7def, 0x80c3, 0x840e, 0x8863,
+ 0x8b02, 0x9055, 0x907a, 0x533b, 0x4e95, 0x4ea5, 0x57df, 0x80b2,
+ 0x90c1, 0x78ef, 0x4e00, 0x58f1, 0x6ea2, 0x9038, 0x7a32, 0x8328,
+ 0x828b, 0x9c2f, 0x5141, 0x5370, 0x54bd, 0x54e1, 0x56e0, 0x59fb,
+ 0x5f15, 0x98f2, 0x6deb, 0x80e4, 0x852d, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _89[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9662, 0x9670, 0x96a0, 0x97fb, 0x540b, 0x53f3, 0x5b87, 0x70cf,
+ 0x7fbd, 0x8fc2, 0x96e8, 0x536f, 0x9d5c, 0x7aba, 0x4e11, 0x7893,
+ 0x81fc, 0x6e26, 0x5618, 0x5504, 0x6b1d, 0x851a, 0x9c3b, 0x59e5,
+ 0x53a9, 0x6d66, 0x74dc, 0x958f, 0x5642, 0x4e91, 0x904b, 0x96f2,
+ 0x834f, 0x990c, 0x53e1, 0x55b6, 0x5b30, 0x5f71, 0x6620, 0x66f3,
+ 0x6804, 0x6c38, 0x6cf3, 0x6d29, 0x745b, 0x76c8, 0x7a4e, 0x9834,
+ 0x82f1, 0x885b, 0x8a60, 0x92ed, 0x6db2, 0x75ab, 0x76ca, 0x99c5,
+ 0x60a6, 0x8b01, 0x8d8a, 0x95b2, 0x698e, 0x53ad, 0x5186, 0x0000,
+ 0x5712, 0x5830, 0x5944, 0x5bb4, 0x5ef6, 0x6028, 0x63a9, 0x63f4,
+ 0x6cbf, 0x6f14, 0x708e, 0x7114, 0x7159, 0x71d5, 0x733f, 0x7e01,
+ 0x8276, 0x82d1, 0x8597, 0x9060, 0x925b, 0x9d1b, 0x5869, 0x65bc,
+ 0x6c5a, 0x7525, 0x51f9, 0x592e, 0x5965, 0x5f80, 0x5fdc, 0x62bc,
+ 0x65fa, 0x6a2a, 0x6b27, 0x6bb4, 0x738b, 0x7fc1, 0x8956, 0x9d2c,
+ 0x9d0e, 0x9ec4, 0x5ca1, 0x6c96, 0x837b, 0x5104, 0x5c4b, 0x61b6,
+ 0x81c6, 0x6876, 0x7261, 0x4e59, 0x4ffa, 0x5378, 0x6069, 0x6e29,
+ 0x7a4f, 0x97f3, 0x4e0b, 0x5316, 0x4eee, 0x4f55, 0x4f3d, 0x4fa1,
+ 0x4f73, 0x52a0, 0x53ef, 0x5609, 0x590f, 0x5ac1, 0x5bb6, 0x5be1,
+ 0x79d1, 0x6687, 0x679c, 0x67b6, 0x6b4c, 0x6cb3, 0x706b, 0x73c2,
+ 0x798d, 0x79be, 0x7a3c, 0x7b87, 0x82b1, 0x82db, 0x8304, 0x8377,
+ 0x83ef, 0x83d3, 0x8766, 0x8ab2, 0x5629, 0x8ca8, 0x8fe6, 0x904e,
+ 0x971e, 0x868a, 0x4fc4, 0x5ce8, 0x6211, 0x7259, 0x753b, 0x81e5,
+ 0x82bd, 0x86fe, 0x8cc0, 0x96c5, 0x9913, 0x99d5, 0x4ecb, 0x4f1a,
+ 0x89e3, 0x56de, 0x584a, 0x58ca, 0x5efb, 0x5feb, 0x602a, 0x6094,
+ 0x6062, 0x61d0, 0x6212, 0x62d0, 0x6539, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _8a[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9b41, 0x6666, 0x68b0, 0x6d77, 0x7070, 0x754c, 0x7686, 0x7d75,
+ 0x82a5, 0x87f9, 0x958b, 0x968e, 0x8c9d, 0x51f1, 0x52be, 0x5916,
+ 0x54b3, 0x5bb3, 0x5d16, 0x6168, 0x6982, 0x6daf, 0x788d, 0x84cb,
+ 0x8857, 0x8a72, 0x93a7, 0x9ab8, 0x6d6c, 0x99a8, 0x86d9, 0x57a3,
+ 0x67ff, 0x86ce, 0x920e, 0x5283, 0x5687, 0x5404, 0x5ed3, 0x62e1,
+ 0x64b9, 0x683c, 0x6838, 0x6bbb, 0x7372, 0x78ba, 0x7a6b, 0x899a,
+ 0x89d2, 0x8d6b, 0x8f03, 0x90ed, 0x95a3, 0x9694, 0x9769, 0x5b66,
+ 0x5cb3, 0x697d, 0x984d, 0x984e, 0x639b, 0x7b20, 0x6a2b, 0x0000,
+ 0x6a7f, 0x68b6, 0x9c0d, 0x6f5f, 0x5272, 0x559d, 0x6070, 0x62ec,
+ 0x6d3b, 0x6e07, 0x6ed1, 0x845b, 0x8910, 0x8f44, 0x4e14, 0x9c39,
+ 0x53f6, 0x691b, 0x6a3a, 0x9784, 0x682a, 0x515c, 0x7ac3, 0x84b2,
+ 0x91dc, 0x938c, 0x565b, 0x9d28, 0x6822, 0x8305, 0x8431, 0x7ca5,
+ 0x5208, 0x82c5, 0x74e6, 0x4e7e, 0x4f83, 0x51a0, 0x5bd2, 0x520a,
+ 0x52d8, 0x52e7, 0x5dfb, 0x559a, 0x582a, 0x59e6, 0x5b8c, 0x5b98,
+ 0x5bdb, 0x5e72, 0x5e79, 0x60a3, 0x611f, 0x6163, 0x61be, 0x63db,
+ 0x6562, 0x67d1, 0x6853, 0x68fa, 0x6b3e, 0x6b53, 0x6c57, 0x6f22,
+ 0x6f97, 0x6f45, 0x74b0, 0x7518, 0x76e3, 0x770b, 0x7aff, 0x7ba1,
+ 0x7c21, 0x7de9, 0x7f36, 0x7ff0, 0x809d, 0x8266, 0x839e, 0x89b3,
+ 0x8acc, 0x8cab, 0x9084, 0x9451, 0x9593, 0x9591, 0x95a2, 0x9665,
+ 0x97d3, 0x9928, 0x8218, 0x4e38, 0x542b, 0x5cb8, 0x5dcc, 0x73a9,
+ 0x764c, 0x773c, 0x5ca9, 0x7feb, 0x8d0b, 0x96c1, 0x9811, 0x9854,
+ 0x9858, 0x4f01, 0x4f0e, 0x5371, 0x559c, 0x5668, 0x57fa, 0x5947,
+ 0x5b09, 0x5bc4, 0x5c90, 0x5e0c, 0x5e7e, 0x5fcc, 0x63ee, 0x673a,
+ 0x65d7, 0x65e2, 0x671f, 0x68cb, 0x68c4, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _8b[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6a5f, 0x5e30, 0x6bc5, 0x6c17, 0x6c7d, 0x757f, 0x7948, 0x5b63,
+ 0x7a00, 0x7d00, 0x5fbd, 0x898f, 0x8a18, 0x8cb4, 0x8d77, 0x8ecc,
+ 0x8f1d, 0x98e2, 0x9a0e, 0x9b3c, 0x4e80, 0x507d, 0x5100, 0x5993,
+ 0x5b9c, 0x622f, 0x6280, 0x64ec, 0x6b3a, 0x72a0, 0x7591, 0x7947,
+ 0x7fa9, 0x87fb, 0x8abc, 0x8b70, 0x63ac, 0x83ca, 0x97a0, 0x5409,
+ 0x5403, 0x55ab, 0x6854, 0x6a58, 0x8a70, 0x7827, 0x6775, 0x9ecd,
+ 0x5374, 0x5ba2, 0x811a, 0x8650, 0x9006, 0x4e18, 0x4e45, 0x4ec7,
+ 0x4f11, 0x53ca, 0x5438, 0x5bae, 0x5f13, 0x6025, 0x6551, 0x0000,
+ 0x673d, 0x6c42, 0x6c72, 0x6ce3, 0x7078, 0x7403, 0x7a76, 0x7aae,
+ 0x7b08, 0x7d1a, 0x7cfe, 0x7d66, 0x65e7, 0x725b, 0x53bb, 0x5c45,
+ 0x5de8, 0x62d2, 0x62e0, 0x6319, 0x6e20, 0x865a, 0x8a31, 0x8ddd,
+ 0x92f8, 0x6f01, 0x79a6, 0x9b5a, 0x4ea8, 0x4eab, 0x4eac, 0x4f9b,
+ 0x4fa0, 0x50d1, 0x5147, 0x7af6, 0x5171, 0x51f6, 0x5354, 0x5321,
+ 0x537f, 0x53eb, 0x55ac, 0x5883, 0x5ce1, 0x5f37, 0x5f4a, 0x602f,
+ 0x6050, 0x606d, 0x631f, 0x6559, 0x6a4b, 0x6cc1, 0x72c2, 0x72ed,
+ 0x77ef, 0x80f8, 0x8105, 0x8208, 0x854e, 0x90f7, 0x93e1, 0x97ff,
+ 0x9957, 0x9a5a, 0x4ef0, 0x51dd, 0x5c2d, 0x6681, 0x696d, 0x5c40,
+ 0x66f2, 0x6975, 0x7389, 0x6850, 0x7c81, 0x50c5, 0x52e4, 0x5747,
+ 0x5dfe, 0x9326, 0x65a4, 0x6b23, 0x6b3d, 0x7434, 0x7981, 0x79bd,
+ 0x7b4b, 0x7dca, 0x82b9, 0x83cc, 0x887f, 0x895f, 0x8b39, 0x8fd1,
+ 0x91d1, 0x541f, 0x9280, 0x4e5d, 0x5036, 0x53e5, 0x533a, 0x72d7,
+ 0x7396, 0x77e9, 0x82e6, 0x8eaf, 0x99c6, 0x99c8, 0x99d2, 0x5177,
+ 0x611a, 0x865e, 0x55b0, 0x7a7a, 0x5076, 0x5bd3, 0x9047, 0x9685,
+ 0x4e32, 0x6adb, 0x91e7, 0x5c51, 0x5c48, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _8c[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6398, 0x7a9f, 0x6c93, 0x9774, 0x8f61, 0x7aaa, 0x718a, 0x9688,
+ 0x7c82, 0x6817, 0x7e70, 0x6851, 0x936c, 0x52f2, 0x541b, 0x85ab,
+ 0x8a13, 0x7fa4, 0x8ecd, 0x90e1, 0x5366, 0x8888, 0x7941, 0x4fc2,
+ 0x50be, 0x5211, 0x5144, 0x5553, 0x572d, 0x73ea, 0x578b, 0x5951,
+ 0x5f62, 0x5f84, 0x6075, 0x6176, 0x6167, 0x61a9, 0x63b2, 0x643a,
+ 0x656c, 0x666f, 0x6842, 0x6e13, 0x7566, 0x7a3d, 0x7cfb, 0x7d4c,
+ 0x7d99, 0x7e4b, 0x7f6b, 0x830e, 0x834a, 0x86cd, 0x8a08, 0x8a63,
+ 0x8b66, 0x8efd, 0x981a, 0x9d8f, 0x82b8, 0x8fce, 0x9be8, 0x0000,
+ 0x5287, 0x621f, 0x6483, 0x6fc0, 0x9699, 0x6841, 0x5091, 0x6b20,
+ 0x6c7a, 0x6f54, 0x7a74, 0x7d50, 0x8840, 0x8a23, 0x6708, 0x4ef6,
+ 0x5039, 0x5026, 0x5065, 0x517c, 0x5238, 0x5263, 0x55a7, 0x570f,
+ 0x5805, 0x5acc, 0x5efa, 0x61b2, 0x61f8, 0x62f3, 0x6372, 0x691c,
+ 0x6a29, 0x727d, 0x72ac, 0x732e, 0x7814, 0x786f, 0x7d79, 0x770c,
+ 0x80a9, 0x898b, 0x8b19, 0x8ce2, 0x8ed2, 0x9063, 0x9375, 0x967a,
+ 0x9855, 0x9a13, 0x9e78, 0x5143, 0x539f, 0x53b3, 0x5e7b, 0x5f26,
+ 0x6e1b, 0x6e90, 0x7384, 0x73fe, 0x7d43, 0x8237, 0x8a00, 0x8afa,
+ 0x9650, 0x4e4e, 0x500b, 0x53e4, 0x547c, 0x56fa, 0x59d1, 0x5b64,
+ 0x5df1, 0x5eab, 0x5f27, 0x6238, 0x6545, 0x67af, 0x6e56, 0x72d0,
+ 0x7cca, 0x88b4, 0x80a1, 0x80e1, 0x83f0, 0x864e, 0x8a87, 0x8de8,
+ 0x9237, 0x96c7, 0x9867, 0x9f13, 0x4e94, 0x4e92, 0x4f0d, 0x5348,
+ 0x5449, 0x543e, 0x5a2f, 0x5f8c, 0x5fa1, 0x609f, 0x68a7, 0x6a8e,
+ 0x745a, 0x7881, 0x8a9e, 0x8aa4, 0x8b77, 0x9190, 0x4e5e, 0x9bc9,
+ 0x4ea4, 0x4f7c, 0x4faf, 0x5019, 0x5016, 0x5149, 0x516c, 0x529f,
+ 0x52b9, 0x52fe, 0x539a, 0x53e3, 0x5411, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _8d[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x540e, 0x5589, 0x5751, 0x57a2, 0x597d, 0x5b54, 0x5b5d, 0x5b8f,
+ 0x5de5, 0x5de7, 0x5df7, 0x5e78, 0x5e83, 0x5e9a, 0x5eb7, 0x5f18,
+ 0x6052, 0x614c, 0x6297, 0x62d8, 0x63a7, 0x653b, 0x6602, 0x6643,
+ 0x66f4, 0x676d, 0x6821, 0x6897, 0x69cb, 0x6c5f, 0x6d2a, 0x6d69,
+ 0x6e2f, 0x6e9d, 0x7532, 0x7687, 0x786c, 0x7a3f, 0x7ce0, 0x7d05,
+ 0x7d18, 0x7d5e, 0x7db1, 0x8015, 0x8003, 0x80af, 0x80b1, 0x8154,
+ 0x818f, 0x822a, 0x8352, 0x884c, 0x8861, 0x8b1b, 0x8ca2, 0x8cfc,
+ 0x90ca, 0x9175, 0x9271, 0x783f, 0x92fc, 0x95a4, 0x964d, 0x0000,
+ 0x9805, 0x9999, 0x9ad8, 0x9d3b, 0x525b, 0x52ab, 0x53f7, 0x5408,
+ 0x58d5, 0x62f7, 0x6fe0, 0x8c6a, 0x8f5f, 0x9eb9, 0x514b, 0x523b,
+ 0x544a, 0x56fd, 0x7a40, 0x9177, 0x9d60, 0x9ed2, 0x7344, 0x6f09,
+ 0x8170, 0x7511, 0x5ffd, 0x60da, 0x9aa8, 0x72db, 0x8fbc, 0x6b64,
+ 0x9803, 0x4eca, 0x56f0, 0x5764, 0x58be, 0x5a5a, 0x6068, 0x61c7,
+ 0x660f, 0x6606, 0x6839, 0x68b1, 0x6df7, 0x75d5, 0x7d3a, 0x826e,
+ 0x9b42, 0x4e9b, 0x4f50, 0x53c9, 0x5506, 0x5d6f, 0x5de6, 0x5dee,
+ 0x67fb, 0x6c99, 0x7473, 0x7802, 0x8a50, 0x9396, 0x88df, 0x5750,
+ 0x5ea7, 0x632b, 0x50b5, 0x50ac, 0x518d, 0x6700, 0x54c9, 0x585e,
+ 0x59bb, 0x5bb0, 0x5f69, 0x624d, 0x63a1, 0x683d, 0x6b73, 0x6e08,
+ 0x707d, 0x91c7, 0x7280, 0x7815, 0x7826, 0x796d, 0x658e, 0x7d30,
+ 0x83dc, 0x88c1, 0x8f09, 0x969b, 0x5264, 0x5728, 0x6750, 0x7f6a,
+ 0x8ca1, 0x51b4, 0x5742, 0x962a, 0x583a, 0x698a, 0x80b4, 0x54b2,
+ 0x5d0e, 0x57fc, 0x7895, 0x9dfa, 0x4f5c, 0x524a, 0x548b, 0x643e,
+ 0x6628, 0x6714, 0x67f5, 0x7a84, 0x7b56, 0x7d22, 0x932f, 0x685c,
+ 0x9bad, 0x7b39, 0x5319, 0x518a, 0x5237, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _8e[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5bdf, 0x62f6, 0x64ae, 0x64e6, 0x672d, 0x6bba, 0x85a9, 0x96d1,
+ 0x7690, 0x9bd6, 0x634c, 0x9306, 0x9bab, 0x76bf, 0x6652, 0x4e09,
+ 0x5098, 0x53c2, 0x5c71, 0x60e8, 0x6492, 0x6563, 0x685f, 0x71e6,
+ 0x73ca, 0x7523, 0x7b97, 0x7e82, 0x8695, 0x8b83, 0x8cdb, 0x9178,
+ 0x9910, 0x65ac, 0x66ab, 0x6b8b, 0x4ed5, 0x4ed4, 0x4f3a, 0x4f7f,
+ 0x523a, 0x53f8, 0x53f2, 0x55e3, 0x56db, 0x58eb, 0x59cb, 0x59c9,
+ 0x59ff, 0x5b50, 0x5c4d, 0x5e02, 0x5e2b, 0x5fd7, 0x601d, 0x6307,
+ 0x652f, 0x5b5c, 0x65af, 0x65bd, 0x65e8, 0x679d, 0x6b62, 0x0000,
+ 0x6b7b, 0x6c0f, 0x7345, 0x7949, 0x79c1, 0x7cf8, 0x7d19, 0x7d2b,
+ 0x80a2, 0x8102, 0x81f3, 0x8996, 0x8a5e, 0x8a69, 0x8a66, 0x8a8c,
+ 0x8aee, 0x8cc7, 0x8cdc, 0x96cc, 0x98fc, 0x6b6f, 0x4e8b, 0x4f3c,
+ 0x4f8d, 0x5150, 0x5b57, 0x5bfa, 0x6148, 0x6301, 0x6642, 0x6b21,
+ 0x6ecb, 0x6cbb, 0x723e, 0x74bd, 0x75d4, 0x78c1, 0x793a, 0x800c,
+ 0x8033, 0x81ea, 0x8494, 0x8f9e, 0x6c50, 0x9e7f, 0x5f0f, 0x8b58,
+ 0x9d2b, 0x7afa, 0x8ef8, 0x5b8d, 0x96eb, 0x4e03, 0x53f1, 0x57f7,
+ 0x5931, 0x5ac9, 0x5ba4, 0x6089, 0x6e7f, 0x6f06, 0x75be, 0x8cea,
+ 0x5b9f, 0x8500, 0x7be0, 0x5072, 0x67f4, 0x829d, 0x5c61, 0x854a,
+ 0x7e1e, 0x820e, 0x5199, 0x5c04, 0x6368, 0x8d66, 0x659c, 0x716e,
+ 0x793e, 0x7d17, 0x8005, 0x8b1d, 0x8eca, 0x906e, 0x86c7, 0x90aa,
+ 0x501f, 0x52fa, 0x5c3a, 0x6753, 0x707c, 0x7235, 0x914c, 0x91c8,
+ 0x932b, 0x82e5, 0x5bc2, 0x5f31, 0x60f9, 0x4e3b, 0x53d6, 0x5b88,
+ 0x624b, 0x6731, 0x6b8a, 0x72e9, 0x73e0, 0x7a2e, 0x816b, 0x8da3,
+ 0x9152, 0x9996, 0x5112, 0x53d7, 0x546a, 0x5bff, 0x6388, 0x6a39,
+ 0x7dac, 0x9700, 0x56da, 0x53ce, 0x5468, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _8f[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b97, 0x5c31, 0x5dde, 0x4fee, 0x6101, 0x62fe, 0x6d32, 0x79c0,
+ 0x79cb, 0x7d42, 0x7e4d, 0x7fd2, 0x81ed, 0x821f, 0x8490, 0x8846,
+ 0x8972, 0x8b90, 0x8e74, 0x8f2f, 0x9031, 0x914b, 0x916c, 0x96c6,
+ 0x919c, 0x4ec0, 0x4f4f, 0x5145, 0x5341, 0x5f93, 0x620e, 0x67d4,
+ 0x6c41, 0x6e0b, 0x7363, 0x7e26, 0x91cd, 0x9283, 0x53d4, 0x5919,
+ 0x5bbf, 0x6dd1, 0x795d, 0x7e2e, 0x7c9b, 0x587e, 0x719f, 0x51fa,
+ 0x8853, 0x8ff0, 0x4fca, 0x5cfb, 0x6625, 0x77ac, 0x7ae3, 0x821c,
+ 0x99ff, 0x51c6, 0x5faa, 0x65ec, 0x696f, 0x6b89, 0x6df3, 0x0000,
+ 0x6e96, 0x6f64, 0x76fe, 0x7d14, 0x5de1, 0x9075, 0x9187, 0x9806,
+ 0x51e6, 0x521d, 0x6240, 0x6691, 0x66d9, 0x6e1a, 0x5eb6, 0x7dd2,
+ 0x7f72, 0x66f8, 0x85af, 0x85f7, 0x8af8, 0x52a9, 0x53d9, 0x5973,
+ 0x5e8f, 0x5f90, 0x6055, 0x92e4, 0x9664, 0x50b7, 0x511f, 0x52dd,
+ 0x5320, 0x5347, 0x53ec, 0x54e8, 0x5546, 0x5531, 0x5617, 0x5968,
+ 0x59be, 0x5a3c, 0x5bb5, 0x5c06, 0x5c0f, 0x5c11, 0x5c1a, 0x5e84,
+ 0x5e8a, 0x5ee0, 0x5f70, 0x627f, 0x6284, 0x62db, 0x638c, 0x6377,
+ 0x6607, 0x660c, 0x662d, 0x6676, 0x677e, 0x68a2, 0x6a1f, 0x6a35,
+ 0x6cbc, 0x6d88, 0x6e09, 0x6e58, 0x713c, 0x7126, 0x7167, 0x75c7,
+ 0x7701, 0x785d, 0x7901, 0x7965, 0x79f0, 0x7ae0, 0x7b11, 0x7ca7,
+ 0x7d39, 0x8096, 0x83d6, 0x848b, 0x8549, 0x885d, 0x88f3, 0x8a1f,
+ 0x8a3c, 0x8a54, 0x8a73, 0x8c61, 0x8cde, 0x91a4, 0x9266, 0x937e,
+ 0x9418, 0x969c, 0x9798, 0x4e0a, 0x4e08, 0x4e1e, 0x4e57, 0x5197,
+ 0x5270, 0x57ce, 0x5834, 0x58cc, 0x5b22, 0x5e38, 0x60c5, 0x64fe,
+ 0x6761, 0x6756, 0x6d44, 0x72b6, 0x7573, 0x7a63, 0x84b8, 0x8b72,
+ 0x91b8, 0x9320, 0x5631, 0x57f4, 0x98fe, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _90[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x62ed, 0x690d, 0x6b96, 0x71ed, 0x7e54, 0x8077, 0x8272, 0x89e6,
+ 0x98df, 0x8755, 0x8fb1, 0x5c3b, 0x4f38, 0x4fe1, 0x4fb5, 0x5507,
+ 0x5a20, 0x5bdd, 0x5be9, 0x5fc3, 0x614e, 0x632f, 0x65b0, 0x664b,
+ 0x68ee, 0x699b, 0x6d78, 0x6df1, 0x7533, 0x75b9, 0x771f, 0x795e,
+ 0x79e6, 0x7d33, 0x81e3, 0x82af, 0x85aa, 0x89aa, 0x8a3a, 0x8eab,
+ 0x8f9b, 0x9032, 0x91dd, 0x9707, 0x4eba, 0x4ec1, 0x5203, 0x5875,
+ 0x58ec, 0x5c0b, 0x751a, 0x5c3d, 0x814e, 0x8a0a, 0x8fc5, 0x9663,
+ 0x976d, 0x7b25, 0x8acf, 0x9808, 0x9162, 0x56f3, 0x53a8, 0x0000,
+ 0x9017, 0x5439, 0x5782, 0x5e25, 0x63a8, 0x6c34, 0x708a, 0x7761,
+ 0x7c8b, 0x7fe0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968f,
+ 0x745e, 0x9ac4, 0x5d07, 0x5d69, 0x6570, 0x67a2, 0x8da8, 0x96db,
+ 0x636e, 0x6749, 0x6919, 0x83c5, 0x9817, 0x96c0, 0x88fe, 0x6f84,
+ 0x647a, 0x5bf8, 0x4e16, 0x702c, 0x755d, 0x662f, 0x51c4, 0x5236,
+ 0x52e2, 0x59d3, 0x5f81, 0x6027, 0x6210, 0x653f, 0x6574, 0x661f,
+ 0x6674, 0x68f2, 0x6816, 0x6b63, 0x6e05, 0x7272, 0x751f, 0x76db,
+ 0x7cbe, 0x8056, 0x58f0, 0x88fd, 0x897f, 0x8aa0, 0x8a93, 0x8acb,
+ 0x901d, 0x9192, 0x9752, 0x9759, 0x6589, 0x7a0e, 0x8106, 0x96bb,
+ 0x5e2d, 0x60dc, 0x621a, 0x65a5, 0x6614, 0x6790, 0x77f3, 0x7a4d,
+ 0x7c4d, 0x7e3e, 0x810a, 0x8cac, 0x8d64, 0x8de1, 0x8e5f, 0x78a9,
+ 0x5207, 0x62d9, 0x63a5, 0x6442, 0x6298, 0x8a2d, 0x7a83, 0x7bc0,
+ 0x8aac, 0x96ea, 0x7d76, 0x820c, 0x8749, 0x4ed9, 0x5148, 0x5343,
+ 0x5360, 0x5ba3, 0x5c02, 0x5c16, 0x5ddd, 0x6226, 0x6247, 0x64b0,
+ 0x6813, 0x6834, 0x6cc9, 0x6d45, 0x6d17, 0x67d3, 0x6f5c, 0x714e,
+ 0x717d, 0x65cb, 0x7a7f, 0x7bad, 0x7dda, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _91[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7e4a, 0x7fa8, 0x817a, 0x821b, 0x8239, 0x85a6, 0x8a6e, 0x8cce,
+ 0x8df5, 0x9078, 0x9077, 0x92ad, 0x9291, 0x9583, 0x9bae, 0x524d,
+ 0x5584, 0x6f38, 0x7136, 0x5168, 0x7985, 0x7e55, 0x81b3, 0x7cce,
+ 0x564c, 0x5851, 0x5ca8, 0x63aa, 0x66fe, 0x66fd, 0x695a, 0x72d9,
+ 0x758f, 0x758e, 0x790e, 0x7956, 0x79df, 0x7c97, 0x7d20, 0x7d44,
+ 0x8607, 0x8a34, 0x963b, 0x9061, 0x9f20, 0x50e7, 0x5275, 0x53cc,
+ 0x53e2, 0x5009, 0x55aa, 0x58ee, 0x594f, 0x723d, 0x5b8b, 0x5c64,
+ 0x531d, 0x60e3, 0x60f3, 0x635c, 0x6383, 0x633f, 0x63bb, 0x0000,
+ 0x64cd, 0x65e9, 0x66f9, 0x5de3, 0x69cd, 0x69fd, 0x6f15, 0x71e5,
+ 0x4e89, 0x75e9, 0x76f8, 0x7a93, 0x7cdf, 0x7dcf, 0x7d9c, 0x8061,
+ 0x8349, 0x8358, 0x846c, 0x84bc, 0x85fb, 0x88c5, 0x8d70, 0x9001,
+ 0x906d, 0x9397, 0x971c, 0x9a12, 0x50cf, 0x5897, 0x618e, 0x81d3,
+ 0x8535, 0x8d08, 0x9020, 0x4fc3, 0x5074, 0x5247, 0x5373, 0x606f,
+ 0x6349, 0x675f, 0x6e2c, 0x8db3, 0x901f, 0x4fd7, 0x5c5e, 0x8cca,
+ 0x65cf, 0x7d9a, 0x5352, 0x8896, 0x5176, 0x63c3, 0x5b58, 0x5b6b,
+ 0x5c0a, 0x640d, 0x6751, 0x905c, 0x4ed6, 0x591a, 0x592a, 0x6c70,
+ 0x8a51, 0x553e, 0x5815, 0x59a5, 0x60f0, 0x6253, 0x67c1, 0x8235,
+ 0x6955, 0x9640, 0x99c4, 0x9a28, 0x4f53, 0x5806, 0x5bfe, 0x8010,
+ 0x5cb1, 0x5e2f, 0x5f85, 0x6020, 0x614b, 0x6234, 0x66ff, 0x6cf0,
+ 0x6ede, 0x80ce, 0x817f, 0x82d4, 0x888b, 0x8cb8, 0x9000, 0x902e,
+ 0x968a, 0x9edb, 0x9bdb, 0x4ee3, 0x53f0, 0x5927, 0x7b2c, 0x918d,
+ 0x984c, 0x9df9, 0x6edd, 0x7027, 0x5353, 0x5544, 0x5b85, 0x6258,
+ 0x629e, 0x62d3, 0x6ca2, 0x6fef, 0x7422, 0x8a17, 0x9438, 0x6fc1,
+ 0x8afe, 0x8338, 0x51e7, 0x86f8, 0x53ea, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _92[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x53e9, 0x4f46, 0x9054, 0x8fb0, 0x596a, 0x8131, 0x5dfd, 0x7aea,
+ 0x8fbf, 0x68da, 0x8c37, 0x72f8, 0x9c48, 0x6a3d, 0x8ab0, 0x4e39,
+ 0x5358, 0x5606, 0x5766, 0x62c5, 0x63a2, 0x65e6, 0x6b4e, 0x6de1,
+ 0x6e5b, 0x70ad, 0x77ed, 0x7aef, 0x7baa, 0x7dbb, 0x803d, 0x80c6,
+ 0x86cb, 0x8a95, 0x935b, 0x56e3, 0x58c7, 0x5f3e, 0x65ad, 0x6696,
+ 0x6a80, 0x6bb5, 0x7537, 0x8ac7, 0x5024, 0x77e5, 0x5730, 0x5f1b,
+ 0x6065, 0x667a, 0x6c60, 0x75f4, 0x7a1a, 0x7f6e, 0x81f4, 0x8718,
+ 0x9045, 0x99b3, 0x7bc9, 0x755c, 0x7af9, 0x7b51, 0x84c4, 0x0000,
+ 0x9010, 0x79e9, 0x7a92, 0x8336, 0x5ae1, 0x7740, 0x4e2d, 0x4ef2,
+ 0x5b99, 0x5fe0, 0x62bd, 0x663c, 0x67f1, 0x6ce8, 0x866b, 0x8877,
+ 0x8a3b, 0x914e, 0x92f3, 0x99d0, 0x6a17, 0x7026, 0x732a, 0x82e7,
+ 0x8457, 0x8caf, 0x4e01, 0x5146, 0x51cb, 0x558b, 0x5bf5, 0x5e16,
+ 0x5e33, 0x5e81, 0x5f14, 0x5f35, 0x5f6b, 0x5fb4, 0x61f2, 0x6311,
+ 0x66a2, 0x671d, 0x6f6e, 0x7252, 0x753a, 0x773a, 0x8074, 0x8139,
+ 0x8178, 0x8776, 0x8abf, 0x8adc, 0x8d85, 0x8df3, 0x929a, 0x9577,
+ 0x9802, 0x9ce5, 0x52c5, 0x6357, 0x76f4, 0x6715, 0x6c88, 0x73cd,
+ 0x8cc3, 0x93ae, 0x9673, 0x6d25, 0x589c, 0x690e, 0x69cc, 0x8ffd,
+ 0x939a, 0x75db, 0x901a, 0x585a, 0x6802, 0x63b4, 0x69fb, 0x4f43,
+ 0x6f2c, 0x67d8, 0x8fbb, 0x8526, 0x7db4, 0x9354, 0x693f, 0x6f70,
+ 0x576a, 0x58f7, 0x5b2c, 0x7d2c, 0x722a, 0x540a, 0x91e3, 0x9db4,
+ 0x4ead, 0x4f4e, 0x505c, 0x5075, 0x5243, 0x8c9e, 0x5448, 0x5824,
+ 0x5b9a, 0x5e1d, 0x5e95, 0x5ead, 0x5ef7, 0x5f1f, 0x608c, 0x62b5,
+ 0x633a, 0x63d0, 0x68af, 0x6c40, 0x7887, 0x798e, 0x7a0b, 0x7de0,
+ 0x8247, 0x8a02, 0x8ae6, 0x8e44, 0x9013, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _93[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x90b8, 0x912d, 0x91d8, 0x9f0e, 0x6ce5, 0x6458, 0x64e2, 0x6575,
+ 0x6ef4, 0x7684, 0x7b1b, 0x9069, 0x93d1, 0x6eba, 0x54f2, 0x5fb9,
+ 0x64a4, 0x8f4d, 0x8fed, 0x9244, 0x5178, 0x586b, 0x5929, 0x5c55,
+ 0x5e97, 0x6dfb, 0x7e8f, 0x751c, 0x8cbc, 0x8ee2, 0x985b, 0x70b9,
+ 0x4f1d, 0x6bbf, 0x6fb1, 0x7530, 0x96fb, 0x514e, 0x5410, 0x5835,
+ 0x5857, 0x59ac, 0x5c60, 0x5f92, 0x6597, 0x675c, 0x6e21, 0x767b,
+ 0x83df, 0x8ced, 0x9014, 0x90fd, 0x934d, 0x7825, 0x783a, 0x52aa,
+ 0x5ea6, 0x571f, 0x5974, 0x6012, 0x5012, 0x515a, 0x51ac, 0x0000,
+ 0x51cd, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5b95, 0x5cf6,
+ 0x5d8b, 0x60bc, 0x6295, 0x642d, 0x6771, 0x6843, 0x68bc, 0x68df,
+ 0x76d7, 0x6dd8, 0x6e6f, 0x6d9b, 0x706f, 0x71c8, 0x5f53, 0x75d8,
+ 0x7977, 0x7b49, 0x7b54, 0x7b52, 0x7cd6, 0x7d71, 0x5230, 0x8463,
+ 0x8569, 0x85e4, 0x8a0e, 0x8b04, 0x8c46, 0x8e0f, 0x9003, 0x900f,
+ 0x9419, 0x9676, 0x982d, 0x9a30, 0x95d8, 0x50cd, 0x52d5, 0x540c,
+ 0x5802, 0x5c0e, 0x61a7, 0x649e, 0x6d1e, 0x77b3, 0x7ae5, 0x80f4,
+ 0x8404, 0x9053, 0x9285, 0x5ce0, 0x9d07, 0x533f, 0x5f97, 0x5fb3,
+ 0x6d9c, 0x7279, 0x7763, 0x79bf, 0x7be4, 0x6bd2, 0x72ec, 0x8aad,
+ 0x6803, 0x6a61, 0x51f8, 0x7a81, 0x6934, 0x5c4a, 0x9cf6, 0x82eb,
+ 0x5bc5, 0x9149, 0x701e, 0x5678, 0x5c6f, 0x60c7, 0x6566, 0x6c8c,
+ 0x8c5a, 0x9041, 0x9813, 0x5451, 0x66c7, 0x920d, 0x5948, 0x90a3,
+ 0x5185, 0x4e4d, 0x51ea, 0x8599, 0x8b0e, 0x7058, 0x637a, 0x934b,
+ 0x6962, 0x99b4, 0x7e04, 0x7577, 0x5357, 0x6960, 0x8edf, 0x96e3,
+ 0x6c5d, 0x4e8c, 0x5c3c, 0x5f10, 0x8fe9, 0x5302, 0x8cd1, 0x8089,
+ 0x8679, 0x5eff, 0x65e5, 0x4e73, 0x5165, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _94[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5982, 0x5c3f, 0x97ee, 0x4efb, 0x598a, 0x5fcd, 0x8a8d, 0x6fe1,
+ 0x79b0, 0x7962, 0x5be7, 0x8471, 0x732b, 0x71b1, 0x5e74, 0x5ff5,
+ 0x637b, 0x649a, 0x71c3, 0x7c98, 0x4e43, 0x5efc, 0x4e4b, 0x57dc,
+ 0x56a2, 0x60a9, 0x6fc3, 0x7d0d, 0x80fd, 0x8133, 0x81bf, 0x8fb2,
+ 0x8997, 0x86a4, 0x5df4, 0x628a, 0x64ad, 0x8987, 0x6777, 0x6ce2,
+ 0x6d3e, 0x7436, 0x7834, 0x5a46, 0x7f75, 0x82ad, 0x99ac, 0x4ff3,
+ 0x5ec3, 0x62dd, 0x6392, 0x6557, 0x676f, 0x76c3, 0x724c, 0x80cc,
+ 0x80ba, 0x8f29, 0x914d, 0x500d, 0x57f9, 0x5a92, 0x6885, 0x0000,
+ 0x6973, 0x7164, 0x72fd, 0x8cb7, 0x58f2, 0x8ce0, 0x966a, 0x9019,
+ 0x877f, 0x79e4, 0x77e7, 0x8429, 0x4f2f, 0x5265, 0x535a, 0x62cd,
+ 0x67cf, 0x6cca, 0x767d, 0x7b94, 0x7c95, 0x8236, 0x8584, 0x8feb,
+ 0x66dd, 0x6f20, 0x7206, 0x7e1b, 0x83ab, 0x99c1, 0x9ea6, 0x51fd,
+ 0x7bb1, 0x7872, 0x7bb8, 0x8087, 0x7b48, 0x6ae8, 0x5e61, 0x808c,
+ 0x7551, 0x7560, 0x516b, 0x9262, 0x6e8c, 0x767a, 0x9197, 0x9aea,
+ 0x4f10, 0x7f70, 0x629c, 0x7b4f, 0x95a5, 0x9ce9, 0x567a, 0x5859,
+ 0x86e4, 0x96bc, 0x4f34, 0x5224, 0x534a, 0x53cd, 0x53db, 0x5e06,
+ 0x642c, 0x6591, 0x677f, 0x6c3e, 0x6c4e, 0x7248, 0x72af, 0x73ed,
+ 0x7554, 0x7e41, 0x822c, 0x85e9, 0x8ca9, 0x7bc4, 0x91c6, 0x7169,
+ 0x9812, 0x98ef, 0x633d, 0x6669, 0x756a, 0x76e4, 0x78d0, 0x8543,
+ 0x86ee, 0x532a, 0x5351, 0x5426, 0x5983, 0x5e87, 0x5f7c, 0x60b2,
+ 0x6249, 0x6279, 0x62ab, 0x6590, 0x6bd4, 0x6ccc, 0x75b2, 0x76ae,
+ 0x7891, 0x79d8, 0x7dcb, 0x7f77, 0x80a5, 0x88ab, 0x8ab9, 0x8cbb,
+ 0x907f, 0x975e, 0x98db, 0x6a0b, 0x7c38, 0x5099, 0x5c3e, 0x5fae,
+ 0x6787, 0x6bd8, 0x7435, 0x7709, 0x7f8e, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _95[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9f3b, 0x67ca, 0x7a17, 0x5339, 0x758b, 0x9aed, 0x5f66, 0x819d,
+ 0x83f1, 0x8098, 0x5f3c, 0x5fc5, 0x7562, 0x7b46, 0x903c, 0x6867,
+ 0x59eb, 0x5a9b, 0x7d10, 0x767e, 0x8b2c, 0x4ff5, 0x5f6a, 0x6a19,
+ 0x6c37, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8a55, 0x8c79, 0x5edf,
+ 0x63cf, 0x75c5, 0x79d2, 0x82d7, 0x9328, 0x92f2, 0x849c, 0x86ed,
+ 0x9c2d, 0x54c1, 0x5f6c, 0x658c, 0x6d5c, 0x7015, 0x8ca7, 0x8cd3,
+ 0x983b, 0x654f, 0x74f6, 0x4e0d, 0x4ed8, 0x57e0, 0x592b, 0x5a66,
+ 0x5bcc, 0x51a8, 0x5e03, 0x5e9c, 0x6016, 0x6276, 0x6577, 0x0000,
+ 0x65a7, 0x666e, 0x6d6e, 0x7236, 0x7b26, 0x8150, 0x819a, 0x8299,
+ 0x8b5c, 0x8ca0, 0x8ce6, 0x8d74, 0x961c, 0x9644, 0x4fae, 0x64ab,
+ 0x6b66, 0x821e, 0x8461, 0x856a, 0x90e8, 0x5c01, 0x6953, 0x98a8,
+ 0x847a, 0x8557, 0x4f0f, 0x526f, 0x5fa9, 0x5e45, 0x670d, 0x798f,
+ 0x8179, 0x8907, 0x8986, 0x6df5, 0x5f17, 0x6255, 0x6cb8, 0x4ecf,
+ 0x7269, 0x9b92, 0x5206, 0x543b, 0x5674, 0x58b3, 0x61a4, 0x626e,
+ 0x711a, 0x596e, 0x7c89, 0x7cde, 0x7d1b, 0x96f0, 0x6587, 0x805e,
+ 0x4e19, 0x4f75, 0x5175, 0x5840, 0x5e63, 0x5e73, 0x5f0a, 0x67c4,
+ 0x4e26, 0x853d, 0x9589, 0x965b, 0x7c73, 0x9801, 0x50fb, 0x58c1,
+ 0x7656, 0x78a7, 0x5225, 0x77a5, 0x8511, 0x7b86, 0x504f, 0x5909,
+ 0x7247, 0x7bc7, 0x7de8, 0x8fba, 0x8fd4, 0x904d, 0x4fbf, 0x52c9,
+ 0x5a29, 0x5f01, 0x97ad, 0x4fdd, 0x8217, 0x92ea, 0x5703, 0x6355,
+ 0x6b69, 0x752b, 0x88dc, 0x8f14, 0x7a42, 0x52df, 0x5893, 0x6155,
+ 0x620a, 0x66ae, 0x6bcd, 0x7c3f, 0x83e9, 0x5023, 0x4ff8, 0x5305,
+ 0x5446, 0x5831, 0x5949, 0x5b9d, 0x5cf0, 0x5cef, 0x5d29, 0x5e96,
+ 0x62b1, 0x6367, 0x653e, 0x65b9, 0x670b, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _96[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6cd5, 0x6ce1, 0x70f9, 0x7832, 0x7e2b, 0x80de, 0x82b3, 0x840c,
+ 0x84ec, 0x8702, 0x8912, 0x8a2a, 0x8c4a, 0x90a6, 0x92d2, 0x98fd,
+ 0x9cf3, 0x9d6c, 0x4e4f, 0x4ea1, 0x508d, 0x5256, 0x574a, 0x59a8,
+ 0x5e3d, 0x5fd8, 0x5fd9, 0x623f, 0x66b4, 0x671b, 0x67d0, 0x68d2,
+ 0x5192, 0x7d21, 0x80aa, 0x81a8, 0x8b00, 0x8c8c, 0x8cbf, 0x927e,
+ 0x9632, 0x5420, 0x982c, 0x5317, 0x50d5, 0x535c, 0x58a8, 0x64b2,
+ 0x6734, 0x7267, 0x7766, 0x7a46, 0x91e6, 0x52c3, 0x6ca1, 0x6b86,
+ 0x5800, 0x5e4c, 0x5954, 0x672c, 0x7ffb, 0x51e1, 0x76c6, 0x0000,
+ 0x6469, 0x78e8, 0x9b54, 0x9ebb, 0x57cb, 0x59b9, 0x6627, 0x679a,
+ 0x6bce, 0x54e9, 0x69d9, 0x5e55, 0x819c, 0x6795, 0x9baa, 0x67fe,
+ 0x9c52, 0x685d, 0x4ea6, 0x4fe3, 0x53c8, 0x62b9, 0x672b, 0x6cab,
+ 0x8fc4, 0x4fad, 0x7e6d, 0x9ebf, 0x4e07, 0x6162, 0x6e80, 0x6f2b,
+ 0x8513, 0x5473, 0x672a, 0x9b45, 0x5df3, 0x7b95, 0x5cac, 0x5bc6,
+ 0x871c, 0x6e4a, 0x84d1, 0x7a14, 0x8108, 0x5999, 0x7c8d, 0x6c11,
+ 0x7720, 0x52d9, 0x5922, 0x7121, 0x725f, 0x77db, 0x9727, 0x9d61,
+ 0x690b, 0x5a7f, 0x5a18, 0x51a5, 0x540d, 0x547d, 0x660e, 0x76df,
+ 0x8ff7, 0x9298, 0x9cf4, 0x59ea, 0x725d, 0x6ec5, 0x514d, 0x68c9,
+ 0x7dbf, 0x7dec, 0x9762, 0x9eba, 0x6478, 0x6a21, 0x8302, 0x5984,
+ 0x5b5f, 0x6bdb, 0x731b, 0x76f2, 0x7db2, 0x8017, 0x8499, 0x5132,
+ 0x6728, 0x9ed9, 0x76ee, 0x6762, 0x52ff, 0x9905, 0x5c24, 0x623b,
+ 0x7c7e, 0x8cb0, 0x554f, 0x60b6, 0x7d0b, 0x9580, 0x5301, 0x4e5f,
+ 0x51b6, 0x591c, 0x723a, 0x8036, 0x91ce, 0x5f25, 0x77e2, 0x5384,
+ 0x5f79, 0x7d04, 0x85ac, 0x8a33, 0x8e8d, 0x9756, 0x67f3, 0x85ae,
+ 0x9453, 0x6109, 0x6108, 0x6cb9, 0x7652, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _97[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x8aed, 0x8f38, 0x552f, 0x4f51, 0x512a, 0x52c7, 0x53cb, 0x5ba5,
+ 0x5e7d, 0x60a0, 0x6182, 0x63d6, 0x6709, 0x67da, 0x6e67, 0x6d8c,
+ 0x7336, 0x7337, 0x7531, 0x7950, 0x88d5, 0x8a98, 0x904a, 0x9091,
+ 0x90f5, 0x96c4, 0x878d, 0x5915, 0x4e88, 0x4f59, 0x4e0e, 0x8a89,
+ 0x8f3f, 0x9810, 0x50ad, 0x5e7c, 0x5996, 0x5bb9, 0x5eb8, 0x63da,
+ 0x63fa, 0x64c1, 0x66dc, 0x694a, 0x69d8, 0x6d0b, 0x6eb6, 0x7194,
+ 0x7528, 0x7aaf, 0x7f8a, 0x8000, 0x8449, 0x84c9, 0x8981, 0x8b21,
+ 0x8e0a, 0x9065, 0x967d, 0x990a, 0x617e, 0x6291, 0x6b32, 0x0000,
+ 0x6c83, 0x6d74, 0x7fcc, 0x7ffc, 0x6dc0, 0x7f85, 0x87ba, 0x88f8,
+ 0x6765, 0x83b1, 0x983c, 0x96f7, 0x6d1b, 0x7d61, 0x843d, 0x916a,
+ 0x4e71, 0x5375, 0x5d50, 0x6b04, 0x6feb, 0x85cd, 0x862d, 0x89a7,
+ 0x5229, 0x540f, 0x5c65, 0x674e, 0x68a8, 0x7406, 0x7483, 0x75e2,
+ 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x9678, 0x5f8b, 0x7387, 0x7acb,
+ 0x844e, 0x63a0, 0x7565, 0x5289, 0x6d41, 0x6e9c, 0x7409, 0x7559,
+ 0x786b, 0x7c92, 0x9686, 0x7adc, 0x9f8d, 0x4fb6, 0x616e, 0x65c5,
+ 0x865c, 0x4e86, 0x4eae, 0x50da, 0x4e21, 0x51cc, 0x5bee, 0x6599,
+ 0x6881, 0x6dbc, 0x731f, 0x7642, 0x77ad, 0x7a1c, 0x7ce7, 0x826f,
+ 0x8ad2, 0x907c, 0x91cf, 0x9675, 0x9818, 0x529b, 0x7dd1, 0x502b,
+ 0x5398, 0x6797, 0x6dcb, 0x71d0, 0x7433, 0x81e8, 0x8f2a, 0x96a3,
+ 0x9c57, 0x9e9f, 0x7460, 0x5841, 0x6d99, 0x7d2f, 0x985e, 0x4ee4,
+ 0x4f36, 0x4f8b, 0x51b7, 0x52b1, 0x5dba, 0x601c, 0x73b2, 0x793c,
+ 0x82d3, 0x9234, 0x96b7, 0x96f6, 0x970a, 0x9e97, 0x9f62, 0x66a6,
+ 0x6b74, 0x5217, 0x52a3, 0x70c8, 0x88c2, 0x5ec9, 0x604b, 0x6190,
+ 0x6f23, 0x7149, 0x7c3e, 0x7df4, 0x806f, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _98[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x84ee, 0x9023, 0x932c, 0x5442, 0x9b6f, 0x6ad3, 0x7089, 0x8cc2,
+ 0x8def, 0x9732, 0x52b4, 0x5a41, 0x5eca, 0x5f04, 0x6717, 0x697c,
+ 0x6994, 0x6d6a, 0x6f0f, 0x7262, 0x72fc, 0x7bed, 0x8001, 0x807e,
+ 0x874b, 0x90ce, 0x516d, 0x9e93, 0x7984, 0x808b, 0x9332, 0x8ad6,
+ 0x502d, 0x548c, 0x8a71, 0x6b6a, 0x8cc4, 0x8107, 0x60d1, 0x67a0,
+ 0x9df2, 0x4e99, 0x4e98, 0x9c10, 0x8a6b, 0x85c1, 0x8568, 0x6900,
+ 0x6e7e, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f0c,
+ 0x4e10, 0x4e15, 0x4e2a, 0x4e31, 0x4e36, 0x4e3c, 0x4e3f, 0x4e42,
+ 0x4e56, 0x4e58, 0x4e82, 0x4e85, 0x8c6b, 0x4e8a, 0x8212, 0x5f0d,
+ 0x4e8e, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea2, 0x4eb0, 0x4eb3, 0x4eb6,
+ 0x4ece, 0x4ecd, 0x4ec4, 0x4ec6, 0x4ec2, 0x4ed7, 0x4ede, 0x4eed,
+ 0x4edf, 0x4ef7, 0x4f09, 0x4f5a, 0x4f30, 0x4f5b, 0x4f5d, 0x4f57,
+ 0x4f47, 0x4f76, 0x4f88, 0x4f8f, 0x4f98, 0x4f7b, 0x4f69, 0x4f70,
+ 0x4f91, 0x4f6f, 0x4f86, 0x4f96, 0x5118, 0x4fd4, 0x4fdf, 0x4fce,
+ 0x4fd8, 0x4fdb, 0x4fd1, 0x4fda, 0x4fd0, 0x4fe4, 0x4fe5, 0x501a,
+ 0x5028, 0x5014, 0x502a, 0x5025, 0x5005, 0x4f1c, 0x4ff6, 0x5021,
+ 0x5029, 0x502c, 0x4ffe, 0x4fef, 0x5011, 0x5006, 0x5043, 0x5047,
+ 0x6703, 0x5055, 0x5050, 0x5048, 0x505a, 0x5056, 0x506c, 0x5078,
+ 0x5080, 0x509a, 0x5085, 0x50b4, 0x50b2, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _99[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x50c9, 0x50ca, 0x50b3, 0x50c2, 0x50d6, 0x50de, 0x50e5, 0x50ed,
+ 0x50e3, 0x50ee, 0x50f9, 0x50f5, 0x5109, 0x5101, 0x5102, 0x5116,
+ 0x5115, 0x5114, 0x511a, 0x5121, 0x513a, 0x5137, 0x513c, 0x513b,
+ 0x513f, 0x5140, 0x5152, 0x514c, 0x5154, 0x5162, 0x7af8, 0x5169,
+ 0x516a, 0x516e, 0x5180, 0x5182, 0x56d8, 0x518c, 0x5189, 0x518f,
+ 0x5191, 0x5193, 0x5195, 0x5196, 0x51a4, 0x51a6, 0x51a2, 0x51a9,
+ 0x51aa, 0x51ab, 0x51b3, 0x51b1, 0x51b2, 0x51b0, 0x51b5, 0x51bd,
+ 0x51c5, 0x51c9, 0x51db, 0x51e0, 0x8655, 0x51e9, 0x51ed, 0x0000,
+ 0x51f0, 0x51f5, 0x51fe, 0x5204, 0x520b, 0x5214, 0x520e, 0x5227,
+ 0x522a, 0x522e, 0x5233, 0x5239, 0x524f, 0x5244, 0x524b, 0x524c,
+ 0x525e, 0x5254, 0x526a, 0x5274, 0x5269, 0x5273, 0x527f, 0x527d,
+ 0x528d, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8fa8, 0x8fa7,
+ 0x52ac, 0x52ad, 0x52bc, 0x52b5, 0x52c1, 0x52cd, 0x52d7, 0x52de,
+ 0x52e3, 0x52e6, 0x98ed, 0x52e0, 0x52f3, 0x52f5, 0x52f8, 0x52f9,
+ 0x5306, 0x5308, 0x7538, 0x530d, 0x5310, 0x530f, 0x5315, 0x531a,
+ 0x5323, 0x532f, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345,
+ 0x4e17, 0x5349, 0x534d, 0x51d6, 0x535e, 0x5369, 0x536e, 0x5918,
+ 0x537b, 0x5377, 0x5382, 0x5396, 0x53a0, 0x53a6, 0x53a5, 0x53ae,
+ 0x53b0, 0x53b6, 0x53c3, 0x7c12, 0x96d9, 0x53df, 0x66fc, 0x71ee,
+ 0x53ee, 0x53e8, 0x53ed, 0x53fa, 0x5401, 0x543d, 0x5440, 0x542c,
+ 0x542d, 0x543c, 0x542e, 0x5436, 0x5429, 0x541d, 0x544e, 0x548f,
+ 0x5475, 0x548e, 0x545f, 0x5471, 0x5477, 0x5470, 0x5492, 0x547b,
+ 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54c7, 0x54a2, 0x54b8,
+ 0x54a5, 0x54ac, 0x54c4, 0x54c8, 0x54a8, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _9a[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x54ab, 0x54c2, 0x54a4, 0x54be, 0x54bc, 0x54d8, 0x54e5, 0x54e6,
+ 0x550f, 0x5514, 0x54fd, 0x54ee, 0x54ed, 0x54fa, 0x54e2, 0x5539,
+ 0x5540, 0x5563, 0x554c, 0x552e, 0x555c, 0x5545, 0x5556, 0x5557,
+ 0x5538, 0x5533, 0x555d, 0x5599, 0x5580, 0x54af, 0x558a, 0x559f,
+ 0x557b, 0x557e, 0x5598, 0x559e, 0x55ae, 0x557c, 0x5583, 0x55a9,
+ 0x5587, 0x55a8, 0x55da, 0x55c5, 0x55df, 0x55c4, 0x55dc, 0x55e4,
+ 0x55d4, 0x5614, 0x55f7, 0x5616, 0x55fe, 0x55fd, 0x561b, 0x55f9,
+ 0x564e, 0x5650, 0x71df, 0x5634, 0x5636, 0x5632, 0x5638, 0x0000,
+ 0x566b, 0x5664, 0x562f, 0x566c, 0x566a, 0x5686, 0x5680, 0x568a,
+ 0x56a0, 0x5694, 0x568f, 0x56a5, 0x56ae, 0x56b6, 0x56b4, 0x56c2,
+ 0x56bc, 0x56c1, 0x56c3, 0x56c0, 0x56c8, 0x56ce, 0x56d1, 0x56d3,
+ 0x56d7, 0x56ee, 0x56f9, 0x5700, 0x56ff, 0x5704, 0x5709, 0x5708,
+ 0x570b, 0x570d, 0x5713, 0x5718, 0x5716, 0x55c7, 0x571c, 0x5726,
+ 0x5737, 0x5738, 0x574e, 0x573b, 0x5740, 0x574f, 0x5769, 0x57c0,
+ 0x5788, 0x5761, 0x577f, 0x5789, 0x5793, 0x57a0, 0x57b3, 0x57a4,
+ 0x57aa, 0x57b0, 0x57c3, 0x57c6, 0x57d4, 0x57d2, 0x57d3, 0x580a,
+ 0x57d6, 0x57e3, 0x580b, 0x5819, 0x581d, 0x5872, 0x5821, 0x5862,
+ 0x584b, 0x5870, 0x6bc0, 0x5852, 0x583d, 0x5879, 0x5885, 0x58b9,
+ 0x589f, 0x58ab, 0x58ba, 0x58de, 0x58bb, 0x58b8, 0x58ae, 0x58c5,
+ 0x58d3, 0x58d1, 0x58d7, 0x58d9, 0x58d8, 0x58e5, 0x58dc, 0x58e4,
+ 0x58df, 0x58ef, 0x58fa, 0x58f9, 0x58fb, 0x58fc, 0x58fd, 0x5902,
+ 0x590a, 0x5910, 0x591b, 0x68a6, 0x5925, 0x592c, 0x592d, 0x5932,
+ 0x5938, 0x593e, 0x7ad2, 0x5955, 0x5950, 0x594e, 0x595a, 0x5958,
+ 0x5962, 0x5960, 0x5967, 0x596c, 0x5969, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _9b[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5978, 0x5981, 0x599d, 0x4f5e, 0x4fab, 0x59a3, 0x59b2, 0x59c6,
+ 0x59e8, 0x59dc, 0x598d, 0x59d9, 0x59da, 0x5a25, 0x5a1f, 0x5a11,
+ 0x5a1c, 0x5a09, 0x5a1a, 0x5a40, 0x5a6c, 0x5a49, 0x5a35, 0x5a36,
+ 0x5a62, 0x5a6a, 0x5a9a, 0x5abc, 0x5abe, 0x5acb, 0x5ac2, 0x5abd,
+ 0x5ae3, 0x5ad7, 0x5ae6, 0x5ae9, 0x5ad6, 0x5afa, 0x5afb, 0x5b0c,
+ 0x5b0b, 0x5b16, 0x5b32, 0x5ad0, 0x5b2a, 0x5b36, 0x5b3e, 0x5b43,
+ 0x5b45, 0x5b40, 0x5b51, 0x5b55, 0x5b5a, 0x5b5b, 0x5b65, 0x5b69,
+ 0x5b70, 0x5b73, 0x5b75, 0x5b78, 0x6588, 0x5b7a, 0x5b80, 0x0000,
+ 0x5b83, 0x5ba6, 0x5bb8, 0x5bc3, 0x5bc7, 0x5bc9, 0x5bd4, 0x5bd0,
+ 0x5be4, 0x5be6, 0x5be2, 0x5bde, 0x5be5, 0x5beb, 0x5bf0, 0x5bf6,
+ 0x5bf3, 0x5c05, 0x5c07, 0x5c08, 0x5c0d, 0x5c13, 0x5c20, 0x5c22,
+ 0x5c28, 0x5c38, 0x5c39, 0x5c41, 0x5c46, 0x5c4e, 0x5c53, 0x5c50,
+ 0x5c4f, 0x5b71, 0x5c6c, 0x5c6e, 0x4e62, 0x5c76, 0x5c79, 0x5c8c,
+ 0x5c91, 0x5c94, 0x599b, 0x5cab, 0x5cbb, 0x5cb6, 0x5cbc, 0x5cb7,
+ 0x5cc5, 0x5cbe, 0x5cc7, 0x5cd9, 0x5ce9, 0x5cfd, 0x5cfa, 0x5ced,
+ 0x5d8c, 0x5cea, 0x5d0b, 0x5d15, 0x5d17, 0x5d5c, 0x5d1f, 0x5d1b,
+ 0x5d11, 0x5d14, 0x5d22, 0x5d1a, 0x5d19, 0x5d18, 0x5d4c, 0x5d52,
+ 0x5d4e, 0x5d4b, 0x5d6c, 0x5d73, 0x5d76, 0x5d87, 0x5d84, 0x5d82,
+ 0x5da2, 0x5d9d, 0x5dac, 0x5dae, 0x5dbd, 0x5d90, 0x5db7, 0x5dbc,
+ 0x5dc9, 0x5dcd, 0x5dd3, 0x5dd2, 0x5dd6, 0x5ddb, 0x5deb, 0x5df2,
+ 0x5df5, 0x5e0b, 0x5e1a, 0x5e19, 0x5e11, 0x5e1b, 0x5e36, 0x5e37,
+ 0x5e44, 0x5e43, 0x5e40, 0x5e4e, 0x5e57, 0x5e54, 0x5e5f, 0x5e62,
+ 0x5e64, 0x5e47, 0x5e75, 0x5e76, 0x5e7a, 0x9ebc, 0x5e7f, 0x5ea0,
+ 0x5ec1, 0x5ec2, 0x5ec8, 0x5ed0, 0x5ecf, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _9c[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5ed6, 0x5ee3, 0x5edd, 0x5eda, 0x5edb, 0x5ee2, 0x5ee1, 0x5ee8,
+ 0x5ee9, 0x5eec, 0x5ef1, 0x5ef3, 0x5ef0, 0x5ef4, 0x5ef8, 0x5efe,
+ 0x5f03, 0x5f09, 0x5f5d, 0x5f5c, 0x5f0b, 0x5f11, 0x5f16, 0x5f29,
+ 0x5f2d, 0x5f38, 0x5f41, 0x5f48, 0x5f4c, 0x5f4e, 0x5f2f, 0x5f51,
+ 0x5f56, 0x5f57, 0x5f59, 0x5f61, 0x5f6d, 0x5f73, 0x5f77, 0x5f83,
+ 0x5f82, 0x5f7f, 0x5f8a, 0x5f88, 0x5f91, 0x5f87, 0x5f9e, 0x5f99,
+ 0x5f98, 0x5fa0, 0x5fa8, 0x5fad, 0x5fbc, 0x5fd6, 0x5ffb, 0x5fe4,
+ 0x5ff8, 0x5ff1, 0x5fdd, 0x60b3, 0x5fff, 0x6021, 0x6060, 0x0000,
+ 0x6019, 0x6010, 0x6029, 0x600e, 0x6031, 0x601b, 0x6015, 0x602b,
+ 0x6026, 0x600f, 0x603a, 0x605a, 0x6041, 0x606a, 0x6077, 0x605f,
+ 0x604a, 0x6046, 0x604d, 0x6063, 0x6043, 0x6064, 0x6042, 0x606c,
+ 0x606b, 0x6059, 0x6081, 0x608d, 0x60e7, 0x6083, 0x609a, 0x6084,
+ 0x609b, 0x6096, 0x6097, 0x6092, 0x60a7, 0x608b, 0x60e1, 0x60b8,
+ 0x60e0, 0x60d3, 0x60b4, 0x5ff0, 0x60bd, 0x60c6, 0x60b5, 0x60d8,
+ 0x614d, 0x6115, 0x6106, 0x60f6, 0x60f7, 0x6100, 0x60f4, 0x60fa,
+ 0x6103, 0x6121, 0x60fb, 0x60f1, 0x610d, 0x610e, 0x6147, 0x613e,
+ 0x6128, 0x6127, 0x614a, 0x613f, 0x613c, 0x612c, 0x6134, 0x613d,
+ 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615a, 0x616b,
+ 0x6174, 0x616f, 0x6165, 0x6171, 0x615f, 0x615d, 0x6153, 0x6175,
+ 0x6199, 0x6196, 0x6187, 0x61ac, 0x6194, 0x619a, 0x618a, 0x6191,
+ 0x61ab, 0x61ae, 0x61cc, 0x61ca, 0x61c9, 0x61f7, 0x61c8, 0x61c3,
+ 0x61c6, 0x61ba, 0x61cb, 0x7f79, 0x61cd, 0x61e6, 0x61e3, 0x61f6,
+ 0x61fa, 0x61f4, 0x61ff, 0x61fd, 0x61fc, 0x61fe, 0x6200, 0x6208,
+ 0x6209, 0x620d, 0x620c, 0x6214, 0x621b, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _9d[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x621e, 0x6221, 0x622a, 0x622e, 0x6230, 0x6232, 0x6233, 0x6241,
+ 0x624e, 0x625e, 0x6263, 0x625b, 0x6260, 0x6268, 0x627c, 0x6282,
+ 0x6289, 0x627e, 0x6292, 0x6293, 0x6296, 0x62d4, 0x6283, 0x6294,
+ 0x62d7, 0x62d1, 0x62bb, 0x62cf, 0x62ff, 0x62c6, 0x64d4, 0x62c8,
+ 0x62dc, 0x62cc, 0x62ca, 0x62c2, 0x62c7, 0x629b, 0x62c9, 0x630c,
+ 0x62ee, 0x62f1, 0x6327, 0x6302, 0x6308, 0x62ef, 0x62f5, 0x6350,
+ 0x633e, 0x634d, 0x641c, 0x634f, 0x6396, 0x638e, 0x6380, 0x63ab,
+ 0x6376, 0x63a3, 0x638f, 0x6389, 0x639f, 0x63b5, 0x636b, 0x0000,
+ 0x6369, 0x63be, 0x63e9, 0x63c0, 0x63c6, 0x63e3, 0x63c9, 0x63d2,
+ 0x63f6, 0x63c4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436,
+ 0x651d, 0x6417, 0x6428, 0x640f, 0x6467, 0x646f, 0x6476, 0x644e,
+ 0x652a, 0x6495, 0x6493, 0x64a5, 0x64a9, 0x6488, 0x64bc, 0x64da,
+ 0x64d2, 0x64c5, 0x64c7, 0x64bb, 0x64d8, 0x64c2, 0x64f1, 0x64e7,
+ 0x8209, 0x64e0, 0x64e1, 0x62ac, 0x64e3, 0x64ef, 0x652c, 0x64f6,
+ 0x64f4, 0x64f2, 0x64fa, 0x6500, 0x64fd, 0x6518, 0x651c, 0x6505,
+ 0x6524, 0x6523, 0x652b, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538,
+ 0x754b, 0x6548, 0x6556, 0x6555, 0x654d, 0x6558, 0x655e, 0x655d,
+ 0x6572, 0x6578, 0x6582, 0x6583, 0x8b8a, 0x659b, 0x659f, 0x65ab,
+ 0x65b7, 0x65c3, 0x65c6, 0x65c1, 0x65c4, 0x65cc, 0x65d2, 0x65db,
+ 0x65d9, 0x65e0, 0x65e1, 0x65f1, 0x6772, 0x660a, 0x6603, 0x65fb,
+ 0x6773, 0x6635, 0x6636, 0x6634, 0x661c, 0x664f, 0x6644, 0x6649,
+ 0x6641, 0x665e, 0x665d, 0x6664, 0x6667, 0x6668, 0x665f, 0x6662,
+ 0x6670, 0x6683, 0x6688, 0x668e, 0x6689, 0x6684, 0x6698, 0x669d,
+ 0x66c1, 0x66b9, 0x66c9, 0x66be, 0x66bc, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _9e[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x66c4, 0x66b8, 0x66d6, 0x66da, 0x66e0, 0x663f, 0x66e6, 0x66e9,
+ 0x66f0, 0x66f5, 0x66f7, 0x670f, 0x6716, 0x671e, 0x6726, 0x6727,
+ 0x9738, 0x672e, 0x673f, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746,
+ 0x675e, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67a9,
+ 0x677c, 0x676a, 0x678c, 0x678b, 0x67a6, 0x67a1, 0x6785, 0x67b7,
+ 0x67ef, 0x67b4, 0x67ec, 0x67b3, 0x67e9, 0x67b8, 0x67e4, 0x67de,
+ 0x67dd, 0x67e2, 0x67ee, 0x67b9, 0x67ce, 0x67c6, 0x67e7, 0x6a9c,
+ 0x681e, 0x6846, 0x6829, 0x6840, 0x684d, 0x6832, 0x684e, 0x0000,
+ 0x68b3, 0x682b, 0x6859, 0x6863, 0x6877, 0x687f, 0x689f, 0x688f,
+ 0x68ad, 0x6894, 0x689d, 0x689b, 0x6883, 0x6aae, 0x68b9, 0x6874,
+ 0x68b5, 0x68a0, 0x68ba, 0x690f, 0x688d, 0x687e, 0x6901, 0x68ca,
+ 0x6908, 0x68d8, 0x6922, 0x6926, 0x68e1, 0x690c, 0x68cd, 0x68d4,
+ 0x68e7, 0x68d5, 0x6936, 0x6912, 0x6904, 0x68d7, 0x68e3, 0x6925,
+ 0x68f9, 0x68e0, 0x68ef, 0x6928, 0x692a, 0x691a, 0x6923, 0x6921,
+ 0x68c6, 0x6979, 0x6977, 0x695c, 0x6978, 0x696b, 0x6954, 0x697e,
+ 0x696e, 0x6939, 0x6974, 0x693d, 0x6959, 0x6930, 0x6961, 0x695e,
+ 0x695d, 0x6981, 0x696a, 0x69b2, 0x69ae, 0x69d0, 0x69bf, 0x69c1,
+ 0x69d3, 0x69be, 0x69ce, 0x5be8, 0x69ca, 0x69dd, 0x69bb, 0x69c3,
+ 0x69a7, 0x6a2e, 0x6991, 0x69a0, 0x699c, 0x6995, 0x69b4, 0x69de,
+ 0x69e8, 0x6a02, 0x6a1b, 0x69ff, 0x6b0a, 0x69f9, 0x69f2, 0x69e7,
+ 0x6a05, 0x69b1, 0x6a1e, 0x69ed, 0x6a14, 0x69eb, 0x6a0a, 0x6a12,
+ 0x6ac1, 0x6a23, 0x6a13, 0x6a44, 0x6a0c, 0x6a72, 0x6a36, 0x6a78,
+ 0x6a47, 0x6a62, 0x6a59, 0x6a66, 0x6a48, 0x6a38, 0x6a22, 0x6a90,
+ 0x6a8d, 0x6aa0, 0x6a84, 0x6aa2, 0x6aa3, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _9f[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6a97, 0x8617, 0x6abb, 0x6ac3, 0x6ac2, 0x6ab8, 0x6ab3, 0x6aac,
+ 0x6ade, 0x6ad1, 0x6adf, 0x6aaa, 0x6ada, 0x6aea, 0x6afb, 0x6b05,
+ 0x8616, 0x6afa, 0x6b12, 0x6b16, 0x9b31, 0x6b1f, 0x6b38, 0x6b37,
+ 0x76dc, 0x6b39, 0x98ee, 0x6b47, 0x6b43, 0x6b49, 0x6b50, 0x6b59,
+ 0x6b54, 0x6b5b, 0x6b5f, 0x6b61, 0x6b78, 0x6b79, 0x6b7f, 0x6b80,
+ 0x6b84, 0x6b83, 0x6b8d, 0x6b98, 0x6b95, 0x6b9e, 0x6ba4, 0x6baa,
+ 0x6bab, 0x6baf, 0x6bb2, 0x6bb1, 0x6bb3, 0x6bb7, 0x6bbc, 0x6bc6,
+ 0x6bcb, 0x6bd3, 0x6bdf, 0x6bec, 0x6beb, 0x6bf3, 0x6bef, 0x0000,
+ 0x9ebe, 0x6c08, 0x6c13, 0x6c14, 0x6c1b, 0x6c24, 0x6c23, 0x6c5e,
+ 0x6c55, 0x6c62, 0x6c6a, 0x6c82, 0x6c8d, 0x6c9a, 0x6c81, 0x6c9b,
+ 0x6c7e, 0x6c68, 0x6c73, 0x6c92, 0x6c90, 0x6cc4, 0x6cf1, 0x6cd3,
+ 0x6cbd, 0x6cd7, 0x6cc5, 0x6cdd, 0x6cae, 0x6cb1, 0x6cbe, 0x6cba,
+ 0x6cdb, 0x6cef, 0x6cd9, 0x6cea, 0x6d1f, 0x884d, 0x6d36, 0x6d2b,
+ 0x6d3d, 0x6d38, 0x6d19, 0x6d35, 0x6d33, 0x6d12, 0x6d0c, 0x6d63,
+ 0x6d93, 0x6d64, 0x6d5a, 0x6d79, 0x6d59, 0x6d8e, 0x6d95, 0x6fe4,
+ 0x6d85, 0x6df9, 0x6e15, 0x6e0a, 0x6db5, 0x6dc7, 0x6de6, 0x6db8,
+ 0x6dc6, 0x6dec, 0x6dde, 0x6dcc, 0x6de8, 0x6dd2, 0x6dc5, 0x6dfa,
+ 0x6dd9, 0x6de4, 0x6dd5, 0x6dea, 0x6dee, 0x6e2d, 0x6e6e, 0x6e2e,
+ 0x6e19, 0x6e72, 0x6e5f, 0x6e3e, 0x6e23, 0x6e6b, 0x6e2b, 0x6e76,
+ 0x6e4d, 0x6e1f, 0x6e43, 0x6e3a, 0x6e4e, 0x6e24, 0x6eff, 0x6e1d,
+ 0x6e38, 0x6e82, 0x6eaa, 0x6e98, 0x6ec9, 0x6eb7, 0x6ed3, 0x6ebd,
+ 0x6eaf, 0x6ec4, 0x6eb2, 0x6ed4, 0x6ed5, 0x6e8f, 0x6ea5, 0x6ec2,
+ 0x6e9f, 0x6f41, 0x6f11, 0x704c, 0x6eec, 0x6ef8, 0x6efe, 0x6f3f,
+ 0x6ef2, 0x6f31, 0x6eef, 0x6f32, 0x6ecc, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e0[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f3e, 0x6f13, 0x6ef7, 0x6f86, 0x6f7a, 0x6f78, 0x6f81, 0x6f80,
+ 0x6f6f, 0x6f5b, 0x6ff3, 0x6f6d, 0x6f82, 0x6f7c, 0x6f58, 0x6f8e,
+ 0x6f91, 0x6fc2, 0x6f66, 0x6fb3, 0x6fa3, 0x6fa1, 0x6fa4, 0x6fb9,
+ 0x6fc6, 0x6faa, 0x6fdf, 0x6fd5, 0x6fec, 0x6fd4, 0x6fd8, 0x6ff1,
+ 0x6fee, 0x6fdb, 0x7009, 0x700b, 0x6ffa, 0x7011, 0x7001, 0x700f,
+ 0x6ffe, 0x701b, 0x701a, 0x6f74, 0x701d, 0x7018, 0x701f, 0x7030,
+ 0x703e, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70af, 0x70f1,
+ 0x70ac, 0x70b8, 0x70b3, 0x70ae, 0x70df, 0x70cb, 0x70dd, 0x0000,
+ 0x70d9, 0x7109, 0x70fd, 0x711c, 0x7119, 0x7165, 0x7155, 0x7188,
+ 0x7166, 0x7162, 0x714c, 0x7156, 0x716c, 0x718f, 0x71fb, 0x7184,
+ 0x7195, 0x71a8, 0x71ac, 0x71d7, 0x71b9, 0x71be, 0x71d2, 0x71c9,
+ 0x71d4, 0x71ce, 0x71e0, 0x71ec, 0x71e7, 0x71f5, 0x71fc, 0x71f9,
+ 0x71ff, 0x720d, 0x7210, 0x721b, 0x7228, 0x722d, 0x722c, 0x7230,
+ 0x7232, 0x723b, 0x723c, 0x723f, 0x7240, 0x7246, 0x724b, 0x7258,
+ 0x7274, 0x727e, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, 0x72a2,
+ 0x72a7, 0x72b9, 0x72b2, 0x72c3, 0x72c6, 0x72c4, 0x72ce, 0x72d2,
+ 0x72e2, 0x72e0, 0x72e1, 0x72f9, 0x72f7, 0x500f, 0x7317, 0x730a,
+ 0x731c, 0x7316, 0x731d, 0x7334, 0x732f, 0x7329, 0x7325, 0x733e,
+ 0x734e, 0x734f, 0x9ed8, 0x7357, 0x736a, 0x7368, 0x7370, 0x7378,
+ 0x7375, 0x737b, 0x737a, 0x73c8, 0x73b3, 0x73ce, 0x73bb, 0x73c0,
+ 0x73e5, 0x73ee, 0x73de, 0x74a2, 0x7405, 0x746f, 0x7425, 0x73f8,
+ 0x7432, 0x743a, 0x7455, 0x743f, 0x745f, 0x7459, 0x7441, 0x745c,
+ 0x7469, 0x7470, 0x7463, 0x746a, 0x7476, 0x747e, 0x748b, 0x749e,
+ 0x74a7, 0x74ca, 0x74cf, 0x74d4, 0x73f1, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e1[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x74e0, 0x74e3, 0x74e7, 0x74e9, 0x74ee, 0x74f2, 0x74f0, 0x74f1,
+ 0x74f8, 0x74f7, 0x7504, 0x7503, 0x7505, 0x750c, 0x750e, 0x750d,
+ 0x7515, 0x7513, 0x751e, 0x7526, 0x752c, 0x753c, 0x7544, 0x754d,
+ 0x754a, 0x7549, 0x755b, 0x7546, 0x755a, 0x7569, 0x7564, 0x7567,
+ 0x756b, 0x756d, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758a,
+ 0x7589, 0x7582, 0x7594, 0x759a, 0x759d, 0x75a5, 0x75a3, 0x75c2,
+ 0x75b3, 0x75c3, 0x75b5, 0x75bd, 0x75b8, 0x75bc, 0x75b1, 0x75cd,
+ 0x75ca, 0x75d2, 0x75d9, 0x75e3, 0x75de, 0x75fe, 0x75ff, 0x0000,
+ 0x75fc, 0x7601, 0x75f0, 0x75fa, 0x75f2, 0x75f3, 0x760b, 0x760d,
+ 0x7609, 0x761f, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634,
+ 0x7630, 0x763b, 0x7647, 0x7648, 0x7646, 0x765c, 0x7658, 0x7661,
+ 0x7662, 0x7668, 0x7669, 0x766a, 0x7667, 0x766c, 0x7670, 0x7672,
+ 0x7676, 0x7678, 0x767c, 0x7680, 0x7683, 0x7688, 0x768b, 0x768e,
+ 0x7696, 0x7693, 0x7699, 0x769a, 0x76b0, 0x76b4, 0x76b8, 0x76b9,
+ 0x76ba, 0x76c2, 0x76cd, 0x76d6, 0x76d2, 0x76de, 0x76e1, 0x76e5,
+ 0x76e7, 0x76ea, 0x862f, 0x76fb, 0x7708, 0x7707, 0x7704, 0x7729,
+ 0x7724, 0x771e, 0x7725, 0x7726, 0x771b, 0x7737, 0x7738, 0x7747,
+ 0x775a, 0x7768, 0x776b, 0x775b, 0x7765, 0x777f, 0x777e, 0x7779,
+ 0x778e, 0x778b, 0x7791, 0x77a0, 0x779e, 0x77b0, 0x77b6, 0x77b9,
+ 0x77bf, 0x77bc, 0x77bd, 0x77bb, 0x77c7, 0x77cd, 0x77d7, 0x77da,
+ 0x77dc, 0x77e3, 0x77ee, 0x77fc, 0x780c, 0x7812, 0x7926, 0x7820,
+ 0x792a, 0x7845, 0x788e, 0x7874, 0x7886, 0x787c, 0x789a, 0x788c,
+ 0x78a3, 0x78b5, 0x78aa, 0x78af, 0x78d1, 0x78c6, 0x78cb, 0x78d4,
+ 0x78be, 0x78bc, 0x78c5, 0x78ca, 0x78ec, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e2[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x78e7, 0x78da, 0x78fd, 0x78f4, 0x7907, 0x7912, 0x7911, 0x7919,
+ 0x792c, 0x792b, 0x7940, 0x7960, 0x7957, 0x795f, 0x795a, 0x7955,
+ 0x7953, 0x797a, 0x797f, 0x798a, 0x799d, 0x79a7, 0x9f4b, 0x79aa,
+ 0x79ae, 0x79b3, 0x79b9, 0x79ba, 0x79c9, 0x79d5, 0x79e7, 0x79ec,
+ 0x79e1, 0x79e3, 0x7a08, 0x7a0d, 0x7a18, 0x7a19, 0x7a20, 0x7a1f,
+ 0x7980, 0x7a31, 0x7a3b, 0x7a3e, 0x7a37, 0x7a43, 0x7a57, 0x7a49,
+ 0x7a61, 0x7a62, 0x7a69, 0x9f9d, 0x7a70, 0x7a79, 0x7a7d, 0x7a88,
+ 0x7a97, 0x7a95, 0x7a98, 0x7a96, 0x7aa9, 0x7ac8, 0x7ab0, 0x0000,
+ 0x7ab6, 0x7ac5, 0x7ac4, 0x7abf, 0x9083, 0x7ac7, 0x7aca, 0x7acd,
+ 0x7acf, 0x7ad5, 0x7ad3, 0x7ad9, 0x7ada, 0x7add, 0x7ae1, 0x7ae2,
+ 0x7ae6, 0x7aed, 0x7af0, 0x7b02, 0x7b0f, 0x7b0a, 0x7b06, 0x7b33,
+ 0x7b18, 0x7b19, 0x7b1e, 0x7b35, 0x7b28, 0x7b36, 0x7b50, 0x7b7a,
+ 0x7b04, 0x7b4d, 0x7b0b, 0x7b4c, 0x7b45, 0x7b75, 0x7b65, 0x7b74,
+ 0x7b67, 0x7b70, 0x7b71, 0x7b6c, 0x7b6e, 0x7b9d, 0x7b98, 0x7b9f,
+ 0x7b8d, 0x7b9c, 0x7b9a, 0x7b8b, 0x7b92, 0x7b8f, 0x7b5d, 0x7b99,
+ 0x7bcb, 0x7bc1, 0x7bcc, 0x7bcf, 0x7bb4, 0x7bc6, 0x7bdd, 0x7be9,
+ 0x7c11, 0x7c14, 0x7be6, 0x7be5, 0x7c60, 0x7c00, 0x7c07, 0x7c13,
+ 0x7bf3, 0x7bf7, 0x7c17, 0x7c0d, 0x7bf6, 0x7c23, 0x7c27, 0x7c2a,
+ 0x7c1f, 0x7c37, 0x7c2b, 0x7c3d, 0x7c4c, 0x7c43, 0x7c54, 0x7c4f,
+ 0x7c40, 0x7c50, 0x7c58, 0x7c5f, 0x7c64, 0x7c56, 0x7c65, 0x7c6c,
+ 0x7c75, 0x7c83, 0x7c90, 0x7ca4, 0x7cad, 0x7ca2, 0x7cab, 0x7ca1,
+ 0x7ca8, 0x7cb3, 0x7cb2, 0x7cb1, 0x7cae, 0x7cb9, 0x7cbd, 0x7cc0,
+ 0x7cc5, 0x7cc2, 0x7cd8, 0x7cd2, 0x7cdc, 0x7ce2, 0x9b3b, 0x7cef,
+ 0x7cf2, 0x7cf4, 0x7cf6, 0x7cfa, 0x7d06, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e3[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7d02, 0x7d1c, 0x7d15, 0x7d0a, 0x7d45, 0x7d4b, 0x7d2e, 0x7d32,
+ 0x7d3f, 0x7d35, 0x7d46, 0x7d73, 0x7d56, 0x7d4e, 0x7d72, 0x7d68,
+ 0x7d6e, 0x7d4f, 0x7d63, 0x7d93, 0x7d89, 0x7d5b, 0x7d8f, 0x7d7d,
+ 0x7d9b, 0x7dba, 0x7dae, 0x7da3, 0x7db5, 0x7dc7, 0x7dbd, 0x7dab,
+ 0x7e3d, 0x7da2, 0x7daf, 0x7ddc, 0x7db8, 0x7d9f, 0x7db0, 0x7dd8,
+ 0x7ddd, 0x7de4, 0x7dde, 0x7dfb, 0x7df2, 0x7de1, 0x7e05, 0x7e0a,
+ 0x7e23, 0x7e21, 0x7e12, 0x7e31, 0x7e1f, 0x7e09, 0x7e0b, 0x7e22,
+ 0x7e46, 0x7e66, 0x7e3b, 0x7e35, 0x7e39, 0x7e43, 0x7e37, 0x0000,
+ 0x7e32, 0x7e3a, 0x7e67, 0x7e5d, 0x7e56, 0x7e5e, 0x7e59, 0x7e5a,
+ 0x7e79, 0x7e6a, 0x7e69, 0x7e7c, 0x7e7b, 0x7e83, 0x7dd5, 0x7e7d,
+ 0x8fae, 0x7e7f, 0x7e88, 0x7e89, 0x7e8c, 0x7e92, 0x7e90, 0x7e93,
+ 0x7e94, 0x7e96, 0x7e8e, 0x7e9b, 0x7e9c, 0x7f38, 0x7f3a, 0x7f45,
+ 0x7f4c, 0x7f4d, 0x7f4e, 0x7f50, 0x7f51, 0x7f55, 0x7f54, 0x7f58,
+ 0x7f5f, 0x7f60, 0x7f68, 0x7f69, 0x7f67, 0x7f78, 0x7f82, 0x7f86,
+ 0x7f83, 0x7f88, 0x7f87, 0x7f8c, 0x7f94, 0x7f9e, 0x7f9d, 0x7f9a,
+ 0x7fa3, 0x7faf, 0x7fb2, 0x7fb9, 0x7fae, 0x7fb6, 0x7fb8, 0x8b71,
+ 0x7fc5, 0x7fc6, 0x7fca, 0x7fd5, 0x7fd4, 0x7fe1, 0x7fe6, 0x7fe9,
+ 0x7ff3, 0x7ff9, 0x98dc, 0x8006, 0x8004, 0x800b, 0x8012, 0x8018,
+ 0x8019, 0x801c, 0x8021, 0x8028, 0x803f, 0x803b, 0x804a, 0x8046,
+ 0x8052, 0x8058, 0x805a, 0x805f, 0x8062, 0x8068, 0x8073, 0x8072,
+ 0x8070, 0x8076, 0x8079, 0x807d, 0x807f, 0x8084, 0x8086, 0x8085,
+ 0x809b, 0x8093, 0x809a, 0x80ad, 0x5190, 0x80ac, 0x80db, 0x80e5,
+ 0x80d9, 0x80dd, 0x80c4, 0x80da, 0x80d6, 0x8109, 0x80ef, 0x80f1,
+ 0x811b, 0x8129, 0x8123, 0x812f, 0x814b, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e4[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x968b, 0x8146, 0x813e, 0x8153, 0x8151, 0x80fc, 0x8171, 0x816e,
+ 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818a, 0x8180, 0x8182,
+ 0x81a0, 0x8195, 0x81a4, 0x81a3, 0x815f, 0x8193, 0x81a9, 0x81b0,
+ 0x81b5, 0x81be, 0x81b8, 0x81bd, 0x81c0, 0x81c2, 0x81ba, 0x81c9,
+ 0x81cd, 0x81d1, 0x81d9, 0x81d8, 0x81c8, 0x81da, 0x81df, 0x81e0,
+ 0x81e7, 0x81fa, 0x81fb, 0x81fe, 0x8201, 0x8202, 0x8205, 0x8207,
+ 0x820a, 0x820d, 0x8210, 0x8216, 0x8229, 0x822b, 0x8238, 0x8233,
+ 0x8240, 0x8259, 0x8258, 0x825d, 0x825a, 0x825f, 0x8264, 0x0000,
+ 0x8262, 0x8268, 0x826a, 0x826b, 0x822e, 0x8271, 0x8277, 0x8278,
+ 0x827e, 0x828d, 0x8292, 0x82ab, 0x829f, 0x82bb, 0x82ac, 0x82e1,
+ 0x82e3, 0x82df, 0x82d2, 0x82f4, 0x82f3, 0x82fa, 0x8393, 0x8303,
+ 0x82fb, 0x82f9, 0x82de, 0x8306, 0x82dc, 0x8309, 0x82d9, 0x8335,
+ 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345,
+ 0x832f, 0x832b, 0x8317, 0x8318, 0x8385, 0x839a, 0x83aa, 0x839f,
+ 0x83a2, 0x8396, 0x8323, 0x838e, 0x8387, 0x838a, 0x837c, 0x83b5,
+ 0x8373, 0x8375, 0x83a0, 0x8389, 0x83a8, 0x83f4, 0x8413, 0x83eb,
+ 0x83ce, 0x83fd, 0x8403, 0x83d8, 0x840b, 0x83c1, 0x83f7, 0x8407,
+ 0x83e0, 0x83f2, 0x840d, 0x8422, 0x8420, 0x83bd, 0x8438, 0x8506,
+ 0x83fb, 0x846d, 0x842a, 0x843c, 0x855a, 0x8484, 0x8477, 0x846b,
+ 0x84ad, 0x846e, 0x8482, 0x8469, 0x8446, 0x842c, 0x846f, 0x8479,
+ 0x8435, 0x84ca, 0x8462, 0x84b9, 0x84bf, 0x849f, 0x84d9, 0x84cd,
+ 0x84bb, 0x84da, 0x84d0, 0x84c1, 0x84c6, 0x84d6, 0x84a1, 0x8521,
+ 0x84ff, 0x84f4, 0x8517, 0x8518, 0x852c, 0x851f, 0x8515, 0x8514,
+ 0x84fc, 0x8540, 0x8563, 0x8558, 0x8548, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e5[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x8541, 0x8602, 0x854b, 0x8555, 0x8580, 0x85a4, 0x8588, 0x8591,
+ 0x858a, 0x85a8, 0x856d, 0x8594, 0x859b, 0x85ea, 0x8587, 0x859c,
+ 0x8577, 0x857e, 0x8590, 0x85c9, 0x85ba, 0x85cf, 0x85b9, 0x85d0,
+ 0x85d5, 0x85dd, 0x85e5, 0x85dc, 0x85f9, 0x860a, 0x8613, 0x860b,
+ 0x85fe, 0x85fa, 0x8606, 0x8622, 0x861a, 0x8630, 0x863f, 0x864d,
+ 0x4e55, 0x8654, 0x865f, 0x8667, 0x8671, 0x8693, 0x86a3, 0x86a9,
+ 0x86aa, 0x868b, 0x868c, 0x86b6, 0x86af, 0x86c4, 0x86c6, 0x86b0,
+ 0x86c9, 0x8823, 0x86ab, 0x86d4, 0x86de, 0x86e9, 0x86ec, 0x0000,
+ 0x86df, 0x86db, 0x86ef, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703,
+ 0x86fb, 0x8711, 0x8709, 0x870d, 0x86f9, 0x870a, 0x8734, 0x873f,
+ 0x8737, 0x873b, 0x8725, 0x8729, 0x871a, 0x8760, 0x875f, 0x8778,
+ 0x874c, 0x874e, 0x8774, 0x8757, 0x8768, 0x876e, 0x8759, 0x8753,
+ 0x8763, 0x876a, 0x8805, 0x87a2, 0x879f, 0x8782, 0x87af, 0x87cb,
+ 0x87bd, 0x87c0, 0x87d0, 0x96d6, 0x87ab, 0x87c4, 0x87b3, 0x87c7,
+ 0x87c6, 0x87bb, 0x87ef, 0x87f2, 0x87e0, 0x880f, 0x880d, 0x87fe,
+ 0x87f6, 0x87f7, 0x880e, 0x87d2, 0x8811, 0x8816, 0x8815, 0x8822,
+ 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883b, 0x8844, 0x8842,
+ 0x8852, 0x8859, 0x885e, 0x8862, 0x886b, 0x8881, 0x887e, 0x889e,
+ 0x8875, 0x887d, 0x88b5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88ae,
+ 0x8899, 0x88a2, 0x888d, 0x88a4, 0x88b0, 0x88bf, 0x88b1, 0x88c3,
+ 0x88c4, 0x88d4, 0x88d8, 0x88d9, 0x88dd, 0x88f9, 0x8902, 0x88fc,
+ 0x88f4, 0x88e8, 0x88f2, 0x8904, 0x890c, 0x890a, 0x8913, 0x8943,
+ 0x891e, 0x8925, 0x892a, 0x892b, 0x8941, 0x8944, 0x893b, 0x8936,
+ 0x8938, 0x894c, 0x891d, 0x8960, 0x895e, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e6[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x8966, 0x8964, 0x896d, 0x896a, 0x896f, 0x8974, 0x8977, 0x897e,
+ 0x8983, 0x8988, 0x898a, 0x8993, 0x8998, 0x89a1, 0x89a9, 0x89a6,
+ 0x89ac, 0x89af, 0x89b2, 0x89ba, 0x89bd, 0x89bf, 0x89c0, 0x89da,
+ 0x89dc, 0x89dd, 0x89e7, 0x89f4, 0x89f8, 0x8a03, 0x8a16, 0x8a10,
+ 0x8a0c, 0x8a1b, 0x8a1d, 0x8a25, 0x8a36, 0x8a41, 0x8a5b, 0x8a52,
+ 0x8a46, 0x8a48, 0x8a7c, 0x8a6d, 0x8a6c, 0x8a62, 0x8a85, 0x8a82,
+ 0x8a84, 0x8aa8, 0x8aa1, 0x8a91, 0x8aa5, 0x8aa6, 0x8a9a, 0x8aa3,
+ 0x8ac4, 0x8acd, 0x8ac2, 0x8ada, 0x8aeb, 0x8af3, 0x8ae7, 0x0000,
+ 0x8ae4, 0x8af1, 0x8b14, 0x8ae0, 0x8ae2, 0x8af7, 0x8ade, 0x8adb,
+ 0x8b0c, 0x8b07, 0x8b1a, 0x8ae1, 0x8b16, 0x8b10, 0x8b17, 0x8b20,
+ 0x8b33, 0x97ab, 0x8b26, 0x8b2b, 0x8b3e, 0x8b28, 0x8b41, 0x8b4c,
+ 0x8b4f, 0x8b4e, 0x8b49, 0x8b56, 0x8b5b, 0x8b5a, 0x8b6b, 0x8b5f,
+ 0x8b6c, 0x8b6f, 0x8b74, 0x8b7d, 0x8b80, 0x8b8c, 0x8b8e, 0x8b92,
+ 0x8b93, 0x8b96, 0x8b99, 0x8b9a, 0x8c3a, 0x8c41, 0x8c3f, 0x8c48,
+ 0x8c4c, 0x8c4e, 0x8c50, 0x8c55, 0x8c62, 0x8c6c, 0x8c78, 0x8c7a,
+ 0x8c82, 0x8c89, 0x8c85, 0x8c8a, 0x8c8d, 0x8c8e, 0x8c94, 0x8c7c,
+ 0x8c98, 0x621d, 0x8cad, 0x8caa, 0x8cbd, 0x8cb2, 0x8cb3, 0x8cae,
+ 0x8cb6, 0x8cc8, 0x8cc1, 0x8ce4, 0x8ce3, 0x8cda, 0x8cfd, 0x8cfa,
+ 0x8cfb, 0x8d04, 0x8d05, 0x8d0a, 0x8d07, 0x8d0f, 0x8d0d, 0x8d10,
+ 0x9f4e, 0x8d13, 0x8ccd, 0x8d14, 0x8d16, 0x8d67, 0x8d6d, 0x8d71,
+ 0x8d73, 0x8d81, 0x8d99, 0x8dc2, 0x8dbe, 0x8dba, 0x8dcf, 0x8dda,
+ 0x8dd6, 0x8dcc, 0x8ddb, 0x8dcb, 0x8dea, 0x8deb, 0x8ddf, 0x8de3,
+ 0x8dfc, 0x8e08, 0x8e09, 0x8dff, 0x8e1d, 0x8e1e, 0x8e10, 0x8e1f,
+ 0x8e42, 0x8e35, 0x8e30, 0x8e34, 0x8e4a, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e7[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x8e47, 0x8e49, 0x8e4c, 0x8e50, 0x8e48, 0x8e59, 0x8e64, 0x8e60,
+ 0x8e2a, 0x8e63, 0x8e55, 0x8e76, 0x8e72, 0x8e7c, 0x8e81, 0x8e87,
+ 0x8e85, 0x8e84, 0x8e8b, 0x8e8a, 0x8e93, 0x8e91, 0x8e94, 0x8e99,
+ 0x8eaa, 0x8ea1, 0x8eac, 0x8eb0, 0x8ec6, 0x8eb1, 0x8ebe, 0x8ec5,
+ 0x8ec8, 0x8ecb, 0x8edb, 0x8ee3, 0x8efc, 0x8efb, 0x8eeb, 0x8efe,
+ 0x8f0a, 0x8f05, 0x8f15, 0x8f12, 0x8f19, 0x8f13, 0x8f1c, 0x8f1f,
+ 0x8f1b, 0x8f0c, 0x8f26, 0x8f33, 0x8f3b, 0x8f39, 0x8f45, 0x8f42,
+ 0x8f3e, 0x8f4c, 0x8f49, 0x8f46, 0x8f4e, 0x8f57, 0x8f5c, 0x0000,
+ 0x8f62, 0x8f63, 0x8f64, 0x8f9c, 0x8f9f, 0x8fa3, 0x8fad, 0x8faf,
+ 0x8fb7, 0x8fda, 0x8fe5, 0x8fe2, 0x8fea, 0x8fef, 0x9087, 0x8ff4,
+ 0x9005, 0x8ff9, 0x8ffa, 0x9011, 0x9015, 0x9021, 0x900d, 0x901e,
+ 0x9016, 0x900b, 0x9027, 0x9036, 0x9035, 0x9039, 0x8ff8, 0x904f,
+ 0x9050, 0x9051, 0x9052, 0x900e, 0x9049, 0x903e, 0x9056, 0x9058,
+ 0x905e, 0x9068, 0x906f, 0x9076, 0x96a8, 0x9072, 0x9082, 0x907d,
+ 0x9081, 0x9080, 0x908a, 0x9089, 0x908f, 0x90a8, 0x90af, 0x90b1,
+ 0x90b5, 0x90e2, 0x90e4, 0x6248, 0x90db, 0x9102, 0x9112, 0x9119,
+ 0x9132, 0x9130, 0x914a, 0x9156, 0x9158, 0x9163, 0x9165, 0x9169,
+ 0x9173, 0x9172, 0x918b, 0x9189, 0x9182, 0x91a2, 0x91ab, 0x91af,
+ 0x91aa, 0x91b5, 0x91b4, 0x91ba, 0x91c0, 0x91c1, 0x91c9, 0x91cb,
+ 0x91d0, 0x91d6, 0x91df, 0x91e1, 0x91db, 0x91fc, 0x91f5, 0x91f6,
+ 0x921e, 0x91ff, 0x9214, 0x922c, 0x9215, 0x9211, 0x925e, 0x9257,
+ 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923f, 0x924b, 0x9250,
+ 0x929c, 0x9296, 0x9293, 0x929b, 0x925a, 0x92cf, 0x92b9, 0x92b7,
+ 0x92e9, 0x930f, 0x92fa, 0x9344, 0x932e, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e8[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9319, 0x9322, 0x931a, 0x9323, 0x933a, 0x9335, 0x933b, 0x935c,
+ 0x9360, 0x937c, 0x936e, 0x9356, 0x93b0, 0x93ac, 0x93ad, 0x9394,
+ 0x93b9, 0x93d6, 0x93d7, 0x93e8, 0x93e5, 0x93d8, 0x93c3, 0x93dd,
+ 0x93d0, 0x93c8, 0x93e4, 0x941a, 0x9414, 0x9413, 0x9403, 0x9407,
+ 0x9410, 0x9436, 0x942b, 0x9435, 0x9421, 0x943a, 0x9441, 0x9452,
+ 0x9444, 0x945b, 0x9460, 0x9462, 0x945e, 0x946a, 0x9229, 0x9470,
+ 0x9475, 0x9477, 0x947d, 0x945a, 0x947c, 0x947e, 0x9481, 0x947f,
+ 0x9582, 0x9587, 0x958a, 0x9594, 0x9596, 0x9598, 0x9599, 0x0000,
+ 0x95a0, 0x95a8, 0x95a7, 0x95ad, 0x95bc, 0x95bb, 0x95b9, 0x95be,
+ 0x95ca, 0x6ff6, 0x95c3, 0x95cd, 0x95cc, 0x95d5, 0x95d4, 0x95d6,
+ 0x95dc, 0x95e1, 0x95e5, 0x95e2, 0x9621, 0x9628, 0x962e, 0x962f,
+ 0x9642, 0x964c, 0x964f, 0x964b, 0x9677, 0x965c, 0x965e, 0x965d,
+ 0x965f, 0x9666, 0x9672, 0x966c, 0x968d, 0x9698, 0x9695, 0x9697,
+ 0x96aa, 0x96a7, 0x96b1, 0x96b2, 0x96b0, 0x96b4, 0x96b6, 0x96b8,
+ 0x96b9, 0x96ce, 0x96cb, 0x96c9, 0x96cd, 0x894d, 0x96dc, 0x970d,
+ 0x96d5, 0x96f9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970e, 0x9711,
+ 0x970f, 0x9716, 0x9719, 0x9724, 0x972a, 0x9730, 0x9739, 0x973d,
+ 0x973e, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975c, 0x9760,
+ 0x9764, 0x9766, 0x9768, 0x52d2, 0x976b, 0x9771, 0x9779, 0x9785,
+ 0x977c, 0x9781, 0x977a, 0x9786, 0x978b, 0x978f, 0x9790, 0x979c,
+ 0x97a8, 0x97a6, 0x97a3, 0x97b3, 0x97b4, 0x97c3, 0x97c6, 0x97c8,
+ 0x97cb, 0x97dc, 0x97ed, 0x9f4f, 0x97f2, 0x7adf, 0x97f6, 0x97f5,
+ 0x980f, 0x980c, 0x9838, 0x9824, 0x9821, 0x9837, 0x983d, 0x9846,
+ 0x984f, 0x984b, 0x986b, 0x986f, 0x9870, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _e9[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9871, 0x9874, 0x9873, 0x98aa, 0x98af, 0x98b1, 0x98b6, 0x98c4,
+ 0x98c3, 0x98c6, 0x98e9, 0x98eb, 0x9903, 0x9909, 0x9912, 0x9914,
+ 0x9918, 0x9921, 0x991d, 0x991e, 0x9924, 0x9920, 0x992c, 0x992e,
+ 0x993d, 0x993e, 0x9942, 0x9949, 0x9945, 0x9950, 0x994b, 0x9951,
+ 0x9952, 0x994c, 0x9955, 0x9997, 0x9998, 0x99a5, 0x99ad, 0x99ae,
+ 0x99bc, 0x99df, 0x99db, 0x99dd, 0x99d8, 0x99d1, 0x99ed, 0x99ee,
+ 0x99f1, 0x99f2, 0x99fb, 0x99f8, 0x9a01, 0x9a0f, 0x9a05, 0x99e2,
+ 0x9a19, 0x9a2b, 0x9a37, 0x9a45, 0x9a42, 0x9a40, 0x9a43, 0x0000,
+ 0x9a3e, 0x9a55, 0x9a4d, 0x9a5b, 0x9a57, 0x9a5f, 0x9a62, 0x9a65,
+ 0x9a64, 0x9a69, 0x9a6b, 0x9a6a, 0x9aad, 0x9ab0, 0x9abc, 0x9ac0,
+ 0x9acf, 0x9ad1, 0x9ad3, 0x9ad4, 0x9ade, 0x9adf, 0x9ae2, 0x9ae3,
+ 0x9ae6, 0x9aef, 0x9aeb, 0x9aee, 0x9af4, 0x9af1, 0x9af7, 0x9afb,
+ 0x9b06, 0x9b18, 0x9b1a, 0x9b1f, 0x9b22, 0x9b23, 0x9b25, 0x9b27,
+ 0x9b28, 0x9b29, 0x9b2a, 0x9b2e, 0x9b2f, 0x9b32, 0x9b44, 0x9b43,
+ 0x9b4f, 0x9b4d, 0x9b4e, 0x9b51, 0x9b58, 0x9b74, 0x9b93, 0x9b83,
+ 0x9b91, 0x9b96, 0x9b97, 0x9b9f, 0x9ba0, 0x9ba8, 0x9bb4, 0x9bc0,
+ 0x9bca, 0x9bb9, 0x9bc6, 0x9bcf, 0x9bd1, 0x9bd2, 0x9be3, 0x9be2,
+ 0x9be4, 0x9bd4, 0x9be1, 0x9c3a, 0x9bf2, 0x9bf1, 0x9bf0, 0x9c15,
+ 0x9c14, 0x9c09, 0x9c13, 0x9c0c, 0x9c06, 0x9c08, 0x9c12, 0x9c0a,
+ 0x9c04, 0x9c2e, 0x9c1b, 0x9c25, 0x9c24, 0x9c21, 0x9c30, 0x9c47,
+ 0x9c32, 0x9c46, 0x9c3e, 0x9c5a, 0x9c60, 0x9c67, 0x9c76, 0x9c78,
+ 0x9ce7, 0x9cec, 0x9cf0, 0x9d09, 0x9d08, 0x9ceb, 0x9d03, 0x9d06,
+ 0x9d2a, 0x9d26, 0x9daf, 0x9d23, 0x9d1f, 0x9d44, 0x9d15, 0x9d12,
+ 0x9d41, 0x9d3f, 0x9d3e, 0x9d46, 0x9d48, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _ea[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9d5d, 0x9d5e, 0x9d64, 0x9d51, 0x9d50, 0x9d59, 0x9d72, 0x9d89,
+ 0x9d87, 0x9dab, 0x9d6f, 0x9d7a, 0x9d9a, 0x9da4, 0x9da9, 0x9db2,
+ 0x9dc4, 0x9dc1, 0x9dbb, 0x9db8, 0x9dba, 0x9dc6, 0x9dcf, 0x9dc2,
+ 0x9dd9, 0x9dd3, 0x9df8, 0x9de6, 0x9ded, 0x9def, 0x9dfd, 0x9e1a,
+ 0x9e1b, 0x9e1e, 0x9e75, 0x9e79, 0x9e7d, 0x9e81, 0x9e88, 0x9e8b,
+ 0x9e8c, 0x9e92, 0x9e95, 0x9e91, 0x9e9d, 0x9ea5, 0x9ea9, 0x9eb8,
+ 0x9eaa, 0x9ead, 0x9761, 0x9ecc, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed4,
+ 0x9edc, 0x9ede, 0x9edd, 0x9ee0, 0x9ee5, 0x9ee8, 0x9eef, 0x0000,
+ 0x9ef4, 0x9ef6, 0x9ef7, 0x9ef9, 0x9efb, 0x9efc, 0x9efd, 0x9f07,
+ 0x9f08, 0x76b7, 0x9f15, 0x9f21, 0x9f2c, 0x9f3e, 0x9f4a, 0x9f52,
+ 0x9f54, 0x9f63, 0x9f5f, 0x9f60, 0x9f61, 0x9f66, 0x9f67, 0x9f6c,
+ 0x9f6a, 0x9f77, 0x9f72, 0x9f76, 0x9f95, 0x9f9c, 0x9fa0, 0x582f,
+ 0x69c7, 0x9059, 0x7464, 0x51dc, 0x7199, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _ed[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7e8a, 0x891c, 0x9348, 0x9288, 0x84dc, 0x4fc9, 0x70bb, 0x6631,
+ 0x68c8, 0x92f9, 0x66fb, 0x5f45, 0x4e28, 0x4ee1, 0x4efc, 0x4f00,
+ 0x4f03, 0x4f39, 0x4f56, 0x4f92, 0x4f8a, 0x4f9a, 0x4f94, 0x4fcd,
+ 0x5040, 0x5022, 0x4fff, 0x501e, 0x5046, 0x5070, 0x5042, 0x5094,
+ 0x50f4, 0x50d8, 0x514a, 0x5164, 0x519d, 0x51be, 0x51ec, 0x5215,
+ 0x529c, 0x52a6, 0x52c0, 0x52db, 0x5300, 0x5307, 0x5324, 0x5372,
+ 0x5393, 0x53b2, 0x53dd, 0xfa0e, 0x549c, 0x548a, 0x54a9, 0x54ff,
+ 0x5586, 0x5759, 0x5765, 0x57ac, 0x57c8, 0x57c7, 0xfa0f, 0x0000,
+ 0xfa10, 0x589e, 0x58b2, 0x590b, 0x5953, 0x595b, 0x595d, 0x5963,
+ 0x59a4, 0x59ba, 0x5b56, 0x5bc0, 0x752f, 0x5bd8, 0x5bec, 0x5c1e,
+ 0x5ca6, 0x5cba, 0x5cf5, 0x5d27, 0x5d53, 0xfa11, 0x5d42, 0x5d6d,
+ 0x5db8, 0x5db9, 0x5dd0, 0x5f21, 0x5f34, 0x5f67, 0x5fb7, 0x5fde,
+ 0x605d, 0x6085, 0x608a, 0x60de, 0x60d5, 0x6120, 0x60f2, 0x6111,
+ 0x6137, 0x6130, 0x6198, 0x6213, 0x62a6, 0x63f5, 0x6460, 0x649d,
+ 0x64ce, 0x654e, 0x6600, 0x6615, 0x663b, 0x6609, 0x662e, 0x661e,
+ 0x6624, 0x6665, 0x6657, 0x6659, 0xfa12, 0x6673, 0x6699, 0x66a0,
+ 0x66b2, 0x66bf, 0x66fa, 0x670e, 0xf929, 0x6766, 0x67bb, 0x6852,
+ 0x67c0, 0x6801, 0x6844, 0x68cf, 0xfa13, 0x6968, 0xfa14, 0x6998,
+ 0x69e2, 0x6a30, 0x6a6b, 0x6a46, 0x6a73, 0x6a7e, 0x6ae2, 0x6ae4,
+ 0x6bd6, 0x6c3f, 0x6c5c, 0x6c86, 0x6c6f, 0x6cda, 0x6d04, 0x6d87,
+ 0x6d6f, 0x6d96, 0x6dac, 0x6dcf, 0x6df8, 0x6df2, 0x6dfc, 0x6e39,
+ 0x6e5c, 0x6e27, 0x6e3c, 0x6ebf, 0x6f88, 0x6fb5, 0x6ff5, 0x7005,
+ 0x7007, 0x7028, 0x7085, 0x70ab, 0x710f, 0x7104, 0x715c, 0x7146,
+ 0x7147, 0xfa15, 0x71c1, 0x71fe, 0x72b1, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _ee[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x72be, 0x7324, 0xfa16, 0x7377, 0x73bd, 0x73c9, 0x73d6, 0x73e3,
+ 0x73d2, 0x7407, 0x73f5, 0x7426, 0x742a, 0x7429, 0x742e, 0x7462,
+ 0x7489, 0x749f, 0x7501, 0x756f, 0x7682, 0x769c, 0x769e, 0x769b,
+ 0x76a6, 0xfa17, 0x7746, 0x52af, 0x7821, 0x784e, 0x7864, 0x787a,
+ 0x7930, 0xfa18, 0xfa19, 0xfa1a, 0x7994, 0xfa1b, 0x799b, 0x7ad1,
+ 0x7ae7, 0xfa1c, 0x7aeb, 0x7b9e, 0xfa1d, 0x7d48, 0x7d5c, 0x7db7,
+ 0x7da0, 0x7dd6, 0x7e52, 0x7f47, 0x7fa1, 0xfa1e, 0x8301, 0x8362,
+ 0x837f, 0x83c7, 0x83f6, 0x8448, 0x84b4, 0x8553, 0x8559, 0x0000,
+ 0x856b, 0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0x88f5, 0x8a12,
+ 0x8a37, 0x8a79, 0x8aa7, 0x8abe, 0x8adf, 0xfa22, 0x8af6, 0x8b53,
+ 0x8b7f, 0x8cf0, 0x8cf4, 0x8d12, 0x8d76, 0xfa23, 0x8ecf, 0xfa24,
+ 0xfa25, 0x9067, 0x90de, 0xfa26, 0x9115, 0x9127, 0x91da, 0x91d7,
+ 0x91de, 0x91ed, 0x91ee, 0x91e4, 0x91e5, 0x9206, 0x9210, 0x920a,
+ 0x923a, 0x9240, 0x923c, 0x924e, 0x9259, 0x9251, 0x9239, 0x9267,
+ 0x92a7, 0x9277, 0x9278, 0x92e7, 0x92d7, 0x92d9, 0x92d0, 0xfa27,
+ 0x92d5, 0x92e0, 0x92d3, 0x9325, 0x9321, 0x92fb, 0xfa28, 0x931e,
+ 0x92ff, 0x931d, 0x9302, 0x9370, 0x9357, 0x93a4, 0x93c6, 0x93de,
+ 0x93f8, 0x9431, 0x9445, 0x9448, 0x9592, 0xf9dc, 0xfa29, 0x969d,
+ 0x96af, 0x9733, 0x973b, 0x9743, 0x974d, 0x974f, 0x9751, 0x9755,
+ 0x9857, 0x9865, 0xfa2a, 0xfa2b, 0x9927, 0xfa2c, 0x999e, 0x9a4e,
+ 0x9ad9, 0x9adc, 0x9b75, 0x9b72, 0x9b8f, 0x9bb1, 0x9bbb, 0x9c00,
+ 0x9d70, 0x9d6b, 0xfa2d, 0x9e19, 0x9ed1, 0x0000, 0x0000, 0x2170,
+ 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178,
+ 0x2179, 0xffe2, 0xffe4, 0xff07, 0xff02, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _fa[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+ 0x2178, 0x2179, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165,
+ 0x2166, 0x2167, 0x2168, 0x2169, 0xffe2, 0xffe4, 0xff07, 0xff02,
+ 0x3231, 0x2116, 0x2121, 0x2235, 0x7e8a, 0x891c, 0x9348, 0x9288,
+ 0x84dc, 0x4fc9, 0x70bb, 0x6631, 0x68c8, 0x92f9, 0x66fb, 0x5f45,
+ 0x4e28, 0x4ee1, 0x4efc, 0x4f00, 0x4f03, 0x4f39, 0x4f56, 0x4f92,
+ 0x4f8a, 0x4f9a, 0x4f94, 0x4fcd, 0x5040, 0x5022, 0x4fff, 0x501e,
+ 0x5046, 0x5070, 0x5042, 0x5094, 0x50f4, 0x50d8, 0x514a, 0x0000,
+ 0x5164, 0x519d, 0x51be, 0x51ec, 0x5215, 0x529c, 0x52a6, 0x52c0,
+ 0x52db, 0x5300, 0x5307, 0x5324, 0x5372, 0x5393, 0x53b2, 0x53dd,
+ 0xfa0e, 0x549c, 0x548a, 0x54a9, 0x54ff, 0x5586, 0x5759, 0x5765,
+ 0x57ac, 0x57c8, 0x57c7, 0xfa0f, 0xfa10, 0x589e, 0x58b2, 0x590b,
+ 0x5953, 0x595b, 0x595d, 0x5963, 0x59a4, 0x59ba, 0x5b56, 0x5bc0,
+ 0x752f, 0x5bd8, 0x5bec, 0x5c1e, 0x5ca6, 0x5cba, 0x5cf5, 0x5d27,
+ 0x5d53, 0xfa11, 0x5d42, 0x5d6d, 0x5db8, 0x5db9, 0x5dd0, 0x5f21,
+ 0x5f34, 0x5f67, 0x5fb7, 0x5fde, 0x605d, 0x6085, 0x608a, 0x60de,
+ 0x60d5, 0x6120, 0x60f2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6218,
+ 0x62a6, 0x63f5, 0x6460, 0x649d, 0x64ce, 0x654e, 0x6600, 0x6615,
+ 0x663b, 0x6609, 0x662e, 0x661e, 0x6624, 0x6665, 0x6657, 0x6659,
+ 0xfa12, 0x6673, 0x6699, 0x66a0, 0x66b2, 0x66bf, 0x66fa, 0x670e,
+ 0xf929, 0x6766, 0x67bb, 0x6852, 0x67c0, 0x6801, 0x6844, 0x68cf,
+ 0xfa13, 0x6968, 0xfa14, 0x6998, 0x69e2, 0x6a30, 0x6a6b, 0x6a46,
+ 0x6a73, 0x6a7e, 0x6ae2, 0x6ae4, 0x6bd6, 0x6c3f, 0x6c5c, 0x6c86,
+ 0x6c6f, 0x6cda, 0x6d04, 0x6d87, 0x6d6f, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _fb[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6d96, 0x6dac, 0x6dcf, 0x6df8, 0x6df2, 0x6dfc, 0x6e39, 0x6e5c,
+ 0x6e27, 0x6e3c, 0x6ebf, 0x6f88, 0x6fb5, 0x6ff5, 0x7005, 0x7007,
+ 0x7028, 0x7085, 0x70ab, 0x710f, 0x7104, 0x715c, 0x7146, 0x7147,
+ 0xfa15, 0x71c1, 0x71fe, 0x72b1, 0x72be, 0x7324, 0xfa16, 0x7377,
+ 0x73bd, 0x73c9, 0x73d6, 0x73e3, 0x73d2, 0x7407, 0x73f5, 0x7426,
+ 0x742a, 0x7429, 0x742e, 0x7462, 0x7489, 0x749f, 0x7501, 0x756f,
+ 0x7682, 0x769c, 0x769e, 0x769b, 0x76a6, 0xfa17, 0x7746, 0x52af,
+ 0x7821, 0x784e, 0x7864, 0x787a, 0x7930, 0xfa18, 0xfa19, 0x0000,
+ 0xfa1a, 0x7994, 0xfa1b, 0x799b, 0x7ad1, 0x7ae7, 0xfa1c, 0x7aeb,
+ 0x7b9e, 0xfa1d, 0x7d48, 0x7d5c, 0x7db7, 0x7da0, 0x7dd6, 0x7e52,
+ 0x7f47, 0x7fa1, 0xfa1e, 0x8301, 0x8362, 0x837f, 0x83c7, 0x83f6,
+ 0x8448, 0x84b4, 0x8553, 0x8559, 0x856b, 0xfa1f, 0x85b0, 0xfa20,
+ 0xfa21, 0x8807, 0x88f5, 0x8a12, 0x8a37, 0x8a79, 0x8aa7, 0x8abe,
+ 0x8adf, 0xfa22, 0x8af6, 0x8b53, 0x8b7f, 0x8cf0, 0x8cf4, 0x8d12,
+ 0x8d76, 0xfa23, 0x8ecf, 0xfa24, 0xfa25, 0x9067, 0x90de, 0xfa26,
+ 0x9115, 0x9127, 0x91da, 0x91d7, 0x91de, 0x91ed, 0x91ee, 0x91e4,
+ 0x91e5, 0x9206, 0x9210, 0x920a, 0x923a, 0x9240, 0x923c, 0x924e,
+ 0x9259, 0x9251, 0x9239, 0x9267, 0x92a7, 0x9277, 0x9278, 0x92e7,
+ 0x92d7, 0x92d9, 0x92d0, 0xfa27, 0x92d5, 0x92e0, 0x92d3, 0x9325,
+ 0x9321, 0x92fb, 0xfa28, 0x931e, 0x92ff, 0x931d, 0x9302, 0x9370,
+ 0x9357, 0x93a4, 0x93c6, 0x93de, 0x93f8, 0x9431, 0x9445, 0x9448,
+ 0x9592, 0xf9dc, 0xfa29, 0x969d, 0x96af, 0x9733, 0x973b, 0x9743,
+ 0x974d, 0x974f, 0x9751, 0x9755, 0x9857, 0x9865, 0xfa2a, 0xfa2b,
+ 0x9927, 0xfa2c, 0x999e, 0x9a4e, 0x9ad9, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short _fc[0x100] =
+{
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x9adc, 0x9b75, 0x9b72, 0x9b8f, 0x9bb1, 0x9bbb, 0x9c00, 0x9d70,
+ 0x9d6b, 0xfa2d, 0x9e19, 0x9ed1, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short *convert_table[0x100] =
+{
+ _00, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, _81, _82, _83, _84, ERR, ERR, _87, _88, _89, _8a, _8b, _8c, _8d, _8e, _8f,
+ _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9a, _9b, _9c, _9d, _9e, _9f,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
+ _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7, _e8, _e9, _ea, ERR, ERR, _ed, _ee, ERR,
+ ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, _fa, _fb, _fc, ERR, ERR, ERR
+};
+
+
+#define issjis1(c) (((c) >= 0x81 && (c) <= 0x9f) | ((c) >= 0xe0 && (c) <= 0xfc))
+#define issjis2(c) ((c) >= 0x40 && (c) <= 0xfc && (c) != 0x7f)
+
+
+/*--------------------------------------------------------
+ Shift_JISã‹ã‚‰USC2ã«å¤‰æ›
+--------------------------------------------------------*/
+
+unsigned short sjis_to_ucs2(unsigned short sjis)
+{
+ const unsigned short *table;
+
+ if ((table = convert_table[sjis >> 8]) != ERR)
+ return table[sjis & 0xff];
+
+ return 0;
+}
+
+
+/*--------------------------------------------------------
+ Shift_JISã‹ã‚‰UTF-8ã«å¤‰æ›
+--------------------------------------------------------*/
+
+int sjis_to_utf8(const void *sjis_text, void *buf)
+{
+ unsigned short unicode;
+ const unsigned char *src = (const unsigned char *)sjis_text;
+ char *dst = (char *)buf;
+ int i = 0;
+
+ while (*src)
+ {
+ if (issjis1(*src) && issjis2(*(src + 1)))
+ {
+ unicode = sjis_to_ucs2((*src << 8) | *(src + 1));
+ src += 2;
+ }
+ else
+ {
+ unicode = sjis_to_ucs2(*src);
+ src++;
+ }
+
+ if (unicode < 0x80)
+ {
+ *dst++ = unicode;
+ }
+ else if (unicode < 0x800)
+ {
+ *dst++ = 0xc0 | ((unicode >> 6) & 0x3f);
+ *dst++ = 0x80 | (unicode & 0x3f);
+ }
+ else
+ {
+ *dst++ = 0xe0 | ((unicode >> 12) & 0x0f);
+ *dst++ = 0x80 | ((unicode >> 6) & 0x3f);
+ *dst++ = 0x80 | (unicode & 0x3f);
+ }
+ i++;
+ }
+
+ *dst = '\0';
+
+ return i;
+}
+
+
+/*--------------------------------------------------------
+ Shift_JISã‹ã‚‰UTF-16LEã«å¤‰æ›
+--------------------------------------------------------*/
+
+int sjis_to_utf16le(const void *sjis_text, void *buf)
+{
+ unsigned short unicode;
+ const unsigned char *src = (const unsigned char *)sjis_text;
+ unsigned short *dst = (unsigned short *)buf;
+ int i = 0;
+
+ while (*src)
+ {
+ if (issjis1(*src) && issjis2(*(src + 1)))
+ {
+ unicode = sjis_to_ucs2((*src << 8) | *(src + 1));
+ src += 2;
+ }
+ else
+ {
+ unicode = sjis_to_ucs2(*src);
+ src++;
+ }
+
+ dst[i++] = unicode;
+ }
+
+ dst[i] = 0;
+
+ return i;
+}
+
+
+/*--------------------------------------------------------
+ Shift_JISã‹ã‚‰UTF-16BEã«å¤‰æ›
+--------------------------------------------------------*/
+
+int sjis_to_utf16be(const void *sjis_text, void *buf)
+{
+ int len = sjis_to_utf16le(sjis_text, buf);
+
+ swab((unsigned char *)buf, (unsigned char *)buf, len);
+
+ return len;
+}
+
+/************************************************************
+* cut down a long sj string to short string
+************************************************************/
+int sjis_to_cut(void *buf, const void *sjis_text, int len)
+{
+ const unsigned char *str= (const unsigned char*)sjis_text;
+ unsigned char *dest= (unsigned char*)buf;
+ int m;
+ unsigned int n;
+
+ m= len;
+ while(*str)
+ {
+ if (issjis1(*str) && issjis2(*(str + 1)))
+ str += 2;
+ else
+ str++;
+ m--;
+ if(m== 0)
+ break;
+ }
+
+ n = (unsigned int)str - (unsigned int)sjis_text;
+ memcpy(dest, (const unsigned char*)sjis_text, n);
+ *(dest+n) = 0;
+
+ if(m == 0)
+ if(*str)
+ {
+ *(dest+n-3) = '.';
+ *(dest+n-2) = '.';
+ *(dest+n-1) = '.';
+ }
+
+ return (len-m);
+}
+
+
diff --git a/source/unicode.h b/source/unicode.h
new file mode 100644
index 0000000..c474f95
--- /dev/null
+++ b/source/unicode.h
@@ -0,0 +1,44 @@
+/* unofficial gameplaySP kai
+ *
+ * Copyright (C) 2007 NJ
+ * Copyright (C) 2007 takka <takka@tfact.net>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef UNICODE_H
+#define UNICODE_H
+
+// 関数宣言
+// UTF-8 -> Shift_JIS
+int utf8_to_sjis(const void *utf8_text, void *buf);
+
+// UTF-16 -> Shift_JIS
+int utf16_to_sjis(const void *utf16_text, void *buf);
+
+// Shift_JIS -> UTF-8
+int sjis_to_utf8(const void *sjis_text, void *buf);
+
+// Shift_JIS -> UTF-16LE
+int sjis_to_utf16le(const void *sjis_text, void *buf);
+
+// Shift_JIS -> UTF-16BE
+int sjis_to_utf16be(const void *sjis_text, void *buf);
+
+unsigned short sjis_to_ucs2(unsigned short sjis);
+
+int sjis_to_cut(void *buf, const void *sjis_text, int len);
+
+#endif
diff --git a/source/unzip/explode.c b/source/unzip/explode.c
new file mode 100644
index 0000000..6558a7b
--- /dev/null
+++ b/source/unzip/explode.c
@@ -0,0 +1,1120 @@
+/* explode.c -- Not copyrighted 1992 by Mark Adler
+ version c7, 27 June 1992 */
+
+
+/* You can do whatever you like with this source file, though I would
+ prefer that if you modify it and redistribute it that you include
+ comments to that effect with your name and the date. Thank you.
+
+ History:
+ vers date who what
+ ---- --------- -------------- ------------------------------------
+ c1 30 Mar 92 M. Adler explode that uses huft_build from inflate
+ (this gives over a 70% speed improvement
+ over the original unimplode.c, which
+ decoded a bit at a time)
+ c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k.
+ c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG
+ c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy()
+ c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing
+ the 32K window size for specialized
+ applications.
+ c6 31 May 92 M. Adler added typecasts to eliminate some warnings
+ c7 27 Jun 92 G. Roelofs added more typecasts
+ */
+
+
+/*
+ Explode imploded (PKZIP method 6 compressed) data. This compression
+ method searches for as much of the current string of bytes (up to a length
+ of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches
+ (of at least length 2 or 3), it codes the next byte. Otherwise, it codes
+ the length of the matched string and its distance backwards from the
+ current position. Single bytes ("literals") are preceded by a one (a
+ single bit) and are either uncoded (the eight bits go directly into the
+ compressed stream for a total of nine bits) or Huffman coded with a
+ supplied literal code tree. If literals are coded, then the minimum match
+ length is three, otherwise it is two.
+
+ There are therefore four kinds of imploded streams: 8K search with coded
+ literals (min match = 3), 4K search with coded literals (min match = 3),
+ 8K with uncoded literals (min match = 2), and 4K with uncoded literals
+ (min match = 2). The kind of stream is identified in two bits of a
+ general purpose bit flag that is outside of the compressed stream.
+
+ Distance-length pairs are always coded. Distance-length pairs for matched
+ strings are preceded by a zero bit (to distinguish them from literals) and
+ are always coded. The distance comes first and is either the low six (4K)
+ or low seven (8K) bits of the distance (uncoded), followed by the high six
+ bits of the distance coded. Then the length is six bits coded (0..63 +
+ min match length), and if the maximum such length is coded, then it's
+ followed by another eight bits (uncoded) to be added to the coded length.
+ This gives a match length range of 2..320 or 3..321 bytes.
+
+ The literal, length, and distance codes are all represented in a slightly
+ compressed form themselves. What is sent are the lengths of the codes for
+ each value, which is sufficient to construct the codes. Each byte of the
+ code representation is the code length (the low four bits representing
+ 1..16), and the number of values sequentially with that length (the high
+ four bits also representing 1..16). There are 256 literal code values (if
+ literals are coded), 64 length code values, and 64 distance code values,
+ in that order at the beginning of the compressed stream. Each set of code
+ values is preceded (redundantly) with a byte indicating how many bytes are
+ in the code description that follows, in the range 1..256.
+
+ The codes themselves are decoded using tables made by huft_build() from
+ the bit lengths. That routine and its comments are in the inflate.c
+ module.
+ */
+
+#include "unz.h" /* this must supply the slide[] (byte) array */
+#include "unzipP.h"
+//#include <stdlib.h>
+#include "ds2_malloc.h"
+
+#ifndef WSIZE
+# define WSIZE 0x8000 /* window size--must be a power of two, and at least
+ 8K for zip's implode method */
+#endif /* !WSIZE */
+
+
+struct huft {
+ byte e; /* number of extra bits or operation */
+ byte b; /* number of bits in this code or subcode */
+ union {
+ UWORD n; /* literal, length base, or distance base */
+ struct huft *t; /* pointer to next level of table */
+ } v;
+};
+
+/* Function prototypes */
+/* routines from inflate.c */
+extern unsigned hufts;
+int huft_build OF((unsigned *, unsigned, unsigned, UWORD *, UWORD *,
+ struct huft **, int *));
+int huft_free OF((struct huft *));
+void flush OF((unsigned));
+
+/* routines here */
+int get_tree OF((unsigned *, unsigned));
+int explode_lit8 OF((struct huft *, struct huft *, struct huft *,
+ int, int, int));
+int explode_lit4 OF((struct huft *, struct huft *, struct huft *,
+ int, int, int));
+int explode_nolit8 OF((struct huft *, struct huft *, int, int));
+int explode_nolit4 OF((struct huft *, struct huft *, int, int));
+int explode ();
+
+extern file_in_zip_read_info_s *pfile_in_zip_read_info;
+extern unz_s *pUnzip;
+
+/* The implode algorithm uses a sliding 4K or 8K byte window on the
+ uncompressed stream to find repeated byte strings. This is implemented
+ here as a circular buffer. The index is updated simply by incrementing
+ and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K
+ buffer of inflate is used, and it works just as well to always have
+ a 32K circular buffer, so the index is anded with 0x7fff. This is
+ done to allow the window to also be used as the output buffer. */
+/* This must be supplied in an external module useable like "byte slide[8192];"
+ or "byte *slide;", where the latter would be malloc'ed. In unzip, slide[]
+ is actually a 32K area for use by inflate, which uses a 32K sliding window.
+ */
+
+
+/* Tables for length and distance */
+UWORD cplen2[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65};
+UWORD cplen3[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66};
+UWORD extra[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8};
+UWORD cpdist4[] = {1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705,
+ 769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473,
+ 1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177,
+ 2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881,
+ 2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585,
+ 3649, 3713, 3777, 3841, 3905, 3969, 4033};
+UWORD cpdist8[] = {1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281,
+ 1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689,
+ 2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097,
+ 4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505,
+ 5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913,
+ 7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065};
+
+
+/* Macros for inflate() bit peeking and grabbing.
+ The usage is:
+
+ NEEDBITS(j)
+ x = b & mask_bits[j];
+ DUMPBITS(j)
+
+ where NEEDBITS makes sure that b has at least j bits in it, and
+ DUMPBITS removes the bits from b. The macros use the variable k
+ for the number of bits in b. Normally, b and k are register
+ variables for speed.
+ */
+
+extern UWORD bytebuf; /* (use the one in inflate.c) */
+#define NEXTBYTE (ReadByte(&bytebuf), bytebuf)
+#define NEEDBITS(n) {while(k<(n)){b|=((ULONG)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(n) {b>>=(n);k-=(n);}
+
+/* HERE */
+UWORD mask_bits[] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+union work area; /* see unzip.h for the definition of work */
+ULONG crc32val;
+ush bytebuf;
+ULONG bitbuf;
+int bits_left;
+boolean zipeof;
+
+int get_tree(l, n)
+unsigned *l; /* bit lengths */
+unsigned n; /* number expected */
+/* Get the bit lengths for a code representation from the compressed
+ stream. If get_tree() returns 4, then there is an error in the data.
+ Otherwise zero is returned. */
+{
+ unsigned i; /* bytes remaining in list */
+ unsigned k; /* lengths entered */
+ unsigned j; /* number of codes */
+ unsigned b; /* bit length for those codes */
+
+
+ /* get bit lengths */
+ ReadByte(&bytebuf);
+ i = bytebuf + 1; /* length/count pairs to read */
+ k = 0; /* next code */
+ do {
+ ReadByte(&bytebuf);
+ b = ((j = bytebuf) & 0xf) + 1; /* bits in code (1..16) */
+ j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */
+ if (k + j > n)
+ return 4; /* don't overflow l[] */
+ do {
+ l[k++] = b;
+ } while (--j);
+ } while (--i);
+ return k != n ? 4 : 0; /* should have read n of them */
+}
+
+
+
+int explode_lit8(tb, tl, td, bb, bl, bd)
+struct huft *tb, *tl, *td; /* literal, length, and distance tables */
+int bb, bl, bd; /* number of bits decoded by those */
+/* Decompress the imploded data using coded literals and an 8K sliding
+ window. */
+{
+ longint s; /* bytes to decompress */
+ register unsigned e; /* table entry flag/number of extra bits */
+ unsigned n, d; /* length and index for copy */
+ unsigned w; /* current window position */
+ struct huft *t; /* pointer to table entry */
+ unsigned mb, ml, md; /* masks for bb, bl, and bd bits */
+ register ULONG b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ unsigned u; /* true if unflushed */
+
+
+ /* explode the coded data */
+ b = k = w = 0; /* initialize bit buffer, window */
+ u = 1; /* buffer unflushed */
+ mb = mask_bits[bb]; /* precompute masks for speed */
+ ml = mask_bits[bl];
+ md = mask_bits[bd];
+ s = pUnzip->pfile_in_zip_read->rest_read_uncompressed;
+ while (s > 0) /* do until ucsize bytes uncompressed */
+ {
+ NEEDBITS(1)
+ if (b & 1) /* then literal--decode it */
+ {
+ DUMPBITS(1)
+ s--;
+ NEEDBITS((unsigned)bb) /* get coded literal */
+ if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ slide[w++] = (byte)t->v.n;
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ }
+ else /* else distance/length */
+ {
+ DUMPBITS(1)
+ NEEDBITS(7) /* get distance low bits */
+ d = (unsigned)b & 0x7f;
+ DUMPBITS(7)
+ NEEDBITS((unsigned)bd) /* get coded distance high bits */
+ if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ d = w - d - t->v.n; /* construct offset */
+ NEEDBITS((unsigned)bl) /* get coded length */
+ if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ n = t->v.n;
+ if (e) /* get length extra bits */
+ {
+ NEEDBITS(8)
+ n += (unsigned)b & 0xff;
+ DUMPBITS(8)
+ }
+
+ /* do the copy */
+ s -= n;
+ do {
+ n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
+ if (u && w <= d)
+ {
+ memset(slide + w, 0, e);
+ w += e;
+ d += e;
+ }
+ else
+#ifndef NOMEMCPY
+ if (w - d >= e) /* (this test assumes unsigned comparison) */
+ {
+ memcpy(slide + w, slide + d, e);
+ w += e;
+ d += e;
+ }
+ else /* do it slow to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+ do {
+ slide[w++] = slide[d++];
+ } while (--e);
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ } while (n);
+ }
+ }
+
+ /* flush out slide */
+ flush(w);
+ return pfile_in_zip_read_info->rest_read_compressed ? 5 : 0; /* should have read csize bytes */
+}
+
+
+
+int explode_lit4(tb, tl, td, bb, bl, bd)
+struct huft *tb, *tl, *td; /* literal, length, and distance tables */
+int bb, bl, bd; /* number of bits decoded by those */
+/* Decompress the imploded data using coded literals and a 4K sliding
+ window. */
+{
+ longint s; /* bytes to decompress */
+ register unsigned e; /* table entry flag/number of extra bits */
+ unsigned n, d; /* length and index for copy */
+ unsigned w; /* current window position */
+ struct huft *t; /* pointer to table entry */
+ unsigned mb, ml, md; /* masks for bb, bl, and bd bits */
+ register ULONG b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ unsigned u; /* true if unflushed */
+
+
+ /* explode the coded data */
+ b = k = w = 0; /* initialize bit buffer, window */
+ u = 1; /* buffer unflushed */
+ mb = mask_bits[bb]; /* precompute masks for speed */
+ ml = mask_bits[bl];
+ md = mask_bits[bd];
+ s = pUnzip->pfile_in_zip_read->rest_read_uncompressed;
+ while (s > 0) /* do until ucsize bytes uncompressed */
+ {
+ NEEDBITS(1)
+ if (b & 1) /* then literal--decode it */
+ {
+ DUMPBITS(1)
+ s--;
+ NEEDBITS((unsigned)bb) /* get coded literal */
+ if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ slide[w++] = (byte)t->v.n;
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ }
+ else /* else distance/length */
+ {
+ DUMPBITS(1)
+ NEEDBITS(6) /* get distance low bits */
+ d = (unsigned)b & 0x3f;
+ DUMPBITS(6)
+ NEEDBITS((unsigned)bd) /* get coded distance high bits */
+ if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ d = w - d - t->v.n; /* construct offset */
+ NEEDBITS((unsigned)bl) /* get coded length */
+ if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ n = t->v.n;
+ if (e) /* get length extra bits */
+ {
+ NEEDBITS(8)
+ n += (unsigned)b & 0xff;
+ DUMPBITS(8)
+ }
+
+ /* do the copy */
+ s -= n;
+ do {
+ n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
+ if (u && w <= d)
+ {
+ memset(slide + w, 0, e);
+ w += e;
+ d += e;
+ }
+ else
+#ifndef NOMEMCPY
+ if (w - d >= e) /* (this test assumes unsigned comparison) */
+ {
+ memcpy(slide + w, slide + d, e);
+ w += e;
+ d += e;
+ }
+ else /* do it slow to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+ do {
+ slide[w++] = slide[d++];
+ } while (--e);
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ } while (n);
+ }
+ }
+
+ /* flush out slide */
+ flush(w);
+ return pfile_in_zip_read_info->rest_read_compressed ? 5 : 0; /* should have read csize bytes */
+}
+
+
+
+int explode_nolit8(tl, td, bl, bd)
+struct huft *tl, *td; /* length and distance decoder tables */
+int bl, bd; /* number of bits decoded by tl[] and td[] */
+/* Decompress the imploded data using uncoded literals and an 8K sliding
+ window. */
+{
+ longint s; /* bytes to decompress */
+ register unsigned e; /* table entry flag/number of extra bits */
+ unsigned n, d; /* length and index for copy */
+ unsigned w; /* current window position */
+ struct huft *t; /* pointer to table entry */
+ unsigned ml, md; /* masks for bl and bd bits */
+ register ULONG b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ unsigned u; /* true if unflushed */
+
+
+ /* explode the coded data */
+ b = k = w = 0; /* initialize bit buffer, window */
+ u = 1; /* buffer unflushed */
+ ml = mask_bits[bl]; /* precompute masks for speed */
+ md = mask_bits[bd];
+ s = pUnzip->pfile_in_zip_read->rest_read_uncompressed;
+ while (s > 0) /* do until ucsize bytes uncompressed */
+ {
+ NEEDBITS(1)
+ if (b & 1) /* then literal--get eight bits */
+ {
+ DUMPBITS(1)
+ s--;
+ NEEDBITS(8)
+ slide[w++] = (byte)b;
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ DUMPBITS(8)
+ }
+ else /* else distance/length */
+ {
+ DUMPBITS(1)
+ NEEDBITS(7) /* get distance low bits */
+ d = (unsigned)b & 0x7f;
+ DUMPBITS(7)
+ NEEDBITS((unsigned)bd) /* get coded distance high bits */
+ if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ d = w - d - t->v.n; /* construct offset */
+ NEEDBITS((unsigned)bl) /* get coded length */
+ if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ n = t->v.n;
+ if (e) /* get length extra bits */
+ {
+ NEEDBITS(8)
+ n += (unsigned)b & 0xff;
+ DUMPBITS(8)
+ }
+
+ /* do the copy */
+ s -= n;
+ do {
+ n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
+ if (u && w <= d)
+ {
+ memset(slide + w, 0, e);
+ w += e;
+ d += e;
+ }
+ else
+#ifndef NOMEMCPY
+ if (w - d >= e) /* (this test assumes unsigned comparison) */
+ {
+ memcpy(slide + w, slide + d, e);
+ w += e;
+ d += e;
+ }
+ else /* do it slow to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+ do {
+ slide[w++] = slide[d++];
+ } while (--e);
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ } while (n);
+ }
+ }
+
+ /* flush out slide */
+ flush(w);
+ return pfile_in_zip_read_info->rest_read_compressed ? 5 : 0; /* should have read csize bytes */
+}
+
+
+
+int explode_nolit4(tl, td, bl, bd)
+struct huft *tl, *td; /* length and distance decoder tables */
+int bl, bd; /* number of bits decoded by tl[] and td[] */
+/* Decompress the imploded data using uncoded literals and a 4K sliding
+ window. */
+{
+ longint s; /* bytes to decompress */
+ register unsigned e; /* table entry flag/number of extra bits */
+ unsigned n, d; /* length and index for copy */
+ unsigned w; /* current window position */
+ struct huft *t; /* pointer to table entry */
+ unsigned ml, md; /* masks for bl and bd bits */
+ register ULONG b; /* bit buffer */
+ register unsigned k; /* number of bits in bit buffer */
+ unsigned u; /* true if unflushed */
+
+
+ /* explode the coded data */
+ b = k = w = 0; /* initialize bit buffer, window */
+ u = 1; /* buffer unflushed */
+ ml = mask_bits[bl]; /* precompute masks for speed */
+ md = mask_bits[bd];
+ s = pUnzip->pfile_in_zip_read->rest_read_uncompressed;
+ while (s > 0) /* do until ucsize bytes uncompressed */
+ {
+ NEEDBITS(1)
+ if (b & 1) /* then literal--get eight bits */
+ {
+ DUMPBITS(1)
+ s--;
+ NEEDBITS(8)
+ slide[w++] = (byte)b;
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ DUMPBITS(8)
+ }
+ else /* else distance/length */
+ {
+ DUMPBITS(1)
+ NEEDBITS(6) /* get distance low bits */
+ d = (unsigned)b & 0x3f;
+ DUMPBITS(6)
+ NEEDBITS((unsigned)bd) /* get coded distance high bits */
+ if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ d = w - d - t->v.n; /* construct offset */
+ NEEDBITS((unsigned)bl) /* get coded length */
+ if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16)
+ do {
+ if (e == 99)
+ return 1;
+ DUMPBITS(t->b)
+ e -= 16;
+ NEEDBITS(e)
+ } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16);
+ DUMPBITS(t->b)
+ n = t->v.n;
+ if (e) /* get length extra bits */
+ {
+ NEEDBITS(8)
+ n += (unsigned)b & 0xff;
+ DUMPBITS(8)
+ }
+
+ /* do the copy */
+ s -= n;
+ do {
+ n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
+ if (u && w <= d)
+ {
+ memset(slide + w, 0, e);
+ w += e;
+ d += e;
+ }
+ else
+#ifndef NOMEMCPY
+ if (w - d >= e) /* (this test assumes unsigned comparison) */
+ {
+ memcpy(slide + w, slide + d, e);
+ w += e;
+ d += e;
+ }
+ else /* do it slow to avoid memcpy() overlap */
+#endif /* !NOMEMCPY */
+ do {
+ slide[w++] = slide[d++];
+ } while (--e);
+ if (w == WSIZE)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ } while (n);
+ }
+ }
+
+ /* flush out slide */
+ flush(w);
+ return pfile_in_zip_read_info->rest_read_compressed ? 5 : 0; /* should have read csize bytes */
+}
+
+
+
+int explode ()
+/* Explode an imploded compressed stream. Based on the general purpose
+ bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding
+ window. Construct the literal (if any), length, and distance codes and
+ the tables needed to decode them (using huft_build() from inflate.c),
+ and call the appropriate routine for the type of data in the remainder
+ of the stream. The four routines are nearly identical, differing only
+ in whether the literal is decoded or simply read in, and in how many
+ bits are read in, uncoded, for the low distance bits. */
+{
+ unsigned r; /* return codes */
+ struct huft *tb; /* literal code table */
+ struct huft *tl; /* length code table */
+ struct huft *td; /* distance code table */
+ int bb; /* bits for tb */
+ int bl; /* bits for tl */
+ int bd; /* bits for td */
+ unsigned l[256]; /* bit lengths for codes */
+
+
+ /* Tune base table sizes. Note: I thought that to truly optimize speed,
+ I would have to select different bl, bd, and bb values for different
+ compressed file sizes. I was suprised to find out the the values of
+ 7, 7, and 9 worked best over a very wide range of sizes, except that
+ bd = 8 worked marginally better for large compressed sizes. */
+ bl = 7;
+ bd = pUnzip->pfile_in_zip_read->rest_read_compressed > 200000L ? 8 : 7;
+
+
+ /* With literal tree--minimum match length is 3 */
+ hufts = 0; /* initialze huft's malloc'ed */
+ if (pUnzip->cur_file_info.flag & 4)
+ {
+ bb = 9; /* base table size for literals */
+ if ((r = get_tree(l, 256)) != 0)
+ return r;
+ if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb)) != 0)
+ {
+ if (r == 1)
+ huft_free(tb);
+ return r;
+ }
+ if ((r = get_tree(l, 64)) != 0)
+ return r;
+ if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl)) != 0)
+ {
+ if (r == 1)
+ huft_free(tl);
+ huft_free(tb);
+ return r;
+ }
+ if ((r = get_tree(l, 64)) != 0)
+ return r;
+ if (pUnzip->cur_file_info.flag & 2) /* true if 8K */
+ {
+ if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
+ {
+ if (r == 1)
+ huft_free(td);
+ huft_free(tl);
+ huft_free(tb);
+ return r;
+ }
+ r = explode_lit8(tb, tl, td, bb, bl, bd);
+ }
+ else /* else 4K */
+ {
+ if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
+ {
+ if (r == 1)
+ huft_free(td);
+ huft_free(tl);
+ huft_free(tb);
+ return r;
+ }
+ r = explode_lit4(tb, tl, td, bb, bl, bd);
+ }
+ huft_free(td);
+ huft_free(tl);
+ huft_free(tb);
+ }
+ else
+
+
+ /* No literal tree--minimum match length is 2 */
+ {
+ if ((r = get_tree(l, 64)) != 0)
+ return r;
+ if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl)) != 0)
+ {
+ if (r == 1)
+ huft_free(tl);
+ return r;
+ }
+ if ((r = get_tree(l, 64)) != 0)
+ return r;
+ if (pUnzip->cur_file_info.flag & 2) /* true if 8K */
+ {
+ if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd)) != 0)
+ {
+ if (r == 1)
+ huft_free(td);
+ huft_free(tl);
+ return r;
+ }
+ r = explode_nolit8(tl, td, bl, bd);
+ }
+ else /* else 4K */
+ {
+ if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd)) != 0)
+ {
+ if (r == 1)
+ huft_free(td);
+ huft_free(tl);
+ return r;
+ }
+ r = explode_nolit4(tl, td, bl, bd);
+ }
+ huft_free(td);
+ huft_free(tl);
+ }
+#ifdef DEBUG
+ fprintf(stderr, "<%u > ", hufts);
+#endif /* DEBUG */
+ return r;
+}
+
+
+int ReadByte(x)
+ UWORD *x;
+{
+ /*
+ * read a byte; return 8 if byte available, 0 if not
+ */
+
+ if (pfile_in_zip_read_info->stream.avail_in == 0)
+ {
+ unsigned int uReadThis = UNZ_BUFSIZE;
+
+ if (pfile_in_zip_read_info->rest_read_compressed <= 0)
+ return (0);
+
+ if (pfile_in_zip_read_info->rest_read_compressed < uReadThis)
+ uReadThis = (uInt) pfile_in_zip_read_info->rest_read_compressed;
+ if (uReadThis == 0)
+ return UNZ_EOF;
+ if (fseek (pfile_in_zip_read_info->file,
+ pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile, SEEK_SET) != 0)
+ return UNZ_ERRNO;
+ if (fread (pfile_in_zip_read_info->read_buffer, uReadThis, 1,
+ pfile_in_zip_read_info->file) != 1)
+ return UNZ_ERRNO;
+ pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+ pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
+
+ pfile_in_zip_read_info->stream.next_in =
+ (Bytef *) pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.avail_in = (uInt) uReadThis;
+ }
+
+ *x = *pfile_in_zip_read_info->stream.next_in++;
+ pfile_in_zip_read_info->stream.avail_in--;
+
+ return 8;
+}
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16 /* maximum bit length of any code (16 for explode) */
+#define N_MAX 288 /* maximum number of codes in any set */
+
+unsigned hufts; /* track memory usage */
+
+
+int huft_build(b, n, s, d, e, t, m)
+unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
+unsigned n; /* number of codes (assumed <= N_MAX) */
+unsigned s; /* number of simple-valued codes (0..s-1) */
+ush *d; /* list of base values for non-simple codes */
+ush *e; /* list of extra bits for non-simple codes */
+struct huft **t; /* result: starting table */
+int *m; /* maximum lookup bits, returns actual */
+/* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return zero on success, one if
+ the given code set is incomplete (the tables are still built in this
+ case), two if the input is invalid (all zero length codes or an
+ oversubscribed set of lengths), and three if not enough memory. */
+{
+ unsigned a; /* counter for codes of length k */
+ unsigned c[BMAX+1]; /* bit length count table */
+ unsigned f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ register unsigned i; /* counter, current code */
+ register unsigned j; /* counter */
+ register int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ register unsigned *p; /* pointer into c[], b[], or v[] */
+ register struct huft *q; /* points to current table */
+ struct huft r; /* table entry for structure assignment */
+ struct huft *u[BMAX]; /* table stack */
+ unsigned v[N_MAX]; /* values in order of bit length */
+ register int w; /* bits before this table == (l * h) */
+ unsigned x[BMAX+1]; /* bit offsets, then code stack */
+ unsigned *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ unsigned z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ memset(c, 0, sizeof(c));
+ p = b; i = n;
+ do {
+ c[*p++]++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (struct huft *)NULL;
+ *m = 0;
+ return 0;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ l = *m;
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if ((unsigned)l < j)
+ l = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if ((unsigned)l > i)
+ l = i;
+ *m = l;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return 2; /* bad input: more codes than bits */
+ if ((y -= c[i]) < 0)
+ return 2;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ p = b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = -l; /* bits decoded == (l * h) */
+ u[0] = (struct huft *)NULL; /* just to keep compilers happy */
+ q = (struct huft *)NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > w + l)
+ {
+ h++;
+ w += l; /* previous table always l bits */
+
+ /* compute minimum size table less than or equal to l bits */
+ z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ while (++j < z) /* try smaller tables up to z bits */
+ {
+ if ((f <<= 1) <= *++xp)
+ break; /* enough codes to use up j bits */
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ z = 1 << j; /* table entries for j-bit table */
+
+ /* allocate and link in new table */
+ if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
+ (struct huft *)NULL)
+ {
+ if (h)
+ huft_free(u[0]);
+ return 3; /* not enough memory */
+ }
+ hufts += z + 1; /* track memory usage */
+ *t = q + 1; /* link to list for huft_free() */
+ *(t = &(q->v.t)) = (struct huft *)NULL;
+ u[h] = ++q; /* table starts after link */
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.b = (uch)l; /* bits to dump before this table */
+ r.e = (uch)(16 + j); /* bits in this table */
+ r.v.t = q; /* pointer to this table */
+ j = i >> (w - l); /* (get around Turbo C bug) */
+ u[h-1][j] = r; /* connect to last table */
+ }
+ }
+
+ /* set up table entry in r */
+ r.b = (uch)(k - w);
+ if (p >= v + n)
+ r.e = 99; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
+ r.v.n = *p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.e = (uch)e[*p - s]; /* non-simple--look up in lists */
+ r.v.n = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ while ((i & ((1 << w) - 1)) != x[h])
+ {
+ h--; /* don't need to update q */
+ w -= l;
+ }
+ }
+ }
+
+
+ /* Return true (1) if we were given an incomplete table */
+ return y != 0 && g != 1;
+}
+
+
+int huft_free(t)
+struct huft *t; /* table to free */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+ list of the tables it made, with the links in a dummy first entry of
+ each table. */
+{
+ register struct huft *p, *q;
+
+
+ /* Go through linked list, freeing from the malloced (t[-1]) address. */
+ p = t;
+ while (p != (struct huft *)NULL)
+ {
+ q = (--p)->v.t;
+ free(p);
+ p = q;
+ }
+ return 0;
+}
+
+void flush(w)
+unsigned w; /* number of bytes to flush */
+/* Do the equivalent of OUTB for the bytes slide[0..w-1]. */
+{
+ memmove (pfile_in_zip_read_info->stream.next_out, slide, w);
+ pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ w);
+ pfile_in_zip_read_info->stream.next_out += w;
+ pfile_in_zip_read_info->stream.avail_out -= w;
+ pfile_in_zip_read_info->stream.total_out += w;
+}
+
+void flush_stack(w)
+unsigned w; /* number of bytes to flush */
+/* Do the equivalent of OUTB for the bytes slide[0..w-1]. */
+{
+ memmove (pfile_in_zip_read_info->stream.next_out, stack, w);
+ pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ w);
+ pfile_in_zip_read_info->stream.next_out += w;
+ pfile_in_zip_read_info->stream.avail_out -= w;
+ pfile_in_zip_read_info->stream.total_out += w;
+}
+
+/****************************/
+/* Function FillBitBuffer() */
+/****************************/
+
+int FillBitBuffer()
+{
+ /*
+ * Fill bitbuf, which is 32 bits. This function is only used by the
+ * READBIT and PEEKBIT macros (which are used by all of the uncompression
+ * routines).
+ */
+ UWORD temp;
+
+ zipeof = 1;
+ while (bits_left < 25 && ReadByte(&temp) == 8)
+ {
+ bitbuf |= (ULONG)temp << bits_left;
+ bits_left += 8;
+ zipeof = 0;
+ }
+ return 0;
+}
+
diff --git a/source/unzip/unreduce.c b/source/unzip/unreduce.c
new file mode 100644
index 0000000..e978746
--- /dev/null
+++ b/source/unzip/unreduce.c
@@ -0,0 +1,217 @@
+/*---------------------------------------------------------------------------
+
+ unreduce.c
+
+ The Reducing algorithm is actually a combination of two distinct algorithms.
+ The first algorithm compresses repeated byte sequences, and the second al-
+ gorithm takes the compressed stream from the first algorithm and applies a
+ probabilistic compression method.
+
+ ---------------------------------------------------------------------------*/
+
+
+#include "unz.h"
+#include "unzipP.h"
+
+/**************************************/
+/* UnReduce Defines, Typedefs, etc. */
+/**************************************/
+
+#define DLE 144
+
+typedef byte f_array[64]; /* for followers[256][64] */
+
+static void LoadFollowers ();
+void flush OF((unsigned)); /* routine from inflate.c */
+
+extern file_in_zip_read_info_s *pfile_in_zip_read_info;
+extern unz_s *pUnzip;
+
+/*******************************/
+/* UnReduce Global Variables */
+/*******************************/
+
+#if (defined(MACOS) || defined(MTS))
+ f_array *followers; /* shared work space */
+#else
+ f_array *followers = (f_array *) (slide + 0x4000);
+#endif
+
+byte Slen[256];
+int factor;
+
+int L_table[] =
+{0, 0x7f, 0x3f, 0x1f, 0x0f};
+
+int D_shift[] =
+{0, 0x07, 0x06, 0x05, 0x04};
+int D_mask[] =
+{0, 0x01, 0x03, 0x07, 0x0f};
+
+int B_table[] =
+{8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8};
+
+
+
+
+
+/*************************/
+/* Function unReduce() */
+/*************************/
+
+void unReduce() /* expand probabilistically reduced data */
+{
+ register int lchar = 0;
+ int nchar;
+ int ExState = 0;
+ int V = 0;
+ int Len = 0;
+ longint s = pUnzip->pfile_in_zip_read->rest_read_compressed;
+ unsigned w = 0; /* position in output window slide[] */
+ unsigned u = 1; /* true if slide[] unflushed */
+
+
+#if (defined(MACOS) || defined(MTS))
+ followers = (f_array *) (slide + 0x4000);
+#endif
+
+ factor = pUnzip->cur_file_info.compression_method;
+ LoadFollowers();
+
+ while (s > 0 /* && (!zipeof) */) {
+ if (Slen[lchar] == 0)
+ READBIT(8, nchar) /* ; */
+ else {
+ READBIT(1, nchar);
+ if (nchar != 0)
+ READBIT(8, nchar) /* ; */
+ else {
+ int follower;
+ int bitsneeded = B_table[Slen[lchar]];
+ READBIT(bitsneeded, follower);
+ nchar = followers[lchar][follower];
+ }
+ }
+ /* expand the resulting byte */
+ switch (ExState) {
+
+ case 0:
+ if (nchar != DLE) {
+ s--;
+ slide[w++] = (byte) nchar;
+ if (w == 0x4000) {
+ flush(w);
+ w = u = 0;
+ }
+ }
+ else
+ ExState = 1;
+ break;
+
+ case 1:
+ if (nchar != 0) {
+ V = nchar;
+ Len = V & L_table[factor];
+ if (Len == L_table[factor])
+ ExState = 2;
+ else
+ ExState = 3;
+ } else {
+ s--;
+ slide[w++] = DLE;
+ if (w == 0x4000)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ ExState = 0;
+ }
+ break;
+
+ case 2:{
+ Len += nchar;
+ ExState = 3;
+ }
+ break;
+
+ case 3:{
+ register unsigned e;
+ register unsigned n = Len + 3;
+ register unsigned d = w - ((((V >> D_shift[factor]) &
+ D_mask[factor]) << 8) + nchar + 1);
+
+ s -= n;
+ do {
+ n -= (e = (e = 0x4000 - ((d &= 0x3fff) > w ? d : w)) > n ?
+ n : e);
+ if (u && w <= d)
+ {
+ memset(slide + w, 0, e);
+ w += e;
+ d += e;
+ }
+ else
+ if (w - d < e) /* (assume unsigned comparison) */
+ do { /* slow to avoid memcpy() overlap */
+ slide[w++] = slide[d++];
+ } while (--e);
+ else
+ {
+ memcpy(slide + w, slide + d, e);
+ w += e;
+ d += e;
+ }
+ if (w == 0x4000)
+ {
+ flush(w);
+ w = u = 0;
+ }
+ } while (n);
+
+ ExState = 0;
+ }
+ break;
+ }
+
+ /* store character for next iteration */
+ lchar = nchar;
+ }
+
+ /* flush out slide */
+ flush(w);
+}
+
+
+
+
+
+/******************************/
+/* Function LoadFollowers() */
+/******************************/
+
+static void LoadFollowers()
+{
+ register int x;
+ register int i;
+
+ for (x = 255; x >= 0; x--) {
+ READBIT(6, Slen[x]);
+ for (i = 0; (byte) i < Slen[x]; i++) {
+ READBIT(8, followers[x][i]);
+ }
+ }
+}
diff --git a/source/unzip/unshrink.c b/source/unzip/unshrink.c
new file mode 100644
index 0000000..6deb4d4
--- /dev/null
+++ b/source/unzip/unshrink.c
@@ -0,0 +1,177 @@
+/*---------------------------------------------------------------------------
+
+ unshrink.c
+
+ Shrinking is a Dynamic Lempel-Ziv-Welch compression algorithm with partial
+ clearing.
+
+ ---------------------------------------------------------------------------*/
+
+
+#include "unz.h"
+void flush_stack (int);
+
+/*************************************/
+/* UnShrink Defines, Globals, etc. */
+/*************************************/
+
+/* MAX_BITS 13 (in unzip.h; defines size of global work area) */
+#define INIT_BITS 9
+#define FIRST_ENT 257
+#define CLEAR 256
+#define GetCode(dest) READBIT(codesize,dest)
+
+static void partial_clear ();
+
+int codesize, maxcode, maxcodemax, free_ent;
+
+
+
+
+/*************************/
+/* Function unShrink() */
+/*************************/
+
+void unShrink()
+{
+ register int code;
+ register int stackp;
+ int finchar;
+ int oldcode;
+ int incode;
+
+
+ /* decompress the file */
+ codesize = INIT_BITS;
+ maxcode = (1 << codesize) - 1;
+ maxcodemax = HSIZE; /* (1 << MAX_BITS) */
+ free_ent = FIRST_ENT;
+
+ code = maxcodemax;
+ do {
+ prefix_of[code] = -1;
+ } while (--code > 255);
+/*
+ OvdL: -Ox with SCO's 3.2.0 cc gives
+ a. warning: overflow in constant multiplication
+ b. segmentation fault (core dumped) when using the executable
+ for (code = maxcodemax; code > 255; code--)
+ prefix_of[code] = -1;
+ */
+
+ for (code = 255; code >= 0; code--) {
+ prefix_of[code] = 0;
+ suffix_of[code] = (byte) code;
+ }
+
+ GetCode(oldcode);
+ if (zipeof)
+ return;
+ finchar = oldcode;
+
+ stack[0] = finchar;
+ flush_stack (1);
+
+ stackp = HSIZE;
+
+ while (!zipeof) {
+ GetCode(code);
+ if (zipeof)
+ return;
+
+ while (code == CLEAR) {
+ GetCode(code);
+ switch (code) {
+ case 1:
+ codesize++;
+ if (codesize == MAX_BITS)
+ maxcode = maxcodemax;
+ else
+ maxcode = (1 << codesize) - 1;
+ break;
+
+ case 2:
+ partial_clear();
+ break;
+ }
+
+ GetCode(code);
+ if (zipeof)
+ return;
+ }
+
+
+ /* special case for KwKwK string */
+ incode = code;
+ if (prefix_of[code] == -1) {
+ stack[--stackp] = (byte) finchar;
+ code = oldcode;
+ }
+ /* generate output characters in reverse order */
+ while (code >= FIRST_ENT) {
+ if (prefix_of[code] == -1) {
+ stack[--stackp] = (byte) finchar;
+ code = oldcode;
+ } else {
+ stack[--stackp] = suffix_of[code];
+ code = prefix_of[code];
+ }
+ }
+
+ finchar = suffix_of[code];
+ stack[--stackp] = (byte) finchar;
+
+ /* and put them out in forward order, block copy */
+ flush_stack (HSIZE - stackp);
+ stackp = HSIZE;
+
+ /* generate new entry */
+ code = free_ent;
+ if (code < maxcodemax) {
+ prefix_of[code] = oldcode;
+ suffix_of[code] = (byte) finchar;
+
+ do
+ code++;
+ while ((code < maxcodemax) && (prefix_of[code] != -1));
+
+ free_ent = code;
+ }
+ /* remember previous code */
+ oldcode = incode;
+ }
+}
+
+
+
+/******************************/
+/* Function partial_clear() */
+/******************************/
+
+static void partial_clear()
+{
+ register int pr;
+ register int cd;
+
+ /* mark all nodes as potentially unused */
+ for (cd = FIRST_ENT; cd < free_ent; cd++)
+ prefix_of[cd] |= 0x8000;
+
+ /* unmark those that are used by other nodes */
+ for (cd = FIRST_ENT; cd < free_ent; cd++) {
+ pr = prefix_of[cd] & 0x7fff; /* reference to another node? */
+ if (pr >= FIRST_ENT) /* flag node as referenced */
+ prefix_of[pr] &= 0x7fff;
+ }
+
+ /* clear the ones that are still marked */
+ for (cd = FIRST_ENT; cd < free_ent; cd++)
+ if ((prefix_of[cd] & 0x8000) != 0)
+ prefix_of[cd] = -1;
+
+ /* find first cleared node as next free_ent */
+ cd = FIRST_ENT;
+ while ((cd < maxcodemax) && (prefix_of[cd] != -1))
+ cd++;
+ free_ent = cd;
+}
diff --git a/source/unzip/unz.h b/source/unzip/unz.h
new file mode 100644
index 0000000..1ea7478
--- /dev/null
+++ b/source/unzip/unz.h
@@ -0,0 +1,994 @@
+/*---------------------------------------------------------------------------
+
+ unzip.h
+
+ This header file is used by all of the unzip source files. Its contents
+ are divided into seven more-or-less separate sections: predefined macros,
+ OS-dependent includes, (mostly) OS-independent defines, typedefs, function
+ prototypes (or "prototypes," in the case of non-ANSI compilers), macros,
+ and global-variable declarations.
+
+ ---------------------------------------------------------------------------*/
+
+#include "zlib.h"
+
+/*****************************************/
+/* Predefined, Machine-specific Macros */
+/*****************************************/
+
+#if (defined(__GO32__) && defined(unix)) /* DOS extender */
+# undef unix
+#endif
+
+#if defined(unix) || defined(__convexc__) || defined(M_XENIX)
+# ifndef UNIX
+# define UNIX
+# endif /* !UNIX */
+#endif /* unix || __convexc__ || M_XENIX */
+
+/* Much of the following is swiped from zip's tailor.h: */
+
+/* define MSDOS for Turbo C (unless OS/2) and Power C as well as Microsoft C */
+#ifdef __POWERC
+# define __TURBOC__
+# define MSDOS
+#endif /* __POWERC */
+#if (defined(__TURBOC__) && defined(__MSDOS__) && !defined(MSDOS))
+# define MSDOS
+#endif
+
+/* use prototypes and ANSI libraries if __STDC__, or Microsoft or Borland C,
+ * or Silicon Graphics, or Convex, or IBM C Set/2, or GNU gcc under emx, or
+ * or Watcom C, or Macintosh, or Windows NT.
+ */
+#if (__STDC__ || defined(MSDOS) || defined(sgi) || defined(CONVEX) || defined(__sun))
+# ifndef PROTO
+# define PROTO
+# endif
+# define MODERN
+#endif
+#if (defined(__IBMC__) || defined(__EMX__) || defined(__WATCOMC__))
+# ifndef PROTO
+# define PROTO
+# endif
+# define MODERN
+#endif
+#if (defined(THINK_C) || defined(MPW) || defined(WIN32))
+# ifndef PROTO
+# define PROTO
+# endif
+# define MODERN
+#endif
+
+/* turn off prototypes if requested */
+#if (defined(NOPROTO) && defined(PROTO))
+# undef PROTO
+#endif
+
+#if (defined(ultrix) || defined(bsd4_2) || defined(sun) || defined(pyr))
+# if (!defined(BSD) && !defined(__SYSTEM_FIVE) && !defined(SYSV))
+# define BSD
+# endif /* !BSD && !__SYSTEM_FIVE && !SYSV */
+#endif /* ultrix || bsd4_2 || sun || pyr */
+
+#if (defined(CONVEX) || defined(CRAY) || defined(__SYSTEM_FIVE))
+# ifndef TERMIO
+# define TERMIO
+# endif /* !TERMIO */
+#endif /* CONVEX || CRAY || __SYSTEM_FIVE */
+
+#ifdef pyr /* Pyramid */
+# ifndef ZMEM
+# define ZMEM
+# endif /* !ZMEM */
+#endif /* pyr */
+
+#ifdef CRAY
+# ifdef ZMEM
+# undef ZMEM
+# endif /* ZMEM */
+#endif /* CRAY */
+
+/* the i386 test below is to catch SCO Unix (which has redefinition
+ * warnings if param.h is included), but it probably doesn't hurt if
+ * other 386 Unixes get nailed, too...except now that 386BSD and BSDI
+ * exist. Sigh. <sys/param.h> is mostly included for "BSD", I think.
+ * [An alternate fix for SCO Unix is below.]
+ */
+#if (defined(MINIX) || (defined(i386) && defined(unix)))
+# define NO_PARAM_H
+#endif /* MINIX || (i386 && unix) */
+
+
+
+
+
+/***************************/
+/* OS-Dependent Includes */
+/***************************/
+
+#ifndef MINIX /* Minix needs it after all the other includes (?) */
+# include <stdio.h>
+#endif
+#include <ctype.h> /* skip for VMS, to use tolower() function? */
+#include <errno.h> /* used in mapname() */
+#ifndef NO_ERRNO
+# define DECLARE_ERRNO /* everybody except MSC 6.0, SCO cc, Watcom C/386 */
+#endif /* !NO_ERRNO */
+#ifdef VMS
+# include <types.h> /* (placed up here instead of in VMS section below */
+# include <stat.h> /* because types.h is used in some other headers) */
+#else /* !VMS */
+# if !defined(THINK_C) && !defined(MPW)
+# include <sys/types.h> /* off_t, time_t, dev_t, ... */
+# include <sys/stat.h>
+# endif /* !THINK_C && !MPW */
+#endif /* ?VMS */
+
+#ifdef MODERN
+# if (!defined(M_XENIX) && !(defined(__GNUC__) && defined(sun)))
+# include <stddef.h>
+# endif
+# if (!defined(__GNUC__) && !defined(apollo)) /* both define __STDC__ */
+# include <stdlib.h> /* standard library prototypes, malloc(), etc. */
+# else
+# ifdef __EMX__
+# include <stdlib.h> /* emx IS gcc but has stdlib.h */
+# endif
+# endif
+# include <string.h> /* defines strcpy, strcmp, memcpy, etc. */
+ typedef size_t extent;
+#else /* !MODERN */
+ char *malloc();
+ char *strchr(), *strrchr();
+ long lseek();
+ typedef unsigned int extent;
+# define void int
+#endif /* ?MODERN */
+
+/* this include must be down here for SysV.4, for some reason... */
+#include <signal.h> /* used in unzip.c, file_io.c */
+
+
+
+/*---------------------------------------------------------------------------
+ Next, a word from our Unix (mostly) sponsors:
+ ---------------------------------------------------------------------------*/
+
+#ifdef UNIX
+# ifdef AMIGA
+# include <libraries/dos.h>
+# else /* !AMIGA */
+# ifndef NO_PARAM_H
+#if 0 /* [GRR: this is an alternate fix for SCO's redefinition bug] */
+# ifdef NGROUPS_MAX
+# undef NGROUPS_MAX /* SCO bug: defined again in <param.h> */
+# endif /* NGROUPS_MAX */
+#endif /* 0 */
+# include <sys/param.h> /* conflict with <sys/types.h>, some systems? */
+# endif /* !NO_PARAM_H */
+# endif /* ?AMIGA */
+
+# ifndef BSIZE
+# ifdef MINIX
+# define BSIZE 1024
+# else /* !MINIX */
+# define BSIZE DEV_BSIZE /* assume common for all Unix systems */
+# endif /* ?MINIX */
+# endif
+
+# ifndef BSD
+# if (!defined(AMIGA) && !defined(MINIX))
+# define NO_MKDIR /* for mapname() */
+# endif /* !AMIGA && !MINIX */
+# include <time.h>
+ struct tm *gmtime(), *localtime();
+# else /* BSD */
+# include <sys/time.h>
+# include <sys/timeb.h>
+# ifdef _AIX
+# include <time.h>
+# endif
+# endif
+
+#else /* !UNIX */
+# define BSIZE 512 /* disk block size */
+#endif /* ?UNIX */
+
+#if (defined(V7) || defined(BSD))
+# define strchr index
+# define strrchr rindex
+#endif
+
+/*---------------------------------------------------------------------------
+ And now, our MS-DOS and OS/2 corner:
+ ---------------------------------------------------------------------------*/
+
+#ifdef __TURBOC__
+# define DOS_OS2
+# include <sys/timeb.h> /* for structure ftime */
+# ifndef __BORLANDC__ /* there appears to be a bug (?) in Borland's */
+# include <mem.h> /* MEM.H related to __STDC__ and far poin- */
+# endif /* ters. (dpk) [mem.h included for memcpy] */
+# include <dos.h> /* for REGS macro (at least for Turbo C 2.0) */
+#else /* NOT Turbo C (or Power C)... */
+# ifdef MSDOS /* but still MS-DOS, so we'll assume it's */
+# ifndef MSC /* Microsoft's compiler and fake the ID, if */
+# define MSC /* necessary (it is in 5.0; apparently not */
+# endif /* in 5.1 and 6.0) */
+# include <dos.h> /* for _dos_setftime() */
+# endif
+#endif
+
+#if (defined(__IBMC__) && defined(__OS2__))
+# define DOS_OS2
+# define S_IFMT 0xF000
+# define timezone _timezone
+#endif
+
+#ifdef __WATCOMC__
+# define DOS_OS2
+# define __32BIT__
+# ifdef DECLARE_ERRNO
+# undef DECLARE_ERRNO
+# endif
+# undef far
+# define far
+#endif
+
+#ifdef __EMX__
+# define DOS_OS2
+# define __32BIT__
+# define far
+#endif /* __EMX__ */
+
+#ifdef MSC /* defined for all versions of MSC now */
+# define DOS_OS2 /* Turbo C under DOS, MSC under DOS or OS/2 */
+# if (defined(_MSC_VER) && (_MSC_VER >= 600)) /* new with 5.1 or 6.0 ... */
+# undef DECLARE_ERRNO /* errno is now a function in a dynamic link */
+# endif /* library (or something)--incompatible with */
+#endif /* the usual "extern int errno" declaration */
+
+#ifdef DOS_OS2 /* defined for all MS-DOS and OS/2 compilers */
+# include <io.h> /* lseek(), open(), setftime(), dup(), creat() */
+# include <time.h> /* localtime() */
+#endif
+
+#ifdef OS2 /* defined for all OS/2 compilers */
+# ifdef isupper
+# undef isupper
+# endif
+# ifdef tolower
+# undef tolower
+# endif
+# define isupper(x) IsUpperNLS((unsigned char)(x))
+# define tolower(x) ToLowerNLS((unsigned char)(x))
+#endif
+
+#ifdef WIN32
+# include <io.h> /* read(), open(), etc. */
+# include <time.h>
+# include <memory.h>
+# include <direct.h> /* mkdir() */
+# ifdef FILE_IO_C
+# include <fcntl.h>
+# include <conio.h>
+# include <sys\types.h>
+# include <sys\utime.h>
+# include <windows.h>
+# define DOS_OS2
+# define getch() getchar()
+# endif
+#endif
+
+/*---------------------------------------------------------------------------
+ Followed by some VMS (mostly) stuff:
+ ---------------------------------------------------------------------------*/
+
+#ifdef VMS
+# include <time.h> /* the usual non-BSD time functions */
+# include <file.h> /* same things as fcntl.h has */
+# include <rms.h>
+# define _MAX_PATH NAM$C_MAXRSS /* to define FILNAMSIZ below */
+# define UNIX /* can share most of same code from now on */
+# define RETURN return_VMS /* VMS interprets return codes incorrectly */
+#else /* !VMS */
+# ifndef THINK_C
+# define RETURN return /* only used in main() */
+# else
+# define RETURN(v) { int n;\
+ n = (v);\
+ fprintf(stderr, "\npress <return> to continue ");\
+ while (getc(stdin) != '\n');\
+ putc('\n', stderr);\
+ InitCursor();\
+ goto start;\
+ }
+# endif
+# ifdef V7
+# define O_RDONLY 0
+# define O_WRONLY 1
+# define O_RDWR 2
+# else /* !V7 */
+# ifdef MTS
+# include <sys/file.h> /* MTS uses this instead of fcntl.h */
+# include <timeb.h>
+# include <time.h>
+# else /* !MTS */
+# ifdef COHERENT /* Coherent 3.10/Mark Williams C */
+# include <sys/fcntl.h>
+# define SHORT_NAMES
+# define tzset settz
+# else /* !COHERENT */
+# include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */
+# endif /* ?COHERENT */
+# endif /* ?MTS */
+# endif /* ?V7 */
+#endif /* ?VMS */
+
+#if (defined(MSDOS) || defined(VMS))
+# define DOS_VMS
+#endif
+
+/*---------------------------------------------------------------------------
+ And some Mac stuff for good measure:
+ ---------------------------------------------------------------------------*/
+
+#ifdef THINK_C
+# define MACOS
+# ifndef __STDC__ /* if Think C hasn't defined __STDC__ ... */
+# define __STDC__ 1 /* make sure it's defined: it needs it */
+# else /* __STDC__ defined */
+# if !__STDC__ /* sometimes __STDC__ is defined as 0; */
+# undef __STDC__ /* it needs to be 1 or required header */
+# define __STDC__ 1 /* files are not properly included. */
+# endif /* !__STDC__ */
+# endif /* ?defined(__STDC__) */
+#endif /* THINK_C */
+
+#ifdef MPW
+# define MACOS
+# include <Errors.h>
+# include <Files.h>
+# include <Memory.h>
+# include <Quickdraw.h>
+# include <ToolUtils.h>
+# define CtoPstr c2pstr
+# define PtoCstr p2cstr
+# ifdef CR
+# undef CR
+# endif
+#endif /* MPW */
+
+#ifdef MACOS
+# define open(x,y) macopen(x,y, gnVRefNum, glDirID)
+# define close macclose
+# define read macread
+# define write macwrite
+# define lseek maclseek
+# define creat(x,y) maccreat(x, gnVRefNum, glDirID, gostCreator, gostType)
+# define stat(x,y) macstat(x,y,gnVRefNum, glDirID)
+
+# ifndef isascii
+# define isascii(c) ((unsigned char)(c) <= 0x3F)
+# endif
+
+# include "macstat.h"
+
+typedef struct _ZipExtraHdr {
+ unsigned short header; /* 2 bytes */
+ unsigned short data; /* 2 bytes */
+} ZIP_EXTRA_HEADER;
+
+typedef struct _MacInfoMin {
+ unsigned short header; /* 2 bytes */
+ unsigned short data; /* 2 bytes */
+ unsigned long signature; /* 4 bytes */
+ FInfo finfo; /* 16 bytes */
+ unsigned long lCrDat; /* 4 bytes */
+ unsigned long lMdDat; /* 4 bytes */
+ unsigned long flags ; /* 4 bytes */
+ unsigned long lDirID; /* 4 bytes */
+ /*------------*/
+} MACINFOMIN; /* = 40 bytes for size of data */
+
+typedef struct _MacInfo {
+ unsigned short header; /* 2 bytes */
+ unsigned short data; /* 2 bytes */
+ unsigned long signature; /* 4 bytes */
+ FInfo finfo; /* 16 bytes */
+ unsigned long lCrDat; /* 4 bytes */
+ unsigned long lMdDat; /* 4 bytes */
+ unsigned long flags ; /* 4 bytes */
+ unsigned long lDirID; /* 4 bytes */
+ char rguchVolName[28]; /* 28 bytes */
+ /*------------*/
+} MACINFO; /* = 68 bytes for size of data */
+#endif /* MACOS */
+
+/*---------------------------------------------------------------------------
+ And finally, some random extra stuff:
+ ---------------------------------------------------------------------------*/
+
+#ifdef MINIX
+# include <stdio.h>
+#endif
+
+#ifdef SHORT_NAMES /* Mark Williams C, ...? */
+# define extract_or_test_files xtr_or_tst_files
+# define extract_or_test_member xtr_or_tst_member
+#endif
+
+#ifdef MTS
+# include <unix.h> /* Some important non-ANSI routines */
+# define mkdir(s,n) (-1) /* No "make directory" capability */
+# define EBCDIC /* Set EBCDIC conversion on */
+#endif
+
+
+
+
+
+/*************/
+/* Defines */
+/*************/
+
+#ifndef WSIZE
+# define WSIZE 0x8000 /* window size--must be a power of two, and */
+#endif /* !WSIZE */ /* at least 32K for zip's deflate method */
+
+#define DIR_BLKSIZ 64 /* number of directory entries per block
+ * (should fit in 4096 bytes, usually) */
+#ifndef INBUFSIZ
+# define INBUFSIZ 2048 /* works for MS-DOS small model */
+#endif /* !INBUFSIZ */
+
+/*
+ * If <limits.h> exists on most systems, should include that, since it may
+ * define some or all of the following: NAME_MAX, PATH_MAX, _POSIX_NAME_MAX,
+ * _POSIX_PATH_MAX.
+ */
+#ifdef DOS_OS2
+# include <limits.h>
+#endif /* DOS_OS2 */
+
+#ifdef _MAX_PATH
+# define FILNAMSIZ (_MAX_PATH)
+#else /* !_MAX_PATH */
+# define FILNAMSIZ 1025
+#endif /* ?_MAX_PATH */
+
+#ifndef PATH_MAX
+# ifdef MAXPATHLEN /* defined in <sys/param.h> some systems */
+# define PATH_MAX MAXPATHLEN
+# else
+# if FILENAME_MAX > 255 /* used like PATH_MAX on some systems */
+# define PATH_MAX FILENAME_MAX
+# else
+# define PATH_MAX (FILNAMSIZ - 1)
+# endif
+# endif /* ?MAXPATHLEN */
+#endif /* !PATH_MAX */
+
+#define OUTBUFSIZ INBUFSIZ
+
+#define ZSUFX ".zip"
+#define CENTRAL_HDR_SIG "\113\001\002" /* the infamous "PK" signature */
+#define LOCAL_HDR_SIG "\113\003\004" /* bytes, sans "P" (so unzip */
+#define END_CENTRAL_SIG "\113\005\006" /* executable not mistaken for */
+#define EXTD_LOCAL_SIG "\113\007\010" /* zipfile itself) */
+
+#define SKIP 0 /* choice of activities for do_string() */
+#define DISPLAY 1
+#define FILENAME 2
+#define EXTRA_FIELD 3
+
+#define DOES_NOT_EXIST -1 /* return values for check_for_newer() */
+#define EXISTS_AND_OLDER 0
+#define EXISTS_AND_NEWER 1
+
+#define DOS_OS2_FAT_ 0 /* version_made_by codes (central dir) */
+#define AMIGA_ 1
+#define VMS_ 2 /* make sure these are not defined on */
+#define UNIX_ 3 /* the respective systems!! (like, for */
+#define VM_CMS_ 4 /* instance, "VMS", or "UNIX": CFLAGS = */
+#define ATARI_ 5 /* -O -DUNIX) */
+#define OS2_HPFS_ 6
+#define MAC_ 7
+#define Z_SYSTEM_ 8
+#define CPM_ 9
+/* #define TOPS20_ 10? (TOPS20_ is to be defined in PKZIP 2.0...) */
+#define NUM_HOSTS 10 /* index of last system + 1 */
+
+#define STORED 0 /* compression methods */
+#define SHRUNK 1
+#define REDUCED1 2
+#define REDUCED2 3
+#define REDUCED3 4
+#define REDUCED4 5
+#define IMPLODED 6
+#define TOKENIZED 7
+#define DEFLATED 8
+#define NUM_METHODS 9 /* index of last method + 1 */
+/* don't forget to update list_files() appropriately if NUM_METHODS changes */
+
+#define DF_MDY 0 /* date format 10/26/91 (USA only) */
+#define DF_DMY 1 /* date format 26/10/91 (most of the world) */
+#define DF_YMD 2 /* date format 91/10/26 (a few countries) */
+
+#define UNZIP_VERSION 20 /* compatible with PKUNZIP 2.0 */
+#define VMS_VERSION 42 /* if OS-needed-to-extract is VMS: can do */
+
+/*---------------------------------------------------------------------------
+ True sizes of the various headers, as defined by PKWare--so it is not
+ likely that these will ever change. But if they do, make sure both these
+ defines AND the typedefs below get updated accordingly.
+ ---------------------------------------------------------------------------*/
+#define LREC_SIZE 26 /* lengths of local file headers, central */
+#define CREC_SIZE 42 /* directory headers, and the end-of- */
+#define ECREC_SIZE 18 /* central-dir record, respectively */
+
+#define MAX_BITS 13 /* used in unShrink() */
+#define HSIZE (1 << MAX_BITS) /* size of global work area */
+
+#define LF 10 /* '\n' on ASCII machines. Must be 10 due to EBCDIC */
+#define CR 13 /* '\r' on ASCII machines. Must be 13 due to EBCDIC */
+#define CTRLZ 26 /* DOS & OS/2 EOF marker (used in file_io.c, vms.c) */
+
+#ifdef EBCDIC
+# define ascii_to_native(c) ebcdic[(c)]
+# define NATIVE "EBCDIC"
+#endif
+
+#if MPW
+# define FFLUSH putc('\n',stderr);
+#else /* !MPW */
+# define FFLUSH fflush(stderr);
+#endif /* ?MPW */
+
+#ifdef VMS
+# define ENV_UNZIP "UNZIP_OPTS" /* name of environment variable */
+# define ENV_ZIPINFO "ZIPINFO_OPTS"
+#else /* !VMS */
+# define ENV_UNZIP "UNZIP"
+# define ENV_ZIPINFO "ZIPINFO"
+#endif /* ?VMS */
+
+#ifdef CRYPT
+# define PWLEN 80
+# define DECRYPT(b) (update_keys(t=((b)&0xff)^decrypt_byte()),t)
+#endif /* CRYPT */
+
+#ifdef QQ /* Newtware version */
+# define QCOND (!quietflg) /* for no file comments with -vq or -vqq */
+#else /* (original) Bill Davidsen version */
+# define QCOND (which_hdr) /* no way to kill file comments with -v, -l */
+#endif
+
+#ifndef TRUE
+# define TRUE 1 /* sort of obvious */
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef SEEK_SET /* These should all be declared in stdio.h! But */
+# define SEEK_SET 0 /* since they're not (in many cases), do so here. */
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+
+#ifndef S_IRUSR
+# define S_IRWXU 00700 /* read, write, execute: owner */
+# define S_IRUSR 00400 /* read permission: owner */
+# define S_IWUSR 00200 /* write permission: owner */
+# define S_IXUSR 00100 /* execute permission: owner */
+# define S_IRWXG 00070 /* read, write, execute: group */
+# define S_IRGRP 00040 /* read permission: group */
+# define S_IWGRP 00020 /* write permission: group */
+# define S_IXGRP 00010 /* execute permission: group */
+# define S_IRWXO 00007 /* read, write, execute: other */
+# define S_IROTH 00004 /* read permission: other */
+# define S_IWOTH 00002 /* write permission: other */
+# define S_IXOTH 00001 /* execute permission: other */
+#endif /* !S_IRUSR */
+
+#ifdef ZIPINFO /* these are individually checked because SysV doesn't */
+# ifndef S_IFBLK /* have some of them, Microsoft C others, etc. */
+# define S_IFBLK 0060000 /* block special */
+# endif
+# ifndef S_IFIFO /* in Borland C, not MSC */
+# define S_IFIFO 0010000 /* fifo */
+# endif
+# ifndef S_IFLNK /* in BSD, not SysV */
+# define S_IFLNK 0120000 /* symbolic link */
+# endif
+# ifndef S_IFSOCK /* in BSD, not SysV */
+# define S_IFSOCK 0140000 /* socket */
+# endif
+# ifndef S_ISUID
+# define S_ISUID 04000 /* set user id on execution */
+# endif
+# ifndef S_ISGID
+# define S_ISGID 02000 /* set group id on execution */
+# endif
+# ifndef S_ISVTX
+# define S_ISVTX 01000 /* directory permissions control */
+# endif
+# ifndef S_ENFMT
+# define S_ENFMT S_ISGID /* record locking enforcement flag */
+# endif
+#endif /* ZIPINFO */
+
+
+
+
+
+/**************/
+/* Typedefs */
+/**************/
+
+#ifndef _BULL_SOURCE /* Bull has it defined somewhere already */
+ typedef unsigned char byte; /* code assumes UNSIGNED bytes */
+#endif /* !_BULL_SOURCE */
+
+typedef char boolean;
+typedef long longint;
+typedef unsigned short UWORD;
+typedef unsigned long ULONG;
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+typedef struct min_info {
+ unsigned unix_attr;
+ unsigned dos_attr;
+ int hostnum;
+ longint offset;
+ ULONG compr_size; /* compressed size (needed if extended header) */
+ ULONG crc; /* crc (needed if extended header) */
+ unsigned encrypted : 1; /* file encrypted: decrypt before uncompressing */
+ unsigned ExtLocHdr : 1; /* use time instead of CRC for decrypt check */
+ unsigned text : 1; /* file is text or binary */
+ unsigned lcflag : 1; /* convert filename to lowercase */
+} min_info;
+
+typedef struct VMStimbuf {
+ char *revdate; /* (both correspond to Unix modtime/st_mtime) */
+ char *credate;
+} VMStimbuf;
+
+/*---------------------------------------------------------------------------
+ Zipfile layout declarations. If these headers ever change, make sure the
+ xxREC_SIZE defines (above) change with them!
+ ---------------------------------------------------------------------------*/
+
+ typedef byte local_byte_hdr[ LREC_SIZE ];
+# define L_VERSION_NEEDED_TO_EXTRACT_0 0
+# define L_VERSION_NEEDED_TO_EXTRACT_1 1
+# define L_GENERAL_PURPOSE_BIT_FLAG 2
+# define L_COMPRESSION_METHOD 4
+# define L_LAST_MOD_FILE_TIME 6
+# define L_LAST_MOD_FILE_DATE 8
+# define L_CRC32 10
+# define L_COMPRESSED_SIZE 14
+# define L_UNCOMPRESSED_SIZE 18
+# define L_FILENAME_LENGTH 22
+# define L_EXTRA_FIELD_LENGTH 24
+
+ typedef byte cdir_byte_hdr[ CREC_SIZE ];
+# define C_VERSION_MADE_BY_0 0
+# define C_VERSION_MADE_BY_1 1
+# define C_VERSION_NEEDED_TO_EXTRACT_0 2
+# define C_VERSION_NEEDED_TO_EXTRACT_1 3
+# define C_GENERAL_PURPOSE_BIT_FLAG 4
+# define C_COMPRESSION_METHOD 6
+# define C_LAST_MOD_FILE_TIME 8
+# define C_LAST_MOD_FILE_DATE 10
+# define C_CRC32 12
+# define C_COMPRESSED_SIZE 16
+# define C_UNCOMPRESSED_SIZE 20
+# define C_FILENAME_LENGTH 24
+# define C_EXTRA_FIELD_LENGTH 26
+# define C_FILE_COMMENT_LENGTH 28
+# define C_DISK_NUMBER_START 30
+# define C_INTERNAL_FILE_ATTRIBUTES 32
+# define C_EXTERNAL_FILE_ATTRIBUTES 34
+# define C_RELATIVE_OFFSET_LOCAL_HEADER 38
+
+ typedef byte ec_byte_rec[ ECREC_SIZE+4 ];
+/* define SIGNATURE 0 space-holder only */
+# define NUMBER_THIS_DISK 4
+# define NUM_DISK_WITH_START_CENTRAL_DIR 6
+# define NUM_ENTRIES_CENTRL_DIR_THS_DISK 8
+# define TOTAL_ENTRIES_CENTRAL_DIR 10
+# define SIZE_CENTRAL_DIRECTORY 12
+# define OFFSET_START_CENTRAL_DIRECTORY 16
+# define ZIPFILE_COMMENT_LENGTH 20
+
+
+ typedef struct local_file_header { /* LOCAL */
+ byte version_needed_to_extract[2];
+ UWORD general_purpose_bit_flag;
+ UWORD compression_method;
+ UWORD last_mod_file_time;
+ UWORD last_mod_file_date;
+ ULONG crc32;
+ ULONG compressed_size;
+ ULONG uncompressed_size;
+ UWORD filename_length;
+ UWORD extra_field_length;
+ } local_file_hdr;
+
+ typedef struct central_directory_file_header { /* CENTRAL */
+ byte version_made_by[2];
+ byte version_needed_to_extract[2];
+ UWORD general_purpose_bit_flag;
+ UWORD compression_method;
+ UWORD last_mod_file_time;
+ UWORD last_mod_file_date;
+ ULONG crc32;
+ ULONG compressed_size;
+ ULONG uncompressed_size;
+ UWORD filename_length;
+ UWORD extra_field_length;
+ UWORD file_comment_length;
+ UWORD disk_number_start;
+ UWORD internal_file_attributes;
+ ULONG external_file_attributes;
+ ULONG relative_offset_local_header;
+ } cdir_file_hdr;
+
+ typedef struct end_central_dir_record { /* END CENTRAL */
+ UWORD number_this_disk;
+ UWORD num_disk_with_start_central_dir;
+ UWORD num_entries_centrl_dir_ths_disk;
+ UWORD total_entries_central_dir;
+ ULONG size_central_directory;
+ ULONG offset_start_central_directory;
+ UWORD zipfile_comment_length;
+ } ecdir_rec;
+
+
+
+
+
+/*************************/
+/* Function Prototypes */
+/*************************/
+
+#ifndef __
+# define __ OF
+#endif
+
+/*---------------------------------------------------------------------------
+ Decompression functions:
+ ---------------------------------------------------------------------------*/
+
+int explode ();
+void unReduce ();
+void unShrink ();
+
+/*---------------------------------------------------------------------------
+ Functions in file_io.c and crypt.c:
+ ---------------------------------------------------------------------------*/
+
+int FillBitBuffer ();
+int ReadByte __((UWORD *x)); /* file_io.c */
+
+/************/
+/* Macros */
+/************/
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+#define LSEEK(abs_offset) {longint request=(abs_offset)+extra_bytes,\
+ inbuf_offset=request%INBUFSIZ, bufstart=request-inbuf_offset;\
+ if(request<0) {fprintf(stderr, SeekMsg, ReportMsg); return(3);}\
+ else if(bufstart!=cur_zipfile_bufstart)\
+ {cur_zipfile_bufstart=lseek(zipfd,bufstart,SEEK_SET);\
+ if((incnt=read(zipfd,(char *)inbuf,INBUFSIZ))<=0) return(51);\
+ inptr=inbuf+(int)inbuf_offset; incnt-=(int)inbuf_offset;} else\
+ {incnt+=(inptr-inbuf)-(int)inbuf_offset; inptr=inbuf+(int)inbuf_offset;}}
+
+/*
+ * Seek to the block boundary of the block which includes abs_offset,
+ * then read block into input buffer and set pointers appropriately.
+ * If block is already in the buffer, just set the pointers. This macro
+ * is used by process_end_central_dir (unzip.c) and do_string (misc.c).
+ * A slightly modified version is embedded within extract_or_test_files
+ * (unzip.c). ReadByte and readbuf (file_io.c) are compatible.
+ *
+ * macro LSEEK(abs_offset)
+ * ULONG abs_offset;
+ * {
+ * longint request = abs_offset + extra_bytes;
+ * longint inbuf_offset = request % INBUFSIZ;
+ * longint bufstart = request - inbuf_offset;
+ *
+ * if (request < 0) {
+ * fprintf(stderr, SeekMsg, ReportMsg);
+ * return(3); /-* 3: severe error in zipfile *-/
+ * } else if (bufstart != cur_zipfile_bufstart) {
+ * cur_zipfile_bufstart = lseek(zipfd, bufstart, SEEK_SET);
+ * if ((incnt = read(zipfd,inbuf,INBUFSIZ)) <= 0)
+ * return(51); /-* 51: unexpected EOF *-/
+ * inptr = inbuf + (int)inbuf_offset;
+ * incnt -= (int)inbuf_offset;
+ * } else {
+ * incnt += (inptr-inbuf) - (int)inbuf_offset;
+ * inptr = inbuf + (int)inbuf_offset;
+ * }
+ * }
+ *
+ */
+
+
+#define SKIP_(length) if(length&&((error=do_string(length,SKIP))!=0))\
+ {error_in_archive=error; if(error>1) return error;}
+
+/*
+ * Skip a variable-length field, and report any errors. Used in zipinfo.c
+ * and unzip.c in several functions.
+ *
+ * macro SKIP_(length)
+ * UWORD length;
+ * {
+ * if (length && ((error = do_string(length, SKIP)) != 0)) {
+ * error_in_archive = error; /-* might be warning *-/
+ * if (error > 1) /-* fatal *-/
+ * return (error);
+ * }
+ * }
+ *
+ */
+
+#define READBIT(nbits,zdest) {if(nbits>bits_left) FillBitBuffer();\
+ zdest=(int)((UWORD)bitbuf&mask_bits[nbits]);bitbuf>>=nbits;bits_left-=nbits;}
+
+/*
+ * macro READBIT(nbits,zdest)
+ * {
+ * if (nbits > bits_left)
+ * FillBitBuffer();
+ * zdest = (int)((UWORD)bitbuf & mask_bits[nbits]);
+ * bitbuf >>= nbits;
+ * bits_left -= nbits;
+ * }
+ *
+ */
+
+
+#define PEEKBIT(nbits) (nbits>bits_left? (FillBitBuffer(),\
+ (UWORD)bitbuf & mask_bits[nbits]) : (UWORD)bitbuf & mask_bits[nbits])
+
+
+#define NUKE_CRs(buf,len) {register int i,j; for (i=j=0; j<len;\
+ (buf)[i++]=(buf)[j++]) if ((buf)[j]=='\r') ++j; len=i;}
+
+/*
+ * Remove all the ASCII carriage returns from buffer buf (length len),
+ * shortening as necessary (note that len gets modified in the process,
+ * so it CANNOT be an expression). This macro is intended to be used
+ * BEFORE A_TO_N(); hence the check for CR instead of '\r'. NOTE: The
+ * if-test gets performed one time too many, but it doesn't matter.
+ *
+ * macro NUKE_CRs(buf,len)
+ * {
+ * register int i, j;
+ *
+ * for (i = j = 0; j < len; (buf)[i++] = (buf)[j++])
+ * if ((buf)[j] == CR)
+ * ++j;
+ * len = i;
+ * }
+ *
+ */
+
+
+#define TOLOWER(str1,str2) {char *ps1,*ps2; ps1=(str1)-1; ps2=(str2);\
+ while(*++ps1) *ps2++=(char)(isupper((int)(*ps1))?tolower((int)(*ps1)):*ps1);\
+ *ps2='\0';}
+
+/*
+ * Copy the zero-terminated string in str1 into str2, converting any
+ * uppercase letters to lowercase as we go. str2 gets zero-terminated
+ * as well, of course. str1 and str2 may be the same character array.
+ *
+ * macro TOLOWER( str1, str2 )
+ * {
+ * char *ps1, *ps2;
+ *
+ * ps1 = (str1) - 1;
+ * ps2 = (str2);
+ * while (*++ps1)
+ * *ps2++ = (char)(isupper((int)(*ps1))? tolower((int)(*ps1)) : *ps1);
+ * *ps2='\0';
+ * }
+ *
+ * NOTES: This macro makes no assumptions about the characteristics of
+ * the tolower() function or macro (beyond its existence), nor does it
+ * make assumptions about the structure of the character set (i.e., it
+ * should work on EBCDIC machines, too). The fact that either or both
+ * of isupper() and tolower() may be macros has been taken into account;
+ * watch out for "side effects" (in the C sense) when modifying this
+ * macro.
+ */
+
+
+#ifndef ascii_to_native
+# define ascii_to_native(c) (c)
+# define A_TO_N(str1)
+#else
+# ifndef NATIVE
+# define NATIVE "native chars"
+# endif
+# define A_TO_N(str1) {register unsigned char *ps1;\
+ for (ps1=str1; *ps1; ps1++) *ps1=ascii_to_native(*ps1);}
+#endif
+
+/*
+ * Translate the zero-terminated string in str1 from ASCII to the native
+ * character set. The translation is performed in-place and uses the
+ * ascii_to_native macro to translate each character.
+ *
+ * macro A_TO_N( str1 )
+ * {
+ * register unsigned char *ps1;
+ *
+ * for (ps1 = str1; *ps1; ++ps1)
+ * *ps1 = ascii_to_native(*ps1);
+ * }
+ *
+ * NOTE: Using the ascii_to_native macro means that is it the only part of
+ * unzip which knows which translation table (if any) is actually in use
+ * to produce the native character set. This makes adding new character
+ * set translation tables easy, insofar as all that is needed is an
+ * appropriate ascii_to_native macro definition and the translation
+ * table itself. Currently, the only non-ASCII native character set
+ * implemented is EBCDIC, but this may not always be so.
+ */
+
+/*************/
+/* Globals */
+/*************/
+
+#ifdef MACOS
+ union work {
+ struct {
+ short *Prefix_of; /* (8193 * sizeof(short)) */
+ byte *Suffix_of;
+ byte *Stack;
+ } shrink;
+ byte *Slide;
+ };
+#else
+ union work {
+ struct {
+ short Prefix_of[HSIZE + 2]; /* (8194 * sizeof(short)) */
+ byte Suffix_of[HSIZE + 2]; /* also s-f length_nodes (smaller) */
+ byte Stack[HSIZE + 2]; /* also s-f distance_nodes (smaller) */
+ } shrink;
+ byte Slide[WSIZE];
+ };
+#endif
+ extern union work area;
+
+# define prefix_of area.shrink.Prefix_of
+# define suffix_of area.shrink.Suffix_of
+# define stack area.shrink.Stack
+# define slide area.Slide
+
+ extern ULONG crc32val;
+ extern UWORD mask_bits[];
+ extern int bits_left;
+ extern ULONG bitbuf;
+ extern boolean zipeof;
+
diff --git a/source/unzip/unzip.c b/source/unzip/unzip.c
new file mode 100644
index 0000000..54695c2
--- /dev/null
+++ b/source/unzip/unzip.c
@@ -0,0 +1,1224 @@
+/*
+ * unzip.c -- IO on .zip files using zlib Version 0.15 beta, Mar 19th, 1998,
+ *
+ * Read unzip.h for more info
+ */
+
+
+//#include <stdio.h>
+//#include <stdlib.h>
+#include "fs_api.h"
+#include "ds2_malloc.h"
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+#include "unzipP.h"
+
+#ifdef STDC
+//#include <stddef.h>
+//#include <string.h>
+//#include <stdlib.h>
+#endif
+
+#ifdef NO_ERRNO_H
+extern int errno;
+#else
+#include <errno.h>
+#endif
+
+const char unz_copyright[] =
+" unzip 0.15 Copyright 1998 Gilles Vollant ";
+
+void unShrink ();
+void unReduce ();
+int explode ();
+
+/*
+ * ===========================================================================
+ * Read a byte from a gz_stream; update next_in and avail_in. Return EOF for
+ * end of file. IN assertion: the stream s has been sucessfully opened for
+ * reading.
+ */
+
+
+local int
+unzlocal_getByte (FILE * fin, int *pi)
+{
+ unsigned char c;
+ int err = fread (&c, 1, 1, fin);
+ if (err == 1)
+ {
+ *pi = (int) c;
+ return UNZ_OK;
+ } else
+ {
+ if (ferror (fin))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
+}
+
+
+/*
+ * ===========================================================================
+ * Reads a long in LSB order from the given gz_stream. Sets
+ */
+local int
+unzlocal_getShort (FILE * fin, uLong * pX)
+{
+ uLong x;
+ int i;
+ int err;
+
+ err = unzlocal_getByte (fin, &i);
+ x = (uLong) i;
+
+ if (err == UNZ_OK)
+ err = unzlocal_getByte (fin, &i);
+ x += ((uLong) i) << 8;
+
+ if (err == UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int
+unzlocal_getLong (FILE * fin, uLong * pX)
+{
+ uLong x;
+ int i;
+ int err;
+
+ err = unzlocal_getByte (fin, &i);
+ x = (uLong) i;
+
+ if (err == UNZ_OK)
+ err = unzlocal_getByte (fin, &i);
+ x += ((uLong) i) << 8;
+
+ if (err == UNZ_OK)
+ err = unzlocal_getByte (fin, &i);
+ x += ((uLong) i) << 16;
+
+ if (err == UNZ_OK)
+ err = unzlocal_getByte (fin, &i);
+ x += ((uLong) i) << 24;
+
+ if (err == UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+
+/* My own strcmpi / strcasecmp */
+local int
+strcmpcasenosensitive_internal (const char *fileName1, const char *fileName2)
+{
+ for (;;)
+ {
+ char c1 = *(fileName1++);
+ char c2 = *(fileName2++);
+ if ((c1 >= 'a') && (c1 <= 'z'))
+ c1 -= 0x20;
+ if ((c2 >= 'a') && (c2 <= 'z'))
+ c2 -= 0x20;
+ if (c1 == '\0')
+ return ((c2 == '\0') ? 0 : -1);
+ if (c2 == '\0')
+ return 1;
+ if (c1 < c2)
+ return -1;
+ if (c1 > c2)
+ return 1;
+ }
+}
+
+
+#ifdef CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+ * Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1,
+ * comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2,
+ * comparision is not case sensitivity (like strcmpi or strcasecmp) If
+ * iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ * (like 1 on Unix, 2 on Windows)
+ *
+ */
+extern int ZEXPORT
+unzStringFileNameCompare (const char *fileName1, const char *fileName2, int iCaseSensitivity)
+{
+ if (iCaseSensitivity == 0)
+ iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE;
+
+ if (iCaseSensitivity == 1)
+ return strcmp (fileName1, fileName2);
+
+ return STRCMPCASENOSENTIVEFUNCTION (fileName1, fileName2);
+}
+
+#define BUFREADCOMMENT (0x400)
+
+/*
+ * Locate the Central directory of a zipfile (at the end, just before the
+ * global comment)
+ */
+local uLong
+unzlocal_SearchCentralDir (FILE * fin)
+{
+ unsigned char *buf;
+ uLong uSizeFile;
+ uLong uBackRead;
+ uLong uMaxBack = 0xffff; /* maximum size of global comment */
+ uLong uPosFound = 0;
+
+ if (fseek (fin, 0, SEEK_END) != 0)
+ return 0;
+
+ uSizeFile = ftell (fin);
+
+ if (uMaxBack > uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char *) ALLOC (BUFREADCOMMENT + 4);
+ if (buf == NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead < uMaxBack)
+ {
+ uLong uReadSize, uReadPos;
+ int i;
+ if (uBackRead + BUFREADCOMMENT > uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead += BUFREADCOMMENT;
+ uReadPos = uSizeFile - uBackRead;
+
+ uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ?
+ (BUFREADCOMMENT + 4) : (uSizeFile - uReadPos);
+ if (fseek (fin, uReadPos, SEEK_SET) != 0)
+ break;
+
+ if (fread (buf, (uInt) uReadSize, 1, fin) != 1)
+ break;
+
+ for (i = 0; i < (int) uReadSize - 3; i++)
+ if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) &&
+ ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06))
+ {
+ uPosFound = uReadPos + i;
+ break;
+ }
+ if (uPosFound != 0)
+ break;
+ }
+ TRYFREE (buf);
+ return uPosFound;
+}
+
+/*
+ * Open a Zip file. path contain the full pathname (by example, on a Windows
+ * NT computer "c:\\test\\zlib109.zip" or on an Unix computer
+ * "zlib/zlib109.zip". If the zipfile cannot be opened (file don't exist or
+ * in not valid), the return value is NULL. Else, the return value is a
+ * unzFile Handle, usable with other function of this unzip package.
+ */
+extern unzFile ZEXPORT
+unzOpen (const char *path)
+{
+ unz_s us;
+ unz_s *s;
+ uLong central_pos, uL;
+ FILE *fin;
+
+ uLong number_disk;/* number of the current dist, used for
+ * spaning ZIP, unsupported, always 0 */
+ uLong number_disk_with_CD; /* number the the disk with
+ * central dir, used for
+ * spaning ZIP, unsupported,
+ * always 0 */
+ uLong number_entry_CD; /* total number of entries in the
+ * central dir (same than
+ * number_entry on nospan) */
+
+ int err = UNZ_OK;
+
+ if (unz_copyright[0] != ' ')
+ return NULL;
+
+ fin = fopen (path, "rb");
+ if (fin == NULL)
+ return NULL;
+
+ central_pos = unzlocal_SearchCentralDir (fin);
+ if (central_pos == 0)
+ err = UNZ_ERRNO;
+
+ if (fseek (fin, central_pos, SEEK_SET) != 0)
+ err = UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unzlocal_getLong (fin, &uL) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unzlocal_getShort (fin, &number_disk) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unzlocal_getShort (fin, &number_disk_with_CD) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ if (unzlocal_getShort (fin, &us.gi.number_entry) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ /* total number of entries in the central dir */
+ if (unzlocal_getShort (fin, &number_entry_CD) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if ((number_entry_CD != us.gi.number_entry) ||
+ (number_disk_with_CD != 0) ||
+ (number_disk != 0))
+ err = UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unzlocal_getLong (fin, &us.size_central_dir) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ /*
+ * offset of start of central directory with respect to the starting disk
+ * number
+ */
+ if (unzlocal_getLong (fin, &us.offset_central_dir) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ /* zipfile comment length */
+ if (unzlocal_getShort (fin, &us.gi.size_comment) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if ((central_pos < us.offset_central_dir + us.size_central_dir) &&
+ (err == UNZ_OK))
+ err = UNZ_BADZIPFILE;
+
+ if (err != UNZ_OK)
+ {
+ fclose (fin);
+ return NULL;
+ }
+ us.file = fin;
+ us.byte_before_the_zipfile = central_pos -
+ (us.offset_central_dir + us.size_central_dir);
+ us.central_pos = central_pos;
+ us.pfile_in_zip_read = NULL;
+
+
+ s = (unz_s *) ALLOC (sizeof (unz_s));
+ *s = us;
+ unzGoToFirstFile ((unzFile) s);
+ return (unzFile) s;
+}
+
+
+/*
+ * Close a ZipFile opened with unzipOpen. If there is files inside the .Zip
+ * opened with unzipOpenCurrentFile (see later), these files MUST be closed
+ * with unzipCloseCurrentFile before call unzipClose. return UNZ_OK if there
+ * is no problem.
+ */
+extern int ZEXPORT
+unzClose (unzFile file)
+{
+ unz_s *s;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+
+ if (s->pfile_in_zip_read != NULL)
+ unzCloseCurrentFile (file);
+
+ fclose (s->file);
+ TRYFREE (s);
+ return UNZ_OK;
+}
+
+
+/*
+ * Write info about the ZipFile in the *pglobal_info structure. No
+ * preparation of the structure is needed return UNZ_OK if there is no
+ * problem.
+ */
+extern int ZEXPORT
+unzGetGlobalInfo (unzFile file, unz_global_info * pglobal_info)
+{
+ unz_s *s;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ *pglobal_info = s->gi;
+ return UNZ_OK;
+}
+
+
+/*
+ * Translate date/time from Dos format to tm_unz (readable more easilty)
+ */
+local void
+unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz * ptm)
+{
+ uLong uDate;
+ uDate = (uLong) (ulDosDate >> 16);
+ ptm->tm_mday = (uInt) (uDate & 0x1f);
+ ptm->tm_mon = (uInt) ((((uDate) & 0x1E0) / 0x20) - 1);
+ ptm->tm_year = (uInt) (((uDate & 0x0FE00) / 0x0200) + 1980);
+
+ ptm->tm_hour = (uInt) ((ulDosDate & 0xF800) / 0x800);
+ ptm->tm_min = (uInt) ((ulDosDate & 0x7E0) / 0x20);
+ ptm->tm_sec = (uInt) (2 * (ulDosDate & 0x1f));
+}
+
+/*
+ * Get Info about the current file in the zipfile, with internal only info
+ */
+local int unzlocal_GetCurrentFileInfoInternal
+OF ((unzFile file,
+ unz_file_info * pfile_info,
+ unz_file_info_internal
+ * pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+ local int unzlocal_GetCurrentFileInfoInternal (
+ unzFile file,
+ unz_file_info * pfile_info,
+ unz_file_info_internal * pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize)
+{
+ unz_s *s;
+ unz_file_info file_info;
+ unz_file_info_internal file_info_internal;
+ int err = UNZ_OK;
+ uLong uMagic;
+ long lSeek = 0;
+
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ if (fseek (s->file, s->pos_in_central_dir + s->byte_before_the_zipfile, SEEK_SET) != 0)
+ err = UNZ_ERRNO;
+
+
+ /* we check the magic */
+ if (err == UNZ_OK)
+ {
+ if (unzlocal_getLong (s->file, &uMagic) != UNZ_OK)
+ err = UNZ_ERRNO;
+ else if (uMagic != 0x02014b50)
+ err = UNZ_BADZIPFILE;
+ }
+ if (unzlocal_getShort (s->file, &file_info.version) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.version_needed) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.flag) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.compression_method) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getLong (s->file, &file_info.dosDate) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ unzlocal_DosDateToTmuDate (file_info.dosDate, &file_info.tmu_date);
+
+ if (unzlocal_getLong (s->file, &file_info.crc) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getLong (s->file, &file_info.compressed_size) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getLong (s->file, &file_info.uncompressed_size) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.size_filename) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.size_file_extra) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.size_file_comment) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.disk_num_start) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &file_info.internal_fa) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getLong (s->file, &file_info.external_fa) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getLong (s->file, &file_info_internal.offset_curfile) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ lSeek += file_info.size_filename;
+ if ((err == UNZ_OK) && (szFileName != NULL))
+ {
+ uLong uSizeRead;
+ if (file_info.size_filename < fileNameBufferSize)
+ {
+ *(szFileName + file_info.size_filename) = '\0';
+ uSizeRead = file_info.size_filename;
+ } else
+ uSizeRead = fileNameBufferSize;
+
+ if ((file_info.size_filename > 0) && (fileNameBufferSize > 0))
+ if (fread (szFileName, (uInt) uSizeRead, 1, s->file) != 1)
+ err = UNZ_ERRNO;
+ lSeek -= uSizeRead;
+ }
+ if ((err == UNZ_OK) && (extraField != NULL))
+ {
+ uLong uSizeRead;
+ if (file_info.size_file_extra < extraFieldBufferSize)
+ uSizeRead = file_info.size_file_extra;
+ else
+ uSizeRead = extraFieldBufferSize;
+
+ if (lSeek != 0)
+ {
+ if (fseek (s->file, lSeek, SEEK_CUR) == 0)
+ lSeek = 0;
+ else
+ err = UNZ_ERRNO;
+ }
+ if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0))
+ if (fread (extraField, (uInt) uSizeRead, 1, s->file) != 1)
+ err = UNZ_ERRNO;
+ lSeek += file_info.size_file_extra - uSizeRead;
+ } else
+ lSeek += file_info.size_file_extra;
+
+
+ if ((err == UNZ_OK) && (szComment != NULL))
+ {
+ uLong uSizeRead;
+ if (file_info.size_file_comment < commentBufferSize)
+ {
+ *(szComment + file_info.size_file_comment) = '\0';
+ uSizeRead = file_info.size_file_comment;
+ } else
+ uSizeRead = commentBufferSize;
+
+ if (lSeek != 0)
+ {
+ if (fseek (s->file, lSeek, SEEK_CUR) == 0)
+ lSeek = 0;
+ else
+ err = UNZ_ERRNO;
+ }
+ if ((file_info.size_file_comment > 0) && (commentBufferSize > 0))
+ if (fread (szComment, (uInt) uSizeRead, 1, s->file) != 1)
+ err = UNZ_ERRNO;
+ lSeek += file_info.size_file_comment - uSizeRead;
+ } else
+ lSeek += file_info.size_file_comment;
+
+ if ((err == UNZ_OK) && (pfile_info != NULL))
+ *pfile_info = file_info;
+
+ if ((err == UNZ_OK) && (pfile_info_internal != NULL))
+ *pfile_info_internal = file_info_internal;
+
+ return err;
+}
+
+
+
+/*
+ * Write info about the ZipFile in the *pglobal_info structure. No
+ * preparation of the structure is needed return UNZ_OK if there is no
+ * problem.
+ */
+extern int ZEXPORT
+unzGetCurrentFileInfo (
+ unzFile file,
+ unz_file_info * pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize)
+{
+ return unzlocal_GetCurrentFileInfoInternal (file, pfile_info, NULL,
+ szFileName, fileNameBufferSize,
+ extraField, extraFieldBufferSize,
+ szComment, commentBufferSize);
+}
+
+/*
+ * Set the current file of the zipfile to the first file. return UNZ_OK if
+ * there is no problem
+ */
+extern int ZEXPORT
+unzGoToFirstFile (unzFile file)
+{
+ int err = UNZ_OK;
+ unz_s *s;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ s->pos_in_central_dir = s->offset_central_dir;
+ s->num_file = 0;
+ err = unzlocal_GetCurrentFileInfoInternal (file, &s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL, 0, NULL, 0, NULL, 0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+
+/*
+ * Set the current file of the zipfile to the next file. return UNZ_OK if
+ * there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was
+ * the latest.
+ */
+extern int ZEXPORT
+unzGoToNextFile (unzFile file)
+{
+ unz_s *s;
+ int err;
+
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (s->num_file + 1 == s->gi.number_entry)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;
+ s->num_file++;
+ err = unzlocal_GetCurrentFileInfoInternal (file, &s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL, 0, NULL, 0, NULL, 0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+
+/*
+ * Try locate the file szFileName in the zipfile. For the iCaseSensitivity
+ * signification, see unzipStringFileNameCompare
+ *
+ * return value : UNZ_OK if the file is found. It becomes the current file.
+ * UNZ_END_OF_LIST_OF_FILE if the file is not found
+ */
+extern int ZEXPORT
+unzLocateFile (
+ unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity)
+{
+ unz_s *s;
+ int err;
+
+
+ uLong num_fileSaved;
+ uLong pos_in_central_dirSaved;
+
+
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+
+ if (strlen (szFileName) >= UNZ_MAXFILENAMEINZIP)
+ return UNZ_PARAMERROR;
+
+ s = (unz_s *) file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ num_fileSaved = s->num_file;
+ pos_in_central_dirSaved = s->pos_in_central_dir;
+
+ err = unzGoToFirstFile (file);
+
+ while (err == UNZ_OK)
+ {
+ char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
+ unzGetCurrentFileInfo (file, NULL,
+ szCurrentFileName, sizeof (szCurrentFileName) - 1,
+ NULL, 0, NULL, 0);
+ if (unzStringFileNameCompare (szCurrentFileName,
+ szFileName, iCaseSensitivity) == 0)
+ return UNZ_OK;
+ err = unzGoToNextFile (file);
+ }
+
+ s->num_file = num_fileSaved;
+ s->pos_in_central_dir = pos_in_central_dirSaved;
+ return err;
+}
+
+
+/*
+ * Read the local header of the current zipfile Check the coherency of the
+ * local header and info in the end of central directory about this file
+ * store in *piSizeVar the size of extra info in local header (filename and
+ * size of extra field data)
+ */
+local int
+unzlocal_CheckCurrentFileCoherencyHeader (
+ unz_s * s,
+ uInt * piSizeVar,
+ uLong * poffset_local_extrafield,
+ uInt * psize_local_extrafield)
+{
+ uLong uMagic, uData, uFlags;
+ uLong size_filename;
+ uLong size_extra_field;
+ int err = UNZ_OK;
+
+ *piSizeVar = 0;
+ *poffset_local_extrafield = 0;
+ *psize_local_extrafield = 0;
+
+ if (fseek (s->file, s->cur_file_info_internal.offset_curfile +
+ s->byte_before_the_zipfile, SEEK_SET) != 0)
+ return UNZ_ERRNO;
+
+
+ if (err == UNZ_OK)
+ {
+ if (unzlocal_getLong (s->file, &uMagic) != UNZ_OK)
+ err = UNZ_ERRNO;
+ else if (uMagic != 0x04034b50)
+ err = UNZ_BADZIPFILE;
+ }
+
+ if (unzlocal_getShort (s->file, &uData) != UNZ_OK)
+ err = UNZ_ERRNO;
+ /*
+ * else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+ * err=UNZ_BADZIPFILE;
+ */
+ if (unzlocal_getShort (s->file, &uFlags) != UNZ_OK)
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getShort (s->file, &uData) != UNZ_OK)
+ err = UNZ_ERRNO;
+ else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method))
+ err = UNZ_BADZIPFILE;
+
+ if ((err == UNZ_OK) &&
+ s->cur_file_info.compression_method > Z_DEFLATED)
+ err = UNZ_BADZIPFILE;
+
+ if (unzlocal_getLong (s->file, &uData) != UNZ_OK) /* date/time */
+ err = UNZ_ERRNO;
+
+ if (unzlocal_getLong (s->file, &uData) != UNZ_OK) /* crc */
+ err = UNZ_ERRNO;
+ else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) &&
+ ((uFlags & 8) == 0))
+ err = UNZ_BADZIPFILE;
+
+ if (unzlocal_getLong (s->file, &uData) != UNZ_OK) /* size compr */
+ err = UNZ_ERRNO;
+ else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) &&
+ ((uFlags & 8) == 0))
+ err = UNZ_BADZIPFILE;
+
+ if (unzlocal_getLong (s->file, &uData) != UNZ_OK) /* size uncompr */
+ err = UNZ_ERRNO;
+ else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) &&
+ ((uFlags & 8) == 0))
+ err = UNZ_BADZIPFILE;
+
+
+ if (unzlocal_getShort (s->file, &size_filename) != UNZ_OK)
+ err = UNZ_ERRNO;
+ else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename))
+ err = UNZ_BADZIPFILE;
+
+ *piSizeVar += (uInt) size_filename;
+
+ if (unzlocal_getShort (s->file, &size_extra_field) != UNZ_OK)
+ err = UNZ_ERRNO;
+ *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile +
+ SIZEZIPLOCALHEADER + size_filename;
+ *psize_local_extrafield = (uInt) size_extra_field;
+
+ *piSizeVar += (uInt) size_extra_field;
+
+ return err;
+}
+
+/*
+ * Open for reading data the current file in the zipfile. If there is no
+ * error and the file is opened, the return value is UNZ_OK.
+ */
+extern int ZEXPORT
+unzOpenCurrentFile (unzFile file)
+{
+ int err = UNZ_OK;
+ uInt iSizeVar;
+ unz_s *s;
+ file_in_zip_read_info_s *pfile_in_zip_read_info;
+ uLong offset_local_extrafield; /* offset of the local extra
+ * field */
+ uInt size_local_extrafield; /* size of the local extra
+ * field */
+
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ if (!s->current_file_ok)
+ return UNZ_PARAMERROR;
+
+ if (s->pfile_in_zip_read != NULL)
+ unzCloseCurrentFile (file);
+
+ if (unzlocal_CheckCurrentFileCoherencyHeader (s, &iSizeVar,
+ &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)
+ return UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info = (file_in_zip_read_info_s *)
+ ALLOC (sizeof (file_in_zip_read_info_s));
+ if (pfile_in_zip_read_info == NULL)
+ return UNZ_INTERNALERROR;
+
+ pfile_in_zip_read_info->read_buffer = (char *) ALLOC (UNZ_BUFSIZE);
+ pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+ pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+ pfile_in_zip_read_info->pos_local_extrafield = 0;
+
+ if (pfile_in_zip_read_info->read_buffer == NULL)
+ {
+ TRYFREE (pfile_in_zip_read_info);
+ return UNZ_INTERNALERROR;
+ }
+ pfile_in_zip_read_info->stream_initialised = 0;
+
+ if (s->cur_file_info.compression_method > Z_DEFLATED)
+ err = UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc;
+ pfile_in_zip_read_info->crc32 = 0;
+ pfile_in_zip_read_info->compression_method =
+ s->cur_file_info.compression_method;
+ pfile_in_zip_read_info->file = s->file;
+ pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile;
+
+ pfile_in_zip_read_info->stream.total_out = 0;
+
+ switch (s->cur_file_info.compression_method)
+ {
+ case UNZ_STORED:
+ break;
+ case UNZ_SHRUNK:
+ break;
+ case UNZ_REDUCED1:
+ case UNZ_REDUCED2:
+ case UNZ_REDUCED3:
+ case UNZ_REDUCED4:
+ break;
+ case UNZ_IMPLODED:
+ break;
+ case UNZ_DEFLATED:
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func) 0;
+ pfile_in_zip_read_info->stream.zfree = (free_func) 0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf) 0;
+
+ err = inflateInit2 (&pfile_in_zip_read_info->stream, -MAX_WBITS);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised = 1;
+ /*
+ * windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END. In unzip, i don't wait absolutely
+ * Z_STREAM_END because I known the size of both compressed and
+ * uncompressed data
+ */
+ break;
+ default:
+ return UNZ_INTERNALERROR;
+ break;
+ }
+ pfile_in_zip_read_info->rest_read_compressed =
+ s->cur_file_info.compressed_size;
+ pfile_in_zip_read_info->rest_read_uncompressed =
+ s->cur_file_info.uncompressed_size;
+
+ pfile_in_zip_read_info->pos_in_zipfile =
+ s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+ iSizeVar;
+
+ pfile_in_zip_read_info->stream.avail_in = (uInt) 0;
+ s->pfile_in_zip_read = pfile_in_zip_read_info;
+ return UNZ_OK;
+}
+
+
+/*
+ * Read bytes from the current file. buf contain buffer where data must be
+ * copied len the size of buf.
+ *
+ * return the number of byte copied if somes bytes are copied return 0 if the
+ * end of file was reached return <0 with error code if there is an error
+ * (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+ */
+
+file_in_zip_read_info_s *pfile_in_zip_read_info = NULL;
+unz_s *pUnzip = NULL;
+extern int ZEXPORT
+unzReadCurrentFile (
+ unzFile file,
+ voidp buf,
+ unsigned len)
+{
+ int err = UNZ_OK;
+ uInt iRead = 0;
+ unz_s *s;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ pUnzip = s;
+ pfile_in_zip_read_info = s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info == NULL)
+ return UNZ_PARAMERROR;
+
+
+ if ((pfile_in_zip_read_info->read_buffer == NULL))
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (len == 0)
+ return 0;
+
+ pfile_in_zip_read_info->stream.next_out = (Bytef *) buf;
+
+ pfile_in_zip_read_info->stream.avail_out = (uInt) len;
+
+ if (len > pfile_in_zip_read_info->rest_read_uncompressed)
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt) pfile_in_zip_read_info->rest_read_uncompressed;
+
+ while (pfile_in_zip_read_info->stream.avail_out > 0 && err == UNZ_OK)
+ {
+ switch (pfile_in_zip_read_info->compression_method)
+ {
+ case UNZ_STORED:
+ case UNZ_DEFLATED:
+ if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+ (pfile_in_zip_read_info->rest_read_compressed > 0))
+ {
+ uInt uReadThis = UNZ_BUFSIZE;
+ if (pfile_in_zip_read_info->rest_read_compressed < uReadThis)
+ uReadThis = (uInt) pfile_in_zip_read_info->rest_read_compressed;
+ if (uReadThis == 0)
+ return UNZ_EOF;
+ if (fseek (pfile_in_zip_read_info->file,
+ pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile, SEEK_SET) != 0)
+ return UNZ_ERRNO;
+ if (fread (pfile_in_zip_read_info->read_buffer, uReadThis, 1,
+ pfile_in_zip_read_info->file) != 1)
+ return UNZ_ERRNO;
+ pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+ pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
+
+ pfile_in_zip_read_info->stream.next_in =
+ (Bytef *) pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.avail_in = (uInt) uReadThis;
+ }
+ break;
+ }
+ switch (pfile_in_zip_read_info->compression_method)
+ {
+ case UNZ_STORED:
+ {
+ uInt uDoCopy, i;
+ if (pfile_in_zip_read_info->stream.avail_out <
+ pfile_in_zip_read_info->stream.avail_in)
+ uDoCopy = pfile_in_zip_read_info->stream.avail_out;
+ else
+ uDoCopy = pfile_in_zip_read_info->stream.avail_in;
+
+ for (i = 0; i < uDoCopy; i++)
+ *(pfile_in_zip_read_info->stream.next_out + i) =
+ *(pfile_in_zip_read_info->stream.next_in + i);
+
+ pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ uDoCopy);
+ pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
+ pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+ pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+ pfile_in_zip_read_info->stream.next_out += uDoCopy;
+ pfile_in_zip_read_info->stream.next_in += uDoCopy;
+ pfile_in_zip_read_info->stream.total_out += uDoCopy;
+ iRead += uDoCopy;
+ break;
+ }
+ case UNZ_SHRUNK:
+ iRead = pfile_in_zip_read_info->rest_read_uncompressed;
+ unShrink ();
+ break;
+ case UNZ_REDUCED1:
+ case UNZ_REDUCED2:
+ case UNZ_REDUCED3:
+ case UNZ_REDUCED4:
+ iRead = pfile_in_zip_read_info->rest_read_uncompressed;
+ unReduce ();
+ break;
+ case UNZ_IMPLODED:
+ iRead = pfile_in_zip_read_info->rest_read_uncompressed;
+ err = explode ();
+ break;
+ case UNZ_DEFLATED:
+ {
+ uLong uTotalOutBefore, uTotalOutAfter;
+ const Bytef *bufBefore;
+ uLong uOutThis;
+ int flush = Z_SYNC_FLUSH;
+
+ uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+ bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+ /*
+ * if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+ * pfile_in_zip_read_info->stream.avail_out) &&
+ * (pfile_in_zip_read_info->rest_read_compressed == 0)) flush =
+ * Z_FINISH;
+ */
+ err = inflate (&pfile_in_zip_read_info->stream, flush);
+
+ uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+ uOutThis = uTotalOutAfter - uTotalOutBefore;
+
+ pfile_in_zip_read_info->crc32 =
+ crc32 (pfile_in_zip_read_info->crc32, bufBefore,
+ (uInt) (uOutThis));
+
+ pfile_in_zip_read_info->rest_read_uncompressed -=
+ uOutThis;
+
+ iRead += (uInt) (uTotalOutAfter - uTotalOutBefore);
+
+ if (err == Z_STREAM_END)
+ return (iRead == 0) ? UNZ_EOF : iRead;
+ if (err != Z_OK)
+ break;
+ break;
+ }
+ default:
+ return (UNZ_EOF);
+ }
+ }
+
+ if (err == Z_OK)
+ return iRead;
+ return err;
+}
+
+
+/*
+ * Give the current position in uncompressed data
+ */
+extern z_off_t ZEXPORT
+unztell (unzFile file)
+{
+ unz_s *s;
+ file_in_zip_read_info_s *pfile_in_zip_read_info;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ pfile_in_zip_read_info = s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info == NULL)
+ return UNZ_PARAMERROR;
+
+ return (z_off_t) pfile_in_zip_read_info->stream.total_out;
+}
+
+
+/*
+ * return 1 if the end of file was reached, 0 elsewhere
+ */
+extern int ZEXPORT
+unzeof (unzFile file)
+{
+ unz_s *s;
+ file_in_zip_read_info_s *pfile_in_zip_read_info;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ pfile_in_zip_read_info = s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info == NULL)
+ return UNZ_PARAMERROR;
+
+ if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+
+/*
+ * Read extra field from the current file (opened by unzOpenCurrentFile) This
+ * is the local-header version of the extra field (sometimes, there is more
+ * info in the local-header version than in the central-header)
+ *
+ * if buf==NULL, it return the size of the local extra field that can be read
+ *
+ * if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ * buf. the return value is the number of bytes copied in buf, or (if <0) the
+ * error code
+ */
+extern int ZEXPORT
+unzGetLocalExtrafield (
+ unzFile file,
+ voidp buf,
+ unsigned len)
+{
+ unz_s *s;
+ file_in_zip_read_info_s *pfile_in_zip_read_info;
+ uInt read_now;
+ uLong size_to_read;
+
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ pfile_in_zip_read_info = s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info == NULL)
+ return UNZ_PARAMERROR;
+
+ size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+ pfile_in_zip_read_info->pos_local_extrafield);
+
+ if (buf == NULL)
+ return (int) size_to_read;
+
+ if (len > size_to_read)
+ read_now = (uInt) size_to_read;
+ else
+ read_now = (uInt) len;
+
+ if (read_now == 0)
+ return 0;
+
+ if (fseek (pfile_in_zip_read_info->file,
+ pfile_in_zip_read_info->offset_local_extrafield +
+ pfile_in_zip_read_info->pos_local_extrafield, SEEK_SET) != 0)
+ return UNZ_ERRNO;
+
+ if (fread (buf, (uInt) size_to_read, 1, pfile_in_zip_read_info->file) != 1)
+ return UNZ_ERRNO;
+
+ return (int) read_now;
+}
+
+/*
+ * Close the file in zip opened with unzipOpenCurrentFile Return UNZ_CRCERROR
+ * if all the file was read but the CRC is not good
+ */
+extern int ZEXPORT
+unzCloseCurrentFile (unzFile file)
+{
+ int err = UNZ_OK;
+
+ unz_s *s;
+ file_in_zip_read_info_s *pfile_in_zip_read_info;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+ pfile_in_zip_read_info = s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info == NULL)
+ return UNZ_PARAMERROR;
+
+
+ if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+ {
+ if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+ err = UNZ_CRCERROR;
+ }
+ TRYFREE (pfile_in_zip_read_info->read_buffer);
+ pfile_in_zip_read_info->read_buffer = NULL;
+ if (pfile_in_zip_read_info->stream_initialised)
+ inflateEnd (&pfile_in_zip_read_info->stream);
+
+ pfile_in_zip_read_info->stream_initialised = 0;
+ TRYFREE (pfile_in_zip_read_info);
+
+ s->pfile_in_zip_read = NULL;
+
+ return err;
+}
+
+
+/*
+ * Get the global comment string of the ZipFile, in the szComment buffer.
+ * uSizeBuf is the size of the szComment buffer. return the number of byte
+ * copied or an error code <0
+ */
+extern int ZEXPORT
+unzGetGlobalComment (
+ unzFile file,
+ char *szComment,
+ uLong uSizeBuf)
+{
+ unz_s *s;
+ uLong uReadThis;
+ if (file == NULL)
+ return UNZ_PARAMERROR;
+ s = (unz_s *) file;
+
+ uReadThis = uSizeBuf;
+ if (uReadThis > s->gi.size_comment)
+ uReadThis = s->gi.size_comment;
+
+ if (fseek (s->file, s->central_pos + 22, SEEK_SET) != 0)
+ return UNZ_ERRNO;
+
+ if (uReadThis > 0)
+ {
+ *szComment = '\0';
+ if (fread (szComment, (uInt) uReadThis, 1, s->file) != 1)
+ return UNZ_ERRNO;
+ }
+ if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+ *(szComment + s->gi.size_comment) = '\0';
+ return (int) uReadThis;
+}
diff --git a/source/unzip/unzip.h b/source/unzip/unzip.h
new file mode 100644
index 0000000..f629782
--- /dev/null
+++ b/source/unzip/unzip.h
@@ -0,0 +1,285 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+ Version 0.15 beta, Mar 19th, 1998,
+
+ Copyright (C) 1998 Gilles Vollant
+
+ This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
+ WinZip, InfoZip tools and compatible.
+ Encryption and multi volume ZipFile (span) are not supported.
+ Old compressions used by old PKZip 1.x are not supported
+
+ THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
+ CAN CHANGE IN FUTURE VERSION !!
+ I WAIT FEEDBACK at mail info@winimage.com
+ Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+
+*/
+/* for more info about .ZIP format, see
+ ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
+ PkWare has also a specification at :
+ ftp://ftp.pkware.com/probdesc.zip */
+
+#ifndef _unz_H
+#define _unz_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO (Z_ERRNO)
+#define UNZ_EOF (0)
+#define UNZ_PARAMERROR (-102)
+#define UNZ_BADZIPFILE (-103)
+#define UNZ_INTERNALERROR (-104)
+#define UNZ_CRCERROR (-105)
+
+#define UNZ_STORED 0 /* compression methods */
+#define UNZ_SHRUNK 1
+#define UNZ_REDUCED1 2
+#define UNZ_REDUCED2 3
+#define UNZ_REDUCED3 4
+#define UNZ_REDUCED4 5
+#define UNZ_IMPLODED 6
+#define UNZ_TOKENIZED 7
+#define UNZ_DEFLATED 8
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+ These data comes from the end of central dir */
+typedef struct unz_global_info_s
+{
+ uLong number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info;
+
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity));
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
+ "zlib/zlib111.zip".
+ If the zipfile cannot be opened (file don't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+ Close a ZipFile opened with unzipOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+ return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+ unz_global_info *pglobal_info));
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+ char *szComment,
+ uLong uSizeBuf));
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity));
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+/*
+ Get Info about the current file
+ if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ the current file
+ if szFileName!=NULL, the filemane string will be copied in szFileName
+ (fileNameBufferSize is the size of the buffer)
+ if extraField!=NULL, the extra field information will be copied in extraField
+ (extraFieldBufferSize is the size of the buffer).
+ This is the Central-header version of the extra field
+ if szComment!=NULL, the comment string of the file will be copied in szComment
+ (commentBufferSize is the size of the buffer)
+*/
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+ from it, and close it (you can close it before reading all the file)
+ */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read bytes from the current file (opened by unzOpenCurrentFile)
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+/*
+ Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read extra field from the current file (opened by unzOpenCurrentFile)
+ This is the local-header version of the extra field (sometimes, there is
+ more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz_H */
diff --git a/source/unzip/unzipP.h b/source/unzip/unzipP.h
new file mode 100644
index 0000000..c44e3cb
--- /dev/null
+++ b/source/unzip/unzipP.h
@@ -0,0 +1,125 @@
+#ifndef _UNZIPP_H_
+#define _UNZIPP_H_
+
+#include "ds2_malloc.h"
+#include "unzip.h"
+
+#ifndef local
+#define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+
+#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
+ !defined(CASESENSITIVITYDEFAULT_NO)
+#define CASESENSITIVITYDEFAULT_NO
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+#define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+#define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+/* 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
+
+/* unz_file_info_interntal contain internal info about a file in zipfile */
+typedef struct unz_file_info_internal_s
+{
+ uLong offset_curfile; /* relative offset of local header 4
+ * bytes */
+} unz_file_info_internal;
+
+
+/*
+ * file_in_zip_read_info_s contain internal information about a file in
+ * zipfile, when reading and decompress it
+ */
+typedef struct
+{
+ char *read_buffer;/* internal buffer for compressed data */
+ z_stream stream; /* zLib stream structure for inflate */
+
+ uLong pos_in_zipfile; /* position in byte on the zipfile,
+ * for fseek */
+ uLong stream_initialised; /* flag set if stream structure is
+ * initialised */
+
+ uLong offset_local_extrafield; /* offset of the local extra
+ * field */
+ uInt size_local_extrafield; /* size of the local extra
+ * field */
+ uLong pos_local_extrafield; /* position in the local
+ * extra field in read */
+
+ uLong crc32; /* crc32 of all data uncompressed */
+ uLong crc32_wait; /* crc32 we must obtain after decompress all */
+ uLong rest_read_compressed; /* number of byte to be
+ * decompressed */
+ uLong rest_read_uncompressed; /* number of byte to be
+ * obtained after decomp */
+ FILE *file; /* io structore of the zipfile */
+ uLong compression_method; /* compression method (0==store) */
+ uLong byte_before_the_zipfile; /* byte before the zipfile,
+ * (>0 for sfx) */
+} file_in_zip_read_info_s;
+
+
+/*
+ * unz_s contain internal information about the zipfile
+ */
+typedef struct
+{
+ FILE *file; /* io structore of the zipfile */
+ unz_global_info gi; /* public global information */
+ uLong byte_before_the_zipfile; /* byte before the zipfile,
+ * (>0 for sfx) */
+ uLong num_file; /* number of the current file in the zipfile */
+ uLong pos_in_central_dir; /* pos of the current file in the
+ * central dir */
+ uLong current_file_ok; /* flag about the usability of the
+ * current file */
+ uLong central_pos;/* position of the beginning of the central
+ * dir */
+
+ uLong size_central_dir; /* size of the central directory */
+ uLong offset_central_dir; /* offset of start of central
+ * directory with respect to the
+ * starting disk number */
+
+ unz_file_info cur_file_info; /* public info about the current file
+ * in zip */
+ unz_file_info_internal cur_file_info_internal; /* private info about it */
+ file_in_zip_read_info_s *pfile_in_zip_read; /* structure about the
+ * current file if we are
+ * decompressing it */
+} unz_s;
+
+#endif