summaryrefslogtreecommitdiff
path: root/libpcsxcore
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-04-16 06:22:51 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-04-16 06:22:51 +0000
commit8139fbf8204882663446bcb06f68789353597820 (patch)
tree6ea1f39932b33faee84d603e956470e37f135804 /libpcsxcore
downloadpcsxr-8139fbf8204882663446bcb06f68789353597820.tar.gz
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@23061 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore')
-rw-r--r--libpcsxcore/Makefile.am76
-rw-r--r--libpcsxcore/Makefile.in1088
-rw-r--r--libpcsxcore/cdriso.c305
-rw-r--r--libpcsxcore/cdriso.h27
-rw-r--r--libpcsxcore/cdrom.c1105
-rw-r--r--libpcsxcore/cdrom.h96
-rw-r--r--libpcsxcore/cheat.c459
-rw-r--r--libpcsxcore/cheat.h51
-rw-r--r--libpcsxcore/coff.h39
-rw-r--r--libpcsxcore/debug.h60
-rw-r--r--libpcsxcore/decode_xa.c368
-rw-r--r--libpcsxcore/decode_xa.h43
-rw-r--r--libpcsxcore/disr3000a.c324
-rw-r--r--libpcsxcore/gte.c3124
-rw-r--r--libpcsxcore/gte.h57
-rw-r--r--libpcsxcore/ix86/iGte.h663
-rw-r--r--libpcsxcore/ix86/iR3000A.c2898
-rw-r--r--libpcsxcore/ix86/ix86.c1759
-rw-r--r--libpcsxcore/ix86/ix86.h667
-rw-r--r--libpcsxcore/ix86_64/README4
-rw-r--r--libpcsxcore/ix86_64/iGte.h672
-rw-r--r--libpcsxcore/ix86_64/iR3000A-64.c2966
-rw-r--r--libpcsxcore/ix86_64/ix86-64.c3141
-rw-r--r--libpcsxcore/ix86_64/ix86-64.h1776
-rw-r--r--libpcsxcore/ix86_64/ix86_3dnow.c178
-rw-r--r--libpcsxcore/ix86_64/ix86_cpudetect.c487
-rw-r--r--libpcsxcore/ix86_64/ix86_fpu.c248
-rw-r--r--libpcsxcore/ix86_64/ix86_mmx.c646
-rw-r--r--libpcsxcore/ix86_64/ix86_sse.c1455
-rw-r--r--libpcsxcore/mdec.c522
-rw-r--r--libpcsxcore/mdec.h39
-rw-r--r--libpcsxcore/misc.c627
-rw-r--r--libpcsxcore/misc.h73
-rw-r--r--libpcsxcore/plugins.c820
-rw-r--r--libpcsxcore/plugins.h348
-rw-r--r--libpcsxcore/ppc/pGte.h670
-rw-r--r--libpcsxcore/ppc/pR3000A.c3528
-rw-r--r--libpcsxcore/ppc/pasm.s124
-rw-r--r--libpcsxcore/ppc/ppc.c32
-rw-r--r--libpcsxcore/ppc/ppc.h74
-rw-r--r--libpcsxcore/ppc/ppc_mnemonics.h529
-rw-r--r--libpcsxcore/ppc/reguse.c419
-rw-r--r--libpcsxcore/ppc/reguse.h77
-rw-r--r--libpcsxcore/psemu_plugin_defs.h279
-rw-r--r--libpcsxcore/psxbios.c2399
-rw-r--r--libpcsxcore/psxbios.h43
-rw-r--r--libpcsxcore/psxcommon.h148
-rw-r--r--libpcsxcore/psxcounters.c247
-rw-r--r--libpcsxcore/psxcounters.h48
-rw-r--r--libpcsxcore/psxdma.c170
-rw-r--r--libpcsxcore/psxdma.h47
-rw-r--r--libpcsxcore/psxhle.c97
-rw-r--r--libpcsxcore/psxhle.h30
-rw-r--r--libpcsxcore/psxhw.c723
-rw-r--r--libpcsxcore/psxhw.h74
-rw-r--r--libpcsxcore/psxinterpreter.c857
-rw-r--r--libpcsxcore/psxmem.c324
-rw-r--r--libpcsxcore/psxmem.h140
-rw-r--r--libpcsxcore/r3000a.c209
-rw-r--r--libpcsxcore/r3000a.h224
-rw-r--r--libpcsxcore/sio.c673
-rw-r--r--libpcsxcore/sio.h85
-rw-r--r--libpcsxcore/spu.c30
-rw-r--r--libpcsxcore/spu.h45
-rw-r--r--libpcsxcore/system.h36
65 files changed, 39592 insertions, 0 deletions
diff --git a/libpcsxcore/Makefile.am b/libpcsxcore/Makefile.am
new file mode 100644
index 00000000..cda48978
--- /dev/null
+++ b/libpcsxcore/Makefile.am
@@ -0,0 +1,76 @@
+INCLUDES = -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -I$(top_srcdir)/include
+
+noinst_LIBRARIES = libpcsxcore.a
+
+libpcsxcore_a_SOURCES = \
+ $(top_builddir)/libpcsxcore/psxbios.c \
+ $(top_builddir)/libpcsxcore/cdrom.c \
+ $(top_builddir)/libpcsxcore/psxcounters.c \
+ $(top_builddir)/libpcsxcore/psxdma.c \
+ $(top_builddir)/libpcsxcore/disr3000a.c \
+ $(top_builddir)/libpcsxcore/spu.c \
+ $(top_builddir)/libpcsxcore/sio.c \
+ $(top_builddir)/libpcsxcore/psxhw.c \
+ $(top_builddir)/libpcsxcore/mdec.c \
+ $(top_builddir)/libpcsxcore/psxmem.c \
+ $(top_builddir)/libpcsxcore/misc.c \
+ $(top_builddir)/libpcsxcore/plugins.c \
+ $(top_builddir)/libpcsxcore/decode_xa.c \
+ $(top_builddir)/libpcsxcore/r3000a.c \
+ $(top_builddir)/libpcsxcore/psxinterpreter.c \
+ $(top_builddir)/libpcsxcore/gte.c \
+ $(top_builddir)/libpcsxcore/psxhle.c \
+ $(top_builddir)/libpcsxcore/cdrom.h \
+ $(top_builddir)/libpcsxcore/coff.h \
+ $(top_builddir)/libpcsxcore/debug.h \
+ $(top_builddir)/libpcsxcore/decode_xa.h \
+ $(top_builddir)/libpcsxcore/gte.h \
+ $(top_builddir)/libpcsxcore/mdec.h \
+ $(top_builddir)/libpcsxcore/misc.h \
+ $(top_builddir)/libpcsxcore/plugins.h \
+ $(top_builddir)/libpcsxcore/psemu_plugin_defs.h \
+ $(top_builddir)/libpcsxcore/psxbios.h \
+ $(top_builddir)/libpcsxcore/psxcommon.h \
+ $(top_builddir)/libpcsxcore/psxcounters.h \
+ $(top_builddir)/libpcsxcore/psxdma.h \
+ $(top_builddir)/libpcsxcore/psxhle.h \
+ $(top_builddir)/libpcsxcore/psxhw.h \
+ $(top_builddir)/libpcsxcore/psxmem.h \
+ $(top_builddir)/libpcsxcore/r3000a.h \
+ $(top_builddir)/libpcsxcore/sio.h \
+ $(top_builddir)/libpcsxcore/spu.h \
+ $(top_builddir)/libpcsxcore/system.h \
+ $(top_builddir)/libpcsxcore/cdriso.c \
+ $(top_builddir)/libpcsxcore/cdriso.h \
+ $(top_builddir)/libpcsxcore/cheat.c \
+ $(top_builddir)/libpcsxcore/cheat.h
+
+if ARCH_X86_64
+libpcsxcore_a_SOURCES += \
+ $(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86-64.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c \
+ $(top_builddir)/libpcsxcore/
+else
+if ARCH_X86
+libpcsxcore_a_SOURCES += \
+ $(top_builddir)/libpcsxcore/ix86/iR3000A.c \
+ $(top_builddir)/libpcsxcore/ix86/ix86.c \
+ $(top_builddir)/libpcsxcore/
+endif
+endif
+
+if ARCH_PPC
+libpcsxcore_a_SOURCES += \
+ $(top_builddir)/libpcsxcore/ppc/pR3000A.c \
+ $(top_builddir)/libpcsxcore/ppc/ppc.c \
+ $(top_builddir)/libpcsxcore/ppc/reguse.c \
+ $(top_builddir)/libpcsxcore/ppc/pasm.s \
+ $(top_builddir)/libpcsxcore/
+libpcsxcore_a_CCASFLAGS = -x assembler-with-cpp -mregnames
+endif
diff --git a/libpcsxcore/Makefile.in b/libpcsxcore/Makefile.in
new file mode 100644
index 00000000..53c18ed1
--- /dev/null
+++ b/libpcsxcore/Makefile.in
@@ -0,0 +1,1088 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@ARCH_X86_64_TRUE@am__append_1 = \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/ix86-64.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c \
+@ARCH_X86_64_TRUE@ $(top_builddir)/libpcsxcore/
+
+@ARCH_X86_64_FALSE@@ARCH_X86_TRUE@am__append_2 = \
+@ARCH_X86_64_FALSE@@ARCH_X86_TRUE@ $(top_builddir)/libpcsxcore/ix86/iR3000A.c \
+@ARCH_X86_64_FALSE@@ARCH_X86_TRUE@ $(top_builddir)/libpcsxcore/ix86/ix86.c \
+@ARCH_X86_64_FALSE@@ARCH_X86_TRUE@ $(top_builddir)/libpcsxcore/
+
+@ARCH_PPC_TRUE@am__append_3 = \
+@ARCH_PPC_TRUE@ $(top_builddir)/libpcsxcore/ppc/pR3000A.c \
+@ARCH_PPC_TRUE@ $(top_builddir)/libpcsxcore/ppc/ppc.c \
+@ARCH_PPC_TRUE@ $(top_builddir)/libpcsxcore/ppc/reguse.c \
+@ARCH_PPC_TRUE@ $(top_builddir)/libpcsxcore/ppc/pasm.s \
+@ARCH_PPC_TRUE@ $(top_builddir)/libpcsxcore/
+
+subdir = libpcsxcore
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libpcsxcore_a_AR = $(AR) $(ARFLAGS)
+libpcsxcore_a_LIBADD =
+am__libpcsxcore_a_SOURCES_DIST = \
+ $(top_builddir)/libpcsxcore/psxbios.c \
+ $(top_builddir)/libpcsxcore/cdrom.c \
+ $(top_builddir)/libpcsxcore/psxcounters.c \
+ $(top_builddir)/libpcsxcore/psxdma.c \
+ $(top_builddir)/libpcsxcore/disr3000a.c \
+ $(top_builddir)/libpcsxcore/spu.c \
+ $(top_builddir)/libpcsxcore/sio.c \
+ $(top_builddir)/libpcsxcore/psxhw.c \
+ $(top_builddir)/libpcsxcore/mdec.c \
+ $(top_builddir)/libpcsxcore/psxmem.c \
+ $(top_builddir)/libpcsxcore/misc.c \
+ $(top_builddir)/libpcsxcore/plugins.c \
+ $(top_builddir)/libpcsxcore/decode_xa.c \
+ $(top_builddir)/libpcsxcore/r3000a.c \
+ $(top_builddir)/libpcsxcore/psxinterpreter.c \
+ $(top_builddir)/libpcsxcore/gte.c \
+ $(top_builddir)/libpcsxcore/psxhle.c \
+ $(top_builddir)/libpcsxcore/cdrom.h \
+ $(top_builddir)/libpcsxcore/coff.h \
+ $(top_builddir)/libpcsxcore/debug.h \
+ $(top_builddir)/libpcsxcore/decode_xa.h \
+ $(top_builddir)/libpcsxcore/gte.h \
+ $(top_builddir)/libpcsxcore/mdec.h \
+ $(top_builddir)/libpcsxcore/misc.h \
+ $(top_builddir)/libpcsxcore/plugins.h \
+ $(top_builddir)/libpcsxcore/psemu_plugin_defs.h \
+ $(top_builddir)/libpcsxcore/psxbios.h \
+ $(top_builddir)/libpcsxcore/psxcommon.h \
+ $(top_builddir)/libpcsxcore/psxcounters.h \
+ $(top_builddir)/libpcsxcore/psxdma.h \
+ $(top_builddir)/libpcsxcore/psxhle.h \
+ $(top_builddir)/libpcsxcore/psxhw.h \
+ $(top_builddir)/libpcsxcore/psxmem.h \
+ $(top_builddir)/libpcsxcore/r3000a.h \
+ $(top_builddir)/libpcsxcore/sio.h \
+ $(top_builddir)/libpcsxcore/spu.h \
+ $(top_builddir)/libpcsxcore/system.h \
+ $(top_builddir)/libpcsxcore/cdriso.c \
+ $(top_builddir)/libpcsxcore/cdriso.h \
+ $(top_builddir)/libpcsxcore/cheat.c \
+ $(top_builddir)/libpcsxcore/cheat.h \
+ $(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86-64.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c \
+ $(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c \
+ $(top_builddir)/libpcsxcore/ \
+ $(top_builddir)/libpcsxcore/ix86/iR3000A.c \
+ $(top_builddir)/libpcsxcore/ix86/ix86.c \
+ $(top_builddir)/libpcsxcore/ppc/pR3000A.c \
+ $(top_builddir)/libpcsxcore/ppc/ppc.c \
+ $(top_builddir)/libpcsxcore/ppc/reguse.c \
+ $(top_builddir)/libpcsxcore/ppc/pasm.s
+@ARCH_X86_64_TRUE@am__objects_1 = iR3000A-64.$(OBJEXT) \
+@ARCH_X86_64_TRUE@ ix86-64.$(OBJEXT) ix86_cpudetect.$(OBJEXT) \
+@ARCH_X86_64_TRUE@ ix86_fpu.$(OBJEXT) ix86_3dnow.$(OBJEXT) \
+@ARCH_X86_64_TRUE@ ix86_mmx.$(OBJEXT) ix86_sse.$(OBJEXT)
+@ARCH_X86_64_FALSE@@ARCH_X86_TRUE@am__objects_2 = iR3000A.$(OBJEXT) \
+@ARCH_X86_64_FALSE@@ARCH_X86_TRUE@ ix86.$(OBJEXT)
+@ARCH_PPC_TRUE@am__objects_3 = pR3000A.$(OBJEXT) ppc.$(OBJEXT) \
+@ARCH_PPC_TRUE@ reguse.$(OBJEXT) libpcsxcore_a-pasm.$(OBJEXT)
+am_libpcsxcore_a_OBJECTS = psxbios.$(OBJEXT) cdrom.$(OBJEXT) \
+ psxcounters.$(OBJEXT) psxdma.$(OBJEXT) disr3000a.$(OBJEXT) \
+ spu.$(OBJEXT) sio.$(OBJEXT) psxhw.$(OBJEXT) mdec.$(OBJEXT) \
+ psxmem.$(OBJEXT) misc.$(OBJEXT) plugins.$(OBJEXT) \
+ decode_xa.$(OBJEXT) r3000a.$(OBJEXT) psxinterpreter.$(OBJEXT) \
+ gte.$(OBJEXT) psxhle.$(OBJEXT) cdriso.$(OBJEXT) \
+ cheat.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
+libpcsxcore_a_OBJECTS = $(am_libpcsxcore_a_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCCASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
+SOURCES = $(libpcsxcore_a_SOURCES)
+DIST_SOURCES = $(am__libpcsxcore_a_SOURCES_DIST)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALSA_LIBS = @ALSA_LIBS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFOPENGL = @DFOPENGL@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLADE2_CFLAGS = @GLADE2_CFLAGS@
+GLADE2_LIBS = @GLADE2_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+GTK2_CFLAGS = @GTK2_CFLAGS@
+GTK2_LIBS = @GTK2_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NASM = @NASM@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -I$(top_srcdir)/include
+
+noinst_LIBRARIES = libpcsxcore.a
+libpcsxcore_a_SOURCES = $(top_builddir)/libpcsxcore/psxbios.c \
+ $(top_builddir)/libpcsxcore/cdrom.c \
+ $(top_builddir)/libpcsxcore/psxcounters.c \
+ $(top_builddir)/libpcsxcore/psxdma.c \
+ $(top_builddir)/libpcsxcore/disr3000a.c \
+ $(top_builddir)/libpcsxcore/spu.c \
+ $(top_builddir)/libpcsxcore/sio.c \
+ $(top_builddir)/libpcsxcore/psxhw.c \
+ $(top_builddir)/libpcsxcore/mdec.c \
+ $(top_builddir)/libpcsxcore/psxmem.c \
+ $(top_builddir)/libpcsxcore/misc.c \
+ $(top_builddir)/libpcsxcore/plugins.c \
+ $(top_builddir)/libpcsxcore/decode_xa.c \
+ $(top_builddir)/libpcsxcore/r3000a.c \
+ $(top_builddir)/libpcsxcore/psxinterpreter.c \
+ $(top_builddir)/libpcsxcore/gte.c \
+ $(top_builddir)/libpcsxcore/psxhle.c \
+ $(top_builddir)/libpcsxcore/cdrom.h \
+ $(top_builddir)/libpcsxcore/coff.h \
+ $(top_builddir)/libpcsxcore/debug.h \
+ $(top_builddir)/libpcsxcore/decode_xa.h \
+ $(top_builddir)/libpcsxcore/gte.h \
+ $(top_builddir)/libpcsxcore/mdec.h \
+ $(top_builddir)/libpcsxcore/misc.h \
+ $(top_builddir)/libpcsxcore/plugins.h \
+ $(top_builddir)/libpcsxcore/psemu_plugin_defs.h \
+ $(top_builddir)/libpcsxcore/psxbios.h \
+ $(top_builddir)/libpcsxcore/psxcommon.h \
+ $(top_builddir)/libpcsxcore/psxcounters.h \
+ $(top_builddir)/libpcsxcore/psxdma.h \
+ $(top_builddir)/libpcsxcore/psxhle.h \
+ $(top_builddir)/libpcsxcore/psxhw.h \
+ $(top_builddir)/libpcsxcore/psxmem.h \
+ $(top_builddir)/libpcsxcore/r3000a.h \
+ $(top_builddir)/libpcsxcore/sio.h \
+ $(top_builddir)/libpcsxcore/spu.h \
+ $(top_builddir)/libpcsxcore/system.h \
+ $(top_builddir)/libpcsxcore/cdriso.c \
+ $(top_builddir)/libpcsxcore/cdriso.h \
+ $(top_builddir)/libpcsxcore/cheat.c \
+ $(top_builddir)/libpcsxcore/cheat.h $(am__append_1) \
+ $(am__append_2) $(am__append_3)
+@ARCH_PPC_TRUE@libpcsxcore_a_CCASFLAGS = -x assembler-with-cpp -mregnames
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libpcsxcore/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu libpcsxcore/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libpcsxcore.a: $(libpcsxcore_a_OBJECTS) $(libpcsxcore_a_DEPENDENCIES)
+ -rm -f libpcsxcore.a
+ $(libpcsxcore_a_AR) libpcsxcore.a $(libpcsxcore_a_OBJECTS) $(libpcsxcore_a_LIBADD)
+ $(RANLIB) libpcsxcore.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdriso.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cheat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode_xa.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disr3000a.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gte.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iR3000A-64.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iR3000A.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86-64.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86_3dnow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86_cpudetect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86_fpu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86_mmx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ix86_sse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pR3000A.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugins.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxbios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxcounters.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxdma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxhle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxhw.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxinterpreter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psxmem.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r3000a.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reguse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spu.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+psxbios.o: $(top_builddir)/libpcsxcore/psxbios.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxbios.o -MD -MP -MF $(DEPDIR)/psxbios.Tpo -c -o psxbios.o `test -f '$(top_builddir)/libpcsxcore/psxbios.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxbios.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxbios.Tpo $(DEPDIR)/psxbios.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxbios.c' object='psxbios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxbios.o `test -f '$(top_builddir)/libpcsxcore/psxbios.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxbios.c
+
+psxbios.obj: $(top_builddir)/libpcsxcore/psxbios.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxbios.obj -MD -MP -MF $(DEPDIR)/psxbios.Tpo -c -o psxbios.obj `if test -f '$(top_builddir)/libpcsxcore/psxbios.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxbios.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxbios.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxbios.Tpo $(DEPDIR)/psxbios.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxbios.c' object='psxbios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxbios.obj `if test -f '$(top_builddir)/libpcsxcore/psxbios.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxbios.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxbios.c'; fi`
+
+cdrom.o: $(top_builddir)/libpcsxcore/cdrom.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdrom.o -MD -MP -MF $(DEPDIR)/cdrom.Tpo -c -o cdrom.o `test -f '$(top_builddir)/libpcsxcore/cdrom.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/cdrom.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cdrom.Tpo $(DEPDIR)/cdrom.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/cdrom.c' object='cdrom.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdrom.o `test -f '$(top_builddir)/libpcsxcore/cdrom.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/cdrom.c
+
+cdrom.obj: $(top_builddir)/libpcsxcore/cdrom.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdrom.obj -MD -MP -MF $(DEPDIR)/cdrom.Tpo -c -o cdrom.obj `if test -f '$(top_builddir)/libpcsxcore/cdrom.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/cdrom.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/cdrom.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cdrom.Tpo $(DEPDIR)/cdrom.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/cdrom.c' object='cdrom.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdrom.obj `if test -f '$(top_builddir)/libpcsxcore/cdrom.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/cdrom.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/cdrom.c'; fi`
+
+psxcounters.o: $(top_builddir)/libpcsxcore/psxcounters.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxcounters.o -MD -MP -MF $(DEPDIR)/psxcounters.Tpo -c -o psxcounters.o `test -f '$(top_builddir)/libpcsxcore/psxcounters.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxcounters.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxcounters.Tpo $(DEPDIR)/psxcounters.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxcounters.c' object='psxcounters.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxcounters.o `test -f '$(top_builddir)/libpcsxcore/psxcounters.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxcounters.c
+
+psxcounters.obj: $(top_builddir)/libpcsxcore/psxcounters.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxcounters.obj -MD -MP -MF $(DEPDIR)/psxcounters.Tpo -c -o psxcounters.obj `if test -f '$(top_builddir)/libpcsxcore/psxcounters.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxcounters.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxcounters.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxcounters.Tpo $(DEPDIR)/psxcounters.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxcounters.c' object='psxcounters.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxcounters.obj `if test -f '$(top_builddir)/libpcsxcore/psxcounters.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxcounters.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxcounters.c'; fi`
+
+psxdma.o: $(top_builddir)/libpcsxcore/psxdma.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxdma.o -MD -MP -MF $(DEPDIR)/psxdma.Tpo -c -o psxdma.o `test -f '$(top_builddir)/libpcsxcore/psxdma.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxdma.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxdma.Tpo $(DEPDIR)/psxdma.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxdma.c' object='psxdma.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxdma.o `test -f '$(top_builddir)/libpcsxcore/psxdma.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxdma.c
+
+psxdma.obj: $(top_builddir)/libpcsxcore/psxdma.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxdma.obj -MD -MP -MF $(DEPDIR)/psxdma.Tpo -c -o psxdma.obj `if test -f '$(top_builddir)/libpcsxcore/psxdma.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxdma.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxdma.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxdma.Tpo $(DEPDIR)/psxdma.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxdma.c' object='psxdma.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxdma.obj `if test -f '$(top_builddir)/libpcsxcore/psxdma.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxdma.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxdma.c'; fi`
+
+disr3000a.o: $(top_builddir)/libpcsxcore/disr3000a.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT disr3000a.o -MD -MP -MF $(DEPDIR)/disr3000a.Tpo -c -o disr3000a.o `test -f '$(top_builddir)/libpcsxcore/disr3000a.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/disr3000a.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/disr3000a.Tpo $(DEPDIR)/disr3000a.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/disr3000a.c' object='disr3000a.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o disr3000a.o `test -f '$(top_builddir)/libpcsxcore/disr3000a.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/disr3000a.c
+
+disr3000a.obj: $(top_builddir)/libpcsxcore/disr3000a.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT disr3000a.obj -MD -MP -MF $(DEPDIR)/disr3000a.Tpo -c -o disr3000a.obj `if test -f '$(top_builddir)/libpcsxcore/disr3000a.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/disr3000a.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/disr3000a.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/disr3000a.Tpo $(DEPDIR)/disr3000a.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/disr3000a.c' object='disr3000a.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o disr3000a.obj `if test -f '$(top_builddir)/libpcsxcore/disr3000a.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/disr3000a.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/disr3000a.c'; fi`
+
+spu.o: $(top_builddir)/libpcsxcore/spu.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spu.o -MD -MP -MF $(DEPDIR)/spu.Tpo -c -o spu.o `test -f '$(top_builddir)/libpcsxcore/spu.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/spu.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/spu.Tpo $(DEPDIR)/spu.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/spu.c' object='spu.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spu.o `test -f '$(top_builddir)/libpcsxcore/spu.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/spu.c
+
+spu.obj: $(top_builddir)/libpcsxcore/spu.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spu.obj -MD -MP -MF $(DEPDIR)/spu.Tpo -c -o spu.obj `if test -f '$(top_builddir)/libpcsxcore/spu.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/spu.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/spu.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/spu.Tpo $(DEPDIR)/spu.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/spu.c' object='spu.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spu.obj `if test -f '$(top_builddir)/libpcsxcore/spu.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/spu.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/spu.c'; fi`
+
+sio.o: $(top_builddir)/libpcsxcore/sio.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sio.o -MD -MP -MF $(DEPDIR)/sio.Tpo -c -o sio.o `test -f '$(top_builddir)/libpcsxcore/sio.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/sio.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sio.Tpo $(DEPDIR)/sio.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/sio.c' object='sio.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sio.o `test -f '$(top_builddir)/libpcsxcore/sio.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/sio.c
+
+sio.obj: $(top_builddir)/libpcsxcore/sio.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sio.obj -MD -MP -MF $(DEPDIR)/sio.Tpo -c -o sio.obj `if test -f '$(top_builddir)/libpcsxcore/sio.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/sio.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/sio.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sio.Tpo $(DEPDIR)/sio.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/sio.c' object='sio.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sio.obj `if test -f '$(top_builddir)/libpcsxcore/sio.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/sio.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/sio.c'; fi`
+
+psxhw.o: $(top_builddir)/libpcsxcore/psxhw.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxhw.o -MD -MP -MF $(DEPDIR)/psxhw.Tpo -c -o psxhw.o `test -f '$(top_builddir)/libpcsxcore/psxhw.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxhw.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxhw.Tpo $(DEPDIR)/psxhw.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxhw.c' object='psxhw.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxhw.o `test -f '$(top_builddir)/libpcsxcore/psxhw.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxhw.c
+
+psxhw.obj: $(top_builddir)/libpcsxcore/psxhw.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxhw.obj -MD -MP -MF $(DEPDIR)/psxhw.Tpo -c -o psxhw.obj `if test -f '$(top_builddir)/libpcsxcore/psxhw.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxhw.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxhw.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxhw.Tpo $(DEPDIR)/psxhw.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxhw.c' object='psxhw.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxhw.obj `if test -f '$(top_builddir)/libpcsxcore/psxhw.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxhw.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxhw.c'; fi`
+
+mdec.o: $(top_builddir)/libpcsxcore/mdec.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mdec.o -MD -MP -MF $(DEPDIR)/mdec.Tpo -c -o mdec.o `test -f '$(top_builddir)/libpcsxcore/mdec.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/mdec.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/mdec.Tpo $(DEPDIR)/mdec.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/mdec.c' object='mdec.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mdec.o `test -f '$(top_builddir)/libpcsxcore/mdec.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/mdec.c
+
+mdec.obj: $(top_builddir)/libpcsxcore/mdec.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mdec.obj -MD -MP -MF $(DEPDIR)/mdec.Tpo -c -o mdec.obj `if test -f '$(top_builddir)/libpcsxcore/mdec.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/mdec.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/mdec.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/mdec.Tpo $(DEPDIR)/mdec.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/mdec.c' object='mdec.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mdec.obj `if test -f '$(top_builddir)/libpcsxcore/mdec.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/mdec.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/mdec.c'; fi`
+
+psxmem.o: $(top_builddir)/libpcsxcore/psxmem.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxmem.o -MD -MP -MF $(DEPDIR)/psxmem.Tpo -c -o psxmem.o `test -f '$(top_builddir)/libpcsxcore/psxmem.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxmem.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxmem.Tpo $(DEPDIR)/psxmem.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxmem.c' object='psxmem.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxmem.o `test -f '$(top_builddir)/libpcsxcore/psxmem.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxmem.c
+
+psxmem.obj: $(top_builddir)/libpcsxcore/psxmem.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxmem.obj -MD -MP -MF $(DEPDIR)/psxmem.Tpo -c -o psxmem.obj `if test -f '$(top_builddir)/libpcsxcore/psxmem.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxmem.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxmem.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxmem.Tpo $(DEPDIR)/psxmem.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxmem.c' object='psxmem.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxmem.obj `if test -f '$(top_builddir)/libpcsxcore/psxmem.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxmem.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxmem.c'; fi`
+
+misc.o: $(top_builddir)/libpcsxcore/misc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc.o -MD -MP -MF $(DEPDIR)/misc.Tpo -c -o misc.o `test -f '$(top_builddir)/libpcsxcore/misc.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/misc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/misc.Tpo $(DEPDIR)/misc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/misc.c' object='misc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc.o `test -f '$(top_builddir)/libpcsxcore/misc.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/misc.c
+
+misc.obj: $(top_builddir)/libpcsxcore/misc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc.obj -MD -MP -MF $(DEPDIR)/misc.Tpo -c -o misc.obj `if test -f '$(top_builddir)/libpcsxcore/misc.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/misc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/misc.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/misc.Tpo $(DEPDIR)/misc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/misc.c' object='misc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc.obj `if test -f '$(top_builddir)/libpcsxcore/misc.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/misc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/misc.c'; fi`
+
+plugins.o: $(top_builddir)/libpcsxcore/plugins.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugins.o -MD -MP -MF $(DEPDIR)/plugins.Tpo -c -o plugins.o `test -f '$(top_builddir)/libpcsxcore/plugins.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/plugins.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/plugins.Tpo $(DEPDIR)/plugins.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/plugins.c' object='plugins.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugins.o `test -f '$(top_builddir)/libpcsxcore/plugins.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/plugins.c
+
+plugins.obj: $(top_builddir)/libpcsxcore/plugins.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugins.obj -MD -MP -MF $(DEPDIR)/plugins.Tpo -c -o plugins.obj `if test -f '$(top_builddir)/libpcsxcore/plugins.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/plugins.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/plugins.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/plugins.Tpo $(DEPDIR)/plugins.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/plugins.c' object='plugins.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugins.obj `if test -f '$(top_builddir)/libpcsxcore/plugins.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/plugins.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/plugins.c'; fi`
+
+decode_xa.o: $(top_builddir)/libpcsxcore/decode_xa.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT decode_xa.o -MD -MP -MF $(DEPDIR)/decode_xa.Tpo -c -o decode_xa.o `test -f '$(top_builddir)/libpcsxcore/decode_xa.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/decode_xa.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/decode_xa.Tpo $(DEPDIR)/decode_xa.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/decode_xa.c' object='decode_xa.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o decode_xa.o `test -f '$(top_builddir)/libpcsxcore/decode_xa.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/decode_xa.c
+
+decode_xa.obj: $(top_builddir)/libpcsxcore/decode_xa.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT decode_xa.obj -MD -MP -MF $(DEPDIR)/decode_xa.Tpo -c -o decode_xa.obj `if test -f '$(top_builddir)/libpcsxcore/decode_xa.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/decode_xa.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/decode_xa.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/decode_xa.Tpo $(DEPDIR)/decode_xa.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/decode_xa.c' object='decode_xa.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o decode_xa.obj `if test -f '$(top_builddir)/libpcsxcore/decode_xa.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/decode_xa.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/decode_xa.c'; fi`
+
+r3000a.o: $(top_builddir)/libpcsxcore/r3000a.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT r3000a.o -MD -MP -MF $(DEPDIR)/r3000a.Tpo -c -o r3000a.o `test -f '$(top_builddir)/libpcsxcore/r3000a.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/r3000a.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/r3000a.Tpo $(DEPDIR)/r3000a.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/r3000a.c' object='r3000a.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o r3000a.o `test -f '$(top_builddir)/libpcsxcore/r3000a.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/r3000a.c
+
+r3000a.obj: $(top_builddir)/libpcsxcore/r3000a.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT r3000a.obj -MD -MP -MF $(DEPDIR)/r3000a.Tpo -c -o r3000a.obj `if test -f '$(top_builddir)/libpcsxcore/r3000a.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/r3000a.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/r3000a.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/r3000a.Tpo $(DEPDIR)/r3000a.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/r3000a.c' object='r3000a.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o r3000a.obj `if test -f '$(top_builddir)/libpcsxcore/r3000a.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/r3000a.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/r3000a.c'; fi`
+
+psxinterpreter.o: $(top_builddir)/libpcsxcore/psxinterpreter.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxinterpreter.o -MD -MP -MF $(DEPDIR)/psxinterpreter.Tpo -c -o psxinterpreter.o `test -f '$(top_builddir)/libpcsxcore/psxinterpreter.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxinterpreter.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxinterpreter.Tpo $(DEPDIR)/psxinterpreter.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxinterpreter.c' object='psxinterpreter.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxinterpreter.o `test -f '$(top_builddir)/libpcsxcore/psxinterpreter.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxinterpreter.c
+
+psxinterpreter.obj: $(top_builddir)/libpcsxcore/psxinterpreter.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxinterpreter.obj -MD -MP -MF $(DEPDIR)/psxinterpreter.Tpo -c -o psxinterpreter.obj `if test -f '$(top_builddir)/libpcsxcore/psxinterpreter.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxinterpreter.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxinterpreter.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxinterpreter.Tpo $(DEPDIR)/psxinterpreter.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxinterpreter.c' object='psxinterpreter.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxinterpreter.obj `if test -f '$(top_builddir)/libpcsxcore/psxinterpreter.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxinterpreter.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxinterpreter.c'; fi`
+
+gte.o: $(top_builddir)/libpcsxcore/gte.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gte.o -MD -MP -MF $(DEPDIR)/gte.Tpo -c -o gte.o `test -f '$(top_builddir)/libpcsxcore/gte.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/gte.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/gte.Tpo $(DEPDIR)/gte.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/gte.c' object='gte.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gte.o `test -f '$(top_builddir)/libpcsxcore/gte.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/gte.c
+
+gte.obj: $(top_builddir)/libpcsxcore/gte.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gte.obj -MD -MP -MF $(DEPDIR)/gte.Tpo -c -o gte.obj `if test -f '$(top_builddir)/libpcsxcore/gte.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/gte.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/gte.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/gte.Tpo $(DEPDIR)/gte.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/gte.c' object='gte.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gte.obj `if test -f '$(top_builddir)/libpcsxcore/gte.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/gte.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/gte.c'; fi`
+
+psxhle.o: $(top_builddir)/libpcsxcore/psxhle.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxhle.o -MD -MP -MF $(DEPDIR)/psxhle.Tpo -c -o psxhle.o `test -f '$(top_builddir)/libpcsxcore/psxhle.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxhle.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxhle.Tpo $(DEPDIR)/psxhle.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxhle.c' object='psxhle.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxhle.o `test -f '$(top_builddir)/libpcsxcore/psxhle.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/psxhle.c
+
+psxhle.obj: $(top_builddir)/libpcsxcore/psxhle.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psxhle.obj -MD -MP -MF $(DEPDIR)/psxhle.Tpo -c -o psxhle.obj `if test -f '$(top_builddir)/libpcsxcore/psxhle.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxhle.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxhle.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psxhle.Tpo $(DEPDIR)/psxhle.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/psxhle.c' object='psxhle.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psxhle.obj `if test -f '$(top_builddir)/libpcsxcore/psxhle.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/psxhle.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/psxhle.c'; fi`
+
+cdriso.o: $(top_builddir)/libpcsxcore/cdriso.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdriso.o -MD -MP -MF $(DEPDIR)/cdriso.Tpo -c -o cdriso.o `test -f '$(top_builddir)/libpcsxcore/cdriso.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/cdriso.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cdriso.Tpo $(DEPDIR)/cdriso.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/cdriso.c' object='cdriso.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdriso.o `test -f '$(top_builddir)/libpcsxcore/cdriso.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/cdriso.c
+
+cdriso.obj: $(top_builddir)/libpcsxcore/cdriso.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdriso.obj -MD -MP -MF $(DEPDIR)/cdriso.Tpo -c -o cdriso.obj `if test -f '$(top_builddir)/libpcsxcore/cdriso.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/cdriso.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/cdriso.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cdriso.Tpo $(DEPDIR)/cdriso.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/cdriso.c' object='cdriso.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdriso.obj `if test -f '$(top_builddir)/libpcsxcore/cdriso.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/cdriso.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/cdriso.c'; fi`
+
+cheat.o: $(top_builddir)/libpcsxcore/cheat.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cheat.o -MD -MP -MF $(DEPDIR)/cheat.Tpo -c -o cheat.o `test -f '$(top_builddir)/libpcsxcore/cheat.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/cheat.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cheat.Tpo $(DEPDIR)/cheat.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/cheat.c' object='cheat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cheat.o `test -f '$(top_builddir)/libpcsxcore/cheat.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/cheat.c
+
+cheat.obj: $(top_builddir)/libpcsxcore/cheat.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cheat.obj -MD -MP -MF $(DEPDIR)/cheat.Tpo -c -o cheat.obj `if test -f '$(top_builddir)/libpcsxcore/cheat.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/cheat.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/cheat.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cheat.Tpo $(DEPDIR)/cheat.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/cheat.c' object='cheat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cheat.obj `if test -f '$(top_builddir)/libpcsxcore/cheat.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/cheat.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/cheat.c'; fi`
+
+iR3000A-64.o: $(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT iR3000A-64.o -MD -MP -MF $(DEPDIR)/iR3000A-64.Tpo -c -o iR3000A-64.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/iR3000A-64.Tpo $(DEPDIR)/iR3000A-64.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c' object='iR3000A-64.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o iR3000A-64.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c
+
+iR3000A-64.obj: $(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT iR3000A-64.obj -MD -MP -MF $(DEPDIR)/iR3000A-64.Tpo -c -o iR3000A-64.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/iR3000A-64.Tpo $(DEPDIR)/iR3000A-64.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c' object='iR3000A-64.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o iR3000A-64.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/iR3000A-64.c'; fi`
+
+ix86-64.o: $(top_builddir)/libpcsxcore/ix86_64/ix86-64.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86-64.o -MD -MP -MF $(DEPDIR)/ix86-64.Tpo -c -o ix86-64.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86-64.Tpo $(DEPDIR)/ix86-64.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c' object='ix86-64.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86-64.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c
+
+ix86-64.obj: $(top_builddir)/libpcsxcore/ix86_64/ix86-64.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86-64.obj -MD -MP -MF $(DEPDIR)/ix86-64.Tpo -c -o ix86-64.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86-64.Tpo $(DEPDIR)/ix86-64.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c' object='ix86-64.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86-64.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86-64.c'; fi`
+
+ix86_cpudetect.o: $(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_cpudetect.o -MD -MP -MF $(DEPDIR)/ix86_cpudetect.Tpo -c -o ix86_cpudetect.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_cpudetect.Tpo $(DEPDIR)/ix86_cpudetect.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c' object='ix86_cpudetect.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_cpudetect.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c
+
+ix86_cpudetect.obj: $(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_cpudetect.obj -MD -MP -MF $(DEPDIR)/ix86_cpudetect.Tpo -c -o ix86_cpudetect.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_cpudetect.Tpo $(DEPDIR)/ix86_cpudetect.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c' object='ix86_cpudetect.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_cpudetect.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_cpudetect.c'; fi`
+
+ix86_fpu.o: $(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_fpu.o -MD -MP -MF $(DEPDIR)/ix86_fpu.Tpo -c -o ix86_fpu.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_fpu.Tpo $(DEPDIR)/ix86_fpu.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c' object='ix86_fpu.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_fpu.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c
+
+ix86_fpu.obj: $(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_fpu.obj -MD -MP -MF $(DEPDIR)/ix86_fpu.Tpo -c -o ix86_fpu.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_fpu.Tpo $(DEPDIR)/ix86_fpu.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c' object='ix86_fpu.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_fpu.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_fpu.c'; fi`
+
+ix86_3dnow.o: $(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_3dnow.o -MD -MP -MF $(DEPDIR)/ix86_3dnow.Tpo -c -o ix86_3dnow.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_3dnow.Tpo $(DEPDIR)/ix86_3dnow.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c' object='ix86_3dnow.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_3dnow.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c
+
+ix86_3dnow.obj: $(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_3dnow.obj -MD -MP -MF $(DEPDIR)/ix86_3dnow.Tpo -c -o ix86_3dnow.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_3dnow.Tpo $(DEPDIR)/ix86_3dnow.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c' object='ix86_3dnow.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_3dnow.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_3dnow.c'; fi`
+
+ix86_mmx.o: $(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_mmx.o -MD -MP -MF $(DEPDIR)/ix86_mmx.Tpo -c -o ix86_mmx.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_mmx.Tpo $(DEPDIR)/ix86_mmx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c' object='ix86_mmx.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_mmx.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c
+
+ix86_mmx.obj: $(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_mmx.obj -MD -MP -MF $(DEPDIR)/ix86_mmx.Tpo -c -o ix86_mmx.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_mmx.Tpo $(DEPDIR)/ix86_mmx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c' object='ix86_mmx.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_mmx.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_mmx.c'; fi`
+
+ix86_sse.o: $(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_sse.o -MD -MP -MF $(DEPDIR)/ix86_sse.Tpo -c -o ix86_sse.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_sse.Tpo $(DEPDIR)/ix86_sse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c' object='ix86_sse.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_sse.o `test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c
+
+ix86_sse.obj: $(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86_sse.obj -MD -MP -MF $(DEPDIR)/ix86_sse.Tpo -c -o ix86_sse.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86_sse.Tpo $(DEPDIR)/ix86_sse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c' object='ix86_sse.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86_sse.obj `if test -f '$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86_64/ix86_sse.c'; fi`
+
+iR3000A.o: $(top_builddir)/libpcsxcore/ix86/iR3000A.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT iR3000A.o -MD -MP -MF $(DEPDIR)/iR3000A.Tpo -c -o iR3000A.o `test -f '$(top_builddir)/libpcsxcore/ix86/iR3000A.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86/iR3000A.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/iR3000A.Tpo $(DEPDIR)/iR3000A.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86/iR3000A.c' object='iR3000A.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o iR3000A.o `test -f '$(top_builddir)/libpcsxcore/ix86/iR3000A.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86/iR3000A.c
+
+iR3000A.obj: $(top_builddir)/libpcsxcore/ix86/iR3000A.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT iR3000A.obj -MD -MP -MF $(DEPDIR)/iR3000A.Tpo -c -o iR3000A.obj `if test -f '$(top_builddir)/libpcsxcore/ix86/iR3000A.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86/iR3000A.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86/iR3000A.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/iR3000A.Tpo $(DEPDIR)/iR3000A.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86/iR3000A.c' object='iR3000A.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o iR3000A.obj `if test -f '$(top_builddir)/libpcsxcore/ix86/iR3000A.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86/iR3000A.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86/iR3000A.c'; fi`
+
+ix86.o: $(top_builddir)/libpcsxcore/ix86/ix86.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86.o -MD -MP -MF $(DEPDIR)/ix86.Tpo -c -o ix86.o `test -f '$(top_builddir)/libpcsxcore/ix86/ix86.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86/ix86.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86.Tpo $(DEPDIR)/ix86.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86/ix86.c' object='ix86.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86.o `test -f '$(top_builddir)/libpcsxcore/ix86/ix86.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ix86/ix86.c
+
+ix86.obj: $(top_builddir)/libpcsxcore/ix86/ix86.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ix86.obj -MD -MP -MF $(DEPDIR)/ix86.Tpo -c -o ix86.obj `if test -f '$(top_builddir)/libpcsxcore/ix86/ix86.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86/ix86.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86/ix86.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ix86.Tpo $(DEPDIR)/ix86.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ix86/ix86.c' object='ix86.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ix86.obj `if test -f '$(top_builddir)/libpcsxcore/ix86/ix86.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ix86/ix86.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ix86/ix86.c'; fi`
+
+pR3000A.o: $(top_builddir)/libpcsxcore/ppc/pR3000A.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pR3000A.o -MD -MP -MF $(DEPDIR)/pR3000A.Tpo -c -o pR3000A.o `test -f '$(top_builddir)/libpcsxcore/ppc/pR3000A.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/pR3000A.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pR3000A.Tpo $(DEPDIR)/pR3000A.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppc/pR3000A.c' object='pR3000A.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pR3000A.o `test -f '$(top_builddir)/libpcsxcore/ppc/pR3000A.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/pR3000A.c
+
+pR3000A.obj: $(top_builddir)/libpcsxcore/ppc/pR3000A.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pR3000A.obj -MD -MP -MF $(DEPDIR)/pR3000A.Tpo -c -o pR3000A.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/pR3000A.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/pR3000A.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/pR3000A.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pR3000A.Tpo $(DEPDIR)/pR3000A.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppc/pR3000A.c' object='pR3000A.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pR3000A.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/pR3000A.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/pR3000A.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/pR3000A.c'; fi`
+
+ppc.o: $(top_builddir)/libpcsxcore/ppc/ppc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ppc.o -MD -MP -MF $(DEPDIR)/ppc.Tpo -c -o ppc.o `test -f '$(top_builddir)/libpcsxcore/ppc/ppc.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/ppc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ppc.Tpo $(DEPDIR)/ppc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppc/ppc.c' object='ppc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ppc.o `test -f '$(top_builddir)/libpcsxcore/ppc/ppc.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/ppc.c
+
+ppc.obj: $(top_builddir)/libpcsxcore/ppc/ppc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ppc.obj -MD -MP -MF $(DEPDIR)/ppc.Tpo -c -o ppc.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/ppc.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/ppc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/ppc.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ppc.Tpo $(DEPDIR)/ppc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppc/ppc.c' object='ppc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ppc.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/ppc.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/ppc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/ppc.c'; fi`
+
+reguse.o: $(top_builddir)/libpcsxcore/ppc/reguse.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reguse.o -MD -MP -MF $(DEPDIR)/reguse.Tpo -c -o reguse.o `test -f '$(top_builddir)/libpcsxcore/ppc/reguse.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/reguse.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/reguse.Tpo $(DEPDIR)/reguse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppc/reguse.c' object='reguse.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reguse.o `test -f '$(top_builddir)/libpcsxcore/ppc/reguse.c' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/reguse.c
+
+reguse.obj: $(top_builddir)/libpcsxcore/ppc/reguse.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reguse.obj -MD -MP -MF $(DEPDIR)/reguse.Tpo -c -o reguse.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/reguse.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/reguse.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/reguse.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/reguse.Tpo $(DEPDIR)/reguse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_builddir)/libpcsxcore/ppc/reguse.c' object='reguse.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reguse.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/reguse.c'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/reguse.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/reguse.c'; fi`
+
+.s.o:
+ $(CCASCOMPILE) -c -o $@ $<
+
+.s.obj:
+ $(CCASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.s.lo:
+ $(LTCCASCOMPILE) -c -o $@ $<
+
+libpcsxcore_a-pasm.o: $(top_builddir)/libpcsxcore/ppc/pasm.s
+ $(CCAS) $(libpcsxcore_a_CCASFLAGS) $(CCASFLAGS) -c -o libpcsxcore_a-pasm.o `test -f '$(top_builddir)/libpcsxcore/ppc/pasm.s' || echo '$(srcdir)/'`$(top_builddir)/libpcsxcore/ppc/pasm.s
+
+libpcsxcore_a-pasm.obj: $(top_builddir)/libpcsxcore/ppc/pasm.s
+ $(CCAS) $(libpcsxcore_a_CCASFLAGS) $(CCASFLAGS) -c -o libpcsxcore_a-pasm.obj `if test -f '$(top_builddir)/libpcsxcore/ppc/pasm.s'; then $(CYGPATH_W) '$(top_builddir)/libpcsxcore/ppc/pasm.s'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/libpcsxcore/ppc/pasm.s'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
new file mode 100644
index 00000000..8de93763
--- /dev/null
+++ b/libpcsxcore/cdriso.c
@@ -0,0 +1,305 @@
+/***************************************************************************
+ * Copyright (C) 2007 PCSX-df Team *
+ * Copyright (C) 2009 Wei Mingzhi *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+// TODO: implement CDDA & subchannel support.
+
+#include "psxcommon.h"
+#include "plugins.h"
+
+#define MSF2SECT(m, s, f) (((m) * 60 + (s) - 2) * 75 + (f))
+#define btoi(b) ((b) / 16 * 10 + (b) % 16) /* BCD to u_char */
+
+#define CD_FRAMESIZE_RAW 2352
+#define DATA_SIZE (CD_FRAMESIZE_RAW - 12)
+
+FILE *cdHandle = NULL;
+static unsigned char cdbuffer[CD_FRAMESIZE_RAW * 10];
+
+char* CALLBACK CDR__getDriveLetter(void);
+unsigned char* CALLBACK CDR__getBufferSub(void);
+long CALLBACK CDR__configure(void);
+long CALLBACK CDR__test(void);
+void CALLBACK CDR__about(void);
+long CALLBACK CDR__setfilename(char *filename);
+long CALLBACK CDR__getStatus(struct CdrStat *stat);
+
+extern void *hCDRDriver;
+
+struct trackinfo {
+ enum {DATA, CDDA} type;
+ char start[3]; // MSF-format
+ char length[3]; // MSF-format
+ char gap[3]; // MSF-format
+};
+
+#define MAXTRACKS 100 /* How many tracks can a CD hold? */
+
+static int numtracks = 0;
+static struct trackinfo ti[MAXTRACKS];
+
+// get a sector from a msf-array
+static unsigned int msf2sec(char *msf) {
+ return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
+}
+
+static void sec2msf(unsigned int s, char *msf) {
+ msf[0] = s / 75 / 60;
+ s = s - msf[0] * 75 * 60;
+ msf[1] = s / 75;
+ s = s - msf[1] * 75;
+ msf[2] = s;
+}
+
+// get size of a track given the sector
+unsigned int ISOgetTrackLength(unsigned int s) {
+ int i = 1;
+
+ while ((msf2sec(ti[i].start) < s) && i <= numtracks)
+ i++;
+
+ return msf2sec(ti[--i].length);
+}
+
+// divide a string of xx:yy:zz into m, s, f
+static void tok2msf(char *time, char *msf) {
+ char *token;
+
+ token = strtok(time, ":");
+ if (token)
+ msf[0] = atoi(token);
+ else
+ msf[0]=0;
+
+ token = strtok(NULL, ":");
+ if (token)
+ msf[1] = atoi(token);
+ else
+ msf[1]=0;
+
+ token = strtok(NULL, ":");
+ if (token)
+ msf[2] = atoi(token);
+ else
+ msf[2]=0;
+}
+
+// this function tries to get the .toc file of the given .bin
+// the neccessary data is put into the ti (trackinformation)-array
+static int parsetoc(char *isofile) {
+ char tocname[MAXPATHLEN];
+ FILE *fi;
+ char linebuf[256], dummy[256];
+ char *token;
+ char name[256];
+ char time[20], time2[20];
+ unsigned int i, t;
+
+ numtracks = 0;
+
+ // copy name of the iso and change extension from .bin to .toc
+ strncpy(tocname, isofile, sizeof(tocname));
+ token = strstr(tocname, ".bin");
+ if (token)
+ sprintf((char *)token, ".toc");
+ else
+ return -1;
+
+ if ((fi = fopen(tocname, "r")) == NULL) {
+ SysPrintf(_("Could not open %s.\n"), tocname);
+ return -1;
+ }
+
+ memset(&ti, 0, sizeof(ti));
+
+ // parse the .toc file
+ while (fgets(linebuf, sizeof(linebuf), fi) != NULL) {
+ // search for tracks
+ strncpy(dummy, linebuf, sizeof(linebuf));
+ token = strtok(dummy, " ");
+
+ // a new track is found
+ if (!strcmp(token, "TRACK")) {
+ // get type of track
+ token = strtok(NULL, " ");
+
+ numtracks++;
+
+ if (!strcmp(token, "MODE2_RAW\n")) {
+ ti[numtracks].type = DATA;
+ sec2msf(2 * 75, ti[numtracks].start); // assume data track on 0:2:0
+ }
+
+ if (!strcmp(token, "AUDIO\n"))
+ ti[numtracks].type = CDDA;
+ }
+
+ // interpretation of other lines
+ if (!strcmp(token, "DATAFILE")) {
+ sscanf(linebuf, "DATAFILE %s %s", name, time);
+ tok2msf((char *)&time, (char *)&ti[numtracks].length);
+ }
+
+ if (!strcmp(token, "FILE")) {
+ sscanf(linebuf, "FILE %s %s %s %s", name, dummy, time, time2);
+ tok2msf((char *)&time, (char *)&ti[numtracks].start);
+ tok2msf((char *)&time2, (char *)&ti[numtracks].length);
+ }
+
+ if (!strcmp(token, "START")) {
+ sscanf(linebuf, "START %s", time);
+ tok2msf((char *)&time, (char *)&ti[numtracks].gap);
+ }
+ }
+
+ fclose(fi);
+
+ // calculate the true start of each track
+ // start+gap+datasize (+2 secs of silence ? I dunno...)
+ for(i = 2; i <= numtracks; i++) {
+ t = msf2sec(ti[1].start) + msf2sec(ti[1].length) + msf2sec(ti[i].start) + msf2sec(ti[i].gap);
+ sec2msf(t, ti[i].start);
+ }
+
+ return 0;
+}
+
+static long CALLBACK ISOinit(void) {
+ assert(cdHandle == NULL);
+ return 0; // do nothing
+}
+
+static long CALLBACK ISOshutdown(void) {
+ if (cdHandle != NULL) {
+ fclose(cdHandle);
+ cdHandle = NULL;
+ }
+ return 0;
+}
+
+// This function is invoked by the front-end when opening an ISO
+// file for playback
+static long CALLBACK ISOopen(void) {
+ if (cdHandle != NULL)
+ return 0; // it's already open
+
+ cdHandle = fopen(cdrfilename, "rb");
+ if (cdHandle == NULL)
+ return -1;
+
+ parsetoc(cdrfilename);
+ return 0;
+}
+
+static long CALLBACK ISOclose(void) {
+ if (cdHandle != NULL) {
+ fclose(cdHandle);
+ cdHandle = NULL;
+ }
+ return 0;
+}
+
+// return Starting and Ending Track
+// buffer:
+// byte 0 - start track
+// byte 1 - end track
+static long CALLBACK ISOgetTN(unsigned char *buffer) {
+ buffer[0] = 1;
+
+ if (numtracks > 0)
+ buffer[1] = numtracks;
+ else
+ buffer[1] = 1;
+
+ return 0;
+}
+
+// return Track Time
+// buffer:
+// byte 0 - frame
+// byte 1 - second
+// byte 2 - minute
+static long CALLBACK ISOgetTD(unsigned char track, unsigned char *buffer) {
+ if (numtracks > 0 && track <= numtracks) {
+ buffer[2] = ti[track].start[0];
+ buffer[1] = ti[track].start[1];
+ buffer[0] = ti[track].start[2];
+ } else {
+ buffer[2] = 0;
+ buffer[1] = 2;
+ buffer[0] = 0;
+ }
+
+ return 0;
+}
+
+// read track
+// time: byte 0 - minute; byte 1 - second; byte 2 - frame
+// uses bcd format
+static long CALLBACK ISOreadTrack(unsigned char *time) {
+ if (cdHandle == NULL)
+ return -1;
+
+ fseek(cdHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * CD_FRAMESIZE_RAW + 12, SEEK_SET);
+ fread(cdbuffer, 1, DATA_SIZE, cdHandle);
+
+ return 0;
+}
+
+// return readed track
+static unsigned char * CALLBACK ISOgetBuffer(void) {
+ return (unsigned char *)&cdbuffer;
+}
+
+// plays cdda audio
+// sector: byte 0 - minute; byte 1 - second; byte 2 - frame
+// does NOT uses bcd format
+static long CALLBACK ISOplay(unsigned char *time) {
+ return 0; // TODO
+}
+
+// stops cdda audio
+static long CALLBACK ISOstop(void) {
+ return 0; // TODO
+}
+
+void imageReaderInit(void) {
+ assert(hCDRDriver == NULL);
+
+ CDR_init = ISOinit;
+ CDR_shutdown = ISOshutdown;
+ CDR_open = ISOopen;
+ CDR_close = ISOclose;
+ CDR_getTN = ISOgetTN;
+ CDR_getTD = ISOgetTD;
+ CDR_readTrack = ISOreadTrack;
+ CDR_getBuffer = ISOgetBuffer;
+ CDR_play = ISOplay;
+ CDR_stop = ISOstop;
+
+ CDR_getStatus = CDR__getStatus;
+ CDR_getDriveLetter = CDR__getDriveLetter;
+ CDR_getBufferSub = CDR__getBufferSub;
+ CDR_configure = CDR__configure;
+ CDR_test = CDR__test;
+ CDR_about = CDR__about;
+ CDR_setfilename = CDR__setfilename;
+
+ numtracks = 0;
+}
diff --git a/libpcsxcore/cdriso.h b/libpcsxcore/cdriso.h
new file mode 100644
index 00000000..ca5d2bfd
--- /dev/null
+++ b/libpcsxcore/cdriso.h
@@ -0,0 +1,27 @@
+/***************************************************************************
+ * Copyright (C) 2007 PCSX-df Team *
+ * Copyright (C) 2009 Wei Mingzhi *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef CDRISO_H
+#define CDRISO_H
+
+int imageReaderInit(void);
+unsigned int ISOgetTrackLength(unsigned int s);
+
+#endif
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c
new file mode 100644
index 00000000..44e4a3d9
--- /dev/null
+++ b/libpcsxcore/cdrom.c
@@ -0,0 +1,1105 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Handles all CD-ROM registers and functions.
+*/
+
+#include "cdrom.h"
+
+/* CD-ROM magic numbers */
+#define CdlSync 0
+#define CdlNop 1
+#define CdlSetloc 2
+#define CdlPlay 3
+#define CdlForward 4
+#define CdlBackward 5
+#define CdlReadN 6
+#define CdlStandby 7
+#define CdlStop 8
+#define CdlPause 9
+#define CdlInit 10
+#define CdlMute 11
+#define CdlDemute 12
+#define CdlSetfilter 13
+#define CdlSetmode 14
+#define CdlGetmode 15
+#define CdlGetlocL 16
+#define CdlGetlocP 17
+#define Cdl18 18
+#define CdlGetTN 19
+#define CdlGetTD 20
+#define CdlSeekL 21
+#define CdlSeekP 22
+#define CdlTest 25
+#define CdlID 26
+#define CdlReadS 27
+#define CdlReset 28
+#define CdlReadToc 30
+
+#define AUTOPAUSE 249
+#define READ_ACK 250
+#define READ 251
+#define REPPLAY_ACK 252
+#define REPPLAY 253
+#define ASYNC 254
+/* don't set 255, it's reserved */
+
+char *CmdName[0x100]= {
+ "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay",
+ "CdlForward", "CdlBackward", "CdlReadN", "CdlStandby",
+ "CdlStop", "CdlPause", "CdlInit", "CdlMute",
+ "CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetmode",
+ "CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN",
+ "CdlGetTD", "CdlSeekL", "CdlSeekP", NULL,
+ NULL, "CdlTest", "CdlID", "CdlReadS",
+ "CdlReset", NULL, "CDlReadToc", NULL
+};
+
+unsigned char Test04[] = { 0 };
+unsigned char Test05[] = { 0 };
+unsigned char Test20[] = { 0x98, 0x06, 0x10, 0xC3 };
+unsigned char Test22[] = { 0x66, 0x6F, 0x72, 0x20, 0x45, 0x75, 0x72, 0x6F };
+unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 };
+
+// 1x = 75 sectors per second
+// PSXCLK = 1 sec in the ps
+// so (PSXCLK / 75) / BIAS = cdr read time (linuzappz)
+#define cdReadTime ((PSXCLK / 75) / BIAS)
+
+#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
+#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
+
+static struct CdrStat stat;
+static struct SubQ *subq;
+
+#define CDR_INT(eCycle) { \
+ psxRegs.interrupt |= 0x4; \
+ psxRegs.intCycle[2 + 1] = eCycle; \
+ psxRegs.intCycle[2] = psxRegs.cycle; }
+
+#define CDREAD_INT(eCycle) { \
+ psxRegs.interrupt |= 0x40000; \
+ psxRegs.intCycle[2 + 16 + 1] = eCycle; \
+ psxRegs.intCycle[2 + 16] = psxRegs.cycle; }
+
+#define StartReading(type) { \
+ cdr.Reading = type; \
+ cdr.FirstSector = 1; \
+ cdr.Readed = 0xff; \
+ AddIrqQueue(READ_ACK, 0x800); \
+}
+
+#define StopReading() { \
+ if (cdr.Reading) { \
+ cdr.Reading = 0; \
+ psxRegs.interrupt &= ~0x40000; \
+ } \
+}
+
+#define StopCdda() { \
+ if (cdr.Play) { \
+ if (!Config.Cdda) CDR_stop(); \
+ cdr.StatP &= ~0x80; \
+ cdr.Play = 0; \
+ } \
+}
+
+#define SetResultSize(size) { \
+ cdr.ResultP = 0; \
+ cdr.ResultC = size; \
+ cdr.ResultReady = 1; \
+}
+
+void ReadTrack() {
+ cdr.Prev[0] = itob(cdr.SetSector[0]);
+ cdr.Prev[1] = itob(cdr.SetSector[1]);
+ cdr.Prev[2] = itob(cdr.SetSector[2]);
+
+#ifdef CDR_LOG
+ CDR_LOG("ReadTrack() Log: KEY *** %x:%x:%x\n", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]);
+#endif
+ cdr.RErr = CDR_readTrack(cdr.Prev);
+}
+
+// cdr.Stat:
+#define NoIntr 0
+#define DataReady 1
+#define Complete 2
+#define Acknowledge 3
+#define DataEnd 4
+#define DiskError 5
+
+void AddIrqQueue(unsigned char irq, unsigned long ecycle) {
+ cdr.Irq = irq;
+ if (cdr.Stat) {
+ cdr.eCycle = ecycle;
+ } else {
+ CDR_INT(ecycle);
+ }
+}
+
+void cdrInterrupt() {
+ int i;
+ unsigned char Irq = cdr.Irq;
+
+ if (cdr.Stat) {
+ CDR_INT(0x800);
+ return;
+ }
+
+ cdr.Irq = 0xff;
+ cdr.Ctrl &= ~0x80;
+
+ switch (Irq) {
+ case CdlSync:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlNop:
+ SetResultSize(1);
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ i = stat.Status;
+ if (CDR_getStatus(&stat) != -1) {
+ if (stat.Type == 0xff) cdr.Stat = DiskError;
+ if (stat.Status & 0x10) {
+ cdr.Stat = DiskError;
+ cdr.Result[0] |= 0x11;
+ cdr.Result[0] &= ~0x02;
+ }
+ else if (i & 0x10) {
+ cdr.StatP |= 0x2;
+ cdr.Result[0] |= 0x2;
+ CheckCdrom();
+ }
+ }
+ break;
+
+ case CdlSetloc:
+ cdr.CmdProcess = 0;
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlPlay:
+ cdr.CmdProcess = 0;
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ cdr.StatP |= 0x80;
+// if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime);
+ break;
+
+ case CdlForward:
+ cdr.CmdProcess = 0;
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case CdlBackward:
+ cdr.CmdProcess = 0;
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case CdlStandby:
+ cdr.CmdProcess = 0;
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case CdlStop:
+ cdr.CmdProcess = 0;
+ SetResultSize(1);
+ cdr.StatP &= ~0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+// cdr.Stat = Acknowledge;
+ break;
+
+ case CdlPause:
+ SetResultSize(1);
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ AddIrqQueue(CdlPause + 0x20, 0x800);
+ cdr.Ctrl |= 0x80;
+ break;
+
+ case CdlPause + 0x20:
+ SetResultSize(1);
+ cdr.StatP &= ~0x20;
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case CdlInit:
+ SetResultSize(1);
+ cdr.StatP = 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+// if (!cdr.Init) {
+ AddIrqQueue(CdlInit + 0x20, 0x800);
+// }
+ break;
+
+ case CdlInit + 0x20:
+ SetResultSize(1);
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ cdr.Init = 1;
+ break;
+
+ case CdlMute:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlDemute:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlSetfilter:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlSetmode:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlGetmode:
+ SetResultSize(6);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Result[1] = cdr.Mode;
+ cdr.Result[2] = cdr.File;
+ cdr.Result[3] = cdr.Channel;
+ cdr.Result[4] = 0;
+ cdr.Result[5] = 0;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlGetlocL:
+ SetResultSize(8);
+// for (i = 0; i < 8; i++)
+// cdr.Result[i] = itob(cdr.Transfer[i]);
+ for (i = 0; i < 8; i++)
+ cdr.Result[i] = cdr.Transfer[i];
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlGetlocP:
+ SetResultSize(8);
+ subq = (struct SubQ *)CDR_getBufferSub();
+ if (subq != NULL) {
+ cdr.Result[0] = subq->TrackNumber;
+ cdr.Result[1] = subq->IndexNumber;
+ memcpy(cdr.Result + 2, subq->TrackRelativeAddress, 3);
+ memcpy(cdr.Result + 5, subq->AbsoluteAddress, 3);
+ } else {
+ cdr.Result[0] = 1;
+ cdr.Result[1] = 1;
+ cdr.Result[2] = cdr.Prev[0];
+ cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2);
+ cdr.Result[4] = cdr.Prev[2];
+ memcpy(cdr.Result + 5, cdr.Prev, 3);
+ }
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlGetTN:
+ cdr.CmdProcess = 0;
+ SetResultSize(3);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ if (CDR_getTN(cdr.ResultTN) == -1) {
+ cdr.Stat = DiskError;
+ cdr.Result[0] |= 0x01;
+ } else {
+ cdr.Stat = Acknowledge;
+ cdr.Result[1] = itob(cdr.ResultTN[0]);
+ cdr.Result[2] = itob(cdr.ResultTN[1]);
+ }
+ break;
+
+ case CdlGetTD:
+ cdr.CmdProcess = 0;
+ cdr.Track = btoi(cdr.Param[0]);
+ SetResultSize(4);
+ cdr.StatP|= 0x2;
+ if (CDR_getTD(cdr.Track, cdr.ResultTD) == -1) {
+ cdr.Stat = DiskError;
+ cdr.Result[0] |= 0x01;
+ } else {
+ cdr.Stat = Acknowledge;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Result[1] = itob(cdr.ResultTD[2]);
+ cdr.Result[2] = itob(cdr.ResultTD[1]);
+ cdr.Result[3] = itob(cdr.ResultTD[0]);
+ }
+ break;
+
+ case CdlSeekL:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.StatP |= 0x40;
+ cdr.Stat = Acknowledge;
+ cdr.Seeked = 1;
+ AddIrqQueue(CdlSeekL + 0x20, 0x800);
+ break;
+
+ case CdlSeekL + 0x20:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.StatP &= ~0x40;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case CdlSeekP:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.StatP |= 0x40;
+ cdr.Stat = Acknowledge;
+ AddIrqQueue(CdlSeekP + 0x20, 0x800);
+ break;
+
+ case CdlSeekP + 0x20:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.StatP &= ~0x40;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case CdlTest:
+ cdr.Stat = Acknowledge;
+ switch (cdr.Param[0]) {
+ case 0x20: // System Controller ROM Version
+ SetResultSize(4);
+ memcpy(cdr.Result, Test20, 4);
+ break;
+ case 0x22:
+ SetResultSize(8);
+ memcpy(cdr.Result, Test22, 4);
+ break;
+ case 0x23: case 0x24:
+ SetResultSize(8);
+ memcpy(cdr.Result, Test23, 4);
+ break;
+ }
+ break;
+
+ case CdlID:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ AddIrqQueue(CdlID + 0x20, 0x800);
+ break;
+
+ case CdlID + 0x20:
+ SetResultSize(8);
+ if (CDR_getStatus(&stat) == -1) {
+ cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player
+ cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD
+ }
+ else {
+ if (stat.Type == 2) {
+ cdr.Result[0] = 0x08;
+ cdr.Result[1] = 0x10;
+ }
+ else {
+ cdr.Result[0] = 0x00;
+ cdr.Result[1] = 0x00;
+ }
+ }
+ cdr.Result[1] |= 0x80;
+ cdr.Result[2] = 0x00;
+ cdr.Result[3] = 0x00;
+ strncpy((char *)&cdr.Result[4], "PCSX", 4);
+ cdr.Stat = Complete;
+ break;
+
+ case CdlReset:
+ SetResultSize(1);
+ cdr.StatP = 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ break;
+
+ case CdlReadToc:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Acknowledge;
+ AddIrqQueue(CdlReadToc + 0x20, 0x800);
+ break;
+
+ case CdlReadToc + 0x20:
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = Complete;
+ break;
+
+ case AUTOPAUSE:
+ cdr.OCUP = 0;
+/* SetResultSize(1);
+ StopCdda();
+ StopReading();
+ cdr.OCUP = 0;
+ cdr.StatP&=~0x20;
+ cdr.StatP|= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ cdr.Stat = DataEnd;
+*/ AddIrqQueue(CdlPause, 0x400);
+ break;
+
+ case READ_ACK:
+ if (!cdr.Reading) return;
+
+ SetResultSize(1);
+ cdr.StatP |= 0x2;
+ cdr.Result[0] = cdr.StatP;
+ if (cdr.Seeked == 0) {
+ cdr.Seeked = 1;
+ cdr.StatP|= 0x40;
+ }
+ cdr.StatP |= 0x20;
+ cdr.Stat = Acknowledge;
+
+ ReadTrack();
+
+// CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
+ CDREAD_INT(0x40000);
+ break;
+
+ case REPPLAY_ACK:
+ cdr.Stat = Acknowledge;
+ cdr.Result[0] = cdr.StatP;
+ SetResultSize(1);
+ AddIrqQueue(REPPLAY, cdReadTime);
+ break;
+
+ case REPPLAY:
+ if ((cdr.Mode & 5) != 5) break;
+/* if (CDR_getStatus(&stat) == -1) {
+ cdr.Result[0] = 0;
+ cdr.Result[1] = 0;
+ cdr.Result[2] = 0;
+ cdr.Result[3] = 0;
+ cdr.Result[4] = 0;
+ cdr.Result[5] = 0;
+ cdr.Result[6] = 0;
+ cdr.Result[7] = 0;
+ } else memcpy(cdr.Result, &stat.Track, 8);
+ cdr.Stat = 1;
+ SetResultSize(8);
+ AddIrqQueue(REPPLAY_ACK, cdReadTime);
+*/ break;
+
+ case 0xff:
+ return;
+
+ default:
+ cdr.Stat = Complete;
+ break;
+ }
+
+ if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) {
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+ psxRegs.interrupt |= 0x80000000;
+ }
+
+#ifdef CDR_LOG
+ CDR_LOG("cdrInterrupt() Log: CDR Interrupt IRQ %x\n", Irq);
+#endif
+}
+
+void cdrReadInterrupt() {
+ u8 *buf;
+
+ if (!cdr.Reading)
+ return;
+
+ if (cdr.Stat) {
+ CDREAD_INT(0x800);
+ return;
+ }
+
+#ifdef CDR_LOG
+ CDR_LOG("cdrReadInterrupt() Log: KEY END");
+#endif
+
+ cdr.OCUP = 1;
+ SetResultSize(1);
+ cdr.StatP |= 0x22;
+ cdr.StatP &= ~0x40;
+ cdr.Result[0] = cdr.StatP;
+
+ buf = CDR_getBuffer();
+ if (buf == NULL)
+ cdr.RErr = -1;
+
+ if (cdr.RErr == -1) {
+#ifdef CDR_LOG
+ fprintf(emuLog, "cdrReadInterrupt() Log: err\n");
+#endif
+ memset(cdr.Transfer, 0, 2340);
+ cdr.Stat = DiskError;
+ cdr.Result[0] |= 0x01;
+ ReadTrack();
+ CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
+ return;
+ }
+
+ memcpy(cdr.Transfer, buf, 2340);
+ cdr.Stat = DataReady;
+
+#ifdef CDR_LOG
+ fprintf(emuLog, "cdrReadInterrupt() Log: cdr.Transfer %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]);
+#endif
+
+ if ((cdr.Muted == 1) && (cdr.Mode & 0x40) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA
+ if ((cdr.Transfer[4 + 2] & 0x4) &&
+ ((cdr.Mode & 0x8) ? (cdr.Transfer[4 + 1] == cdr.Channel) : 1) &&
+ (cdr.Transfer[4 + 0] == cdr.File)) {
+ int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector);
+
+ if (!ret) {
+ SPU_playADPCMchannel(&cdr.Xa);
+ cdr.FirstSector = 0;
+ }
+ else cdr.FirstSector = -1;
+ }
+ }
+
+ cdr.SetSector[2]++;
+ if (cdr.SetSector[2] == 75) {
+ cdr.SetSector[2] = 0;
+ cdr.SetSector[1]++;
+ if (cdr.SetSector[1] == 60) {
+ cdr.SetSector[1] = 0;
+ cdr.SetSector[0]++;
+ }
+ }
+
+ cdr.Readed = 0;
+
+ if ((cdr.Transfer[4 + 2] & 0x80) && (cdr.Mode & 0x2)) { // EOF
+#ifdef CDR_LOG
+ CDR_LOG("cdrReadInterrupt() Log: Autopausing read\n");
+#endif
+// AddIrqQueue(AUTOPAUSE, 0x800);
+ AddIrqQueue(CdlPause, 0x800);
+ }
+ else {
+ ReadTrack();
+ CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
+ }
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+ psxRegs.interrupt |= 0x80000000;
+}
+
+/*
+cdrRead0:
+ bit 0 - 0 REG1 command send / 1 REG1 data read
+ bit 1 - 0 data transfer finish / 1 data transfer ready/in progress
+ bit 2 - unknown
+ bit 3 - unknown
+ bit 4 - unknown
+ bit 5 - 1 result ready
+ bit 6 - 1 dma ready
+ bit 7 - 1 command being processed
+*/
+
+unsigned char cdrRead0(void) {
+ if (cdr.ResultReady)
+ cdr.Ctrl |= 0x20;
+ else
+ cdr.Ctrl &= ~0x20;
+
+ if (cdr.OCUP)
+ cdr.Ctrl |= 0x40;
+// else
+// cdr.Ctrl &= ~0x40;
+
+ // What means the 0x10 and the 0x08 bits? I only saw it used by the bios
+ cdr.Ctrl |= 0x18;
+
+#ifdef CDR_LOG
+ CDR_LOG("cdrRead0() Log: CD0 Read: %x\n", cdr.Ctrl);
+#endif
+
+ return psxHu8(0x1800) = cdr.Ctrl;
+}
+
+/*
+cdrWrite0:
+ 0 - to send a command / 1 - to get the result
+*/
+
+void cdrWrite0(unsigned char rt) {
+#ifdef CDR_LOG
+ CDR_LOG("cdrWrite0() Log: CD0 write: %x\n", rt);
+#endif
+ cdr.Ctrl = rt | (cdr.Ctrl & ~0x3);
+
+ if (rt == 0) {
+ cdr.ParamP = 0;
+ cdr.ParamC = 0;
+ cdr.ResultReady = 0;
+ }
+}
+
+unsigned char cdrRead1(void) {
+ if (cdr.ResultReady) { // && cdr.Ctrl & 0x1) {
+ psxHu8(0x1801) = cdr.Result[cdr.ResultP++];
+ if (cdr.ResultP == cdr.ResultC)
+ cdr.ResultReady = 0;
+ } else {
+ psxHu8(0x1801) = 0;
+ }
+#ifdef CDR_LOG
+ CDR_LOG("cdrRead1() Log: CD1 Read: %x\n", psxHu8(0x1801));
+#endif
+ return psxHu8(0x1801);
+}
+
+void cdrWrite1(unsigned char rt) {
+ int i;
+
+#ifdef CDR_LOG
+ CDR_LOG("cdrWrite1() Log: CD1 write: %x (%s)\n", rt, CmdName[rt]);
+#endif
+// psxHu8(0x1801) = rt;
+ cdr.Cmd = rt;
+ cdr.OCUP = 0;
+
+#ifdef CDRCMD_DEBUG
+ SysPrintf("cdrWrite1() Log: CD1 write: %x (%s)", rt, CmdName[rt]);
+ if (cdr.ParamC) {
+ SysPrintf(" Param[%d] = {", cdr.ParamC);
+ for (i = 0; i < cdr.ParamC; i++)
+ SysPrintf(" %x,", cdr.Param[i]);
+ SysPrintf("}\n");
+ } else {
+ SysPrintf("\n");
+ }
+#endif
+
+ if (cdr.Ctrl & 0x1) return;
+
+ switch (cdr.Cmd) {
+ case CdlSync:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlNop:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlSetloc:
+ StopReading();
+ cdr.Seeked = 0;
+ for (i = 0; i < 3; i++)
+ cdr.SetSector[i] = btoi(cdr.Param[i]);
+ cdr.SetSector[3] = 0;
+/* if ((cdr.SetSector[0] | cdr.SetSector[1] | cdr.SetSector[2]) == 0) {
+ *(u32 *)cdr.SetSector = *(u32 *)cdr.SetSectorSeek;
+ }*/
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlPlay:
+ if (!cdr.SetSector[0] & !cdr.SetSector[1] & !cdr.SetSector[2]) {
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ if (cdr.CurTrack > cdr.ResultTN[1])
+ cdr.CurTrack = cdr.ResultTN[1];
+ if (CDR_getTD((unsigned char)(cdr.CurTrack), cdr.ResultTD) != -1) {
+ int tmp = cdr.ResultTD[2];
+ cdr.ResultTD[2] = cdr.ResultTD[0];
+ cdr.ResultTD[0] = tmp;
+ if (!Config.Cdda) CDR_play(cdr.ResultTD);
+ }
+ }
+ } else if (!Config.Cdda) {
+ CDR_play(cdr.SetSector);
+ }
+ cdr.Play = 1;
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlForward:
+ if (cdr.CurTrack < 0xaa)
+ cdr.CurTrack++;
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlBackward:
+ if (cdr.CurTrack > 1)
+ cdr.CurTrack--;
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlReadN:
+ cdr.Irq = 0;
+ StopReading();
+ cdr.Ctrl|= 0x80;
+ cdr.Stat = NoIntr;
+ StartReading(1);
+ break;
+
+ case CdlStandby:
+ StopCdda();
+ StopReading();
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlStop:
+ StopCdda();
+ StopReading();
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlPause:
+ StopCdda();
+ StopReading();
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x40000);
+ break;
+
+ case CdlReset:
+ case CdlInit:
+ StopCdda();
+ StopReading();
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlMute:
+ cdr.Muted = 0;
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlDemute:
+ cdr.Muted = 1;
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlSetfilter:
+ cdr.File = cdr.Param[0];
+ cdr.Channel = cdr.Param[1];
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlSetmode:
+#ifdef CDR_LOG
+ CDR_LOG("cdrWrite1() Log: Setmode %x\n", cdr.Param[0]);
+#endif
+ cdr.Mode = cdr.Param[0];
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlGetmode:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlGetlocL:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlGetlocP:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlGetTN:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlGetTD:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlSeekL:
+// ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0];
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlSeekP:
+// ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0];
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlTest:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlID:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ case CdlReadS:
+ cdr.Irq = 0;
+ StopReading();
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ StartReading(2);
+ break;
+
+ case CdlReadToc:
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x800);
+ break;
+
+ default:
+#ifdef CDR_LOG
+ CDR_LOG("cdrWrite1() Log: Unknown command: %x\n", cdr.Cmd);
+#endif
+ return;
+ }
+ if (cdr.Stat != NoIntr) {
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+ psxRegs.interrupt |= 0x80000000;
+ }
+}
+
+unsigned char cdrRead2(void) {
+ unsigned char ret;
+
+ if (cdr.Readed == 0) {
+ ret = 0;
+ } else {
+ ret = *cdr.pTransfer++;
+ }
+
+#ifdef CDR_LOG
+ CDR_LOG("cdrRead2() Log: CD2 Read: %x\n", ret);
+#endif
+ return ret;
+}
+
+void cdrWrite2(unsigned char rt) {
+#ifdef CDR_LOG
+ CDR_LOG("cdrWrite2() Log: CD2 write: %x\n", rt);
+#endif
+ if (cdr.Ctrl & 0x1) {
+ switch (rt) {
+ case 0x07:
+ cdr.ParamP = 0;
+ cdr.ParamC = 0;
+ cdr.ResultReady = 1; //0;
+ cdr.Ctrl &= ~3; //cdr.Ctrl = 0;
+ break;
+
+ default:
+ cdr.Reg2 = rt;
+ break;
+ }
+ } else if (!(cdr.Ctrl & 0x1) && cdr.ParamP < 8) {
+ cdr.Param[cdr.ParamP++] = rt;
+ cdr.ParamC++;
+ }
+}
+
+unsigned char cdrRead3(void) {
+ if (cdr.Stat) {
+ if (cdr.Ctrl & 0x1)
+ psxHu8(0x1803) = cdr.Stat | 0xE0;
+ else
+ psxHu8(0x1803) = 0xff;
+ } else {
+ psxHu8(0x1803) = 0;
+ }
+#ifdef CDR_LOG
+ CDR_LOG("cdrRead3() Log: CD3 Read: %x\n", psxHu8(0x1803));
+#endif
+ return psxHu8(0x1803);
+}
+
+void cdrWrite3(unsigned char rt) {
+#ifdef CDR_LOG
+ CDR_LOG("cdrWrite3() Log: CD3 write: %x\n", rt);
+#endif
+ if (rt == 0x07 && cdr.Ctrl & 0x1) {
+ cdr.Stat = 0;
+
+ if (cdr.Irq == 0xff) {
+ cdr.Irq = 0;
+ return;
+ }
+ if (cdr.Irq)
+ CDR_INT(cdr.eCycle);
+ if (cdr.Reading && !cdr.ResultReady)
+ CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
+
+ return;
+ }
+ if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) {
+ cdr.Readed = 1;
+ cdr.pTransfer = cdr.Transfer;
+
+ switch (cdr.Mode&0x30) {
+ case 0x10:
+ case 0x00:
+ cdr.pTransfer += 12;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void psxDma3(u32 madr, u32 bcr, u32 chcr) {
+ u32 cdsize;
+ u8 *ptr;
+
+#ifdef CDR_LOG
+ CDR_LOG("psxDma3() Log: *** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+
+ switch (chcr) {
+ case 0x11000000:
+ case 0x11400100:
+ if (cdr.Readed == 0) {
+#ifdef CDR_LOG
+ CDR_LOG("psxDma3() Log: *** DMA 3 *** NOT READY\n");
+#endif
+ break;
+ }
+
+ cdsize = (bcr & 0xffff) * 4;
+
+ ptr = (u8 *)PSXM(madr);
+ if (ptr == NULL) {
+#ifdef CPU_LOG
+ CDR_LOG("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n");
+#endif
+ break;
+ }
+ memcpy(ptr, cdr.pTransfer, cdsize);
+ psxCpu->Clear(madr, cdsize / 4);
+ cdr.pTransfer += cdsize;
+ break;
+ default:
+#ifdef CDR_LOG
+ CDR_LOG("psxDma3() Log: Unknown cddma %lx\n", chcr);
+#endif
+ break;
+ }
+
+ HW_DMA3_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(3);
+}
+
+void cdrReset() {
+ memset(&cdr, 0, sizeof(cdr));
+ cdr.CurTrack = 1;
+ cdr.File = 1;
+ cdr.Channel = 1;
+}
+
+int cdrFreeze(gzFile f, int Mode) {
+ uintptr_t tmp;
+
+ gzfreeze(&cdr, sizeof(cdr));
+
+ if (Mode == 1)
+ tmp = cdr.pTransfer - cdr.Transfer;
+
+ gzfreezel(&tmp);
+
+ if (Mode == 0)
+ cdr.pTransfer = cdr.Transfer + tmp;
+
+ return 0;
+}
diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h
new file mode 100644
index 00000000..70f93a5d
--- /dev/null
+++ b/libpcsxcore/cdrom.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __CDROM_H__
+#define __CDROM_H__
+
+#include "psxcommon.h"
+#include "decode_xa.h"
+#include "r3000a.h"
+#include "plugins.h"
+#include "psxmem.h"
+#include "psxhw.h"
+
+typedef struct {
+ unsigned char OCUP;
+ unsigned char Reg1Mode;
+ unsigned char Reg2;
+ unsigned char CmdProcess;
+ unsigned char Ctrl;
+ unsigned char Stat;
+
+ unsigned char StatP;
+
+ unsigned char Transfer[2352];
+ unsigned char *pTransfer;
+
+ unsigned char Prev[4];
+ unsigned char Param[8];
+ unsigned char Result[8];
+
+ unsigned char ParamC;
+ unsigned char ParamP;
+ unsigned char ResultC;
+ unsigned char ResultP;
+ unsigned char ResultReady;
+ unsigned char Cmd;
+ unsigned char Readed;
+ unsigned long Reading;
+
+ unsigned char ResultTN[6];
+ unsigned char ResultTD[4];
+ unsigned char SetSector[4];
+ unsigned char SetSectorSeek[4];
+ unsigned char Track;
+ int Play;
+ int CurTrack;
+ int Mode, File, Channel, Muted;
+ int Reset;
+ int RErr;
+ int FirstSector;
+
+ xa_decode_t Xa;
+
+ int Init;
+
+ unsigned char Irq;
+ unsigned long eCycle;
+
+ int Seeked;
+
+ char Unused[4083];
+} cdrStruct;
+
+cdrStruct cdr;
+
+void cdrReset();
+void cdrInterrupt();
+void cdrReadInterrupt();
+unsigned char cdrRead0(void);
+unsigned char cdrRead1(void);
+unsigned char cdrRead2(void);
+unsigned char cdrRead3(void);
+void cdrWrite0(unsigned char rt);
+void cdrWrite1(unsigned char rt);
+void cdrWrite2(unsigned char rt);
+void cdrWrite3(unsigned char rt);
+int cdrFreeze(gzFile f, int Mode);
+
+#endif /* __CDROM_H__ */
diff --git a/libpcsxcore/cheat.c b/libpcsxcore/cheat.c
new file mode 100644
index 00000000..284d833b
--- /dev/null
+++ b/libpcsxcore/cheat.c
@@ -0,0 +1,459 @@
+/* Cheat Support for PCSX-Reloaded
+ *
+ * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>.
+ *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxmem.h"
+
+#include "cheat.h"
+
+Cheat *Cheats = NULL;
+int NumCheats = 0;
+static int NumCheatsAllocated = 0;
+
+CheatCode *CheatCodes = NULL;
+int NumCodes = 0;
+static int NumCodesAllocated = 0;
+
+#define ALLOC_INCREMENT 100
+
+// cheat types
+#define CHEAT_CONST8 0x30 /* 8-bit Constant Write */
+#define CHEAT_CONST16 0x80 /* 16-bit Constant Write */
+#define CHEAT_INC16 0x10 /* 16-bit Increment */
+#define CHEAT_DEC16 0x11 /* 16-bit Decrement */
+#define CHEAT_INC8 0x20 /* 8-bit Increment */
+#define CHEAT_DEC8 0x21 /* 8-bit Decrement */
+#define CHEAT_SLIDE 0x50 /* Slide Codes */
+#define CHEAT_MEMCPY 0xC2 /* Memory Copy */
+
+#define CHEAT_EQU8 0xE0 /* 8-bit Equal To */
+#define CHEAT_NOTEQU8 0xE1 /* 8-bit Not Equal To */
+#define CHEAT_LESSTHAN8 0xE2 /* 8-bit Less Than */
+#define CHEAT_GREATERTHAN8 0xE3 /* 8-bit Greater Than */
+#define CHEAT_EQU16 0xD0 /* 16-bit Equal To */
+#define CHEAT_NOTEQU16 0xD1 /* 16-bit Not Equal To */
+#define CHEAT_LESSTHAN16 0xD2 /* 16-bit Less Than */
+#define CHEAT_GREATERTHAN16 0xD3 /* 16-bit Greater Than */
+
+void ClearAllCheats() {
+ int i;
+
+ if (Cheats != NULL) {
+ for (i = 0; i < NumCheats; i++) {
+ free(Cheats[i].Descr);
+ }
+ free(Cheats);
+ }
+
+ Cheats = NULL;
+ NumCheats = 0;
+ NumCheatsAllocated = 0;
+
+ if (CheatCodes != NULL) {
+ free(CheatCodes);
+ }
+
+ CheatCodes = NULL;
+ NumCodes = 0;
+ NumCodesAllocated = 0;
+}
+
+// load cheats from the specific filename
+void LoadCheats(const char *filename) {
+ FILE *fp;
+ char buf[256];
+ int count = 0;
+ unsigned int t1, t2;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ return;
+ }
+
+ ClearAllCheats();
+
+ while (fgets(buf, 255, fp) != NULL) {
+ buf[255] = '\0';
+ trim(buf);
+
+ // Skip comment or blank lines
+ if (buf[0] == '#' || buf[0] == ';' || buf[0] == '/' || buf[0] == '\"' || buf[0] == '\0')
+ continue;
+
+ if (buf[0] == '[' && buf[strlen(buf) - 1] == ']') {
+ if (NumCheats > 0)
+ Cheats[NumCheats - 1].n = count;
+
+ if (NumCheats >= NumCheatsAllocated) {
+ NumCheatsAllocated += ALLOC_INCREMENT;
+
+ if (Cheats == NULL) {
+ assert(NumCheats == 0);
+ assert(NumCheatsAllocated == ALLOC_INCREMENT);
+ Cheats = (Cheat *)malloc(sizeof(Cheat) * NumCheatsAllocated);
+ } else {
+ Cheats = (Cheat *)realloc(Cheats, sizeof(Cheat) * NumCheatsAllocated);
+ }
+ }
+
+ buf[strlen(buf) - 1] = '\0';
+ count = 0;
+
+ if (buf[1] == '*') {
+ Cheats[NumCheats].Descr = strdup(buf + 2);
+ Cheats[NumCheats].Enabled = 1;
+ } else {
+ Cheats[NumCheats].Descr = strdup(buf + 1);
+ Cheats[NumCheats].Enabled = 0;
+ }
+
+ Cheats[NumCheats].First = NumCodes;
+
+ NumCheats++;
+ continue;
+ }
+
+ if (NumCheats <= 0)
+ continue;
+
+ if (NumCodes >= NumCodesAllocated) {
+ NumCodesAllocated += ALLOC_INCREMENT;
+
+ if (CheatCodes == NULL) {
+ assert(NumCodes == 0);
+ assert(NumCodesAllocated == ALLOC_INCREMENT);
+ CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
+ } else {
+ CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
+ }
+ }
+
+ sscanf(buf, "%x %x", &t1, &t2);
+
+ CheatCodes[NumCodes].Addr = t1;
+ CheatCodes[NumCodes].Val = t2;
+
+ NumCodes++;
+ count++;
+ }
+
+ if (NumCheats > 0)
+ Cheats[NumCheats - 1].n = count;
+
+ fclose(fp);
+
+ SysPrintf("Cheats loaded from: %s\n", filename);
+}
+
+// save all cheats to the specified filename
+void SaveCheats(const char *filename) {
+ FILE *fp;
+ int i, j;
+
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ return;
+ }
+
+ for (i = 0; i < NumCheats; i++) {
+ // write the description
+ if (Cheats[i].Enabled)
+ fprintf(fp, "[*%s]\n", Cheats[i].Descr);
+ else
+ fprintf(fp, "[%s]\n", Cheats[i].Descr);
+
+ // write all cheat codes
+ for (j = 0; j < Cheats[i].n; j++) {
+ fprintf(fp, "%.8X %.4X\n",
+ CheatCodes[Cheats[i].First + j].Addr,
+ CheatCodes[Cheats[i].First + j].Val);
+ }
+
+ fprintf(fp, "\n");
+ }
+
+ fclose(fp);
+
+ SysPrintf("Cheats saved to: %s\n", filename);
+}
+
+// apply all enabled cheats
+void ApplyCheats() {
+ int i, j, k, endindex;
+
+ for (i = 0; i < NumCheats; i++) {
+ if (!Cheats[i].Enabled) {
+ continue;
+ }
+
+ // process all cheat codes
+ endindex = Cheats[i].First + Cheats[i].n;
+
+ for (j = Cheats[i].First; j < endindex; j++) {
+ u8 type = (uint8_t)(CheatCodes[j].Addr >> 24);
+ u32 addr = (CheatCodes[j].Addr & 0x001FFFFF);
+ u16 val = CheatCodes[j].Val;
+ u32 taddr;
+
+ switch (type) {
+ case CHEAT_CONST8:
+ psxMemWrite8(addr, (u8)val);
+ break;
+
+ case CHEAT_CONST16:
+ psxMemWrite16(addr, (u16)val);
+ break;
+
+ case CHEAT_INC16:
+ psxMemWrite16(addr, psxMemRead16(addr) + val);
+ break;
+
+ case CHEAT_DEC16:
+ psxMemWrite16(addr, psxMemRead16(addr) - val);
+ break;
+
+ case CHEAT_INC8:
+ psxMemWrite8(addr, psxMemRead8(addr) + (u8)val);
+ break;
+
+ case CHEAT_DEC8:
+ psxMemWrite8(addr, psxMemRead8(addr) - (u8)val);
+ break;
+
+ case CHEAT_SLIDE:
+ j++;
+ if (j >= endindex)
+ break;
+
+ type = (uint8_t)(CheatCodes[j].Addr >> 24);
+ taddr = (CheatCodes[j].Addr & 0x001FFFFF);
+ val = CheatCodes[j].Val;
+
+ if (type == CHEAT_CONST8) {
+ for (k = 0; k < ((addr >> 8) & 0xFF); k++) {
+ psxMemWrite8(taddr, (u8)val);
+ taddr += (s8)(addr & 0xFF);
+ val += (s8)(CheatCodes[j - 1].Val & 0xFF);
+ }
+ } else if (type == CHEAT_CONST16) {
+ for (k = 0; k < ((addr >> 8) & 0xFF); k++) {
+ psxMemWrite16(taddr, val);
+ taddr += (s8)(addr & 0xFF);
+ val += (s8)(CheatCodes[j - 1].Val & 0xFF);
+ }
+ }
+ break;
+
+ case CHEAT_MEMCPY:
+ j++;
+ if (j >= endindex)
+ break;
+
+ taddr = (CheatCodes[j].Addr & 0x001FFFFF);
+ for (k = 0; k < val; k++) {
+ psxMemWrite8(taddr + k, psxMemRead8(addr + k));
+ }
+ break;
+
+ case CHEAT_EQU8:
+ if (psxMemRead8(addr) != (u8)val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_NOTEQU8:
+ if (psxMemRead8(addr) == (u8)val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_LESSTHAN8:
+ if (psxMemRead8(addr) >= (u8)val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_GREATERTHAN8:
+ if (psxMemRead8(addr) <= (u8)val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_EQU16:
+ if (psxMemRead16(addr) != val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_NOTEQU16:
+ if (psxMemRead16(addr) == val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_LESSTHAN16:
+ if (psxMemRead16(addr) >= val)
+ j++; // skip the next code
+ break;
+
+ case CHEAT_GREATERTHAN16:
+ if (psxMemRead16(addr) <= val)
+ j++; // skip the next code
+ break;
+ }
+ }
+ }
+}
+
+int AddCheat(const char *descr, char *code) {
+ int c = 1;
+ char *p1, *p2;
+
+ if (NumCheats >= NumCheatsAllocated) {
+ NumCheatsAllocated += ALLOC_INCREMENT;
+
+ if (Cheats == NULL) {
+ assert(NumCheats == 0);
+ assert(NumCheatsAllocated == ALLOC_INCREMENT);
+ Cheats = (Cheat *)malloc(sizeof(Cheat) * NumCheatsAllocated);
+ } else {
+ Cheats = (Cheat *)realloc(Cheats, sizeof(Cheat) * NumCheatsAllocated);
+ }
+ }
+
+ Cheats[NumCheats].Descr = strdup(descr[0] ? descr : _("(Untitled)"));
+ Cheats[NumCheats].Enabled = 0;
+ Cheats[NumCheats].First = NumCodes;
+ Cheats[NumCheats].n = 0;
+
+ p1 = code;
+ p2 = code;
+
+ while (c) {
+ unsigned int t1, t2;
+
+ while (*p2 != '\n' && *p2 != '\0')
+ p2++;
+
+ if (*p2 == '\0')
+ c = 0;
+
+ *p2 = '\0';
+ p2++;
+
+ t1 = 0;
+ t2 = 0;
+ sscanf(p1, "%x %x", &t1, &t2);
+
+ if (t1 > 0x10000000) {
+ if (NumCodes >= NumCodesAllocated) {
+ NumCodesAllocated += ALLOC_INCREMENT;
+
+ if (CheatCodes == NULL) {
+ assert(NumCodes == 0);
+ assert(NumCodesAllocated == ALLOC_INCREMENT);
+ CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
+ } else {
+ CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
+ }
+ }
+
+ CheatCodes[NumCodes].Addr = t1;
+ CheatCodes[NumCodes].Val = t2;
+ NumCodes++;
+ Cheats[NumCheats].n++;
+ }
+
+ p1 = p2;
+ }
+
+ if (Cheats[NumCheats].n == 0) {
+ return -1;
+ }
+
+ NumCheats++;
+ return 0;
+}
+
+void RemoveCheat(int index) {
+ assert(index >= 0 && index < NumCheats);
+
+ free(Cheats[index].Descr);
+
+ while (index < NumCheats - 1) {
+ Cheats[index] = Cheats[index + 1];
+ index++;
+ }
+
+ NumCheats--;
+}
+
+int EditCheat(int index, const char *descr, char *code) {
+ int c = 1;
+ int prev = NumCodes;
+ char *p1, *p2;
+
+ assert(index >= 0 && index < NumCheats);
+
+ p1 = code;
+ p2 = code;
+
+ while (c) {
+ unsigned int t1, t2;
+
+ while (*p2 != '\n' && *p2 != '\0')
+ p2++;
+
+ if (*p2 == '\0')
+ c = 0;
+
+ *p2 = '\0';
+ p2++;
+
+ t1 = 0;
+ t2 = 0;
+ sscanf(p1, "%x %x", &t1, &t2);
+
+ if (t1 > 0x10000000) {
+ if (NumCodes >= NumCodesAllocated) {
+ NumCodesAllocated += ALLOC_INCREMENT;
+
+ if (CheatCodes == NULL) {
+ assert(NumCodes == 0);
+ assert(NumCodesAllocated == ALLOC_INCREMENT);
+ CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
+ } else {
+ CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
+ }
+ }
+
+ CheatCodes[NumCodes].Addr = t1;
+ CheatCodes[NumCodes].Val = t2;
+ NumCodes++;
+ }
+
+ p1 = p2;
+ }
+
+ if (NumCodes == prev) {
+ return -1;
+ }
+
+ free(Cheats[index].Descr);
+ Cheats[index].Descr = strdup(descr[0] ? descr : _("(Untitled)"));
+ Cheats[index].First = prev;
+ Cheats[index].n = NumCodes - prev;
+
+ return 0;
+}
diff --git a/libpcsxcore/cheat.h b/libpcsxcore/cheat.h
new file mode 100644
index 00000000..3e32c753
--- /dev/null
+++ b/libpcsxcore/cheat.h
@@ -0,0 +1,51 @@
+/* Cheat Support for PCSX-Reloaded
+ *
+ * Copyright (C) 2009, Wei Mingzhi <whistler@openoffice.org>.
+ *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHEAT_H
+#define CHEAT_H
+
+typedef struct {
+ uint32_t Addr;
+ uint16_t Val;
+} CheatCode;
+
+typedef struct {
+ char *Descr;
+ int First; // index of the first cheat code
+ int n; // number of cheat codes for this cheat
+ int Enabled;
+} Cheat;
+
+void ClearAllCheats();
+
+void LoadCheats(const char *filename);
+void SaveCheats(const char *filename);
+
+void ApplyCheats();
+
+int AddCheat(const char *descr, char *code);
+void RemoveCheat(int index);
+int EditCheat(int index, const char *descr, char *code);
+
+extern Cheat *Cheats;
+extern CheatCode *CheatCodes;
+extern int NumCheats;
+extern int NumCodes;
+
+#endif
diff --git a/libpcsxcore/coff.h b/libpcsxcore/coff.h
new file mode 100644
index 00000000..74f3dc41
--- /dev/null
+++ b/libpcsxcore/coff.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __COFF_H__
+#define __COFF_H__
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ unsigned long f_timdat; /* time & date stamp */
+ unsigned long f_symptr; /* file pointer to symtab */
+ unsigned long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+};
+
+#define FILHDR struct external_filehdr
+#define FILHSZ sizeof(FILHDR)
+
+#endif /* __COFF_H__ */
diff --git a/libpcsxcore/debug.h b/libpcsxcore/debug.h
new file mode 100644
index 00000000..d61f2ba0
--- /dev/null
+++ b/libpcsxcore/debug.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Specficies which logs should be activated.
+* Ryan TODO: These should ALL be definable with configure flags.
+*/
+
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+extern char *disRNameCP0[];
+
+char* disR3000AF(u32 code, u32 pc);
+
+FILE *emuLog;
+
+//#define GTE_DUMP
+
+#ifdef GTE_DUMP
+FILE *gteLog;
+#endif
+
+//#define LOG_STDOUT
+
+//#define PAD_LOG __Log
+//#define GTE_LOG __Log
+//#define CDR_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log
+
+//#define PSXHW_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log
+//#define PSXBIOS_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log
+//#define PSXDMA_LOG __Log
+//#define PSXMEM_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log
+//#define PSXCPU_LOG __Log
+
+//#define CDRCMD_DEBUG
+
+#if defined (PSXCPU_LOG) || defined(PSXDMA_LOG) || defined(CDR_LOG) || defined(PSXHW_LOG) || \
+ defined(PSXBIOS_LOG) || defined(PSXMEM_LOG) || defined(GTE_LOG) || defined(PAD_LOG)
+#define EMU_LOG __Log
+#endif
+
+#endif /* __DEBUG_H__ */
diff --git a/libpcsxcore/decode_xa.c b/libpcsxcore/decode_xa.c
new file mode 100644
index 00000000..385c0571
--- /dev/null
+++ b/libpcsxcore/decode_xa.c
@@ -0,0 +1,368 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* XA audio decoding functions (Kazzuya).
+*/
+
+#include "decode_xa.h"
+
+#define FIXED
+
+#define NOT(_X_) (!(_X_))
+#define XACLAMP(_X_,_MI_,_MA_) {if(_X_<_MI_)_X_=_MI_;if(_X_>_MA_)_X_=_MA_;}
+
+#define SH 4
+#define SHC 10
+
+//============================================
+//=== ADPCM DECODING ROUTINES
+//============================================
+
+#ifndef FIXED
+static double K0[4] = {
+ 0.0,
+ 0.9375,
+ 1.796875,
+ 1.53125
+};
+
+static double K1[4] = {
+ 0.0,
+ 0.0,
+ -0.8125,
+ -0.859375
+};
+#else
+static int K0[4] = {
+ 0.0 * (1<<SHC),
+ 0.9375 * (1<<SHC),
+ 1.796875 * (1<<SHC),
+ 1.53125 * (1<<SHC)
+};
+
+static int K1[4] = {
+ 0.0 * (1<<SHC),
+ 0.0 * (1<<SHC),
+ -0.8125 * (1<<SHC),
+ -0.859375 * (1<<SHC)
+};
+#endif
+
+#define BLKSIZ 28 /* block size (32 - 4 nibbles) */
+
+//===========================================
+void ADPCM_InitDecode(ADPCM_Decode_t *decp) {
+ decp->y0 = 0;
+ decp->y1 = 0;
+}
+
+//===========================================
+#ifndef FIXED
+#define IK0(fid) ((int)((-K0[fid]) * (1<<SHC)))
+#define IK1(fid) ((int)((-K1[fid]) * (1<<SHC)))
+#else
+#define IK0(fid) (-K0[fid])
+#define IK1(fid) (-K1[fid])
+#endif
+
+static __inline void ADPCM_DecodeBlock16( ADPCM_Decode_t *decp, u8 filter_range, const void *vblockp, short *destp, int inc ) {
+ int i;
+ int range, filterid;
+ s32 fy0, fy1;
+ const u16 *blockp;
+
+ blockp = (const unsigned short *)vblockp;
+ filterid = (filter_range >> 4) & 0x0f;
+ range = (filter_range >> 0) & 0x0f;
+
+ fy0 = decp->y0;
+ fy1 = decp->y1;
+
+ for (i = BLKSIZ/4; i; --i) {
+ s32 y;
+ s32 x0, x1, x2, x3;
+
+ y = *blockp++;
+ x3 = (short)( y & 0xf000) >> range; x3 <<= SH;
+ x2 = (short)((y << 4) & 0xf000) >> range; x2 <<= SH;
+ x1 = (short)((y << 8) & 0xf000) >> range; x1 <<= SH;
+ x0 = (short)((y << 12) & 0xf000) >> range; x0 <<= SH;
+
+ x0 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x0;
+ x1 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x1;
+ x2 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x2;
+ x3 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x3;
+
+ XACLAMP( x0, -32768<<SH, 32767<<SH ); *destp = x0 >> SH; destp += inc;
+ XACLAMP( x1, -32768<<SH, 32767<<SH ); *destp = x1 >> SH; destp += inc;
+ XACLAMP( x2, -32768<<SH, 32767<<SH ); *destp = x2 >> SH; destp += inc;
+ XACLAMP( x3, -32768<<SH, 32767<<SH ); *destp = x3 >> SH; destp += inc;
+ }
+ decp->y0 = fy0;
+ decp->y1 = fy1;
+}
+
+static int headtable[4] = {0,2,8,10};
+
+//===========================================
+static void xa_decode_data( xa_decode_t *xdp, unsigned char *srcp ) {
+ const u8 *sound_groupsp;
+ const u8 *sound_datap, *sound_datap2;
+ int i, j, k, nbits;
+ u16 data[4096], *datap;
+ short *destp;
+
+ destp = xdp->pcm;
+ nbits = xdp->nbits == 4 ? 4 : 2;
+
+ if (xdp->stereo) { // stereo
+ if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp+0, 2 );
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+ ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data,
+ destp+1, 2 );
+
+ destp += 28*2;
+ }
+ }
+ } else { // level B/C
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] & 0x0f) |
+ ((u16)(sound_datap2[ 4] & 0x0f) << 4) |
+ ((u16)(sound_datap2[ 8] & 0x0f) << 8) |
+ ((u16)(sound_datap2[12] & 0x0f) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp+0, 2 );
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] >> 4) |
+ ((u16)(sound_datap2[ 4] >> 4) << 4) |
+ ((u16)(sound_datap2[ 8] >> 4) << 8) |
+ ((u16)(sound_datap2[12] >> 4) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data,
+ destp+1, 2 );
+
+ destp += 28*2;
+ }
+ }
+ }
+ } else { // mono
+ if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp, 1 );
+
+ destp += 28;
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data,
+ destp, 1 );
+
+ destp += 28;
+ }
+ }
+ } else { // level B/C
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] & 0x0f) |
+ ((u16)(sound_datap2[ 4] & 0x0f) << 4) |
+ ((u16)(sound_datap2[ 8] & 0x0f) << 8) |
+ ((u16)(sound_datap2[12] & 0x0f) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp, 1 );
+
+ destp += 28;
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] >> 4) |
+ ((u16)(sound_datap2[ 4] >> 4) << 4) |
+ ((u16)(sound_datap2[ 8] >> 4) << 8) |
+ ((u16)(sound_datap2[12] >> 4) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data,
+ destp, 1 );
+
+ destp += 28;
+ }
+ }
+ }
+ }
+}
+
+//============================================
+//=== XA SPECIFIC ROUTINES
+//============================================
+typedef struct {
+u8 filenum;
+u8 channum;
+u8 submode;
+u8 coding;
+
+u8 filenum2;
+u8 channum2;
+u8 submode2;
+u8 coding2;
+} xa_subheader_t;
+
+#define SUB_SUB_EOF (1<<7) // end of file
+#define SUB_SUB_RT (1<<6) // real-time sector
+#define SUB_SUB_FORM (1<<5) // 0 form1 1 form2
+#define SUB_SUB_TRIGGER (1<<4) // used for interrupt
+#define SUB_SUB_DATA (1<<3) // contains data
+#define SUB_SUB_AUDIO (1<<2) // contains audio
+#define SUB_SUB_VIDEO (1<<1) // contains video
+#define SUB_SUB_EOR (1<<0) // end of record
+
+#define AUDIO_CODING_GET_STEREO(_X_) ( (_X_) & 3)
+#define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3)
+#define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3)
+#define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1)
+
+#define SUB_UNKNOWN 0
+#define SUB_VIDEO 1
+#define SUB_AUDIO 2
+
+//============================================
+static int parse_xa_audio_sector( xa_decode_t *xdp,
+ xa_subheader_t *subheadp,
+ unsigned char *sectorp,
+ int is_first_sector ) {
+ if ( is_first_sector ) {
+ switch ( AUDIO_CODING_GET_FREQ(subheadp->coding) ) {
+ case 0: xdp->freq = 37800; break;
+ case 1: xdp->freq = 18900; break;
+ default: xdp->freq = 0; break;
+ }
+ switch ( AUDIO_CODING_GET_BPS(subheadp->coding) ) {
+ case 0: xdp->nbits = 4; break;
+ case 1: xdp->nbits = 8; break;
+ default: xdp->nbits = 0; break;
+ }
+ switch ( AUDIO_CODING_GET_STEREO(subheadp->coding) ) {
+ case 0: xdp->stereo = 0; break;
+ case 1: xdp->stereo = 1; break;
+ default: xdp->stereo = 0; break;
+ }
+
+ if ( xdp->freq == 0 )
+ return -1;
+
+ ADPCM_InitDecode( &xdp->left );
+ ADPCM_InitDecode( &xdp->right );
+
+ xdp->nsamples = 18 * 28 * 8;
+ if (xdp->stereo == 1) xdp->nsamples /= 2;
+ }
+ xa_decode_data( xdp, sectorp );
+
+ return 0;
+}
+
+//================================================================
+//=== THIS IS WHAT YOU HAVE TO CALL
+//=== xdp - structure were all important data are returned
+//=== sectorp - data in input
+//=== pcmp - data in output
+//=== is_first_sector - 1 if it's the 1st sector of the stream
+//=== - 0 for any other successive sector
+//=== return -1 if error
+//================================================================
+s32 xa_decode_sector( xa_decode_t *xdp,
+ unsigned char *sectorp, int is_first_sector ) {
+ if (parse_xa_audio_sector(xdp, (xa_subheader_t *)sectorp, sectorp + sizeof(xa_subheader_t), is_first_sector))
+ return -1;
+
+ return 0;
+}
+
+/* EXAMPLE:
+"nsamples" is the number of 16 bit samples
+every sample is 2 bytes in mono and 4 bytes in stereo
+
+xa_decode_t xa;
+
+ sectorp = read_first_sector();
+ xa_decode_sector( &xa, sectorp, 1 );
+ play_wave( xa.pcm, xa.freq, xa.nsamples );
+
+ while ( --n_sectors )
+ {
+ sectorp = read_next_sector();
+ xa_decode_sector( &xa, sectorp, 0 );
+ play_wave( xa.pcm, xa.freq, xa.nsamples );
+ }
+*/
diff --git a/libpcsxcore/decode_xa.h b/libpcsxcore/decode_xa.h
new file mode 100644
index 00000000..2fc71140
--- /dev/null
+++ b/libpcsxcore/decode_xa.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __DECODE_XA_H__
+#define __DECODE_XA_H__
+
+#include "psxcommon.h"
+
+typedef struct {
+ s32 y0, y1;
+} ADPCM_Decode_t;
+
+typedef struct {
+ int freq;
+ int nbits;
+ int stereo;
+ int nsamples;
+ ADPCM_Decode_t left, right;
+ short pcm[16384];
+} xa_decode_t;
+
+s32 xa_decode_sector( xa_decode_t *xdp,
+ unsigned char *sectorp,
+ int is_first_sector );
+
+#endif
diff --git a/libpcsxcore/disr3000a.c b/libpcsxcore/disr3000a.c
new file mode 100644
index 00000000..3314df88
--- /dev/null
+++ b/libpcsxcore/disr3000a.c
@@ -0,0 +1,324 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* R3000A disassembler.
+*/
+
+#include "psxcommon.h"
+
+char ostr[256];
+
+// Names of registers
+static char *disRNameGPR[] = {
+ "r0", "at", "v0", "v1", "a0", "a1","a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5","t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5","s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp","fp", "ra"};
+
+char *disRNameCP0[] = {
+ "Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*",
+ "BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" ,
+ "Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" ,
+ "*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" };
+
+
+// Type deffinition of our functions
+
+typedef char* (*TdisR3000AF)(u32 code, u32 pc);
+
+// These macros are used to assemble the disassembler functions
+#define MakeDisFg(fn, b) char* fn(u32 code, u32 pc) { b; return ostr; }
+#define MakeDisF(fn, b) \
+ static char* fn(u32 code, u32 pc) { \
+ sprintf (ostr, "%8.8x %8.8x:", pc, code); \
+ b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \
+ }
+
+
+#include "r3000a.h"
+
+#undef _Funct_
+#undef _Rd_
+#undef _Rt_
+#undef _Rs_
+#undef _Sa_
+#undef _Im_
+#undef _Target_
+
+#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register
+#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register
+#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register
+#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register
+#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register
+#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register
+
+#define _Target_ ((pc & 0xf0000000) + ((code & 0x03ffffff) * 4))
+#define _Branch_ (pc + 4 + ((short)_Im_ * 4))
+#define _OfB_ _Im_, _nRs_
+
+#define dName(i) sprintf(ostr, "%s %-7s,", ostr, i)
+#define dGPR(i) sprintf(ostr, "%s %8.8x (%s),", ostr, psxRegs.GPR.r[i], disRNameGPR[i])
+#define dCP0(i) sprintf(ostr, "%s %8.8x (%s),", ostr, psxRegs.CP0.r[i], disRNameCP0[i])
+#define dHI() sprintf(ostr, "%s %8.8x (%s),", ostr, psxRegs.GPR.n.hi, "hi")
+#define dLO() sprintf(ostr, "%s %8.8x (%s),", ostr, psxRegs.GPR.n.lo, "lo")
+#define dImm() sprintf(ostr, "%s %4.4x (%d),", ostr, _Im_, _Im_)
+#define dTarget() sprintf(ostr, "%s %8.8x,", ostr, _Target_)
+#define dSa() sprintf(ostr, "%s %2.2x (%d),", ostr, _Sa_, _Sa_)
+#define dOfB() sprintf(ostr, "%s %4.4x (%8.8x (%s)),", ostr, _Im_, psxRegs.GPR.r[_Rs_], disRNameGPR[_Rs_])
+#define dOffset() sprintf(ostr, "%s %8.8x,", ostr, _Branch_)
+#define dCode() sprintf(ostr, "%s %8.8x,", ostr, (code >> 6) & 0xffffff)
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+MakeDisF(disADDI, dName("ADDI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+MakeDisF(disADDIU, dName("ADDIU"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+MakeDisF(disANDI, dName("ANDI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+MakeDisF(disORI, dName("ORI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+MakeDisF(disSLTI, dName("SLTI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+MakeDisF(disSLTIU, dName("SLTIU"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+MakeDisF(disXORI, dName("XORI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+MakeDisF(disADD, dName("ADD"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disADDU, dName("ADDU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disAND, dName("AND"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disNOR, dName("NOR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disOR, dName("OR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disSLT, dName("SLT"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disSLTU, dName("SLTU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disSUB, dName("SUB"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disSUBU, dName("SUBU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disXOR, dName("XOR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
+
+/*********************************************************
+* Register arithmetic & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+MakeDisF(disDIV, dName("DIV"); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disDIVU, dName("DIVU"); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disMULT, dName("MULT"); dGPR(_Rs_); dGPR(_Rt_);)
+MakeDisF(disMULTU, dName("MULTU"); dGPR(_Rs_); dGPR(_Rt_);)
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, offset *
+*********************************************************/
+MakeDisF(disBGEZ, dName("BGEZ"); dGPR(_Rs_); dOffset();)
+MakeDisF(disBGEZAL, dName("BGEZAL"); dGPR(_Rs_); dOffset();)
+MakeDisF(disBGTZ, dName("BGTZ"); dGPR(_Rs_); dOffset();)
+MakeDisF(disBLEZ, dName("BLEZ"); dGPR(_Rs_); dOffset();)
+MakeDisF(disBLTZ, dName("BLTZ"); dGPR(_Rs_); dOffset();)
+MakeDisF(disBLTZAL, dName("BLTZAL"); dGPR(_Rs_); dOffset();)
+
+/*********************************************************
+* Shift arithmetic with constant shift *
+* Format: OP rd, rt, sa *
+*********************************************************/
+MakeDisF(disSLL, if (code) { dName("SLL"); dGPR(_Rd_); dGPR(_Rt_); dSa(); } else { dName("NOP"); })
+MakeDisF(disSRA, dName("SRA"); dGPR(_Rd_); dGPR(_Rt_); dSa();)
+MakeDisF(disSRL, dName("SRL"); dGPR(_Rd_); dGPR(_Rt_); dSa();)
+
+/*********************************************************
+* Shift arithmetic with variant register shift *
+* Format: OP rd, rt, rs *
+*********************************************************/
+MakeDisF(disSLLV, dName("SLLV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);)
+MakeDisF(disSRAV, dName("SRAV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);)
+MakeDisF(disSRLV, dName("SRLV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);)
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+MakeDisF(disLUI, dName("LUI"); dGPR(_Rt_); dImm();)
+
+/*********************************************************
+* Move from HI/LO to GPR *
+* Format: OP rd *
+*********************************************************/
+MakeDisF(disMFHI, dName("MFHI"); dGPR(_Rd_); dHI();)
+MakeDisF(disMFLO, dName("MFLO"); dGPR(_Rd_); dLO();)
+
+/*********************************************************
+* Move from GPR to HI/LO *
+* Format: OP rd *
+*********************************************************/
+MakeDisF(disMTHI, dName("MTHI"); dHI(); dGPR(_Rs_);)
+MakeDisF(disMTLO, dName("MTLO"); dLO(); dGPR(_Rs_);)
+
+/*********************************************************
+* Special purpose instructions *
+* Format: OP *
+*********************************************************/
+MakeDisF(disBREAK, dName("BREAK"))
+MakeDisF(disRFE, dName("RFE"))
+MakeDisF(disSYSCALL, dName("SYSCALL"))
+MakeDisF(disHLE, dName("HLE"))
+
+
+MakeDisF(disRTPS, dName("RTPS"))
+MakeDisF(disOP , dName("OP"))
+MakeDisF(disNCLIP, dName("NCLIP"))
+MakeDisF(disDPCS, dName("DPCS"))
+MakeDisF(disINTPL, dName("INTPL"))
+MakeDisF(disMVMVA, dName("MVMVA"))
+MakeDisF(disNCDS , dName("NCDS"))
+MakeDisF(disCDP , dName("CDP"))
+MakeDisF(disNCDT , dName("NCDT"))
+MakeDisF(disNCCS , dName("NCCS"))
+MakeDisF(disCC , dName("CC"))
+MakeDisF(disNCS , dName("NCS"))
+MakeDisF(disNCT , dName("NCT"))
+MakeDisF(disSQR , dName("SQR"))
+MakeDisF(disDCPL , dName("DCPL"))
+MakeDisF(disDPCT , dName("DPCT"))
+MakeDisF(disAVSZ3, dName("AVSZ3"))
+MakeDisF(disAVSZ4, dName("AVSZ4"))
+MakeDisF(disRTPT , dName("RTPT"))
+MakeDisF(disGPF , dName("GPF"))
+MakeDisF(disGPL , dName("GPL"))
+MakeDisF(disNCCT , dName("NCCT"))
+
+MakeDisF(disMFC2, dName("MFC2"); dGPR(_Rt_);)
+MakeDisF(disCFC2, dName("CFC2"); dGPR(_Rt_);)
+MakeDisF(disMTC2, dName("MTC2"); dGPR(_Rt_);)
+MakeDisF(disCTC2, dName("CTC2"); dGPR(_Rt_);)
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, rt, offset *
+*********************************************************/
+MakeDisF(disBEQ, dName("BEQ"); dGPR(_Rs_); dGPR(_Rt_); dOffset();)
+MakeDisF(disBNE, dName("BNE"); dGPR(_Rs_); dGPR(_Rt_); dOffset();)
+
+/*********************************************************
+* Jump to target *
+* Format: OP target *
+*********************************************************/
+MakeDisF(disJ, dName("J"); dTarget();)
+MakeDisF(disJAL, dName("JAL"); dTarget(); dGPR(31);)
+
+/*********************************************************
+* Register jump *
+* Format: OP rs, rd *
+*********************************************************/
+MakeDisF(disJR, dName("JR"); dGPR(_Rs_);)
+MakeDisF(disJALR, dName("JALR"); dGPR(_Rs_); dGPR(_Rd_))
+
+/*********************************************************
+* Load and store for GPR *
+* Format: OP rt, offset(base) *
+*********************************************************/
+MakeDisF(disLB, dName("LB"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLBU, dName("LBU"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLH, dName("LH"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLHU, dName("LHU"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLW, dName("LW"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLWL, dName("LWL"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLWR, dName("LWR"); dGPR(_Rt_); dOfB();)
+MakeDisF(disLWC2, dName("LWC2"); dGPR(_Rt_); dOfB();)
+MakeDisF(disSB, dName("SB"); dGPR(_Rt_); dOfB();)
+MakeDisF(disSH, dName("SH"); dGPR(_Rt_); dOfB();)
+MakeDisF(disSW, dName("SW"); dGPR(_Rt_); dOfB();)
+MakeDisF(disSWL, dName("SWL"); dGPR(_Rt_); dOfB();)
+MakeDisF(disSWR, dName("SWR"); dGPR(_Rt_); dOfB();)
+MakeDisF(disSWC2, dName("SWC2"); dGPR(_Rt_); dOfB();)
+
+/*********************************************************
+* Moves between GPR and COPx *
+* Format: OP rt, fs *
+*********************************************************/
+MakeDisF(disMFC0, dName("MFC0"); dGPR(_Rt_); dCP0(_Rd_);)
+MakeDisF(disMTC0, dName("MTC0"); dCP0(_Rd_); dGPR(_Rt_);)
+MakeDisF(disCFC0, dName("CFC0"); dGPR(_Rt_); dCP0(_Rd_);)
+MakeDisF(disCTC0, dName("CTC0"); dCP0(_Rd_); dGPR(_Rt_);)
+
+/*********************************************************
+* Unknow instruction (would generate an exception) *
+* Format: ? *
+*********************************************************/
+MakeDisF(disNULL, dName("*** Bad OP ***");)
+
+
+TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL
+ disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV ,
+ disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL ,
+ disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL ,
+ disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL ,
+ disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR ,
+ disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL ,
+ disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL ,
+ disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL};
+
+MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](code, pc))
+
+TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND
+ disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](code, pc))
+
+TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0
+ disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disCOP0, disR3000A_COP0[_Rs_](code, pc))
+
+TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs)
+ disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](code, pc))
+
+TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct)
+ disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL,
+ disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL,
+ disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL,
+ disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL,
+ disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
+ disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL,
+ disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
+ disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT };
+
+MakeDisF(disCOP2, disR3000A_COP2[_Funct_](code, pc))
+
+TdisR3000AF disR3000A[] = {
+ disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ ,
+ disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI ,
+ disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL ,
+ disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL ,
+ disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disNULL , disNULL , disSWC2 , disHLE , disNULL, disNULL, disNULL , disNULL };
+
+MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc))
diff --git a/libpcsxcore/gte.c b/libpcsxcore/gte.c
new file mode 100644
index 00000000..6e42c5cb
--- /dev/null
+++ b/libpcsxcore/gte.c
@@ -0,0 +1,3124 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* GTE functions.
+*/
+
+#include "gte.h"
+
+#ifdef GTE_DUMP
+#define G_OP(name,delay) fprintf(gteLog, "* : %08X : %02d : %s\n", psxRegs.code, delay, name);
+#define G_SD(reg) fprintf(gteLog, "+D%02d : %08X\n", reg, psxRegs.CP2D.r[reg]);
+#define G_SC(reg) fprintf(gteLog, "+C%02d : %08X\n", reg, psxRegs.CP2C.r[reg]);
+#define G_GD(reg) fprintf(gteLog, "-D%02d : %08X\n", reg, psxRegs.CP2D.r[reg]);
+#define G_GC(reg) fprintf(gteLog, "-C%02d : %08X\n", reg, psxRegs.CP2C.r[reg]);
+#else
+#define G_OP(name,delay)
+#define G_SD(reg)
+#define G_SC(reg)
+#define G_GD(reg)
+#define G_GC(reg)
+#endif
+
+#define SUM_FLAG if (gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000;
+
+#ifndef _MSC_VER
+#define UNDERFLOW_BOUND ((s64)0xffffffff80000000LL)
+#else
+#define UNDERFLOW_BOUND ((s64)0xffffffff80000000)
+#endif
+
+#if defined(__BIGENDIAN__)
+#define SEL16(n) ((n)^1)
+#define SEL8(n) ((n)^3)
+#else
+#define SEL16(n) (n)
+#define SEL8(n) (n)
+#endif
+
+#define gteVX0 ((s16*)psxRegs.CP2D.r)[SEL16(0)]
+#define gteVY0 ((s16*)psxRegs.CP2D.r)[SEL16(1)]
+#define gteVZ0 ((s16*)psxRegs.CP2D.r)[SEL16(2)]
+#define gteVX1 ((s16*)psxRegs.CP2D.r)[SEL16(4)]
+#define gteVY1 ((s16*)psxRegs.CP2D.r)[SEL16(5)]
+#define gteVZ1 ((s16*)psxRegs.CP2D.r)[SEL16(6)]
+#define gteVX2 ((s16*)psxRegs.CP2D.r)[SEL16(8)]
+#define gteVY2 ((s16*)psxRegs.CP2D.r)[SEL16(9)]
+#define gteVZ2 ((s16*)psxRegs.CP2D.r)[SEL16(10)]
+#define gteRGB psxRegs.CP2D.r[6]
+#define gteOTZ ((s16*)psxRegs.CP2D.r)[SEL16(7*2)]
+#define gteIR0 ((s32*)psxRegs.CP2D.r)[8]
+#define gteIR1 ((s32*)psxRegs.CP2D.r)[9]
+#define gteIR2 ((s32*)psxRegs.CP2D.r)[10]
+#define gteIR3 ((s32*)psxRegs.CP2D.r)[11]
+#define gteSXY0 ((s32*)psxRegs.CP2D.r)[12]
+#define gteSXY1 ((s32*)psxRegs.CP2D.r)[13]
+#define gteSXY2 ((s32*)psxRegs.CP2D.r)[14]
+#define gteSXYP ((s32*)psxRegs.CP2D.r)[15]
+#define gteSX0 ((s16*)psxRegs.CP2D.r)[SEL16(12*2)]
+#define gteSY0 ((s16*)psxRegs.CP2D.r)[SEL16(12*2+1)]
+#define gteSX1 ((s16*)psxRegs.CP2D.r)[SEL16(13*2)]
+#define gteSY1 ((s16*)psxRegs.CP2D.r)[SEL16(13*2+1)]
+#define gteSX2 ((s16*)psxRegs.CP2D.r)[SEL16(14*2)]
+#define gteSY2 ((s16*)psxRegs.CP2D.r)[SEL16(14*2+1)]
+#define gteSXP ((s16*)psxRegs.CP2D.r)[SEL16(15*2)]
+#define gteSYP ((s16*)psxRegs.CP2D.r)[SEL16(15*2+1)]
+#define gteSZx ((u16*)psxRegs.CP2D.r)[SEL16(16*2)]
+#define gteSZ0 ((u16*)psxRegs.CP2D.r)[SEL16(17*2)]
+#define gteSZ1 ((u16*)psxRegs.CP2D.r)[SEL16(18*2)]
+#define gteSZ2 ((u16*)psxRegs.CP2D.r)[SEL16(19*2)]
+#define gteRGB0 psxRegs.CP2D.r[20]
+#define gteRGB1 psxRegs.CP2D.r[21]
+#define gteRGB2 psxRegs.CP2D.r[22]
+#define gteMAC0 psxRegs.CP2D.r[24]
+#define gteMAC1 ((s32*)psxRegs.CP2D.r)[25]
+#define gteMAC2 ((s32*)psxRegs.CP2D.r)[26]
+#define gteMAC3 ((s32*)psxRegs.CP2D.r)[27]
+#define gteIRGB psxRegs.CP2D.r[28]
+#define gteORGB psxRegs.CP2D.r[29]
+#define gteLZCS psxRegs.CP2D.r[30]
+#define gteLZCR psxRegs.CP2D.r[31]
+
+#define gteR ((u8 *)psxRegs.CP2D.r)[SEL8(6*4)]
+#define gteG ((u8 *)psxRegs.CP2D.r)[SEL8(6*4+1)]
+#define gteB ((u8 *)psxRegs.CP2D.r)[SEL8(6*4+2)]
+#define gteCODE ((u8 *)psxRegs.CP2D.r)[SEL8(6*4+3)]
+#define gteC gteCODE
+
+#define gteR0 ((u8 *)psxRegs.CP2D.r)[SEL8(20*4)]
+#define gteG0 ((u8 *)psxRegs.CP2D.r)[SEL8(20*4+1)]
+#define gteB0 ((u8 *)psxRegs.CP2D.r)[SEL8(20*4+2)]
+#define gteCODE0 ((u8 *)psxRegs.CP2D.r)[SEL8(20*4+3)]
+#define gteC0 gteCODE0
+
+#define gteR1 ((u8 *)psxRegs.CP2D.r)[SEL8(21*4)]
+#define gteG1 ((u8 *)psxRegs.CP2D.r)[SEL8(21*4+1)]
+#define gteB1 ((u8 *)psxRegs.CP2D.r)[SEL8(21*4+2)]
+#define gteCODE1 ((u8 *)psxRegs.CP2D.r)[SEL8(21*4+3)]
+#define gteC1 gteCODE1
+
+#define gteR2 ((u8 *)psxRegs.CP2D.r)[SEL8(22*4)]
+#define gteG2 ((u8 *)psxRegs.CP2D.r)[SEL8(22*4+1)]
+#define gteB2 ((u8 *)psxRegs.CP2D.r)[SEL8(22*4+2)]
+#define gteCODE2 ((u8 *)psxRegs.CP2D.r)[SEL8(22*4+3)]
+#define gteC2 gteCODE2
+
+
+
+#define gteR11 ((s16*)psxRegs.CP2C.r)[SEL16(0)]
+#define gteR12 ((s16*)psxRegs.CP2C.r)[SEL16(1)]
+#define gteR13 ((s16*)psxRegs.CP2C.r)[SEL16(2)]
+#define gteR21 ((s16*)psxRegs.CP2C.r)[SEL16(3)]
+#define gteR22 ((s16*)psxRegs.CP2C.r)[SEL16(4)]
+#define gteR23 ((s16*)psxRegs.CP2C.r)[SEL16(5)]
+#define gteR31 ((s16*)psxRegs.CP2C.r)[SEL16(6)]
+#define gteR32 ((s16*)psxRegs.CP2C.r)[SEL16(7)]
+#define gteR33 ((s16*)psxRegs.CP2C.r)[SEL16(8)]
+#define gteTRX ((s32*)psxRegs.CP2C.r)[5]
+#define gteTRY ((s32*)psxRegs.CP2C.r)[6]
+#define gteTRZ ((s32*)psxRegs.CP2C.r)[7]
+#define gteL11 ((s16*)psxRegs.CP2C.r)[SEL16(16)]
+#define gteL12 ((s16*)psxRegs.CP2C.r)[SEL16(17)]
+#define gteL13 ((s16*)psxRegs.CP2C.r)[SEL16(18)]
+#define gteL21 ((s16*)psxRegs.CP2C.r)[SEL16(19)]
+#define gteL22 ((s16*)psxRegs.CP2C.r)[SEL16(20)]
+#define gteL23 ((s16*)psxRegs.CP2C.r)[SEL16(21)]
+#define gteL31 ((s16*)psxRegs.CP2C.r)[SEL16(22)]
+#define gteL32 ((s16*)psxRegs.CP2C.r)[SEL16(23)]
+#define gteL33 ((s16*)psxRegs.CP2C.r)[SEL16(24)]
+#define gteRBK ((s32*)psxRegs.CP2C.r)[13]
+#define gteGBK ((s32*)psxRegs.CP2C.r)[14]
+#define gteBBK ((s32*)psxRegs.CP2C.r)[15]
+#define gteLR1 ((s16*)psxRegs.CP2C.r)[SEL16(32)]
+#define gteLR2 ((s16*)psxRegs.CP2C.r)[SEL16(33)]
+#define gteLR3 ((s16*)psxRegs.CP2C.r)[SEL16(34)]
+#define gteLG1 ((s16*)psxRegs.CP2C.r)[SEL16(35)]
+#define gteLG2 ((s16*)psxRegs.CP2C.r)[SEL16(36)]
+#define gteLG3 ((s16*)psxRegs.CP2C.r)[SEL16(37)]
+#define gteLB1 ((s16*)psxRegs.CP2C.r)[SEL16(38)]
+#define gteLB2 ((s16*)psxRegs.CP2C.r)[SEL16(39)]
+#define gteLB3 ((s16*)psxRegs.CP2C.r)[SEL16(40)]
+#define gteRFC ((s32*)psxRegs.CP2C.r)[21]
+#define gteGFC ((s32*)psxRegs.CP2C.r)[22]
+#define gteBFC ((s32*)psxRegs.CP2C.r)[23]
+#define gteOFX ((s32*)psxRegs.CP2C.r)[24]
+#define gteOFY ((s32*)psxRegs.CP2C.r)[25]
+#define gteH ((u16*)psxRegs.CP2C.r)[SEL16(52)]
+#define gteDQA ((s16*)psxRegs.CP2C.r)[SEL16(54)]
+#define gteDQB ((s32*)psxRegs.CP2C.r)[28]
+#define gteZSF3 ((s16*)psxRegs.CP2C.r)[SEL16(58)]
+#define gteZSF4 ((s16*)psxRegs.CP2C.r)[SEL16(60)]
+#define gteFLAG psxRegs.CP2C.r[31]
+
+__inline u32 MFC2(int reg) {
+ switch(reg) {
+ case 29:
+ gteORGB = (((gteIR1 >> 7) & 0x1f)) |
+ (((gteIR2 >> 7) & 0x1f)<<5) |
+ (((gteIR3 >> 7) & 0x1f)<<10);
+// gteORGB = (gteIR1 ) |
+// (gteIR2 << 5) |
+// (gteIR3 << 10);
+// gteORGB = ((gteIR1 & 0xf80)>>7) |
+// ((gteIR2 & 0xf80)>>2) |
+// ((gteIR3 & 0xf80)<<3);
+ return gteORGB;
+
+ default:
+ return psxRegs.CP2D.r[reg];
+ }
+}
+
+__inline void MTC2(u32 value, int reg) {
+ int a;
+
+ switch(reg) {
+ case 8: case 9: case 10: case 11:
+ psxRegs.CP2D.r[reg] = (short)value;
+ break;
+
+ case 15:
+ gteSXY0 = gteSXY1;
+ gteSXY1 = gteSXY2;
+ gteSXY2 = value;
+ gteSXYP = value;
+ break;
+
+ case 16: case 17: case 18: case 19:
+ psxRegs.CP2D.r[reg] = (value & 0xffff);
+ break;
+
+ case 28:
+ psxRegs.CP2D.r[28] = value;
+ gteIR1 = ((value ) & 0x1f) << 7;
+ gteIR2 = ((value >> 5) & 0x1f) << 7;
+ gteIR3 = ((value >> 10) & 0x1f) << 7;
+// gteIR1 = (value ) & 0x1f;
+// gteIR2 = (value >> 5) & 0x1f;
+// gteIR3 = (value >> 10) & 0x1f;
+// gteIR1 = ((value ) & 0x1f) << 4;
+// gteIR2 = ((value >> 5) & 0x1f) << 4;
+// gteIR3 = ((value >> 10) & 0x1f) << 4;
+ break;
+
+ case 30:
+ psxRegs.CP2D.r[30] = value;
+
+ a = psxRegs.CP2D.r[30];
+ if (a > 0) {
+ int i;
+ for (i=31; (a & (1 << i)) == 0 && i >= 0; i--);
+ psxRegs.CP2D.r[31] = 31 - i;
+ } else if (a < 0) {
+ int i;
+ a^= 0xffffffff;
+ for (i=31; (a & (1 << i)) == 0 && i >= 0; i--);
+ psxRegs.CP2D.r[31] = 31 - i;
+ } else {
+ psxRegs.CP2D.r[31] = 32;
+ }
+ break;
+
+ default:
+ psxRegs.CP2D.r[reg] = value;
+ }
+}
+
+void gteMFC2() {
+ if (!_Rt_) return;
+ psxRegs.GPR.r[_Rt_] = MFC2(_Rd_);
+}
+
+void gteCFC2() {
+ if (!_Rt_) return;
+ psxRegs.GPR.r[_Rt_] = psxRegs.CP2C.r[_Rd_];
+}
+
+void gteMTC2() {
+ MTC2(psxRegs.GPR.r[_Rt_], _Rd_);
+}
+
+void gteCTC2() {
+ psxRegs.CP2C.r[_Rd_] = psxRegs.GPR.r[_Rt_];
+}
+
+#define _oB_ (psxRegs.GPR.r[_Rs_] + _Imm_)
+
+void gteLWC2() {
+ MTC2(psxMemRead32(_oB_), _Rt_);
+}
+
+void gteSWC2() {
+ psxMemWrite32(_oB_, MFC2(_Rt_));
+}
+
+/////LIMITATIONS AND OTHER STUFF************************************
+
+
+/*
+#define MAGIC (((65536. * 65536. * 16) + (65536.*.5)) * 65536.)
+
+static __inline long float2int(double d)
+{
+ double dtemp = MAGIC + d;
+ return (*(long *)&dtemp)-0x80000000;
+}*/
+/*
+__inline double EDETEC1(double data)
+{
+ if (data<(double)-2147483647) {gteFLAG|=1<<30; return (double)-2147483647;}
+ else
+ if (data>(double) 2147483647) {gteFLAG|=1<<27; return (double) 2147483647;}
+
+ else return data;
+}
+
+__inline double EDETEC2(double data)
+{
+ if (data<(double)-2147483647) {gteFLAG|=1<<29; return (double)-2147483647;}
+ else
+ if (data>(double) 2147483647) {gteFLAG|=1<<26; return (double) 2147483647;}
+
+ else return data;
+}
+
+__inline double EDETEC3(double data)
+{
+ if (data<(double)-2147483647) {gteFLAG|=1<<28; return (double)-2147483647;}
+ else
+ if (data>(double) 2147483647) {gteFLAG|=1<<25; return (double) 2147483647;}
+
+ else return data;
+}
+
+__inline double EDETEC4(double data)
+{
+ if (data<(double)-2147483647) {gteFLAG|=1<<16; return (double)-2147483647;}
+ else
+ if (data>(double) 2147483647) {gteFLAG|=1<<15; return (double) 2147483647;}
+
+ else return data;
+}*/
+/*
+double LimitAU(double fraction,unsigned long bitIndex) {
+ if (fraction < 0.0) { fraction = 0.0; gteFLAG |= (1<<bitIndex); }
+ else
+ if (fraction > 32767.0) { fraction = 32767.0; gteFLAG |= (1<<bitIndex); }
+
+ return (fraction);
+}
+
+double LimitAS(double fraction,unsigned long bitIndex) {
+ if (fraction <-32768.0) { fraction =-32768.0; gteFLAG |= (1<<bitIndex); }
+ else
+ if (fraction > 32767.0) { fraction = 32767.0; gteFLAG |= (1<<bitIndex); }
+
+ return (fraction);
+}
+
+double LimitB (double fraction,unsigned long bitIndex) {
+ if (fraction < 0.0) { fraction = 0.0; gteFLAG |= (1<<bitIndex); }
+ else
+ if (fraction > 255.0) { fraction = 255.0; gteFLAG |= (1<<bitIndex); }
+
+ return (fraction);
+}
+
+double LimitC (double fraction,unsigned long bitIndex) {
+ if (fraction < 0.0) { fraction = 0.0; gteFLAG |= (1<<bitIndex); }
+ else
+ if (fraction > 65535.0) { fraction = 65535.0; gteFLAG |= (1<<bitIndex); }
+
+ return (fraction);
+}
+
+double LimitD (double fraction,unsigned long bitIndex) {
+ if (fraction < -1024.0) { fraction = -1024.0; gteFLAG |= (1<<bitIndex); }
+ else
+ if (fraction > 1023.0) { fraction = 1023.0; gteFLAG |= (1<<bitIndex); }
+
+ return (fraction);
+}
+
+double LimitE (double fraction,unsigned long bitIndex) {
+ if (fraction < 0.0) { fraction = 0.0; gteFLAG |= (1<<bitIndex); }
+ else
+ if (fraction > 1023.0) { fraction = 1023.0; gteFLAG |= (1<<bitIndex); }
+
+ return (fraction);
+}
+
+double LIMIT(double data,double MIN,double MAX,int FLAG)
+{
+ if (data<MIN) {gteFLAG|=1<<FLAG; return MIN;}
+ else
+ if (data>MAX) {gteFLAG|=1<<FLAG; return MAX;}
+
+ else return data;
+}
+
+double ALIMIT(double data,double MIN,double MAX)
+{
+ if (data<MIN) return MIN;
+ else
+ if (data>MAX) return MAX;
+
+ else return data;
+}
+
+double OLIMIT(double data)
+{
+ data=(data);
+
+ if (data<(double)-2147483647) {return (double)-2147483647;}
+ else
+ if (data>(double) 2147483647) {return (double) 2147483647;}
+
+ else return data;
+}*/
+
+__inline double NC_OVERFLOW1(double x) {
+ if (x<-2147483648.0) {gteFLAG |= 1<<29;}
+ else if (x> 2147483647.0) {gteFLAG |= 1<<26;}
+
+ return x;
+}
+
+__inline double NC_OVERFLOW2(double x) {
+ if (x<-2147483648.0) {gteFLAG |= 1<<28;}
+ else if (x> 2147483647.0) {gteFLAG |= 1<<25;}
+
+ return x;
+}
+
+__inline double NC_OVERFLOW3(double x) {
+ if (x<-2147483648.0) {gteFLAG |= 1<<27;}
+ else if (x> 2147483647.0) {gteFLAG |= 1<<24;}
+
+ return x;
+}
+
+__inline double NC_OVERFLOW4(double x) {
+ if (x<-2147483648.0) {gteFLAG |= 1<<16;}
+ else if (x> 2147483647.0) {gteFLAG |= 1<<15;}
+
+ return x;
+}
+
+__inline s32 FNC_OVERFLOW1(s64 x) {
+ if (x < UNDERFLOW_BOUND) { gteFLAG |= (1 << 29); }
+ else if (x > 2147483647) { gteFLAG |= (1 << 26); }
+
+ return (s32)x;
+}
+
+__inline s32 FNC_OVERFLOW2(s64 x) {
+ if (x < UNDERFLOW_BOUND) { gteFLAG |= (1 << 28); }
+ else if (x > 2147483647) { gteFLAG |= (1 << 25); }
+
+ return (s32)x;
+}
+
+__inline s32 FNC_OVERFLOW3(s64 x) {
+ if (x < UNDERFLOW_BOUND) { gteFLAG |= (1 << 27); }
+ else if (x > 2147483647) { gteFLAG |= (1 << 24); }
+
+ return (s32)x;
+}
+
+__inline s32 FNC_OVERFLOW4(s64 x) {
+ if (x < UNDERFLOW_BOUND) { gteFLAG |= (1 << 16); }
+ else if (x > 2147483647) { gteFLAG |= (1 << 15); }
+
+ return (s32)x;
+}
+
+#define _LIMX(negv, posv, flagb) { \
+ if (x < (negv)) { x = (negv); gteFLAG |= (1<<flagb); } else \
+ if (x > (posv)) { x = (posv); gteFLAG |= (1<<flagb); } return (x); \
+}
+
+__inline double limA1S(double x) { _LIMX(-32768.0, 32767.0, 24); }
+__inline double limA2S(double x) { _LIMX(-32768.0, 32767.0, 23); }
+__inline double limA3S(double x) { _LIMX(-32768.0, 32767.0, 22); }
+__inline double limA1U(double x) { _LIMX(0.0, 32767.0, 24); }
+__inline double limA2U(double x) { _LIMX(0.0, 32767.0, 23); }
+__inline double limA3U(double x) { _LIMX(0.0, 32767.0, 22); }
+__inline double limB1 (double x) { _LIMX(0.0, 255.0, 21); }
+__inline double limB2 (double x) { _LIMX(0.0, 255.0, 20); }
+__inline double limB3 (double x) { _LIMX(0.0, 255.0, 19); }
+__inline double limC (double x) { _LIMX(0.0, 65535.0, 18); }
+__inline double limD1 (double x) { _LIMX(-1024.0, 1023.0, 14); }
+__inline double limD2 (double x) { _LIMX(-1024.0, 1023.0, 13); }
+__inline double limE (double x) { _LIMX(0.0, 4095.0, 12); }
+
+__inline double limG1(double x) {
+ if (x > 2147483647.0) { gteFLAG |= (1<<16); } else
+ if (x <-2147483648.0) { gteFLAG |= (1<<15); }
+
+ if (x > 1023.0) { x = 1023.0; gteFLAG |= (1<<14); } else
+ if (x < -1024.0) { x = -1024.0; gteFLAG |= (1<<14); } return (x);
+}
+
+__inline double limG2(double x) {
+ if (x > 2147483647.0) { gteFLAG |= (1<<16); } else
+ if (x <-2147483648.0) { gteFLAG |= (1<<15); }
+
+ if (x > 1023.0) { x = 1023.0; gteFLAG |= (1<<13); } else
+ if (x < -1024.0) { x = -1024.0; gteFLAG |= (1<<13); } return (x);
+}
+
+__inline s32 F12limA1S(s64 x) { _LIMX(-32768<<12, 32767<<12, 24); }
+__inline s32 F12limA2S(s64 x) { _LIMX(-32768<<12, 32767<<12, 23); }
+__inline s32 F12limA3S(s64 x) { _LIMX(-32768<<12, 32767<<12, 22); }
+__inline s32 F12limA1U(s64 x) { _LIMX(0, 32767<<12, 24); }
+__inline s32 F12limA2U(s64 x) { _LIMX(0, 32767<<12, 23); }
+__inline s32 F12limA3U(s64 x) { _LIMX(0, 32767<<12, 22); }
+
+__inline s16 FlimA1S(s32 x) { _LIMX(-32768, 32767, 24); }
+__inline s16 FlimA2S(s32 x) { _LIMX(-32768, 32767, 23); }
+__inline s16 FlimA3S(s32 x) { _LIMX(-32768, 32767, 22); }
+__inline s16 FlimA1U(s32 x) { _LIMX(0, 32767, 24); }
+__inline s16 FlimA2U(s32 x) { _LIMX(0, 32767, 23); }
+__inline s16 FlimA3U(s32 x) { _LIMX(0, 32767, 22); }
+__inline u8 FlimB1 (s32 x) { _LIMX(0, 255, 21); }
+__inline u8 FlimB2 (s32 x) { _LIMX(0, 255, 20); }
+__inline u8 FlimB3 (s32 x) { _LIMX(0, 255, 19); }
+__inline u16 FlimC (s32 x) { _LIMX(0, 65535, 18); }
+__inline s32 FlimD1 (s32 x) { _LIMX(-1024, 1023, 14); }
+__inline s32 FlimD2 (s32 x) { _LIMX(-1024, 1023, 13); }
+__inline s32 FlimE (s32 x) { _LIMX(0, 65535, 12); }
+//__inline s32 FlimE (s32 x) { _LIMX(0, 4095, 12); }
+
+__inline s32 FlimG1(s64 x) {
+ if (x > 2147483647) { gteFLAG |= (1 << 16); }
+ else if (x < UNDERFLOW_BOUND) { gteFLAG |= (1 << 15); }
+
+ if (x > 1023) { x = 1023; gteFLAG |= (1 << 14); }
+ else if (x < -1024) { x = -1024; gteFLAG |= (1 << 14); } return (x);
+}
+
+__inline s32 FlimG2(s64 x) {
+ if (x > 2147483647) { gteFLAG |= (1 << 16); }
+ else if (x < UNDERFLOW_BOUND) { gteFLAG |= (1 << 15); }
+
+ if (x > 1023) { x = 1023; gteFLAG |= (1 << 13); }
+ else if (x < -1024) { x = -1024; gteFLAG |= (1 << 13); } return (x);
+}
+
+#define MAC2IR() { \
+ if (gteMAC1 < (long)(-32768)) { gteIR1=(long)(-32768); gteFLAG |= (1 << 24);} \
+ else \
+ if (gteMAC1 > (long)( 32767)) { gteIR1=(long)( 32767); gteFLAG |= (1 << 24);} \
+ else gteIR1=(long)gteMAC1; \
+ if (gteMAC2 < (long)(-32768)) { gteIR2=(long)(-32768); gteFLAG|=1<<23;} \
+ else \
+ if (gteMAC2 > (long)( 32767)) { gteIR2=(long)( 32767); gteFLAG|=1<<23;} \
+ else gteIR2=(long)gteMAC2; \
+ if (gteMAC3 < (long)(-32768)) { gteIR3=(long)(-32768); gteFLAG|=1<<22;} \
+ else \
+ if (gteMAC3 > (long)( 32767)) { gteIR3=(long)( 32767); gteFLAG|=1<<22;} \
+ else gteIR3=(long)gteMAC3; \
+}
+
+
+#define MAC2IR1() { \
+ if (gteMAC1 < (long)0) { gteIR1=(long)0; gteFLAG|=1<<24;} \
+ else if (gteMAC1 > (long)(32767)) { gteIR1=(long)(32767); gteFLAG|=1<<24;} \
+ else gteIR1=(long)gteMAC1; \
+ if (gteMAC2 < (long)0) { gteIR2=(long)0; gteFLAG|=1<<23;} \
+ else if (gteMAC2 > (long)(32767)) { gteIR2=(long)(32767); gteFLAG|=1<<23;} \
+ else gteIR2=(long)gteMAC2; \
+ if (gteMAC3 < (long)0) { gteIR3=(long)0; gteFLAG|=1<<22;} \
+ else if (gteMAC3 > (long)(32767)) { gteIR3=(long)(32767); gteFLAG|=1<<22;} \
+ else gteIR3=(long)gteMAC3; \
+}
+
+//********END OF LIMITATIONS**********************************/
+
+#define GTE_RTPS1(vn) { \
+ gteMAC1 = FNC_OVERFLOW1(((signed long)(gteR11*gteVX##vn + gteR12*gteVY##vn + gteR13*gteVZ##vn)>>12) + gteTRX); \
+ gteMAC2 = FNC_OVERFLOW2(((signed long)(gteR21*gteVX##vn + gteR22*gteVY##vn + gteR23*gteVZ##vn)>>12) + gteTRY); \
+ gteMAC3 = FNC_OVERFLOW3(((signed long)(gteR31*gteVX##vn + gteR32*gteVY##vn + gteR33*gteVZ##vn)>>12) + gteTRZ); \
+}
+
+/* gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX0 + gteR12*gteVY0 + gteR13*gteVZ0)>>12) + gteTRX);
+ gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX0 + gteR22*gteVY0 + gteR23*gteVZ0)>>12) + gteTRY);
+ gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX0 + gteR32*gteVY0 + gteR33*gteVZ0)>>12) + gteTRZ);*/
+
+#if 0
+
+#define GTE_RTPS2(vn) { \
+ if (gteSZ##vn == 0) { \
+ DSZ = 2.0f; gteFLAG |= 1<<17; \
+ } else { \
+ DSZ = (double)gteH / gteSZ##vn; \
+ if (DSZ > 2.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } \
+/* if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; }*/ \
+ } \
+ \
+/* gteSX##vn = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ));*/ \
+/* gteSY##vn = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ));*/ \
+ gteSX##vn = FlimG1(gteOFX/65536.0 + (gteIR1 * DSZ)); \
+ gteSY##vn = FlimG2(gteOFY/65536.0 + (gteIR2 * DSZ)); \
+}
+
+#define GTE_RTPS3() { \
+ DSZ = gteDQB/16777216.0 + (gteDQA/256.0) * DSZ; \
+ gteMAC0 = DSZ * 16777216.0; \
+ gteIR0 = limE(DSZ * 4096.0f); \
+printf("zero %x, %x\n", gteMAC0, gteIR0); \
+}
+#endif
+//#if 0
+#define GTE_RTPS2(vn) { \
+ if (gteSZ##vn == 0) { \
+ FDSZ = 2 << 16; gteFLAG |= 1<<17; \
+ } else { \
+ FDSZ = ((u64)gteH << 32) / ((u64)gteSZ##vn << 16); \
+ if ((u64)FDSZ > (2 << 16)) { FDSZ = 2 << 16; gteFLAG |= 1<<17; } \
+ } \
+ \
+ gteSX##vn = FlimG1((gteOFX + (((s64)((s64)gteIR1 << 16) * FDSZ) >> 16)) >> 16); \
+ gteSY##vn = FlimG2((gteOFY + (((s64)((s64)gteIR2 << 16) * FDSZ) >> 16)) >> 16); \
+}
+
+#define GTE_RTPS3() { \
+ FDSZ = (s64)((s64)gteDQB + (((s64)((s64)gteDQA << 8) * FDSZ) >> 8)); \
+ gteMAC0 = FDSZ; \
+ gteIR0 = FlimE(FDSZ >> 12); \
+}
+//#endif
+// gteMAC0 = (gteDQB/16777216.0 + (gteDQA/256.0) * DSZ) * 16777216.0;
+// gteIR0 = limE((gteDQB/16777216.0 + (gteDQA/256.0) * DSZ) * 4096.0);
+// gteMAC0 = ((gteDQB >> 24) + (gteDQA >> 8) * DSZ) * 16777216.0;
+// gteIR0 = FlimE(((gteDQB >> 24) + (gteDQA >> 8) * DSZ) * 4096.0);
+
+
+void gteRTPS() {
+// double SSX0,SSY0,SSZ0;
+// double SZ;
+// double DSZ;
+ s64 FDSZ;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_RTPS\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("RTPS", 14);
+ G_SD(0);
+ G_SD(1);
+
+ G_SD(16); // Store original fifo
+ G_SD(17);
+ G_SD(18);
+ G_SD(19);
+
+ G_SC(0);
+ G_SC(1);
+ G_SC(2);
+ G_SC(3);
+ G_SC(4);
+ G_SC(5);
+ G_SC(6);
+ G_SC(7);
+
+ G_SC(24);
+ G_SC(25);
+ G_SC(26);
+ G_SC(27);
+ G_SC(28);
+ }
+#endif
+/* gteFLAG = 0;
+
+ SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX0*gteR11) + (double)(gteVY0*gteR12) + (double)(gteVZ0*gteR13))/4096.0);
+ SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX0*gteR21) + (double)(gteVY0*gteR22) + (double)(gteVZ0*gteR23))/4096.0);
+ SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX0*gteR31) + (double)(gteVY0*gteR32) + (double)(gteVZ0*gteR33))/4096.0);
+
+ SZ = LIMIT(SSZ0,(double)0,(double)65535,18);
+ DSZ = ((double)gteH/SZ);
+
+ if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;}
+
+ gteSZ0 = gteSZ1;
+ gteSZ1 = gteSZ2;
+ gteSZ2 = gteSZx;
+ gteSZx = (unsigned short)float2int(SZ);
+
+ psxRegs.CP2D.r[12]= psxRegs.CP2D.r[13];
+ psxRegs.CP2D.r[13]= psxRegs.CP2D.r[14];
+
+ gteSX2 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1024,14));
+ gteSY2 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1024,13));
+
+ gteMAC1 = (signed long)(SSX0);
+ gteMAC2 = (signed long)(SSY0);
+ gteMAC3 = (signed long)(SSZ0);
+
+ MAC2IR();
+
+ gteMAC0 = (signed long)float2int(OLIMIT((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*16777216));
+ gteIR0 = (signed long)float2int(LIMIT(((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*4096),(double)0,(double)4095,12));
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+ gteFLAG = 0;
+
+ GTE_RTPS1(0);
+
+ MAC2IR();
+
+ gteSZx = gteSZ0;
+ gteSZ0 = gteSZ1;
+ gteSZ1 = gteSZ2;
+// gteSZ2 = limC(gteMAC3);
+ gteSZ2 = FlimC(gteMAC3);
+
+ gteSXY0 = gteSXY1;
+ gteSXY1 = gteSXY2;
+
+ GTE_RTPS2(2);
+ gteSXYP = gteSXY2;
+
+ GTE_RTPS3();
+
+ SUM_FLAG;
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(8);
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(12);
+ //G_GD(13);
+ G_GD(14);
+
+ G_GD(16);
+ G_GD(17);
+ G_GD(18);
+ G_GD(19);
+
+ G_GD(24);
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteRTPT() {
+// double SSX0,SSY0,SSZ0;
+// double SZ;
+// double DSZ;
+ s64 FDSZ;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_RTPT\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("RTPT", 22);
+ G_SD(0);
+ G_SD(1);
+ G_SD(2);
+ G_SD(3);
+ G_SD(4);
+ G_SD(5);
+
+ G_SD(16); // Store original fifo
+ G_SD(17);
+ G_SD(18);
+ G_SD(19);
+
+ G_SC(0);
+ G_SC(1);
+ G_SC(2);
+ G_SC(3);
+ G_SC(4);
+ G_SC(5);
+ G_SC(6);
+ G_SC(7);
+
+ G_SC(24);
+ G_SC(25);
+ G_SC(26);
+ G_SC(27);
+ G_SC(28);
+ }
+#endif
+/* gteFLAG = 0;
+
+ gteSZ0 = gteSZx;
+
+ SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX0 * gteR11) + (double)(gteVY0 * gteR12) + (double)(gteVZ0 * gteR13)) / 4096.0);
+ SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX0 * gteR21) + (double)(gteVY0 * gteR22) + (double)(gteVZ0 * gteR23)) / 4096.0);
+ SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX0 * gteR31) + (double)(gteVY0 * gteR32) + (double)(gteVZ0 * gteR33)) / 4096.0);
+
+ SZ = LIMIT(SSZ0, (double)0, (double)65535, 18);
+ DSZ = ((double)gteH / SZ);
+
+ if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;}
+
+ gteSZ1 = (unsigned short)float2int(SZ);
+ gteSX0 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1023,14));
+ gteSY0 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1023,13));
+
+ SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX1*gteR11) + (double)(gteVY1*gteR12) + (double)(gteVZ1*gteR13))/4096.0);
+ SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX1*gteR21) + (double)(gteVY1*gteR22) + (double)(gteVZ1*gteR23))/4096.0);
+ SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX1*gteR31) + (double)(gteVY1*gteR32) + (double)(gteVZ1*gteR33))/4096.0);
+
+ SZ = LIMIT(SSZ0,(double)0,(double)65535,18);
+ DSZ = ((double)gteH/SZ);
+
+ if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;}
+
+ gteSZ2 = (unsigned short)float2int(SZ);
+ gteSX1 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1023,14));
+ gteSY1 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1023,13));
+
+ SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX2*gteR11) + (double)(gteVY2*gteR12) + (double)(gteVZ2*gteR13))/4096.0);
+ SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX2*gteR21) + (double)(gteVY2*gteR22) + (double)(gteVZ2*gteR23))/4096.0);
+ SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX2*gteR31) + (double)(gteVY2*gteR32) + (double)(gteVZ2*gteR33))/4096.0);
+
+ SZ = LIMIT(SSZ0,(double)0,(double)65535,18);
+ DSZ = ((double)gteH/SZ);
+
+ if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;}
+
+ gteSZx = (unsigned short)float2int(SZ);
+ gteSX2 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1023,14));
+ gteSY2 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1023,13));
+
+ gteMAC1 = (signed long)float2int(SSX0);
+ gteMAC2 = (signed long)float2int(SSY0);
+ gteMAC3 = (signed long)float2int(SSZ0);
+
+ MAC2IR();
+
+ gteMAC0 = (signed long)float2int(OLIMIT((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*16777216));
+ gteIR0 = (signed long)float2int(LIMIT(((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*4096),(double)0,(double)4095,12));
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+ /* NC: old
+ gteFLAG = 0;
+
+ gteSZ0 = gteSZx;
+
+ gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX0 + gteR12*gteVY0 + gteR13*gteVZ0)>>12) + gteTRX);
+ gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX0 + gteR22*gteVY0 + gteR23*gteVZ0)>>12) + gteTRY);
+ gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX0 + gteR32*gteVY0 + gteR33*gteVZ0)>>12) + gteTRZ);
+
+ DSZ = gteH / limC(gteMAC3);
+ if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; }
+
+ gteSZ1 = limC(gteMAC3);
+
+ gteSX0 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ));
+ gteSY0 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ));
+
+ gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX1 + gteR12*gteVY1 + gteR13*gteVZ1)>>12) + gteTRX);
+ gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX1 + gteR22*gteVY1 + gteR23*gteVZ1)>>12) + gteTRY);
+ gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX1 + gteR32*gteVY1 + gteR33*gteVZ1)>>12) + gteTRZ);
+
+ DSZ = gteH / limC(gteMAC3);
+ if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; }
+
+ gteSZ2 = limC(gteMAC3);
+
+ gteSX1 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ ));
+ gteSY1 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ ));
+
+ gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX2 + gteR12*gteVY2 + gteR13*gteVZ2)>>12) + gteTRX);
+ gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX2 + gteR22*gteVY2 + gteR23*gteVZ2)>>12) + gteTRY);
+ gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX2 + gteR32*gteVY2 + gteR33*gteVZ2)>>12) + gteTRZ);
+
+ DSZ = gteH / limC(gteMAC3); if (DSZ > 2147483647.0f) { DSZ = 2.0f; gteFLAG |= 1<<17; }
+
+ gteSZx = gteSZ2;
+
+ gteSX2 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ ));
+ gteSY2 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ ));
+
+ MAC2IR();
+
+ gteMAC0 = (gteDQB/16777216.0 + (gteDQA/256.0) * DSZ ) * 16777216.0;
+ gteIR0 = limE((gteDQB/16777216.0 + (gteDQA/256.0) * DSZ ) * 4096.0f);
+ */
+
+ gteFLAG = 0;
+
+ gteSZx = gteSZ2;
+
+ GTE_RTPS1(0);
+
+// gteSZ0 = limC(gteMAC3);
+ gteSZ0 = FlimC(gteMAC3);
+
+ gteIR1 = FlimA1S(gteMAC1);
+ gteIR2 = FlimA2S(gteMAC2);
+ GTE_RTPS2(0);
+
+ GTE_RTPS1(1);
+
+// gteSZ1 = limC(gteMAC3);
+ gteSZ1 = FlimC(gteMAC3);
+
+ gteIR1 = FlimA1S(gteMAC1);
+ gteIR2 = FlimA2S(gteMAC2);
+ GTE_RTPS2(1);
+
+ GTE_RTPS1(2);
+
+ MAC2IR();
+
+// gteSZ2 = limC(gteMAC3);
+ gteSZ2 = FlimC(gteMAC3);
+
+ GTE_RTPS2(2);
+ gteSXYP = gteSXY2;
+
+ GTE_RTPS3();
+
+ SUM_FLAG;
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(8);
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ G_GD(12);
+ G_GD(13);
+ G_GD(14);
+
+ G_GD(16);
+ G_GD(17);
+ G_GD(18);
+ G_GD(19);
+
+ G_GD(24);
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+#define gte_C11 gteLR1
+#define gte_C12 gteLR2
+#define gte_C13 gteLR3
+#define gte_C21 gteLG1
+#define gte_C22 gteLG2
+#define gte_C23 gteLG3
+#define gte_C31 gteLB1
+#define gte_C32 gteLB2
+#define gte_C33 gteLB3
+
+#define _MVMVA_FUNC(_v0, _v1, _v2, mx) { \
+ SSX = (_v0) * mx##11 + (_v1) * mx##12 + (_v2) * mx##13; \
+ SSY = (_v0) * mx##21 + (_v1) * mx##22 + (_v2) * mx##23; \
+ SSZ = (_v0) * mx##31 + (_v1) * mx##32 + (_v2) * mx##33; \
+}
+
+void gteMVMVA() {
+// double SSX, SSY, SSZ;
+ s64 SSX, SSY, SSZ;
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_MVMVA %lx\n", psxRegs.code & 0x1ffffff);
+#endif
+
+ switch (psxRegs.code & 0x78000) {
+ case 0x00000: // V0 * R
+ _MVMVA_FUNC(gteVX0, gteVY0, gteVZ0, gteR); break;
+ case 0x08000: // V1 * R
+ _MVMVA_FUNC(gteVX1, gteVY1, gteVZ1, gteR); break;
+ case 0x10000: // V2 * R
+ _MVMVA_FUNC(gteVX2, gteVY2, gteVZ2, gteR); break;
+ case 0x18000: // IR * R
+ _MVMVA_FUNC((short)gteIR1, (short)gteIR2, (short)gteIR3, gteR);
+ break;
+ case 0x20000: // V0 * L
+ _MVMVA_FUNC(gteVX0, gteVY0, gteVZ0, gteL); break;
+ case 0x28000: // V1 * L
+ _MVMVA_FUNC(gteVX1, gteVY1, gteVZ1, gteL); break;
+ case 0x30000: // V2 * L
+ _MVMVA_FUNC(gteVX2, gteVY2, gteVZ2, gteL); break;
+ case 0x38000: // IR * L
+ _MVMVA_FUNC((short)gteIR1, (short)gteIR2, (short)gteIR3, gteL); break;
+ case 0x40000: // V0 * C
+ _MVMVA_FUNC(gteVX0, gteVY0, gteVZ0, gte_C); break;
+ case 0x48000: // V1 * C
+ _MVMVA_FUNC(gteVX1, gteVY1, gteVZ1, gte_C); break;
+ case 0x50000: // V2 * C
+ _MVMVA_FUNC(gteVX2, gteVY2, gteVZ2, gte_C); break;
+ case 0x58000: // IR * C
+ _MVMVA_FUNC((short)gteIR1, (short)gteIR2, (short)gteIR3, gte_C); break;
+ default:
+ SSX = SSY = SSZ = 0;
+ }
+
+ if (psxRegs.code & 0x80000) {
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ SSX>>= 12; SSY>>= 12; SSZ>>= 12;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ SSX+= gteTRX;
+ SSY+= gteTRY;
+ SSZ+= gteTRZ;
+ break;
+ case 0x2000: // Add BK
+ SSX+= gteRBK;
+ SSY+= gteGBK;
+ SSZ+= gteBBK;
+ break;
+ case 0x4000: // Add FC
+ SSX+= gteRFC;
+ SSY+= gteGFC;
+ SSZ+= gteBFC;
+ break;
+ }
+
+ gteFLAG = 0;
+ //gteMAC1 = (long)SSX;
+ //gteMAC2 = (long)SSY;
+ //gteMAC3 = (long)SSZ;//okay the follow lines are correct??
+/* gteMAC1 = NC_OVERFLOW1(SSX);
+ gteMAC2 = NC_OVERFLOW2(SSY);
+ gteMAC3 = NC_OVERFLOW3(SSZ);*/
+ gteMAC1 = FNC_OVERFLOW1(SSX);
+ gteMAC2 = FNC_OVERFLOW2(SSY);
+ gteMAC3 = FNC_OVERFLOW3(SSZ);
+ if (psxRegs.code & 0x400)
+ MAC2IR1()
+ else MAC2IR()
+
+ SUM_FLAG;
+}
+
+void gteNCLIP() {
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCLIP\n");
+#endif
+
+ //gteLog
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCLIP", 8);
+ G_SD(12);
+ G_SD(13);
+ G_SD(14);
+ }
+#endif
+
+/* gteFLAG = 0;
+
+ gteMAC0 = (signed long)float2int(EDETEC4(
+ ((double)gteSX0*((double)gteSY1-(double)gteSY2))+
+ ((double)gteSX1*((double)gteSY2-(double)gteSY0))+
+ ((double)gteSX2*((double)gteSY0-(double)gteSY1))));
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+
+ gteMAC0 = gteSX0 * (gteSY1 - gteSY2) +
+ gteSX1 * (gteSY2 - gteSY0) +
+ gteSX2 * (gteSY0 - gteSY1);
+
+ //gteMAC0 = (gteSX0 - gteSX1) * (gteSY0 - gteSY2) - (gteSX0 - gteSX2) * (gteSY0 - gteSY1);
+
+ SUM_FLAG;
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(24);
+ G_GC(31);
+ }
+#endif
+}
+
+void gteAVSZ3() {
+// unsigned long SS;
+// double SZ1,SZ2,SZ3;
+// double ZSF3;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_AVSZ3\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("AVSZ3", 5);
+ G_SD(16);
+ G_SD(17);
+ G_SD(18);
+ G_SD(19);
+ G_SC(29);
+ G_SC(30);
+ }
+#endif
+
+/* gteFLAG = 0;
+
+ SS = psxRegs.CP2D.r[17] & 0xffff; SZ1 = (double)SS;
+ SS = psxRegs.CP2D.r[18] & 0xffff; SZ2 = (double)SS;
+ SS = psxRegs.CP2D.r[19] & 0xffff; SZ3 = (double)SS;
+ SS = psxRegs.CP2C.r[29] & 0xffff; ZSF3 = (double)SS/(double)4096;
+
+ psxRegs.CP2D.r[24] = (signed long)float2int(EDETEC4(((SZ1+SZ2+SZ3)*ZSF3)));
+ psxRegs.CP2D.r[7] = (unsigned short)float2int(LimitC(((SZ1+SZ2+SZ3)*ZSF3),18));
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+
+ gteFLAG = 0;
+
+ /* NC: OLD
+ gteMAC0 = ((gteSZ1 + gteSZ2 + gteSZx) * (gteZSF3/4096.0f));
+
+ gteOTZ = limC((double)gteMAC0);
+ */
+/* gteMAC0 = ((gteSZ1 + gteSZ2 + gteSZx) * (gteZSF3));
+
+ gteOTZ = limC((double)(gteMAC0 >> 12));*/
+ gteMAC0 = ((gteSZ0 + gteSZ1 + gteSZ2) * (gteZSF3)) >> 12;
+
+ gteOTZ = FlimC(gteMAC0);
+// gteOTZ = limC((double)gteMAC0);
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(7);
+ G_GD(24);
+ G_GC(31);
+ }
+#endif
+}
+
+void gteAVSZ4() {
+// unsigned long SS;
+// double SZ0,SZ1,SZ2,SZ3;
+// double ZSF4;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_AVSZ4\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("AVSZ4", 6);
+ G_SD(16);
+ G_SD(17);
+ G_SD(18);
+ G_SD(19);
+ G_SC(29);
+ G_SC(30);
+ }
+#endif
+
+/* gteFLAG = 0;
+
+ SS = psxRegs.CP2D.r[16] & 0xffff; SZ0 = (double)SS;
+ SS = psxRegs.CP2D.r[17] & 0xffff; SZ1 = (double)SS;
+ SS = psxRegs.CP2D.r[18] & 0xffff; SZ2 = (double)SS;
+ SS = psxRegs.CP2D.r[19] & 0xffff; SZ3 = (double)SS;
+ SS = psxRegs.CP2C.r[30] & 0xffff; ZSF4 = (double)SS/(double)4096;
+
+ psxRegs.CP2D.r[24] = (signed long)float2int(EDETEC4(((SZ0+SZ1+SZ2+SZ3)*ZSF4)));
+ psxRegs.CP2D.r[7] = (unsigned short)float2int(LimitC(((SZ0+SZ1+SZ2+SZ3)*ZSF4),18));
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+ /* NC: OLD
+ gteMAC0 = ((gteSZ0 + gteSZ1 + gteSZ2 + gteSZx) * (gteZSF4/4096.0f));
+
+ gteOTZ = limC((double)gteMAC0);
+ */
+/* gteMAC0 = ((gteSZ0 + gteSZ1 + gteSZ2 + gteSZx) * (gteZSF4));
+
+ gteOTZ = limC((double)(gteMAC0 >> 12));
+*/
+ gteMAC0 = ((gteSZx + gteSZ0 + gteSZ1 + gteSZ2) * (gteZSF4))>> 12;
+
+ gteOTZ = FlimC(gteMAC0);
+// gteOTZ = limC((double)gteMAC0);
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(7);
+ G_GD(24);
+ G_GC(31);
+ }
+#endif
+}
+
+void gteSQR() {
+ //double SSX0,SSY0,SSZ0;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_SQR %lx\n", psxRegs.code & 0x1ffffff);
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("SQR", 5);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+ }
+#endif
+
+/* gteFLAG = 0;
+
+ SSX0 = (double)gteIR1 * gteIR1;
+ SSY0 = (double)gteIR2 * gteIR2;
+ SSZ0 = (double)gteIR3 * gteIR3;
+
+ if (psxRegs.code & 0x80000) {
+ SSX0 /= 4096.0; SSY0 /= 4096.0; SSZ0 /= 4096.0;
+ }
+
+ gteMAC1 = (long)SSX0;
+ gteMAC2 = (long)SSY0;
+ gteMAC3 = (long)SSZ0;
+
+ MAC2IR1();
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+/* if (psxRegs.code & 0x80000) {
+ gteMAC1 = NC_OVERFLOW1((gteIR1 * gteIR1) / 4096.0f);
+ gteMAC2 = NC_OVERFLOW2((gteIR2 * gteIR2) / 4096.0f);
+ gteMAC3 = NC_OVERFLOW3((gteIR3 * gteIR3) / 4096.0f);
+ } else {
+ gteMAC1 = NC_OVERFLOW1(gteIR1 * gteIR1);
+ gteMAC2 = NC_OVERFLOW2(gteIR2 * gteIR2);
+ gteMAC3 = NC_OVERFLOW3(gteIR3 * gteIR3);
+ }*/
+ if (psxRegs.code & 0x80000) {
+ gteMAC1 = FNC_OVERFLOW1((gteIR1 * gteIR1) >> 12);
+ gteMAC2 = FNC_OVERFLOW2((gteIR2 * gteIR2) >> 12);
+ gteMAC3 = FNC_OVERFLOW3((gteIR3 * gteIR3) >> 12);
+ } else {
+ gteMAC1 = FNC_OVERFLOW1(gteIR1 * gteIR1);
+ gteMAC2 = FNC_OVERFLOW2(gteIR2 * gteIR2);
+ gteMAC3 = FNC_OVERFLOW3(gteIR3 * gteIR3);
+ }
+ MAC2IR1();
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+ G_GC(31);
+ }
+#endif
+}
+/*
+#define GTE_NCCS(vn) { \
+ RR0 = ((double)gteL11 * gteVX##vn + (double)gteL12 * gteVY##vn + (double)gteL13 * gteVZ##vn)/4096.0; \
+ GG0 = ((double)gteL21 * gteVX##vn + (double)gteL22 * gteVY##vn + (double)gteL23 * gteVZ##vn)/4096.0; \
+ BB0 = ((double)gteL31 * gteVX##vn + (double)gteL32 * gteVY##vn + (double)gteL33 * gteVZ##vn)/4096.0; \
+ t1 = LimitAU(RR0,24); \
+ t2 = LimitAU(GG0,23); \
+ t3 = LimitAU(BB0,22); \
+ \
+ RR0 = (double)gteRBK + ((double)gteLR1 * t1 + (double)gteLR2 * t2 + (double)gteLR3 * t3)/4096.0; \
+ GG0 = (double)gteGBK + ((double)gteLG1 * t1 + (double)gteLG2 * t2 + (double)gteLG3 * t3)/4096.0; \
+ BB0 = (double)gteBBK + ((double)gteLB1 * t1 + (double)gteLB2 * t2 + (double)gteLB3 * t3)/4096.0; \
+ t1 = LimitAU(RR0,24); \
+ t2 = LimitAU(GG0,23); \
+ t3 = LimitAU(BB0,22); \
+ \
+ RR0 = ((double)gteR * t1)/256.0; \
+ GG0 = ((double)gteG * t2)/256.0; \
+ BB0 = ((double)gteB * t3)/256.0; \
+ \
+ gteIR1 = (long)LimitAU(RR0,24); \
+ gteIR2 = (long)LimitAU(GG0,23); \
+ gteIR3 = (long)LimitAU(BB0,22); \
+ \
+ gteCODE0 = gteCODE1; gteCODE1 = gteCODE2; gteCODE2 = gteCODE; \
+ gteR0 = gteR1; gteR1 = gteR2; gteR2 = (unsigned char)LimitB(RR0/16.0,21); \
+ gteG0 = gteG1; gteG1 = gteG2; gteG2 = (unsigned char)LimitB(GG0/16.0,20); \
+ gteB0 = gteB1; gteB1 = gteB2; gteB2 = (unsigned char)LimitB(BB0/16.0,19); \
+ \
+ gteMAC1 = (long)RR0; \
+ gteMAC2 = (long)GG0; \
+ gteMAC3 = (long)BB0; \
+}
+*/
+/*
+__forceinline double ncLIM1(double x)
+{
+ if(x > 8796093022207.0)
+ {
+ return 8796093022207.0;
+ }
+}
+*/
+
+
+
+/* NC: OLD
+#define GTE_NCCS(vn)\
+gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\
+gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\
+gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\
+gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\
+gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\
+gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\
+gte_RR0 = gteR*gte_RRLT;\
+gte_GG0 = gteG*gte_GGLT;\
+gte_BB0 = gteB*gte_BBLT;\
+gteIR1 = (long)limA1U(gte_RR0);\
+gteIR2 = (long)limA2U(gte_GG0);\
+gteIR3 = (long)limA3U(gte_BB0);\
+gteCODE0 = gteCODE1; gteCODE1 = gteCODE2; gteCODE2 = gteCODE;\
+gteR0 = gteR1; gteR1 = gteR2; gteR2 = (unsigned char)limB1(gte_RR0);\
+gteG0 = gteG1; gteG1 = gteG2; gteG2 = (unsigned char)limB2(gte_GG0);\
+gteB0 = gteB1; gteB1 = gteB2; gteB2 = (unsigned char)limB3(gte_BB0);\
+gteMAC1 = (long)gte_RR0;\
+gteMAC2 = (long)gte_GG0;\
+gteMAC3 = (long)gte_BB0;\
+*/
+/*
+#define GTE_NCCS(vn)\
+gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\
+gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\
+gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\
+gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\
+gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\
+gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\
+gteMAC1 = (long)(gteR*gte_RRLT*16);\
+gteMAC2 = (long)(gteG*gte_GGLT*16);\
+gteMAC3 = (long)(gteB*gte_BBLT*16);\
+gteIR1 = (long)limA1U(gteMAC1);\
+gteIR2 = (long)limA2U(gteMAC2);\
+gteIR3 = (long)limA3U(gteMAC3);\
+gte_RR0 = gteMAC1>>4;\
+gte_GG0 = gteMAC2>>4;\
+gte_BB0 = gteMAC3>>4;\
+gteCODE0 = gteCODE1; gteCODE1 = gteCODE2; gteCODE2 = gteCODE;\
+gteR0 = gteR1; gteR1 = gteR2; gteR2 = (unsigned char)limB1(gte_RR0);\
+gteG0 = gteG1; gteG1 = gteG2; gteG2 = (unsigned char)limB2(gte_GG0);\
+gteB0 = gteB1; gteB1 = gteB2; gteB2 = (unsigned char)limB3(gte_BB0);*/
+
+
+/*
+ gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f); \
+ gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f); \
+ gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f); \
+ gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3)); \
+ gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3)); \
+ gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3)); \
+ \
+ gteMAC1 = (long)(gteR*gte_RRLT*16); \
+ gteMAC2 = (long)(gteG*gte_GGLT*16); \
+ gteMAC3 = (long)(gteB*gte_BBLT*16); \
+*/
+#define GTE_NCCS(vn) \
+ gte_LL1 = F12limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn) >> 12); \
+ gte_LL2 = F12limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn) >> 12); \
+ gte_LL3 = F12limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn) >> 12); \
+ gte_RRLT= F12limA1U(gteRBK + ((gteLR1*gte_LL1 + gteLR2*gte_LL2 + gteLR3*gte_LL3) >> 12)); \
+ gte_GGLT= F12limA2U(gteGBK + ((gteLG1*gte_LL1 + gteLG2*gte_LL2 + gteLG3*gte_LL3) >> 12)); \
+ gte_BBLT= F12limA3U(gteBBK + ((gteLB1*gte_LL1 + gteLB2*gte_LL2 + gteLB3*gte_LL3) >> 12)); \
+ \
+ gteMAC1 = (long)(((s64)((u32)gteR<<12)*gte_RRLT) >> 20);\
+ gteMAC2 = (long)(((s64)((u32)gteG<<12)*gte_GGLT) >> 20);\
+ gteMAC3 = (long)(((s64)((u32)gteB<<12)*gte_BBLT) >> 20);
+
+
+void gteNCCS() {
+// double RR0,GG0,BB0;
+// double t1, t2, t3;
+// double gte_LL1, gte_LL2, gte_LL3;
+// double gte_RRLT, gte_GGLT, gte_BBLT;
+ s32 gte_LL1, gte_LL2, gte_LL3;
+ s32 gte_RRLT, gte_GGLT, gte_BBLT;
+
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCCS\n");
+#endif
+
+/*
+ gteFLAG = 0;
+
+ GTE_NCCS(0);
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCCS", 17);
+ G_SD(0);
+ G_SD(1);
+ G_SD(6);
+ G_SC(8);
+ G_SC(9);
+ G_SC(10);
+ G_SC(11);
+ G_SC(12);
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ }
+#endif
+
+ gteFLAG = 0;
+
+ GTE_NCCS(0);
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteR2 = FlimB1(gteMAC1>>4);
+ gteG2 = FlimB2(gteMAC2>>4);
+ gteB2 = FlimB3(gteMAC3>>4); gteCODE2 = gteCODE;
+
+ MAC2IR1();
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ //G_GD(24); Doc must be wrong. PSX does not touch it.
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteNCCT() {
+// double RR0,GG0,BB0;
+// double t1, t2, t3;
+// double gte_LL1, gte_LL2, gte_LL3;
+// double gte_RRLT, gte_GGLT, gte_BBLT;
+ s32 gte_LL1, gte_LL2, gte_LL3;
+ s32 gte_RRLT, gte_GGLT, gte_BBLT;
+
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCCT\n");
+#endif
+
+
+ /*gteFLAG = 0;
+
+ GTE_NCCS(0);
+ GTE_NCCS(1);
+ GTE_NCCS(2);
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCCT", 39);
+ G_SD(0);
+ G_SD(1);
+ G_SD(2);
+ G_SD(3);
+ G_SD(4);
+ G_SD(5);
+ G_SD(6);
+
+ G_SC(8);
+ G_SC(9);
+ G_SC(10);
+ G_SC(11);
+ G_SC(12);
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ }
+#endif
+
+ gteFLAG = 0;
+
+ GTE_NCCS(0);
+
+ gteR0 = FlimB1(gteMAC1>>4);
+ gteG0 = FlimB2(gteMAC2>>4);
+ gteB0 = FlimB3(gteMAC3>>4); gteCODE0 = gteCODE;
+
+ GTE_NCCS(1);
+
+ gteR1 = FlimB1(gteMAC1>>4);
+ gteG1 = FlimB2(gteMAC2>>4);
+ gteB1 = FlimB3(gteMAC3>>4); gteCODE1 = gteCODE;
+
+ GTE_NCCS(2);
+
+ gteR2 = FlimB1(gteMAC1>>4);
+ gteG2 = FlimB2(gteMAC2>>4);
+ gteB2 = FlimB3(gteMAC3>>4); gteCODE2 = gteCODE;
+
+ MAC2IR1();
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ G_GD(20);
+ G_GD(21);
+ G_GD(22);
+
+ //G_GD(24); Doc must be wrong. PSX does not touch it.
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+/*
+#define GTE_NCDS(vn) \
+gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\
+gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\
+gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\
+gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\
+gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\
+gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\
+gte_RR0 = (gteR*gte_RRLT) + (gteIR0/4096.0f * limA1S(gteRFC/16.0f - (gteR*gte_RRLT)));\
+gte_GG0 = (gteG*gte_GGLT) + (gteIR0/4096.0f * limA2S(gteGFC/16.0f - (gteG*gte_GGLT)));\
+gte_BB0 = (gteB*gte_BBLT) + (gteIR0/4096.0f * limA3S(gteBFC/16.0f - (gteB*gte_BBLT)));\
+gteMAC1= (long)(gte_RR0 * 16.0f); gteIR1 = (long)limA1U(gte_RR0*16.0f);\
+gteMAC2= (long)(gte_GG0 * 16.0f); gteIR2 = (long)limA2U(gte_GG0*16.0f);\
+gteMAC3= (long)(gte_BB0 * 16.0f); gteIR3 = (long)limA3U(gte_BB0*16.0f);\
+gteRGB0 = gteRGB1; \
+gteRGB1 = gteRGB2; \
+gteR2 = limB1(gte_RR0); \
+gteG2 = limB2(gte_GG0); \
+gteB2 = limB3(gte_BB0); gteCODE2 = gteCODE;
+*/
+/*
+#define GTE_NCDS(vn) \
+gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\
+gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\
+gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\
+gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\
+gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\
+gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\
+ \
+ gte_RR0 = (gteR*gte_RRLT) + (gteIR0/4096.0f * limA1S(gteRFC/16.0f - (gteR*gte_RRLT)));\
+ gte_GG0 = (gteG*gte_GGLT) + (gteIR0/4096.0f * limA2S(gteGFC/16.0f - (gteG*gte_GGLT)));\
+ gte_BB0 = (gteB*gte_BBLT) + (gteIR0/4096.0f * limA3S(gteBFC/16.0f - (gteB*gte_BBLT)));\
+ gteMAC1 = (long)(gte_RR0 << 4); \
+ gteMAC2 = (long)(gte_GG0 << 4); \
+ gteMAC3 = (long)(gte_BB0 << 4);
+*/
+#define GTE_NCDS(vn) \
+ gte_LL1 = F12limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn) >> 12); \
+ gte_LL2 = F12limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn) >> 12); \
+ gte_LL3 = F12limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn) >> 12); \
+ gte_RRLT= F12limA1U(gteRBK + ((gteLR1*gte_LL1 + gteLR2*gte_LL2 + gteLR3*gte_LL3) >> 12)); \
+ gte_GGLT= F12limA2U(gteGBK + ((gteLG1*gte_LL1 + gteLG2*gte_LL2 + gteLG3*gte_LL3) >> 12)); \
+ gte_BBLT= F12limA3U(gteBBK + ((gteLB1*gte_LL1 + gteLB2*gte_LL2 + gteLB3*gte_LL3) >> 12)); \
+ \
+ gte_RR0 = (long)(((s64)((u32)gteR<<12)*gte_RRLT) >> 12);\
+ gte_GG0 = (long)(((s64)((u32)gteG<<12)*gte_GGLT) >> 12);\
+ gte_BB0 = (long)(((s64)((u32)gteB<<12)*gte_BBLT) >> 12);\
+ gteMAC1 = (long)((gte_RR0 + (((s64)gteIR0 * F12limA1S((s64)(gteRFC << 8) - gte_RR0)) >> 12)) >> 8);\
+ gteMAC2 = (long)((gte_GG0 + (((s64)gteIR0 * F12limA2S((s64)(gteGFC << 8) - gte_GG0)) >> 12)) >> 8);\
+ gteMAC3 = (long)((gte_BB0 + (((s64)gteIR0 * F12limA3S((s64)(gteBFC << 8) - gte_BB0)) >> 12)) >> 8);
+
+void gteNCDS() {
+/* double tRLT,tRRLT;
+ double tGLT,tGGLT;
+ double tBLT,tBBLT;
+ double tRR0,tL1,tLL1;
+ double tGG0,tL2,tLL2;
+ double tBB0,tL3,tLL3;
+ unsigned long C,R,G,B; */
+// double gte_LL1, gte_LL2, gte_LL3;
+// double gte_RRLT, gte_GGLT, gte_BBLT;
+ s32 gte_LL1, gte_LL2, gte_LL3;
+ s32 gte_RRLT, gte_GGLT, gte_BBLT;
+ s32 gte_RR0, gte_GG0, gte_BB0;
+
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCDS\n");
+#endif
+
+/* gteFLAG = 0;
+
+ R = ((gteRGB)&0xff);
+ G = ((gteRGB>> 8)&0xff);
+ B = ((gteRGB>>16)&0xff);
+ C = ((gteRGB>>24)&0xff);
+
+ tLL1 = (gteL11/4096.0 * gteVX0/4096.0) + (gteL12/4096.0 * gteVY0/4096.0) + (gteL13/4096.0 * gteVZ0/4096.0);
+ tLL2 = (gteL21/4096.0 * gteVX0/4096.0) + (gteL22/4096.0 * gteVY0/4096.0) + (gteL23/4096.0 * gteVZ0/4096.0);
+ tLL3 = (gteL31/4096.0 * gteVX0/4096.0) + (gteL32/4096.0 * gteVY0/4096.0) + (gteL33/4096.0 * gteVZ0/4096.0);
+
+ tL1 = LimitAU(tLL1,24);
+ tL2 = LimitAU(tLL2,23);
+ tL3 = LimitAU(tLL3,22);
+
+ tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3);
+ tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3);
+ tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3);
+
+ tRLT = LimitAU(tRRLT,24);
+ tGLT = LimitAU(tGGLT,23);
+ tBLT = LimitAU(tBBLT,22);
+
+ tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24));
+ tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23));
+ tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22));
+
+ gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24);
+ gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23);
+ gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22);
+
+ R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0;
+ G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0;
+ B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0;
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteRGB2 = R|(G<<8)|(B<<16)|(C<<24);
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCDS", 19);
+ G_SD(0);
+ G_SD(1);
+ G_SD(6);
+ G_SD(8);
+
+ G_SC(8);
+ G_SC(9);
+ G_SC(10);
+ G_SC(11);
+ G_SC(12);
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+
+ gteFLAG = 0;
+ GTE_NCDS(0);
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ MAC2IR1();
+
+ SUM_FLAG;
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteNCDT() {
+ /*double tRLT,tRRLT;
+ double tGLT,tGGLT;
+ double tBLT,tBBLT;
+ double tRR0,tL1,tLL1;
+ double tGG0,tL2,tLL2;
+ double tBB0,tL3,tLL3;
+ unsigned long C,R,G,B;*/
+// double gte_LL1, gte_LL2, gte_LL3;
+// double gte_RRLT, gte_GGLT, gte_BBLT;
+ s32 gte_LL1, gte_LL2, gte_LL3;
+ s32 gte_RRLT, gte_GGLT, gte_BBLT;
+ s32 gte_RR0, gte_GG0, gte_BB0;
+
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCDT\n");
+#endif
+
+/* gteFLAG = 0;
+
+ R = ((gteRGB)&0xff);
+ G = ((gteRGB>> 8)&0xff);
+ B = ((gteRGB>>16)&0xff);
+ C = ((gteRGB>>24)&0xff);
+
+ tLL1 = (gteL11/4096.0 * gteVX0/4096.0) + (gteL12/4096.0 * gteVY0/4096.0) + (gteL13/4096.0 * gteVZ0/4096.0);
+ tLL2 = (gteL21/4096.0 * gteVX0/4096.0) + (gteL22/4096.0 * gteVY0/4096.0) + (gteL23/4096.0 * gteVZ0/4096.0);
+ tLL3 = (gteL31/4096.0 * gteVX0/4096.0) + (gteL32/4096.0 * gteVY0/4096.0) + (gteL33/4096.0 * gteVZ0/4096.0);
+
+ tL1 = LimitAU(tLL1,24);
+ tL2 = LimitAU(tLL2,23);
+ tL3 = LimitAU(tLL3,22);
+
+ tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3);
+ tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3);
+ tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3);
+
+ tRLT = LimitAU(tRRLT,24);
+ tGLT = LimitAU(tGGLT,23);
+ tBLT = LimitAU(tBBLT,22);
+
+ tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24));
+ tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23));
+ tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22));
+
+ gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24);
+ gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23);
+ gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22);
+
+ R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0;
+ G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0;
+ B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0;
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteRGB2 = R|(G<<8)|(B<<16)|(C<<24);
+
+ R = ((gteRGB)&0xff);
+ G = ((gteRGB>> 8)&0xff);
+ B = ((gteRGB>>16)&0xff);
+ C = ((gteRGB>>24)&0xff);
+
+ tLL1 = (gteL11/4096.0 * gteVX1/4096.0) + (gteL12/4096.0 * gteVY1/4096.0) + (gteL13/4096.0 * gteVZ1/4096.0);
+ tLL2 = (gteL21/4096.0 * gteVX1/4096.0) + (gteL22/4096.0 * gteVY1/4096.0) + (gteL23/4096.0 * gteVZ1/4096.0);
+ tLL3 = (gteL31/4096.0 * gteVX1/4096.0) + (gteL32/4096.0 * gteVY1/4096.0) + (gteL33/4096.0 * gteVZ1/4096.0);
+
+ tL1 = LimitAU(tLL1,24);
+ tL2 = LimitAU(tLL2,23);
+ tL3 = LimitAU(tLL3,22);
+
+ tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3);
+ tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3);
+ tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3);
+
+ tRLT = LimitAU(tRRLT,24);
+ tGLT = LimitAU(tGGLT,23);
+ tBLT = LimitAU(tBBLT,22);
+
+ tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24));
+ tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23));
+ tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22));
+
+ gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24);
+ gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23);
+ gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22);
+
+ R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0;
+ G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0;
+ B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0;
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteRGB2 = R|(G<<8)|(B<<16)|(C<<24);
+
+ R = ((gteRGB)&0xff);
+ G = ((gteRGB>> 8)&0xff);
+ B = ((gteRGB>>16)&0xff);
+ C = ((gteRGB>>24)&0xff);
+
+ tLL1 = (gteL11/4096.0 * gteVX2/4096.0) + (gteL12/4096.0 * gteVY2/4096.0) + (gteL13/4096.0 * gteVZ2/4096.0);
+ tLL2 = (gteL21/4096.0 * gteVX2/4096.0) + (gteL22/4096.0 * gteVY2/4096.0) + (gteL23/4096.0 * gteVZ2/4096.0);
+ tLL3 = (gteL31/4096.0 * gteVX2/4096.0) + (gteL32/4096.0 * gteVY2/4096.0) + (gteL33/4096.0 * gteVZ2/4096.0);
+
+ tL1 = LimitAU(tLL1,24);
+ tL2 = LimitAU(tLL2,23);
+ tL3 = LimitAU(tLL3,22);
+
+ tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3);
+ tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3);
+ tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3);
+
+ tRLT = LimitAU(tRRLT,24);
+ tGLT = LimitAU(tGGLT,23);
+ tBLT = LimitAU(tBBLT,22);
+
+ tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24));
+ tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23));
+ tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22));
+
+ gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24);
+ gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23);
+ gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22);
+
+ R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0;
+ G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0;
+ B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0;
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteRGB2 = R|(G<<8)|(B<<16)|(C<<24);
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCDT", 44);
+ G_SD(0);
+ G_SD(1);
+ G_SD(2);
+ G_SD(3);
+ G_SD(4);
+ G_SD(5);
+ G_SD(6);
+ G_SD(8);
+
+ G_SC(8);
+ G_SC(9);
+ G_SC(10);
+ G_SC(11);
+ G_SC(12);
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+
+ gteFLAG = 0;
+ GTE_NCDS(0);
+
+ gteR0 = FlimB1(gteMAC1 >> 4);
+ gteG0 = FlimB2(gteMAC2 >> 4);
+ gteB0 = FlimB3(gteMAC3 >> 4); gteCODE0 = gteCODE;
+
+ GTE_NCDS(1);
+
+ gteR1 = FlimB1(gteMAC1 >> 4);
+ gteG1 = FlimB2(gteMAC2 >> 4);
+ gteB1 = FlimB3(gteMAC3 >> 4); gteCODE1 = gteCODE;
+
+ GTE_NCDS(2);
+
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ MAC2IR1();
+
+ SUM_FLAG;
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ G_GD(20);
+ G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+#define gteD1 (*(short *)&gteR11)
+#define gteD2 (*(short *)&gteR22)
+#define gteD3 (*(short *)&gteR33)
+
+void gteOP() {
+// double SSX0=0,SSY0=0,SSZ0=0;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_OP %lx\n", psxRegs.code & 0x1ffffff);
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("OP", 6);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+
+ G_SC(0);
+ G_SC(2);
+ G_SC(4);
+ }
+#endif
+/* gteFLAG=0;
+
+ switch (psxRegs.code & 0x1ffffff) {
+ case 0x178000C://op12
+ SSX0 = EDETEC1((gteR22*(short)gteIR3 - gteR33*(short)gteIR2)/(double)4096);
+ SSY0 = EDETEC2((gteR33*(short)gteIR1 - gteR11*(short)gteIR3)/(double)4096);
+ SSZ0 = EDETEC3((gteR11*(short)gteIR2 - gteR22*(short)gteIR1)/(double)4096);
+ break;
+ case 0x170000C:
+ SSX0 = EDETEC1((gteR22*(short)gteIR3 - gteR33*(short)gteIR2));
+ SSY0 = EDETEC2((gteR33*(short)gteIR1 - gteR11*(short)gteIR3));
+ SSZ0 = EDETEC3((gteR11*(short)gteIR2 - gteR22*(short)gteIR1));
+ break;
+ }
+
+ gteMAC1 = (long)float2int(SSX0);
+ gteMAC2 = (long)float2int(SSY0);
+ gteMAC3 = (long)float2int(SSZ0);
+
+ MAC2IR();
+
+ if (gteIR1<0) gteIR1=0;
+ if (gteIR2<0) gteIR2=0;
+ if (gteIR3<0) gteIR3=0;
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+/* if (psxRegs.code & 0x80000) {
+
+ gteMAC1 = NC_OVERFLOW1((gteD2 * gteIR3 - gteD3 * gteIR2) / 4096.0f);
+ gteMAC2 = NC_OVERFLOW2((gteD3 * gteIR1 - gteD1 * gteIR3) / 4096.0f);
+ gteMAC3 = NC_OVERFLOW3((gteD1 * gteIR2 - gteD2 * gteIR1) / 4096.0f);
+ } else {
+
+ gteMAC1 = NC_OVERFLOW1(gteD2 * gteIR3 - gteD3 * gteIR2);
+ gteMAC2 = NC_OVERFLOW2(gteD3 * gteIR1 - gteD1 * gteIR3);
+ gteMAC3 = NC_OVERFLOW3(gteD1 * gteIR2 - gteD2 * gteIR1);
+ }*/
+ if (psxRegs.code & 0x80000) {
+ gteMAC1 = FNC_OVERFLOW1((gteD2 * gteIR3 - gteD3 * gteIR2) >> 12);
+ gteMAC2 = FNC_OVERFLOW2((gteD3 * gteIR1 - gteD1 * gteIR3) >> 12);
+ gteMAC3 = FNC_OVERFLOW3((gteD1 * gteIR2 - gteD2 * gteIR1) >> 12);
+ } else {
+ gteMAC1 = FNC_OVERFLOW1(gteD2 * gteIR3 - gteD3 * gteIR2);
+ gteMAC2 = FNC_OVERFLOW2(gteD3 * gteIR1 - gteD1 * gteIR3);
+ gteMAC3 = FNC_OVERFLOW3(gteD1 * gteIR2 - gteD2 * gteIR1);
+ }
+
+ /* NC: old
+ MAC2IR1();
+ */
+ MAC2IR();
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteDCPL() {
+// unsigned long C,R,G,B;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_DCPL\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("DCPL", 8);
+ G_SD(6);
+ G_SD(8);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+/* R = ((gteRGB)&0xff);
+ G = ((gteRGB>> 8)&0xff);
+ B = ((gteRGB>>16)&0xff);
+ C = ((gteRGB>>24)&0xff);
+
+ gteMAC1 = (signed long)((double)(R*gteIR1) + (double)(gteIR0*LimitAS(gteRFC-(double)(R*gteIR1),24))/4096.0);
+ gteMAC2 = (signed long)((double)(G*gteIR2) + (double)(gteIR0*LimitAS(gteGFC-(double)(G*gteIR2),23))/4096.0);
+ gteMAC3 = (signed long)((double)(B*gteIR3) + (double)(gteIR0*LimitAS(gteBFC-(double)(B*gteIR3),22))/4096.0);
+
+ MAC2IR()
+
+ R = (unsigned long)LimitB(gteMAC1,21); if (R>255) R=255; else if (R<0) R=0;
+ G = (unsigned long)LimitB(gteMAC2,20); if (G>255) G=255; else if (G<0) G=0;
+ B = (unsigned long)LimitB(gteMAC3,19); if (B>255) B=255; else if (B<0) B=0;
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteRGB2 = R|(G<<8)|(B<<16)|(C<<24);
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+
+/* gteFLAG = 0;
+
+ gteMAC1 = NC_OVERFLOW1((gteR * gteIR1) / 256.0f + (gteIR0 * limA1S(gteRFC - ((gteR * gteIR1) / 256.0f))) / 4096.0f);
+ gteMAC2 = NC_OVERFLOW2((gteG * gteIR1) / 256.0f + (gteIR0 * limA2S(gteGFC - ((gteG * gteIR1) / 256.0f))) / 4096.0f);
+ gteMAC3 = NC_OVERFLOW3((gteB * gteIR1) / 256.0f + (gteIR0 * limA3S(gteBFC - ((gteB * gteIR1) / 256.0f))) / 4096.0f);
+ */
+/* gteMAC1 = ( (signed long)(gteR)*gteIR1 + (gteIR0*(signed short)limA1S(gteRFC - ((gteR*gteIR1)>>12) )) ) >>6;
+ gteMAC2 = ( (signed long)(gteG)*gteIR2 + (gteIR0*(signed short)limA2S(gteGFC - ((gteG*gteIR2)>>12) )) ) >>6;
+ gteMAC3 = ( (signed long)(gteB)*gteIR3 + (gteIR0*(signed short)limA3S(gteBFC - ((gteB*gteIR3)>>12) )) ) >>6;*/
+
+/* gteMAC1 = ( (signed long)(gteR)*gteIR1 + (gteIR0*(signed short)limA1S(gteRFC - ((gteR*gteIR1)>>12) )) ) >>8;
+ gteMAC2 = ( (signed long)(gteG)*gteIR2 + (gteIR0*(signed short)limA2S(gteGFC - ((gteG*gteIR2)>>12) )) ) >>8;
+ gteMAC3 = ( (signed long)(gteB)*gteIR3 + (gteIR0*(signed short)limA3S(gteBFC - ((gteB*gteIR3)>>12) )) ) >>8;*/
+ gteMAC1 = ( (signed long)(gteR)*gteIR1 + (gteIR0*(signed short)FlimA1S(gteRFC - ((gteR*gteIR1)>>12) )) ) >>8;
+ gteMAC2 = ( (signed long)(gteG)*gteIR2 + (gteIR0*(signed short)FlimA2S(gteGFC - ((gteG*gteIR2)>>12) )) ) >>8;
+ gteMAC3 = ( (signed long)(gteB)*gteIR3 + (gteIR0*(signed short)FlimA3S(gteBFC - ((gteB*gteIR3)>>12) )) ) >>8;
+
+ gteFLAG=0;
+ MAC2IR();
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteGPF() {
+// double ipx, ipy, ipz;
+// s32 ipx, ipy, ipz;
+
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_GPF %lx\n", psxRegs.code & 0x1ffffff);
+#endif
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("GPF", 5);
+ G_SD(6);
+ G_SD(8);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+ }
+#endif
+/* gteFLAG = 0;
+
+ ipx = (double)((short)gteIR0) * ((short)gteIR1);
+ ipy = (double)((short)gteIR0) * ((short)gteIR2);
+ ipz = (double)((short)gteIR0) * ((short)gteIR3);
+
+ // same as mvmva
+ if (psxRegs.code & 0x80000) {
+ ipx /= 4096.0; ipy /= 4096.0; ipz /= 4096.0;
+ }
+
+ gteMAC1 = (long)ipx;
+ gteMAC2 = (long)ipy;
+ gteMAC3 = (long)ipz;
+
+ gteIR1 = (long)LimitAS(ipx,24);
+ gteIR2 = (long)LimitAS(ipy,23);
+ gteIR3 = (long)LimitAS(ipz,22);
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteC2 = gteCODE;
+ gteR2 = (unsigned char)LimitB(ipx,21);
+ gteG2 = (unsigned char)LimitB(ipy,20);
+ gteB2 = (unsigned char)LimitB(ipz,19);*/
+
+ gteFLAG = 0;
+
+/* if (psxRegs.code & 0x80000) {
+ gteMAC1 = NC_OVERFLOW1((gteIR0 * gteIR1) / 4096.0f);
+ gteMAC2 = NC_OVERFLOW2((gteIR0 * gteIR2) / 4096.0f);
+ gteMAC3 = NC_OVERFLOW3((gteIR0 * gteIR3) / 4096.0f);
+ } else {
+ gteMAC1 = NC_OVERFLOW1(gteIR0 * gteIR1);
+ gteMAC2 = NC_OVERFLOW2(gteIR0 * gteIR2);
+ gteMAC3 = NC_OVERFLOW3(gteIR0 * gteIR3);
+ }*/
+ if (psxRegs.code & 0x80000) {
+ gteMAC1 = FNC_OVERFLOW1((gteIR0 * gteIR1) >> 12);
+ gteMAC2 = FNC_OVERFLOW2((gteIR0 * gteIR2) >> 12);
+ gteMAC3 = FNC_OVERFLOW3((gteIR0 * gteIR3) >> 12);
+ } else {
+ gteMAC1 = FNC_OVERFLOW1(gteIR0 * gteIR1);
+ gteMAC2 = FNC_OVERFLOW2(gteIR0 * gteIR2);
+ gteMAC3 = FNC_OVERFLOW3(gteIR0 * gteIR3);
+ }
+ MAC2IR();
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteGPL() {
+ // double IPX=0,IPY=0,IPZ=0;
+// unsigned long C,R,G,B;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_GPL %lx\n", psxRegs.code & 0x1ffffff);
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("GPL", 5);
+ G_SD(6);
+ G_SD(8);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+
+ G_SD(25);
+ G_SD(26);
+ G_SD(27);
+ }
+#endif
+
+/* gteFLAG=0;
+ switch(psxRegs.code & 0x1ffffff) {
+ case 0x1A8003E:
+ IPX = EDETEC1((double)gteMAC1 + ((double)gteIR0*(double)gteIR1)/4096.0f);
+ IPY = EDETEC2((double)gteMAC2 + ((double)gteIR0*(double)gteIR2)/4096.0f);
+ IPZ = EDETEC3((double)gteMAC3 + ((double)gteIR0*(double)gteIR3)/4096.0f);
+ break;
+
+ case 0x1A0003E:
+ IPX = EDETEC1((double)gteMAC1 + ((double)gteIR0*(double)gteIR1));
+ IPY = EDETEC2((double)gteMAC2 + ((double)gteIR0*(double)gteIR2));
+ IPZ = EDETEC3((double)gteMAC3 + ((double)gteIR0*(double)gteIR3));
+ break;
+ }
+ gteIR1 = (short)float2int(LimitAS(IPX,24));
+ gteIR2 = (short)float2int(LimitAS(IPY,23));
+ gteIR3 = (short)float2int(LimitAS(IPZ,22));
+
+ gteMAC1 = (int)float2int(IPX);
+ gteMAC2 = (int)float2int(IPY);
+ gteMAC3 = (int)float2int(IPZ);
+
+ C = gteRGB & 0xff000000;
+ R = float2int(ALIMIT(IPX,0,255));
+ G = float2int(ALIMIT(IPY,0,255));
+ B = float2int(ALIMIT(IPZ,0,255));
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteRGB2 = C|R|(G<<8)|(B<<16);*/
+ gteFLAG = 0;
+
+/* if (psxRegs.code & 0x80000) {
+ gteMAC1 = NC_OVERFLOW1(gteMAC1 + (gteIR0 * gteIR1) / 4096.0f);
+ gteMAC2 = NC_OVERFLOW2(gteMAC2 + (gteIR0 * gteIR2) / 4096.0f);
+ gteMAC3 = NC_OVERFLOW3(gteMAC3 + (gteIR0 * gteIR3) / 4096.0f);
+ } else {
+ gteMAC1 = NC_OVERFLOW1(gteMAC1 + (gteIR0 * gteIR1));
+ gteMAC2 = NC_OVERFLOW2(gteMAC2 + (gteIR0 * gteIR2));
+ gteMAC3 = NC_OVERFLOW3(gteMAC3 + (gteIR0 * gteIR3));
+ }*/
+ if (psxRegs.code & 0x80000) {
+ gteMAC1 = FNC_OVERFLOW1(gteMAC1 + ((gteIR0 * gteIR1) >> 12));
+ gteMAC2 = FNC_OVERFLOW2(gteMAC2 + ((gteIR0 * gteIR2) >> 12));
+ gteMAC3 = FNC_OVERFLOW3(gteMAC3 + ((gteIR0 * gteIR3) >> 12));
+ } else {
+ gteMAC1 = FNC_OVERFLOW1(gteMAC1 + (gteIR0 * gteIR1));
+ gteMAC2 = FNC_OVERFLOW2(gteMAC2 + (gteIR0 * gteIR2));
+ gteMAC3 = FNC_OVERFLOW3(gteMAC3 + (gteIR0 * gteIR3));
+ }
+ MAC2IR();
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+/*
+#define GTE_DPCS() { \
+ RR0 = (double)R + (gteIR0*LimitAS((double)(gteRFC - R),24))/4096.0; \
+ GG0 = (double)G + (gteIR0*LimitAS((double)(gteGFC - G),23))/4096.0; \
+ BB0 = (double)B + (gteIR0*LimitAS((double)(gteBFC - B),22))/4096.0; \
+ \
+ gteIR1 = (long)LimitAS(RR0,24); \
+ gteIR2 = (long)LimitAS(GG0,23); \
+ gteIR3 = (long)LimitAS(BB0,22); \
+ \
+ gteRGB0 = gteRGB1; \
+ gteRGB1 = gteRGB2; \
+ gteC2 = C; \
+ gteR2 = (unsigned char)LimitB(RR0/16.0,21); \
+ gteG2 = (unsigned char)LimitB(GG0/16.0,20); \
+ gteB2 = (unsigned char)LimitB(BB0/16.0,19); \
+ \
+ gteMAC1 = (long)RR0; \
+ gteMAC2 = (long)GG0; \
+ gteMAC3 = (long)BB0; \
+}
+*/
+void gteDPCS() {
+// unsigned long C,R,G,B;
+// double RR0,GG0,BB0;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_DPCS\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("DPCS", 8);
+ G_SD(6);
+ G_SD(8);
+
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+
+/* gteFLAG = 0;
+
+ C = gteCODE;
+ R = gteR * 16.0;
+ G = gteG * 16.0;
+ B = gteB * 16.0;
+
+ GTE_DPCS();
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+/* gteFLAG = 0;
+
+ gteMAC1 = NC_OVERFLOW1((gteR * 16.0f) + (gteIR0 * limA1S(gteRFC - (gteR * 16.0f))) / 4096.0f);
+ gteMAC2 = NC_OVERFLOW2((gteG * 16.0f) + (gteIR0 * limA2S(gteGFC - (gteG * 16.0f))) / 4096.0f);
+ gteMAC3 = NC_OVERFLOW3((gteB * 16.0f) + (gteIR0 * limA3S(gteBFC - (gteB * 16.0f))) / 4096.0f);
+ */
+/* gteMAC1 = (gteR<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR<<4)) ) >>12);
+ gteMAC2 = (gteG<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG<<4)) ) >>12);
+ gteMAC3 = (gteB<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB<<4)) ) >>12);*/
+ gteMAC1 = (gteR<<4) + ( (gteIR0*(signed short)FlimA1S(gteRFC-(gteR<<4)) ) >>12);
+ gteMAC2 = (gteG<<4) + ( (gteIR0*(signed short)FlimA2S(gteGFC-(gteG<<4)) ) >>12);
+ gteMAC3 = (gteB<<4) + ( (gteIR0*(signed short)FlimA3S(gteBFC-(gteB<<4)) ) >>12);
+
+ gteFLAG = 0;
+ MAC2IR();
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteDPCT() {
+// unsigned long C,R,G,B;
+// double RR0,GG0,BB0;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_DPCT\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("DPCT", 17);
+ G_SD(8);
+
+ G_SD(20);
+ G_SD(21);
+ G_SD(22);
+
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+/* gteFLAG = 0;
+
+ C = gteCODE0;
+ R = gteR0 * 16.0;
+ G = gteG0 * 16.0;
+ B = gteB0 * 16.0;
+
+ GTE_DPCS();
+
+ C = gteCODE0;
+ R = gteR0 * 16.0;
+ G = gteG0 * 16.0;
+ B = gteB0 * 16.0;
+
+ GTE_DPCS();
+
+ C = gteCODE0;
+ R = gteR0 * 16.0;
+ G = gteG0 * 16.0;
+ B = gteB0 * 16.0;
+
+ GTE_DPCS();
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+/* gteFLAG = 0;
+
+ gteMAC1 = NC_OVERFLOW1((gteR0 * 16.0f) + gteIR0 * limA1S(gteRFC - (gteR0 * 16.0f)));
+ gteMAC2 = NC_OVERFLOW2((gteG0 * 16.0f) + gteIR0 * limA2S(gteGFC - (gteG0 * 16.0f)));
+ gteMAC3 = NC_OVERFLOW3((gteB0 * 16.0f) + gteIR0 * limA3S(gteBFC - (gteB0 * 16.0f)));
+ */
+/* gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR0<<4)) ) >>12);
+ gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG0<<4)) ) >>12);
+ gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB0<<4)) ) >>12);*/
+ gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)FlimA1S(gteRFC-(gteR0<<4)) ) >>12);
+ gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)FlimA2S(gteGFC-(gteG0<<4)) ) >>12);
+ gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)FlimA3S(gteBFC-(gteB0<<4)) ) >>12);
+// MAC2IR();
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+/* gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR0<<4)) ) >>12);
+ gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG0<<4)) ) >>12);
+ gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB0<<4)) ) >>12);*/
+ gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)FlimA1S(gteRFC-(gteR0<<4)) ) >>12);
+ gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)FlimA2S(gteGFC-(gteG0<<4)) ) >>12);
+ gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)FlimA3S(gteBFC-(gteB0<<4)) ) >>12);
+// MAC2IR();
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+/* gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR0<<4)) ) >>12);
+ gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG0<<4)) ) >>12);
+ gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB0<<4)) ) >>12);*/
+ gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)FlimA1S(gteRFC-(gteR0<<4)) ) >>12);
+ gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)FlimA2S(gteGFC-(gteG0<<4)) ) >>12);
+ gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)FlimA3S(gteBFC-(gteB0<<4)) ) >>12);
+ gteFLAG = 0;
+ MAC2IR();
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ G_GD(20);
+ G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+/*
+#define GTE_NCS(vn) { \
+ RR0 = ((double)gteVX##vn * gteL11 + (double)gteVY##vn * (double)gteL12 + (double)gteVZ##vn * gteL13) / 4096.0; \
+ GG0 = ((double)gteVX##vn * gteL21 + (double)gteVY##vn * (double)gteL22 + (double)gteVZ##vn * gteL23) / 4096.0; \
+ BB0 = ((double)gteVX##vn * gteL31 + (double)gteVY##vn * (double)gteL32 + (double)gteVZ##vn * gteL33) / 4096.0; \
+ t1 = LimitAU(RR0, 24); \
+ t2 = LimitAU(GG0, 23); \
+ t3 = LimitAU(BB0, 22); \
+ \
+ RR0 = (double)gteRBK + ((double)gteLR1 * t1 + (double)gteLR2 * t2 + (double)gteLR3 * t3) / 4096.0; \
+ GG0 = (double)gteGBK + ((double)gteLG1 * t1 + (double)gteLG2 * t2 + (double)gteLG3 * t3) / 4096.0; \
+ BB0 = (double)gteBBK + ((double)gteLB1 * t1 + (double)gteLB2 * t2 + (double)gteLB3 * t3) / 4096.0; \
+ t1 = LimitAU(RR0, 24); \
+ t2 = LimitAU(GG0, 23); \
+ t3 = LimitAU(BB0, 22); \
+ \
+ gteRGB0 = gteRGB1; gteRGB1 = gteRGB2; \
+ gteR2 = (unsigned char)LimitB(RR0/16.0, 21); \
+ gteG2 = (unsigned char)LimitB(GG0/16.0, 20); \
+ gteB2 = (unsigned char)LimitB(BB0/16.0, 19); \
+ gteCODE2=gteCODE0; \
+}*/
+
+#define LOW(a) (((a) < 0) ? 0 : (a))
+/*
+#define GTE_NCS(vn) \
+RR0 = LOW((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/4096.0f); \
+GG0 = LOW((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/4096.0f); \
+BB0 = LOW((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/4096.0f); \
+gteMAC1 = gteRBK + (gteLR1*RR0 + gteLR2*GG0 + gteLR3*BB0)/4096.0f; \
+gteMAC2 = gteGBK + (gteLG1*RR0 + gteLG2*GG0 + gteLG3*BB0)/4096.0f; \
+gteMAC3 = gteBBK + (gteLB1*RR0 + gteLB2*GG0 + gteLB3*BB0)/4096.0f; \
+gteRGB0 = gteRGB1; \
+gteRGB1 = gteRGB2; \
+gteR2 = FlimB1(gteMAC1 >> 4); \
+gteG2 = FlimB2(gteMAC2 >> 4); \
+gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;*/
+/*gteR2 = limB1(gteMAC1 / 16.0f); \
+gteG2 = limB2(gteMAC2 / 16.0f); \
+gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+
+#define GTE_NCS(vn) \
+ gte_LL1 = F12limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn) >> 12); \
+ gte_LL2 = F12limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn) >> 12); \
+ gte_LL3 = F12limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn) >> 12); \
+ gteMAC1 = F12limA1U(gteRBK + ((gteLR1*gte_LL1 + gteLR2*gte_LL2 + gteLR3*gte_LL3) >> 12)); \
+ gteMAC2 = F12limA2U(gteGBK + ((gteLG1*gte_LL1 + gteLG2*gte_LL2 + gteLG3*gte_LL3) >> 12)); \
+ gteMAC3 = F12limA3U(gteBBK + ((gteLB1*gte_LL1 + gteLB2*gte_LL2 + gteLB3*gte_LL3) >> 12));
+
+void gteNCS() {
+// double RR0,GG0,BB0;
+ s32 gte_LL1,gte_LL2,gte_LL3;
+// s32 RR0,GG0,BB0;
+// double t1, t2, t3;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCS\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCS", 14);
+ G_SD(0);
+ G_SD(1);
+ G_SD(6);
+
+ G_SC(8);
+ G_SC(9);
+ G_SC(10);
+ G_SC(11);
+ G_SC(12);
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ }
+#endif
+/* gteFLAG = 0;
+
+ GTE_NCS(0);
+
+ gteMAC1=(long)RR0;
+ gteMAC2=(long)GG0;
+ gteMAC3=(long)BB0;
+
+ gteIR1=(long)t1;
+ gteIR2=(long)t2;
+ gteIR3=(long)t3;
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+ GTE_NCS(0);
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ MAC2IR1();
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteNCT() {
+// double RR0,GG0,BB0;
+ s32 gte_LL1,gte_LL2,gte_LL3;
+// s32 RR0,GG0,BB0;
+// double t1, t2, t3;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_NCT\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("NCT", 30);
+ G_SD(0);
+ G_SD(1);
+ G_SD(2);
+ G_SD(3);
+ G_SD(4);
+ G_SD(5);
+ G_SD(6);
+
+ G_SC(8);
+ G_SC(9);
+ G_SC(10);
+ G_SC(11);
+ G_SC(12);
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ }
+#endif
+/*
+ gteFLAG = 0;
+
+//V0
+ GTE_NCS(0);
+//V1
+ GTE_NCS(1);
+//V2
+ GTE_NCS(2);
+
+ gteMAC1=(long)RR0;
+ gteMAC2=(long)GG0;
+ gteMAC3=(long)BB0;
+
+ gteIR1=(long)t1;
+ gteIR2=(long)t2;
+ gteIR3=(long)t3;
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+ GTE_NCS(0);
+
+ gteR0 = FlimB1(gteMAC1 >> 4);
+ gteG0 = FlimB2(gteMAC2 >> 4);
+ gteB0 = FlimB3(gteMAC3 >> 4); gteCODE0 = gteCODE;
+
+ GTE_NCS(1);
+ gteR1 = FlimB1(gteMAC1 >> 4);
+ gteG1 = FlimB2(gteMAC2 >> 4);
+ gteB1 = FlimB3(gteMAC3 >> 4); gteCODE1 = gteCODE;
+
+ GTE_NCS(2);
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ MAC2IR1();
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ G_GD(20);
+ G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteCC() {
+// double RR0,GG0,BB0;
+ s32 RR0,GG0,BB0;
+// double t1,t2,t3;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_CC\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("CC", 11);
+ G_SD(6);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ }
+#endif
+/* gteFLAG = 0;
+
+ RR0 = (double)gteRBK + ((double)gteLR1 * gteIR1 + (double)gteLR2 * gteIR2 + (double)gteLR3 * gteIR3) / 4096.0;
+ GG0 = (double)gteGBK + ((double)gteLG1 * gteIR1 + (double)gteLG2 * gteIR2 + (double)gteLG3 * gteIR3) / 4096.0;
+ BB0 = (double)gteBBK + ((double)gteLB1 * gteIR1 + (double)gteLB2 * gteIR2 + (double)gteLB3 * gteIR3) / 4096.0;
+ t1 = LimitAU(RR0, 24);
+ t2 = LimitAU(GG0, 23);
+ t3 = LimitAU(BB0, 22);
+
+ RR0=((double)gteR * t1)/256.0;
+ GG0=((double)gteG * t2)/256.0;
+ BB0=((double)gteB * t3)/256.0;
+ gteIR1 = (long)LimitAU(RR0,24);
+ gteIR2 = (long)LimitAU(GG0,23);
+ gteIR3 = (long)LimitAU(BB0,22);
+
+ gteCODE0=gteCODE1; gteCODE1=gteCODE2;
+ gteC2 = gteCODE0;
+ gteR2 = (unsigned char)LimitB(RR0/16.0, 21);
+ gteG2 = (unsigned char)LimitB(GG0/16.0, 20);
+ gteB2 = (unsigned char)LimitB(BB0/16.0, 19);
+
+ if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/
+ gteFLAG = 0;
+
+/* RR0 = NC_OVERFLOW1(gteRBK + (gteLR1*gteIR1 + gteLR2*gteIR2 + gteLR3*gteIR3) / 4096.0f);
+ GG0 = NC_OVERFLOW2(gteGBK + (gteLG1*gteIR1 + gteLG2*gteIR2 + gteLG3*gteIR3) / 4096.0f);
+ BB0 = NC_OVERFLOW3(gteBBK + (gteLB1*gteIR1 + gteLB2*gteIR2 + gteLB3*gteIR3) / 4096.0f);
+
+ gteMAC1 = gteR * RR0 / 256.0f;
+ gteMAC2 = gteG * GG0 / 256.0f;
+ gteMAC3 = gteB * BB0 / 256.0f;*/
+ RR0 = FNC_OVERFLOW1(gteRBK + ((gteLR1*gteIR1 + gteLR2*gteIR2 + gteLR3*gteIR3) >> 12));
+ GG0 = FNC_OVERFLOW2(gteGBK + ((gteLG1*gteIR1 + gteLG2*gteIR2 + gteLG3*gteIR3) >> 12));
+ BB0 = FNC_OVERFLOW3(gteBBK + ((gteLB1*gteIR1 + gteLB2*gteIR2 + gteLB3*gteIR3) >> 12));
+
+ gteMAC1 = (gteR * RR0) >> 8;
+ gteMAC2 = (gteG * GG0) >> 8;
+ gteMAC3 = (gteB * BB0) >> 8;
+
+ MAC2IR1();
+
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteINTPL() { //test opcode
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+#ifdef GTE_LOG
+ GTE_LOG("GTE_INTP\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("INTPL", 8);
+ G_SD(6);
+ G_SD(8);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+ /* NC: old
+ gteFLAG=0;
+ gteMAC1 = gteIR1 + gteIR0*limA1S(gteRFC-gteIR1);
+ gteMAC2 = gteIR2 + gteIR0*limA2S(gteGFC-gteIR2);
+ gteMAC3 = gteIR3 + gteIR0*limA3S(gteBFC-gteIR3);
+ //gteFLAG = 0;
+ MAC2IR();
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+ gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;
+ */
+
+/* gteFLAG=0;
+ gteMAC1 = gteIR1 + gteIR0*(gteRFC-gteIR1)/4096.0;
+ gteMAC2 = gteIR2 + gteIR0*(gteGFC-gteIR2)/4096.0;
+ gteMAC3 = gteIR3 + gteIR0*(gteBFC-gteIR3)/4096.0;
+
+ //gteMAC3 = (int)((((psxRegs).CP2D).n).ir3+(((psxRegs).CP2D).n).ir0 * ((((psxRegs).CP2C).n).bfc-(((psxRegs).CP2D).n).ir3)/4096.0);
+
+ if(gteMAC3 > gteIR1 && gteMAC3 > gteBFC)
+ {
+ gteMAC3 = gteMAC3;
+ }
+ //gteFLAG = 0;*/
+ //NEW CODE
+/* gteMAC1 = gteIR1 + ((gteIR0*(signed short)limA1S(gteRFC-gteIR1))>>12);
+ gteMAC2 = gteIR2 + ((gteIR0*(signed short)limA2S(gteGFC-gteIR2))>>12);
+ gteMAC3 = gteIR3 + ((gteIR0*(signed short)limA3S(gteBFC-gteIR3))>>12);*/
+ gteMAC1 = gteIR1 + ((gteIR0*(signed short)FlimA1S(gteRFC-gteIR1))>>12);
+ gteMAC2 = gteIR2 + ((gteIR0*(signed short)FlimA2S(gteGFC-gteIR2))>>12);
+ gteMAC3 = gteIR3 + ((gteIR0*(signed short)FlimA3S(gteBFC-gteIR3))>>12);
+ gteFLAG = 0;
+
+ MAC2IR();
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
+
+void gteCDP() { //test opcode
+ double RR0,GG0,BB0;
+// s32 RR0,GG0,BB0;
+#ifdef GTE_DUMP
+ static int sample = 0; sample++;
+#endif
+
+#ifdef GTE_LOG
+ GTE_LOG("GTE_CDP\n");
+#endif
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_OP("CDP", 13);
+ G_SD(6);
+ G_SD(8);
+ G_SD(9);
+ G_SD(10);
+ G_SD(11);
+
+ G_SC(13);
+ G_SC(14);
+ G_SC(15);
+ G_SC(16);
+ G_SC(17);
+ G_SC(18);
+ G_SC(19);
+ G_SC(20);
+ G_SC(21);
+ G_SC(22);
+ G_SC(23);
+ }
+#endif
+
+ gteFLAG = 0;
+
+ RR0 = NC_OVERFLOW1(gteRBK + (gteLR1*gteIR1 +gteLR2*gteIR2 + gteLR3*gteIR3));
+ GG0 = NC_OVERFLOW2(gteGBK + (gteLG1*gteIR1 +gteLG2*gteIR2 + gteLG3*gteIR3));
+ BB0 = NC_OVERFLOW3(gteBBK + (gteLB1*gteIR1 +gteLB2*gteIR2 + gteLB3*gteIR3));
+ gteMAC1 = gteR*RR0 + gteIR0*limA1S(gteRFC-gteR*RR0);
+ gteMAC2 = gteG*GG0 + gteIR0*limA2S(gteGFC-gteG*GG0);
+ gteMAC3 = gteB*BB0 + gteIR0*limA3S(gteBFC-gteB*BB0);
+
+/* RR0 = FNC_OVERFLOW1(gteRBK + (gteLR1*gteIR1 +gteLR2*gteIR2 + gteLR3*gteIR3));
+ GG0 = FNC_OVERFLOW2(gteGBK + (gteLG1*gteIR1 +gteLG2*gteIR2 + gteLG3*gteIR3));
+ BB0 = FNC_OVERFLOW3(gteBBK + (gteLB1*gteIR1 +gteLB2*gteIR2 + gteLB3*gteIR3));
+ gteMAC1 = gteR*RR0 + gteIR0*FlimA1S(gteRFC-gteR*RR0);
+ gteMAC2 = gteG*GG0 + gteIR0*FlimA2S(gteGFC-gteG*GG0);
+ gteMAC3 = gteB*BB0 + gteIR0*FlimA3S(gteBFC-gteB*BB0);*/
+
+ MAC2IR1();
+ gteRGB0 = gteRGB1;
+ gteRGB1 = gteRGB2;
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+ gteR2 = FlimB1(gteMAC1 >> 4);
+ gteG2 = FlimB2(gteMAC2 >> 4);
+ gteB2 = FlimB3(gteMAC3 >> 4); gteCODE2 = gteCODE;
+
+ SUM_FLAG
+
+#ifdef GTE_DUMP
+ if(sample < 100)
+ {
+ G_GD(9);
+ G_GD(10);
+ G_GD(11);
+
+ //G_GD(20);
+ //G_GD(21);
+ G_GD(22);
+
+ G_GD(25);
+ G_GD(26);
+ G_GD(27);
+
+ G_GC(31);
+ }
+#endif
+}
diff --git a/libpcsxcore/gte.h b/libpcsxcore/gte.h
new file mode 100644
index 00000000..b369eaae
--- /dev/null
+++ b/libpcsxcore/gte.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __GTE_H__
+#define __GTE_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+
+void gteMFC2();
+void gteCFC2();
+void gteMTC2();
+void gteCTC2();
+void gteLWC2();
+void gteSWC2();
+
+void gteRTPS();
+void gteOP();
+void gteNCLIP();
+void gteDPCS();
+void gteINTPL();
+void gteMVMVA();
+void gteNCDS();
+void gteNCDT();
+void gteCDP();
+void gteNCCS();
+void gteCC();
+void gteNCS();
+void gteNCT();
+void gteSQR();
+void gteDCPL();
+void gteDPCT();
+void gteAVSZ3();
+void gteAVSZ4();
+void gteRTPT();
+void gteGPF();
+void gteGPL();
+void gteNCCT();
+
+#endif /* __GTE_H__ */
diff --git a/libpcsxcore/ix86/iGte.h b/libpcsxcore/ix86/iGte.h
new file mode 100644
index 00000000..f9b42879
--- /dev/null
+++ b/libpcsxcore/ix86/iGte.h
@@ -0,0 +1,663 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __IGTE_H__
+#define __IGTE_H__
+
+#include "../r3000a.h"
+#include "../psxmem.h"
+
+#define CP2_FUNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ CALLFunc ((u32)gte##f); \
+/* branch = 2; */\
+}
+
+#define CP2_FUNCNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ CALLFunc ((u32)gte##f); \
+/* branch = 2; */\
+}
+
+/*CP2_FUNC(MFC2);
+CP2_FUNC(MTC2);
+CP2_FUNC(CFC2);
+CP2_FUNC(CTC2);
+CP2_FUNC(LWC2);
+CP2_FUNC(SWC2);*/
+
+void gteMFC2();
+static void recMFC2() {
+// Rt = Cop2D->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+
+ switch (_Rd_) {
+ case 29:
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteMFC2);
+ break;
+
+ default:
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2D.r[_Rd_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ break;
+ }
+}
+
+void gteMTC2();
+static void recMTC2() {
+// Cop2D->Rd = Rt
+ int fixt = 0;
+
+// iFlushRegs();
+
+ switch (_Rd_) {
+ case 8: case 9: case 10: case 11:
+ fixt = 1; break;
+
+ case 16: case 17: case 18: case 19:
+ fixt = 2; break;
+
+ case 15:
+ case 28:
+ case 30:
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteMTC2);
+ break;
+ }
+
+ if (IsConst(_Rt_)) {
+ if (fixt == 1) MOV32ItoM((u32)&psxRegs.CP2D.r[_Rd_], (s16)iRegs[_Rt_].k);
+ else if (fixt == 2) MOV32ItoM((u32)&psxRegs.CP2D.r[_Rd_], iRegs[_Rt_].k & 0xffff);
+ else MOV32ItoM((u32)&psxRegs.CP2D.r[_Rd_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rd_], EAX);
+ }
+}
+
+void gteLWC2();
+static void recLWC2() {
+// Cop2D->Rt = mem[Rs + Im] (unsigned)
+ int fixt = 0;
+
+ switch (_Rt_) {
+ case 8: case 9: case 10: case 11:
+ fixt = 1; break;
+
+ case 16: case 17: case 18: case 19:
+ fixt = 2; break;
+
+ case 15:
+ case 28:
+ case 30:
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteLWC2);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead32);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rt_], EAX);
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+void gteSWC2();
+static void recSWC2() {
+// mem[Rs + Im] = Rt
+
+ switch (_Rt_) {
+ case 29:
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteSWC2);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2D.r[_Rt_]);
+ MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2D.r[_Rt_]);
+ MOV32RtoM((u32)&psxH[addr & 0xfff], EAX);
+ return;
+ }
+ }
+
+ PUSH32M ((u32)&psxRegs.CP2D.r[_Rt_]);
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+static void recCFC2() {
+// Rt = Cop2C->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2C.r[_Rd_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+}
+
+static void recCTC2() {
+// Cop2C->Rd = Rt
+
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxRegs.CP2C.r[_Rd_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.CP2C.r[_Rd_], EAX);
+ }
+}
+
+CP2_FUNCNC(RTPS);
+CP2_FUNC(OP);
+CP2_FUNCNC(NCLIP);
+CP2_FUNCNC(DPCS);
+CP2_FUNCNC(INTPL);
+CP2_FUNC(MVMVA);
+CP2_FUNCNC(NCDS);
+CP2_FUNCNC(NCDT);
+CP2_FUNCNC(CDP);
+CP2_FUNCNC(NCCS);
+CP2_FUNCNC(CC);
+CP2_FUNCNC(NCS);
+CP2_FUNCNC(NCT);
+CP2_FUNC(SQR);
+CP2_FUNCNC(DCPL);
+CP2_FUNCNC(DPCT);
+CP2_FUNCNC(AVSZ3);
+CP2_FUNCNC(AVSZ4);
+CP2_FUNCNC(RTPT);
+CP2_FUNC(GPF);
+CP2_FUNC(GPL);
+CP2_FUNCNC(NCCT);
+
+#if 0
+
+#define gteVX0 ((s16*)psxRegs.CP2D.r)[0]
+#define gteVY0 ((s16*)psxRegs.CP2D.r)[1]
+#define gteVZ0 ((s16*)psxRegs.CP2D.r)[2]
+#define gteVX1 ((s16*)psxRegs.CP2D.r)[4]
+#define gteVY1 ((s16*)psxRegs.CP2D.r)[5]
+#define gteVZ1 ((s16*)psxRegs.CP2D.r)[6]
+#define gteVX2 ((s16*)psxRegs.CP2D.r)[8]
+#define gteVY2 ((s16*)psxRegs.CP2D.r)[9]
+#define gteVZ2 ((s16*)psxRegs.CP2D.r)[10]
+#define gteRGB psxRegs.CP2D.r[6]
+#define gteOTZ ((s16*)psxRegs.CP2D.r)[7*2]
+#define gteIR0 ((s32*)psxRegs.CP2D.r)[8]
+#define gteIR1 ((s32*)psxRegs.CP2D.r)[9]
+#define gteIR2 ((s32*)psxRegs.CP2D.r)[10]
+#define gteIR3 ((s32*)psxRegs.CP2D.r)[11]
+#define gteSX0 ((s16*)psxRegs.CP2D.r)[12*2]
+#define gteSY0 ((s16*)psxRegs.CP2D.r)[12*2+1]
+#define gteSX1 ((s16*)psxRegs.CP2D.r)[13*2]
+#define gteSY1 ((s16*)psxRegs.CP2D.r)[13*2+1]
+#define gteSX2 ((s16*)psxRegs.CP2D.r)[14*2]
+#define gteSY2 ((s16*)psxRegs.CP2D.r)[14*2+1]
+#define gteSXP ((s16*)psxRegs.CP2D.r)[15*2]
+#define gteSYP ((s16*)psxRegs.CP2D.r)[15*2+1]
+#define gteSZx ((u16*)psxRegs.CP2D.r)[16*2]
+#define gteSZ0 ((u16*)psxRegs.CP2D.r)[17*2]
+#define gteSZ1 ((u16*)psxRegs.CP2D.r)[18*2]
+#define gteSZ2 ((u16*)psxRegs.CP2D.r)[19*2]
+#define gteRGB0 psxRegs.CP2D.r[20]
+#define gteRGB1 psxRegs.CP2D.r[21]
+#define gteRGB2 psxRegs.CP2D.r[22]
+#define gteMAC0 psxRegs.CP2D.r[24]
+#define gteMAC1 ((s32*)psxRegs.CP2D.r)[25]
+#define gteMAC2 ((s32*)psxRegs.CP2D.r)[26]
+#define gteMAC3 ((s32*)psxRegs.CP2D.r)[27]
+#define gteIRGB psxRegs.CP2D.r[28]
+#define gteORGB psxRegs.CP2D.r[29]
+#define gteLZCS psxRegs.CP2D.r[30]
+#define gteLZCR psxRegs.CP2D.r[31]
+
+#define gteR ((u8 *)psxRegs.CP2D.r)[6*4]
+#define gteG ((u8 *)psxRegs.CP2D.r)[6*4+1]
+#define gteB ((u8 *)psxRegs.CP2D.r)[6*4+2]
+#define gteCODE ((u8 *)psxRegs.CP2D.r)[6*4+3]
+#define gteC gteCODE
+
+#define gteR0 ((u8 *)psxRegs.CP2D.r)[20*4]
+#define gteG0 ((u8 *)psxRegs.CP2D.r)[20*4+1]
+#define gteB0 ((u8 *)psxRegs.CP2D.r)[20*4+2]
+#define gteCODE0 ((u8 *)psxRegs.CP2D.r)[20*4+3]
+#define gteC0 gteCODE0
+
+#define gteR1 ((u8 *)psxRegs.CP2D.r)[21*4]
+#define gteG1 ((u8 *)psxRegs.CP2D.r)[21*4+1]
+#define gteB1 ((u8 *)psxRegs.CP2D.r)[21*4+2]
+#define gteCODE1 ((u8 *)psxRegs.CP2D.r)[21*4+3]
+#define gteC1 gteCODE1
+
+#define gteR2 ((u8 *)psxRegs.CP2D.r)[22*4]
+#define gteG2 ((u8 *)psxRegs.CP2D.r)[22*4+1]
+#define gteB2 ((u8 *)psxRegs.CP2D.r)[22*4+2]
+#define gteCODE2 ((u8 *)psxRegs.CP2D.r)[22*4+3]
+#define gteC2 gteCODE2
+
+
+
+#define gteR11 ((s16*)psxRegs.CP2C.r)[0]
+#define gteR12 ((s16*)psxRegs.CP2C.r)[1]
+#define gteR13 ((s16*)psxRegs.CP2C.r)[2]
+#define gteR21 ((s16*)psxRegs.CP2C.r)[3]
+#define gteR22 ((s16*)psxRegs.CP2C.r)[4]
+#define gteR23 ((s16*)psxRegs.CP2C.r)[5]
+#define gteR31 ((s16*)psxRegs.CP2C.r)[6]
+#define gteR32 ((s16*)psxRegs.CP2C.r)[7]
+#define gteR33 ((s16*)psxRegs.CP2C.r)[8]
+#define gteTRX ((s32*)psxRegs.CP2C.r)[5]
+#define gteTRY ((s32*)psxRegs.CP2C.r)[6]
+#define gteTRZ ((s32*)psxRegs.CP2C.r)[7]
+#define gteL11 ((s16*)psxRegs.CP2C.r)[16]
+#define gteL12 ((s16*)psxRegs.CP2C.r)[17]
+#define gteL13 ((s16*)psxRegs.CP2C.r)[18]
+#define gteL21 ((s16*)psxRegs.CP2C.r)[19]
+#define gteL22 ((s16*)psxRegs.CP2C.r)[20]
+#define gteL23 ((s16*)psxRegs.CP2C.r)[21]
+#define gteL31 ((s16*)psxRegs.CP2C.r)[22]
+#define gteL32 ((s16*)psxRegs.CP2C.r)[23]
+#define gteL33 ((s16*)psxRegs.CP2C.r)[24]
+#define gteRBK ((s32*)psxRegs.CP2C.r)[13]
+#define gteGBK ((s32*)psxRegs.CP2C.r)[14]
+#define gteBBK ((s32*)psxRegs.CP2C.r)[15]
+#define gteLR1 ((s16*)psxRegs.CP2C.r)[32]
+#define gteLR2 ((s16*)psxRegs.CP2C.r)[33]
+#define gteLR3 ((s16*)psxRegs.CP2C.r)[34]
+#define gteLG1 ((s16*)psxRegs.CP2C.r)[35]
+#define gteLG2 ((s16*)psxRegs.CP2C.r)[36]
+#define gteLG3 ((s16*)psxRegs.CP2C.r)[37]
+#define gteLB1 ((s16*)psxRegs.CP2C.r)[38]
+#define gteLB2 ((s16*)psxRegs.CP2C.r)[39]
+#define gteLB3 ((s16*)psxRegs.CP2C.r)[40]
+#define gteRFC ((s32*)psxRegs.CP2C.r)[21]
+#define gteGFC ((s32*)psxRegs.CP2C.r)[22]
+#define gteBFC ((s32*)psxRegs.CP2C.r)[23]
+#define gteOFX ((s32*)psxRegs.CP2C.r)[24]
+#define gteOFY ((s32*)psxRegs.CP2C.r)[25]
+#define gteH ((u16*)psxRegs.CP2C.r)[52]
+#define gteDQA ((s16*)psxRegs.CP2C.r)[54]
+#define gteDQB ((s32*)psxRegs.CP2C.r)[28]
+#define gteZSF3 ((s16*)psxRegs.CP2C.r)[58]
+#define gteZSF4 ((s16*)psxRegs.CP2C.r)[60]
+#define gteFLAG psxRegs.CP2C.r[31]
+
+//#define SUM_FLAG if(gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000;
+
+#define SUM_FLAG() { \
+ TEST32ItoM((u32)&gteFLAG, 0x7F87E000); \
+ j8Ptr[0] = JZ8(0); \
+ OR32ItoM((u32)&gteFLAG, 0x80000000); \
+ \
+ x86SetJ8(j8Ptr[0]); \
+}
+
+#define LIM32X8(reg, gteout, negv, posv, flagb) { \
+ CMP32ItoR(reg, negv); \
+ j8Ptr[0] = JL8(0); \
+ CMP32ItoR(reg, posv); \
+ j8Ptr[1] = JG8(0); \
+ \
+ MOV8RtoM((u32)&gteout, reg); \
+ j8Ptr[2] = JMP8(0); \
+ \
+ x86SetJ8(j8Ptr[0]); \
+ MOV8ItoM((u32)&gteout, negv); \
+ j8Ptr[3] = JMP8(0); \
+ \
+ x86SetJ8(j8Ptr[1]); \
+ MOV8ItoM((u32)&gteout, posv); \
+ \
+ x86SetJ8(j8Ptr[3]); \
+ OR32ItoM((u32)&gteFLAG, 1<<flagb); \
+ \
+ x86SetJ8(j8Ptr[2]); \
+}
+
+#define _LIM_B1(reg, gteout) LIM32X8(reg, gteout, 0, 255, 21);
+#define _LIM_B2(reg, gteout) LIM32X8(reg, gteout, 0, 255, 20);
+#define _LIM_B3(reg, gteout) LIM32X8(reg, gteout, 0, 255, 19);
+
+#define MAC2IRn(reg, ir, flagb, negv, posv) { \
+/* CMP32ItoR(reg, negv);*/ \
+/* j8Ptr[0] = JL8(0); */\
+/* CMP32ItoR(reg, posv);*/ \
+/* j8Ptr[1] = JG8(0);*/ \
+ \
+ MOV32RtoM((u32)&ir, reg); \
+/* j8Ptr[2] = JMP8(0);*/ \
+ \
+/* x86SetJ8(j8Ptr[0]);*/ \
+/* MOV32ItoM((u32)&ir, negv);*/ \
+/* j8Ptr[3] = JMP8(0);*/ \
+ \
+/* x86SetJ8(j8Ptr[1]);*/ \
+/* MOV32ItoM((u32)&ir, posv);*/ \
+ \
+/* x86SetJ8(j8Ptr[3]);*/ \
+/* OR32ItoR((u32)&gteFLAG, 1<<flagb);*/ \
+ \
+/* x86SetJ8(j8Ptr[2]);*/ \
+}
+
+
+
+#define gte_C11 gteLR1
+#define gte_C12 gteLR2
+#define gte_C13 gteLR3
+#define gte_C21 gteLG1
+#define gte_C22 gteLG2
+#define gte_C23 gteLG3
+#define gte_C31 gteLB1
+#define gte_C32 gteLB2
+#define gte_C33 gteLB3
+
+
+#define _MVMVA_FUNC(vn, mx) { \
+ MOVSX32M16toR(EAX, (u32)&mx##vn##1); \
+ IMUL32R(EBX); \
+/* j8Ptr[0] = JO8(0);*/ \
+ MOV32RtoR(ECX, EAX); \
+ \
+ MOVSX32M16toR(EAX, (u32)&mx##vn##2); \
+ IMUL32R(EDI); \
+/* j8Ptr[1] = JO8(0);*/ \
+ ADD32RtoR(ECX, EAX); \
+/* j8Ptr[2] = JO8(0);*/ \
+ \
+ MOVSX32M16toR(EAX, (u32)&mx##vn##3); \
+ IMUL32R(ESI); \
+/* j8Ptr[3] = JO8(0);*/ \
+ ADD32RtoR(ECX, EAX); \
+/* j8Ptr[4] = JO8(0);*/ \
+}
+
+/* SSX = (_v0) * mx##11 + (_v1) * mx##12 + (_v2) * mx##13;
+ SSY = (_v0) * mx##21 + (_v1) * mx##22 + (_v2) * mx##23;
+ SSZ = (_v0) * mx##31 + (_v1) * mx##32 + (_v2) * mx##33; */
+
+#define _MVMVA_ADD(_vx, jn) { \
+ ADD32MtoR(ECX, (u32)&_vx); \
+/* j8Ptr[jn] = JO8(0);*/ \
+}
+/* SSX+= gteRFC;
+ SSY+= gteGFC;
+ SSZ+= gteBFC;*/
+
+#define _MVMVA1(vn) { \
+ switch (psxRegs.code & 0x60000) { \
+ case 0x00000: /* R */ \
+ _MVMVA_FUNC(vn, gteR); break; \
+ case 0x20000: /* L */ \
+ _MVMVA_FUNC(vn, gteL); break; \
+ case 0x40000: /* C */ \
+ _MVMVA_FUNC(vn, gte_C); break; \
+ default: \
+ return; \
+ } \
+}
+
+#define _MVMVA_LOAD(_v0, _v1, _v2) { \
+ MOVSX32M16toR(EBX, (u32)&_v0); \
+ MOVSX32M16toR(EDI, (u32)&_v1); \
+ MOVSX32M16toR(ESI, (u32)&_v2); \
+}
+
+static void recMVMVA() {
+ int i;
+
+// SysPrintf("GTE_MVMVA %lx\n", psxRegs.code & 0x1ffffff);
+
+/* PUSH32R(ESI);
+ PUSH32R(EDI);
+ PUSH32R(EBX);
+*/
+ XOR32RtoR(EAX, EAX); /* gteFLAG = 0 */
+ MOV32RtoM((u32)&gteFLAG, EAX);
+
+ switch (psxRegs.code & 0x18000) {
+ case 0x00000: /* V0 */
+ _MVMVA_LOAD(gteVX0, gteVY0, gteVZ0); break;
+ case 0x08000: /* V1 */
+ _MVMVA_LOAD(gteVX1, gteVY1, gteVZ1); break;
+ case 0x10000: /* V2 */
+ _MVMVA_LOAD(gteVX2, gteVY2, gteVZ2); break;
+ case 0x18000: /* IR */
+ _MVMVA_LOAD(gteIR1, gteIR2, gteIR3); break;
+ }
+
+// MAC1
+ for (i=5; i<8; i++) j8Ptr[i] = 0;
+ _MVMVA1(1);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRX, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteRBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteRFC, 7); break;
+ }
+/*
+ j8Ptr[9] = JMP8(0);
+ for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);
+
+// TEST32ItoR(EDX, 0x80000000);
+ OR32ItoM((u32)&gteFLAG, 1<<29);
+ x86SetJ8(j8Ptr[9]);*/
+ MOV32RtoM((u32)&gteMAC1, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR1, 24, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR1, 24, -32768, 32767);
+ }
+
+// MAC2
+ _MVMVA1(2);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRY, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteGBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteGFC, 7); break;
+ }
+
+/* for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);*/
+ MOV32RtoM((u32)&gteMAC2, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR2, 23, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR2, 23, -32768, 32767);
+ }
+
+// MAC3
+ _MVMVA1(3);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRZ, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteBBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteBFC, 7); break;
+ }
+
+/* for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);*/
+ MOV32RtoM((u32)&gteMAC3, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR3, 22, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR3, 22, -32768, 32767);
+ }
+/* MAC2IR1()
+ else MAC2IR()*/
+
+// SUM_FLAG();
+
+/* POP32R(EBX);
+ POP32R(EDI);
+ POP32R(ESI);*/
+}
+
+#if 0
+
+#define _GPF1(vn) { \
+ MOV32MtoR(EAX, (u32)&gteIR##vn); \
+ IMUL32R(ECX); \
+/* MOV32RtoR(ECX, EAX); */\
+}
+
+static void recGPF() {
+// SysPrintf("GTE_GPF %lx\n", psxRegs.code & 0x1ffffff);
+
+ PUSH32R(EBX);
+
+ XOR32RtoR(EBX, EBX); /* gteFLAG = 0 */
+
+/* gteMAC1 = NC_OVERFLOW1(gteIR0 * gteIR1);
+ gteMAC2 = NC_OVERFLOW2(gteIR0 * gteIR2);
+ gteMAC3 = NC_OVERFLOW3(gteIR0 * gteIR3);*/
+ MOV32MtoR(ECX, (u32)&gteIR0);
+// MAC1
+ _GPF1(1);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR1, 24, -32768, 32767);
+ PUSH32R(EAX);
+
+// MAC2
+ _GPF1(2);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR2, 23, -32768, 32767);
+ PUSH32R(EAX);
+
+// MAC3
+ _GPF1(3);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR3, 22, -32768, 32767);
+// MAC2IR();
+
+// gteRGB0 = gteRGB1;
+// gteRGB1 = gteRGB2;
+ MOV32MtoR(EDX, (u32)&gteRGB1);
+ MOV32MtoR(ECX, (u32)&gteRGB2);
+ MOV32RtoM((u32)&gteRGB0, EDX);
+ MOV32RtoM((u32)&gteRGB1, ECX);
+
+ POP32R(EDX);
+ POP32R(ECX);
+ SAR32ItoR(ECX, 4);
+ SAR32ItoR(EDX, 4);
+ SAR32ItoR(EAX, 4);
+
+ _LIM_B1(ECX, gteR2);
+ _LIM_B2(EDX, gteG2);
+ _LIM_B3(EAX, gteB2);
+ MOV8MtoR(EAX, (u32)&gteCODE);
+ MOV8RtoM((u32)&gteCODE2, EAX);
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+
+ SUM_FLAG();
+ MOV32RtoM((u32)&gteFLAG, EBX);
+
+// POP32R(EBX);
+}
+#endif
+#endif
+
+
+#endif /* __IGTE_H__ */
diff --git a/libpcsxcore/ix86/iR3000A.c b/libpcsxcore/ix86/iR3000A.c
new file mode 100644
index 00000000..ad2e3c6e
--- /dev/null
+++ b/libpcsxcore/ix86/iR3000A.c
@@ -0,0 +1,2898 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* i386 assembly functions for R3000A core.
+*/
+
+#include "ix86.h"
+#include <sys/mman.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+u32 *psxRecLUT;
+
+#undef PC_REC
+#undef PC_REC8
+#undef PC_REC16
+#undef PC_REC32
+#define PC_REC(x) (psxRecLUT[x >> 16] + (x & 0xffff))
+#define PC_REC8(x) (*(u8 *)PC_REC(x))
+#define PC_REC16(x) (*(u16*)PC_REC(x))
+#define PC_REC32(x) (*(u32*)PC_REC(x))
+
+#define RECMEM_SIZE (8 * 1024 * 1024)
+
+static char *recMem; /* the recompiled blocks will be here */
+static char *recRAM; /* and the ptr to the blocks here */
+static char *recROM; /* and here */
+
+static u32 pc; /* recompiler pc */
+static u32 pcold; /* recompiler oldpc */
+static int count; /* recompiler intruction count */
+static int branch; /* set for branch */
+static u32 target; /* branch target */
+static u32 resp;
+
+typedef struct {
+ int state;
+ u32 k;
+ int reg;
+} iRegisters;
+
+static iRegisters iRegs[32];
+static iRegisters iRegsS[32];
+
+#define ST_UNK 0
+#define ST_CONST 1
+#define ST_MAPPED 2
+
+#define IsConst(reg) (iRegs[reg].state == ST_CONST)
+#define IsMapped(reg) (iRegs[reg].state == ST_MAPPED)
+
+static void (*recBSC[64])();
+static void (*recSPC[64])();
+static void (*recREG[32])();
+static void (*recCP0[32])();
+static void (*recCP2[64])();
+static void (*recCP2BSC[32])();
+
+static void MapConst(int reg, u32 _const) {
+ iRegs[reg].k = _const;
+ iRegs[reg].state = ST_CONST;
+}
+
+static void iFlushReg(int reg) {
+ if (IsConst(reg)) {
+ MOV32ItoM((u32)&psxRegs.GPR.r[reg], iRegs[reg].k);
+ }
+ iRegs[reg].state = ST_UNK;
+}
+
+static void iFlushRegs() {
+ int i;
+
+ for (i=1; i<32; i++) {
+ iFlushReg(i);
+ }
+}
+
+static void iRet() {
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+ RET();
+}
+
+static int iLoadTest() {
+ u32 tmp;
+
+ // check for load delay
+ tmp = psxRegs.code >> 26;
+ switch (tmp) {
+ case 0x10: // COP0
+ switch (_Rs_) {
+ case 0x00: // MFC0
+ case 0x02: // CFC0
+ return 1;
+ }
+ break;
+ case 0x12: // COP2
+ switch (_Funct_) {
+ case 0x00:
+ switch (_Rs_) {
+ case 0x00: // MFC2
+ case 0x02: // CFC2
+ return 1;
+ }
+ break;
+ }
+ break;
+ case 0x32: // LWC2
+ return 1;
+ default:
+ if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+/* set a pending branch */
+static void SetBranch() {
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc += 4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = (pc - pcold) / 4;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ PUSH32M((u32)&target);
+ PUSH32I(_Rt_);
+ CALLFunc((u32)psxDelayTest);
+ ADD32ItoR(ESP, 2*4);
+
+ RET();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32MtoR(EAX, (u32)&target);
+ MOV32RtoM((u32)&psxRegs.pc, EAX);
+ CALLFunc((u32)psxBranchTest);
+
+ iRet();
+}
+
+static void iJump(u32 branchPC) {
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc+=4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ PUSH32I(branchPC);
+ PUSH32I(_Rt_);
+ CALLFunc((u32)psxDelayTest);
+ ADD32ItoR(ESP, 2*4);
+
+ RET();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, branchPC);
+ CALLFunc((u32)psxBranchTest);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ // maybe just happened an interruption, check so
+ CMP32ItoM((u32)&psxRegs.pc, branchPC);
+ j8Ptr[0] = JE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[0]);
+ MOV32MtoR(EAX, PC_REC(branchPC));
+ TEST32RtoR(EAX, EAX);
+ j8Ptr[1] = JNE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[1]);
+ RET();
+ JMP32R(EAX);
+}
+
+static void iBranch(u32 branchPC, int savectx) {
+ u32 respold=0;
+
+ if (savectx) {
+ respold = resp;
+ memcpy(iRegsS, iRegs, sizeof(iRegs));
+ }
+
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+
+ // the delay test is only made when the branch is taken
+ // savectx == 0 will mean that :)
+ if (savectx == 0 && iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = ((pc+4) - pcold)/4;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ PUSH32I(branchPC);
+ PUSH32I(_Rt_);
+ CALLFunc((u32)psxDelayTest);
+ ADD32ItoR(ESP, 2*4);
+
+ RET();
+ return;
+ }
+
+ pc+= 4;
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, branchPC);
+ CALLFunc((u32)psxBranchTest);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ // maybe just happened an interruption, check so
+ CMP32ItoM((u32)&psxRegs.pc, branchPC);
+ j8Ptr[1] = JE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[1]);
+ MOV32MtoR(EAX, PC_REC(branchPC));
+ TEST32RtoR(EAX, EAX);
+ j8Ptr[2] = JNE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[2]);
+ JMP32R(EAX);
+
+ pc-= 4;
+ if (savectx) {
+ resp = respold;
+ memcpy(iRegs, iRegsS, sizeof(iRegs));
+ }
+}
+
+
+char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
+char *txt1 = "EAX = %x\n";
+char *txt2 = "M32 = %x\n";
+
+void iLogX86() {
+ PUSHA32();
+
+ PUSH32R (EDX);
+ PUSH32R (ECX);
+ PUSH32R (EAX);
+ PUSH32M ((u32)&txt0);
+ CALLFunc ((u32)SysPrintf);
+ ADD32ItoR(ESP, 4*4);
+
+ POPA32();
+}
+
+void iLogEAX() {
+ PUSH32R (EAX);
+ PUSH32M ((u32)&txt1);
+ CALLFunc ((u32)SysPrintf);
+ ADD32ItoR(ESP, 4*2);
+}
+
+void iLogM32(u32 mem) {
+ PUSH32M (mem);
+ PUSH32M ((u32)&txt2);
+ CALLFunc ((u32)SysPrintf);
+ ADD32ItoR(ESP, 4*2);
+}
+
+static void iDumpRegs() {
+ int i, j;
+
+ printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle);
+ for (i=0; i<4; i++) {
+ for (j=0; j<8; j++)
+ printf("%lx ", psxRegs.GPR.r[j*i]);
+ printf("\n");
+ }
+}
+
+void iDumpBlock(char *ptr) {
+ FILE *f;
+ u32 i;
+
+ SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxRegs.cycle);
+
+ for (i = psxRegs.pc; i < pc; i+=4)
+ SysPrintf("%s\n", disR3000AF(PSXMu32(i), i));
+
+ fflush(stdout);
+ f = fopen("dump1", "w");
+ fwrite(ptr, 1, (u32)x86Ptr - (u32)ptr, f);
+ fclose(f);
+ system("ndisasmw -u dump1");
+ fflush(stdout);
+}
+
+#define REC_FUNC(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
+ CALLFunc((u32)psx##f); \
+/* branch = 2; */\
+}
+
+#define REC_SYS(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
+ CALLFunc((u32)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+#define REC_BRANCH(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
+ CALLFunc((u32)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+static void recRecompile();
+
+static int recInit() {
+ int i;
+
+ psxRecLUT = (u32*) malloc(0x010000 * 4);
+
+ //recMem = (char*) malloc(RECMEM_SIZE);
+ recMem = mmap(0, RECMEM_SIZE + 0x1000,
+ PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ recRAM = (char*) malloc(0x200000);
+ recROM = (char*) malloc(0x080000);
+ if (recRAM == NULL || recROM == NULL || recMem == NULL || psxRecLUT == NULL) {
+ SysMessage("Error allocating memory"); return -1;
+ }
+
+ for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16];
+ memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * 4);
+ memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * 4);
+
+ for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = (u32)&recROM[i << 16];
+
+ return 0;
+}
+
+static void recReset() {
+ memset(recRAM, 0, 0x200000);
+ memset(recROM, 0, 0x080000);
+
+ x86Init();
+
+ x86SetPtr(recMem);
+
+ branch = 0;
+ memset(iRegs, 0, sizeof(iRegs));
+ iRegs[0].state = ST_CONST;
+ iRegs[0].k = 0;
+}
+
+static void recShutdown() {
+ if (recMem == NULL) return;
+ free(psxRecLUT);
+ //free(recMem);
+ munmap(recMem, RECMEM_SIZE + 0x1000);
+ free(recRAM);
+ free(recROM);
+ x86Shutdown();
+}
+
+static void recError() {
+ SysReset();
+ ClosePlugins();
+ SysMessage("Unrecoverable error while running recompiler\n");
+ SysRunGui();
+}
+
+__inline static void execute() {
+ void (**recFunc)() = NULL;
+ char *p;
+
+ p = (char *)PC_REC(psxRegs.pc);
+ if (p != NULL) recFunc = (void (**)()) (u32)p;
+ else { recError(); return; }
+
+ if (*recFunc == 0) {
+ recRecompile();
+ }
+ (*recFunc)();
+}
+
+static void recExecute() {
+ for (;;) execute();
+}
+
+static void recExecuteBlock() {
+ execute();
+}
+
+static void recClear(u32 Addr, u32 Size) {
+ memset((void*)PC_REC(Addr), 0, Size * 4);
+}
+
+static void recNULL() {
+// SysMessage("recUNK: %8.8x\n", psxRegs.code);
+}
+
+/*********************************************************
+* goes to opcodes tables... *
+* Format: table[something....] *
+*********************************************************/
+
+//REC_SYS(SPECIAL);
+static void recSPECIAL() {
+ recSPC[_Funct_]();
+}
+
+static void recREGIMM() {
+ recREG[_Rt_]();
+}
+
+static void recCOP0() {
+ recCP0[_Rs_]();
+}
+
+//REC_SYS(COP2);
+static void recCOP2() {
+ recCP2[_Funct_]();
+}
+
+static void recBASIC() {
+ recCP2BSC[_Rs_]();
+}
+
+//end of Tables opcodes...
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+
+/*REC_FUNC(ADDI);
+REC_FUNC(ADDIU);
+REC_FUNC(ANDI);
+REC_FUNC(ORI);
+REC_FUNC(XORI);
+REC_FUNC(SLTI);
+REC_FUNC(SLTIU);
+#if 0*/
+static void recADDIU() {
+// Rt = Rs + Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k+= _Imm_;
+ } else {
+ if (_Imm_ == 1) {
+ INC32M((u32)&psxRegs.GPR.r[_Rt_]);
+ } else if (_Imm_ == -1) {
+ DEC32M((u32)&psxRegs.GPR.r[_Rt_]);
+ } else if (_Imm_) {
+ ADD32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_);
+ }
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k + _Imm_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_ == 1) {
+ INC32R(EAX);
+ } else if (_Imm_ == -1) {
+ DEC32R(EAX);
+ } else if (_Imm_) {
+ ADD32ItoR(EAX, _Imm_);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recADDI() {
+// Rt = Rs + Im
+ recADDIU();
+}
+
+static void recSLTI() {
+// Rt = Rs < Im (signed)
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, _Imm_);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+}
+
+static void recSLTIU() {
+// Rt = Rs < Im (unsigned)
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, _Imm_);
+ SETB8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+}
+
+static void recANDI() {
+// Rt = Rs And Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k&= _ImmU_;
+ } else {
+ AND32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32ItoR(EAX, _ImmU_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recORI() {
+// Rt = Rs Or Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k|= _ImmU_;
+ } else {
+ OR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_ImmU_) OR32ItoR (EAX, _ImmU_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recXORI() {
+// Rt = Rs Xor Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k^= _ImmU_;
+ } else {
+ XOR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ XOR32ItoR(EAX, _ImmU_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+//#endif
+//end of * Arithmetic with immediate operand
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+/*REC_FUNC(LUI);
+#if 0*/
+static void recLUI() {
+// Rt = Imm << 16
+ if (!_Rt_) return;
+
+ MapConst(_Rt_, psxRegs.code << 16);
+}
+//#endif
+//End of Load Higher .....
+
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+
+/*REC_FUNC(ADD);
+REC_FUNC(ADDU);
+REC_FUNC(SUB);
+REC_FUNC(SUBU);
+REC_FUNC(AND);
+REC_FUNC(OR);
+REC_FUNC(XOR);
+REC_FUNC(NOR);
+REC_FUNC(SLT);
+REC_FUNC(SLTU);
+
+#if 0*/
+static void recADDU() {
+// Rd = Rs + Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rt_ == _Rd_) {
+ if (iRegs[_Rs_].k == 1) {
+ INC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rs_].k == -1) {
+ DEC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rs_].k) {
+ ADD32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
+ }
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (iRegs[_Rs_].k == 1) {
+ INC32R(EAX);
+ } else if (iRegs[_Rs_].k == 0xffffffff) {
+ DEC32R(EAX);
+ } else if (iRegs[_Rs_].k) {
+ ADD32ItoR(EAX, iRegs[_Rs_].k);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) {
+ if (iRegs[_Rt_].k == 1) {
+ INC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rt_].k == -1) {
+ DEC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rt_].k) {
+ ADD32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
+ }
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (iRegs[_Rt_].k == 1) {
+ INC32R(EAX);
+ } else if (iRegs[_Rt_].k == 0xffffffff) {
+ DEC32R(EAX);
+ } else if (iRegs[_Rt_].k) {
+ ADD32ItoR(EAX, iRegs[_Rt_].k);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) { // Rd+= Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ ADD32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (_Rt_ == _Rd_) { // Rd+= Rs
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else { // Rd = Rs + Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ }
+}
+
+static void recADD() {
+// Rd = Rs + Rt
+ recADDU();
+}
+
+static void recSUBU() {
+// Rd = Rs - Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SUB32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSUB() {
+// Rd = Rs - Rt
+ recSUBU();
+}
+
+static void recAND() {
+// Rd = Rs And Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rd_ == _Rt_) { // Rd&= Rs
+ AND32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
+ } else {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rd_ == _Rs_) { // Rd&= kRt
+ AND32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
+ } else { // Rd = Rs & kRt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) { // Rd&= Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ AND32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (_Rt_ == _Rd_) { // Rd&= Rs
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else { // Rd = Rs & Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ }
+}
+
+static void recOR() {
+// Rd = Rs Or Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32ItoR (EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recXOR() {
+// Rd = Rs Xor Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ XOR32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recNOR() {
+// Rd = Rs Nor Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k));
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ NOT32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32ItoR (EAX, iRegs[_Rt_].k);
+ NOT32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ NOT32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSLT() {
+// Rd = Rs < Rt (signed)
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, iRegs[_Rt_].k);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSLTU() {
+// Rd = Rs < Rt (unsigned)
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, iRegs[_Rt_].k);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+//#endif
+//End of * Register arithmetic
+
+/*********************************************************
+* Register mult/div & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+
+/*REC_FUNC(MULT);
+REC_FUNC(MULTU);
+REC_FUNC(DIV);
+REC_FUNC(DIVU);
+#if 0*/
+static void recMULT() {
+// Lo/Hi = Rs * Rt (signed)
+
+// iFlushRegs();
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ XOR32RtoR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multrsk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multrtk %x\n", iRegs[_Rt_].k);
+ IMUL32R (EDX);
+ } else {
+ IMUL32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+}
+
+static void recMULTU() {
+// Lo/Hi = Rs * Rt (unsigned)
+
+// iFlushRegs();
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ XOR32RtoR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multursk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multurtk %x\n", iRegs[_Rt_].k);
+ MUL32R (EDX);
+ } else {
+ MUL32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+}
+
+static void recDIV() {
+// Lo/Hi = Rs / Rt (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ if (iRegs[_Rt_].k == 0) return;
+ MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divrtk %x\n", iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ CMP32ItoR(ECX, 0);
+ j8Ptr[0] = JE8(0);
+ }
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divrsk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ CDQ();
+ IDIV32R (ECX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+ if (!IsConst(_Rt_)) {
+ x86SetJ8(j8Ptr[0]);
+ }
+}
+
+static void recDIVU() {
+// Lo/Hi = Rs / Rt (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ if (iRegs[_Rt_].k == 0) return;
+ MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divurtk %x\n", iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ CMP32ItoR(ECX, 0);
+ j8Ptr[0] = JE8(0);
+ }
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divursk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ XOR32RtoR(EDX, EDX);
+ DIV32R (ECX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+ if (!IsConst(_Rt_)) {
+ x86SetJ8(j8Ptr[0]);
+ }
+}
+//#endif
+//End of * Register mult/div & Register trap logic
+
+/*REC_FUNC(LB);
+REC_FUNC(LBU);
+REC_FUNC(LH);
+REC_FUNC(LHU);
+REC_FUNC(LW);
+
+REC_FUNC(SB);
+REC_FUNC(SH);
+REC_FUNC(SW);*/
+
+//REC_FUNC(LWL);
+//REC_FUNC(LWR);
+//REC_FUNC(SWL);
+//REC_FUNC(SWR);
+
+/* Push OfB for Stores/Loads */
+static void iPushOfB() {
+ if (IsConst(_Rs_)) {
+ PUSH32I (iRegs[_Rs_].k + _Imm_);
+ } else {
+ if (_Imm_) {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32ItoR(EAX, _Imm_);
+ PUSH32R (EAX);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ }
+}
+
+//#if 0
+static void recLB() {
+// Rt = mem[Rs + Im] (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRs8(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M8toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M8toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r8 %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead8);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVSX32R8toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLBU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu8(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M8toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M8toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r8u %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead8);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVZX32R8toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLH() {
+// Rt = mem[Rs + Im] (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRs16(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M16toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M16toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r16 %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead16);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVSX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLHU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu16(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ PUSH32I (addr);
+ CALL32M ((u32)&SPU_readRegister);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+#ifndef __WIN32__
+ resp+= 4;
+#endif
+ return;
+ }
+ switch (addr) {
+ case 0x1f801100: case 0x1f801110: case 0x1f801120:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ PUSH32I((addr >> 4) & 0x3);
+ CALLFunc((u32)psxRcntRcount);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ resp+= 4;
+ return;
+
+ case 0x1f801104: case 0x1f801114: case 0x1f801124:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (u32)&psxCounters[(addr >> 4) & 0x3].mode);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801108: case 0x1f801118: case 0x1f801128:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (u32)&psxCounters[(addr >> 4) & 0x3].target);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+// SysPrintf("unhandled r16u %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead16);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLW() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu32(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80) {
+ switch (addr) {
+ case 0x1f801080: case 0x1f801084: case 0x1f801088:
+ case 0x1f801090: case 0x1f801094: case 0x1f801098:
+ case 0x1f8010a0: case 0x1f8010a4: case 0x1f8010a8:
+ case 0x1f8010b0: case 0x1f8010b4: case 0x1f8010b8:
+ case 0x1f8010c0: case 0x1f8010c4: case 0x1f8010c8:
+ case 0x1f8010d0: case 0x1f8010d4: case 0x1f8010d8:
+ case 0x1f8010e0: case 0x1f8010e4: case 0x1f8010e8:
+ case 0x1f801070: case 0x1f801074:
+ case 0x1f8010f0: case 0x1f8010f4:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801810:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ CALL32M((u32)&GPU_readData);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801814:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ CALL32M((u32)&GPU_readStatus);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+// SysPrintf("unhandled r32 %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead32);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+extern u32 LWL_MASK[4];
+extern u32 LWL_SHIFT[4];
+
+void iLWLk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32ItoR(ECX, LWL_MASK[shift]);
+ SHL32ItoR(EAX, LWL_SHIFT[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recLWL() {
+// Rt = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iLWLk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iLWLk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+ CALLFunc((u32)psxMemRead32);
+
+ if (_Rt_) {
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)LWL_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ SHL32CLtoR(EAX); // mem(EAX) << LWL_SHIFT[shift]
+
+ MOV32ItoR(ECX, (u32)LWL_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32RtoR(EDX, ECX); // _rRt_ & LWL_MASK[shift]
+
+ OR32RtoR(EAX, EDX);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ } else {
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+ }
+}
+
+static void recLWBlock(int count) {
+ u32 *code = (u32 *)PSXM(pc);
+ int i, respsave;
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ // since bios is readonly it won't change
+ for (i = 0; i < count; i++, code++, addr += 4) {
+ if (_fRt_(*code)) {
+ MapConst(_fRt_(*code), psxRu32(addr));
+ }
+ }
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ for (i = 0; i < count; i++, code++, addr += 4) {
+ if (!_fRt_(*code))
+ return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ for (i = 0; i < count; i++, code++, addr += 4) {
+ if (!_fRt_(*code))
+ return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ }
+
+ SysPrintf("recLWBlock %d: %d\n", count, IsConst(_Rs_));
+ iPushOfB();
+ CALLFunc((u32)psxMemPointer);
+// ADD32ItoR(ESP, 4);
+ resp += 4;
+
+ respsave = resp; resp = 0;
+ TEST32RtoR(EAX, EAX);
+ j32Ptr[4] = JZ32(0);
+ XOR32RtoR(ECX, ECX);
+ for (i = 0; i < count; i++, code++) {
+ if (_fRt_(*code)) {
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32RmStoR(EDX, EAX, ECX, 2);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EDX);
+ }
+ if (i != (count - 1))
+ INC32R(ECX);
+ }
+ j32Ptr[5] = JMP32(0);
+ x86SetJ32(j32Ptr[4]);
+ for (i = 0, code = (u32 *)PSXM(pc); i < count; i++, code++) {
+ psxRegs.code = *code;
+ recLW();
+ }
+ ADD32ItoR(ESP, resp);
+ x86SetJ32(j32Ptr[5]);
+ resp = respsave;
+}
+
+extern u32 LWR_MASK[4];
+extern u32 LWR_SHIFT[4];
+
+void iLWRk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32ItoR(ECX, LWR_MASK[shift]);
+ SHR32ItoR(EAX, LWR_SHIFT[shift]);
+ OR32RtoR(EAX, ECX);
+}
+
+void recLWR() {
+// Rt = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iLWRk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iLWRk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_))
+ MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+ CALLFunc((u32)psxMemRead32);
+
+ if (_Rt_) {
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)LWR_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ SHR32CLtoR(EAX); // mem(EAX) >> LWR_SHIFT[shift]
+
+ MOV32ItoR(ECX, (u32)LWR_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32RtoR(EDX, ECX); // _rRt_ & LWR_MASK[shift]
+
+ OR32RtoR(EAX, EDX);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ } else {
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+ }
+}
+
+static void recSB() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV8ItoM((u32)&psxM[addr & 0x1fffff], (u8)iRegs[_Rt_].k);
+ } else {
+ MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV8RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV8ItoM((u32)&psxH[addr & 0xfff], (u8)iRegs[_Rt_].k);
+ } else {
+ MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV8RtoM((u32)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+// SysPrintf("unhandled w8 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ PUSH32I (iRegs[_Rt_].k);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite8);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+static void recSH() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV16ItoM((u32)&psxM[addr & 0x1fffff], (u16)iRegs[_Rt_].k);
+ } else {
+ MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV16RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV16ItoM((u32)&psxH[addr & 0xfff], (u16)iRegs[_Rt_].k);
+ } else {
+ MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV16RtoM((u32)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (IsConst(_Rt_)) {
+ PUSH32I(iRegs[_Rt_].k);
+ } else {
+ PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ PUSH32I (addr);
+ CALL32M ((u32)&SPU_writeRegister);
+#ifndef __WIN32__
+ resp+= 8;
+#endif
+ return;
+ }
+ }
+// SysPrintf("unhandled w16 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ PUSH32I (iRegs[_Rt_].k);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite16);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+static void recSW() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxH[addr & 0xfff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80) {
+ switch (addr) {
+ case 0x1f801080: case 0x1f801084:
+ case 0x1f801090: case 0x1f801094:
+ case 0x1f8010a0: case 0x1f8010a4:
+ case 0x1f8010b0: case 0x1f8010b4:
+ case 0x1f8010c0: case 0x1f8010c4:
+ case 0x1f8010d0: case 0x1f8010d4:
+ case 0x1f8010e0: case 0x1f8010e4:
+ case 0x1f801074:
+ case 0x1f8010f0:
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxH[addr & 0xffff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxH[addr & 0xffff], EAX);
+ }
+ return;
+
+ case 0x1f801810:
+ if (IsConst(_Rt_)) {
+ PUSH32I(iRegs[_Rt_].k);
+ } else {
+ PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ CALL32M((u32)&GPU_writeData);
+#ifndef __WIN32__
+ resp+= 4;
+#endif
+ return;
+
+ case 0x1f801814:
+ if (IsConst(_Rt_)) {
+ PUSH32I(iRegs[_Rt_].k);
+ } else {
+ PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ CALL32M((u32)&GPU_writeStatus);
+#ifndef __WIN32__
+ resp+= 4;
+#endif
+ }
+ }
+// SysPrintf("unhandled w32 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ PUSH32I (iRegs[_Rt_].k);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+//#endif
+
+static void recSWBlock(int count) {
+ u32 *code;
+ int i, respsave;
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+ code = (u32 *)PSXM(pc);
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ for (i = 0; i < count; i++, code++, addr += 4) {
+ if (IsConst(_fRt_(*code))) {
+ MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_fRt_(*code)].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_fRt_(*code)]);
+ MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ for (i = 0; i < count; i++, code++, addr += 4) {
+ if (!_fRt_(*code))
+ return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ }
+
+ SysPrintf("recSWBlock %d: %d\n", count, IsConst(_Rs_));
+ iPushOfB();
+ CALLFunc((u32)psxMemPointer);
+// ADD32ItoR(ESP, 4);
+ resp += 4;
+
+ respsave = resp;
+ resp = 0;
+ TEST32RtoR(EAX, EAX);
+ j32Ptr[4] = JZ32(0);
+ XOR32RtoR(ECX, ECX);
+ for (i = 0, code = (u32 *)PSXM(pc); i < count; i++, code++) {
+ if (IsConst(_fRt_(*code))) {
+ MOV32ItoR(EDX, iRegs[_fRt_(*code)].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_fRt_(*code)]);
+ }
+ MOV32RtoRmS(EAX, ECX, 2, EDX);
+ if (i != (count - 1))
+ INC32R(ECX);
+ }
+ j32Ptr[5] = JMP32(0);
+ x86SetJ32(j32Ptr[4]);
+ for (i = 0, code = (u32 *)PSXM(pc); i < count; i++, code++) {
+ psxRegs.code = *code;
+ recSW();
+ }
+ ADD32ItoR(ESP, resp);
+ x86SetJ32(j32Ptr[5]);
+ resp = respsave;
+}
+
+extern u32 SWL_MASK[4];
+extern u32 SWL_SHIFT[4];
+
+void iSWLk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHR32ItoR(ECX, SWL_SHIFT[shift]);
+ AND32ItoR(EAX, SWL_MASK[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recSWL() {
+// mem[Rs + Im] = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((u32)&psxH[addr & 0xffc], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemRead32);
+
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)SWL_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ AND32RtoR(EAX, ECX); // mem & SWL_MASK[shift]
+
+ MOV32ItoR(ECX, (u32)SWL_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift]
+
+ OR32RtoR (EAX, EDX);
+ PUSH32R (EAX);
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+extern u32 SWR_MASK[4];
+extern u32 SWR_SHIFT[4];
+
+void iSWRk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHL32ItoR(ECX, SWR_SHIFT[shift]);
+ AND32ItoR(EAX, SWR_MASK[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recSWR() {
+// mem[Rs + Im] = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((u32)&psxH[addr & 0xffc], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemRead32);
+
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)SWR_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ AND32RtoR(EAX, ECX); // mem & SWR_MASK[shift]
+
+ MOV32ItoR(ECX, (u32)SWR_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift]
+
+ OR32RtoR (EAX, EDX);
+ PUSH32R (EAX);
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp += 8;
+}
+
+/*REC_FUNC(SLL);
+REC_FUNC(SRL);
+REC_FUNC(SRA);
+#if 0*/
+static void recSLL() {
+// Rd = Rt << Sa
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SHL32ItoR(EAX, _Sa_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRL() {
+// Rd = Rt >> Sa
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SHR32ItoR(EAX, _Sa_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRA() {
+// Rd = Rt >> Sa
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SAR32ItoR(EAX, _Sa_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+//#endif
+
+/*REC_FUNC(SLLV);
+REC_FUNC(SRLV);
+REC_FUNC(SRAV);
+#if 0*/
+static void recSLLV() {
+// Rd = Rt << Rs
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRLV() {
+// Rd = Rt >> Rs
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRAV() {
+// Rd = Rt >> Rs
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+//#endif
+
+/*REC_SYS(SYSCALL);
+REC_SYS(BREAK);
+
+#if 0*/
+int dump;
+static void recSYSCALL() {
+// dump = 1;
+ iFlushRegs();
+
+ MOV32ItoR(EAX, pc - 4);
+ MOV32RtoM((u32)&psxRegs.pc, EAX);
+ PUSH32I (branch == 1 ? 1 : 0);
+ PUSH32I (0x20);
+ CALLFunc ((u32)psxException);
+ ADD32ItoR(ESP, 8);
+
+ branch = 2;
+ iRet();
+}
+
+static void recBREAK() {
+}
+//#endif
+
+/*REC_FUNC(MFHI);
+REC_FUNC(MTHI);
+REC_FUNC(MFLO);
+REC_FUNC(MTLO);
+#if 0*/
+static void recMFHI() {
+// Rd = Hi
+ if (!_Rd_)
+ return;
+
+ iRegs[_Rd_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.hi);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+}
+
+static void recMTHI() {
+// Hi = Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ }
+}
+
+static void recMFLO() {
+// Rd = Lo
+ if (!_Rd_)
+ return;
+
+ iRegs[_Rd_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.lo);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+}
+
+static void recMTLO() {
+// Lo = Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.lo, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ }
+}
+//#endif
+
+/*REC_BRANCH(J);
+REC_BRANCH(JR);
+REC_BRANCH(JAL);
+REC_BRANCH(JALR);
+REC_BRANCH(BLTZ);
+REC_BRANCH(BGTZ);
+REC_BRANCH(BLTZAL);
+REC_BRANCH(BGEZAL);
+REC_BRANCH(BNE);
+REC_BRANCH(BEQ);
+REC_BRANCH(BLEZ);
+REC_BRANCH(BGEZ);*/
+
+//#if 0
+static void recBLTZ() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JL32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBGTZ() {
+// Branch if Rs > 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k > 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JG32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBLTZAL() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iJump(bpc); return;
+ } else {
+ iJump(pc + 4); return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JL32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBGEZAL() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JGE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recJ() {
+// j target
+
+ iJump(_Target_ * 4 + (pc & 0xf0000000));
+}
+
+static void recJAL() {
+// jal target
+
+ MapConst(31, pc + 4);
+
+ iJump(_Target_ * 4 + (pc & 0xf0000000));
+}
+
+static void recJR() {
+// jr Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&target, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&target, EAX);
+ }
+
+ SetBranch();
+}
+
+static void recJALR() {
+// jalr Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&target, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&target, EAX);
+ }
+
+ if (_Rd_) {
+ MapConst(_Rd_, pc + 4);
+ }
+
+ SetBranch();
+}
+
+static void recBEQ() {
+// Branch if Rs == Rt
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (_Rs_ == _Rt_) {
+ iJump(bpc);
+ } else {
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k == iRegs[_Rt_].k) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ } else if (IsConst(_Rs_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
+ } else if (IsConst(_Rt_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+
+ j32Ptr[4] = JE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+ }
+}
+
+static void recBNE() {
+// Branch if Rs != Rt
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k != iRegs[_Rt_].k) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ } else if (IsConst(_Rs_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
+ } else if (IsConst(_Rt_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ j32Ptr[4] = JNE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBLEZ() {
+// Branch if Rs <= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k <= 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JLE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBGEZ() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JGE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+//#endif
+
+/*REC_FUNC(MFC0);
+REC_SYS(MTC0);
+REC_FUNC(CFC0);
+REC_SYS(CTC0);
+REC_FUNC(RFE);
+#if 0*/
+static void recMFC0() {
+// Rt = Cop0->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+}
+
+static void recCFC0() {
+// Rt = Cop0->Rd
+
+ recMFC0();
+}
+
+void psxMTC0();
+static void recMTC0() {
+// Cop0->Rd = Rt
+
+ if (IsConst(_Rt_)) {
+ switch (_Rd_) {
+ case 12:
+ MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
+ break;
+ case 13:
+ MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k & ~(0xfc00));
+ break;
+ default:
+ MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
+ break;
+ }
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ switch (_Rd_) {
+ case 13:
+ AND32ItoR(EAX, ~(0xfc00));
+ break;
+ }
+ MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX);
+ }
+
+ if (_Rd_ == 12 || _Rd_ == 13) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc);
+ CALLFunc((u32)psxTestSWInts);
+ if (_Rd_ == 12)
+ OR32ItoM((u32)&psxRegs.interrupt, 0x80000000);
+ if (branch == 0) {
+ branch = 2;
+ iRet();
+ }
+ }
+}
+
+static void recCTC0() {
+// Cop0->Rd = Rt
+
+ recMTC0();
+}
+
+static void recRFE() {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
+ MOV32RtoR(ECX, EAX);
+ AND32ItoR(EAX, 0xfffffff0);
+ AND32ItoR(ECX, 0x3c);
+ SHR32ItoR(ECX, 2);
+ OR32RtoR (EAX, ECX);
+ MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX);
+
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc);
+ CALLFunc((u32)psxTestSWInts);
+ if (branch == 0) {
+ branch = 2;
+ iRet();
+ }
+}
+//#endif
+
+#include "iGte.h"
+
+//
+
+static void recHLE() {
+ iFlushRegs();
+
+ MOV32ItoR(EAX, (u32)psxHLEt[psxRegs.code & 0xffff]);
+ CALL32R(EAX);
+ branch = 2;
+ iRet();
+}
+
+//
+
+static void (*recBSC[64])() = {
+ recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
+ recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
+ recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL,
+ recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL,
+ recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recSPC[64])() = {
+ recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV,
+ recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL,
+ recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL,
+ recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL,
+ recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR ,
+ recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL
+};
+
+static void (*recREG[32])() = {
+ recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recCP0[32])() = {
+ recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recCP2[64])() = {
+ recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00
+ recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08
+ recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10
+ recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18
+ recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20
+ recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28
+ recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30
+ recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38
+};
+
+static void (*recCP2BSC[32])() = {
+ recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void recRecompile() {
+ char *p;
+ char *ptr;
+
+ dump = 0;
+ resp = 0;
+
+ /* if x86Ptr reached the mem limit reset whole mem */
+ if (((u32)x86Ptr - (u32)recMem) >= (RECMEM_SIZE - 0x10000))
+ recReset();
+
+ x86Align(32);
+ ptr = x86Ptr;
+
+ PC_REC32(psxRegs.pc) = (u32)x86Ptr;
+ pc = psxRegs.pc;
+ pcold = pc;
+
+ for (count = 0; count < 500;) {
+ p = (char *)PSXM(pc);
+ if (p == NULL) recError();
+ psxRegs.code = *(u32 *)p;
+/*
+ if ((psxRegs.code >> 26) == 0x23) { // LW
+ int i;
+ u32 code;
+
+ for (i=1;; i++) {
+ p = (char *)PSXM(pc+i*4);
+ if (p == NULL) recError();
+ code = *(u32 *)p;
+
+ if ((code >> 26) != 0x23 ||
+ _fRs_(code) != _Rs_ ||
+ _fImm_(code) != (_Imm_+i*4))
+ break;
+ }
+ if (i > 1) {
+ recLWBlock(i);
+ pc = pc + i*4; continue;
+ }
+ }
+
+ if ((psxRegs.code >> 26) == 0x2b) { // SW
+ int i;
+ u32 code;
+
+ for (i=1;; i++) {
+ p = (char *)PSXM(pc+i*4);
+ if (p == NULL) recError();
+ code = *(u32 *)p;
+
+ if ((code >> 26) != 0x2b ||
+ _fRs_(code) != _Rs_ ||
+ _fImm_(code) != (_Imm_+i*4))
+ break;
+ }
+ if (i > 1) {
+ recSWBlock(i);
+ pc = pc + i*4; continue;
+ }
+ }*/
+
+ pc += 4;
+ count++;
+ recBSC[psxRegs.code >> 26]();
+
+ if (branch) {
+ branch = 0;
+ if (dump) iDumpBlock(ptr);
+ return;
+ }
+ }
+
+ iFlushRegs();
+
+ MOV32ItoM((u32)&psxRegs.pc, pc);
+
+ iRet();
+}
+
+R3000Acpu psxRec = {
+ recInit,
+ recReset,
+ recExecute,
+ recExecuteBlock,
+ recClear,
+ recShutdown
+};
diff --git a/libpcsxcore/ix86/ix86.c b/libpcsxcore/ix86/ix86.c
new file mode 100644
index 00000000..63909be4
--- /dev/null
+++ b/libpcsxcore/ix86/ix86.c
@@ -0,0 +1,1759 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+ * ix86 core v0.5.1
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ */
+
+#include "ix86.h"
+
+void x86Init() {
+}
+
+void x86SetPtr(char *ptr) {
+ x86Ptr = ptr;
+}
+
+void x86Shutdown() {
+}
+
+void x86SetJ8(u8 *j8) {
+ u32 jump = (x86Ptr - (s8*)j8) - 1;
+
+ if (jump > 0x7f) printf("j8 greater than 0x7f!!\n");
+ *j8 = (u8)jump;
+}
+
+void x86SetJ32(u32 *j32) {
+ *j32 = (x86Ptr - (s8*)j32) - 4;
+}
+
+void x86Align(int bytes) {
+ // fordward align
+ x86Ptr = (s8*)(((u32)x86Ptr + bytes) & ~(bytes - 1));
+}
+
+#define SIB 4
+#define DISP32 5
+
+/* macros helpers */
+
+#define ModRM(mod, rm, reg) \
+ write8((mod << 6) | (rm << 3) | (reg));
+
+#define SibSB(ss, rm, index) \
+ write8((ss << 6) | (rm << 3) | (index));
+
+#define SET8R(cc, to) { \
+ write8(0x0F); write8(cc); \
+ write8((0xC0) | (to)); }
+
+#define J8Rel(cc, to) { \
+ write8(cc); write8(to); return x86Ptr - 1; }
+
+#define J32Rel(cc, to) { \
+ write8(0x0F); write8(cc); write32(to); return (u32*)(x86Ptr - 4); }
+
+#define CMOV32RtoR(cc, to, from) { \
+ write8(0x0F); write8(cc); \
+ ModRM(3, to, from); }
+
+#define CMOV32MtoR(cc, to, from) { \
+ write8(0x0F); write8(cc); \
+ ModRM(0, to, DISP32); \
+ write32(from); }
+
+/********************/
+/* IX86 intructions */
+/********************/
+
+// mov instructions
+
+/* mov r32 to r32 */
+void MOV32RtoR(int to, int from) {
+ write8(0x89);
+ ModRM(3, from, to);
+}
+
+/* mov r32 to m32 */
+void MOV32RtoM(u32 to, int from) {
+ write8(0x89);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* mov m32 to r32 */
+void MOV32MtoR(int to, u32 from) {
+ write8(0x8B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* mov [r32] to r32 */
+void MOV32RmtoR(int to, int from) {
+ write8(0x8B);
+ ModRM(0, to, from);
+}
+
+/* mov [r32][r32*scale] to r32 */
+void MOV32RmStoR(int to, int from, int from2, int scale) {
+ write8(0x8B);
+ ModRM(0, to, 0x4);
+ SibSB(scale, from2, from);
+}
+
+/* mov r32 to [r32] */
+void MOV32RtoRm(int to, int from) {
+ write8(0x89);
+ ModRM(0, from, to);
+}
+
+/* mov r32 to [r32][r32*scale] */
+void MOV32RtoRmS(int to, int to2, int scale, int from) {
+ write8(0x89);
+ ModRM(0, from, 0x4);
+ SibSB(scale, to2, to);
+}
+
+/* mov imm32 to r32 */
+void MOV32ItoR(int to, u32 from) {
+ write8(0xB8 | to);
+ write32(from);
+}
+
+/* mov imm32 to m32 */
+void MOV32ItoM(u32 to, u32 from) {
+ write8(0xC7);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* mov r16 to m16 */
+void MOV16RtoM(u32 to, int from) {
+ write8(0x66);
+ write8(0x89);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* mov m16 to r16 */
+void MOV16MtoR(int to, u32 from) {
+ write8(0x66);
+ write8(0x8B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* mov imm16 to m16 */
+void MOV16ItoM(u32 to, u16 from) {
+ write8(0x66);
+ write8(0xC7);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write16(from);
+}
+
+/* mov r8 to m8 */
+void MOV8RtoM(u32 to, int from) {
+ write8(0x88);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* mov m8 to r8 */
+void MOV8MtoR(int to, u32 from) {
+ write8(0x8A);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* mov imm8 to m8 */
+void MOV8ItoM(u32 to, u8 from) {
+ write8(0xC6);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write8(from);
+}
+
+/* movsx r8 to r32 */
+void MOVSX32R8toR(int to, int from) {
+ write16(0xBE0F);
+ ModRM(3, to, from);
+}
+
+/* movsx m8 to r32 */
+void MOVSX32M8toR(int to, u32 from) {
+ write16(0xBE0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movsx r16 to r32 */
+void MOVSX32R16toR(int to, int from) {
+ write16(0xBF0F);
+ ModRM(3, to, from);
+}
+
+/* movsx m16 to r32 */
+void MOVSX32M16toR(int to, u32 from) {
+ write16(0xBF0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movzx r8 to r32 */
+void MOVZX32R8toR(int to, int from) {
+ write16(0xB60F);
+ ModRM(3, to, from);
+}
+
+/* movzx m8 to r32 */
+void MOVZX32M8toR(int to, u32 from) {
+ write16(0xB60F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movzx r16 to r32 */
+void MOVZX32R16toR(int to, int from) {
+ write16(0xB70F);
+ ModRM(3, to, from);
+}
+
+/* movzx m16 to r32 */
+void MOVZX32M16toR(int to, u32 from) {
+ write16(0xB70F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* cmovne r32 to r32 */
+void CMOVNE32RtoR(int to, int from) {
+ CMOV32RtoR(0x45, to, from);
+}
+
+/* cmovne m32 to r32*/
+void CMOVNE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x45, to, from);
+}
+
+/* cmove r32 to r32*/
+void CMOVE32RtoR(int to, int from) {
+ CMOV32RtoR(0x44, to, from);
+}
+
+/* cmove m32 to r32*/
+void CMOVE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x44, to, from);
+}
+
+/* cmovg r32 to r32*/
+void CMOVG32RtoR(int to, int from) {
+ CMOV32RtoR(0x4F, to, from);
+}
+
+/* cmovg m32 to r32*/
+void CMOVG32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4F, to, from);
+}
+
+/* cmovge r32 to r32*/
+void CMOVGE32RtoR(int to, int from) {
+ CMOV32RtoR(0x4D, to, from);
+}
+
+/* cmovge m32 to r32*/
+void CMOVGE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4D, to, from);
+}
+
+/* cmovl r32 to r32*/
+void CMOVL32RtoR(int to, int from) {
+ CMOV32RtoR(0x4C, to, from);
+}
+
+/* cmovl m32 to r32*/
+void CMOVL32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4C, to, from);
+}
+
+/* cmovle r32 to r32*/
+void CMOVLE32RtoR(int to, int from) {
+ CMOV32RtoR(0x4E, to, from);
+}
+
+/* cmovle m32 to r32*/
+void CMOVLE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4E, to, from);
+}
+
+// arithmic instructions
+
+/* add imm32 to r32 */
+void ADD32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x05);
+ } else {
+ write8(0x81);
+ ModRM(3, 0, to);
+ }
+ write32(from);
+}
+
+/* add imm32 to m32 */
+void ADD32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* add r32 to r32 */
+void ADD32RtoR(int to, int from) {
+ write8(0x01);
+ ModRM(3, from, to);
+}
+
+/* add r32 to m32 */
+void ADD32RtoM(u32 to, int from) {
+ write8(0x01);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* add m32 to r32 */
+void ADD32MtoR(int to, u32 from) {
+ write8(0x03);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* adc imm32 to r32 */
+void ADC32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x15);
+ } else {
+ write8(0x81);
+ ModRM(3, 2, to);
+ }
+ write32(from);
+}
+
+/* adc r32 to r32 */
+void ADC32RtoR(int to, int from) {
+ write8(0x11);
+ ModRM(3, from, to);
+}
+
+/* adc m32 to r32 */
+void ADC32MtoR(int to, u32 from) {
+ write8(0x13);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* inc r32 */
+void INC32R(int to) {
+ write8(0x40 + to);
+}
+
+/* inc m32 */
+void INC32M(u32 to) {
+ write8(0xFF);
+ ModRM(0, 0, DISP32);
+ write32(to);
+}
+
+/* sub imm32 to r32 */
+void SUB32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x2D);
+ } else {
+ write8(0x81);
+ ModRM(3, 5, to);
+ }
+ write32(from);
+}
+
+/* sub r32 to r32 */
+void SUB32RtoR(int to, int from) {
+ write8(0x29);
+ ModRM(3, from, to);
+}
+
+/* sub m32 to r32 */
+void SUB32MtoR(int to, u32 from) {
+ write8(0x2B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* sbb imm32 to r32 */
+void SBB32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x1D);
+ } else {
+ write8(0x81);
+ ModRM(3, 3, to);
+ }
+ write32(from);
+}
+
+/* sbb r32 to r32 */
+void SBB32RtoR(int to, int from) {
+ write8(0x19);
+ ModRM(3, from, to);
+}
+
+/* sbb m32 to r32 */
+void SBB32MtoR(int to, u32 from) {
+ write8(0x1B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* dec r32 */
+void DEC32R(int to) {
+ write8(0x48 + to);
+}
+
+/* dec m32 */
+void DEC32M(u32 to) {
+ write8(0xFF);
+ ModRM(0, 1, DISP32);
+ write32(to);
+}
+
+/* mul eax by r32 to edx:eax */
+void MUL32R(int from) {
+ write8(0xF7);
+ ModRM(3, 4, from);
+}
+
+/* imul eax by r32 to edx:eax */
+void IMUL32R(int from) {
+ write8(0xF7);
+ ModRM(3, 5, from);
+}
+
+/* mul eax by m32 to edx:eax */
+void MUL32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 4, DISP32);
+ write32(from);
+}
+
+/* imul eax by m32 to edx:eax */
+void IMUL32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 5, DISP32);
+ write32(from);
+}
+
+/* imul r32 by r32 to r32 */
+void IMUL32RtoR(int to, int from) {
+ write16(0xAF0F);
+ ModRM(3, to, from);
+}
+
+/* div eax by r32 to edx:eax */
+void DIV32R(int from) {
+ write8(0xF7);
+ ModRM(3, 6, from);
+}
+
+/* idiv eax by r32 to edx:eax */
+void IDIV32R(int from) {
+ write8(0xF7);
+ ModRM(3, 7, from);
+}
+
+/* div eax by m32 to edx:eax */
+void DIV32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 6, DISP32);
+ write32(from);
+}
+
+/* idiv eax by m32 to edx:eax */
+void IDIV32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 7, DISP32);
+ write32(from);
+}
+
+// shifting instructions
+
+void RCR32ItoR(int to,int from)
+{
+ if (from==1)
+ {
+ write8(0xd1);
+ write8(0xd8 | to);
+ }
+ else
+ {
+ write8(0xc1);
+ write8(0xd8 | to);
+ write8(from);
+ }
+}
+
+/* shl imm8 to r32 */
+void SHL32ItoR(int to, u8 from) {
+ if (from==1)
+ {
+ write8(0xd1);
+ write8(0xe0 | to);
+ return;
+ }
+ write8(0xC1);
+ ModRM(3, 4, to);
+ write8(from);
+}
+
+/* shl cl to r32 */
+void SHL32CLtoR(int to) {
+ write8(0xD3);
+ ModRM(3, 4, to);
+}
+
+/* shr imm8 to r32 */
+void SHR32ItoR(int to, u8 from) {
+ if (from==1)
+ {
+ write8(0xd1);
+ write8(0xe8 | to);
+ return;
+ }
+ write8(0xC1);
+ ModRM(3, 5, to);
+ write8(from);
+}
+
+/* shr cl to r32 */
+void SHR32CLtoR(int to) {
+ write8(0xD3);
+ ModRM(3, 5, to);
+}
+
+/* sar imm8 to r32 */
+void SAR32ItoR(int to, u8 from) {
+ write8(0xC1);
+ ModRM(3, 7, to);
+ write8(from);
+}
+
+/* sar cl to r32 */
+void SAR32CLtoR(int to) {
+ write8(0xD3);
+ ModRM(3, 7, to);
+}
+
+
+// logical instructions
+
+/* or imm32 to r32 */
+void OR32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x0D);
+ } else {
+ write8(0x81);
+ ModRM(3, 1, to);
+ }
+ write32(from);
+}
+
+/* or imm32 to m32 */
+void OR32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 1, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* or r32 to r32 */
+void OR32RtoR(int to, int from) {
+ write8(0x09);
+ ModRM(3, from, to);
+}
+
+/* or r32 to m32 */
+void OR32RtoM(u32 to, int from) {
+ write8(0x09);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* or m32 to r32 */
+void OR32MtoR(int to, u32 from) {
+ write8(0x0B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* xor imm32 to r32 */
+void XOR32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x35);
+ } else {
+ write8(0x81);
+ ModRM(3, 6, to);
+ }
+ write32(from);
+}
+
+/* xor imm32 to m32 */
+void XOR32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 6, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* xor r32 to r32 */
+void XOR32RtoR(int to, int from) {
+ write8(0x31);
+ ModRM(3, from, to);
+}
+
+/* xor r32 to m32 */
+void XOR32RtoM(u32 to, int from) {
+ write8(0x31);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* xor m32 to r32 */
+void XOR32MtoR(int to, u32 from) {
+ write8(0x33);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* and imm32 to r32 */
+void AND32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x25);
+ } else {
+ write8(0x81);
+ ModRM(3, 0x4, to);
+ }
+ write32(from);
+}
+
+/* and imm32 to m32 */
+void AND32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 0x4, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* and r32 to r32 */
+void AND32RtoR(int to, int from) {
+ write8(0x21);
+ ModRM(3, from, to);
+}
+
+/* and r32 to m32 */
+void AND32RtoM(u32 to, int from) {
+ write8(0x21);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* and m32 to r32 */
+void AND32MtoR(int to, u32 from) {
+ write8(0x23);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* not r32 */
+void NOT32R(int from) {
+ write8(0xF7);
+ ModRM(3, 2, from);
+}
+
+/* neg r32 */
+void NEG32R(int from) {
+ write8(0xF7);
+ ModRM(3, 3, from);
+}
+
+// jump instructions
+
+/* jmp rel8 */
+u8* JMP8(u8 to) {
+ write8(0xEB);
+ write8(to);
+ return x86Ptr - 1;
+}
+
+/* jmp rel32 */
+u32* JMP32(u32 to) {
+ write8(0xE9);
+ write32(to);
+ return (u32*)(x86Ptr - 4);
+}
+
+/* jmp r32 */
+void JMP32R(int to) {
+ write8(0xFF);
+ ModRM(3, 4, to);
+}
+
+/* je rel8 */
+u8* JE8(u8 to) {
+ J8Rel(0x74, to);
+}
+
+/* jz rel8 */
+u8* JZ8(u8 to) {
+ J8Rel(0x74, to);
+}
+
+/* jg rel8 */
+u8* JG8(u8 to) {
+ J8Rel(0x7F, to);
+}
+
+/* jge rel8 */
+u8* JGE8(u8 to) {
+ J8Rel(0x7D, to);
+}
+
+/* jl rel8 */
+u8* JL8(u8 to) {
+ J8Rel(0x7C, to);
+}
+
+/* jle rel8 */
+u8* JLE8(u8 to) {
+ J8Rel(0x7E, to);
+}
+
+/* jne rel8 */
+u8* JNE8(u8 to) {
+ J8Rel(0x75, to);
+}
+
+/* jnz rel8 */
+u8* JNZ8(u8 to) {
+ J8Rel(0x75, to);
+}
+
+/* jng rel8 */
+u8* JNG8(u8 to) {
+ J8Rel(0x7E, to);
+}
+
+/* jnge rel8 */
+u8* JNGE8(u8 to) {
+ J8Rel(0x7C, to);
+}
+
+/* jnl rel8 */
+u8* JNL8(u8 to) {
+ J8Rel(0x7D, to);
+}
+
+/* jnle rel8 */
+u8* JNLE8(u8 to) {
+ J8Rel(0x7F, to);
+}
+
+/* jo rel8 */
+u8* JO8(u8 to) {
+ J8Rel(0x70, to);
+}
+
+/* jno rel8 */
+u8* JNO8(u8 to) {
+ J8Rel(0x71, to);
+}
+
+/* je rel32 */
+u32* JE32(u32 to) {
+ J32Rel(0x84, to);
+}
+
+/* jz rel32 */
+u32* JZ32(u32 to) {
+ J32Rel(0x84, to);
+}
+
+/* jg rel32 */
+u32* JG32(u32 to) {
+ J32Rel(0x8F, to);
+}
+
+/* jge rel32 */
+u32* JGE32(u32 to) {
+ J32Rel(0x8D, to);
+}
+
+/* jl rel32 */
+u32* JL32(u32 to) {
+ J32Rel(0x8C, to);
+}
+
+/* jle rel32 */
+u32* JLE32(u32 to) {
+ J32Rel(0x8E, to);
+}
+
+/* jne rel32 */
+u32* JNE32(u32 to) {
+ J32Rel(0x85, to);
+}
+
+/* jnz rel32 */
+u32* JNZ32(u32 to) {
+ J32Rel(0x85, to);
+}
+
+/* jng rel32 */
+u32* JNG32(u32 to) {
+ J32Rel(0x8E, to);
+}
+
+/* jnge rel32 */
+u32* JNGE32(u32 to) {
+ J32Rel(0x8C, to);
+}
+
+/* jnl rel32 */
+u32* JNL32(u32 to) {
+ J32Rel(0x8D, to);
+}
+
+/* jnle rel32 */
+u32* JNLE32(u32 to) {
+ J32Rel(0x8F, to);
+}
+
+/* jo rel32 */
+u32* JO32(u32 to) {
+ J32Rel(0x80, to);
+}
+
+/* jno rel32 */
+u32* JNO32(u32 to) {
+ J32Rel(0x81, to);
+}
+
+/* call func */
+void CALLFunc(u32 func) {
+ CALL32(func - ((u32)x86Ptr + 5));
+}
+
+/* call rel32 */
+void CALL32(u32 to) {
+ write8(0xE8);
+ write32(to);
+}
+
+/* call r32 */
+void CALL32R(int to) {
+ write8(0xFF);
+ ModRM(3, 2, to);
+}
+
+/* call m32 */
+void CALL32M(u32 to) {
+ write8(0xFF);
+ ModRM(0, 2, DISP32);
+ write32(to);
+}
+
+// misc instructions
+
+/* cmp imm32 to r32 */
+void CMP32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x3D);
+ } else {
+ write8(0x81);
+ ModRM(3, 7, to);
+ }
+ write32(from);
+}
+
+/* cmp imm32 to m32 */
+void CMP32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 7, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* cmp r32 to r32 */
+void CMP32RtoR(int to, int from) {
+ write8(0x39);
+ ModRM(3, from, to);
+}
+
+/* cmp m32 to r32 */
+void CMP32MtoR(int to, u32 from) {
+ write8(0x3B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* test imm32 to r32 */
+void TEST32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0xA9);
+ } else {
+ write8(0xF7);
+ ModRM(3, 0, to);
+ }
+ write32(from);
+}
+
+/* test r32 to r32 */
+void TEST32RtoR(int to, int from) {
+ write8(0x85);
+ ModRM(3, from, to);
+}
+
+void BT32ItoR(int to,int from)
+{
+ write16(0xba0f);
+ write8(0xe0 | to);
+ write8(from);
+}
+
+/* sets r8 */
+void SETS8R(int to) {
+ SET8R(0x98, to);
+}
+/* setl r8 */
+void SETL8R(int to) {
+ SET8R(0x9C, to);
+}
+
+/* setb r8 */
+void SETB8R(int to) {
+ SET8R(0x92, to);
+}
+
+/* setnz r8 */
+void SETNZ8R(int to) {
+ SET8R(0x95,to);
+}
+
+/* cbw */
+void CBW() {
+ write16(0x9866);
+}
+
+/* cwd */
+void CWD() {
+ write8(0x98);
+}
+
+/* cdq */
+void CDQ() {
+ write8(0x99);
+}
+
+/* push r32 */
+void PUSH32R(int from) {
+ write8(0x50 | from);
+}
+
+/* push m32 */
+void PUSH32M(u32 from) {
+ write8(0xFF);
+ ModRM(0, 6, DISP32);
+ write32(from);
+}
+
+/* push imm32 */
+void PUSH32I(u32 from) {
+ write8(0x68); write32(from);
+}
+
+/* pop r32 */
+void POP32R(int from) {
+ write8(0x58 | from);
+}
+
+/* pushad */
+void PUSHA32() {
+ write8(0x60);
+}
+
+/* popad */
+void POPA32() {
+ write8(0x61);
+}
+
+/* ret */
+void RET() {
+ write8(0xC3);
+}
+
+/********************/
+/* FPU instructions */
+/********************/
+
+//Added:basara 14.01.2003
+/* compare m32 to fpu reg stack */
+void FCOMP32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x3, DISP32);
+ write32(from);
+}
+
+void FNSTSWtoAX() {
+ write16(0xE0DF);
+}
+
+/* fild m32 to fpu reg stack */
+void FILD32(u32 from) {
+ write8(0xDB);
+ ModRM(0, 0x0, DISP32);
+ write32(from);
+}
+
+/* fistp m32 from fpu reg stack */
+void FISTP32(u32 from) {
+ write8(0xDB);
+ ModRM(0, 0x3, DISP32);
+ write32(from);
+}
+
+/* fld m32 to fpu reg stack */
+void FLD32(u32 from) {
+ write8(0xD9);
+ ModRM(0, 0x0, DISP32);
+ write32(from);
+}
+
+/* fstp m32 from fpu reg stack */
+void FSTP32(u32 to) {
+ write8(0xD9);
+ ModRM(0, 0x3, DISP32);
+ write32(to);
+}
+
+//
+
+/* fldcw fpu control word from m16 */
+void FLDCW(u32 from) {
+ write8(0xD9);
+ ModRM(0, 0x5, DISP32);
+ write32(from);
+}
+
+/* fnstcw fpu control word to m16 */
+void FNSTCW(u32 to) {
+ write8(0xD9);
+ ModRM(0, 0x7, DISP32);
+ write32(to);
+}
+
+//
+
+/* fadd m32 to fpu reg stack */
+void FADD32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x0, DISP32);
+ write32(from);
+}
+
+/* fsub m32 to fpu reg stack */
+void FSUB32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x4, DISP32);
+ write32(from);
+}
+
+/* fmul m32 to fpu reg stack */
+void FMUL32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x1, DISP32);
+ write32(from);
+}
+
+/* fdiv m32 to fpu reg stack */
+void FDIV32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x6, DISP32);
+ write32(from);
+}
+
+/* fabs fpu reg stack */
+void FABS() {
+ write16(0xE1D9);
+}
+
+/* fsqrt fpu reg stack */
+void FSQRT() {
+ write16(0xFAD9);
+}
+
+/* fchs fpu reg stack */
+void FCHS() {
+ write16(0xE0D9);
+}
+
+/********************/
+/* MMX instructions */
+/********************/
+
+// r64 = mm
+
+/* movq m64 to r64 */
+void MOVQMtoR(int to, u32 from) {
+ write16(0x6F0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movq r64 to m64 */
+void MOVQRtoM(u32 to, int from) {
+ write16(0x7F0F);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* pand r64 to r64 */
+void PANDRtoR(int to, int from) {
+ write16(0xDB0F);
+ ModRM(3, to, from);
+}
+
+/* pand r64 to r64 */
+void PANDNRtoR(int to, int from) {
+ write16(0xDF0F);
+ ModRM(3, to, from);
+}
+
+/* por r64 to r64 */
+void PORRtoR(int to, int from) {
+ write16(0xEB0F);
+ ModRM(3, to, from);
+}
+
+/* pxor r64 to r64 */
+void PXORRtoR(int to, int from) {
+ write16(0xEF0F);
+ ModRM(3, to, from);
+}
+
+/* psllq r64 to r64 */
+void PSLLQRtoR(int to, int from) {
+ write16(0xF30F);
+ ModRM(3, to, from);
+}
+
+/* psllq m64 to r64 */
+void PSLLQMtoR(int to, u32 from) {
+ write16(0xF30F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* psllq imm8 to r64 */
+void PSLLQItoR(int to, u8 from) {
+ write16(0x730F);
+ ModRM(3, 6, to);
+ write8(from);
+}
+
+/* psrlq r64 to r64 */
+void PSRLQRtoR(int to, int from) {
+ write16(0xD30F);
+ ModRM(3, to, from);
+}
+
+/* psrlq m64 to r64 */
+void PSRLQMtoR(int to, u32 from) {
+ write16(0xD30F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* psrlq imm8 to r64 */
+void PSRLQItoR(int to, u8 from) {
+ write16(0x730F);
+ ModRM(3, 2, to);
+ write8(from);
+}
+
+/* paddusb r64 to r64 */
+void PADDUSBRtoR(int to, int from) {
+ write16(0xDC0F);
+ ModRM(3, to, from);
+}
+
+/* paddusb m64 to r64 */
+void PADDUSBMtoR(int to, u32 from) {
+ write16(0xDC0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddusw r64 to r64 */
+void PADDUSWRtoR(int to, int from) {
+ write16(0xDD0F);
+ ModRM(3, to, from);
+}
+
+/* paddusw m64 to r64 */
+void PADDUSWMtoR(int to, u32 from) {
+ write16(0xDD0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddb r64 to r64 */
+void PADDBRtoR(int to, int from) {
+ write16(0xFC0F);
+ ModRM(3, to, from);
+}
+
+/* paddb m64 to r64 */
+void PADDBMtoR(int to, u32 from) {
+ write16(0xFC0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddw r64 to r64 */
+void PADDWRtoR(int to, int from) {
+ write16(0xFD0F);
+ ModRM(3, to, from);
+}
+
+/* paddw m64 to r64 */
+void PADDWMtoR(int to, u32 from) {
+ write16(0xFD0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddd r64 to r64 */
+void PADDDRtoR(int to, int from) {
+ write16(0xFE0F);
+ ModRM(3, to, from);
+}
+
+/* paddd m64 to r64 */
+void PADDDMtoR(int to, u32 from) {
+ write16(0xFE0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* emms */
+void EMMS() {
+ //use femms if we have 3dnow
+ write16(0x0e0f);
+ return;
+}
+
+/* femms */
+void FEMMS() {
+ write16(0x770F);
+ return;
+}
+
+//Basara:changed
+void PADDSBRtoR(int to, int from) {
+ write16(0xEC0F);
+ ModRM(3, to, from);
+}
+
+void PADDSWRtoR(int to, int from) {
+ write16(0xED0F);
+ ModRM(3, to, from);
+}
+
+void PADDSDRtoR(int to, int from) {
+ write16(0xEE0F);
+ ModRM(3, to, from);
+}
+
+void PSUBSBRtoR(int to, int from) {
+ write16(0xE80F);
+ ModRM(3, to, from);
+}
+
+void PSUBSWRtoR(int to, int from) {
+ write16(0xE90F);
+ ModRM(3, to, from);
+}
+
+void PSUBSDRtoR(int to, int from) {
+ write16(0xEA0F);
+ ModRM(3, to, from);
+}
+
+void PSUBBRtoR(int to, int from) {
+ write16(0xF80F);
+ ModRM(3, to, from);
+}
+
+void PSUBWRtoR(int to, int from) {
+ write16(0xF90F);
+ ModRM(3, to, from);
+}
+
+void PSUBDRtoR(int to, int from) {
+ write16(0xFA0F);
+ ModRM(3, to, from);
+}
+
+//changed:basara
+//P.s.It's sux.Don't use it offten.
+void MOVQ64ItoR(int reg,u64 i)
+{
+ MOVQMtoR(reg,(u32)(x86Ptr)+2+7);
+ JMP8(8);
+ write64(i);
+}
+
+void PSUBUSBRtoR(int to, int from) {
+ write16(0xD80F);
+ ModRM(3, to, from);
+}
+
+void PSUBUSWRtoR(int to, int from) {
+ write16(0xD90F);
+ ModRM(3, to, from);
+}
+
+void PMAXSWRtoR(int to,int from)
+{
+ write16(0xEE0F);
+ ModRM(3, to, from);
+}
+
+void PMINSWRtoR(int to,int from)
+{
+ write16(0xEA0F);
+ ModRM(3, to, from);
+}
+
+void PCMPEQBRtoR(int to,int from)
+{
+ write16(0x740F);
+ ModRM(3, to, from);
+}
+
+void PCMPEQWRtoR(int to,int from)
+{
+ write16(0x750F);
+ ModRM(3, to, from);
+}
+
+void PCMPEQDRtoR(int to,int from)
+{
+ write16(0x760F);
+ ModRM(3, to, from);
+}
+
+void PCMPGTBRtoR(int to,int from)
+{
+ write16(0x640F);
+ ModRM(3, to, from);
+}
+
+void PCMPGTWRtoR(int to,int from)
+{
+ write16(0x650F);
+ ModRM(3, to, from);
+}
+
+void PCMPGTDRtoR(int to,int from)
+{
+ write16(0x660F);
+ ModRM(3, to, from);
+}
+
+//Basara:Added 10.01.2003
+void PSRLWItoR(int to,int from)
+{
+ write16(0x710f);
+ ModRM(2, 2 , to);
+ write8(from);
+}
+void PSRLDItoR(int to,int from)
+{
+ write16(0x720f);
+ ModRM(2, 2 , to);
+ write8(from);
+}
+
+void PSLLWItoR(int to,int from)
+{
+ write16(0x710f);
+ ModRM(3, 6 , to);
+ write8(from);
+}
+
+void PSLLDItoR(int to,int from)
+{
+ write16(0x720f);
+ ModRM(3, 6 , to);
+ write8(from);
+}
+
+void PSRAWItoR(int to,int from)
+{
+ write16(0x710f);
+ ModRM(3, 4 , to);
+ write8(from);
+}
+
+void PSRADItoR(int to,int from)
+{
+ write16(0x720f);
+ ModRM(3, 4 , to);
+ write8(from);
+}
+
+/* por m64 to r64 */
+void PORMtoR(int to, u32 from) {
+ write16(0xEB0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* pxor m64 to r64 */
+void PXORMtoR(int to, u32 from) {
+ write16(0xEF0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* pand m64 to r64 */
+void PANDMtoR(int to, u32 from) {
+ write16(0xDB0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* pandn m64 to r64 */
+void PANDNMtoR(int to, u32 from) {
+ write16(0xDF0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movd m32 to r64 */
+void MOVDMtoR(int to, u32 from) {
+ write16(0x6E0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movq r64 to m32 */
+void MOVDRtoM(u32 to, int from) {
+ write16(0x7E0F);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* movd r32 to r64 */
+void MOVD32RtoR(int to, int from) {
+ write16(0x6E0F);
+ ModRM(3, to,from);
+}
+
+/* movq r64 to r32 */
+void MOVD64RtoR(int to, int from) {
+ write16(0x7E0F);
+ ModRM(3, from,to);
+}
+
+void MOVQRtoR(int to,int from)
+{
+ write16(0x6F0F);
+ ModRM(3, to,from);
+}
+
+void PUNPCKHDQRtoR(int to,int from)
+{
+ write16(0x6A0F);
+ ModRM(3, to,from);
+}
+
+void PUNPCKLDQRtoR(int to,int from)
+{
+ write16(0x620F);
+ ModRM(3, to,from);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SSE intructions
+//////////////////////////////////////////////////////////////////////////
+
+void MOVAPSMtoR(int to,int from)
+{
+ write16(0x280f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void MOVAPSRtoM(int to,int from)
+{
+ write16(0x2b0f);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+void MOVAPSRtoR(int to,int from)
+{
+ write16(0x290f);
+ ModRM(3, to,from);
+}
+
+void ORPSMtoR(int to,int from)
+{
+ write16(0x560f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void ORPSRtoR(int to,int from)
+{
+ write16(0x560f);
+ ModRM(3, to,from);
+}
+
+void XORPSMtoR(int to,int from)
+{
+ write16(0x570f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void XORPSRtoR(int to,int from)
+{
+ write16(0x570f);
+ ModRM(3, to,from);
+}
+
+void ANDPSMtoR(int to,int from)
+{
+ write16(0x540f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void ANDPSRtoR(int to,int from)
+{
+ write16(0x540f);
+ ModRM(3, to,from);
+}
+
+/*
+ 3DNOW intructions
+*/
+
+void PFCMPEQMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xb0);
+}
+
+void PFCMPGTMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xa0);
+}
+
+void PFCMPGEMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x90);
+}
+
+
+void PFADDMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x9e);
+}
+
+void PFADDRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x9e);
+}
+
+
+void PFSUBMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x9a);
+}
+
+void PFSUBRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x9a);
+}
+
+
+void PFMULMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xb4);
+}
+
+void PFMULRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xb4);
+}
+
+void PFRCPMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x96);
+}
+
+void PFRCPRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0x96);
+}
+
+void PFRCPIT1RtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xa6);
+}
+
+void PFRCPIT2RtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xb6);
+}
+
+void PFRSQRTRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0x97);
+}
+
+void PFRSQIT1RtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xa7);
+}
+
+void PF2IDMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x1d);
+}
+
+void PF2IDRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x1d);
+}
+
+void PI2FDMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x0d);
+}
+
+void PI2FDRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x0d);
+}
+
+
+/*
+ 3DNOW Extension intructions
+*/
+
+void PFMAXMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xa4);
+}
+
+void PFMAXRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0xa4);
+}
+
+void PFMINMtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x94);
+}
+
+void PFMINRtoR(int to,int from)
+{
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x94);
+}
diff --git a/libpcsxcore/ix86/ix86.h b/libpcsxcore/ix86/ix86.h
new file mode 100644
index 00000000..8a5550ee
--- /dev/null
+++ b/libpcsxcore/ix86/ix86.h
@@ -0,0 +1,667 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+ * ix86 definitions v0.5.1
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ */
+
+#ifndef __IX86_H__
+#define __IX86_H__
+
+// include basic types
+#include "../psxcommon.h"
+#include "../r3000a.h"
+#include "../psxhle.h"
+
+// x86Flags defines
+#define X86FLAG_FPU 0x00000001
+#define X86FLAG_VME 0x00000002
+#define X86FLAG_DEBUGEXT 0x00000004
+#define X86FLAG_4MPAGE 0x00000008
+#define X86FLAG_TSC 0x00000010
+#define X86FLAG_MSR 0x00000020
+#define X86FLAG_PAE 0x00000040
+#define X86FLAG_MCHKXCP 0x00000080
+#define X86FLAG_CMPXCHG8B 0x00000100
+#define X86FLAG_APIC 0x00000200
+#define X86FLAG_SYSENTER 0x00000800
+#define X86FLAG_MTRR 0x00001000
+#define X86FLAG_GPE 0x00002000
+#define X86FLAG_MCHKARCH 0x00004000
+#define X86FLAG_CMOV 0x00008000
+#define X86FLAG_PAT 0x00010000
+#define X86FLAG_PSE36 0x00020000
+#define X86FLAG_PN 0x00040000
+#define X86FLAG_MMX 0x00800000
+#define X86FLAG_FXSAVE 0x01000000
+#define X86FLAG_SSE 0x02000000
+
+// x86EFlags defines
+
+#define X86EFLAG_MMXEXT 0x00400000
+#define X86EFLAG_3DNOWEXT 0x40000000
+#define X86EFLAG_3DNOW 0x80000000
+
+/* general defines */
+#define write8(val) *(u8 *)x86Ptr = val; x86Ptr++;
+#define write16(val) *(u16*)x86Ptr = val; x86Ptr+=2;
+#define write32(val) *(u32*)x86Ptr = val; x86Ptr+=4;
+#define write64(val) *(u64*)x86Ptr = val; x86Ptr+=8;
+
+#define EAX 0
+#define EBX 3
+#define ECX 1
+#define EDX 2
+#define ESI 6
+#define EDI 7
+#define EBP 5
+#define ESP 4
+
+#define MM0 0
+#define MM1 1
+#define MM2 2
+#define MM3 3
+#define MM4 4
+#define MM5 5
+#define MM6 6
+#define MM7 7
+
+#define XMM0 0
+#define XMM1 1
+#define XMM2 2
+#define XMM3 3
+#define XMM4 4
+#define XMM5 5
+#define XMM6 6
+#define XMM7 7
+
+s8 *x86Ptr;
+u8 *j8Ptr[32];
+u32 *j32Ptr[32];
+
+void x86Init();
+void x86SetPtr(char *ptr);
+void x86Shutdown();
+
+void x86SetJ8(u8 *j8);
+void x86SetJ32(u32 *j32);
+void x86Align(int bytes);
+
+
+/********************/
+/* IX86 intructions */
+/********************/
+
+/*
+ * scale values:
+ * 0 - *1
+ * 1 - *2
+ * 2 - *4
+ * 3 - *8
+ */
+
+////////////////////////////////////
+// mov instructions /
+////////////////////////////////////
+
+/* mov r32 to r32 */
+void MOV32RtoR(int to, int from);
+/* mov r32 to m32 */
+void MOV32RtoM(u32 to, int from);
+/* mov m32 to r32 */
+void MOV32MtoR(int to, u32 from);
+/* mov [r32] to r32 */
+void MOV32RmtoR(int to, int from);
+/* mov [r32][r32*scale] to r32 */
+void MOV32RmStoR(int to, int from, int from2, int scale);
+/* mov r32 to [r32] */
+void MOV32RtoRm(int to, int from);
+/* mov r32 to [r32][r32*scale] */
+void MOV32RtoRmS(int to, int to2, int scale, int from);
+/* mov imm32 to r32 */
+void MOV32ItoR(int to, u32 from);
+/* mov imm32 to m32 */
+void MOV32ItoM(u32 to, u32 from);
+
+/* mov r16 to m16 */
+void MOV16RtoM(u32 to, int from);
+/* mov m16 to r16 */
+void MOV16MtoR(int to, u32 from);
+/* mov imm16 to m16 */
+void MOV16ItoM(u32 to, u16 from);
+
+/* mov r8 to m8 */
+void MOV8RtoM(u32 to, int from);
+/* mov m8 to r8 */
+void MOV8MtoR(int to, u32 from);
+/* mov imm8 to m8 */
+void MOV8ItoM(u32 to, u8 from);
+
+/* movsx r8 to r32 */
+void MOVSX32R8toR(int to, int from);
+/* movsx m8 to r32 */
+void MOVSX32M8toR(int to, u32 from);
+/* movsx r16 to r32 */
+void MOVSX32R16toR(int to, int from);
+/* movsx m16 to r32 */
+void MOVSX32M16toR(int to, u32 from);
+
+/* movzx r8 to r32 */
+void MOVZX32R8toR(int to, int from);
+/* movzx m8 to r32 */
+void MOVZX32M8toR(int to, u32 from);
+/* movzx r16 to r32 */
+void MOVZX32R16toR(int to, int from);
+/* movzx m16 to r32 */
+void MOVZX32M16toR(int to, u32 from);
+
+/* cmovne r32 to r32 */
+void CMOVNE32RtoR(int to, int from);
+/* cmovne m32 to r32*/
+void CMOVNE32MtoR(int to, u32 from);
+/* cmove r32 to r32*/
+void CMOVE32RtoR(int to, int from);
+/* cmove m32 to r32*/
+void CMOVE32MtoR(int to, u32 from);
+/* cmovg r32 to r32*/
+void CMOVG32RtoR(int to, int from);
+/* cmovg m32 to r32*/
+void CMOVG32MtoR(int to, u32 from);
+/* cmovge r32 to r32*/
+void CMOVGE32RtoR(int to, int from);
+/* cmovge m32 to r32*/
+void CMOVGE32MtoR(int to, u32 from);
+/* cmovl r32 to r32*/
+void CMOVL32RtoR(int to, int from);
+/* cmovl m32 to r32*/
+void CMOVL32MtoR(int to, u32 from);
+/* cmovle r32 to r32*/
+void CMOVLE32RtoR(int to, int from);
+/* cmovle m32 to r32*/
+void CMOVLE32MtoR(int to, u32 from);
+
+////////////////////////////////////
+// arithmetic instructions /
+////////////////////////////////////
+
+/* add imm32 to r32 */
+void ADD32ItoR(int to, u32 from);
+/* add imm32 to m32 */
+void ADD32ItoM(u32 to, u32 from);
+/* add r32 to r32 */
+void ADD32RtoR(int to, int from);
+/* add r32 to m32 */
+void ADD32RtoM(u32 to, int from);
+/* add m32 to r32 */
+void ADD32MtoR(int to, u32 from);
+
+/* adc imm32 to r32 */
+void ADC32ItoR(int to, u32 from);
+/* adc r32 to r32 */
+void ADC32RtoR(int to, int from);
+/* adc m32 to r32 */
+void ADC32MtoR(int to, u32 from);
+
+/* inc r32 */
+void INC32R(int to);
+/* inc m32 */
+void INC32M(u32 to);
+
+/* sub imm32 to r32 */
+void SUB32ItoR(int to, u32 from);
+/* sub r32 to r32 */
+void SUB32RtoR(int to, int from);
+/* sub m32 to r32 */
+void SUB32MtoR(int to, u32 from);
+
+/* sbb imm32 to r32 */
+void SBB32ItoR(int to, u32 from);
+/* sbb r32 to r32 */
+void SBB32RtoR(int to, int from);
+/* sbb m32 to r32 */
+void SBB32MtoR(int to, u32 from);
+
+/* dec r32 */
+void DEC32R(int to);
+/* dec m32 */
+void DEC32M(u32 to);
+
+/* mul eax by r32 to edx:eax */
+void MUL32R(int from);
+/* mul eax by m32 to edx:eax */
+void MUL32M(u32 from);
+
+/* imul eax by r32 to edx:eax */
+void IMUL32R(int from);
+/* imul eax by m32 to edx:eax */
+void IMUL32M(u32 from);
+/* imul r32 by r32 to r32 */
+void IMUL32RtoR(int to, int from);
+
+/* div eax by r32 to edx:eax */
+void DIV32R(int from);
+/* div eax by m32 to edx:eax */
+void DIV32M(u32 from);
+
+/* idiv eax by r32 to edx:eax */
+void IDIV32R(int from);
+/* idiv eax by m32 to edx:eax */
+void IDIV32M(u32 from);
+
+////////////////////////////////////
+// shifting instructions /
+////////////////////////////////////
+
+/* shl imm8 to r32 */
+void SHL32ItoR(int to, u8 from);
+/* shl cl to r32 */
+void SHL32CLtoR(int to);
+
+/* shr imm8 to r32 */
+void SHR32ItoR(int to, u8 from);
+/* shr cl to r32 */
+void SHR32CLtoR(int to);
+
+/* sar imm8 to r32 */
+void SAR32ItoR(int to, u8 from);
+/* sar cl to r32 */
+void SAR32CLtoR(int to);
+
+/* sal imm8 to r32 */
+#define SAL32ItoR SHL32ItoR
+/* sal cl to r32 */
+#define SAL32CLtoR SHL32CLtoR
+
+// logical instructions
+
+/* or imm32 to r32 */
+void OR32ItoR(int to, u32 from);
+/* or imm32 to m32 */
+void OR32ItoM(u32 to, u32 from);
+/* or r32 to r32 */
+void OR32RtoR(int to, int from);
+/* or r32 to m32 */
+void OR32RtoM(u32 to, int from);
+/* or m32 to r32 */
+void OR32MtoR(int to, u32 from);
+
+/* xor imm32 to r32 */
+void XOR32ItoR(int to, u32 from);
+/* xor imm32 to m32 */
+void XOR32ItoM(u32 to, u32 from);
+/* xor r32 to r32 */
+void XOR32RtoR(int to, int from);
+/* xor r32 to m32 */
+void XOR32RtoM(u32 to, int from);
+/* xor m32 to r32 */
+void XOR32MtoR(int to, u32 from);
+
+/* and imm32 to r32 */
+void AND32ItoR(int to, u32 from);
+/* and imm32 to m32 */
+void AND32ItoM(u32 to, u32 from);
+/* and r32 to r32 */
+void AND32RtoR(int to, int from);
+/* and r32 to m32 */
+void AND32RtoM(u32 to, int from);
+/* and m32 to r32 */
+void AND32MtoR(int to, u32 from);
+
+/* not r32 */
+void NOT32R(int from);
+/* neg r32 */
+void NEG32R(int from);
+
+////////////////////////////////////
+// jump instructions /
+////////////////////////////////////
+
+/* jmp rel8 */
+u8* JMP8(u8 to);
+
+/* jmp rel32 */
+u32* JMP32(u32 to);
+/* jmp r32 */
+void JMP32R(int to);
+
+/* je rel8 */
+u8* JE8(u8 to);
+/* jz rel8 */
+u8* JZ8(u8 to);
+/* jg rel8 */
+u8* JG8(u8 to);
+/* jge rel8 */
+u8* JGE8(u8 to);
+/* jl rel8 */
+u8* JL8(u8 to);
+/* jle rel8 */
+u8* JLE8(u8 to);
+/* jne rel8 */
+u8* JNE8(u8 to);
+/* jnz rel8 */
+u8* JNZ8(u8 to);
+/* jng rel8 */
+u8* JNG8(u8 to);
+/* jnge rel8 */
+u8* JNGE8(u8 to);
+/* jnl rel8 */
+u8* JNL8(u8 to);
+/* jnle rel8 */
+u8* JNLE8(u8 to);
+/* jo rel8 */
+u8* JO8(u8 to);
+/* jno rel8 */
+u8* JNO8(u8 to);
+
+/* je rel32 */
+u32* JE32(u32 to);
+/* jz rel32 */
+u32* JZ32(u32 to);
+/* jg rel32 */
+u32* JG32(u32 to);
+/* jge rel32 */
+u32* JGE32(u32 to);
+/* jl rel32 */
+u32* JL32(u32 to);
+/* jle rel32 */
+u32* JLE32(u32 to);
+/* jne rel32 */
+u32* JNE32(u32 to);
+/* jnz rel32 */
+u32* JNZ32(u32 to);
+/* jng rel32 */
+u32* JNG32(u32 to);
+/* jnge rel32 */
+u32* JNGE32(u32 to);
+/* jnl rel32 */
+u32* JNL32(u32 to);
+/* jnle rel32 */
+u32* JNLE32(u32 to);
+/* jo rel32 */
+u32* JO32(u32 to);
+/* jno rel32 */
+u32* JNO32(u32 to);
+
+/* call func */
+void CALLFunc(u32 func); // based on CALL32
+/* call rel32 */
+void CALL32(u32 to);
+/* call r32 */
+void CALL32R(int to);
+/* call m32 */
+void CALL32M(u32 to);
+
+////////////////////////////////////
+// misc instructions /
+////////////////////////////////////
+
+/* cmp imm32 to r32 */
+void CMP32ItoR(int to, u32 from);
+/* cmp imm32 to m32 */
+void CMP32ItoM(u32 to, u32 from);
+/* cmp r32 to r32 */
+void CMP32RtoR(int to, int from);
+/* cmp m32 to r32 */
+void CMP32MtoR(int to, u32 from);
+
+/* test imm32 to r32 */
+void TEST32ItoR(int to, u32 from);
+/* test r32 to r32 */
+void TEST32RtoR(int to, int from);
+/* sets r8 */
+void SETS8R(int to);
+/* setl r8 */
+void SETL8R(int to);
+/* setb r8 */
+void SETB8R(int to);
+
+/* cbw */
+void CBW();
+/* cwd */
+void CWD();
+/* cdq */
+void CDQ();
+
+/* push r32 */
+void PUSH32R(int from);
+/* push m32 */
+void PUSH32M(u32 from);
+/* push imm32 */
+void PUSH32I(u32 from);
+
+/* pop r32 */
+void POP32R(int from);
+
+/* pushad */
+void PUSHA32();
+/* popad */
+void POPA32();
+
+/* ret */
+void RET();
+
+/********************/
+/* FPU instructions */
+/********************/
+
+/* fild m32 to fpu reg stack */
+void FILD32(u32 from);
+/* fistp m32 from fpu reg stack */
+void FISTP32(u32 from);
+/* fld m32 to fpu reg stack */
+void FLD32(u32 from);
+/* fstp m32 from fpu reg stack */
+void FSTP32(u32 to);
+
+/* fldcw fpu control word from m16 */
+void FLDCW(u32 from);
+/* fstcw fpu control word to m16 */
+void FNSTCW(u32 to);
+
+/* fadd m32 to fpu reg stack */
+void FADD32(u32 from);
+/* fsub m32 to fpu reg stack */
+void FSUB32(u32 from);
+/* fmul m32 to fpu reg stack */
+void FMUL32(u32 from);
+/* fdiv m32 to fpu reg stack */
+void FDIV32(u32 from);
+/* fabs fpu reg stack */
+void FABS();
+/* fsqrt fpu reg stack */
+void FSQRT();
+/* fchs fpu reg stack */
+void FCHS();
+
+/********************/
+/* MMX instructions */
+/********************/
+
+// r64 = mm
+
+/* movq m64 to r64 */
+void MOVQMtoR(int to, u32 from);
+/* movq r64 to m64 */
+void MOVQRtoM(u32 to, int from);
+
+/* pand r64 to r64 */
+void PANDRtoR(int to, int from);
+/* pand m64 to r64 */
+void PANDMtoR(int to, u32 from);
+
+/* pandn r64 to r64 */
+void PANDNRtoR(int to, int from);
+
+/* pandn r64 to r64 */
+void PANDNMtoR(int to, u32 from);
+
+/* por r64 to r64 */
+void PORRtoR(int to, int from);
+/* por m64 to r64 */
+void PORMtoR(int to, u32 from);
+
+/* pxor r64 to r64 */
+void PXORRtoR(int to, int from);
+/* pxor m64 to r64 */
+void PXORMtoR(int to, u32 from);
+
+/* psllq r64 to r64 */
+void PSLLQRtoR(int to, int from);
+/* psllq m64 to r64 */
+void PSLLQMtoR(int to, u32 from);
+/* psllq imm8 to r64 */
+void PSLLQItoR(int to, u8 from);
+
+/* psrlq r64 to r64 */
+void PSRLQRtoR(int to, int from);
+/* psrlq m64 to r64 */
+void PSRLQMtoR(int to, u32 from);
+/* psrlq imm8 to r64 */
+void PSRLQItoR(int to, u8 from);
+
+/* paddusb r64 to r64 */
+void PADDUSBRtoR(int to, int from);
+/* paddusb m64 to r64 */
+void PADDUSBMtoR(int to, u32 from);
+/* paddusw r64 to r64 */
+void PADDUSWRtoR(int to, int from);
+/* paddusw m64 to r64 */
+void PADDUSWMtoR(int to, u32 from);
+
+/* paddb r64 to r64 */
+void PADDBRtoR(int to, int from);
+/* paddb m64 to r64 */
+void PADDBMtoR(int to, u32 from);
+/* paddw r64 to r64 */
+void PADDWRtoR(int to, int from);
+/* paddw m64 to r64 */
+void PADDWMtoR(int to, u32 from);
+/* paddd r64 to r64 */
+void PADDDRtoR(int to, int from);
+/* paddd m64 to r64 */
+void PADDDMtoR(int to, u32 from);
+
+/* emms */
+void EMMS();
+void FEMMS();
+void BT32ItoR(int to,int from);
+void RCR32ItoR(int to,int from);
+
+//Basara:changed
+void PADDSBRtoR(int to, int from);
+void PADDSWRtoR(int to, int from);
+void PADDSDRtoR(int to, int from);
+void PSUBSBRtoR(int to, int from);
+void PSUBSWRtoR(int to, int from);
+void PSUBSDRtoR(int to, int from);
+
+void PSUBBRtoR(int to, int from);
+void PSUBWRtoR(int to, int from);
+void PSUBDRtoR(int to, int from);
+
+void MOVQ64ItoR(int reg,u64 i); //Prototype.Todo add all consts to end of block.not after jr $+8
+
+void PMAXSWRtoR(int to,int from);
+void PMINSWRtoR(int to,int from);
+
+void PCMPEQBRtoR(int to,int from);
+void PCMPEQWRtoR(int to,int from);
+void PCMPEQDRtoR(int to,int from);
+
+void PCMPGTBRtoR(int to,int from);
+void PCMPGTWRtoR(int to,int from);
+void PCMPGTDRtoR(int to,int from);
+
+void PSRLWItoR(int to,int from);
+void PSRLDItoR(int to,int from);
+void PSLLWItoR(int to,int from);
+void PSLLDItoR(int to,int from);
+void PSRAWItoR(int to,int from);
+void PSRADItoR(int to,int from);
+
+//Added:basara 11.01.2003
+void FCOMP32(u32 from);
+void FNSTSWtoAX();
+void SETNZ8R(int to);
+
+//Added:basara 14.01.2003
+void PFCMPEQMtoR(int to,int from);
+void PFCMPGTMtoR(int to,int from);
+void PFCMPGEMtoR(int to,int from);
+
+void PFADDMtoR(int to,int from);
+void PFADDRtoR(int to,int from);
+
+void PFSUBMtoR(int to,int from);
+void PFSUBRtoR(int to,int from);
+
+void PFMULMtoR(int to,int from);
+void PFMULRtoR(int to,int from);
+
+void PFRCPMtoR(int to,int from);
+void PFRCPRtoR(int to,int from);
+void PFRCPIT1RtoR(int to,int from);
+void PFRCPIT2RtoR(int to,int from);
+
+void PFRSQRTRtoR(int to,int from);
+void PFRSQIT1RtoR(int to,int from);
+
+void PF2IDMtoR(int to,int from);
+void PF2IDRtoR(int to,int from);
+void PI2FDMtoR(int to,int from);
+void PI2FDRtoR(int to,int from);
+
+void PFMAXMtoR(int to,int from);
+void PFMAXRtoR(int to,int from);
+void PFMINMtoR(int to,int from);
+void PFMINRtoR(int to,int from);
+
+void MOVDMtoR(int to, u32 from);
+void MOVDRtoM(u32 to, int from);
+void MOVD32RtoR(int to, int from);
+void MOVD64RtoR(int to, int from);
+
+void MOVQRtoR(int to,int from);
+
+//if to==from MMLO=MMHI
+void PUNPCKHDQRtoR(int to,int from);
+
+//if to==from MMHI=MMLO
+void PUNPCKLDQRtoR(int to,int from);
+
+/*
+ SSE intructions
+*/
+void MOVAPSMtoR(int to,int from);
+void MOVAPSRtoM(int to,int from);
+void MOVAPSRtoR(int to,int from);
+
+void ORPSMtoR(int to,int from);
+void ORPSRtoR(int to,int from);
+
+void XORPSMtoR(int to,int from);
+void XORPSRtoR(int to,int from);
+
+void ANDPSMtoR(int to,int from);
+void ANDPSRtoR(int to,int from);
+
+#endif /* __IX86_H__ */
diff --git a/libpcsxcore/ix86_64/README b/libpcsxcore/ix86_64/README
new file mode 100644
index 00000000..23a798bf
--- /dev/null
+++ b/libpcsxcore/ix86_64/README
@@ -0,0 +1,4 @@
+This is the AMD64 dynamic recompiler.
+Made from opcodes from PCSX2 0.9.3 and the x86 recompiler modified to fit. ie. currently no AMD64/SSE specific code advantages.
+
+Note that this recompiler currently requires all variables, data heaps, function pointers, etc to be within a 4 Gig range of each other. While this is currently the case through luck and dirty hacks, a proper fix should be implemented.
diff --git a/libpcsxcore/ix86_64/iGte.h b/libpcsxcore/ix86_64/iGte.h
new file mode 100644
index 00000000..07f55542
--- /dev/null
+++ b/libpcsxcore/ix86_64/iGte.h
@@ -0,0 +1,672 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __IGTE_H__
+#define __IGTE_H__
+
+#include "../r3000a.h"
+#include "../psxmem.h"
+
+#define CP2_FUNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code); \
+ CALLFunc((uptr)gte##f); \
+/* branch = 2; */\
+}
+
+#define CP2_FUNCNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ CALLFunc((uptr)gte##f); \
+/* branch = 2; */\
+}
+
+
+#if 0
+CP2_FUNC(MFC2);
+CP2_FUNC(MTC2);
+CP2_FUNC(CFC2);
+CP2_FUNC(CTC2);
+CP2_FUNC(LWC2);
+CP2_FUNC(SWC2);
+#endif
+
+#if 1
+void gteMFC2();
+static void recMFC2() {
+// Rt = Cop2D->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+
+ switch (_Rd_) {
+ case 29:
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc((uptr)gteMFC2);
+ break;
+
+ default:
+ MOV32MtoR(EAX, (uptr)&psxRegs.CP2D.r[_Rd_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ break;
+ }
+}
+
+void gteMTC2();
+static void recMTC2() {
+// Cop2D->Rd = Rt
+ int fixt = 0;
+
+// iFlushRegs();
+
+ switch (_Rd_) {
+ case 8: case 9: case 10: case 11:
+ fixt = 1; break;
+
+ case 16: case 17: case 18: case 19:
+ fixt = 2; break;
+
+ case 15:
+ case 28:
+ case 30:
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc((uptr)gteMTC2);
+ break;
+ }
+
+ if (IsConst(_Rt_)) {
+ if (fixt == 1) MOV32ItoM((uptr)&psxRegs.CP2D.r[_Rd_], (s16)iRegs[_Rt_].k);
+ else if (fixt == 2) MOV32ItoM((uptr)&psxRegs.CP2D.r[_Rd_], iRegs[_Rt_].k & 0xffff);
+ else MOV32ItoM((uptr)&psxRegs.CP2D.r[_Rd_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((uptr)&psxRegs.CP2D.r[_Rd_], EAX);
+ }
+}
+
+void gteLWC2();
+static void recLWC2() {
+// Cop2D->Rt = mem[Rs + Im] (unsigned)
+ int fixt = 0;
+
+ switch (_Rt_) {
+ case 8: case 9: case 10: case 11:
+ fixt = 1; break;
+
+ case 16: case 17: case 18: case 19:
+ fixt = 2; break;
+
+ case 15:
+ case 28:
+ case 30:
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc((uptr)gteLWC2);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((uptr)&psxRegs.CP2D.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xfff]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((uptr)&psxRegs.CP2D.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ //iPushOfB();
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemRead32);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((uptr)&psxRegs.CP2D.r[_Rt_], EAX);
+// ADD32ItoR(ESP, 4);
+ //resp+= 4;
+}
+
+void gteSWC2();
+static void recSWC2() {
+// mem[Rs + Im] = Rt
+
+ switch (_Rt_) {
+ case 29:
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc((uptr)gteSWC2);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (uptr)&psxRegs.CP2D.r[_Rt_]);
+ MOV32RtoM((uptr)&psxM[addr & 0x1fffff], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (uptr)&psxRegs.CP2D.r[_Rt_]);
+ MOV32RtoM((uptr)&psxH[addr & 0xfff], EAX);
+ return;
+ }
+ }
+
+ //PUSH64M ((uptr)&psxRegs.CP2D.r[_Rt_]);
+ MOV32MtoR(X86ARG2, (uptr)&psxRegs.CP2D.r[_Rt_]);
+ //iPushOfB();
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ //resp+= 8;
+}
+
+static void recCFC2() {
+// Rt = Cop2C->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32MtoR(EAX, (uptr)&psxRegs.CP2C.r[_Rd_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+}
+
+static void recCTC2() {
+// Cop2C->Rd = Rt
+
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((uptr)&psxRegs.CP2C.r[_Rd_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.CP2C.r[_Rd_], EAX);
+ }
+}
+
+#endif
+
+CP2_FUNCNC(RTPS);
+CP2_FUNC(OP);
+CP2_FUNCNC(NCLIP);
+CP2_FUNCNC(DPCS);
+CP2_FUNCNC(INTPL);
+CP2_FUNC(MVMVA);
+CP2_FUNCNC(NCDS);
+CP2_FUNCNC(NCDT);
+CP2_FUNCNC(CDP);
+CP2_FUNCNC(NCCS);
+CP2_FUNCNC(CC);
+CP2_FUNCNC(NCS);
+CP2_FUNCNC(NCT);
+CP2_FUNC(SQR);
+CP2_FUNCNC(DCPL);
+CP2_FUNCNC(DPCT);
+CP2_FUNCNC(AVSZ3);
+CP2_FUNCNC(AVSZ4);
+CP2_FUNCNC(RTPT);
+CP2_FUNC(GPF);
+CP2_FUNC(GPL);
+CP2_FUNCNC(NCCT);
+
+#if 0
+
+#define gteVX0 ((s16*)psxRegs.CP2D.r)[0]
+#define gteVY0 ((s16*)psxRegs.CP2D.r)[1]
+#define gteVZ0 ((s16*)psxRegs.CP2D.r)[2]
+#define gteVX1 ((s16*)psxRegs.CP2D.r)[4]
+#define gteVY1 ((s16*)psxRegs.CP2D.r)[5]
+#define gteVZ1 ((s16*)psxRegs.CP2D.r)[6]
+#define gteVX2 ((s16*)psxRegs.CP2D.r)[8]
+#define gteVY2 ((s16*)psxRegs.CP2D.r)[9]
+#define gteVZ2 ((s16*)psxRegs.CP2D.r)[10]
+#define gteRGB psxRegs.CP2D.r[6]
+#define gteOTZ ((s16*)psxRegs.CP2D.r)[7*2]
+#define gteIR0 ((s32*)psxRegs.CP2D.r)[8]
+#define gteIR1 ((s32*)psxRegs.CP2D.r)[9]
+#define gteIR2 ((s32*)psxRegs.CP2D.r)[10]
+#define gteIR3 ((s32*)psxRegs.CP2D.r)[11]
+#define gteSX0 ((s16*)psxRegs.CP2D.r)[12*2]
+#define gteSY0 ((s16*)psxRegs.CP2D.r)[12*2+1]
+#define gteSX1 ((s16*)psxRegs.CP2D.r)[13*2]
+#define gteSY1 ((s16*)psxRegs.CP2D.r)[13*2+1]
+#define gteSX2 ((s16*)psxRegs.CP2D.r)[14*2]
+#define gteSY2 ((s16*)psxRegs.CP2D.r)[14*2+1]
+#define gteSXP ((s16*)psxRegs.CP2D.r)[15*2]
+#define gteSYP ((s16*)psxRegs.CP2D.r)[15*2+1]
+#define gteSZx ((u16*)psxRegs.CP2D.r)[16*2]
+#define gteSZ0 ((u16*)psxRegs.CP2D.r)[17*2]
+#define gteSZ1 ((u16*)psxRegs.CP2D.r)[18*2]
+#define gteSZ2 ((u16*)psxRegs.CP2D.r)[19*2]
+#define gteRGB0 psxRegs.CP2D.r[20]
+#define gteRGB1 psxRegs.CP2D.r[21]
+#define gteRGB2 psxRegs.CP2D.r[22]
+#define gteMAC0 psxRegs.CP2D.r[24]
+#define gteMAC1 ((s32*)psxRegs.CP2D.r)[25]
+#define gteMAC2 ((s32*)psxRegs.CP2D.r)[26]
+#define gteMAC3 ((s32*)psxRegs.CP2D.r)[27]
+#define gteIRGB psxRegs.CP2D.r[28]
+#define gteORGB psxRegs.CP2D.r[29]
+#define gteLZCS psxRegs.CP2D.r[30]
+#define gteLZCR psxRegs.CP2D.r[31]
+
+#define gteR ((u8 *)psxRegs.CP2D.r)[6*4]
+#define gteG ((u8 *)psxRegs.CP2D.r)[6*4+1]
+#define gteB ((u8 *)psxRegs.CP2D.r)[6*4+2]
+#define gteCODE ((u8 *)psxRegs.CP2D.r)[6*4+3]
+#define gteC gteCODE
+
+#define gteR0 ((u8 *)psxRegs.CP2D.r)[20*4]
+#define gteG0 ((u8 *)psxRegs.CP2D.r)[20*4+1]
+#define gteB0 ((u8 *)psxRegs.CP2D.r)[20*4+2]
+#define gteCODE0 ((u8 *)psxRegs.CP2D.r)[20*4+3]
+#define gteC0 gteCODE0
+
+#define gteR1 ((u8 *)psxRegs.CP2D.r)[21*4]
+#define gteG1 ((u8 *)psxRegs.CP2D.r)[21*4+1]
+#define gteB1 ((u8 *)psxRegs.CP2D.r)[21*4+2]
+#define gteCODE1 ((u8 *)psxRegs.CP2D.r)[21*4+3]
+#define gteC1 gteCODE1
+
+#define gteR2 ((u8 *)psxRegs.CP2D.r)[22*4]
+#define gteG2 ((u8 *)psxRegs.CP2D.r)[22*4+1]
+#define gteB2 ((u8 *)psxRegs.CP2D.r)[22*4+2]
+#define gteCODE2 ((u8 *)psxRegs.CP2D.r)[22*4+3]
+#define gteC2 gteCODE2
+
+
+
+#define gteR11 ((s16*)psxRegs.CP2C.r)[0]
+#define gteR12 ((s16*)psxRegs.CP2C.r)[1]
+#define gteR13 ((s16*)psxRegs.CP2C.r)[2]
+#define gteR21 ((s16*)psxRegs.CP2C.r)[3]
+#define gteR22 ((s16*)psxRegs.CP2C.r)[4]
+#define gteR23 ((s16*)psxRegs.CP2C.r)[5]
+#define gteR31 ((s16*)psxRegs.CP2C.r)[6]
+#define gteR32 ((s16*)psxRegs.CP2C.r)[7]
+#define gteR33 ((s16*)psxRegs.CP2C.r)[8]
+#define gteTRX ((s32*)psxRegs.CP2C.r)[5]
+#define gteTRY ((s32*)psxRegs.CP2C.r)[6]
+#define gteTRZ ((s32*)psxRegs.CP2C.r)[7]
+#define gteL11 ((s16*)psxRegs.CP2C.r)[16]
+#define gteL12 ((s16*)psxRegs.CP2C.r)[17]
+#define gteL13 ((s16*)psxRegs.CP2C.r)[18]
+#define gteL21 ((s16*)psxRegs.CP2C.r)[19]
+#define gteL22 ((s16*)psxRegs.CP2C.r)[20]
+#define gteL23 ((s16*)psxRegs.CP2C.r)[21]
+#define gteL31 ((s16*)psxRegs.CP2C.r)[22]
+#define gteL32 ((s16*)psxRegs.CP2C.r)[23]
+#define gteL33 ((s16*)psxRegs.CP2C.r)[24]
+#define gteRBK ((s32*)psxRegs.CP2C.r)[13]
+#define gteGBK ((s32*)psxRegs.CP2C.r)[14]
+#define gteBBK ((s32*)psxRegs.CP2C.r)[15]
+#define gteLR1 ((s16*)psxRegs.CP2C.r)[32]
+#define gteLR2 ((s16*)psxRegs.CP2C.r)[33]
+#define gteLR3 ((s16*)psxRegs.CP2C.r)[34]
+#define gteLG1 ((s16*)psxRegs.CP2C.r)[35]
+#define gteLG2 ((s16*)psxRegs.CP2C.r)[36]
+#define gteLG3 ((s16*)psxRegs.CP2C.r)[37]
+#define gteLB1 ((s16*)psxRegs.CP2C.r)[38]
+#define gteLB2 ((s16*)psxRegs.CP2C.r)[39]
+#define gteLB3 ((s16*)psxRegs.CP2C.r)[40]
+#define gteRFC ((s32*)psxRegs.CP2C.r)[21]
+#define gteGFC ((s32*)psxRegs.CP2C.r)[22]
+#define gteBFC ((s32*)psxRegs.CP2C.r)[23]
+#define gteOFX ((s32*)psxRegs.CP2C.r)[24]
+#define gteOFY ((s32*)psxRegs.CP2C.r)[25]
+#define gteH ((u16*)psxRegs.CP2C.r)[52]
+#define gteDQA ((s16*)psxRegs.CP2C.r)[54]
+#define gteDQB ((s32*)psxRegs.CP2C.r)[28]
+#define gteZSF3 ((s16*)psxRegs.CP2C.r)[58]
+#define gteZSF4 ((s16*)psxRegs.CP2C.r)[60]
+#define gteFLAG psxRegs.CP2C.r[31]
+
+//#define SUM_FLAG if(gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000;
+
+#define SUM_FLAG() { \
+ TEST32ItoM((uptr)&gteFLAG, 0x7F87E000); \
+ j8Ptr[0] = JZ8(0); \
+ OR32ItoM((uptr)&gteFLAG, 0x80000000); \
+ \
+ x86SetJ8(j8Ptr[0]); \
+}
+
+#define LIM32X8(reg, gteout, negv, posv, flagb) { \
+ CMP32ItoR(reg, negv); \
+ j8Ptr[0] = JL8(0); \
+ CMP32ItoR(reg, posv); \
+ j8Ptr[1] = JG8(0); \
+ \
+ MOV8RtoM((uptr)&gteout, reg); \
+ j8Ptr[2] = JMP8(0); \
+ \
+ x86SetJ8(j8Ptr[0]); \
+ MOV8ItoM((uptr)&gteout, negv); \
+ j8Ptr[3] = JMP8(0); \
+ \
+ x86SetJ8(j8Ptr[1]); \
+ MOV8ItoM((uptr)&gteout, posv); \
+ \
+ x86SetJ8(j8Ptr[3]); \
+ OR32ItoM((uptr)&gteFLAG, 1<<flagb); \
+ \
+ x86SetJ8(j8Ptr[2]); \
+}
+
+#define _LIM_B1(reg, gteout) LIM32X8(reg, gteout, 0, 255, 21);
+#define _LIM_B2(reg, gteout) LIM32X8(reg, gteout, 0, 255, 20);
+#define _LIM_B3(reg, gteout) LIM32X8(reg, gteout, 0, 255, 19);
+
+#define MAC2IRn(reg, ir, flagb, negv, posv) { \
+/* CMP32ItoR(reg, negv);*/ \
+/* j8Ptr[0] = JL8(0); */\
+/* CMP32ItoR(reg, posv);*/ \
+/* j8Ptr[1] = JG8(0);*/ \
+ \
+ MOV32RtoM((uptr)&ir, reg); \
+/* j8Ptr[2] = JMP8(0);*/ \
+ \
+/* x86SetJ8(j8Ptr[0]);*/ \
+/* MOV32ItoM((uptr)&ir, negv);*/ \
+/* j8Ptr[3] = JMP8(0);*/ \
+ \
+/* x86SetJ8(j8Ptr[1]);*/ \
+/* MOV32ItoM((uptr)&ir, posv);*/ \
+ \
+/* x86SetJ8(j8Ptr[3]);*/ \
+/* OR32ItoR((uptr)&gteFLAG, 1<<flagb);*/ \
+ \
+/* x86SetJ8(j8Ptr[2]);*/ \
+}
+
+
+
+#define gte_C11 gteLR1
+#define gte_C12 gteLR2
+#define gte_C13 gteLR3
+#define gte_C21 gteLG1
+#define gte_C22 gteLG2
+#define gte_C23 gteLG3
+#define gte_C31 gteLB1
+#define gte_C32 gteLB2
+#define gte_C33 gteLB3
+
+
+#define _MVMVA_FUNC(vn, mx) { \
+ MOVSX32M16toR(EAX, (uptr)&mx##vn##1); \
+ IMUL32R(EBX); \
+/* j8Ptr[0] = JO8(0);*/ \
+ MOV32RtoR(ECX, EAX); \
+ \
+ MOVSX32M16toR(EAX, (uptr)&mx##vn##2); \
+ IMUL32R(EDI); \
+/* j8Ptr[1] = JO8(0);*/ \
+ ADD32RtoR(ECX, EAX); \
+/* j8Ptr[2] = JO8(0);*/ \
+ \
+ MOVSX32M16toR(EAX, (uptr)&mx##vn##3); \
+ IMUL32R(ESI); \
+/* j8Ptr[3] = JO8(0);*/ \
+ ADD32RtoR(ECX, EAX); \
+/* j8Ptr[4] = JO8(0);*/ \
+}
+
+/* SSX = (_v0) * mx##11 + (_v1) * mx##12 + (_v2) * mx##13;
+ SSY = (_v0) * mx##21 + (_v1) * mx##22 + (_v2) * mx##23;
+ SSZ = (_v0) * mx##31 + (_v1) * mx##32 + (_v2) * mx##33; */
+
+#define _MVMVA_ADD(_vx, jn) { \
+ ADD32MtoR(ECX, (uptr)&_vx); \
+/* j8Ptr[jn] = JO8(0);*/ \
+}
+/* SSX+= gteRFC;
+ SSY+= gteGFC;
+ SSZ+= gteBFC;*/
+
+#define _MVMVA1(vn) { \
+ switch (psxRegs.code & 0x60000) { \
+ case 0x00000: /* R */ \
+ _MVMVA_FUNC(vn, gteR); break; \
+ case 0x20000: /* L */ \
+ _MVMVA_FUNC(vn, gteL); break; \
+ case 0x40000: /* C */ \
+ _MVMVA_FUNC(vn, gte_C); break; \
+ default: \
+ return; \
+ } \
+}
+
+#define _MVMVA_LOAD(_v0, _v1, _v2) { \
+ MOVSX32M16toR(EBX, (uptr)&_v0); \
+ MOVSX32M16toR(EDI, (uptr)&_v1); \
+ MOVSX32M16toR(ESI, (uptr)&_v2); \
+}
+
+static void recMVMVA() {
+ int i;
+
+// SysPrintf("GTE_MVMVA %lx\n", psxRegs.code & 0x1ffffff);
+
+/* PUSH32R(ESI);
+ PUSH32R(EDI);
+ PUSH32R(EBX);
+*/
+ XOR32RtoR(EAX, EAX); /* gteFLAG = 0 */
+ MOV32RtoM((uptr)&gteFLAG, EAX);
+
+ switch (psxRegs.code & 0x18000) {
+ case 0x00000: /* V0 */
+ _MVMVA_LOAD(gteVX0, gteVY0, gteVZ0); break;
+ case 0x08000: /* V1 */
+ _MVMVA_LOAD(gteVX1, gteVY1, gteVZ1); break;
+ case 0x10000: /* V2 */
+ _MVMVA_LOAD(gteVX2, gteVY2, gteVZ2); break;
+ case 0x18000: /* IR */
+ _MVMVA_LOAD(gteIR1, gteIR2, gteIR3); break;
+ }
+
+// MAC1
+ for (i=5; i<8; i++) j8Ptr[i] = 0;
+ _MVMVA1(1);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRX, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteRBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteRFC, 7); break;
+ }
+/*
+ j8Ptr[9] = JMP8(0);
+ for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);
+
+// TEST32ItoR(EDX, 0x80000000);
+ OR32ItoM((uptr)&gteFLAG, 1<<29);
+ x86SetJ8(j8Ptr[9]);*/
+ MOV32RtoM((uptr)&gteMAC1, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR1, 24, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR1, 24, -32768, 32767);
+ }
+
+// MAC2
+ _MVMVA1(2);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRY, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteGBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteGFC, 7); break;
+ }
+
+/* for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);*/
+ MOV32RtoM((uptr)&gteMAC2, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR2, 23, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR2, 23, -32768, 32767);
+ }
+
+// MAC3
+ _MVMVA1(3);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRZ, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteBBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteBFC, 7); break;
+ }
+
+/* for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);*/
+ MOV32RtoM((uptr)&gteMAC3, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR3, 22, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR3, 22, -32768, 32767);
+ }
+/* MAC2IR1()
+ else MAC2IR()*/
+
+// SUM_FLAG();
+
+/* POP32R(EBX);
+ POP32R(EDI);
+ POP32R(ESI);*/
+}
+
+#if 0
+
+#define _GPF1(vn) { \
+ MOV32MtoR(EAX, (uptr)&gteIR##vn); \
+ IMUL32R(ECX); \
+/* MOV32RtoR(ECX, EAX); */\
+}
+
+static void recGPF() {
+// SysPrintf("GTE_GPF %lx\n", psxRegs.code & 0x1ffffff);
+
+ PUSH32R(EBX);
+
+ XOR32RtoR(EBX, EBX); /* gteFLAG = 0 */
+
+/* gteMAC1 = NC_OVERFLOW1(gteIR0 * gteIR1);
+ gteMAC2 = NC_OVERFLOW2(gteIR0 * gteIR2);
+ gteMAC3 = NC_OVERFLOW3(gteIR0 * gteIR3);*/
+ MOV32MtoR(ECX, (uptr)&gteIR0);
+// MAC1
+ _GPF1(1);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR1, 24, -32768, 32767);
+ PUSH32R(EAX);
+
+// MAC2
+ _GPF1(2);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR2, 23, -32768, 32767);
+ PUSH32R(EAX);
+
+// MAC3
+ _GPF1(3);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR3, 22, -32768, 32767);
+// MAC2IR();
+
+// gteRGB0 = gteRGB1;
+// gteRGB1 = gteRGB2;
+ MOV32MtoR(EDX, (uptr)&gteRGB1);
+ MOV32MtoR(ECX, (uptr)&gteRGB2);
+ MOV32RtoM((uptr)&gteRGB0, EDX);
+ MOV32RtoM((uptr)&gteRGB1, ECX);
+
+ POP32R(EDX);
+ POP32R(ECX);
+ SAR32ItoR(ECX, 4);
+ SAR32ItoR(EDX, 4);
+ SAR32ItoR(EAX, 4);
+
+ _LIM_B1(ECX, gteR2);
+ _LIM_B2(EDX, gteG2);
+ _LIM_B3(EAX, gteB2);
+ MOV8MtoR(EAX, (uptr)&gteCODE);
+ MOV8RtoM((uptr)&gteCODE2, EAX);
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+
+ SUM_FLAG();
+ MOV32RtoM((uptr)&gteFLAG, EBX);
+
+// POP32R(EBX);
+}
+#endif
+#endif
+
+
+#endif /* __IGTE_H__ */
diff --git a/libpcsxcore/ix86_64/iR3000A-64.c b/libpcsxcore/ix86_64/iR3000A-64.c
new file mode 100644
index 00000000..326ee938
--- /dev/null
+++ b/libpcsxcore/ix86_64/iR3000A-64.c
@@ -0,0 +1,2966 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* i386 assembly functions for R3000A core.
+*/
+
+#include "ix86-64.h"
+#include "../r3000a.h"
+#include "../psxhle.h"
+
+#include <sys/mman.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+uptr* psxRecLUT;
+
+#define PTRMULT (sizeof(uptr)/sizeof(u32))
+
+#undef PC_REC
+#undef PC_REC8
+#undef PC_REC16
+#undef PC_REC32
+#define PC_REC(x) (psxRecLUT[(x) >> 16] + PTRMULT*((x) & 0xffff))
+#define PC_RECP(x) (*(uptr*)PC_REC(x))
+
+#define RECMEM_SIZE (PTRMULT*8*1024*1024)
+
+static char *recMem; /* the recompiled blocks will be here */
+static char *recRAM; /* and the ptr to the blocks here */
+static char *recROM; /* and here */
+
+static u32 pc; /* recompiler pc */
+static u32 pcold; /* recompiler oldpc */
+static int count; /* recompiler intruction count */
+static int branch; /* set for branch */
+static u32 target; /* branch target */
+static u32 resp;
+
+typedef struct {
+ int state;
+ u32 k;
+ int reg;
+} iRegisters;
+
+static iRegisters iRegs[32];
+static iRegisters iRegsS[32];
+
+#define ST_UNK 0
+#define ST_CONST 1
+#define ST_MAPPED 2
+
+#define IsConst(reg) (iRegs[reg].state == ST_CONST)
+#define IsMapped(reg) (iRegs[reg].state == ST_MAPPED)
+
+static void (*recBSC[64])();
+static void (*recSPC[64])();
+static void (*recREG[32])();
+static void (*recCP0[32])();
+static void (*recCP2[64])();
+static void (*recCP2BSC[32])();
+
+#define STACKSIZE 0x18
+static void StackRes()
+{
+#ifdef __x86_64__
+ ADD64ItoR(RSP, STACKSIZE);
+#else
+ if (resp) ADD32ItoR(ESP, resp);
+#endif
+}
+
+static void MapConst(int reg, u32 _const) {
+ iRegs[reg].k = _const;
+ iRegs[reg].state = ST_CONST;
+}
+
+static void iFlushReg(int reg) {
+ if (IsConst(reg)) {
+ MOV32ItoM((uptr)&psxRegs.GPR.r[reg], iRegs[reg].k);
+ }
+ iRegs[reg].state = ST_UNK;
+}
+
+static void iFlushRegs() {
+ int i;
+
+ for (i=1; i<32; i++) {
+ iFlushReg(i);
+ }
+}
+
+static void iRet() {
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((uptr)&psxRegs.cycle, count);
+ StackRes();
+ RET();
+}
+
+static int iLoadTest() {
+ u32 tmp;
+
+ // check for load delay
+ tmp = psxRegs.code >> 26;
+ switch (tmp) {
+ case 0x10: // COP0
+ switch (_Rs_) {
+ case 0x00: // MFC0
+ case 0x02: // CFC0
+ return 1;
+ }
+ break;
+ case 0x12: // COP2
+ switch (_Funct_) {
+ case 0x00:
+ switch (_Rs_) {
+ case 0x00: // MFC2
+ case 0x02: // CFC2
+ return 1;
+ }
+ break;
+ }
+ break;
+ case 0x32: // LWC2
+ return 1;
+ default:
+ if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+/* set a pending branch */
+static void SetBranch() {
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc+=4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((uptr)&psxRegs.cycle, count);
+
+ //PUSH64M((uptr)&target);
+ MOV32MtoR(X86ARG2, (uptr)&target);
+ //PUSHI(_Rt_);
+ MOV64ItoR(X86ARG1, _Rt_);
+ CALLFunc((uptr)psxDelayTest);
+ StackRes();
+ RET();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32MtoR(EAX, (uptr)&target);
+ MOV32RtoM((uptr)&psxRegs.pc, EAX);
+ CALLFunc((uptr)psxBranchTest);
+
+ iRet();
+}
+
+static void iJump(u32 branchPC) {
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc+=4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((uptr)&psxRegs.cycle, count);
+
+ //PUSHI(branchPC);
+ MOV64ItoR(X86ARG2, branchPC);
+ //PUSHI(_Rt_);
+ MOV64ItoR(X86ARG1, _Rt_);
+ CALLFunc((uptr)psxDelayTest);
+ //ADD32ItoR(ESP, 2*8);
+ StackRes();
+ RET();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.pc, branchPC);
+ CALLFunc((uptr)psxBranchTest);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((uptr)&psxRegs.cycle, count);
+ StackRes();
+
+ RET();
+ //* XXX?
+ // maybe just happened an interruption, check so
+ CMP32ItoM((uptr)&psxRegs.pc, branchPC);
+ j8Ptr[0] = JE8(0);
+
+ RET();
+
+ x86SetJ8(j8Ptr[0]);
+ MOV64MtoR(RAX, PC_REC(branchPC));
+ TEST64RtoR(RAX,RAX);
+ j8Ptr[1] = JNE8(0);
+
+ RET();
+
+ x86SetJ8(j8Ptr[1]);
+
+ RET();
+ //JMP32R(EAX);
+ JMPR(EAX);
+ //*/
+}
+
+static void iBranch(u32 branchPC, int savectx) {
+ u32 respold=0;
+
+ if (savectx) {
+ respold = resp;
+ memcpy(iRegsS, iRegs, sizeof(iRegs));
+ }
+
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+
+ // the delay test is only made when the branch is taken
+ // savectx == 0 will mean that :)
+ if (savectx == 0 && iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = ((pc+4) - pcold)/4;
+ ADD32ItoM((uptr)&psxRegs.cycle, count);
+ //if (resp) ADD32ItoR(ESP, resp);
+
+ //PUSHI(branchPC);
+ MOV64ItoR(X86ARG2, branchPC);
+ //PUSHI(_Rt_);
+ MOV64ItoR(X86ARG1,_Rt_);
+ CALLFunc((uptr)psxDelayTest);
+ StackRes();
+ RET();
+ return;
+ }
+
+ pc+= 4;
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.pc, branchPC);
+ CALLFunc((uptr)psxBranchTest);
+ /* store cycle */
+ count = (pc - pcold)/4;
+ ADD32ItoM((uptr)&psxRegs.cycle, count);
+
+ StackRes();
+
+ // maybe just happened an interruption, check so
+ CMP32ItoM((uptr)&psxRegs.pc, branchPC);
+ j8Ptr[1] = JE8(0);
+
+ RET();
+
+ x86SetJ8(j8Ptr[1]);
+ MOV64MtoR(RAX, PC_REC(branchPC));
+ TEST64RtoR(RAX, RAX);
+ j8Ptr[2] = JNE8(0);
+
+ RET();
+
+ x86SetJ8(j8Ptr[2]);
+ //JMP32R(EAX);
+ JMPR(EAX);
+
+ pc-= 4;
+ if (savectx) {
+ resp = respold;
+ memcpy(iRegs, iRegsS, sizeof(iRegs));
+ }
+}
+
+
+char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
+char *txt1 = "EAX = %x\n";
+char *txt2 = "M32 = %x\n";
+
+/*
+void iLogX86() {
+ PUSHA32();
+
+ PUSH32R (EDX);
+ PUSH32R (ECX);
+ PUSH32R (EAX);
+ PUSH32M ((uptr)&txt0);
+ CALLFunc((uptr)SysPrintf);
+ ADD32ItoR(ESP, 4*4);
+
+ POPA32();
+}
+*/
+
+void iLogEAX() {
+ PUSH64R (EAX);
+ PUSH64M ((uptr)&txt1);
+ CALLFunc((uptr)SysPrintf);
+ ADD32ItoR(ESP, 8*2);
+}
+
+void iLogM32(u32 mem) {
+ PUSH64M (mem);
+ PUSH64M ((uptr)&txt2);
+ CALLFunc((uptr)SysPrintf);
+ ADD32ItoR(ESP, 8*2);
+}
+
+static void iDumpRegs() {
+ int i, j;
+
+ printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle);
+ for (i=0; i<4; i++) {
+ for (j=0; j<8; j++)
+ printf("%lx ", psxRegs.GPR.r[j*i]);
+ printf("\n");
+ }
+}
+
+void iDumpBlock(char *ptr) {
+ FILE *f;
+ u32 i;
+
+ SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxRegs.cycle);
+
+ for (i = psxRegs.pc; i < pc; i+=4)
+ SysPrintf("%s\n", disR3000AF(PSXMu32(i), i));
+
+ fflush(stdout);
+ f = fopen("dump1", "w");
+ fwrite(ptr, 1, (uptr)x86Ptr - (uptr)ptr, f);
+ fclose(f);
+ //system("ndisasm -b64 dump1");
+ fflush(stdout);
+}
+
+#define REC_FUNC(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((uptr)&psxRegs.pc, (u32)pc); \
+ CALLFunc((uptr)psx##f); \
+/* branch = 2; */\
+}
+
+#define REC_SYS(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((uptr)&psxRegs.pc, (u32)pc); \
+ CALLFunc((uptr)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+#define REC_BRANCH(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((uptr)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((uptr)&psxRegs.pc, (u32)pc); \
+ CALLFunc((uptr)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+static void recRecompile();
+
+static int recInit() {
+ int i;
+
+ psxRecLUT = (uptr*) malloc(0x010000 * sizeof(uptr));
+
+ recMem = mmap(0,
+ RECMEM_SIZE + PTRMULT*0x1000,
+ PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ recRAM = mmap(0,
+ 0x280000*PTRMULT,
+ PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ //recRAM = (uptr*) malloc(0x200000 * sizeof(void*));
+ //recROM = (uptr*) malloc(0x080000 * sizeof(void*));
+ recROM = &recRAM[0x200000*PTRMULT];
+
+ if (recRAM == NULL || recROM == NULL || recMem == NULL || psxRecLUT == NULL) {
+ SysMessage("Error allocating memory"); return -1;
+ }
+ memset(recMem, 0, RECMEM_SIZE);
+ memset(recRAM, 0, 0x200000 * PTRMULT);
+ memset(recROM, 0, 0x080000 * PTRMULT);
+
+ for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = (uptr)&recRAM[PTRMULT*((i & 0x1f) << 16)];
+ memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * sizeof(uptr));
+ memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * sizeof(uptr));
+
+ for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = (uptr)&recROM[PTRMULT*(i << 16)];
+
+ return 0;
+}
+
+static void recReset() {
+ memset(recRAM, 0, 0x200000 * PTRMULT);
+ memset(recROM, 0, 0x080000 * PTRMULT);
+
+ //x86Init();
+ cpudetectInit();
+ x86SetPtr(recMem);
+
+ branch = 0;
+ memset(iRegs, 0, sizeof(iRegs));
+ iRegs[0].state = ST_CONST;
+ iRegs[0].k = 0;
+}
+
+static void recShutdown() {
+ if (recMem == NULL) return;
+ free(psxRecLUT);
+ //free(recMem);
+ munmap(recMem, RECMEM_SIZE + PTRMULT*0x1000);
+ //free(recRAM);
+ munmap(recRAM, 0x280000*PTRMULT);
+ //free(recROM);
+ x86Shutdown();
+}
+
+static void recError() {
+ SysReset();
+ ClosePlugins();
+ SysMessage("Unrecoverable error while running recompiler\n");
+ SysRunGui();
+}
+
+/*__inline*/ static void execute() {
+ void (*recFunc)();
+ uptr *p;
+
+ p = (uptr *)PC_REC(psxRegs.pc);
+ // if (!p) { recError(); return; }
+
+ if (*p == 0) {
+ recRecompile();
+ }
+
+ if (*p < (uptr)recMem || *p >= (uptr)recMem + RECMEM_SIZE)
+ {
+ recError();
+ return;
+ }
+ recFunc = (void (*)())*p;
+ (*recFunc)();
+}
+
+static void recExecute() {
+ for (;;) execute();
+}
+
+static void recExecuteBlock() {
+ execute();
+}
+
+static void recClear(u32 Addr, u32 Size) {
+ memset((void*)PC_REC(Addr), 0, Size * sizeof(uptr));
+}
+
+static void recNULL() {
+// SysMessage("recUNK: %8.8x\n", psxRegs.code);
+}
+
+/*********************************************************
+* goes to opcodes tables... *
+* Format: table[something....] *
+*********************************************************/
+
+//REC_SYS(SPECIAL);
+#if 1
+static void recSPECIAL() {
+ recSPC[_Funct_]();
+}
+#endif
+
+static void recREGIMM() {
+ recREG[_Rt_]();
+}
+
+static void recCOP0() {
+ recCP0[_Rs_]();
+}
+
+//REC_SYS(COP2);
+#if 1
+static void recCOP2() {
+ recCP2[_Funct_]();
+}
+#endif
+
+static void recBASIC() {
+ recCP2BSC[_Rs_]();
+}
+
+//end of Tables opcodes...
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+
+#if 0
+REC_FUNC(ADDI);
+REC_FUNC(ADDIU);
+REC_FUNC(ANDI);
+REC_FUNC(ORI);
+REC_FUNC(XORI);
+REC_FUNC(SLTI);
+REC_FUNC(SLTIU);
+#endif
+
+#if 1
+static void recADDIU() {
+// Rt = Rs + Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k+= _Imm_;
+ } else {
+ if (_Imm_ == 1) {
+ INC32M((uptr)&psxRegs.GPR.r[_Rt_]);
+ } else if (_Imm_ == -1) {
+ DEC32M((uptr)&psxRegs.GPR.r[_Rt_]);
+ } else if (_Imm_) {
+ ADD32ItoM((uptr)&psxRegs.GPR.r[_Rt_], _Imm_);
+ }
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k + _Imm_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_ == 1) {
+ INC32R(EAX);
+ } else if (_Imm_ == -1) {
+ DEC32R(EAX);
+ } else if (_Imm_) {
+ ADD32ItoR(EAX, _Imm_);
+ }
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recADDI() {
+// Rt = Rs + Im
+ recADDIU();
+}
+
+static void recSLTI() {
+// Rt = Rs < Im (signed)
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, _Imm_);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+}
+
+static void recSLTIU() {
+// Rt = Rs < Im (unsigned)
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, _Imm_);
+ SETB8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+}
+
+static void recANDI() {
+// Rt = Rs And Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k&= _ImmU_;
+ } else {
+ AND32ItoM((uptr)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ AND32ItoR(EAX, _ImmU_);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recORI() {
+// Rt = Rs Or Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k|= _ImmU_;
+ } else {
+ OR32ItoM((uptr)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_ImmU_) OR32ItoR (EAX, _ImmU_);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recXORI() {
+// Rt = Rs Xor Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k^= _ImmU_;
+ } else {
+ XOR32ItoM((uptr)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ XOR32ItoR(EAX, _ImmU_);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+#endif
+//end of * Arithmetic with immediate operand
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+//REC_FUNC(LUI);
+#if 1
+static void recLUI() {
+// Rt = Imm << 16
+ if (!_Rt_) return;
+
+ MapConst(_Rt_, psxRegs.code << 16);
+}
+#endif
+//End of Load Higher .....
+
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+
+
+#if 0
+REC_FUNC(ADD);
+REC_FUNC(ADDU);
+REC_FUNC(SUB);
+REC_FUNC(SUBU);
+REC_FUNC(AND);
+REC_FUNC(OR);
+REC_FUNC(XOR);
+REC_FUNC(NOR);
+REC_FUNC(SLT);
+REC_FUNC(SLTU);
+#endif
+
+#if 1
+static void recADDU() {
+// Rd = Rs + Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rt_ == _Rd_) {
+ if (iRegs[_Rs_].k == 1) {
+ INC32M((uptr)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rs_].k == -1) {
+ DEC32M((uptr)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rs_].k) {
+ ADD32ItoM((uptr)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
+ }
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ if (iRegs[_Rs_].k == 1) {
+ INC32R(EAX);
+ } else if (iRegs[_Rs_].k == 0xffffffff) {
+ DEC32R(EAX);
+ } else if (iRegs[_Rs_].k) {
+ ADD32ItoR(EAX, iRegs[_Rs_].k);
+ }
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) {
+ if (iRegs[_Rt_].k == 1) {
+ INC32M((uptr)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rt_].k == -1) {
+ DEC32M((uptr)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rt_].k) {
+ ADD32ItoM((uptr)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
+ }
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (iRegs[_Rt_].k == 1) {
+ INC32R(EAX);
+ } else if (iRegs[_Rt_].k == 0xffffffff) {
+ DEC32R(EAX);
+ } else if (iRegs[_Rt_].k) {
+ ADD32ItoR(EAX, iRegs[_Rt_].k);
+ }
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) { // Rd+= Rt
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ ADD32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (_Rt_ == _Rd_) { // Rd+= Rs
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ ADD32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else { // Rd = Rs + Rt
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ ADD32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ }
+}
+
+static void recADD() {
+// Rd = Rs + Rt
+ recADDU();
+}
+
+static void recSUBU() {
+// Rd = Rs - Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ SUB32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SUB32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SUB32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSUB() {
+// Rd = Rs - Rt
+ recSUBU();
+}
+
+static void recAND() {
+// Rd = Rs And Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rd_ == _Rt_) { // Rd&= Rs
+ AND32ItoM((uptr)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
+ } else {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ AND32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rd_ == _Rs_) { // Rd&= kRt
+ AND32ItoM((uptr)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
+ } else { // Rd = Rs & kRt
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ AND32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) { // Rd&= Rt
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ AND32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (_Rt_ == _Rd_) { // Rd&= Rs
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ AND32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else { // Rd = Rs & Rt
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ AND32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ }
+}
+
+static void recOR() {
+// Rd = Rs Or Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ OR32MtoR (EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ OR32ItoR (EAX, iRegs[_Rt_].k);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ OR32MtoR (EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recXOR() {
+// Rd = Rs Xor Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ XOR32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ XOR32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ XOR32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recNOR() {
+// Rd = Rs Nor Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k));
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ OR32MtoR (EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ NOT32R (EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ OR32ItoR (EAX, iRegs[_Rt_].k);
+ NOT32R (EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ OR32MtoR (EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ NOT32R (EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSLT() {
+// Rd = Rs < Rt (signed)
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ CMP32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, iRegs[_Rt_].k);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSLTU() {
+// Rd = Rs < Rt (unsigned)
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ CMP32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, iRegs[_Rt_].k);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+#endif
+//End of * Register arithmetic
+
+/*********************************************************
+* Register mult/div & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+
+#if 0
+REC_FUNC(MULT);
+REC_FUNC(MULTU);
+REC_FUNC(DIV);
+REC_FUNC(DIVU);
+#endif
+
+#if 1
+static void recMULT() {
+// Lo/Hi = Rs * Rt (signed)
+
+// iFlushRegs();
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ XOR32RtoR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EAX);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multrsk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ }
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multrtk %x\n", iRegs[_Rt_].k);
+ IMUL32R (EDX);
+ } else {
+ IMUL32M ((uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EDX);
+}
+
+static void recMULTU() {
+// Lo/Hi = Rs * Rt (unsigned)
+
+// iFlushRegs();
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ XOR32RtoR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EAX);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multursk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ }
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multurtk %x\n", iRegs[_Rt_].k);
+ MUL32R (EDX);
+ } else {
+ MUL32M ((uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EDX);
+}
+
+static void recDIV() {
+// Lo/Hi = Rs / Rt (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ if (iRegs[_Rt_].k == 0) return;
+ MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divrtk %x\n", iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ CMP32ItoR(ECX, 0);
+ j8Ptr[0] = JE8(0);
+ }
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divrsk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ }
+ CDQ();
+ IDIV32R (ECX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EDX);
+ if (!IsConst(_Rt_)) {
+ x86SetJ8(j8Ptr[0]);
+ }
+}
+
+static void recDIVU() {
+// Lo/Hi = Rs / Rt (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ if (iRegs[_Rt_].k == 0) return;
+ MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divurtk %x\n", iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ CMP32ItoR(ECX, 0);
+ j8Ptr[0] = JE8(0);
+ }
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divursk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ }
+ XOR32RtoR(EDX, EDX);
+ DIV32R (ECX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EDX);
+ if (!IsConst(_Rt_)) {
+ x86SetJ8(j8Ptr[0]);
+ }
+}
+#endif
+//End of * Register mult/div & Register trap logic
+
+#if 0
+REC_FUNC(LB);
+REC_FUNC(LBU);
+REC_FUNC(LH);
+REC_FUNC(LHU);
+REC_FUNC(LW);
+
+REC_FUNC(SB);
+REC_FUNC(SH);
+REC_FUNC(SW);
+
+REC_FUNC(LWL);
+REC_FUNC(LWR);
+REC_FUNC(SWL);
+REC_FUNC(SWR);
+#endif
+
+
+static void SetArg_OfB(x86IntRegType arg) {
+ if (IsConst(_Rs_))
+#ifdef __x86_64__
+ MOV64ItoR(arg, iRegs[_Rs_].k + _Imm_);
+#else
+ PUSH32I (iRegs[_Rs_].k + _Imm_);
+#endif
+ else {
+#ifdef __x86_64__
+ MOV32MtoR(arg, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_)
+ ADD32ItoR(arg, _Imm_);
+#else
+ if (_Imm_) {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32ItoR(EAX, _Imm_);
+ PUSH32R (EAX);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rs_]);
+ }
+#endif
+ }
+#ifndef __x86_64__
+ resp += 4;
+#endif
+}
+
+#if 1
+static void recLB() {
+// Rt = mem[Rs + Im] (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRs8(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M8toR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M8toR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r8 %x\n", addr);
+ }
+
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemRead8);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVSX32R8toR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+}
+
+static void recLBU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu8(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M8toR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M8toR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r8u %x\n", addr);
+ }
+
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemRead8);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVZX32R8toR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+}
+
+static void recLH() {
+// Rt = mem[Rs + Im] (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRs16(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M16toR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M16toR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r16 %x\n", addr);
+ }
+
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemRead16);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVSX32R16toR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+}
+
+static void recLHU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu16(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ //PUSHI (addr);
+ MOV64ItoR(X86ARG1, addr);
+ //CALLFunc ((uptr)SPU_readRegister);
+ MOV64ItoR(RAX, (uptr)SPU_readRegister);
+ CALL64R(RAX);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+#ifndef __WIN32__
+ resp+= 4;
+#endif
+ return;
+ }
+ switch (addr) {
+ case 0x1f801100: case 0x1f801110: case 0x1f801120:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ //PUSHI((addr >> 4) & 0x3);
+ MOV64ItoR(X86ARG1, (addr >> 4) & 0x3);
+ CALLFunc((uptr)psxRcntRcount);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ resp+= 4;
+ return;
+
+ case 0x1f801104: case 0x1f801114: case 0x1f801124:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (uptr)&psxCounters[(addr >> 4) & 0x3].mode);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801108: case 0x1f801118: case 0x1f801128:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (uptr)&psxCounters[(addr >> 4) & 0x3].target);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+// SysPrintf("unhandled r16u %x\n", addr);
+ }
+
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemRead16);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+}
+
+static void recLW() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu32(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80) {
+ switch (addr) {
+ case 0x1f801080: case 0x1f801084: case 0x1f801088:
+ case 0x1f801090: case 0x1f801094: case 0x1f801098:
+ case 0x1f8010a0: case 0x1f8010a4: case 0x1f8010a8:
+ case 0x1f8010b0: case 0x1f8010b4: case 0x1f8010b8:
+ case 0x1f8010c0: case 0x1f8010c4: case 0x1f8010c8:
+ case 0x1f8010d0: case 0x1f8010d4: case 0x1f8010d8:
+ case 0x1f8010e0: case 0x1f8010e4: case 0x1f8010e8:
+ case 0x1f801070: case 0x1f801074:
+ case 0x1f8010f0: case 0x1f8010f4:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801810:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ CALLFunc((uptr)GPU_readData);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801814:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ CALLFunc((uptr)GPU_readStatus);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+// SysPrintf("unhandled r32 %x\n", addr);
+ }
+
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemRead32);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+}
+
+extern u32 LWL_MASK[4];
+extern u32 LWL_SHIFT[4];
+
+void iLWLk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32ItoR(ECX, LWL_MASK[shift]);
+ SHL32ItoR(EAX, LWL_SHIFT[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recLWL() {
+// Rt = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1ffffc]);
+ iLWLk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xffc]);
+ iLWLk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ //PUSH64R (EAX);
+ AND32ItoR(EAX, ~3);
+ //PUSH64R (EAX);
+ MOV32RtoR(X86ARG1, EAX);
+ CALLFunc((uptr)psxMemRead32);
+
+ if (_Rt_) {
+ //ADD32ItoR(ESP, 4);
+ //POP64R (EDX);
+ if (IsConst(_Rs_)) MOV32ItoR(EDX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EDX, _Imm_);
+ }
+
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV64ItoR(ECX, (uptr)LWL_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ SHL32CLtoR(EAX); // mem(EAX) << LWL_SHIFT[shift]
+
+ MOV64ItoR(ECX, (uptr)LWL_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32RtoR(EDX, ECX); // _rRt_ & LWL_MASK[shift]
+
+ OR32RtoR(EAX, EDX);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ //} else {
+ //ADD64ItoR(RSP, 8);
+ //resp+= 8;
+ }
+}
+
+/*
+static void recLWBlock(int count) {
+ u32 *code = PSXM(pc);
+ int i, respsave;
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ // since bios is readonly it won't change
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (_fRt_(*code)) {
+ MapConst(_fRt_(*code), psxRu32(addr));
+ }
+ }
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (!_fRt_(*code)) return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (!_fRt_(*code)) return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ }
+
+ SysPrintf("recLWBlock %d: %d\n", count, IsConst(_Rs_));
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemPointer);
+// ADD32ItoR(ESP, 4);
+
+ respsave = resp; resp = 0;
+ TEST64RtoR(RAX,RAX);
+ j32Ptr[4] = JZ32(0);
+ XOR32RtoR(ECX, ECX);
+ for (i=0; i<count; i++, code++) {
+ if (_fRt_(*code)) {
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV64RmStoR(EDX, EAX, ECX, 2);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_fRt_(*code)], EDX);
+ }
+ if (i != (count-1)) INC32R(ECX);
+ }
+ j32Ptr[5] = JMP32(0);
+ x86SetJ32(j32Ptr[4]);
+ for (i=0, code = PSXM(pc); i<count; i++, code++) {
+ psxRegs.code = *code;
+ recLW();
+ }
+#ifndef __x86_64__
+ ADD32ItoR(ESP, resp);
+#endif
+ x86SetJ32(j32Ptr[5]);
+ resp = respsave;
+}
+*/
+
+extern u32 LWR_MASK[4];
+extern u32 LWR_SHIFT[4];
+
+void iLWRk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32ItoR(ECX, LWR_MASK[shift]);
+ SHR32ItoR(EAX, LWR_SHIFT[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recLWR() {
+// Rt = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1ffffc]);
+ iLWRk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xffc]);
+ iLWRk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSHR(EAX);
+ AND32ItoR(EAX, ~3);
+ MOV32RtoR(X86ARG1, EAX);
+ CALLFunc((uptr)psxMemRead32);
+
+ POPR (EDX);
+ if (_Rt_) {
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV64ItoR(ECX, (uptr)LWR_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ SHR32CLtoR(EAX); // mem(EAX) >> LWR_SHIFT[shift]
+
+ MOV64ItoR(ECX, (uptr)LWR_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32RtoR(EDX, ECX); // _rRt_ & LWR_MASK[shift]
+
+ OR32RtoR(EAX, EDX);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+ //} else {
+ //resp+= 8;
+ }
+}
+
+static void recSB() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV8ItoM((uptr)&psxM[addr & 0x1fffff], (u8)iRegs[_Rt_].k);
+ } else {
+ MOV8MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV8RtoM((uptr)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV8ItoM((uptr)&psxH[addr & 0xfff], (u8)iRegs[_Rt_].k);
+ } else {
+ MOV8MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV8RtoM((uptr)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+// SysPrintf("unhandled w8 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ MOV64ItoR(X86ARG2, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemWrite8);
+// ADD32ItoR(ESP, 8);
+}
+
+static void recSH() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV16ItoM((uptr)&psxM[addr & 0x1fffff], (u16)iRegs[_Rt_].k);
+ } else {
+ MOV16MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV16RtoM((uptr)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV16ItoM((uptr)&psxH[addr & 0xfff], (u16)iRegs[_Rt_].k);
+ } else {
+ MOV16MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV16RtoM((uptr)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (IsConst(_Rt_)) {
+ MOV64ItoR(X86ARG2, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV64ItoR(X86ARG1, addr);
+ CALLFunc ((uptr)SPU_writeRegister);
+#ifndef __WIN32__
+ //resp+= 8;
+#endif
+ return;
+ }
+ }
+// SysPrintf("unhandled w16 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ MOV64ItoR(X86ARG2, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemWrite16);
+// ADD32ItoR(ESP, 8);
+}
+
+static void recSW() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((uptr)&psxM[addr & 0x1fffff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((uptr)&psxH[addr & 0xfff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80) {
+ switch (addr) {
+ case 0x1f801080: case 0x1f801084:
+ case 0x1f801090: case 0x1f801094:
+ case 0x1f8010a0: case 0x1f8010a4:
+ case 0x1f8010b0: case 0x1f8010b4:
+ case 0x1f8010c0: case 0x1f8010c4:
+ case 0x1f8010d0: case 0x1f8010d4:
+ case 0x1f8010e0: case 0x1f8010e4:
+ case 0x1f801074:
+ case 0x1f8010f0:
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((uptr)&psxH[addr & 0xffff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((uptr)&psxH[addr & 0xffff], EAX);
+ }
+ return;
+
+ case 0x1f801810:
+ if (IsConst(_Rt_)) {
+ MOV64ItoR(X86ARG1, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ CALLFunc((uptr)GPU_writeData);
+#ifndef __WIN32__
+ //resp+= 4;
+#endif
+ return;
+
+ case 0x1f801814:
+ if (IsConst(_Rt_)) {
+ MOV64ItoR(X86ARG1, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ CALLFunc((uptr)GPU_writeStatus);
+#ifndef __WIN32__
+ //resp+= 4;
+#endif
+ }
+ }
+// SysPrintf("unhandled w32 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ MOV64ItoR(X86ARG2, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ //resp+= 8;
+}
+
+/*
+static void recSWBlock(int count) {
+ u32 *code;
+ int i, respsave;
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+ code = PSXM(pc);
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (IsConst(_fRt_(*code))) {
+ MOV32ItoM((uptr)&psxM[addr & 0x1fffff], iRegs[_fRt_(*code)].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_fRt_(*code)]);
+ MOV32RtoM((uptr)&psxM[addr & 0x1fffff], EAX);
+ }
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (!_fRt_(*code)) return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xfff]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ }
+
+ SysPrintf("recSWBlock %d: %d\n", count, IsConst(_Rs_));
+ SetArg_OfB(X86ARG1);
+ CALLFunc((uptr)psxMemPointer);
+// ADD32ItoR(ESP, 4);
+ //resp+= 4;
+
+ respsave = resp; resp = 0;
+ TEST64RtoR(RAX,RAX);
+ j32Ptr[4] = JZ32(0);
+ XOR32RtoR(ECX, ECX);
+ for (i=0, code = PSXM(pc); i<count; i++, code++) {
+ if (IsConst(_fRt_(*code))) {
+ MOV32ItoR(EDX, iRegs[_fRt_(*code)].k);
+ } else {
+ MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_fRt_(*code)]);
+ }
+ MOV32RtoRmS(EAX, ECX, 2, EDX);
+ if (i != (count-1)) INC32R(ECX);
+ }
+ j32Ptr[5] = JMP32(0);
+ x86SetJ32(j32Ptr[4]);
+ for (i=0, code = PSXM(pc); i<count; i++, code++) {
+ psxRegs.code = *code;
+ recSW();
+ }
+ //ADD32ItoR(ESP, resp);
+ x86SetJ32(j32Ptr[5]);
+ resp = respsave;
+}
+*/
+
+extern u32 SWL_MASK[4];
+extern u32 SWL_SHIFT[4];
+
+void iSWLk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHR32ItoR(ECX, SWL_SHIFT[shift]);
+ AND32ItoR(EAX, SWL_MASK[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recSWL() {
+// mem[Rs + Im] = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1ffffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((uptr)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((uptr)&psxH[addr & 0xffc], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSHR (EAX);
+ AND32ItoR(EAX, ~3);
+ MOV32RtoR(X86ARG1, EAX);
+
+ CALLFunc((uptr)psxMemRead32);
+
+ POPR (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV64ItoR(ECX, (uptr)SWL_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ AND32RtoR(EAX, ECX); // mem & SWL_MASK[shift]
+
+ MOV64ItoR(ECX, (uptr)SWL_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift]
+
+ OR32RtoR (EAX, EDX);
+ MOV32RtoR(X86ARG2, EAX);
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ AND32ItoR(EAX, ~3);
+ MOV32RtoR(X86ARG1, EAX);
+
+ CALLFunc((uptr)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ //resp+= 8;
+}
+
+extern u32 SWR_MASK[4];
+extern u32 SWR_SHIFT[4];
+
+void iSWRk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHL32ItoR(ECX, SWR_SHIFT[shift]);
+ AND32ItoR(EAX, SWR_MASK[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recSWR() {
+// mem[Rs + Im] = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (uptr)&psxM[addr & 0x1ffffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((uptr)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (uptr)&psxH[addr & 0xffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((uptr)&psxH[addr & 0xffc], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSHR (EAX);
+
+ AND32ItoR(EAX, ~3);
+ MOV32RtoR(X86ARG1, EAX);
+
+ CALLFunc((uptr)psxMemRead32);
+
+ POPR (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV64ItoR(ECX, (uptr)SWR_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ AND32RtoR(EAX, ECX); // mem & SWR_MASK[shift]
+
+ MOV64ItoR(ECX, (uptr)SWR_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift]
+
+ OR32RtoR (EAX, EDX);
+ MOV32RtoR(X86ARG2, EAX);
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ AND32ItoR(EAX, ~3);
+ MOV32RtoR(X86ARG1, EAX);
+ CALLFunc((uptr)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ //resp+= 8;
+}
+
+#endif
+
+#if 0
+REC_FUNC(SLL);
+REC_FUNC(SRL);
+REC_FUNC(SRA);
+#endif
+#if 1
+static void recSLL() {
+// Rd = Rt << Sa
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SHL32ItoR(EAX, _Sa_);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRL() {
+// Rd = Rt >> Sa
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SHR32ItoR(EAX, _Sa_);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRA() {
+// Rd = Rt >> Sa
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SAR32ItoR(EAX, _Sa_);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+#endif
+
+#if 0
+REC_FUNC(SLLV);
+REC_FUNC(SRLV);
+REC_FUNC(SRAV);
+#endif
+
+#if 1
+static void recSLLV() {
+// Rd = Rt << Rs
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRLV() {
+// Rd = Rt >> Rs
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRAV() {
+// Rd = Rt >> Rs
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+#endif
+
+#if 0
+REC_SYS(SYSCALL);
+REC_SYS(BREAK);
+#endif
+
+int dump;
+
+#if 1
+static void recSYSCALL() {
+// dump=1;
+ iFlushRegs();
+
+ MOV32ItoR(EAX, pc - 4);
+ MOV32RtoM((uptr)&psxRegs.pc, EAX);
+ MOV64ItoR(X86ARG2, branch == 1 ? 1 : 0);
+ MOV64ItoR(X86ARG1, 0x20);
+ CALLFunc((uptr)psxException);
+ //ADD32ItoR(ESP, 8);
+
+ branch = 2;
+ iRet();
+}
+
+static void recBREAK() {
+}
+#endif
+
+#if 0
+REC_FUNC(MFHI);
+REC_FUNC(MTHI);
+REC_FUNC(MFLO);
+REC_FUNC(MTLO);
+#endif
+#if 1
+static void recMFHI() {
+// Rd = Hi
+ if (!_Rd_) return;
+
+ iRegs[_Rd_].state = ST_UNK;
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.n.hi);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+}
+
+static void recMTHI() {
+// Hi = Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((uptr)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.hi, EAX);
+ }
+}
+
+static void recMFLO() {
+// Rd = Lo
+ if (!_Rd_) return;
+
+ iRegs[_Rd_].state = ST_UNK;
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.n.lo);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rd_], EAX);
+}
+
+static void recMTLO() {
+// Lo = Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((uptr)&psxRegs.GPR.n.lo, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.n.lo, EAX);
+ }
+}
+#endif
+
+#if 0
+REC_BRANCH(J);
+REC_BRANCH(JR);
+REC_BRANCH(JAL);
+REC_BRANCH(JALR);
+REC_BRANCH(BLTZ);
+REC_BRANCH(BGTZ);
+REC_BRANCH(BLTZAL);
+REC_BRANCH(BGEZAL);
+REC_BRANCH(BNE);
+REC_BRANCH(BEQ);
+REC_BRANCH(BLEZ);
+REC_BRANCH(BGEZ);
+#endif
+#if 1
+static void recBLTZ() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JL32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBGTZ() {
+// Branch if Rs > 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k > 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JG32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBLTZAL() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ MOV32ItoM((uptr)&psxRegs.GPR.r[31], pc + 4);
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JL32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ MOV32ItoM((uptr)&psxRegs.GPR.r[31], pc + 4);
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBGEZAL() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ MOV32ItoM((uptr)&psxRegs.GPR.r[31], pc + 4);
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JGE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ MOV32ItoM((uptr)&psxRegs.GPR.r[31], pc + 4);
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recJ() {
+// j target
+
+ iJump(_Target_ * 4 + (pc & 0xf0000000));
+}
+
+static void recJAL() {
+// jal target
+
+ MapConst(31, pc + 4);
+
+ iJump(_Target_ * 4 + (pc & 0xf0000000));
+}
+
+static void recJR() {
+// jr Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((uptr)&target, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((uptr)&target, EAX);
+ }
+
+ SetBranch();
+}
+
+static void recJALR() {
+// jalr Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((uptr)&target, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((uptr)&target, EAX);
+ }
+
+ if (_Rd_) {
+ MapConst(_Rd_, pc + 4);
+ }
+
+ SetBranch();
+}
+
+static void recBEQ() {
+// Branch if Rs == Rt
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (_Rs_ == _Rt_) {
+ iJump(bpc);
+ } else {
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k == iRegs[_Rt_].k) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ } else if (IsConst(_Rs_)) {
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
+ } else if (IsConst(_Rt_)) {
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+
+ j32Ptr[4] = JE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+ }
+}
+
+static void recBNE() {
+// Branch if Rs != Rt
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k != iRegs[_Rt_].k) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ } else if (IsConst(_Rs_)) {
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
+ } else if (IsConst(_Rt_)) {
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ }
+ j32Ptr[4] = JNE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBLEZ() {
+// Branch if Rs <= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k <= 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JLE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBGEZ() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JGE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+#endif
+
+#if 0
+REC_FUNC(MFC0);
+REC_SYS(MTC0);
+REC_FUNC(CFC0);
+REC_SYS(CTC0);
+REC_FUNC(RFE);
+#endif
+//REC_SYS(MTC0);
+#if 1
+static void recMFC0() {
+// Rt = Cop0->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32MtoR(EAX, (uptr)&psxRegs.CP0.r[_Rd_]);
+ MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
+}
+
+static void recCFC0() {
+// Rt = Cop0->Rd
+
+ recMFC0();
+}
+
+//*
+void psxMTC0();
+static void recMTC0() {
+// Cop0->Rd = Rt
+
+ if (IsConst(_Rt_)) {
+ switch (_Rd_) {
+ case 12:
+ MOV32ItoM((uptr)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
+ break;
+ case 13:
+ MOV32ItoM((uptr)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k & ~(0xfc00));
+ break;
+ default:
+ MOV32ItoM((uptr)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
+ break;
+ }
+ } else {
+ MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rt_]);
+ switch (_Rd_) {
+ case 13:
+ AND32ItoR(EAX, ~(0xfc00));
+ break;
+ }
+ MOV32RtoM((uptr)&psxRegs.CP0.r[_Rd_], EAX);
+ }
+
+ if (_Rd_ == 12 || _Rd_ == 13) {
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.pc, (u32)pc);
+ CALLFunc((uptr)psxTestSWInts);
+ if (_Rd_ == 12)
+ OR32ItoM((uptr)&psxRegs.interrupt, 0x80000000);
+ if (branch == 0) {
+ branch = 2;
+ iRet();
+ }
+ }
+}//*/
+
+static void recCTC0() {
+// Cop0->Rd = Rt
+
+ recMTC0();
+}
+
+static void recRFE() {
+ MOV32MtoR(EAX, (uptr)&psxRegs.CP0.n.Status);
+ MOV32RtoR(ECX, EAX);
+ AND32ItoR(EAX, 0xfffffff0);
+ AND32ItoR(ECX, 0x3c);
+ SHR32ItoR(ECX, 2);
+ OR32RtoR (EAX, ECX);
+ MOV32RtoM((uptr)&psxRegs.CP0.n.Status, EAX);
+
+ iFlushRegs();
+ MOV32ItoM((uptr)&psxRegs.pc, (u32)pc);
+ CALLFunc((uptr)psxTestSWInts);
+ if (branch == 0) {
+ branch = 2;
+ iRet();
+ }
+}
+#endif
+
+#include "iGte.h"
+
+//
+
+static void recHLE() {
+ iFlushRegs();
+
+ CALLFunc((uptr)psxHLEt[psxRegs.code & 0xffff]);
+ branch = 2;
+ iRet();
+}
+
+//
+
+static void (*recBSC[64])() = {
+ recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
+ recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
+ recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL,
+ recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL,
+ recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recSPC[64])() = {
+ recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV,
+ recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL,
+ recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL,
+ recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL,
+ recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR ,
+ recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL
+};
+
+static void (*recREG[32])() = {
+ recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recCP0[32])() = {
+ recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recCP2[64])() = {
+ recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00
+ recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08
+ recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10
+ recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18
+ recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20
+ recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28
+ recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30
+ recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38
+};
+
+static void (*recCP2BSC[32])() = {
+ recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+
+static void recRecompile() {
+ char *p;
+ char *ptr;
+
+ dump=0;
+ resp = 0;
+
+ /* if x86Ptr reached the mem limit reset whole mem */
+ if (((uptr)x86Ptr - (uptr)recMem) >= (RECMEM_SIZE - PTRMULT*0x10000))
+ recReset();
+
+ x86Align(32);
+ ptr = x86Ptr;
+
+ PC_RECP(psxRegs.pc) = x86Ptr;
+ pc = psxRegs.pc;
+ pcold = pc;
+
+ //Make some stack space for function arguments spill (x86-64 calling conventions)
+ // 0x38 = 7 args, should be plenty...
+ SUB64ItoR(RSP, STACKSIZE);
+
+ for (count=0; count<500;) {
+ p = (char *)PSXM(pc);
+ if (p == NULL) recError();
+ psxRegs.code = *(u32 *)p;
+/*
+ if ((psxRegs.code >> 26) == 0x23) { // LW
+ int i;
+ u32 code;
+
+ for (i=1;; i++) {
+ p = (char *)PSXM(pc+i*4);
+ if (p == NULL) recError();
+ code = *(u32 *)p;
+
+ if ((code >> 26) != 0x23 ||
+ _fRs_(code) != _Rs_ ||
+ _fImm_(code) != (_Imm_+i*4))
+ break;
+ }
+ if (i > 1) {
+ recLWBlock(i);
+ pc = pc + i*4; continue;
+ }
+ }
+
+ if ((psxRegs.code >> 26) == 0x2b) { // SW
+ int i;
+ u32 code;
+
+ for (i=1;; i++) {
+ p = (char *)PSXM(pc+i*4);
+ if (p == NULL) recError();
+ code = *(u32 *)p;
+
+ if ((code >> 26) != 0x2b ||
+ _fRs_(code) != _Rs_ ||
+ _fImm_(code) != (_Imm_+i*4))
+ break;
+ }
+ if (i > 1) {
+ recSWBlock(i);
+ pc = pc + i*4; continue;
+ }
+ }*/
+
+ pc+=4; count++;
+ recBSC[psxRegs.code>>26]();
+
+ if (branch) {
+ branch = 0;
+ if (dump) iDumpBlock(ptr);
+ return;
+ }
+ }
+
+ iFlushRegs();
+
+ MOV32ItoM((uptr)&psxRegs.pc, pc);
+ iRet();
+}
+
+
+R3000Acpu psxRec = {
+ recInit,
+ recReset,
+ recExecute,
+ recExecuteBlock,
+ recClear,
+ recShutdown
+};
+
diff --git a/libpcsxcore/ix86_64/ix86-64.c b/libpcsxcore/ix86_64/ix86-64.c
new file mode 100644
index 00000000..a4399ab5
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86-64.c
@@ -0,0 +1,3141 @@
+/*
+ * ix86 core v0.6.2
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ * goldfinger
+ * zerofrog(@gmail.com)
+ */
+
+// stop compiling if NORECBUILD build (only for Visual Studio)
+#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "ix86-64.h"
+
+#ifdef __x86_64__
+
+#ifdef _MSC_VER
+// visual studio calling convention
+x86IntRegType g_x86savedregs[] = { RBX, RBP, RSI, RDI, R12, R13, R14, R15 };
+x86IntRegType g_x86tempregs[] = { R8, R9, R10, R11, RDX, RCX };
+
+// arranged in savedreg -> tempreg order
+x86IntRegType g_x86allregs[14] = { RBX, RBP, RSI, RDI, R12, R13, R14, R15, R8, R9, R10, R11, RDX, RCX };
+
+#else
+// standard calling convention
+
+// registers saved by called functions (no need to flush them across calls)
+x86IntRegType g_x86savedregs[] = { RBX, RBP, R12, R13, R14, R15 };
+// temp registers that need to be saved across calls
+x86IntRegType g_x86tempregs[] = { RCX, RDX, R8, R9, R10, R11, RSI, RDI };
+
+// arranged in savedreg -> tempreg order
+x86IntRegType g_x86allregs[14] = { RBX, RBP, R12, R13, R14, R15, RCX, RDX, R8, R9, R10, R11, RSI, RDI };
+
+#endif
+
+x86IntRegType g_x868bitregs[11] = { RBX, R12, R13, R14, R15, RCX, RDX, R8, R9, R10, R11 };
+x86IntRegType g_x86non8bitregs[3] = { RBP, RSI, RDI };
+
+#endif // __x86_64__
+
+s8 *x86Ptr;
+u8 *j8Ptr[32];
+u32 *j32Ptr[32];
+
+extern void SysPrintf(char *fmt, ...);
+
+void WriteRmOffset(x86IntRegType to, int offset)
+{
+ if( (to&7) == ESP ) {
+ if( offset == 0 ) {
+ ModRM( 0, 0, 4 );
+ ModRM( 0, ESP, 4 );
+ }
+ else if( offset < 128 && offset >= -128 ) {
+ ModRM( 1, 0, 4 );
+ ModRM( 0, ESP, 4 );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, 0, 4 );
+ ModRM( 0, ESP, 4 );
+ write32(offset);
+ }
+ }
+ else {
+ if( offset == 0 ) {
+ ModRM( 0, 0, to );
+ }
+ else if( offset < 128 && offset >= -128 ) {
+ ModRM( 1, 0, to );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, 0, to );
+ write32(offset);
+ }
+ }
+}
+
+void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset)
+{
+ if ((from&7) == ESP) {
+ if( offset == 0 ) {
+ ModRM( 0, to, 0x4 );
+ SibSB( 0, 0x4, 0x4 );
+ }
+ else if( offset < 128 && offset >= -128 ) {
+ ModRM( 1, to, 0x4 );
+ SibSB( 0, 0x4, 0x4 );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, to, 0x4 );
+ SibSB( 0, 0x4, 0x4 );
+ write32(offset);
+ }
+ }
+ else {
+ if( offset == 0 ) {
+ ModRM( 0, to, from );
+ }
+ else if( offset < 128 && offset >= -128 ) {
+ ModRM( 1, to, from );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, to, from );
+ write32(offset);
+ }
+ }
+}
+
+// This function is just for rec debugging purposes
+void CheckX86Ptr( void )
+{
+}
+
+void writeVAROP(unsigned opl, u64 op)
+{
+ while (opl--)
+ {
+ write8(op & 0xFF);
+ op >>= 8;
+ }
+}
+
+#define writeVARROP(REX, opl, op) ({ \
+ if (opl > 1 && ((op & 0xFF) == 0x66 || (op & 0xFF) == 0xF3 || (op & 0xFF) == 0xF2)) { \
+ write8(op & 0xFF); \
+ opl --; \
+ op >>= 8; \
+ } \
+ REX; \
+ writeVAROP(opl, op); \
+ })
+
+void MEMADDR_OP(bool w, unsigned opl, u64 op, bool isreg, int reg, uptr p, sptr off)
+{
+#ifdef __x86_64__
+ sptr pr = MEMADDR_(p, 5 + opl + (w || reg >= 8) + off);
+ if (SPTR32(pr))
+ {
+ writeVARROP(RexR(w, reg), opl, op);
+ ModRM(0, reg, DISP32);
+ write32(pr);
+ }
+ else if (UPTR32(p))
+ {
+ writeVARROP(RexR(w, reg), opl, op);
+ ModRM(0, reg, SIB);
+ SibSB(0, SIB, DISP32);
+ write32(p);
+ }
+ else
+ {
+ assert(!isreg || reg != X86_TEMP);
+ MOV64ItoR(X86_TEMP, p);
+ writeVARROP(RexRB(w, reg, X86_TEMP), opl, op);
+ ModRM(0, reg, X86_TEMP);
+ }
+#else
+ writeVARROP(RexR(w, reg), opl, op);
+ ModRM(0, reg, DISP32);
+ write32(p);
+#endif
+}
+
+void SET8R( int cc, int to )
+{
+ RexB(0, to);
+ write8( 0x0F );
+ write8( cc );
+ write8( 0xC0 | ( to ) );
+}
+
+u8* J8Rel( int cc, int to )
+{
+ write8( cc );
+ write8( to );
+ return x86Ptr - 1;
+}
+
+u16* J16Rel( int cc, u32 to )
+{
+ write16( 0x0F66 );
+ write8( cc );
+ write16( to );
+ return (u16*)( x86Ptr - 2 );
+}
+
+u32* J32Rel( int cc, u32 to )
+{
+ write8( 0x0F );
+ write8( cc );
+ write32( to );
+ return (u32*)( x86Ptr - 4 );
+}
+
+void CMOV32RtoR( int cc, int to, int from )
+{
+ RexRB(0,to, from);
+ write8( 0x0F );
+ write8( cc );
+ ModRM( 3, to, from );
+}
+
+void CMOV32MtoR( int cc, x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, cc), true, to, from, 0);
+}
+
+////////////////////////////////////////////////////
+void x86SetPtr( char* ptr )
+{
+ x86Ptr = ptr;
+}
+
+////////////////////////////////////////////////////
+void x86Shutdown( void )
+{
+}
+
+////////////////////////////////////////////////////
+void x86SetJ8( u8* j8 )
+{
+ u32 jump = ( x86Ptr - (s8*)j8 ) - 1;
+
+ if ( jump > 0x7f ) {
+ assert(0);
+ SysPrintf( "j8 greater than 0x7f!!\n" );
+ }
+ *j8 = (u8)jump;
+}
+
+void x86SetJ8A( u8* j8 )
+{
+ u32 jump = ( x86Ptr - (s8*)j8 ) - 1;
+
+ if ( jump > 0x7f ) {
+ assert(0);
+ SysPrintf( "j8 greater than 0x7f!!\n" );
+ }
+
+ if( ((uptr)x86Ptr&0xf) > 4 ) {
+
+ uptr newjump = jump + 16-((uptr)x86Ptr&0xf);
+
+ if( newjump <= 0x7f ) {
+ jump = newjump;
+ while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
+ }
+ }
+ *j8 = (u8)jump;
+}
+
+void x86SetJ16( u16 *j16 )
+{
+ // doesn't work
+ u32 jump = ( x86Ptr - (s8*)j16 ) - 2;
+
+ if ( jump > 0x7fff ) {
+ assert(0);
+ SysPrintf( "j16 greater than 0x7fff!!\n" );
+ }
+ *j16 = (u16)jump;
+}
+
+void x86SetJ16A( u16 *j16 )
+{
+ if( ((uptr)x86Ptr&0xf) > 4 ) {
+ while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
+ }
+ x86SetJ16(j16);
+}
+
+////////////////////////////////////////////////////
+void x86SetJ32( u32* j32 )
+{
+ *j32 = ( x86Ptr - (s8*)j32 ) - 4;
+}
+
+void x86SetJ32A( u32* j32 )
+{
+ while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
+ x86SetJ32(j32);
+}
+
+////////////////////////////////////////////////////
+void x86Align( int bytes )
+{
+ // fordward align
+ x86Ptr = (s8*)( ( (uptr)x86Ptr + bytes - 1) & ~( bytes - 1 ) );
+}
+
+/********************/
+/* IX86 intructions */
+/********************/
+
+void STC( void )
+{
+ write8( 0xF9 );
+}
+
+void CLC( void )
+{
+ write8( 0xF8 );
+}
+
+////////////////////////////////////
+// mov instructions /
+////////////////////////////////////
+
+/* mov r64 to r64 */
+void MOV64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x89 );
+ ModRM( 3, from, to );
+}
+
+/* mov r64 to m64 */
+void MOV64RtoM( uptr to, x86IntRegType from )
+{
+ if (from == RAX)
+ {
+ RexR(1, 0);
+ write8(0xA3);
+ write64(to);
+ }
+ else
+ {
+ MEMADDR_OP(1, VAROP1(0x89), true, from, to, 0);
+ }
+}
+
+/* mov m64 to r64 */
+void MOV64MtoR( x86IntRegType to, uptr from )
+{
+ if (to == RAX)
+ {
+ RexR(1, 0);
+ write8(0xA1);
+ write64(from);
+ }
+ else
+ {
+ MEMADDR_OP(1, VAROP1(0x8B), true, to, from, 0);
+ }
+}
+
+/* mov imm32 to m64 */
+void MOV64I32toM(uptr to, u32 from )
+{
+ MEMADDR_OP(1, VAROP1(0xC7), false, 0, to, 4);
+ write32(from);
+}
+
+// mov imm64 to r64
+void MOV64ItoR( x86IntRegType to, u64 from)
+{
+ RexB(1, to);
+ write8( 0xB8 | (to & 0x7) );
+ write64( from );
+}
+
+/* mov imm32 to r64 */
+void MOV64I32toR( x86IntRegType to, s32 from )
+{
+ RexB(1, to);
+ write8( 0xC7 );
+ ModRM( 0, 0, to );
+ write32( from );
+}
+
+// mov imm64 to [r64+off]
+void MOV64ItoRmOffset( x86IntRegType to, u32 from, int offset)
+{
+ RexB(1,to);
+ write8( 0xC7 );
+ WriteRmOffset(to, offset);
+ write32(from);
+}
+
+// mov [r64+offset] to r64
+void MOV64RmOffsettoR( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(1, to, from);
+ write8( 0x8B );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+/* mov [r64][r64*scale] to r64 */
+void MOV64RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
+ RexRXB(1, to, from2, from);
+ write8( 0x8B );
+ ModRM( 0, to, 0x4 );
+ SibSB(scale, from2, from );
+}
+
+/* mov r64 to [r64+offset] */
+void MOV64RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(1,from,to);
+ write8( 0x89 );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+/* mov r64 to [r64][r64*scale] */
+void MOV64RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
+ RexRXB(1, to, from2, from);
+ write8( 0x89 );
+ ModRM( 0, to, 0x4 );
+ SibSB(scale, from2, from );
+}
+
+
+/* mov r32 to r32 */
+void MOV32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, from, to);
+ write8( 0x89 );
+ ModRM( 3, from, to );
+}
+
+/* mov r32 to m32 */
+void MOV32RtoM( uptr to, x86IntRegType from )
+{
+ if (from == EAX)
+ {
+ write8(0xA3);
+ write64(to);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0x89), true, from, to, 0);
+ }
+}
+
+/* mov m32 to r32 */
+void MOV32MtoR( x86IntRegType to, uptr from )
+{
+ if (to == RAX)
+ {
+ write8(0xA1);
+ write64(from);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0x8B), true, to, from, 0);
+ }
+}
+
+/* mov [r32] to r32 */
+void MOV32RmtoR( x86IntRegType to, x86IntRegType from ) {
+ RexRB(0, to, from);
+ write8(0x8B);
+ WriteRmOffsetFrom(to, from, 0);
+}
+
+void MOV32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset ) {
+ RexRB(0, to, from);
+ write8( 0x8B );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+/* mov [r32+r32*scale] to r32 */
+void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
+ RexRXB(0,to,from2,from);
+ write8( 0x8B );
+ ModRM( 0, to, 0x4 );
+ SibSB(scale, from2, from );
+}
+
+// mov r32 to [r32<<scale+from2]
+void MOV32RmSOffsettoR( x86IntRegType to, x86IntRegType from1, int from2, int scale )
+{
+ RexRXB(0,to,from1,0);
+ write8( 0x8B );
+ ModRM( 0, to, 0x4 );
+ ModRM( scale, from1, 5);
+ write32(from2);
+}
+
+/* mov r32 to [r32] */
+void MOV32RtoRm( x86IntRegType to, x86IntRegType from ) {
+ RexRB(0, from, to);
+ if ((to&7) == ESP) {
+ write8( 0x89 );
+ ModRM( 0, from, 0x4 );
+ SibSB( 0, 0x4, 0x4 );
+ } else {
+ write8( 0x89 );
+ ModRM( 0, from, to );
+ }
+}
+
+/* mov r32 to [r32][r32*scale] */
+void MOV32RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
+ RexRXB(0, to, from2, from);
+ write8( 0x89 );
+ ModRM( 0, to, 0x4 );
+ SibSB(scale, from2, from );
+}
+
+/* mov imm32 to r32 */
+void MOV32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0, to);
+ write8( 0xB8 | (to & 0x7) );
+ write32( from );
+}
+
+/* mov imm32 to m32 */
+void MOV32ItoM(uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0xC7), false, 0, to, 4);
+ write32(from);
+}
+
+// mov imm32 to [r32+off]
+void MOV32ItoRmOffset( x86IntRegType to, u32 from, int offset)
+{
+ RexB(0,to);
+ write8( 0xC7 );
+ WriteRmOffset(to, offset);
+ write32(from);
+}
+
+// mov r32 to [r32+off]
+void MOV32RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset)
+{
+ RexRB(0,from,to);
+ write8( 0x89 );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+/* mov r16 to m16 */
+void MOV16RtoM(uptr to, x86IntRegType from )
+{
+ if (from == EAX)
+ {
+ write8(0x66);
+ write8(0xA3);
+ write64(to);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP2(0x66, 0x89), true, from, to, 0);
+ }
+}
+
+/* mov m16 to r16 */
+void MOV16MtoR( x86IntRegType to, uptr from )
+{
+ if (to == EAX)
+ {
+ write8(0x66);
+ write8(0xA1);
+ write64(from);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP2(0x66, 0x8B), true, to, from, 0);
+ }
+}
+
+void MOV16RmtoR( x86IntRegType to, x86IntRegType from)
+{
+ write8( 0x66 );
+ RexRB(0,to,from);
+ write8( 0x8B );
+ WriteRmOffsetFrom(to, from, 0);
+}
+
+void MOV16RmtoROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ write8( 0x66 );
+ RexRB(0,to,from);
+ write8( 0x8B );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+void MOV16RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale )
+{
+ write8(0x66);
+ RexRXB(0,to,from1,0);
+ write8( 0x8B );
+ ModRM( 0, to, 0x4 );
+ ModRM( scale, from1, 5);
+ write32(from2);
+}
+
+void MOV16RtoRm(x86IntRegType to, x86IntRegType from)
+{
+ write8( 0x66 );
+ RexRB(0,from,to);
+ write8( 0x89 );
+ ModRM( 0, from, to );
+}
+
+/* mov imm16 to m16 */
+void MOV16ItoM( uptr to, u16 from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0xC7), false, 0, to, 2);
+ write16( from );
+}
+
+/* mov r16 to [r32][r32*scale] */
+void MOV16RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) {
+ write8( 0x66 );
+ RexRXB(0,to,from2,from);
+ write8( 0x89 );
+ ModRM( 0, to, 0x4 );
+ SibSB(scale, from2, from );
+}
+
+void MOV16ItoR( x86IntRegType to, u16 from )
+{
+ RexB(0, to);
+ write16( 0xB866 | ((to & 0x7)<<8) );
+ write16( from );
+}
+
+// mov imm16 to [r16+off]
+void MOV16ItoRmOffset( x86IntRegType to, u16 from, u32 offset)
+{
+ write8(0x66);
+ RexB(0,to);
+ write8( 0xC7 );
+ WriteRmOffset(to, offset);
+ write16(from);
+}
+
+// mov r16 to [r16+off]
+void MOV16RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset)
+{
+ write8(0x66);
+ RexRB(0,from,to);
+ write8( 0x89 );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+/* mov r8 to m8 */
+void MOV8RtoM( uptr to, x86IntRegType from )
+{
+ if (from == EAX)
+ {
+ write8(0xA2);
+ write64(to);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0x88), true, from, to, 0);
+ }
+}
+
+/* mov m8 to r8 */
+void MOV8MtoR( x86IntRegType to, uptr from )
+{
+ if (to == EAX)
+ {
+ write8(0xA0);
+ write64(from);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0x8A), true, to, from, 0);
+ }
+}
+
+/* mov [r32] to r8 */
+void MOV8RmtoR(x86IntRegType to, x86IntRegType from)
+{
+ RexRB(0,to,from);
+ write8( 0x8A );
+ WriteRmOffsetFrom(to, from, 0);
+}
+
+void MOV8RmtoROffset(x86IntRegType to, x86IntRegType from, int offset)
+{
+ RexRB(0,to,from);
+ write8( 0x8A );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+void MOV8RtoRm(x86IntRegType to, x86IntRegType from)
+{
+ RexRB(0,from,to);
+ write8( 0x88 );
+ WriteRmOffsetFrom(from, to, 0);
+}
+
+/* mov imm8 to m8 */
+void MOV8ItoM( uptr to, u8 from )
+{
+ MEMADDR_OP(0, VAROP1(0xC6), false, 0, to, 1);
+ write8( from );
+}
+
+// mov imm8 to r8
+void MOV8ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0, to);
+ write8( 0xB0 | (to & 0x7) );
+ write8( from );
+}
+
+// mov imm8 to [r8+off]
+void MOV8ItoRmOffset( x86IntRegType to, u8 from, int offset)
+{
+ assert( to != ESP );
+ RexB(0,to);
+ write8( 0xC6 );
+ WriteRmOffset(to,offset);
+ write8(from);
+}
+
+// mov r8 to [r8+off]
+void MOV8RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset)
+{
+ assert( to != ESP );
+ RexRB(0,from,to);
+ write8( 0x88 );
+ WriteRmOffsetFrom(from,to,offset);
+}
+
+/* movsx r8 to r32 */
+void MOVSX32R8toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xBE0F );
+ ModRM( 3, to, from );
+}
+
+void MOVSX32Rm8toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xBE0F );
+ ModRM( 0, to, from );
+}
+
+void MOVSX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(0,to,from);
+ write16( 0xBE0F );
+ WriteRmOffsetFrom(to,from,offset);
+}
+
+/* movsx m8 to r32 */
+void MOVSX32M8toR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xBE), true, to, from, 0);
+}
+
+/* movsx r16 to r32 */
+void MOVSX32R16toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xBF0F );
+ ModRM( 3, to, from );
+}
+
+void MOVSX32Rm16toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xBF0F );
+ ModRM( 0, to, from );
+}
+
+void MOVSX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(0,to,from);
+ write16( 0xBF0F );
+ WriteRmOffsetFrom(to,from,offset);
+}
+
+/* movsx m16 to r32 */
+void MOVSX32M16toR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xBF), true, to, from, 0);
+}
+
+/* movzx r8 to r32 */
+void MOVZX32R8toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xB60F );
+ ModRM( 3, to, from );
+}
+
+void MOVZX32Rm8toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xB60F );
+ ModRM( 0, to, from );
+}
+
+void MOVZX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(0,to,from);
+ write16( 0xB60F );
+ WriteRmOffsetFrom(to,from,offset);
+}
+
+/* movzx m8 to r32 */
+void MOVZX32M8toR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xB6), true, to, from, 0);
+}
+
+/* movzx r16 to r32 */
+void MOVZX32R16toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xB70F );
+ ModRM( 3, to, from );
+}
+
+void MOVZX32Rm16toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xB70F );
+ ModRM( 0, to, from );
+}
+
+void MOVZX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(0,to,from);
+ write16( 0xB70F );
+ WriteRmOffsetFrom(to,from,offset);
+}
+
+/* movzx m16 to r32 */
+void MOVZX32M16toR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xB7), true, to, from, 0);
+}
+
+#ifdef __x86_64__
+
+/* movzx r8 to r64 */
+void MOVZX64R8toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1,to,from);
+ write16( 0xB60F );
+ ModRM( 3, to, from );
+}
+
+void MOVZX64Rm8toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1,to,from);
+ write16( 0xB60F );
+ ModRM( 0, to, from );
+}
+
+void MOVZX64Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(1,to,from);
+ write16( 0xB60F );
+ WriteRmOffsetFrom(to,from,offset);
+}
+
+/* movzx m8 to r64 */
+void MOVZX64M8toR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP2(0x0F, 0xB6), true, to, from, 0);
+}
+
+/* movzx r16 to r64 */
+void MOVZX64R16toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1,to,from);
+ write16( 0xB70F );
+ ModRM( 3, to, from );
+}
+
+void MOVZX64Rm16toR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1,to,from);
+ write16( 0xB70F );
+ ModRM( 0, to, from );
+}
+
+void MOVZX64Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset )
+{
+ RexRB(1,to,from);
+ write16( 0xB70F );
+ WriteRmOffsetFrom(to,from,offset);
+}
+
+/* movzx m16 to r64 */
+void MOVZX64M16toR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP2(0x0F, 0xB7), true, to, from, 0);
+}
+#endif
+
+/* cmovbe r32 to r32 */
+void CMOVBE32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x46, to, from );
+}
+
+/* cmovbe m32 to r32*/
+void CMOVBE32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x46, to, from );
+}
+
+/* cmovb r32 to r32 */
+void CMOVB32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x42, to, from );
+}
+
+/* cmovb m32 to r32*/
+void CMOVB32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x42, to, from );
+}
+
+/* cmovae r32 to r32 */
+void CMOVAE32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x43, to, from );
+}
+
+/* cmovae m32 to r32*/
+void CMOVAE32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x43, to, from );
+}
+
+/* cmova r32 to r32 */
+void CMOVA32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x47, to, from );
+}
+
+/* cmova m32 to r32*/
+void CMOVA32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x47, to, from );
+}
+
+/* cmovo r32 to r32 */
+void CMOVO32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x40, to, from );
+}
+
+/* cmovo m32 to r32 */
+void CMOVO32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x40, to, from );
+}
+
+/* cmovp r32 to r32 */
+void CMOVP32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x4A, to, from );
+}
+
+/* cmovp m32 to r32 */
+void CMOVP32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x4A, to, from );
+}
+
+/* cmovs r32 to r32 */
+void CMOVS32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x48, to, from );
+}
+
+/* cmovs m32 to r32 */
+void CMOVS32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x48, to, from );
+}
+
+/* cmovno r32 to r32 */
+void CMOVNO32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x41, to, from );
+}
+
+/* cmovno m32 to r32 */
+void CMOVNO32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x41, to, from );
+}
+
+/* cmovnp r32 to r32 */
+void CMOVNP32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x4B, to, from );
+}
+
+/* cmovnp m32 to r32 */
+void CMOVNP32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x4B, to, from );
+}
+
+/* cmovns r32 to r32 */
+void CMOVNS32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x49, to, from );
+}
+
+/* cmovns m32 to r32 */
+void CMOVNS32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x49, to, from );
+}
+
+/* cmovne r32 to r32 */
+void CMOVNE32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x45, to, from );
+}
+
+/* cmovne m32 to r32*/
+void CMOVNE32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x45, to, from );
+}
+
+/* cmove r32 to r32*/
+void CMOVE32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x44, to, from );
+}
+
+/* cmove m32 to r32*/
+void CMOVE32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x44, to, from );
+}
+
+/* cmovg r32 to r32*/
+void CMOVG32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x4F, to, from );
+}
+
+/* cmovg m32 to r32*/
+void CMOVG32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x4F, to, from );
+}
+
+/* cmovge r32 to r32*/
+void CMOVGE32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x4D, to, from );
+}
+
+/* cmovge m32 to r32*/
+void CMOVGE32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x4D, to, from );
+}
+
+/* cmovl r32 to r32*/
+void CMOVL32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x4C, to, from );
+}
+
+/* cmovl m32 to r32*/
+void CMOVL32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x4C, to, from );
+}
+
+/* cmovle r32 to r32*/
+void CMOVLE32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ CMOV32RtoR( 0x4E, to, from );
+}
+
+/* cmovle m32 to r32*/
+void CMOVLE32MtoR( x86IntRegType to, uptr from )
+{
+ CMOV32MtoR( 0x4E, to, from );
+}
+
+////////////////////////////////////
+// arithmetic instructions /
+////////////////////////////////////
+
+/* add imm32 to r64 */
+void ADD64ItoR( x86IntRegType to, u32 from )
+{
+ RexB(1, to);
+ if (from <= 0x7f)
+ {
+ write8(0x83);
+ ModRM( 3, 0, to );
+ write8(from);
+ }
+ else
+ {
+ if (to == RAX) {
+ write8( 0x05 );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 0, to );
+ }
+ write32( from );
+ }
+}
+
+/* add m64 to r64 */
+void ADD64MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP1(0x03), true, to, from, 0);
+}
+
+/* add r64 to r64 */
+void ADD64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x01 );
+ ModRM( 3, from, to );
+}
+
+/* add imm32 to r32 */
+void ADD32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0, to);
+ if ( to == EAX) {
+ write8( 0x05 );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 0, to );
+ }
+ write32( from );
+}
+
+/* add imm32 to m32 */
+void ADD32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 0, to, 4);
+ write32(from);
+}
+
+// add imm32 to [r32+off]
+void ADD32ItoRmOffset( x86IntRegType to, u32 from, int offset)
+{
+ RexB(0,to);
+ write8( 0x81 );
+ WriteRmOffset(to,offset);
+ write32(from);
+}
+
+/* add r32 to r32 */
+void ADD32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, from, to);
+ write8( 0x01 );
+ ModRM( 3, from, to );
+}
+
+/* add r32 to m32 */
+void ADD32RtoM(uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x01), true, from, to, 0);
+}
+
+/* add m32 to r32 */
+void ADD32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x03), true, to, from, 0);
+}
+
+// add r16 to r16
+void ADD16RtoR( x86IntRegType to , x86IntRegType from )
+{
+ write8(0x66);
+ RexRB(0,to,from);
+ write8( 0x03 );
+ ModRM( 3, to, from );
+}
+
+/* add imm16 to r16 */
+void ADD16ItoR( x86IntRegType to, u16 from )
+{
+ write8( 0x66 );
+ RexB(0,to);
+ if ( to == EAX)
+ {
+ write8( 0x05 );
+ }
+ else
+ {
+ write8( 0x81 );
+ ModRM( 3, 0, to );
+ }
+ write16( from );
+}
+
+/* add imm16 to m16 */
+void ADD16ItoM( uptr to, u16 from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 0, to, 2);
+ write16( from );
+}
+
+/* add r16 to m16 */
+void ADD16RtoM(uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x01), true, from, to, 0);
+}
+
+/* add m16 to r16 */
+void ADD16MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x03), true, to, from, 0);
+}
+
+// add m8 to r8
+void ADD8MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x02), true, to, from, 0);
+}
+
+/* adc imm32 to r32 */
+void ADC32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x15 );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 2, to );
+ }
+ write32( from );
+}
+
+/* adc imm32 to m32 */
+void ADC32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 2, to, 4);
+ write32(from);
+}
+
+/* adc r32 to r32 */
+void ADC32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x11 );
+ ModRM( 3, from, to );
+}
+
+/* adc m32 to r32 */
+void ADC32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x13), true, to, from, 0);
+}
+
+// adc r32 to m32
+void ADC32RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x11), true, from, to, 0);
+}
+
+
+#ifdef __x86_64__
+void INC32R( x86IntRegType to )
+{
+ write8( 0xFF );
+ ModRM(3,0,to);
+}
+#else
+/* inc r32 */
+void INC32R( x86IntRegType to )
+{
+ X86_64ASSERT();
+ write8( 0x40 + to );
+}
+#endif
+/* inc m32 */
+void INC32M( uptr to )
+{
+ MEMADDR_OP(0, VAROP1(0xFF), false, 0, to, 0);
+}
+
+/* inc r16 */
+void INC16R( x86IntRegType to )
+{
+ X86_64ASSERT();
+ write8( 0x66 );
+ write8( 0x40 + to );
+}
+
+/* inc m16 */
+void INC16M( uptr to )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0xFF), false, 0, to, 0);
+}
+
+
+/* sub imm32 to r64 */
+void SUB64ItoR( x86IntRegType to, u32 from )
+{
+ RexB(1, to);
+ if (from <= 0x7f)
+ {
+ write8(0x83);
+ ModRM( 3, 5, to );
+ write8(from);
+ }
+ else
+ {
+ if ( to == RAX ) {
+ write8( 0x2D );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 5, to );
+ }
+ write32( from );
+ }
+}
+
+/* sub r64 to r64 */
+void SUB64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x29 );
+ ModRM( 3, from, to );
+}
+
+/* sub m64 to r64 */
+void SUB64MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP1(0x2B), true, to, from, 0);
+}
+
+/* sub imm32 to r32 */
+void SUB32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x2D );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 5, to );
+ }
+ write32( from );
+}
+
+/* sub imm32 to m32 */
+void SUB32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 5, to, 4);
+ write32(from);
+}
+
+/* sub r32 to r32 */
+void SUB32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, from, to);
+ write8( 0x29 );
+ ModRM( 3, from, to );
+}
+
+/* sub m32 to r32 */
+void SUB32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x2B), true, to, from, 0);
+}
+
+// sub r32 to m32
+void SUB32RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x29), true, from, to, 0);
+}
+
+// sub r16 to r16
+void SUB16RtoR( x86IntRegType to, u16 from )
+{
+ write8(0x66);
+ RexRB(0,to,from);
+ write8( 0x2b );
+ ModRM( 3, to, from );
+}
+
+/* sub imm16 to r16 */
+void SUB16ItoR( x86IntRegType to, u16 from ) {
+ write8( 0x66 );
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x2D );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 5, to );
+ }
+ write16( from );
+}
+
+/* sub imm16 to m16 */
+void SUB16ItoM( uptr to, u16 from ) {
+ MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 5, to, 2);
+ write16( from );
+}
+
+/* sub m16 to r16 */
+void SUB16MtoR( x86IntRegType to, uptr from ) {
+ MEMADDR_OP(0, VAROP2(0x66, 0x2B), true, to, from, 0);
+}
+
+/* sbb r64 to r64 */
+void SBB64RtoR( x86IntRegType to, x86IntRegType from ) {
+ RexRB(1, from,to);
+ write8( 0x19 );
+ ModRM( 3, from, to );
+}
+
+/* sbb imm32 to r32 */
+void SBB32ItoR( x86IntRegType to, u32 from ) {
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x1D );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 3, to );
+ }
+ write32( from );
+}
+
+/* sbb imm32 to m32 */
+void SBB32ItoM( uptr to, u32 from ) {
+ MEMADDR_OP(0, VAROP1(0x81), false, 3, to, 4);
+ write32( from );
+}
+
+/* sbb r32 to r32 */
+void SBB32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x19 );
+ ModRM( 3, from, to );
+}
+
+/* sbb m32 to r32 */
+void SBB32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x1B), true, to, from, 0);
+}
+
+/* sbb r32 to m32 */
+void SBB32RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x19), true, from, to, 0);
+}
+
+#ifdef __x86_64__
+void DEC32R( x86IntRegType to )
+{
+ write8( 0xFF );
+ ModRM(3,1,to);
+}
+#else
+/* dec r32 */
+void DEC32R( x86IntRegType to )
+{
+ X86_64ASSERT();
+ write8( 0x48 + to );
+}
+#endif
+
+/* dec m32 */
+void DEC32M( uptr to )
+{
+ MEMADDR_OP(0, VAROP1(0xFF), false, 1, to, 0);
+}
+
+/* dec r16 */
+void DEC16R( x86IntRegType to )
+{
+ X86_64ASSERT();
+ write8( 0x66 );
+ write8( 0x48 + to );
+}
+
+/* dec m16 */
+void DEC16M( uptr to )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0xFF), false, 1, to, 0);
+}
+
+/* mul eax by r32 to edx:eax */
+void MUL32R( x86IntRegType from )
+{
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 4, from );
+}
+
+/* imul eax by r32 to edx:eax */
+void IMUL32R( x86IntRegType from )
+{
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 5, from );
+}
+
+/* mul eax by m32 to edx:eax */
+void MUL32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 4, from, 0);
+}
+
+/* imul eax by m32 to edx:eax */
+void IMUL32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 5, from, 0);
+}
+
+/* imul r32 by r32 to r32 */
+void IMUL32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write16( 0xAF0F );
+ ModRM( 3, to, from );
+}
+
+/* div eax by r32 to edx:eax */
+void DIV32R( x86IntRegType from )
+{
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 6, from );
+}
+
+/* idiv eax by r32 to edx:eax */
+void IDIV32R( x86IntRegType from )
+{
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 7, from );
+}
+
+/* div eax by m32 to edx:eax */
+void DIV32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 6, from, 0);
+}
+
+/* idiv eax by m32 to edx:eax */
+void IDIV32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 7, from, 0);
+}
+
+////////////////////////////////////
+// shifting instructions /
+////////////////////////////////////
+
+/* shl imm8 to r64 */
+void SHL64ItoR( x86IntRegType to, u8 from )
+{
+ RexB(1, to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ ModRM( 3, 4, to );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 4, to );
+ write8( from );
+}
+
+/* shl cl to r64 */
+void SHL64CLtoR( x86IntRegType to )
+{
+ RexB(1, to);
+ write8( 0xD3 );
+ ModRM( 3, 4, to );
+}
+
+/* shr imm8 to r64 */
+void SHR64ItoR( x86IntRegType to, u8 from )
+{
+ RexB(1,to);
+ if ( from == 1 ) {
+ write8( 0xD1 );
+ ModRM( 3, 5, to );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 5, to );
+ write8( from );
+}
+
+/* shr cl to r64 */
+void SHR64CLtoR( x86IntRegType to )
+{
+ RexB(1, to);
+ write8( 0xD3 );
+ ModRM( 3, 5, to );
+}
+
+/* shl imm8 to r32 */
+void SHL32ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0, to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ write8( 0xE0 | (to & 0x7) );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 4, to );
+ write8( from );
+}
+
+/* shl imm8 to m32 */
+void SHL32ItoM( uptr to, u8 from )
+{
+ if ( from == 1 )
+ {
+ MEMADDR_OP(0, VAROP1(0xD1), false, 4, to, 0);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0xC1), false, 4, to, 1);
+ write8( from );
+ }
+}
+
+/* shl cl to r32 */
+void SHL32CLtoR( x86IntRegType to )
+{
+ RexB(0,to);
+ write8( 0xD3 );
+ ModRM( 3, 4, to );
+}
+
+// shl imm8 to r16
+void SHL16ItoR( x86IntRegType to, u8 from )
+{
+ write8(0x66);
+ RexB(0,to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ write8( 0xE0 | (to & 0x7) );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 4, to );
+ write8( from );
+}
+
+// shl imm8 to r8
+void SHL8ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( from == 1 )
+ {
+ write8( 0xD0 );
+ write8( 0xE0 | (to & 0x7) );
+ return;
+ }
+ write8( 0xC0 );
+ ModRM( 3, 4, to );
+ write8( from );
+}
+
+/* shr imm8 to r32 */
+void SHR32ItoR( x86IntRegType to, u8 from ) {
+ RexB(0,to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ write8( 0xE8 | (to & 0x7) );
+ }
+ else
+ {
+ write8( 0xC1 );
+ ModRM( 3, 5, to );
+ write8( from );
+ }
+}
+
+/* shr imm8 to m32 */
+void SHR32ItoM( uptr to, u8 from )
+{
+ if ( from == 1 )
+ {
+ MEMADDR_OP(0, VAROP1(0xD1), false, 5, to, 0);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0xC1), false, 5, to, 1);
+ write8( from );
+ }
+}
+
+/* shr cl to r32 */
+void SHR32CLtoR( x86IntRegType to )
+{
+ RexB(0,to);
+ write8( 0xD3 );
+ ModRM( 3, 5, to );
+}
+
+// shr imm8 to r8
+void SHR8ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( from == 1 )
+ {
+ write8( 0xD0 );
+ write8( 0xE8 | (to & 0x7) );
+ }
+ else
+ {
+ write8( 0xC0 );
+ ModRM( 3, 5, to );
+ write8( from );
+ }
+}
+
+/* sar imm8 to r64 */
+void SAR64ItoR( x86IntRegType to, u8 from )
+{
+ RexB(1,to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ ModRM( 3, 7, to );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 7, to );
+ write8( from );
+}
+
+/* sar cl to r64 */
+void SAR64CLtoR( x86IntRegType to )
+{
+ RexB(1, to);
+ write8( 0xD3 );
+ ModRM( 3, 7, to );
+}
+
+/* sar imm8 to r32 */
+void SAR32ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ ModRM( 3, 7, to );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 7, to );
+ write8( from );
+}
+
+/* sar imm8 to m32 */
+void SAR32ItoM( uptr to, u8 from )
+{
+ if (from == 1)
+ {
+ MEMADDR_OP(0, VAROP1(0xD1), false, 7, to, 0);
+ }
+ else
+ {
+ MEMADDR_OP(0, VAROP1(0xC1), false, 7, to, 1);
+ write8( from );
+ }
+}
+
+/* sar cl to r32 */
+void SAR32CLtoR( x86IntRegType to )
+{
+ RexB(0,to);
+ write8( 0xD3 );
+ ModRM( 3, 7, to );
+}
+
+// sar imm8 to r16
+void SAR16ItoR( x86IntRegType to, u8 from )
+{
+ write8(0x66);
+ RexB(0,to);
+ if ( from == 1 )
+ {
+ write8( 0xD1 );
+ ModRM( 3, 7, to );
+ return;
+ }
+ write8( 0xC1 );
+ ModRM( 3, 7, to );
+ write8( from );
+}
+
+void ROR32ItoR( x86IntRegType to,u8 from )
+{
+ RexB(0,to);
+ if ( from == 1 ) {
+ write8( 0xd1 );
+ write8( 0xc8 | to );
+ }
+ else
+ {
+ write8( 0xc1 );
+ write8( 0xc8 | to );
+ write8( from );
+ }
+}
+
+void RCR32ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( from == 1 ) {
+ write8( 0xd1 );
+ write8( 0xd8 | to );
+ }
+ else
+ {
+ write8( 0xc1 );
+ write8( 0xd8 | to );
+ write8( from );
+ }
+}
+
+// shld imm8 to r32
+void SHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift )
+{
+ RexRB(0,from,to);
+ write8( 0x0F );
+ write8( 0xA4 );
+ ModRM( 3, from, to );
+ write8( shift );
+}
+
+// shrd imm8 to r32
+void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift )
+{
+ RexRB(0,from,to);
+ write8( 0x0F );
+ write8( 0xAC );
+ ModRM( 3, from, to );
+ write8( shift );
+}
+
+////////////////////////////////////
+// logical instructions /
+////////////////////////////////////
+
+/* or imm32 to r32 */
+void OR64ItoR( x86IntRegType to, u32 from )
+{
+ RexB(1, to);
+ if ( to == EAX ) {
+ write8( 0x0D );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 1, to );
+ }
+ write32( from );
+}
+
+/* or m64 to r64 */
+void OR64MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP1(0x0B), true, to, from, 0);
+}
+
+/* or r64 to r64 */
+void OR64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x09 );
+ ModRM( 3, from, to );
+}
+
+// or r32 to m64
+void OR64RtoM(uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(1, VAROP1(0x09), true, from, to, 0);
+}
+
+/* or imm32 to r32 */
+void OR32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x0D );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 1, to );
+ }
+ write32( from );
+}
+
+/* or imm32 to m32 */
+void OR32ItoM(uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 1, to, 4);
+ write32(from);
+}
+
+/* or r32 to r32 */
+void OR32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x09 );
+ ModRM( 3, from, to );
+}
+
+/* or r32 to m32 */
+void OR32RtoM(uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x09), true, from, to, 0);
+}
+
+/* or m32 to r32 */
+void OR32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x0B), true, to, from, 0);
+}
+
+// or r16 to r16
+void OR16RtoR( x86IntRegType to, x86IntRegType from )
+{
+ write8(0x66);
+ RexRB(0,from,to);
+ write8( 0x09 );
+ ModRM( 3, from, to );
+}
+
+// or imm16 to r16
+void OR16ItoR( x86IntRegType to, u16 from )
+{
+ write8(0x66);
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x0D );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 1, to );
+ }
+ write16( from );
+}
+
+// or imm16 to m316
+void OR16ItoM( uptr to, u16 from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 1, to, 2);
+ write16( from );
+}
+
+/* or m16 to r16 */
+void OR16MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x0B), true, to, from, 0);
+}
+
+// or r16 to m16
+void OR16RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x09), true, from, to, 0);
+}
+
+// or r8 to r8
+void OR8RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x08 );
+ ModRM( 3, from, to );
+}
+
+// or r8 to m8
+void OR8RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x08), true, from, to, 0);
+}
+
+// or imm8 to m8
+void OR8ItoM( uptr to, u8 from )
+{
+ MEMADDR_OP(0, VAROP1(0x80), false, 1, to, 1);
+ write8( from );
+}
+
+// or m8 to r8
+void OR8MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x0A), true, to, from, 0);
+}
+
+/* xor imm32 to r64 */
+void XOR64ItoR( x86IntRegType to, u32 from )
+{
+ RexB(1,to);
+ if ( to == EAX ) {
+ write8( 0x35 );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 6, to );
+ }
+ write32( from );
+}
+
+/* xor r64 to r64 */
+void XOR64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x31 );
+ ModRM( 3, from, to );
+}
+
+/* xor m64 to r64 */
+void XOR64MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP1(0x33), true, to, from, 0);
+}
+
+/* xor r64 to m64 */
+void XOR64RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(1, VAROP1(0x31), true, from, to, 0);
+}
+
+/* xor imm32 to r32 */
+void XOR32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x35 );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 6, to );
+ }
+ write32( from );
+}
+
+/* xor imm32 to m32 */
+void XOR32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 6, to, 4);
+ write32( from );
+}
+
+/* xor r32 to r32 */
+void XOR32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x31 );
+ ModRM( 3, from, to );
+}
+
+/* xor r16 to r16 */
+void XOR16RtoR( x86IntRegType to, x86IntRegType from )
+{
+ write8( 0x66 );
+ RexRB(0,from,to);
+ write8( 0x31 );
+ ModRM( 3, from, to );
+}
+
+/* xor r32 to m32 */
+void XOR32RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x31), true, from, to, 0);
+}
+
+/* xor m32 to r32 */
+void XOR32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x33), true, to, from, 0);
+}
+
+// xor imm16 to r16
+void XOR16ItoR( x86IntRegType to, u16 from )
+{
+ write8(0x66);
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x35 );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 6, to );
+ }
+ write16( from );
+}
+
+// xor r16 to m16
+void XOR16RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x31), true, from, to, 0);
+}
+
+/* and imm32 to r64 */
+void AND64I32toR( x86IntRegType to, u32 from )
+{
+ RexB(1, to);
+ if ( to == EAX ) {
+ write8( 0x25 );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 0x4, to );
+ }
+ write32( from );
+}
+
+/* and m64 to r64 */
+void AND64MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP1(0x23), true, to, from, 0);
+}
+
+/* and r64 to m64 */
+void AND64RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(1, VAROP1(0x21), true, from, to, 0);
+}
+
+/* and r64 to r64 */
+void AND64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x21 );
+ ModRM( 3, from, to );
+}
+
+/* and imm32 to m64 */
+void AND64I32toM( uptr to, u32 from )
+{
+ MEMADDR_OP(1, VAROP1(0x81), false, 4, to, 4);
+ write32( from );
+}
+
+/* and imm32 to r32 */
+void AND32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x25 );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 0x4, to );
+ }
+ write32( from );
+}
+
+/* and sign ext imm8 to r32 */
+void AND32I8toR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ write8( 0x83 );
+ ModRM( 3, 0x4, to );
+ write8( from );
+}
+
+/* and imm32 to m32 */
+void AND32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 4, to, 4);
+ write32(from);
+}
+
+/* and sign ext imm8 to m32 */
+void AND32I8toM( uptr to, u8 from )
+{
+ MEMADDR_OP(0, VAROP1(0x83), false, 4, to, 1);
+ write8( from );
+}
+
+/* and r32 to r32 */
+void AND32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x21 );
+ ModRM( 3, from, to );
+}
+
+/* and r32 to m32 */
+void AND32RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x21), true, from, to, 0);
+}
+
+/* and m32 to r32 */
+void AND32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x23), true, to, from, 0);
+}
+
+// and r16 to r16
+void AND16RtoR( x86IntRegType to, x86IntRegType from )
+{
+ write8(0x66);
+ RexRB(0,to,from);
+ write8( 0x23 );
+ ModRM( 3, to, from );
+}
+
+/* and imm16 to r16 */
+void AND16ItoR( x86IntRegType to, u16 from )
+{
+ write8(0x66);
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x25 );
+ } else {
+ write8( 0x81 );
+ ModRM( 3, 0x4, to );
+ }
+ write16( from );
+}
+
+/* and imm16 to m16 */
+void AND16ItoM( uptr to, u16 from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 4, to, 2);
+ write16( from );
+}
+
+/* and r16 to m16 */
+void AND16RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x21), true, from, to, 0);
+}
+
+/* and m16 to r16 */
+void AND16MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x23), true, to, from, 0);
+}
+
+/* and imm8 to r8 */
+void AND8ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x24 );
+ } else {
+ write8( 0x80 );
+ ModRM( 3, 0x4, to );
+ }
+ write8( from );
+}
+
+/* and imm8 to m8 */
+void AND8ItoM( uptr to, u8 from )
+{
+ MEMADDR_OP(0, VAROP1(0x80), false, 4, to, 1);
+ write8( from );
+}
+
+// and r8 to r8
+void AND8RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,to,from);
+ write8( 0x22 );
+ ModRM( 3, to, from );
+}
+
+/* and r8 to m8 */
+void AND8RtoM( uptr to, x86IntRegType from )
+{
+ MEMADDR_OP(0, VAROP1(0x20), true, from, to, 0);
+}
+
+/* and m8 to r8 */
+void AND8MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x22), true, to, from, 0);
+}
+
+/* not r64 */
+void NOT64R( x86IntRegType from )
+{
+ RexB(1, from);
+ write8( 0xF7 );
+ ModRM( 3, 2, from );
+}
+
+/* not r32 */
+void NOT32R( x86IntRegType from )
+{
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 2, from );
+}
+
+// not m32
+void NOT32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 2, from, 0);
+}
+
+/* neg r64 */
+void NEG64R( x86IntRegType from )
+{
+ RexB(1, from);
+ write8( 0xF7 );
+ ModRM( 3, 3, from );
+}
+
+/* neg r32 */
+void NEG32R( x86IntRegType from )
+{
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 3, from );
+}
+
+void NEG32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 3, from, 0);
+}
+
+/* neg r16 */
+void NEG16R( x86IntRegType from )
+{
+ write8( 0x66 );
+ RexB(0,from);
+ write8( 0xF7 );
+ ModRM( 3, 3, from );
+}
+
+////////////////////////////////////
+// jump instructions /
+////////////////////////////////////
+
+u8* JMP( uptr to ) {
+ uptr jump = ( x86Ptr - (s8*)to ) - 1;
+
+ if ( jump > 0x7f ) {
+ assert( to <= 0xffffffff );
+ return (u8*)JMP32( to );
+ } else {
+ return (u8*)JMP8( to );
+ }
+}
+
+/* jmp rel8 */
+u8* JMP8( u8 to )
+{
+ write8( 0xEB );
+ write8( to );
+ return x86Ptr - 1;
+}
+
+/* jmp rel32 */
+u32* JMP32( uptr to )
+{
+ assert(SPTR32((sptr)to));
+ write8( 0xE9 );
+ write32( (sptr)to );
+ return (u32*)(x86Ptr - 4 );
+}
+
+/* jmp r32/r64 */
+void JMPR( x86IntRegType to )
+{
+ RexB(0, to);
+ write8( 0xFF );
+ ModRM( 3, 4, to );
+}
+
+// jmp m32
+void JMP32M( uptr to )
+{
+ /* FIXME */
+ MEMADDR_OP(0, VAROP1(0xFF), false, 4, to, 0);
+}
+
+/* jp rel8 */
+u8* JP8( u8 to ) {
+ return J8Rel( 0x7A, to );
+}
+
+/* jnp rel8 */
+u8* JNP8( u8 to ) {
+ return J8Rel( 0x7B, to );
+}
+
+/* je rel8 */
+u8* JE8( u8 to ) {
+ return J8Rel( 0x74, to );
+}
+
+/* jz rel8 */
+u8* JZ8( u8 to )
+{
+ return J8Rel( 0x74, to );
+}
+
+/* js rel8 */
+u8* JS8( u8 to )
+{
+ return J8Rel( 0x78, to );
+}
+
+/* jns rel8 */
+u8* JNS8( u8 to )
+{
+ return J8Rel( 0x79, to );
+}
+
+/* jg rel8 */
+u8* JG8( u8 to )
+{
+ return J8Rel( 0x7F, to );
+}
+
+/* jge rel8 */
+u8* JGE8( u8 to )
+{
+ return J8Rel( 0x7D, to );
+}
+
+/* jl rel8 */
+u8* JL8( u8 to )
+{
+ return J8Rel( 0x7C, to );
+}
+
+/* ja rel8 */
+u8* JA8( u8 to )
+{
+ return J8Rel( 0x77, to );
+}
+
+u8* JAE8( u8 to )
+{
+ return J8Rel( 0x73, to );
+}
+
+/* jb rel8 */
+u8* JB8( u8 to )
+{
+ return J8Rel( 0x72, to );
+}
+
+/* jbe rel8 */
+u8* JBE8( u8 to )
+{
+ return J8Rel( 0x76, to );
+}
+
+/* jle rel8 */
+u8* JLE8( u8 to )
+{
+ return J8Rel( 0x7E, to );
+}
+
+/* jne rel8 */
+u8* JNE8( u8 to )
+{
+ return J8Rel( 0x75, to );
+}
+
+/* jnz rel8 */
+u8* JNZ8( u8 to )
+{
+ return J8Rel( 0x75, to );
+}
+
+/* jng rel8 */
+u8* JNG8( u8 to )
+{
+ return J8Rel( 0x7E, to );
+}
+
+/* jnge rel8 */
+u8* JNGE8( u8 to )
+{
+ return J8Rel( 0x7C, to );
+}
+
+/* jnl rel8 */
+u8* JNL8( u8 to )
+{
+ return J8Rel( 0x7D, to );
+}
+
+/* jnle rel8 */
+u8* JNLE8( u8 to )
+{
+ return J8Rel( 0x7F, to );
+}
+
+/* jo rel8 */
+u8* JO8( u8 to )
+{
+ return J8Rel( 0x70, to );
+}
+
+/* jno rel8 */
+u8* JNO8( u8 to )
+{
+ return J8Rel( 0x71, to );
+}
+
+// jb rel8
+u16* JB16( u16 to )
+{
+ return J16Rel( 0x82, to );
+}
+
+// jb rel32
+u32* JB32( u32 to )
+{
+ return J32Rel( 0x82, to );
+}
+
+/* je rel32 */
+u32* JE32( u32 to )
+{
+ return J32Rel( 0x84, to );
+}
+
+/* jz rel32 */
+u32* JZ32( u32 to )
+{
+ return J32Rel( 0x84, to );
+}
+
+/* jg rel32 */
+u32* JG32( u32 to )
+{
+ return J32Rel( 0x8F, to );
+}
+
+/* jge rel32 */
+u32* JGE32( u32 to )
+{
+ return J32Rel( 0x8D, to );
+}
+
+/* jl rel32 */
+u32* JL32( u32 to )
+{
+ return J32Rel( 0x8C, to );
+}
+
+/* jle rel32 */
+u32* JLE32( u32 to )
+{
+ return J32Rel( 0x8E, to );
+}
+
+/* jae rel32 */
+u32* JAE32( u32 to )
+{
+ return J32Rel( 0x83, to );
+}
+
+/* jne rel32 */
+u32* JNE32( u32 to )
+{
+ return J32Rel( 0x85, to );
+}
+
+/* jnz rel32 */
+u32* JNZ32( u32 to )
+{
+ return J32Rel( 0x85, to );
+}
+
+/* jng rel32 */
+u32* JNG32( u32 to )
+{
+ return J32Rel( 0x8E, to );
+}
+
+/* jnge rel32 */
+u32* JNGE32( u32 to )
+{
+ return J32Rel( 0x8C, to );
+}
+
+/* jnl rel32 */
+u32* JNL32( u32 to )
+{
+ return J32Rel( 0x8D, to );
+}
+
+/* jnle rel32 */
+u32* JNLE32( u32 to )
+{
+ return J32Rel( 0x8F, to );
+}
+
+/* jo rel32 */
+u32* JO32( u32 to )
+{
+ return J32Rel( 0x80, to );
+}
+
+/* jno rel32 */
+u32* JNO32( u32 to )
+{
+ return J32Rel( 0x81, to );
+}
+
+// js rel32
+u32* JS32( u32 to )
+{
+ return J32Rel( 0x88, to );
+}
+
+
+/* call func */
+void CALLFunc( uptr func )
+{
+ sptr p = MEMADDR_(func, 5);
+ if (SPTR32(p))
+ {
+ CALL32(p);
+ }
+ else
+ {
+ MOV64ItoR(X86_TEMP, func);
+ CALL64R(X86_TEMP);
+ }
+}
+
+/* call rel32 */
+void CALL32( s32 to )
+{
+ write8( 0xE8 );
+ write32( to );
+}
+
+/* call r32 */
+void CALL32R( x86IntRegType to )
+{
+ RexB(0, to);
+ write8( 0xFF );
+ ModRM( 3, 2, to );
+}
+
+/* call r64 */
+void CALL64R( x86IntRegType to )
+{
+ RexB(0, to);
+ write8( 0xFF );
+ ModRM( 3, 2, to );
+}
+
+////////////////////////////////////
+// misc instructions /
+////////////////////////////////////
+
+/* cmp imm32 to r64 */
+void CMP64I32toR( x86IntRegType to, u32 from )
+{
+ RexB(1, to);
+ if ( to == EAX ) {
+ write8( 0x3D );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 7, to );
+ }
+ write32( from );
+}
+
+/* cmp m64 to r64 */
+void CMP64MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(1, VAROP1(0x3B), true, 2, from, 0);
+}
+
+// cmp r64 to r64
+void CMP64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1,from,to);
+ write8( 0x39 );
+ ModRM( 3, from, to );
+}
+
+/* cmp imm32 to r32 */
+void CMP32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX ) {
+ write8( 0x3D );
+ }
+ else {
+ write8( 0x81 );
+ ModRM( 3, 7, to );
+ }
+ write32( from );
+}
+
+/* cmp imm32 to m32 */
+void CMP32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0x81), false, 7, to, 4);
+ write32(from);
+}
+
+/* cmp r32 to r32 */
+void CMP32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x39 );
+ ModRM( 3, from, to );
+}
+
+/* cmp m32 to r32 */
+void CMP32MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x3B), true, to, from, 0);
+}
+
+// cmp imm8 to [r32]
+void CMP32I8toRm( x86IntRegType to, u8 from)
+{
+ RexB(0,to);
+ write8( 0x83 );
+ ModRM( 0, 7, to );
+ write8(from);
+}
+
+// cmp imm32 to [r32+off]
+void CMP32I8toRmOffset8( x86IntRegType to, u8 from, u8 off)
+{
+ RexB(0,to);
+ write8( 0x83 );
+ ModRM( 1, 7, to );
+ write8(off);
+ write8(from);
+}
+
+// cmp imm8 to [r32]
+void CMP32I8toM( uptr to, u8 from)
+{
+ MEMADDR_OP(0, VAROP1(0x83), false, 7, to, 1);
+ write8( from );
+}
+
+/* cmp imm16 to r16 */
+void CMP16ItoR( x86IntRegType to, u16 from )
+{
+ write8( 0x66 );
+ RexB(0,to);
+ if ( to == EAX )
+ {
+ write8( 0x3D );
+ }
+ else
+ {
+ write8( 0x81 );
+ ModRM( 3, 7, to );
+ }
+ write16( from );
+}
+
+/* cmp imm16 to m16 */
+void CMP16ItoM( uptr to, u16 from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 7, to, 2);
+ write16( from );
+}
+
+/* cmp r16 to r16 */
+void CMP16RtoR( x86IntRegType to, x86IntRegType from )
+{
+ write8( 0x66 );
+ RexRB(0,from,to);
+ write8( 0x39 );
+ ModRM( 3, from, to );
+}
+
+/* cmp m16 to r16 */
+void CMP16MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x66, 0x3B), true, to, from, 0);
+}
+
+// cmp imm8 to r8
+void CMP8ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( to == EAX )
+ {
+ write8( 0x3C );
+ }
+ else
+ {
+ write8( 0x80 );
+ ModRM( 3, 7, to );
+ }
+ write8( from );
+}
+
+// cmp m8 to r8
+void CMP8MtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0x3A), true, to, from, 0);
+}
+
+/* test r64 to r64 */
+void TEST64RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(1, from, to);
+ write8( 0x85 );
+ ModRM( 3, from, to );
+}
+
+/* test imm32 to r32 */
+void TEST32ItoR( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ if ( to == EAX )
+ {
+ write8( 0xA9 );
+ }
+ else
+ {
+ write8( 0xF7 );
+ ModRM( 3, 0, to );
+ }
+ write32( from );
+}
+
+void TEST32ItoM( uptr to, u32 from )
+{
+ MEMADDR_OP(0, VAROP1(0xF7), false, 0, to, 4);
+ write32( from );
+}
+
+/* test r32 to r32 */
+void TEST32RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0,from,to);
+ write8( 0x85 );
+ ModRM( 3, from, to );
+}
+
+// test imm32 to [r32]
+void TEST32ItoRm( x86IntRegType to, u32 from )
+{
+ RexB(0,to);
+ write8( 0xF7 );
+ ModRM( 0, 0, to );
+ write32(from);
+}
+
+// test imm16 to r16
+void TEST16ItoR( x86IntRegType to, u16 from )
+{
+ write8(0x66);
+ RexB(0,to);
+ if ( to == EAX )
+ {
+ write8( 0xA9 );
+ }
+ else
+ {
+ write8( 0xF7 );
+ ModRM( 3, 0, to );
+ }
+ write16( from );
+}
+
+// test r16 to r16
+void TEST16RtoR( x86IntRegType to, x86IntRegType from )
+{
+ write8(0x66);
+ RexRB(0,from,to);
+ write16( 0x85 );
+ ModRM( 3, from, to );
+}
+
+// test imm8 to r8
+void TEST8ItoR( x86IntRegType to, u8 from )
+{
+ RexB(0,to);
+ if ( to == EAX )
+ {
+ write8( 0xA8 );
+ }
+ else
+ {
+ write8( 0xF6 );
+ ModRM( 3, 0, to );
+ }
+ write8( from );
+}
+
+// test imm8 to r8
+void TEST8ItoM( uptr to, u8 from )
+{
+ MEMADDR_OP(0, VAROP1(0xF6), false, 0, to, 1);
+ write8( from );
+}
+
+/* sets r8 */
+void SETS8R( x86IntRegType to )
+{
+ SET8R( 0x98, to );
+}
+
+/* setl r8 */
+void SETL8R( x86IntRegType to )
+{
+ SET8R( 0x9C, to );
+}
+
+// setge r8
+void SETGE8R( x86IntRegType to ) { SET8R(0x9d, to); }
+// setg r8
+void SETG8R( x86IntRegType to ) { SET8R(0x9f, to); }
+// seta r8
+void SETA8R( x86IntRegType to ) { SET8R(0x97, to); }
+// setae r8
+void SETAE8R( x86IntRegType to ) { SET8R(0x99, to); }
+/* setb r8 */
+void SETB8R( x86IntRegType to ) { SET8R( 0x92, to ); }
+/* setb r8 */
+void SETNZ8R( x86IntRegType to ) { SET8R( 0x95, to ); }
+// setz r8
+void SETZ8R( x86IntRegType to ) { SET8R(0x94, to); }
+// sete r8
+void SETE8R( x86IntRegType to ) { SET8R(0x94, to); }
+
+/* push imm32 */
+void PUSH32I( u32 from )
+{
+ //X86_64ASSERT(); //becomes sign extended in x86_64
+ write8( 0x68 );
+ write32( from );
+}
+
+#ifdef __x86_64__
+
+/* push r64 */
+void PUSH64R( x86IntRegType from )
+{
+ RexB(0,from);
+ //write8( 0x51 | from );
+ write8( 0x50 | from );
+}
+
+/* push m64 */
+void PUSH64M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xFF), false, 6, from, 0);
+}
+
+/* pop r64 */
+void POP64R( x86IntRegType from ) {
+ RexB(0,from);
+ //write8( 0x59 | from );
+ write8( 0x58 | from );
+}
+
+void PUSHR(x86IntRegType from) { PUSH64R(from); }
+void POPR(x86IntRegType from) { POP64R(from); }
+
+#else
+
+/* push r32 */
+void PUSH32R( x86IntRegType from ) { write8( 0x50 | from ); }
+
+/* push m32 */
+void PUSH32M( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xFF), false, 6, from, 0);
+}
+
+/* pop r32 */
+void POP32R( x86IntRegType from ) { write8( 0x58 | from ); }
+
+/* pushad */
+void PUSHA32( void ) { write8( 0x60 ); }
+
+/* popad */
+void POPA32( void ) { write8( 0x61 ); }
+
+void PUSHR(x86IntRegType from) { PUSH32R(from); }
+void POPR(x86IntRegType from) { POP32R(from); }
+
+#endif
+
+
+/* pushfd */
+void PUSHFD( void ) { write8( 0x9C ); }
+/* popfd */
+void POPFD( void ) { write8( 0x9D ); }
+
+void RET( void ) { write8( 0xC3 ); }
+void RET2( void ) { write16( 0xc3f3 ); }
+
+void CBW( void ) { write16( 0x9866 ); }
+void CWD( void ) { write8( 0x98 ); }
+void CDQ( void ) { write8( 0x99 ); }
+void CWDE() { write8(0x98); }
+
+#ifdef __x86_64__
+void CDQE( void ) { RexR(1,0); write8( 0x98 ); }
+#endif
+
+void LAHF() { write8(0x9f); }
+void SAHF() { write8(0x9e); }
+
+void BT32ItoR( x86IntRegType to, x86IntRegType from )
+{
+ write16( 0xBA0F );
+ write8( 0xE0 | to );
+ write8( from );
+}
+
+void BSRRtoR(x86IntRegType to, x86IntRegType from)
+{
+ write16( 0xBD0F );
+ ModRM( 3, from, to );
+}
+
+void BSWAP32R( x86IntRegType to )
+{
+ write8( 0x0F );
+ write8( 0xC8 + to );
+}
+
+// to = from + offset
+void LEA16RtoR(x86IntRegType to, x86IntRegType from, u16 offset)
+{
+ write8(0x66);
+ LEA32RtoR(to, from, offset);
+}
+
+void LEA32RtoR(x86IntRegType to, x86IntRegType from, u32 offset)
+{
+ RexRB(0,to,from);
+ write8(0x8d);
+
+ if( (from&7) == ESP ) {
+ if( offset == 0 ) {
+ ModRM(1, to, from);
+ write8(0x24);
+ }
+ else if( offset < 128 ) {
+ ModRM(1, to, from);
+ write8(0x24);
+ write8(offset);
+ }
+ else {
+ ModRM(2, to, from);
+ write8(0x24);
+ write32(offset);
+ }
+ }
+ else {
+ if( offset == 0 && from != EBP && from!=ESP ) {
+ ModRM(0, to, from);
+ }
+ else if( offset < 128 ) {
+ ModRM(1, to, from);
+ write8(offset);
+ }
+ else {
+ ModRM(2, to, from);
+ write32(offset);
+ }
+ }
+}
+
+// to = from0 + from1
+void LEA16RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1)
+{
+ write8(0x66);
+ LEA32RRtoR(to, from0, from1);
+}
+
+void LEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1)
+{
+ RexRXB(0, to, from0, from1);
+ write8(0x8d);
+
+ if( (from1&7) == EBP ) {
+ ModRM(1, to, 4);
+ ModRM(0, from0, from1);
+ write8(0);
+ }
+ else {
+ ModRM(0, to, 4);
+ ModRM(0, from0, from1);
+ }
+}
+
+// to = from << scale (max is 3)
+void LEA16RStoR(x86IntRegType to, x86IntRegType from, u32 scale)
+{
+ write8(0x66);
+ LEA32RStoR(to, from, scale);
+}
+
+void LEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale)
+{
+ if( to == from ) {
+ SHL32ItoR(to, scale);
+ return;
+ }
+
+ if( from != ESP ) {
+ RexRXB(0,to,from,0);
+ write8(0x8d);
+ ModRM(0, to, 4);
+ ModRM(scale, from, 5);
+ write32(0);
+ }
+ else {
+ assert( to != ESP );
+ MOV32RtoR(to, from);
+ LEA32RStoR(to, to, scale);
+ }
+}
+
+#endif
diff --git a/libpcsxcore/ix86_64/ix86-64.h b/libpcsxcore/ix86_64/ix86-64.h
new file mode 100644
index 00000000..009fa5a1
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86-64.h
@@ -0,0 +1,1776 @@
+/*
+ * ix86 definitions v0.6.2
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ * goldfinger
+ * shadow < shadow@pcsx2.net >
+ */
+
+#ifndef __IX86_H__
+#define __IX86_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../psxcommon.h" // Basic types header
+#include <assert.h>
+#include <stdbool.h>
+
+#if defined(__MINGW32__)
+#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
+#else
+#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
+#endif
+
+
+#ifdef __x86_64__
+#define XMMREGS 16
+#define X86REGS 16
+#else
+#define XMMREGS 8
+#define X86REGS 8
+#endif
+
+#define MMXREGS 8
+
+#define SIB 4
+#define DISP32 5
+
+// general types
+typedef int x86IntRegType;
+#define EAX 0
+#define EBX 3
+#define ECX 1
+#define EDX 2
+#define ESI 6
+#define EDI 7
+#define EBP 5
+#define ESP 4
+
+#ifdef __x86_64__
+#define RAX 0
+#define RBX 3
+#define RCX 1
+#define RDX 2
+#define RSI 6
+#define RDI 7
+#define RBP 5
+#define RSP 4
+#define R8 8
+#define R9 9
+#define R10 10
+#define R11 11
+#define R12 12
+#define R13 13
+#define R14 14
+#define R15 15
+
+#define X86_TEMP RAX // don't allocate anything
+
+#ifdef _MSC_VER
+extern x86IntRegType g_x86savedregs[8];
+extern x86IntRegType g_x86tempregs[6];
+#else
+extern x86IntRegType g_x86savedregs[6];
+extern x86IntRegType g_x86tempregs[8];
+#endif
+
+extern x86IntRegType g_x86allregs[14]; // all registers that can be used by the recs
+extern x86IntRegType g_x868bitregs[11];
+extern x86IntRegType g_x86non8bitregs[3];
+
+#ifdef _MSC_VER
+#define X86ARG1 RCX
+#define X86ARG2 RDX
+#define X86ARG3 R8
+#define X86ARG4 R9
+#else
+#define X86ARG1 RDI
+#define X86ARG2 RSI
+#define X86ARG3 RDX
+#define X86ARG4 RCX
+#endif
+
+#else
+
+#define X86ARG1 EAX
+#define X86ARG2 ECX
+#define X86ARG3 EDX
+#define X86ARG4 EBX
+
+#endif // __x86_64__
+
+#define MM0 0
+#define MM1 1
+#define MM2 2
+#define MM3 3
+#define MM4 4
+#define MM5 5
+#define MM6 6
+#define MM7 7
+
+typedef int x86MMXRegType;
+
+#define XMM0 0
+#define XMM1 1
+#define XMM2 2
+#define XMM3 3
+#define XMM4 4
+#define XMM5 5
+#define XMM6 6
+#define XMM7 7
+#define XMM8 8
+#define XMM9 9
+#define XMM10 10
+#define XMM11 11
+#define XMM12 12
+#define XMM13 13
+#define XMM14 14
+#define XMM15 15
+
+typedef int x86SSERegType;
+
+typedef enum
+{
+ XMMT_INT = 0, // integer (sse2 only)
+ XMMT_FPS = 1, // floating point
+ //XMMT_FPD = 3, // double
+} XMMSSEType;
+
+extern XMMSSEType g_xmmtypes[XMMREGS];
+
+void cpudetectInit( void );//this is all that needs to be called and will fill up the below structs
+
+//cpu capabilities structure
+typedef struct {
+ u32 hasFloatingPointUnit;
+ u32 hasVirtual8086ModeEnhancements;
+ u32 hasDebuggingExtensions;
+ u32 hasPageSizeExtensions;
+ u32 hasTimeStampCounter;
+ u32 hasModelSpecificRegisters;
+ u32 hasPhysicalAddressExtension;
+ u32 hasCOMPXCHG8BInstruction;
+ u32 hasAdvancedProgrammableInterruptController;
+ u32 hasSEPFastSystemCall;
+ u32 hasMemoryTypeRangeRegisters;
+ u32 hasPTEGlobalFlag;
+ u32 hasMachineCheckArchitecture;
+ u32 hasConditionalMoveAndCompareInstructions;
+ u32 hasFGPageAttributeTable;
+ u32 has36bitPageSizeExtension;
+ u32 hasProcessorSerialNumber;
+ u32 hasCFLUSHInstruction;
+ u32 hasDebugStore;
+ u32 hasACPIThermalMonitorAndClockControl;
+ u32 hasMultimediaExtensions;
+ u32 hasFastStreamingSIMDExtensionsSaveRestore;
+ u32 hasStreamingSIMDExtensions;
+ u32 hasStreamingSIMD2Extensions;
+ u32 hasSelfSnoop;
+ u32 hasHyperThreading;
+ u32 hasThermalMonitor;
+ u32 hasIntel64BitArchitecture;
+ u32 hasStreamingSIMD3Extensions;
+ //that is only for AMDs
+ u32 hasMultimediaExtensionsExt;
+ u32 hasAMD64BitArchitecture;
+ u32 has3DNOWInstructionExtensionsExt;
+ u32 has3DNOWInstructionExtensions;
+} CAPABILITIES;
+
+extern CAPABILITIES cpucaps;
+
+typedef struct {
+
+ u32 x86Family; // Processor Family
+ u32 x86Model; // Processor Model
+ u32 x86PType; // Processor Type
+ u32 x86StepID; // Stepping ID
+ u32 x86Flags; // Feature Flags
+ u32 x86EFlags; // Extended Feature Flags
+ //all the above returns hex values
+ s8 x86ID[16]; // Vendor ID //the vendor creator (in %s)
+ s8 x86Type[20]; //cpu type in char format //the cpu type (in %s)
+ s8 x86Fam[50]; // family in char format //the original cpu name string (in %s)
+ u32 cpuspeed; // speed of cpu //this will give cpu speed (in %d)
+} CPUINFO;
+
+extern CPUINFO cpuinfo;
+
+extern s8 *x86Ptr;
+extern u8 *j8Ptr[32];
+extern u32 *j32Ptr[32];
+
+
+#ifdef __x86_64__
+#define X86_64ASSERT() assert(0)
+#define MEMADDR_(addr, oplen) (sptr)((uptr)(addr) - ((uptr)x86Ptr + ((u64)(oplen))))
+#define SPTR32(addr) ((addr) < 0x80000000L && (addr) >= -0x80000000L)
+#define UPTR32(addr) ((addr) < 0x100000000L)
+#define MEMADDR(addr, oplen) ({ sptr _a = MEMADDR_(addr, oplen); assert(SPTR32(_a)); _a; })
+#else
+#define X86_64ASSERT()
+#define SPTR32(a) 1
+#define UPTR32(a) 1
+#define MEMADDR(addr, oplen) (addr)
+#endif
+
+#ifdef __x86_64__
+#define Rex( w, r, x, b ) write8( 0x40 | ((w) << 3) | ((r) << 2) | ((x) << 1) | (b) )
+#else
+#define Rex(w,r,x,b) assert(0)
+#endif
+#define RexRXB(w, reg, index, base) if(w || (reg) >= 8 || (index) >= 8 || (base) >= 8 ) \
+ Rex(w, (reg)>=8, (index)>=8, (base)>=8)
+#define RexR(w, reg) RexRXB(w, reg, 0, 0)
+#define RexB(w, base) RexRXB(w, 0, 0, base)
+#define RexRB(w, reg, base) RexRXB(w, reg, 0, base)
+
+void x86SetPtr( char *ptr );
+void x86Shutdown( void );
+
+void x86SetJ8( u8 *j8 );
+void x86SetJ8A( u8 *j8 );
+void x86SetJ16( u16 *j16 );
+void x86SetJ16A( u16 *j16 );
+void x86SetJ32( u32 *j32 );
+void x86SetJ32A( u32 *j32 );
+
+void x86Align( int bytes );
+u64 GetCPUTick( void );
+
+// General Helper functions
+#define ModRM(mod, rm, reg) write8( ( mod << 6 ) | ( (rm & 7) << 3 ) | ( reg & 7 ) )
+#define SibSB(ss, rm, index) write8( ( ss << 6 ) | ( rm << 3 ) | ( index ) )
+void SET8R( int cc, int to );
+u8* J8Rel( int cc, int to );
+u32* J32Rel( int cc, u32 to );
+void CMOV32RtoR( int cc, int to, int from );
+void CMOV32MtoR( int cc, int to, uptr from );
+
+void MEMADDR_OP(bool w, unsigned opl, u64 op, bool isreg, int reg, uptr p, sptr off);
+
+#define VAROP1(op) 1, op
+#define VAROP2(op1, op2) 2, (op1) | ((op2) << 8)
+
+//******************
+// IX86 intructions
+//******************
+
+//
+// * scale values:
+// * 0 - *1
+// * 1 - *2
+// * 2 - *4
+// * 3 - *8
+//
+
+void STC( void );
+void CLC( void );
+
+////////////////////////////////////
+// mov instructions //
+////////////////////////////////////
+
+// mov r64 to r64
+void MOV64RtoR( x86IntRegType to, x86IntRegType from );
+// mov r64 to m64
+void MOV64RtoM( uptr to, x86IntRegType from );
+// mov m64 to r64
+void MOV64MtoR( x86IntRegType to, uptr from );
+// mov sign ext imm32 to m64
+void MOV64I32toM( uptr to, u32 from );
+// mov sign ext imm32 to r64
+void MOV64I32toR( x86IntRegType to, s32 from);
+// mov imm64 to r64
+void MOV64ItoR( x86IntRegType to, u64 from);
+// mov imm64 to [r64+off]
+void MOV64ItoRmOffset( x86IntRegType to, u32 from, int offset);
+// mov [r64+offset] to r64
+void MOV64RmOffsettoR( x86IntRegType to, x86IntRegType from, int offset );
+// mov [r64][r64*scale] to r64
+void MOV64RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale);
+// mov r64 to [r64+offset]
+void MOV64RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset );
+// mov r64 to [r64][r64*scale]
+void MOV64RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale);
+
+// mov r32 to r32
+void MOV32RtoR( x86IntRegType to, x86IntRegType from );
+// mov r32 to m32
+void MOV32RtoM( uptr to, x86IntRegType from );
+// mov m32 to r32
+void MOV32MtoR( x86IntRegType to, uptr from );
+// mov [r32] to r32
+void MOV32RmtoR( x86IntRegType to, x86IntRegType from );
+void MOV32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset );
+// mov [r32][r32<<scale] to r32
+void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale );
+// mov [imm32(from2) + r32(from1)<<scale] to r32
+void MOV32RmSOffsettoR( x86IntRegType to, x86IntRegType from1, int from2, int scale );
+// mov r32 to [r32]
+void MOV32RtoRm( x86IntRegType to, x86IntRegType from );
+// mov r32 to [r32][r32*scale]
+void MOV32RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale );
+// mov imm32 to r32
+void MOV32ItoR( x86IntRegType to, u32 from );
+// mov imm32 to m32
+void MOV32ItoM( uptr to, u32 from );
+// mov imm32 to [r32+off]
+void MOV32ItoRmOffset( x86IntRegType to, u32 from, int offset);
+// mov r32 to [r32+off]
+void MOV32RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset);
+
+// mov r16 to m16
+void MOV16RtoM( uptr to, x86IntRegType from );
+// mov m16 to r16
+void MOV16MtoR( x86IntRegType to, uptr from );
+// mov [r32] to r16
+void MOV16RmtoR( x86IntRegType to, x86IntRegType from ) ;
+void MOV16RmtoROffset( x86IntRegType to, x86IntRegType from, int offset );
+// mov [imm32(from2) + r32(from1)<<scale] to r16
+void MOV16RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale );
+// mov r16 to [r32]
+void MOV16RtoRm(x86IntRegType to, x86IntRegType from);
+// mov imm16 to m16
+void MOV16ItoM( uptr to, u16 from );
+/* mov r16 to [r32][r32*scale] */
+void MOV16RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale);
+// mov imm16 to r16
+void MOV16ItoR( x86IntRegType to, u16 from );
+// mov imm16 to [r16+off]
+void MOV16ItoRmOffset( x86IntRegType to, u16 from, u32 offset);
+// mov r16 to [r16+off]
+void MOV16RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset);
+
+// mov r8 to m8
+void MOV8RtoM( uptr to, x86IntRegType from );
+// mov m8 to r8
+void MOV8MtoR( x86IntRegType to, uptr from );
+// mov [r32] to r8
+void MOV8RmtoR(x86IntRegType to, x86IntRegType from);
+void MOV8RmtoROffset(x86IntRegType to, x86IntRegType from, int offset);
+// mov r8 to [r32]
+void MOV8RtoRm(x86IntRegType to, x86IntRegType from);
+// mov imm8 to m8
+void MOV8ItoM( uptr to, u8 from );
+// mov imm8 to r8
+void MOV8ItoR( x86IntRegType to, u8 from );
+// mov imm8 to [r8+off]
+void MOV8ItoRmOffset( x86IntRegType to, u8 from, int offset);
+// mov r8 to [r8+off]
+void MOV8RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset);
+
+// movsx r8 to r32
+void MOVSX32R8toR( x86IntRegType to, x86IntRegType from );
+void MOVSX32Rm8toR( x86IntRegType to, x86IntRegType from );
+void MOVSX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset );
+// movsx m8 to r32
+void MOVSX32M8toR( x86IntRegType to, uptr from );
+// movsx r16 to r32
+void MOVSX32R16toR( x86IntRegType to, x86IntRegType from );
+void MOVSX32Rm16toR( x86IntRegType to, x86IntRegType from );
+void MOVSX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset );
+// movsx m16 to r32
+void MOVSX32M16toR( x86IntRegType to, uptr from );
+
+// movzx r8 to r32
+void MOVZX32R8toR( x86IntRegType to, x86IntRegType from );
+void MOVZX32Rm8toR( x86IntRegType to, x86IntRegType from );
+void MOVZX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset );
+// movzx m8 to r32
+void MOVZX32M8toR( x86IntRegType to, uptr from );
+// movzx r16 to r32
+void MOVZX32R16toR( x86IntRegType to, x86IntRegType from );
+void MOVZX32Rm16toR( x86IntRegType to, x86IntRegType from );
+void MOVZX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset );
+// movzx m16 to r32
+void MOVZX32M16toR( x86IntRegType to, uptr from );
+
+#ifdef __x86_64__
+void MOVZX64R8toR( x86IntRegType to, x86IntRegType from );
+void MOVZX64Rm8toR( x86IntRegType to, x86IntRegType from );
+void MOVZX64Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset );
+// movzx m8 to r64
+void MOVZX64M8toR( x86IntRegType to, uptr from );
+// movzx r16 to r64
+void MOVZX64R16toR( x86IntRegType to, x86IntRegType from );
+void MOVZX64Rm16toR( x86IntRegType to, x86IntRegType from );
+void MOVZX64Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset );
+// movzx m16 to r64
+void MOVZX64M16toR( x86IntRegType to, uptr from );
+#endif
+
+// cmovbe r32 to r32
+void CMOVBE32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovbe m32 to r32
+void CMOVBE32MtoR( x86IntRegType to, uptr from );
+// cmovb r32 to r32
+void CMOVB32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovb m32 to r32
+void CMOVB32MtoR( x86IntRegType to, uptr from );
+// cmovae r32 to r32
+void CMOVAE32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovae m32 to r32
+void CMOVAE32MtoR( x86IntRegType to, uptr from );
+// cmova r32 to r32
+void CMOVA32RtoR( x86IntRegType to, x86IntRegType from );
+// cmova m32 to r32
+void CMOVA32MtoR( x86IntRegType to, uptr from );
+
+// cmovo r32 to r32
+void CMOVO32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovo m32 to r32
+void CMOVO32MtoR( x86IntRegType to, uptr from );
+// cmovp r32 to r32
+void CMOVP32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovp m32 to r32
+void CMOVP32MtoR( x86IntRegType to, uptr from );
+// cmovs r32 to r32
+void CMOVS32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovs m32 to r32
+void CMOVS32MtoR( x86IntRegType to, uptr from );
+// cmovno r32 to r32
+void CMOVNO32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovno m32 to r32
+void CMOVNO32MtoR( x86IntRegType to, uptr from );
+// cmovnp r32 to r32
+void CMOVNP32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovnp m32 to r32
+void CMOVNP32MtoR( x86IntRegType to, uptr from );
+// cmovns r32 to r32
+void CMOVNS32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovns m32 to r32
+void CMOVNS32MtoR( x86IntRegType to, uptr from );
+
+// cmovne r32 to r32
+void CMOVNE32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovne m32 to r32
+void CMOVNE32MtoR( x86IntRegType to, uptr from );
+// cmove r32 to r32
+void CMOVE32RtoR( x86IntRegType to, x86IntRegType from );
+// cmove m32 to r32
+void CMOVE32MtoR( x86IntRegType to, uptr from );
+// cmovg r32 to r32
+void CMOVG32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovg m32 to r32
+void CMOVG32MtoR( x86IntRegType to, uptr from );
+// cmovge r32 to r32
+void CMOVGE32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovge m32 to r32
+void CMOVGE32MtoR( x86IntRegType to, uptr from );
+// cmovl r32 to r32
+void CMOVL32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovl m32 to r32
+void CMOVL32MtoR( x86IntRegType to, uptr from );
+// cmovle r32 to r32
+void CMOVLE32RtoR( x86IntRegType to, x86IntRegType from );
+// cmovle m32 to r32
+void CMOVLE32MtoR( x86IntRegType to, uptr from );
+
+////////////////////////////////////
+// arithmetic instructions //
+////////////////////////////////////
+
+// add imm32 to r64
+void ADD64ItoR( x86IntRegType to, u32 from );
+// add m64 to r64
+void ADD64MtoR( x86IntRegType to, uptr from );
+
+// add imm32 to r32
+void ADD32ItoR( x86IntRegType to, u32 from );
+// add imm32 to m32
+void ADD32ItoM( uptr to, u32 from );
+// add imm32 to [r32+off]
+void ADD32ItoRmOffset( x86IntRegType to, u32 from, int offset);
+// add r32 to r32
+void ADD32RtoR( x86IntRegType to, x86IntRegType from );
+// add r32 to m32
+void ADD32RtoM( uptr to, x86IntRegType from );
+// add m32 to r32
+void ADD32MtoR( x86IntRegType to, uptr from );
+
+// add r16 to r16
+void ADD16RtoR( x86IntRegType to , x86IntRegType from );
+// add imm16 to r16
+void ADD16ItoR( x86IntRegType to, u16 from );
+// add imm16 to m16
+void ADD16ItoM( uptr to, u16 from );
+// add r16 to m16
+void ADD16RtoM( uptr to, x86IntRegType from );
+// add m16 to r16
+void ADD16MtoR( x86IntRegType to, uptr from );
+
+// add m8 to r8
+void ADD8MtoR( x86IntRegType to, uptr from );
+
+// adc imm32 to r32
+void ADC32ItoR( x86IntRegType to, u32 from );
+// adc imm32 to m32
+void ADC32ItoM( uptr to, u32 from );
+// adc r32 to r32
+void ADC32RtoR( x86IntRegType to, x86IntRegType from );
+// adc m32 to r32
+void ADC32MtoR( x86IntRegType to, uptr from );
+// adc r32 to m32
+void ADC32RtoM( uptr to, x86IntRegType from );
+
+// inc r32
+void INC32R( x86IntRegType to );
+// inc m32
+void INC32M( uptr to );
+// inc r16
+void INC16R( x86IntRegType to );
+// inc m16
+void INC16M( uptr to );
+
+// sub m64 to r64
+void SUB64MtoR( x86IntRegType to, uptr from );
+void SUB64ItoR( x86IntRegType to, u32 from );
+
+// sub imm32 to r32
+void SUB32ItoR( x86IntRegType to, u32 from );
+// sub imm32 to m32
+void SUB32ItoM( uptr to, u32 from ) ;
+// sub r32 to r32
+void SUB32RtoR( x86IntRegType to, x86IntRegType from );
+// sub m32 to r32
+void SUB32MtoR( x86IntRegType to, uptr from ) ;
+// sub r32 to m32
+void SUB32RtoM( uptr to, x86IntRegType from );
+// sub r16 to r16
+void SUB16RtoR( x86IntRegType to, u16 from );
+// sub imm16 to r16
+void SUB16ItoR( x86IntRegType to, u16 from );
+// sub imm16 to m16
+void SUB16ItoM( uptr to, u16 from ) ;
+// sub m16 to r16
+void SUB16MtoR( x86IntRegType to, uptr from );
+
+// sbb r64 to r64
+void SBB64RtoR( x86IntRegType to, x86IntRegType from );
+
+// sbb imm32 to r32
+void SBB32ItoR( x86IntRegType to, u32 from );
+// sbb imm32 to m32
+void SBB32ItoM( uptr to, u32 from );
+// sbb r32 to r32
+void SBB32RtoR( x86IntRegType to, x86IntRegType from );
+// sbb m32 to r32
+void SBB32MtoR( x86IntRegType to, uptr from );
+// sbb r32 to m32
+void SBB32RtoM( uptr to, x86IntRegType from );
+
+// dec r32
+void DEC32R( x86IntRegType to );
+// dec m32
+void DEC32M( uptr to );
+// dec r16
+void DEC16R( x86IntRegType to );
+// dec m16
+void DEC16M( uptr to );
+
+// mul eax by r32 to edx:eax
+void MUL32R( x86IntRegType from );
+// mul eax by m32 to edx:eax
+void MUL32M( uptr from );
+
+// imul eax by r32 to edx:eax
+void IMUL32R( x86IntRegType from );
+// imul eax by m32 to edx:eax
+void IMUL32M( uptr from );
+// imul r32 by r32 to r32
+void IMUL32RtoR( x86IntRegType to, x86IntRegType from );
+
+// div eax by r32 to edx:eax
+void DIV32R( x86IntRegType from );
+// div eax by m32 to edx:eax
+void DIV32M( uptr from );
+
+// idiv eax by r32 to edx:eax
+void IDIV32R( x86IntRegType from );
+// idiv eax by m32 to edx:eax
+void IDIV32M( uptr from );
+
+////////////////////////////////////
+// shifting instructions //
+////////////////////////////////////
+
+// shl imm8 to r64
+void SHL64ItoR( x86IntRegType to, u8 from );
+// shl cl to r64
+void SHL64CLtoR( x86IntRegType to );
+// shr imm8 to r64
+void SHR64ItoR( x86IntRegType to, u8 from );
+// shr cl to r64
+void SHR64CLtoR( x86IntRegType to );
+// sar imm8 to r64
+void SAR64ItoR( x86IntRegType to, u8 from );
+// sar cl to r64
+void SAR64CLtoR( x86IntRegType to );
+
+// shl imm8 to r32
+void SHL32ItoR( x86IntRegType to, u8 from );
+/* shl imm8 to m32 */
+void SHL32ItoM( uptr to, u8 from );
+// shl cl to r32
+void SHL32CLtoR( x86IntRegType to );
+
+// shl imm8 to r16
+void SHL16ItoR( x86IntRegType to, u8 from );
+// shl imm8 to r8
+void SHL8ItoR( x86IntRegType to, u8 from );
+
+// shr imm8 to r32
+void SHR32ItoR( x86IntRegType to, u8 from );
+/* shr imm8 to m32 */
+void SHR32ItoM( uptr to, u8 from );
+// shr cl to r32
+void SHR32CLtoR( x86IntRegType to );
+
+// shr imm8 to r8
+void SHR8ItoR( x86IntRegType to, u8 from );
+
+// sar imm8 to r32
+void SAR32ItoR( x86IntRegType to, u8 from );
+// sar imm8 to m32
+void SAR32ItoM( uptr to, u8 from );
+// sar cl to r32
+void SAR32CLtoR( x86IntRegType to );
+
+// sar imm8 to r16
+void SAR16ItoR( x86IntRegType to, u8 from );
+
+// ror imm8 to r32 (rotate right)
+void ROR32ItoR( x86IntRegType to,u8 from );
+
+void RCR32ItoR( x86IntRegType to,u8 from );
+// shld imm8 to r32
+void SHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift );
+// shrd imm8 to r32
+void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift );
+
+// sal imm8 to r32
+#define SAL32ItoR SHL32ItoR
+// sal cl to r32
+#define SAL32CLtoR SHL32CLtoR
+
+// logical instructions
+
+// or imm32 to r64
+void OR64ItoR( x86IntRegType to, u32 from );
+// or m64 to r64
+void OR64MtoR( x86IntRegType to, uptr from );
+// or r64 to r64
+void OR64RtoR( x86IntRegType to, x86IntRegType from );
+// or r32 to m64
+void OR64RtoM( uptr to, x86IntRegType from );
+
+// or imm32 to r32
+void OR32ItoR( x86IntRegType to, u32 from );
+// or imm32 to m32
+void OR32ItoM( uptr to, u32 from );
+// or r32 to r32
+void OR32RtoR( x86IntRegType to, x86IntRegType from );
+// or r32 to m32
+void OR32RtoM( uptr to, x86IntRegType from );
+// or m32 to r32
+void OR32MtoR( x86IntRegType to, uptr from );
+// or r16 to r16
+void OR16RtoR( x86IntRegType to, x86IntRegType from );
+// or imm16 to r16
+void OR16ItoR( x86IntRegType to, u16 from );
+// or imm16 to m16
+void OR16ItoM( uptr to, u16 from );
+// or m16 to r16
+void OR16MtoR( x86IntRegType to, uptr from );
+// or r16 to m16
+void OR16RtoM( uptr to, x86IntRegType from );
+
+// or r8 to r8
+void OR8RtoR( x86IntRegType to, x86IntRegType from );
+// or r8 to m8
+void OR8RtoM( uptr to, x86IntRegType from );
+// or imm8 to m8
+void OR8ItoM( uptr to, u8 from );
+// or m8 to r8
+void OR8MtoR( x86IntRegType to, uptr from );
+
+// xor imm32 to r64
+void XOR64ItoR( x86IntRegType to, u32 from );
+// xor r64 to r64
+void XOR64RtoR( x86IntRegType to, x86IntRegType from );
+// xor m64 to r64
+void XOR64MtoR( x86IntRegType to, uptr from );
+// xor r64 to r64
+void XOR64RtoR( x86IntRegType to, x86IntRegType from );
+// xor r64 to m64
+void XOR64RtoM( uptr to, x86IntRegType from );
+// xor imm32 to r32
+void XOR32ItoR( x86IntRegType to, u32 from );
+// xor imm32 to m32
+void XOR32ItoM( uptr to, u32 from );
+// xor r32 to r32
+void XOR32RtoR( x86IntRegType to, x86IntRegType from );
+// xor r16 to r16
+void XOR16RtoR( x86IntRegType to, x86IntRegType from );
+// xor r32 to m32
+void XOR32RtoM( uptr to, x86IntRegType from );
+// xor m32 to r32
+void XOR32MtoR( x86IntRegType to, uptr from );
+// xor r16 to m16
+void XOR16RtoM( uptr to, x86IntRegType from );
+// xor imm16 to r16
+void XOR16ItoR( x86IntRegType to, u16 from );
+
+// and imm32 to r64
+void AND64I32toR( x86IntRegType to, u32 from );
+// and m64 to r64
+void AND64MtoR( x86IntRegType to, uptr from );
+// and r64 to m64
+void AND64RtoM( uptr to, x86IntRegType from );
+// and r64 to r64
+void AND64RtoR( x86IntRegType to, x86IntRegType from );
+// and imm32 to m64
+void AND64I32toM( uptr to, u32 from );
+
+// and imm32 to r32
+void AND32ItoR( x86IntRegType to, u32 from );
+// and sign ext imm8 to r32
+void AND32I8toR( x86IntRegType to, u8 from );
+// and imm32 to m32
+void AND32ItoM( uptr to, u32 from );
+// and sign ext imm8 to m32
+void AND32I8toM( uptr to, u8 from );
+// and r32 to r32
+void AND32RtoR( x86IntRegType to, x86IntRegType from );
+// and r32 to m32
+void AND32RtoM( uptr to, x86IntRegType from );
+// and m32 to r32
+void AND32MtoR( x86IntRegType to, uptr from );
+// and r16 to r16
+void AND16RtoR( x86IntRegType to, x86IntRegType from );
+// and imm16 to r16
+void AND16ItoR( x86IntRegType to, u16 from );
+// and imm16 to m16
+void AND16ItoM( uptr to, u16 from );
+// and r16 to m16
+void AND16RtoM( uptr to, x86IntRegType from );
+// and m16 to r16
+void AND16MtoR( x86IntRegType to, uptr from );
+// and imm8 to r8
+void AND8ItoR( x86IntRegType to, u8 from );
+// and imm8 to m32
+void AND8ItoM( uptr to, u8 from );
+// and r8 to m8
+void AND8RtoM( uptr to, x86IntRegType from );
+// and m8 to r8
+void AND8MtoR( x86IntRegType to, uptr from );
+// and r8 to r8
+void AND8RtoR( x86IntRegType to, x86IntRegType from );
+
+// not r64
+void NOT64R( x86IntRegType from );
+// not r32
+void NOT32R( x86IntRegType from );
+// not m32
+void NOT32M( uptr from );
+// neg r64
+void NEG64R( x86IntRegType from );
+// neg r32
+void NEG32R( x86IntRegType from );
+// neg m32
+void NEG32M( uptr from );
+// neg r16
+void NEG16R( x86IntRegType from );
+
+////////////////////////////////////
+// jump instructions //
+////////////////////////////////////
+
+// jmp rel8
+u8* JMP8( u8 to );
+
+// jmp rel32
+u32* JMP32( uptr to );
+// jmp r32 (r64 if __x86_64__)
+void JMPR( x86IntRegType to );
+// jmp m32
+void JMP32M( uptr to );
+
+// jp rel8
+u8* JP8( u8 to );
+// jnp rel8
+u8* JNP8( u8 to );
+// je rel8
+u8* JE8( u8 to );
+// jz rel8
+u8* JZ8( u8 to );
+// jg rel8
+u8* JG8( u8 to );
+// jge rel8
+u8* JGE8( u8 to );
+// js rel8
+u8* JS8( u8 to );
+// jns rel8
+u8* JNS8( u8 to );
+// jl rel8
+u8* JL8( u8 to );
+// ja rel8
+u8* JA8( u8 to );
+// jae rel8
+u8* JAE8( u8 to );
+// jb rel8
+u8* JB8( u8 to );
+// jbe rel8
+u8* JBE8( u8 to );
+// jle rel8
+u8* JLE8( u8 to );
+// jne rel8
+u8* JNE8( u8 to );
+// jnz rel8
+u8* JNZ8( u8 to );
+// jng rel8
+u8* JNG8( u8 to );
+// jnge rel8
+u8* JNGE8( u8 to );
+// jnl rel8
+u8* JNL8( u8 to );
+// jnle rel8
+u8* JNLE8( u8 to );
+// jo rel8
+u8* JO8( u8 to );
+// jno rel8
+u8* JNO8( u8 to );
+
+// jb rel8
+u16* JB16( u16 to );
+
+// jb rel32
+u32* JB32( u32 to );
+// je rel32
+u32* JE32( u32 to );
+// jz rel32
+u32* JZ32( u32 to );
+// jg rel32
+u32* JG32( u32 to );
+// jge rel32
+u32* JGE32( u32 to );
+// jl rel32
+u32* JL32( u32 to );
+// jle rel32
+u32* JLE32( u32 to );
+// jae rel32
+u32* JAE32( u32 to );
+// jne rel32
+u32* JNE32( u32 to );
+// jnz rel32
+u32* JNZ32( u32 to );
+// jng rel32
+u32* JNG32( u32 to );
+// jnge rel32
+u32* JNGE32( u32 to );
+// jnl rel32
+u32* JNL32( u32 to );
+// jnle rel32
+u32* JNLE32( u32 to );
+// jo rel32
+u32* JO32( u32 to );
+// jno rel32
+u32* JNO32( u32 to );
+// js rel32
+u32* JS32( u32 to );
+
+// call func
+void CALLFunc( uptr func);
+// call rel32
+void CALL32( s32 to );
+// call r32
+void CALL32R( x86IntRegType to );
+// call m32
+void CALL64R( x86IntRegType to );
+
+
+////////////////////////////////////
+// misc instructions //
+////////////////////////////////////
+
+// cmp imm32 to r64
+void CMP64I32toR( x86IntRegType to, u32 from );
+// cmp m64 to r64
+void CMP64MtoR( x86IntRegType to, uptr from );
+// cmp r64 to r64
+void CMP64RtoR( x86IntRegType to, x86IntRegType from );
+
+// cmp imm32 to r32
+void CMP32ItoR( x86IntRegType to, u32 from );
+// cmp imm32 to m32
+void CMP32ItoM( uptr to, u32 from );
+// cmp r32 to r32
+void CMP32RtoR( x86IntRegType to, x86IntRegType from );
+// cmp m32 to r32
+void CMP32MtoR( x86IntRegType to, uptr from );
+// cmp imm32 to [r32]
+void CMP32I8toRm( x86IntRegType to, u8 from);
+// cmp imm32 to [r32+off]
+void CMP32I8toRmOffset8( x86IntRegType to, u8 from, u8 off);
+// cmp imm8 to [r32]
+void CMP32I8toM( uptr to, u8 from);
+
+// cmp imm16 to r16
+void CMP16ItoR( x86IntRegType to, u16 from );
+// cmp imm16 to m16
+void CMP16ItoM( uptr to, u16 from );
+// cmp r16 to r16
+void CMP16RtoR( x86IntRegType to, x86IntRegType from );
+// cmp m16 to r16
+void CMP16MtoR( x86IntRegType to, uptr from );
+
+// cmp imm8 to r8
+void CMP8ItoR( x86IntRegType to, u8 from );
+// cmp m8 to r8
+void CMP8MtoR( x86IntRegType to, uptr from );
+
+// test r64 to r64
+void TEST64RtoR( x86IntRegType to, x86IntRegType from );
+// test imm32 to r32
+void TEST32ItoR( x86IntRegType to, u32 from );
+// test imm32 to m32
+void TEST32ItoM( uptr to, u32 from );
+// test r32 to r32
+void TEST32RtoR( x86IntRegType to, x86IntRegType from );
+// test imm32 to [r32]
+void TEST32ItoRm( x86IntRegType to, u32 from );
+// test imm16 to r16
+void TEST16ItoR( x86IntRegType to, u16 from );
+// test r16 to r16
+void TEST16RtoR( x86IntRegType to, x86IntRegType from );
+// test imm8 to r8
+void TEST8ItoR( x86IntRegType to, u8 from );
+// test imm8 to r8
+void TEST8ItoM( uptr to, u8 from );
+
+// sets r8
+void SETS8R( x86IntRegType to );
+// setl r8
+void SETL8R( x86IntRegType to );
+// setge r8
+void SETGE8R( x86IntRegType to );
+// setge r8
+void SETG8R( x86IntRegType to );
+// seta r8
+void SETA8R( x86IntRegType to );
+// setae r8
+void SETAE8R( x86IntRegType to );
+// setb r8
+void SETB8R( x86IntRegType to );
+// setnz r8
+void SETNZ8R( x86IntRegType to );
+// setz r8
+void SETZ8R( x86IntRegType to );
+// sete r8
+void SETE8R( x86IntRegType to );
+
+// push imm32
+void PUSH32I( u32 from );
+
+#ifdef __x86_64__
+void PUSHI( u32 from );
+// push r64
+void PUSH64R( x86IntRegType from );
+// push m64
+void PUSH64M( uptr from );
+// pop r32
+void POP64R( x86IntRegType from );
+#else
+// push r32
+void PUSH32R( x86IntRegType from );
+// push m32
+void PUSH32M( u32 from );
+// push imm32
+void PUSH32I( u32 from );
+// pop r32
+void POP32R( x86IntRegType from );
+// pushad
+void PUSHA32( void );
+// popad
+void POPA32( void );
+#endif
+
+void PUSHR(x86IntRegType from);
+void POPR(x86IntRegType from);
+
+// pushfd
+void PUSHFD( void );
+// popfd
+void POPFD( void );
+// ret
+void RET( void );
+// ret (2-byte code used for misprediction)
+void RET2( void );
+
+void CBW();
+void CWDE();
+// cwd
+void CWD( void );
+// cdq
+void CDQ( void );
+// cdqe
+void CDQE( void );
+
+void LAHF();
+void SAHF();
+
+void BT32ItoR( x86IntRegType to, x86IntRegType from );
+void BSRRtoR(x86IntRegType to, x86IntRegType from);
+void BSWAP32R( x86IntRegType to );
+
+// to = from + offset
+void LEA16RtoR(x86IntRegType to, x86IntRegType from, u16 offset);
+void LEA32RtoR(x86IntRegType to, x86IntRegType from, u32 offset);
+
+// to = from0 + from1
+void LEA16RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1);
+void LEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1);
+
+// to = from << scale (max is 3)
+void LEA16RStoR(x86IntRegType to, x86IntRegType from, u32 scale);
+void LEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale);
+
+//******************
+// FPU instructions
+//******************
+
+// fild m32 to fpu reg stack
+void FILD32( uptr from );
+// fistp m32 from fpu reg stack
+void FISTP32( uptr from );
+// fld m32 to fpu reg stack
+void FLD32( uptr from );
+// fld st(i)
+void FLD(int st);
+// fld1 (push +1.0f on the stack)
+void FLD1();
+// fld1 (push log_2 e on the stack)
+void FLDL2E();
+// fst m32 from fpu reg stack
+void FST32( uptr to );
+// fstp m32 from fpu reg stack
+void FSTP32( uptr to );
+// fstp st(i)
+void FSTP(int st);
+
+// fldcw fpu control word from m16
+void FLDCW( uptr from );
+// fstcw fpu control word to m16
+void FNSTCW( uptr to );
+void FXAM();
+void FDECSTP();
+// frndint
+void FRNDINT();
+void FXCH(int st);
+void F2XM1();
+void FSCALE();
+
+// fadd ST(src) to fpu reg stack ST(0)
+void FADD32Rto0( x86IntRegType src );
+// fadd ST(0) to fpu reg stack ST(src)
+void FADD320toR( x86IntRegType src );
+// fsub ST(src) to fpu reg stack ST(0)
+void FSUB32Rto0( x86IntRegType src );
+// fsub ST(0) to fpu reg stack ST(src)
+void FSUB320toR( x86IntRegType src );
+// fsubp -> subtract ST(0) from ST(1), store in ST(1) and POP stack
+void FSUBP( void );
+// fmul ST(src) to fpu reg stack ST(0)
+void FMUL32Rto0( x86IntRegType src );
+// fmul ST(0) to fpu reg stack ST(src)
+void FMUL320toR( x86IntRegType src );
+// fdiv ST(src) to fpu reg stack ST(0)
+void FDIV32Rto0( x86IntRegType src );
+// fdiv ST(0) to fpu reg stack ST(src)
+void FDIV320toR( x86IntRegType src );
+// fdiv ST(0) to fpu reg stack ST(src), pop stack, store in ST(src)
+void FDIV320toRP( x86IntRegType src );
+
+// fadd m32 to fpu reg stack
+void FADD32( uptr from );
+// fsub m32 to fpu reg stack
+void FSUB32( uptr from );
+// fmul m32 to fpu reg stack
+void FMUL32( uptr from );
+// fdiv m32 to fpu reg stack
+void FDIV32( uptr from );
+// fcomi st, st( i)
+void FCOMI( x86IntRegType src );
+// fcomip st, st( i)
+void FCOMIP( x86IntRegType src );
+// fucomi st, st( i)
+void FUCOMI( x86IntRegType src );
+// fucomip st, st( i)
+void FUCOMIP( x86IntRegType src );
+// fcom m32 to fpu reg stack
+void FCOM32( uptr from );
+// fabs fpu reg stack
+void FABS( void );
+// fsqrt fpu reg stack
+void FSQRT( void );
+// ftan fpu reg stack
+void FPATAN( void );
+// fsin fpu reg stack
+void FSIN( void );
+// fchs fpu reg stack
+void FCHS( void );
+
+// fcmovb fpu reg to fpu reg stack
+void FCMOVB32( x86IntRegType from );
+// fcmove fpu reg to fpu reg stack
+void FCMOVE32( x86IntRegType from );
+// fcmovbe fpu reg to fpu reg stack
+void FCMOVBE32( x86IntRegType from );
+// fcmovu fpu reg to fpu reg stack
+void FCMOVU32( x86IntRegType from );
+// fcmovnb fpu reg to fpu reg stack
+void FCMOVNB32( x86IntRegType from );
+// fcmovne fpu reg to fpu reg stack
+void FCMOVNE32( x86IntRegType from );
+// fcmovnbe fpu reg to fpu reg stack
+void FCMOVNBE32( x86IntRegType from );
+// fcmovnu fpu reg to fpu reg stack
+void FCMOVNU32( x86IntRegType from );
+void FCOMP32( uptr from );
+void FNSTSWtoAX( void );
+
+// probably a little extreme here, but x86-64 should NOT use MMX
+#ifdef __x86_64__
+
+#define MMXONLY(code)
+
+#else
+
+#define MMXONLY(code) code
+
+//******************
+// MMX instructions
+//******************
+
+// r64 = mm
+
+// movq m64 to r64
+void MOVQMtoR( x86MMXRegType to, uptr from );
+// movq r64 to m64
+void MOVQRtoM( uptr to, x86MMXRegType from );
+
+// pand r64 to r64
+void PANDRtoR( x86MMXRegType to, x86MMXRegType from );
+void PANDNRtoR( x86MMXRegType to, x86MMXRegType from );
+// pand m64 to r64 ;
+void PANDMtoR( x86MMXRegType to, uptr from );
+// pandn r64 to r64
+void PANDNRtoR( x86MMXRegType to, x86MMXRegType from );
+// pandn r64 to r64
+void PANDNMtoR( x86MMXRegType to, uptr from );
+// por r64 to r64
+void PORRtoR( x86MMXRegType to, x86MMXRegType from );
+// por m64 to r64
+void PORMtoR( x86MMXRegType to, uptr from );
+// pxor r64 to r64
+void PXORRtoR( x86MMXRegType to, x86MMXRegType from );
+// pxor m64 to r64
+void PXORMtoR( x86MMXRegType to, uptr from );
+
+// psllq r64 to r64
+void PSLLQRtoR( x86MMXRegType to, x86MMXRegType from );
+// psllq m64 to r64
+void PSLLQMtoR( x86MMXRegType to, uptr from );
+// psllq imm8 to r64
+void PSLLQItoR( x86MMXRegType to, u8 from );
+// psrlq r64 to r64
+void PSRLQRtoR( x86MMXRegType to, x86MMXRegType from );
+// psrlq m64 to r64
+void PSRLQMtoR( x86MMXRegType to, uptr from );
+// psrlq imm8 to r64
+void PSRLQItoR( x86MMXRegType to, u8 from );
+
+// paddusb r64 to r64
+void PADDUSBRtoR( x86MMXRegType to, x86MMXRegType from );
+// paddusb m64 to r64
+void PADDUSBMtoR( x86MMXRegType to, uptr from );
+// paddusw r64 to r64
+void PADDUSWRtoR( x86MMXRegType to, x86MMXRegType from );
+// paddusw m64 to r64
+void PADDUSWMtoR( x86MMXRegType to, uptr from );
+
+// paddb r64 to r64
+void PADDBRtoR( x86MMXRegType to, x86MMXRegType from );
+// paddb m64 to r64
+void PADDBMtoR( x86MMXRegType to, uptr from );
+// paddw r64 to r64
+void PADDWRtoR( x86MMXRegType to, x86MMXRegType from );
+// paddw m64 to r64
+void PADDWMtoR( x86MMXRegType to, uptr from );
+// paddd r64 to r64
+void PADDDRtoR( x86MMXRegType to, x86MMXRegType from );
+// paddd m64 to r64
+void PADDDMtoR( x86MMXRegType to, uptr from );
+void PADDSBRtoR( x86MMXRegType to, x86MMXRegType from );
+void PADDSWRtoR( x86MMXRegType to, x86MMXRegType from );
+
+// paddq m64 to r64 (sse2 only?)
+void PADDQMtoR( x86MMXRegType to, uptr from );
+// paddq r64 to r64 (sse2 only?)
+void PADDQRtoR( x86MMXRegType to, x86MMXRegType from );
+
+void PSUBSBRtoR( x86MMXRegType to, x86MMXRegType from );
+void PSUBSWRtoR( x86MMXRegType to, x86MMXRegType from );
+
+void PSUBBRtoR( x86MMXRegType to, x86MMXRegType from );
+void PSUBWRtoR( x86MMXRegType to, x86MMXRegType from );
+void PSUBDRtoR( x86MMXRegType to, x86MMXRegType from );
+void PSUBDMtoR( x86MMXRegType to, uptr from );
+
+// psubq m64 to r64 (sse2 only?)
+void PSUBQMtoR( x86MMXRegType to, uptr from );
+// psubq r64 to r64 (sse2 only?)
+void PSUBQRtoR( x86MMXRegType to, x86MMXRegType from );
+
+// pmuludq m64 to r64 (sse2 only?)
+void PMULUDQMtoR( x86MMXRegType to, uptr from );
+// pmuludq r64 to r64 (sse2 only?)
+void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from );
+
+void PCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from );
+void PCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from );
+void PCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from );
+void PCMPEQDMtoR( x86MMXRegType to, uptr from );
+void PCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from );
+void PCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from );
+void PCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from );
+void PCMPGTDMtoR( x86MMXRegType to, uptr from );
+void PSRLWItoR( x86MMXRegType to, u8 from );
+void PSRLDItoR( x86MMXRegType to, u8 from );
+void PSRLDRtoR( x86MMXRegType to, x86MMXRegType from );
+void PSLLWItoR( x86MMXRegType to, u8 from );
+void PSLLDItoR( x86MMXRegType to, u8 from );
+void PSLLDRtoR( x86MMXRegType to, x86MMXRegType from );
+void PSRAWItoR( x86MMXRegType to, u8 from );
+void PSRADItoR( x86MMXRegType to, u8 from );
+void PSRADRtoR( x86MMXRegType to, x86MMXRegType from );
+void PUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from );
+void PUNPCKLDQMtoR( x86MMXRegType to, uptr from );
+void PUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from );
+void PUNPCKHDQMtoR( x86MMXRegType to, uptr from );
+void MOVQ64ItoR( x86MMXRegType reg, u64 i ); //Prototype.Todo add all consts to end of block.not after jr $+8
+void MOVQRtoR( x86MMXRegType to, x86MMXRegType from );
+void MOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset );
+void MOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset );
+void MOVDMtoMMX( x86MMXRegType to, uptr from );
+void MOVDMMXtoM( uptr to, x86MMXRegType from );
+void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from );
+void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from );
+void MOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset );
+void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from );
+void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from );
+void MOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset );
+void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 );
+void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8);
+void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8);
+void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from);
+
+// emms
+void EMMS( void );
+
+//**********************************************************************************/
+//PACKSSWB,PACKSSDW: Pack Saturate Signed Word 64bits
+//**********************************************************************************
+void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from);
+void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from);
+
+void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from);
+
+void SSE2_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from);
+void SSE2_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from);
+
+#endif // !__x86_64__
+
+//*********************
+// SSE instructions *
+//*********************
+void SSE_MOVAPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_MOVAPS_XMM_to_M128( uptr to, x86SSERegType from );
+void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSE_MOVUPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_MOVUPS_XMM_to_M128( uptr to, x86SSERegType from );
+
+void SSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from );
+void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from );
+void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MOVSS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
+void SSE_MOVSS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset );
+
+void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from );
+void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_MOVQ_XMM_to_M64( u32 to, x86SSERegType from );
+
+void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from );
+void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from );
+void SSE_MOVLPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
+void SSE_MOVLPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset );
+
+void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from );
+void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from );
+void SSE_MOVHPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
+void SSE_MOVHPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset );
+
+void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from );
+void SSE_MOVLPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset );
+void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from );
+void SSE_MOVLPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset );
+
+void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale );
+void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale );
+void SSE_MOVAPSRtoRmOffset( x86IntRegType to, x86SSERegType from, int offset );
+void SSE_MOVAPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset );
+void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale );
+void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale );
+void SSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from );
+void SSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from );
+
+void SSE_MOVUPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset );
+void SSE_MOVUPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset );
+
+void SSE2_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset );
+void SSE2_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset );
+
+void SSE_RCPPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_RCPPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_RCPSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_RCPSS_M32_to_XMM( x86SSERegType to, uptr from );
+
+void SSE_ORPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_ORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_XORPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_XORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_ANDPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_ANDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_ANDNPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_ANDNPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_ADDPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_ADDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_ADDSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_ADDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_SUBPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_SUBPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_SUBSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_SUBSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MULPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_MULPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MULSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_MULSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPEQSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPEQSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPLTSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPLESS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPUNORDSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPUNORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPNESS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPNESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPNLTSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPNLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPNLESS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPNLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPORDSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSE_UCOMISS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_UCOMISS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+#ifndef __x86_64__
+void SSE_PMAXSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from );
+void SSE_PMINSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from );
+void SSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from );
+void SSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from );
+void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from );
+#endif
+void SSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from );
+void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from);
+void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from);
+void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from);
+void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from);
+
+void SSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSE_MAXPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_MAXPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MAXSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_MAXSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MINPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_MINPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_MINSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_MINSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_RSQRTPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_RSQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_RSQRTSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_RSQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_SQRTPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_SQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_SQRTSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_SQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_UNPCKLPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_UNPCKLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_UNPCKHPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_UNPCKHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 );
+void SSE_SHUFPS_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 );
+void SSE_SHUFPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset, u8 imm8 );
+void SSE_CMPEQPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPEQPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPLTPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPLEPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPUNORDPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPUNORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPNEPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPNEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPNLTPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPNLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPNLEPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPNLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_CMPORDPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_CMPORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_DIVPS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE_DIVPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE_DIVSS_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE_DIVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+// VectorPath
+void SSE2_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 );
+void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 );
+
+void SSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 );
+void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 );
+void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 );
+void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 );
+
+void SSE_STMXCSR( uptr from );
+void SSE_LDMXCSR( uptr from );
+
+
+//*********************
+// SSE 2 Instructions*
+//*********************
+void SSE2_MOVDQA_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from);
+void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from);
+
+void SSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from);
+void SSE2_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from);
+
+void SSE2_PSRLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSRLW_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSRLW_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSRLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSRLD_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSRLD_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSRLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSRLQ_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSRLQ_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSRLDQ_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSRAW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSRAW_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSRAW_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSRAD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSRAD_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSRAD_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSLLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSLLW_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSLLW_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSLLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSLLD_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSLLD_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSLLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PSLLQ_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PSLLQ_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PSLLDQ_I8_to_XMM(x86SSERegType to, u8 imm8);
+void SSE2_PMAXSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PMAXSW_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PMAXUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PMAXUB_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PMINSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PMINSW_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PMINUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PMINUB_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PADDSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PADDSB_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PADDSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PADDSW_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PSUBSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBSB_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PSUBSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBSW_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PSUBUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBUSB_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PSUBUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBUSW_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PAND_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PANDN_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PADDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PADDW_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PADDUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PADDUSB_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PADDUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_PADDUSW_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2_PADDB_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PADDB_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PADDD_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PADDD_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PADDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PADDQ_M128_to_XMM(x86SSERegType to, uptr from );
+
+//**********************************************************************************/
+//PACKSSWB,PACKSSDW: Pack Saturate Signed Word
+//**********************************************************************************
+void SSE2_PACKSSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PACKSSWB_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PACKSSDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PACKSSDW_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE2_PACKUSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PACKUSWB_M128_to_XMM(x86SSERegType to, uptr from);
+
+//**********************************************************************************/
+//PUNPCKHWD: Unpack 16bit high
+//**********************************************************************************
+void SSE2_PUNPCKLBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKLBW_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PUNPCKHBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKHBW_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE2_PUNPCKLWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKLWD_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PUNPCKHWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKHWD_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE2_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE2_PUNPCKLQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKLQDQ_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE2_PUNPCKHQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PUNPCKHQDQ_M128_to_XMM(x86SSERegType to, uptr from);
+
+// mult by half words
+void SSE2_PMULLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PMULLW_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE2_PMULHW_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PMULHW_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE2_PMULUDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE2_PMULUDQ_M128_to_XMM(x86SSERegType to, uptr from);
+
+
+//**********************************************************************************/
+//PMOVMSKB: Create 16bit mask from signs of 8bit integers
+//**********************************************************************************
+void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from);
+
+void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from);
+void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from);
+
+//**********************************************************************************/
+//PEXTRW,PINSRW: Packed Extract/Insert Word *
+//**********************************************************************************
+void SSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 );
+void SSE_PINSRW_R32_to_XMM(x86SSERegType from, x86IntRegType to, u8 imm8 );
+
+
+//**********************************************************************************/
+//PSUBx: Subtract Packed Integers *
+//**********************************************************************************
+void SSE2_PSUBB_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBB_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PSUBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBW_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PSUBD_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBD_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PSUBQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PSUBQ_M128_to_XMM(x86SSERegType to, uptr from );
+///////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PCMPxx: Compare Packed Integers *
+//**********************************************************************************
+void SSE2_PCMPGTB_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PCMPGTB_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PCMPGTW_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PCMPGTW_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PCMPGTD_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PCMPGTD_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PCMPEQB_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PCMPEQB_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PCMPEQW_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PCMPEQW_M128_to_XMM(x86SSERegType to, uptr from );
+void SSE2_PCMPEQD_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
+void SSE2_PCMPEQD_M128_to_XMM(x86SSERegType to, uptr from );
+//**********************************************************************************/
+//MOVD: Move Dword(32bit) to /from XMM reg *
+//**********************************************************************************
+void SSE2_MOVD_M32_to_XMM( x86SSERegType to, uptr from );
+void SSE2_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from );
+void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from );
+void SSE2_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
+void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from );
+void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from );
+void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from );
+void SSE2_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset );
+
+#ifdef __x86_64__
+void SSE2_MOVQ_XMM_to_R( x86IntRegType to, x86SSERegType from );
+void SSE2_MOVQ_R_to_XMM( x86SSERegType to, x86IntRegType from );
+#endif
+
+//**********************************************************************************/
+//POR : SSE Bitwise OR *
+//**********************************************************************************
+void SSE2_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2_POR_M128_to_XMM( x86SSERegType to, uptr from );
+
+void SSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSE3_MOVSLDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE3_MOVSLDUP_M128_to_XMM(x86SSERegType to, uptr from);
+void SSE3_MOVSHDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from);
+//*********************
+// SSE-X - uses both SSE,SSE2 code and tries to keep consistensies between the data
+// Uses g_xmmtypes to infer the correct type.
+//*********************
+void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from );
+void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from );
+void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSEX_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset );
+void SSEX_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset );
+
+void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from );
+void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from );
+void SSEX_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from );
+void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from );
+void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from );
+void SSEX_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
+void SSEX_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset );
+
+void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from );
+void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from );
+void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from );
+void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from );
+void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from);
+void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
+void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from);
+
+void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+
+//*********************
+// 3DNOW instructions *
+//*********************
+void FEMMS( void );
+void PFCMPEQMtoR( x86IntRegType to, uptr from );
+void PFCMPGTMtoR( x86IntRegType to, uptr from );
+void PFCMPGEMtoR( x86IntRegType to, uptr from );
+void PFADDMtoR( x86IntRegType to, uptr from );
+void PFADDRtoR( x86IntRegType to, x86IntRegType from );
+void PFSUBMtoR( x86IntRegType to, uptr from );
+void PFSUBRtoR( x86IntRegType to, x86IntRegType from );
+void PFMULMtoR( x86IntRegType to, uptr from );
+void PFMULRtoR( x86IntRegType to, x86IntRegType from );
+void PFRCPMtoR( x86IntRegType to, uptr from );
+void PFRCPRtoR( x86IntRegType to, x86IntRegType from );
+void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from );
+void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from );
+void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from );
+void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from );
+void PF2IDMtoR( x86IntRegType to, uptr from );
+void PF2IDRtoR( x86IntRegType to, x86IntRegType from );
+void PI2FDMtoR( x86IntRegType to, uptr from );
+void PI2FDRtoR( x86IntRegType to, x86IntRegType from );
+void PFMAXMtoR( x86IntRegType to, uptr from );
+void PFMAXRtoR( x86IntRegType to, x86IntRegType from );
+void PFMINMtoR( x86IntRegType to, uptr from );
+void PFMINRtoR( x86IntRegType to, x86IntRegType from );
+
+void SSE2EMU_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from);
+void SSE2EMU_MOVQ_M64_to_XMM( x86SSERegType to, uptr from);
+void SSE2EMU_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from);
+void SSE2EMU_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
+void SSE2EMU_MOVD_XMM_to_RmOffset(x86IntRegType to, x86SSERegType from, int offset );
+
+#ifndef __x86_64__
+void SSE2EMU_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from);
+void SSE2EMU_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from);
+#endif
+
+/* SSE2 emulated functions for SSE CPU's by kekko*/
+
+void SSE2EMU_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 );
+void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from );
+void SSE2EMU_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
+void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from );
+void SSE2EMU_MOVD_XMM_to_M32( uptr to, x86SSERegType from );
+void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from );
+
+////////////////////////////////////////////////////
+#ifdef _DEBUG
+#define WRITECHECK() CheckX86Ptr()
+#else
+#define WRITECHECK()
+#endif
+
+#define writeVAL(val) ({ \
+ WRITECHECK(); \
+ *(typeof(val)*)x86Ptr = (val); \
+ x86Ptr += sizeof(val); \
+ (void)0; \
+ })
+
+#define write8(val ) writeVAL((u8)(val))
+#define write16(val ) writeVAL((u16)(val))
+#define write32( val ) writeVAL((u32)(val))
+#define write64( val ) writeVAL((u64)(val))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __IX86_H__
diff --git a/libpcsxcore/ix86_64/ix86_3dnow.c b/libpcsxcore/ix86_64/ix86_3dnow.c
new file mode 100644
index 00000000..8fd42333
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86_3dnow.c
@@ -0,0 +1,178 @@
+// stop compiling if NORECBUILD build (only for Visual Studio)
+#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
+
+#include "ix86-64.h"
+
+/**********************/
+/* 3DNOW instructions */
+/**********************/
+
+/* femms */
+void FEMMS( void )
+{
+ write16( 0x0E0F );
+}
+
+void PFCMPEQMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0xB0 );
+}
+
+void PFCMPGTMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0xA0 );
+}
+
+void PFCMPGEMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x90 );
+}
+
+void PFADDMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x9E );
+}
+
+void PFADDRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x9E );
+}
+
+void PFSUBMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x9A );
+}
+
+void PFSUBRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x9A );
+}
+
+void PFMULMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0xB4 );
+}
+
+void PFMULRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0xB4 );
+}
+
+void PFRCPMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x96 );
+}
+
+void PFRCPRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x96 );
+}
+
+void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0xA6 );
+}
+
+void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0xB6 );
+}
+
+void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x97 );
+}
+
+void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0xA7 );
+}
+
+void PF2IDMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x1D );
+}
+
+void PF2IDRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x1D );
+}
+
+void PI2FDMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x0D );
+}
+
+void PI2FDRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x0D );
+}
+
+void PFMAXMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0xA4 );
+}
+
+void PFMAXRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0xA4 );
+}
+
+void PFMINMtoR( x86IntRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
+ write8( 0x94 );
+}
+
+void PFMINRtoR( x86IntRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x0F0F );
+ ModRM( 3, to, from );
+ write8( 0x94 );
+}
+
+#endif
diff --git a/libpcsxcore/ix86_64/ix86_cpudetect.c b/libpcsxcore/ix86_64/ix86_cpudetect.c
new file mode 100644
index 00000000..f34292a6
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86_cpudetect.c
@@ -0,0 +1,487 @@
+/* Cpudetection lib
+ * Copyright (C) 2002-2003 Pcsx2 Team
+ *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+#if defined (_WIN32)
+#include <windows.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ix86-64.h"
+
+#if defined (_MSC_VER) && _MSC_VER >= 1400
+
+ void __cpuid(int* CPUInfo, int InfoType);
+ unsigned __int64 __rdtsc();
+
+ #pragma intrinsic(__cpuid)
+ #pragma intrinsic(__rdtsc)
+
+#endif
+
+CAPABILITIES cpucaps;
+CPUINFO cpuinfo;
+
+#define cpuid(cmd,a,b,c,d) \
+ __asm__ __volatile__("cpuid" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (cmd))
+
+static s32 iCpuId( u32 cmd, u32 *regs )
+{
+ int flag=1;
+
+#if defined (_MSC_VER) && _MSC_VER >= 1400
+
+ __cpuid( regs, cmd );
+
+ return 0;
+
+#elif defined (_MSC_VER)
+
+#ifdef __x86_64__
+ assert(0);
+#else // __x86_64__
+ __asm
+ {
+ push ebx;
+ push edi;
+
+ pushfd;
+ pop eax;
+ mov edx, eax;
+ xor eax, 1 << 21;
+ push eax;
+ popfd;
+ pushfd;
+ pop eax;
+ xor eax, edx;
+ mov flag, eax;
+ }
+ if ( ! flag )
+ {
+ return -1;
+ }
+
+ __asm
+ {
+ mov eax, cmd;
+ cpuid;
+ mov edi, [regs]
+ mov [edi], eax;
+ mov [edi+4], ebx;
+ mov [edi+8], ecx;
+ mov [edi+12], edx;
+
+ pop edi;
+ pop ebx;
+ }
+#endif // __x86_64__
+ return 0;
+
+
+#else
+
+#ifndef __x86_64__
+ // see if we can use cpuid
+ __asm__ __volatile__ (
+ "sub $0x18, %%esp\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "mov %%eax, %%edx\n"
+ "xor $0x200000, %%eax\n"
+ "push %%eax\n"
+ "popf\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "xor %%edx, %%eax\n"
+ "mov %%eax, %0\n"
+ "add $0x18, %%esp\n"
+ : "=r"(flag) :
+ );
+#endif
+
+ if ( !flag )
+ return -1;
+
+ cpuid(cmd, regs[0], regs[1], regs[2], regs[3]);
+ return 0;
+#endif // _MSC_VER
+}
+
+u64 GetCPUTick( void )
+{
+#if defined (_MSC_VER) && _MSC_VER >= 1400
+
+ return __rdtsc();
+
+#elif defined(__MSCW32__) && !defined(__x86_64__)
+
+ __asm rdtsc;
+
+#else
+
+ u32 _a, _d;
+ __asm__ __volatile__ ("rdtsc" : "=a"(_a), "=d"(_d));
+ return (u64)_a | ((u64)_d << 32);
+
+#endif
+}
+
+#if defined __LINUX__
+
+#include <sys/time.h>
+#include <errno.h>
+//*
+unsigned long timeGetTime2()
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0); // well, maybe there are better ways
+ return (unsigned long)tv.tv_sec * 1000 + tv.tv_usec/1000; // to do that, but at least it works
+}
+//*/
+#endif
+
+s64 CPUSpeedHz( unsigned int time )
+{
+ s64 timeStart,
+ timeStop;
+ s64 startTick,
+ endTick;
+ s64 overhead;
+
+ if( ! cpucaps.hasTimeStampCounter )
+ {
+ return 0; //check if function is supported
+ }
+
+ overhead = GetCPUTick() - GetCPUTick();
+
+ timeStart = timeGetTime2( );
+ while( timeGetTime2( ) == timeStart )
+ {
+ timeStart = timeGetTime2( );
+ }
+ for(;;)
+ {
+ timeStop = timeGetTime2( );
+ if ( ( timeStop - timeStart ) > 1 )
+ {
+ startTick = GetCPUTick( );
+ break;
+ }
+ }
+
+ timeStart = timeStop;
+ for(;;)
+ {
+ timeStop = timeGetTime2( );
+ if ( ( timeStop - timeStart ) > time )
+ {
+ endTick = GetCPUTick( );
+ break;
+ }
+ }
+
+ return (s64)( ( endTick - startTick ) + ( overhead ) );
+}
+
+////////////////////////////////////////////////////
+void cpudetectInit( void )
+{
+ u32 regs[ 4 ];
+ u32 cmds;
+ u32 AMDspeed;
+ s8 AMDspeedString[10];
+ int cputype=0; // Cpu type
+ //AMD 64 STUFF
+ u32 x86_64_8BITBRANDID;
+ u32 x86_64_12BITBRANDID;
+ memset( cpuinfo.x86ID, 0, sizeof( cpuinfo.x86ID ) );
+ cpuinfo.x86Family = 0;
+ cpuinfo.x86Model = 0;
+ cpuinfo.x86PType = 0;
+ cpuinfo.x86StepID = 0;
+ cpuinfo.x86Flags = 0;
+ cpuinfo.x86EFlags = 0;
+
+ if ( iCpuId( 0, regs ) == -1 ) return;
+
+ cmds = regs[ 0 ];
+ ((u32*)cpuinfo.x86ID)[ 0 ] = regs[ 1 ];
+ ((u32*)cpuinfo.x86ID)[ 1 ] = regs[ 3 ];
+ ((u32*)cpuinfo.x86ID)[ 2 ] = regs[ 2 ];
+ if ( cmds >= 0x00000001 )
+ {
+ if ( iCpuId( 0x00000001, regs ) != -1 )
+ {
+ cpuinfo.x86StepID = regs[ 0 ] & 0xf;
+ cpuinfo.x86Model = (regs[ 0 ] >> 4) & 0xf;
+ cpuinfo.x86Family = (regs[ 0 ] >> 8) & 0xf;
+ cpuinfo.x86PType = (regs[ 0 ] >> 12) & 0x3;
+ x86_64_8BITBRANDID = regs[1] & 0xff;
+ cpuinfo.x86Flags = regs[ 3 ];
+ }
+ }
+ if ( iCpuId( 0x80000000, regs ) != -1 )
+ {
+ cmds = regs[ 0 ];
+ if ( cmds >= 0x80000001 )
+ {
+ if ( iCpuId( 0x80000001, regs ) != -1 )
+ {
+ x86_64_12BITBRANDID = regs[1] & 0xfff;
+ cpuinfo.x86EFlags = regs[ 3 ];
+
+ }
+ }
+ }
+ switch(cpuinfo.x86PType)
+ {
+ case 0:
+ strcpy( cpuinfo.x86Type, "Standard OEM");
+ break;
+ case 1:
+ strcpy( cpuinfo.x86Type, "Overdrive");
+ break;
+ case 2:
+ strcpy( cpuinfo.x86Type, "Dual");
+ break;
+ case 3:
+ strcpy( cpuinfo.x86Type, "Reserved");
+ break;
+ default:
+ strcpy( cpuinfo.x86Type, "Unknown");
+ break;
+ }
+ if ( cpuinfo.x86ID[ 0 ] == 'G' ){ cputype=0;}//trick lines but if you know a way better ;p
+ if ( cpuinfo.x86ID[ 0 ] == 'A' ){ cputype=1;}
+
+ if ( cputype == 0 ) //intel cpu
+ {
+ if( ( cpuinfo.x86Family >= 7 ) && ( cpuinfo.x86Family < 15 ) )
+ {
+ strcpy( cpuinfo.x86Fam, "Intel P6 family (Not PIV and Higher then PPro" );
+ }
+ else
+ {
+ switch( cpuinfo.x86Family )
+ {
+ // Start at 486 because if it's below 486 there is no cpuid instruction
+ case 4:
+ strcpy( cpuinfo.x86Fam, "Intel 486" );
+ break;
+ case 5:
+ switch( cpuinfo.x86Model )
+ {
+ case 4:
+ case 8: // 0.25 µm
+ strcpy( cpuinfo.x86Fam, "Intel Pentium (MMX)");
+ break;
+ default:
+ strcpy( cpuinfo.x86Fam, "Intel Pentium" );
+ }
+ break;
+ case 6:
+ switch( cpuinfo.x86Model )
+ {
+ case 0: // Pentium pro (P6 A-Step)
+ case 1: // Pentium pro
+ strcpy( cpuinfo.x86Fam, "Intel Pentium Pro" );
+ break;
+
+ case 2: // 66 MHz FSB
+ case 5: // Xeon/Celeron (0.25 µm)
+ case 6: // Internal L2 cache
+ strcpy( cpuinfo.x86Fam, "Intel Pentium II" );
+ break;
+
+ case 7: // Xeon external L2 cache
+ case 8: // Xeon/Celeron with 256 KB on-die L2 cache
+ case 10: // Xeon/Celeron with 1 or 2 MB on-die L2 cache
+ case 11: // Xeon/Celeron with Tualatin core, on-die cache
+ strcpy( cpuinfo.x86Fam, "Intel Pentium III" );
+ break;
+ case 15: // Core 2 Duo Allendale/Conroe
+ strcpy( cpuinfo.x86Fam, "Intel Core 2 Duo" );
+ break;
+
+ default:
+ strcpy( cpuinfo.x86Fam, "Intel Pentium Pro (Unknown)" );
+ }
+ break;
+ case 15:
+ switch( cpuinfo.x86Model )
+ {
+ case 0: // Willamette (A-Step)
+ case 1: // Willamette
+ strcpy( cpuinfo.x86Fam, "Willamette Intel Pentium IV" );
+ break;
+ case 2: // Northwood
+ strcpy( cpuinfo.x86Fam, "Northwood Intel Pentium IV" );
+ break;
+
+ default:
+ strcpy( cpuinfo.x86Fam, "Intel Pentium IV (Unknown)" );
+ break;
+ }
+ break;
+ default:
+ strcpy( cpuinfo.x86Fam, "Unknown Intel CPU" );
+ }
+ }
+ }
+ else if ( cputype == 1 ) //AMD cpu
+ {
+ if( cpuinfo.x86Family >= 7 )
+ {
+ if((x86_64_12BITBRANDID !=0) || (x86_64_8BITBRANDID !=0))
+ {
+ if(x86_64_8BITBRANDID == 0 )
+ {
+ switch((x86_64_12BITBRANDID >>6)& 0x3f)
+ {
+ case 4:
+ strcpy(cpuinfo.x86Fam,"AMD Athlon(tm) 64 Processor");
+ AMDspeed = 22 + (x86_64_12BITBRANDID & 0x1f);
+ //AMDspeedString = strtol(AMDspeed, (char**)NULL,10);
+ sprintf(AMDspeedString," %d",AMDspeed);
+ strcat(AMDspeedString,"00+");
+ strcat(cpuinfo.x86Fam,AMDspeedString);
+ break;
+ case 12:
+ strcpy(cpuinfo.x86Fam,"AMD Opteron(tm) Processor");
+ break;
+ case 5:
+ strcpy( cpuinfo.x86Fam, "AMD Athlon X2 Processor" );
+ AMDspeed = 22 + (x86_64_12BITBRANDID & 0x1f);
+ //AMDspeedString = strtol(AMDspeed, (char**)NULL,10);
+ sprintf(AMDspeedString," %d",AMDspeed);
+ strcat(AMDspeedString,"00+");
+ strcat(cpuinfo.x86Fam,AMDspeedString);
+ break;
+ case 44:
+ strcpy( cpuinfo.x86Fam, "AMD Opteron(tm) Dual Core Processor" );
+ break;
+ default:
+ strcpy(cpuinfo.x86Fam,"Unknown AMD 64 proccesor");
+
+ }
+ }
+ else //8bit brand id is non zero
+ {
+ strcpy(cpuinfo.x86Fam,"Unsupported yet AMD64 cpu");
+ }
+ }
+ else
+ {
+ strcpy( cpuinfo.x86Fam, "AMD K7+ Processor" );
+ }
+ }
+ else
+ {
+ switch ( cpuinfo.x86Family )
+ {
+ case 4:
+ switch( cpuinfo.x86Model )
+ {
+ case 14:
+ case 15: // Write-back enhanced
+ strcpy( cpuinfo.x86Fam, "AMD 5x86 Processor" );
+ break;
+
+ case 3: // DX2
+ case 7: // Write-back enhanced DX2
+ case 8: // DX4
+ case 9: // Write-back enhanced DX4
+ strcpy( cpuinfo.x86Fam, "AMD 486 Processor" );
+ break;
+
+
+ default:
+ strcpy( cpuinfo.x86Fam, "AMD Unknown Processor" );
+
+ }
+ break;
+
+ case 5:
+ switch( cpuinfo.x86Model)
+ {
+ case 0: // SSA 5 (75, 90 and 100 Mhz)
+ case 1: // 5k86 (PR 120 and 133 MHz)
+ case 2: // 5k86 (PR 166 MHz)
+ case 3: // K5 5k86 (PR 200 MHz)
+ strcpy( cpuinfo.x86Fam, "AMD K5 Processor" );
+ break;
+
+ case 6:
+ case 7: // (0.25 µm)
+ case 8: // K6-2
+ case 9: // K6-III
+ case 14: // K6-2+ / K6-III+
+ strcpy( cpuinfo.x86Fam, "AMD K6 Series Processor" );
+ break;
+
+ default:
+ strcpy( cpuinfo.x86Fam, "AMD Unknown Processor" );
+ }
+ break;
+ case 6:
+ strcpy( cpuinfo.x86Fam, "AMD Athlon XP Processor" );
+ break;
+ default:
+ strcpy( cpuinfo.x86Fam, "Unknown AMD CPU" );
+ }
+ }
+ }
+ //capabilities
+ cpucaps.hasFloatingPointUnit = ( cpuinfo.x86Flags >> 0 ) & 1;
+ cpucaps.hasVirtual8086ModeEnhancements = ( cpuinfo.x86Flags >> 1 ) & 1;
+ cpucaps.hasDebuggingExtensions = ( cpuinfo.x86Flags >> 2 ) & 1;
+ cpucaps.hasPageSizeExtensions = ( cpuinfo.x86Flags >> 3 ) & 1;
+ cpucaps.hasTimeStampCounter = ( cpuinfo.x86Flags >> 4 ) & 1;
+ cpucaps.hasModelSpecificRegisters = ( cpuinfo.x86Flags >> 5 ) & 1;
+ cpucaps.hasPhysicalAddressExtension = ( cpuinfo.x86Flags >> 6 ) & 1;
+ cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 7 ) & 1;
+ cpucaps.hasCOMPXCHG8BInstruction = ( cpuinfo.x86Flags >> 8 ) & 1;
+ cpucaps.hasAdvancedProgrammableInterruptController = ( cpuinfo.x86Flags >> 9 ) & 1;
+ cpucaps.hasSEPFastSystemCall = ( cpuinfo.x86Flags >> 11 ) & 1;
+ cpucaps.hasMemoryTypeRangeRegisters = ( cpuinfo.x86Flags >> 12 ) & 1;
+ cpucaps.hasPTEGlobalFlag = ( cpuinfo.x86Flags >> 13 ) & 1;
+ cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 14 ) & 1;
+ cpucaps.hasConditionalMoveAndCompareInstructions = ( cpuinfo.x86Flags >> 15 ) & 1;
+ cpucaps.hasFGPageAttributeTable = ( cpuinfo.x86Flags >> 16 ) & 1;
+ cpucaps.has36bitPageSizeExtension = ( cpuinfo.x86Flags >> 17 ) & 1;
+ cpucaps.hasProcessorSerialNumber = ( cpuinfo.x86Flags >> 18 ) & 1;
+ cpucaps.hasCFLUSHInstruction = ( cpuinfo.x86Flags >> 19 ) & 1;
+ cpucaps.hasDebugStore = ( cpuinfo.x86Flags >> 21 ) & 1;
+ cpucaps.hasACPIThermalMonitorAndClockControl = ( cpuinfo.x86Flags >> 22 ) & 1;
+ cpucaps.hasMultimediaExtensions = ( cpuinfo.x86Flags >> 23 ) & 1; //mmx
+ cpucaps.hasFastStreamingSIMDExtensionsSaveRestore = ( cpuinfo.x86Flags >> 24 ) & 1;
+ cpucaps.hasStreamingSIMDExtensions = ( cpuinfo.x86Flags >> 25 ) & 1; //sse
+ cpucaps.hasStreamingSIMD2Extensions = ( cpuinfo.x86Flags >> 26 ) & 1; //sse2
+ cpucaps.hasSelfSnoop = ( cpuinfo.x86Flags >> 27 ) & 1;
+ cpucaps.hasHyperThreading = ( cpuinfo.x86Flags >> 28 ) & 1;
+ cpucaps.hasThermalMonitor = ( cpuinfo.x86Flags >> 29 ) & 1;
+ cpucaps.hasIntel64BitArchitecture = ( cpuinfo.x86Flags >> 30 ) & 1;
+ //that is only for AMDs
+ cpucaps.hasMultimediaExtensionsExt = ( cpuinfo.x86EFlags >> 22 ) & 1; //mmx2
+ cpucaps.hasAMD64BitArchitecture = ( cpuinfo.x86EFlags >> 29 ) & 1; //64bit cpu
+ cpucaps.has3DNOWInstructionExtensionsExt = ( cpuinfo.x86EFlags >> 30 ) & 1; //3dnow+
+ cpucaps.has3DNOWInstructionExtensions = ( cpuinfo.x86EFlags >> 31 ) & 1; //3dnow
+ cpuinfo.cpuspeed = (u32 )(CPUSpeedHz( 1000 ) / 1000000);
+}
diff --git a/libpcsxcore/ix86_64/ix86_fpu.c b/libpcsxcore/ix86_64/ix86_fpu.c
new file mode 100644
index 00000000..ca49eb7c
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86_fpu.c
@@ -0,0 +1,248 @@
+// stop compiling if NORECBUILD build (only for Visual Studio)
+#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
+
+#include <stdio.h>
+#include <string.h>
+#include "ix86-64.h"
+
+/********************/
+/* FPU instructions */
+/********************/
+
+/* fild m32 to fpu reg stack */
+void FILD32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xDB), false, 0, from, 0);
+}
+
+/* fistp m32 from fpu reg stack */
+void FISTP32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xDB), false, 3, from, 0);
+}
+
+/* fld m32 to fpu reg stack */
+void FLD32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD9), false, 0, from, 0);
+}
+
+// fld st(i)
+void FLD(int st) { write16(0xc0d9+(st<<8)); }
+
+void FLD1() { write16(0xe8d9); }
+void FLDL2E() { write16(0xead9); }
+
+/* fst m32 from fpu reg stack */
+void FST32( uptr to )
+{
+ MEMADDR_OP(0, VAROP1(0xD9), false, 2, to, 0);
+}
+
+/* fstp m32 from fpu reg stack */
+void FSTP32( uptr to )
+{
+ MEMADDR_OP(0, VAROP1(0xD9), false, 3, to, 0);
+}
+
+// fstp st(i)
+void FSTP(int st) { write16(0xd8dd+(st<<8)); }
+
+/* fldcw fpu control word from m16 */
+void FLDCW( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD9), false, 5, from, 0);
+}
+
+/* fnstcw fpu control word to m16 */
+void FNSTCW( uptr to )
+{
+ MEMADDR_OP(0, VAROP1(0xD9), false, 7, to, 0);
+}
+
+void FNSTSWtoAX( void )
+{
+ write16( 0xE0DF );
+}
+
+void FXAM()
+{
+ write16(0xe5d9);
+}
+
+void FDECSTP() { write16(0xf6d9); }
+void FRNDINT() { write16(0xfcd9); }
+void FXCH(int st) { write16(0xc8d9+(st<<8)); }
+void F2XM1() { write16(0xf0d9); }
+void FSCALE() { write16(0xfdd9); }
+
+/* fadd ST(src) to fpu reg stack ST(0) */
+void FADD32Rto0( x86IntRegType src )
+{
+ write8( 0xD8 );
+ write8( 0xC0 + src );
+}
+
+/* fadd ST(0) to fpu reg stack ST(src) */
+void FADD320toR( x86IntRegType src )
+{
+ write8( 0xDC );
+ write8( 0xC0 + src );
+}
+
+/* fsub ST(src) to fpu reg stack ST(0) */
+void FSUB32Rto0( x86IntRegType src )
+{
+ write8( 0xD8 );
+ write8( 0xE0 + src );
+}
+
+/* fsub ST(0) to fpu reg stack ST(src) */
+void FSUB320toR( x86IntRegType src )
+{
+ write8( 0xDC );
+ write8( 0xE8 + src );
+}
+
+/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */
+void FSUBP( void )
+{
+ write8( 0xDE );
+ write8( 0xE9 );
+}
+
+/* fmul ST(src) to fpu reg stack ST(0) */
+void FMUL32Rto0( x86IntRegType src )
+{
+ write8( 0xD8 );
+ write8( 0xC8 + src );
+}
+
+/* fmul ST(0) to fpu reg stack ST(src) */
+void FMUL320toR( x86IntRegType src )
+{
+ write8( 0xDC );
+ write8( 0xC8 + src );
+}
+
+/* fdiv ST(src) to fpu reg stack ST(0) */
+void FDIV32Rto0( x86IntRegType src )
+{
+ write8( 0xD8 );
+ write8( 0xF0 + src );
+}
+
+/* fdiv ST(0) to fpu reg stack ST(src) */
+void FDIV320toR( x86IntRegType src )
+{
+ write8( 0xDC );
+ write8( 0xF8 + src );
+}
+
+void FDIV320toRP( x86IntRegType src )
+{
+ write8( 0xDE );
+ write8( 0xF8 + src );
+}
+
+/* fadd m32 to fpu reg stack */
+void FADD32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD8), false, 0, from, 0);
+}
+
+/* fsub m32 to fpu reg stack */
+void FSUB32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD8), false, 4, from, 0);
+}
+
+/* fmul m32 to fpu reg stack */
+void FMUL32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD8), false, 1, from, 0);
+}
+
+/* fdiv m32 to fpu reg stack */
+void FDIV32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD8), false, 6, from, 0);
+}
+
+/* fabs fpu reg stack */
+void FABS( void )
+{
+ write16( 0xE1D9 );
+}
+
+/* fsqrt fpu reg stack */
+void FSQRT( void )
+{
+ write16( 0xFAD9 );
+}
+
+void FPATAN(void) { write16(0xf3d9); }
+void FSIN(void) { write16(0xfed9); }
+
+/* fchs fpu reg stack */
+void FCHS( void )
+{
+ write16( 0xE0D9 );
+}
+
+/* fcomi st, st(i) */
+void FCOMI( x86IntRegType src )
+{
+ write8( 0xDB );
+ write8( 0xF0 + src );
+}
+
+/* fcomip st, st(i) */
+void FCOMIP( x86IntRegType src )
+{
+ write8( 0xDF );
+ write8( 0xF0 + src );
+}
+
+/* fucomi st, st(i) */
+void FUCOMI( x86IntRegType src )
+{
+ write8( 0xDB );
+ write8( 0xE8 + src );
+}
+
+/* fucomip st, st(i) */
+void FUCOMIP( x86IntRegType src )
+{
+ write8( 0xDF );
+ write8( 0xE8 + src );
+}
+
+/* fcom m32 to fpu reg stack */
+void FCOM32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD8), false, 2, from, 0);
+}
+
+/* fcomp m32 to fpu reg stack */
+void FCOMP32( uptr from )
+{
+ MEMADDR_OP(0, VAROP1(0xD8), false, 3, from, 0);
+}
+
+#define FCMOV32( low, high ) \
+ { \
+ write8( low ); \
+ write8( high + from ); \
+ }
+
+void FCMOVB32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC0 ); }
+void FCMOVE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC8 ); }
+void FCMOVBE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD0 ); }
+void FCMOVU32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD8 ); }
+void FCMOVNB32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC0 ); }
+void FCMOVNE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC8 ); }
+void FCMOVNBE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD0 ); }
+void FCMOVNU32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD8 ); }
+
+#endif
diff --git a/libpcsxcore/ix86_64/ix86_mmx.c b/libpcsxcore/ix86_64/ix86_mmx.c
new file mode 100644
index 00000000..eddbbfcc
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86_mmx.c
@@ -0,0 +1,646 @@
+// stop compiling if NORECBUILD build (only for Visual Studio)
+#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
+
+#include "ix86-64.h"
+
+#include <assert.h>
+
+/********************/
+/* MMX instructions */
+/********************/
+
+// r64 = mm
+
+/* movq m64 to r64 */
+void MOVQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x6F), true, to, from, 0);
+}
+
+/* movq r64 to m64 */
+void MOVQRtoM( uptr to, x86MMXRegType from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x7F), true, from, to, 0);
+}
+
+/* pand r64 to r64 */
+void PANDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xDB0F );
+ ModRM( 3, to, from );
+}
+
+void PANDNRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xDF0F );
+ ModRM( 3, to, from );
+}
+
+/* por r64 to r64 */
+void PORRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xEB0F );
+ ModRM( 3, to, from );
+}
+
+/* pxor r64 to r64 */
+void PXORRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xEF0F );
+ ModRM( 3, to, from );
+}
+
+/* psllq r64 to r64 */
+void PSLLQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xF30F );
+ ModRM( 3, to, from );
+}
+
+/* psllq m64 to r64 */
+void PSLLQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xF3), true, to, from, 0);
+}
+
+/* psllq imm8 to r64 */
+void PSLLQItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x730F );
+ ModRM( 3, 6, to);
+ write8( from );
+}
+
+/* psrlq r64 to r64 */
+void PSRLQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xD30F );
+ ModRM( 3, to, from );
+}
+
+/* psrlq m64 to r64 */
+void PSRLQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xD3), true, to, from, 0);
+}
+
+/* psrlq imm8 to r64 */
+void PSRLQItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x730F );
+ ModRM( 3, 2, to);
+ write8( from );
+}
+
+/* paddusb r64 to r64 */
+void PADDUSBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xDC0F );
+ ModRM( 3, to, from );
+}
+
+/* paddusb m64 to r64 */
+void PADDUSBMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xDC), true, to, from, 0);
+}
+
+/* paddusw r64 to r64 */
+void PADDUSWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xDD0F );
+ ModRM( 3, to, from );
+}
+
+/* paddusw m64 to r64 */
+void PADDUSWMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xDD), true, to, from, 0);
+}
+
+/* paddb r64 to r64 */
+void PADDBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xFC0F );
+ ModRM( 3, to, from );
+}
+
+/* paddb m64 to r64 */
+void PADDBMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xFC), true, to, from, 0);
+}
+
+/* paddw r64 to r64 */
+void PADDWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xFD0F );
+ ModRM( 3, to, from );
+}
+
+/* paddw m64 to r64 */
+void PADDWMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xFD), true, to, from, 0);
+}
+
+/* paddd r64 to r64 */
+void PADDDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xFE0F );
+ ModRM( 3, to, from );
+}
+
+/* paddd m64 to r64 */
+void PADDDMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xFE), true, to, from, 0);
+}
+
+/* emms */
+void EMMS( void )
+{
+ write16( 0x770F );
+}
+
+void PADDSBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xEC0F );
+ ModRM( 3, to, from );
+}
+
+void PADDSWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xED0F );
+ ModRM( 3, to, from );
+}
+
+// paddq m64 to r64 (sse2 only?)
+void PADDQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xD4), true, to, from, 0);
+}
+
+// paddq r64 to r64 (sse2 only?)
+void PADDQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xD40F );
+ ModRM( 3, to, from );
+}
+
+void PSUBSBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xE80F );
+ ModRM( 3, to, from );
+}
+
+void PSUBSWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xE90F );
+ ModRM( 3, to, from );
+}
+
+
+void PSUBBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xF80F );
+ ModRM( 3, to, from );
+}
+
+void PSUBWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xF90F );
+ ModRM( 3, to, from );
+}
+
+void PSUBDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xFA0F );
+ ModRM( 3, to, from );
+}
+
+void PSUBDMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xFA), true, to, from, 0);
+}
+
+void PSUBUSBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xD80F );
+ ModRM( 3, to, from );
+}
+
+void PSUBUSWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xD90F );
+ ModRM( 3, to, from );
+}
+
+// psubq m64 to r64 (sse2 only?)
+void PSUBQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xFB), true, to, from, 0);
+}
+
+// psubq r64 to r64 (sse2 only?)
+void PSUBQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xFB0F );
+ ModRM( 3, to, from );
+}
+
+// pmuludq m64 to r64 (sse2 only?)
+void PMULUDQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xF4), true, to, from, 0);
+}
+
+// pmuludq r64 to r64 (sse2 only?)
+void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xF40F );
+ ModRM( 3, to, from );
+}
+
+void PCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x740F );
+ ModRM( 3, to, from );
+}
+
+void PCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x750F );
+ ModRM( 3, to, from );
+}
+
+void PCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x760F );
+ ModRM( 3, to, from );
+}
+
+void PCMPEQDMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x76), true, to, from, 0);
+}
+
+void PCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x640F );
+ ModRM( 3, to, from );
+}
+
+void PCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x650F );
+ ModRM( 3, to, from );
+}
+
+void PCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x660F );
+ ModRM( 3, to, from );
+}
+
+void PCMPGTDMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x66), true, to, from, 0);
+}
+
+void PSRLWItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x710F );
+ ModRM( 3, 2 , to );
+ write8( from );
+}
+
+void PSRLDItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x720F );
+ ModRM( 3, 2 , to );
+ write8( from );
+}
+
+void PSRLDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xD20F );
+ ModRM( 3, to, from );
+}
+
+void PSLLWItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x710F );
+ ModRM( 3, 6 , to );
+ write8( from );
+}
+
+void PSLLDItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x720F );
+ ModRM( 3, 6 , to );
+ write8( from );
+}
+
+void PSLLDRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xF20F );
+ ModRM( 3, to, from );
+}
+
+void PSRAWItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x710F );
+ ModRM( 3, 4 , to );
+ write8( from );
+}
+
+void PSRADItoR( x86MMXRegType to, u8 from )
+{
+ RexB(0, to);
+ write16( 0x720F );
+ ModRM( 3, 4 , to );
+ write8( from );
+}
+
+void PSRADRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0xE20F );
+ ModRM( 3, to, from );
+}
+
+/* por m64 to r64 */
+void PORMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xEB), true, to, from, 0);
+}
+
+/* pxor m64 to r64 */
+void PXORMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xEF), true, to, from, 0);
+}
+
+/* pand m64 to r64 */
+void PANDMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xDB), true, to, from, 0);
+}
+
+void PANDNMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0xDF), true, to, from, 0);
+}
+
+void PUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x6A0F );
+ ModRM( 3, to, from );
+}
+
+void PUNPCKHDQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x6A), true, to, from, 0);
+}
+
+void PUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x620F );
+ ModRM( 3, to, from );
+}
+
+void PUNPCKLDQMtoR( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x62), true, to, from, 0);
+}
+
+void MOVQ64ItoR( x86MMXRegType reg, u64 i )
+{
+ RexR(0, reg);
+ write16(0x6F0F);
+ ModRM(0, reg, DISP32);
+ write32(2);
+ JMP8( 8 );
+ write64( i );
+}
+
+void MOVQRtoR( x86MMXRegType to, x86MMXRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x6F0F );
+ ModRM( 3, to, from );
+}
+
+void MOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset )
+{
+ RexRB(0, to, from);
+ write16( 0x6F0F );
+
+ if( offset < 128 ) {
+ ModRM( 1, to, from );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, to, from );
+ write32(offset);
+ }
+}
+
+void MOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
+{
+ RexRB(0, from, to);
+ write16( 0x7F0F );
+
+ if( offset < 128 ) {
+ ModRM( 1, from , to );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, from, to );
+ write32(offset);
+ }
+}
+
+/* movd m32 to r64 */
+void MOVDMtoMMX( x86MMXRegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x6E), true, to, from, 0);
+}
+
+/* movd r64 to m32 */
+void MOVDMMXtoM( uptr to, x86MMXRegType from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x7E), true, from, to, 0);
+}
+
+void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x6E0F );
+ ModRM( 3, to, from );
+}
+
+void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x6E0F );
+ ModRM( 0, to, from );
+}
+
+void MOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset )
+{
+ RexRB(0, to, from);
+ write16( 0x6E0F );
+
+ if( offset < 128 ) {
+ ModRM( 1, to, from );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, to, from );
+ write32(offset);
+ }
+}
+
+void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
+{
+ RexRB(0, from, to);
+ write16( 0x7E0F );
+ ModRM( 3, from, to );
+}
+
+void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from )
+{
+ RexRB(0, from, to);
+ write16( 0x7E0F );
+ ModRM( 0, from, to );
+ if( to >= 4 ) {
+ // no idea why
+ assert( to == ESP );
+ write8(0x24);
+ }
+
+}
+
+void MOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
+{
+ RexRB(0, from, to);
+ write16( 0x7E0F );
+
+ if( offset < 128 ) {
+ ModRM( 1, from, to );
+ write8(offset);
+ }
+ else {
+ ModRM( 2, from, to );
+ write32(offset);
+ }
+}
+
+///* movd r32 to r64 */
+//void MOVD32MMXtoMMX( x86MMXRegType to, x86MMXRegType from )
+//{
+// write16( 0x6E0F );
+// ModRM( 3, to, from );
+//}
+//
+///* movq r64 to r32 */
+//void MOVD64MMXtoMMX( x86MMXRegType to, x86MMXRegType from )
+//{
+// write16( 0x7E0F );
+// ModRM( 3, from, to );
+//}
+
+// untested
+void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
+{
+ RexRB(0, to, from);
+ write16( 0x630F );
+ ModRM( 3, to, from );
+}
+
+void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
+{
+ RexRB(0, to, from);
+ write16( 0x6B0F );
+ ModRM( 3, to, from );
+}
+
+void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from)
+{
+ RexRB(0, to, from);
+ write16( 0xD70F );
+ ModRM( 3, to, from );
+}
+
+void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 )
+{
+ RexRB(0, to, from);
+ write16( 0xc40f );
+ ModRM( 3, to, from );
+ write8( imm8 );
+}
+
+void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8)
+{
+ RexRB(0, to, from);
+ write16(0x700f);
+ ModRM( 3, to, from );
+ write8(imm8);
+}
+
+void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8)
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x70), true, to, from, 1 /* XXX was 0? */);
+ write8(imm8);
+}
+
+void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from)
+{
+ RexRB(0, to, from);
+ write16(0xf70f);
+ ModRM( 3, to, from );
+}
+
+#endif
diff --git a/libpcsxcore/ix86_64/ix86_sse.c b/libpcsxcore/ix86_64/ix86_sse.c
new file mode 100644
index 00000000..cb391dca
--- /dev/null
+++ b/libpcsxcore/ix86_64/ix86_sse.c
@@ -0,0 +1,1455 @@
+// stop compiling if NORECBUILD build (only for Visual Studio)
+#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
+
+#include <assert.h>
+#include "ix86-64.h"
+
+PCSX2_ALIGNED16(static unsigned int p[4]);
+PCSX2_ALIGNED16(static unsigned int p2[4]);
+PCSX2_ALIGNED16(static float f[4]);
+
+
+XMMSSEType g_xmmtypes[XMMREGS] = {0};
+
+/********************/
+/* SSE instructions */
+/********************/
+
+#define SSEMtoRv( nc, code, overb ) \
+ assert( cpucaps.hasStreamingSIMDExtensions ); \
+ assert( to < XMMREGS ) ; \
+ MEMADDR_OP(0, nc, code, true, to, from, overb)
+
+#define SSEMtoR( code, overb ) SSEMtoRv(2, code, overb)
+
+#define SSERtoMv( nc, code, overb ) \
+ assert( cpucaps.hasStreamingSIMDExtensions ); \
+ assert( from < XMMREGS) ; \
+ MEMADDR_OP(0, nc, code, true, from, to, overb)
+
+#define SSERtoM( code, overb ) SSERtoMv( 2, code, overb ) \
+
+#define SSE_SS_MtoR( code, overb ) \
+ SSEMtoRv(3, (code << 8) | 0xF3, overb)
+
+#define SSE_SS_RtoM( code, overb ) \
+ SSERtoMv(3, (code << 8) | 0xF3, overb)
+
+#define SSERtoR( code ) \
+ assert( cpucaps.hasStreamingSIMDExtensions ); \
+ assert( to < XMMREGS && from < XMMREGS) ; \
+ RexRB(0, to, from); \
+ write16( code ); \
+ ModRM( 3, to, from );
+
+#define SSEMtoR66( code ) \
+ SSEMtoRv( 3, (code << 8) | 0x66, 0 )
+
+#define SSERtoM66( code ) \
+ SSERtoMv( 3, (code << 8) | 0x66, 0 )
+
+#define SSERtoR66( code ) \
+ write8( 0x66 ); \
+ SSERtoR( code );
+
+#define _SSERtoR66( code ) \
+ assert( cpucaps.hasStreamingSIMDExtensions ); \
+ assert( to < XMMREGS && from < XMMREGS) ; \
+ write8( 0x66 ); \
+ RexRB(0, from, to); \
+ write16( code ); \
+ ModRM( 3, from, to );
+
+#define SSE_SS_RtoR( code ) \
+ assert( cpucaps.hasStreamingSIMDExtensions ); \
+ assert( to < XMMREGS && from < XMMREGS) ; \
+ write8( 0xf3 ); \
+ RexRB(0, to, from); \
+ write16( code ); \
+ ModRM( 3, to, from );
+
+#define CMPPSMtoR( op ) \
+ SSEMtoR( 0xc20f, 1 ); \
+ write8( op );
+
+#define CMPPSRtoR( op ) \
+ SSERtoR( 0xc20f ); \
+ write8( op );
+
+#define CMPSSMtoR( op ) \
+ SSE_SS_MtoR( 0xc20f, 1 ); \
+ write8( op );
+
+#define CMPSSRtoR( op ) \
+ SSE_SS_RtoR( 0xc20f ); \
+ write8( op );
+
+
+
+void WriteRmOffset(x86IntRegType to, int offset);
+void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset);
+
+/* movups [r32][r32*scale] to xmm1 */
+void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRXB(0, to, from2, from);
+ write16( 0x100f );
+ ModRM( 0, to, 0x4 );
+ SibSB( scale, from2, from );
+}
+
+/* movups xmm1 to [r32][r32*scale] */
+void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRXB(1, to, from2, from);
+ write16( 0x110f );
+ ModRM( 0, to, 0x4 );
+ SibSB( scale, from2, from );
+}
+
+/* movups [r32] to r32 */
+void SSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, to, from);
+ write16( 0x100f );
+ ModRM( 0, to, from );
+}
+
+/* movups r32 to [r32] */
+void SSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, from, to);
+ write16( 0x110f );
+ ModRM( 0, from, to );
+}
+
+/* movlps [r32] to r32 */
+void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(1, to, from);
+ write16( 0x120f );
+ ModRM( 0, to, from );
+}
+
+void SSE_MOVLPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, to, from);
+ write16( 0x120f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+/* movaps r32 to [r32] */
+void SSE_MOVLPSRtoRm( x86IntRegType to, x86IntRegType from )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, from, to);
+ write16( 0x130f );
+ ModRM( 0, from, to );
+}
+
+void SSE_MOVLPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, from, to);
+ write16( 0x130f );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+/* movaps [r32][r32*scale] to xmm1 */
+void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions && from != EBP );
+ RexRXB(0, to, from2, from);
+ write16( 0x280f );
+ ModRM( 0, to, 0x4 );
+ SibSB( scale, from2, from );
+}
+
+/* movaps xmm1 to [r32][r32*scale] */
+void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions && from != EBP );
+ RexRXB(0, to, from2, from);
+ write16( 0x290f );
+ ModRM( 0, to, 0x4 );
+ SibSB( scale, from2, from );
+}
+
+// movaps [r32+offset] to r32
+void SSE_MOVAPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, to, from);
+ write16( 0x280f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+// movaps r32 to [r32+offset]
+void SSE_MOVAPSRtoRmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, from, to);
+ write16( 0x290f );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+// movdqa [r32+offset] to r32
+void SSE2_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ write8(0x66);
+ RexRB(0, to, from);
+ write16( 0x6f0f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+// movdqa r32 to [r32+offset]
+void SSE2_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ write8(0x66);
+ RexRB(0, from, to);
+ write16( 0x7f0f );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+// movups [r32+offset] to r32
+void SSE_MOVUPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ RexRB(0, to, from);
+ write16( 0x100f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+// movups r32 to [r32+offset]
+void SSE_MOVUPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, from, to);
+ write16( 0x110f );
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+//**********************************************************************************/
+//MOVAPS: Move aligned Packed Single Precision FP values *
+//**********************************************************************************
+void SSE_MOVAPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x280f, 0 ); }
+void SSE_MOVAPS_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM( 0x290f, 0 ); }
+void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x280f ); }
+
+void SSE_MOVUPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x100f, 0 ); }
+void SSE_MOVUPS_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM( 0x110f, 0 ); }
+
+void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVSD_XMM_to_XMM(to, from);
+ else {
+ write8(0xf2);
+ SSERtoR( 0x100f);
+ }
+}
+
+void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVQ_M64_to_XMM(to, from);
+ else {
+ SSE_SS_MtoR( 0x7e0f, 0);
+ }
+}
+
+void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVQ_XMM_to_XMM(to, from);
+ else {
+ SSE_SS_RtoR( 0x7e0f);
+ }
+}
+
+void SSE2_MOVQ_XMM_to_M64( u32 to, x86SSERegType from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) SSE_MOVLPS_XMM_to_M64(to, from);
+ else {
+ SSERtoM66(0xd60f);
+ }
+}
+
+#ifndef __x86_64__
+void SSE2_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from)
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVDQ2Q_XMM_to_MM(to, from);
+ else {
+ write8(0xf2);
+ SSERtoR( 0xd60f);
+ }
+}
+void SSE2_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from)
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVQ2DQ_MM_to_XMM(to, from);
+ else {
+ SSE_SS_RtoR( 0xd60f);
+ }
+}
+#endif
+
+//**********************************************************************************/
+//MOVSS: Move Scalar Single-Precision FP value *
+//**********************************************************************************
+void SSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x100f, 0 ); }
+void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ) { SSE_SS_RtoM( 0x110f, 0 ); }
+void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from )
+{
+ write8(0xf3);
+ RexRB(0, from, to);
+ write16(0x110f);
+ ModRM(0, from, to);
+}
+
+void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x100f ); }
+
+void SSE_MOVSS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
+{
+ write8(0xf3);
+ RexRB(0, to, from);
+ write16( 0x100f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+void SSE_MOVSS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ write8(0xf3);
+ RexRB(0, from, to);
+ write16(0x110f);
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xf70f ); }
+//**********************************************************************************/
+//MOVLPS: Move low Packed Single-Precision FP *
+//**********************************************************************************
+void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x120f, 0 ); }
+void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x130f, 0 ); }
+
+void SSE_MOVLPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, to, from);
+ write16( 0x120f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+void SSE_MOVLPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ RexRB(0, from, to);
+ write16(0x130f);
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MOVHPS: Move High Packed Single-Precision FP *
+//**********************************************************************************
+void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x160f, 0 ); }
+void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x170f, 0 ); }
+
+void SSE_MOVHPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, to, from);
+ write16( 0x160f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+void SSE_MOVHPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ assert( cpucaps.hasStreamingSIMDExtensions );
+ RexRB(0, from, to);
+ write16(0x170f);
+ WriteRmOffsetFrom(from, to, offset);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MOVLHPS: Moved packed Single-Precision FP low to high *
+//**********************************************************************************
+void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x160f ); }
+
+//////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MOVHLPS: Moved packed Single-Precision FP High to Low *
+//**********************************************************************************
+void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x120f ); }
+
+///////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//ANDPS: Logical Bit-wise AND for Single FP *
+//**********************************************************************************
+void SSE_ANDPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x540f, 0 ); }
+void SSE_ANDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x540f ); }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//ANDNPS : Logical Bit-wise AND NOT of Single-precision FP values *
+//**********************************************************************************
+void SSE_ANDNPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x550f, 0 ); }
+void SSE_ANDNPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR( 0x550f ); }
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//RCPPS : Packed Single-Precision FP Reciprocal *
+//**********************************************************************************
+void SSE_RCPPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x530f ); }
+void SSE_RCPPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x530f, 0 ); }
+
+void SSE_RCPSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR(0x530f); }
+void SSE_RCPSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR(0x530f, 0); }
+
+//////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//ORPS : Bit-wise Logical OR of Single-Precision FP Data *
+//**********************************************************************************
+void SSE_ORPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x560f, 0 ); }
+void SSE_ORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x560f ); }
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//XORPS : Bitwise Logical XOR of Single-Precision FP Values *
+//**********************************************************************************
+void SSE_XORPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x570f, 0 ); }
+void SSE_XORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x570f ); }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//ADDPS : ADD Packed Single-Precision FP Values *
+//**********************************************************************************
+void SSE_ADDPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x580f, 0 ); }
+void SSE_ADDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x580f ); }
+
+////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//ADDSS : ADD Scalar Single-Precision FP Values *
+//**********************************************************************************
+void SSE_ADDSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x580f, 0 ); }
+void SSE_ADDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x580f ); }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//SUBPS: Packed Single-Precision FP Subtract *
+//**********************************************************************************
+void SSE_SUBPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5c0f, 0 ); }
+void SSE_SUBPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5c0f ); }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//SUBSS : Scalar Single-Precision FP Subtract *
+//**********************************************************************************
+void SSE_SUBSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5c0f, 0 ); }
+void SSE_SUBSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5c0f ); }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MULPS : Packed Single-Precision FP Multiply *
+//**********************************************************************************
+void SSE_MULPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x590f, 0 ); }
+void SSE_MULPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x590f ); }
+
+////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MULSS : Scalar Single-Precision FP Multiply *
+//**********************************************************************************
+void SSE_MULSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x590f, 0 ); }
+void SSE_MULSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x590f ); }
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//Packed Single-Precission FP compare (CMPccPS) *
+//**********************************************************************************
+//missing SSE_CMPPS_I8_to_XMM
+// SSE_CMPPS_M32_to_XMM
+// SSE_CMPPS_XMM_to_XMM
+void SSE_CMPEQPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 0 ); }
+void SSE_CMPEQPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 0 ); }
+void SSE_CMPLTPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 1 ); }
+void SSE_CMPLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 1 ); }
+void SSE_CMPLEPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 2 ); }
+void SSE_CMPLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 2 ); }
+void SSE_CMPUNORDPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 3 ); }
+void SSE_CMPUNORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 3 ); }
+void SSE_CMPNEPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 4 ); }
+void SSE_CMPNEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 4 ); }
+void SSE_CMPNLTPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 5 ); }
+void SSE_CMPNLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 5 ); }
+void SSE_CMPNLEPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 6 ); }
+void SSE_CMPNLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 6 ); }
+void SSE_CMPORDPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 7 ); }
+void SSE_CMPORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 7 ); }
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//Scalar Single-Precission FP compare (CMPccSS) *
+//**********************************************************************************
+//missing SSE_CMPSS_I8_to_XMM
+// SSE_CMPSS_M32_to_XMM
+// SSE_CMPSS_XMM_to_XMM
+void SSE_CMPEQSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 0 ); }
+void SSE_CMPEQSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 0 ); }
+void SSE_CMPLTSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 1 ); }
+void SSE_CMPLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 1 ); }
+void SSE_CMPLESS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 2 ); }
+void SSE_CMPLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 2 ); }
+void SSE_CMPUNORDSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 3 ); }
+void SSE_CMPUNORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 3 ); }
+void SSE_CMPNESS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 4 ); }
+void SSE_CMPNESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 4 ); }
+void SSE_CMPNLTSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 5 ); }
+void SSE_CMPNLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 5 ); }
+void SSE_CMPNLESS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 6 ); }
+void SSE_CMPNLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 6 ); }
+void SSE_CMPORDSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 7 ); }
+void SSE_CMPORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 7 ); }
+
+void SSE_UCOMISS_M32_to_XMM( x86SSERegType to, uptr from )
+{
+ MEMADDR_OP(0, VAROP2(0x0F, 0x2E), true, to, from, 0);
+}
+
+void SSE_UCOMISS_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ RexRB(0, to, from);
+ write16( 0x2e0f );
+ ModRM( 3, to, from );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//RSQRTPS : Packed Single-Precision FP Square Root Reciprocal *
+//**********************************************************************************
+void SSE_RSQRTPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x520f, 0 ); }
+void SSE_RSQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR( 0x520f ); }
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//RSQRTSS : Scalar Single-Precision FP Square Root Reciprocal *
+//**********************************************************************************
+void SSE_RSQRTSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x520f, 0 ); }
+void SSE_RSQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSE_SS_RtoR( 0x520f ); }
+
+////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//SQRTPS : Packed Single-Precision FP Square Root *
+//**********************************************************************************
+void SSE_SQRTPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x510f, 0 ); }
+void SSE_SQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR( 0x510f ); }
+
+//////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//SQRTSS : Scalar Single-Precision FP Square Root *
+//**********************************************************************************
+void SSE_SQRTSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x510f, 0 ); }
+void SSE_SQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSE_SS_RtoR( 0x510f ); }
+
+////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MAXPS: Return Packed Single-Precision FP Maximum *
+//**********************************************************************************
+void SSE_MAXPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5f0f, 0 ); }
+void SSE_MAXPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5f0f ); }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MAXSS: Return Scalar Single-Precision FP Maximum *
+//**********************************************************************************
+void SSE_MAXSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5f0f, 0 ); }
+void SSE_MAXSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5f0f ); }
+
+#ifndef __x86_64__
+/////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//CVTPI2PS: Packed Signed INT32 to Packed Single FP Conversion *
+//**********************************************************************************
+void SSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x2a0f, 0 ); }
+void SSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from ) { SSERtoR( 0x2a0f ); }
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//CVTPS2PI: Packed Single FP to Packed Signed INT32 Conversion *
+//**********************************************************************************
+void SSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from ) { SSEMtoR( 0x2d0f, 0 ); }
+void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from ) { SSERtoR( 0x2d0f ); }
+#endif
+
+void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { SSE_SS_MtoR(0x2c0f, 0); }
+void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from)
+{
+ write8(0xf3);
+ RexRB(0, to, from);
+ write16(0x2c0f);
+ ModRM(3, to, from);
+}
+
+void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x2a0f, 0); }
+void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from)
+{
+ write8(0xf3);
+ RexRB(0, to, from);
+ write16(0x2a0f);
+ ModRM(3, to, from);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//CVTDQ2PS: Packed Signed INT32 to Packed Single Precision FP Conversion *
+//**********************************************************************************
+void SSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5b0f, 0 ); }
+void SSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5b0f ); }
+
+//**********************************************************************************/
+//CVTPS2DQ: Packed Single Precision FP to Packed Signed INT32 Conversion *
+//**********************************************************************************
+void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0x5b0f ); }
+void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0x5b0f ); }
+
+void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR(0x5b0f); }
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MINPS: Return Packed Single-Precision FP Minimum *
+//**********************************************************************************
+void SSE_MINPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5d0f, 0 ); }
+void SSE_MINPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5d0f ); }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MINSS: Return Scalar Single-Precision FP Minimum *
+//**********************************************************************************
+void SSE_MINSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5d0f, 0 ); }
+void SSE_MINSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5d0f ); }
+
+#ifndef __x86_64__
+///////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PMAXSW: Packed Signed Integer Word Maximum *
+//**********************************************************************************
+//missing
+ // SSE_PMAXSW_M64_to_MM
+// SSE2_PMAXSW_M128_to_XMM
+// SSE2_PMAXSW_XMM_to_XMM
+void SSE_PMAXSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ){ SSERtoR( 0xEE0F ); }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PMINSW: Packed Signed Integer Word Minimum *
+//**********************************************************************************
+//missing
+ // SSE_PMINSW_M64_to_MM
+// SSE2_PMINSW_M128_to_XMM
+// SSE2_PMINSW_XMM_to_XMM
+void SSE_PMINSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ){ SSERtoR( 0xEA0F ); }
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//SHUFPS: Shuffle Packed Single-Precision FP Values *
+//**********************************************************************************
+void SSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { SSERtoR( 0xC60F ); write8( imm8 ); }
+void SSE_SHUFPS_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoR( 0xC60F, 1 ); write8( imm8 ); }
+
+void SSE_SHUFPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset, u8 imm8 )
+{
+ RexRB(0, to, from);
+ write16(0xc60f);
+ WriteRmOffsetFrom(to, from, offset);
+ write8(imm8);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PSHUFD: Shuffle Packed DoubleWords *
+//**********************************************************************************
+void SSE2_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) {
+ SSE2EMU_PSHUFD_XMM_to_XMM(to, from, imm8);
+ }
+ else {
+ SSERtoR66( 0x700F );
+ write8( imm8 );
+ }
+}
+void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoRv( 3, 0x700F66, 1 ); write8( imm8 ); }
+
+void SSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { write8(0xF2); SSERtoR(0x700F); write8(imm8); }
+void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoRv(3, 0x700FF2, 1); write8(imm8); }
+void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { SSE_SS_RtoR(0x700F); write8(imm8); }
+void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSE_SS_MtoR(0x700F, 1); write8(imm8); }
+
+///////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//UNPCKLPS: Unpack and Interleave low Packed Single-Precision FP Data *
+//**********************************************************************************
+void SSE_UNPCKLPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR(0x140f, 0); }
+void SSE_UNPCKLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x140F ); }
+
+////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//UNPCKHPS: Unpack and Interleave High Packed Single-Precision FP Data *
+//**********************************************************************************
+void SSE_UNPCKHPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR(0x150f, 0); }
+void SSE_UNPCKHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x150F ); }
+
+////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//DIVPS : Packed Single-Precision FP Divide *
+//**********************************************************************************
+void SSE_DIVPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5e0F, 0 ); }
+void SSE_DIVPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5e0F ); }
+
+//////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//DIVSS : Scalar Single-Precision FP Divide *
+//**********************************************************************************
+void SSE_DIVSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5e0F, 0 ); }
+void SSE_DIVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5e0F ); }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//STMXCSR : Store Streaming SIMD Extension Control/Status *
+//**********************************************************************************
+void SSE_STMXCSR( uptr from ) {
+ MEMADDR_OP(0, VAROP2(0x0F, 0xAE), false, 3, from, 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//LDMXCSR : Load Streaming SIMD Extension Control/Status *
+//**********************************************************************************
+void SSE_LDMXCSR( uptr from ) {
+ MEMADDR_OP(0, VAROP2(0x0F, 0xAE), false, 2, from, 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PADDB,PADDW,PADDD : Add Packed Integers *
+//**********************************************************************************
+void SSE2_PADDB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFC0F ); }
+void SSE2_PADDB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFC0F ); }
+void SSE2_PADDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFD0F ); }
+void SSE2_PADDW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFD0F ); }
+void SSE2_PADDD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFE0F ); }
+void SSE2_PADDD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFE0F ); }
+
+void SSE2_PADDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD40F ); }
+void SSE2_PADDQ_M128_to_XMM(x86SSERegType to, uptr from ) { SSEMtoR66( 0xD40F ); }
+
+///////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PCMPxx: Compare Packed Integers *
+//**********************************************************************************
+void SSE2_PCMPGTB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x640F ); }
+void SSE2_PCMPGTB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x640F ); }
+void SSE2_PCMPGTW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x650F ); }
+void SSE2_PCMPGTW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x650F ); }
+void SSE2_PCMPGTD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x660F ); }
+void SSE2_PCMPGTD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x660F ); }
+void SSE2_PCMPEQB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x740F ); }
+void SSE2_PCMPEQB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x740F ); }
+void SSE2_PCMPEQW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x750F ); }
+void SSE2_PCMPEQW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x750F ); }
+void SSE2_PCMPEQD_XMM_to_XMM(x86SSERegType to, x86SSERegType from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) {
+ SSE_CMPEQPS_XMM_to_XMM(to, from);
+ }
+ else {
+ SSERtoR66( 0x760F );
+ }
+}
+
+void SSE2_PCMPEQD_M128_to_XMM(x86SSERegType to, uptr from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) {
+ SSE_CMPEQPS_M128_to_XMM(to, from);
+ }
+ else {
+ SSEMtoR66( 0x760F );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PEXTRW,PINSRW: Packed Extract/Insert Word *
+//**********************************************************************************
+void SSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 ){ SSERtoR66(0xC50F); write8( imm8 ); }
+void SSE_PINSRW_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8 ){ SSERtoR66(0xC40F); write8( imm8 ); }
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PSUBx: Subtract Packed Integers *
+//**********************************************************************************
+void SSE2_PSUBB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xF80F ); }
+void SSE2_PSUBB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xF80F ); }
+void SSE2_PSUBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xF90F ); }
+void SSE2_PSUBW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xF90F ); }
+void SSE2_PSUBD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFA0F ); }
+void SSE2_PSUBD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFA0F ); }
+void SSE2_PSUBQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFB0F ); }
+void SSE2_PSUBQ_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFB0F ); }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//MOVD: Move Dword(32bit) to /from XMM reg *
+//**********************************************************************************
+void SSE2_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66(0x6E0F); }
+void SSE2_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) {
+ SSE2EMU_MOVD_R_to_XMM(to, from);
+ }
+ else {
+ SSERtoR66(0x6E0F);
+ }
+}
+
+void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from )
+{
+ write8(0x66);
+ RexRB(0, to, from);
+ write16( 0x6e0f );
+ ModRM( 0, to, from);
+}
+
+void SSE2_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
+{
+ write8(0x66);
+ RexRB(0, to, from);
+ write16( 0x6e0f );
+ WriteRmOffsetFrom(to, from, offset);
+}
+
+void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) { SSERtoM66(0x7E0F); }
+void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) {
+ if( !cpucaps.hasStreamingSIMD2Extensions ) {
+ SSE2EMU_MOVD_XMM_to_R(to, from);
+ }
+ else {
+ _SSERtoR66(0x7E0F);
+ }
+}
+
+void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from )
+{
+ write8(0x66);
+ RexRB(0, from, to);
+ write16( 0x7e0f );
+ ModRM( 0, from, to );
+}
+
+void SSE2_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ if( !cpucaps.hasStreamingSIMD2Extensions ) {
+ SSE2EMU_MOVD_XMM_to_RmOffset(to, from, offset);
+ }
+ else {
+ write8(0x66);
+ RexRB(0, from, to);
+ write16( 0x7e0f );
+ WriteRmOffsetFrom(from, to, offset);
+ }
+}
+
+#ifdef __x86_64__
+void SSE2_MOVQ_XMM_to_R( x86IntRegType to, x86SSERegType from )
+{
+ assert( from < XMMREGS);
+ write8( 0x66 );
+ RexRB(1, from, to);
+ write16( 0x7e0f );
+ ModRM( 3, from, to );
+}
+
+void SSE2_MOVQ_R_to_XMM( x86SSERegType to, x86IntRegType from )
+{
+ assert( to < XMMREGS);
+ write8(0x66);
+ RexRB(1, to, from);
+ write16( 0x6e0f );
+ ModRM( 3, to, from );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//POR : SSE Bitwise OR *
+//**********************************************************************************
+void SSE2_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEB0F ); }
+void SSE2_POR_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEB0F ); }
+
+// logical and to &= from
+void SSE2_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDB0F ); }
+void SSE2_PAND_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDB0F ); }
+
+// to = (~to) & from
+void SSE2_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDF0F ); }
+void SSE2_PANDN_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDF0F ); }
+
+/////////////////////////////////////////////////////////////////////////////////////
+//**********************************************************************************/
+//PXOR : SSE Bitwise XOR *
+//**********************************************************************************
+void SSE2_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xEF0F ); }
+void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xEF0F ); }
+///////////////////////////////////////////////////////////////////////////////////////
+
+void SSE2_MOVDQA_M128_to_XMM(x86SSERegType to, uptr from) {SSEMtoR66(0x6F0F); }
+void SSE2_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ){SSERtoM66(0x7F0F);}
+void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { SSERtoR66(0x6F0F); }
+
+void SSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x6F0F, 0); }
+void SSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from) { SSE_SS_RtoM(0x7F0F, 0); }
+void SSE2_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { SSE_SS_RtoR(0x6F0F); }
+
+// shift right logical
+
+void SSE2_PSRLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD10F); }
+void SSE2_PSRLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD10F); }
+void SSE2_PSRLW_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x710F );
+ ModRM( 3, 2 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSRLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD20F); }
+void SSE2_PSRLD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD20F); }
+void SSE2_PSRLD_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x720F );
+ ModRM( 3, 2 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSRLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD30F); }
+void SSE2_PSRLQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD30F); }
+void SSE2_PSRLQ_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x730F );
+ ModRM( 3, 2 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSRLDQ_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x730F );
+ ModRM( 3, 3 , to );
+ write8( imm8 );
+}
+
+// shift right arithmetic
+
+void SSE2_PSRAW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xE10F); }
+void SSE2_PSRAW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xE10F); }
+void SSE2_PSRAW_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x710F );
+ ModRM( 3, 4 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSRAD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xE20F); }
+void SSE2_PSRAD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xE20F); }
+void SSE2_PSRAD_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x720F );
+ ModRM( 3, 4 , to );
+ write8( imm8 );
+}
+
+// shift left logical
+
+void SSE2_PSLLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF10F); }
+void SSE2_PSLLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF10F); }
+void SSE2_PSLLW_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x710F );
+ ModRM( 3, 6 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSLLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF20F); }
+void SSE2_PSLLD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF20F); }
+void SSE2_PSLLD_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x720F );
+ ModRM( 3, 6 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSLLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF30F); }
+void SSE2_PSLLQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF30F); }
+void SSE2_PSLLQ_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x730F );
+ ModRM( 3, 6 , to );
+ write8( imm8 );
+}
+
+void SSE2_PSLLDQ_I8_to_XMM(x86SSERegType to, u8 imm8)
+{
+ write8( 0x66 );
+ RexB(0, to);
+ write16( 0x730F );
+ ModRM( 3, 7 , to );
+ write8( imm8 );
+}
+
+
+void SSE2_PMAXSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xEE0F ); }
+void SSE2_PMAXSW_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xEE0F ); }
+
+void SSE2_PMAXUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xDE0F ); }
+void SSE2_PMAXUB_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xDE0F ); }
+
+void SSE2_PMINSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xEA0F ); }
+void SSE2_PMINSW_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xEA0F ); }
+
+void SSE2_PMINUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xDA0F ); }
+void SSE2_PMINUB_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xDA0F ); }
+
+//
+
+void SSE2_PADDSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xEC0F ); }
+void SSE2_PADDSB_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xEC0F ); }
+
+void SSE2_PADDSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xED0F ); }
+void SSE2_PADDSW_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xED0F ); }
+
+void SSE2_PSUBSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xE80F ); }
+void SSE2_PSUBSB_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xE80F ); }
+
+void SSE2_PSUBSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xE90F ); }
+void SSE2_PSUBSW_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xE90F ); }
+
+void SSE2_PSUBUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD80F ); }
+void SSE2_PSUBUSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xD80F ); }
+void SSE2_PSUBUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD90F ); }
+void SSE2_PSUBUSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xD90F ); }
+
+void SSE2_PADDUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDC0F ); }
+void SSE2_PADDUSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDC0F ); }
+void SSE2_PADDUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDD0F ); }
+void SSE2_PADDUSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDD0F ); }
+
+//**********************************************************************************/
+//PACKSSWB,PACKSSDW: Pack Saturate Signed Word
+//**********************************************************************************
+void SSE2_PACKSSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x630F ); }
+void SSE2_PACKSSWB_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x630F ); }
+void SSE2_PACKSSDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6B0F ); }
+void SSE2_PACKSSDW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6B0F ); }
+
+void SSE2_PACKUSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x670F ); }
+void SSE2_PACKUSWB_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x670F ); }
+
+//**********************************************************************************/
+//PUNPCKHWD: Unpack 16bit high
+//**********************************************************************************
+void SSE2_PUNPCKLBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x600F ); }
+void SSE2_PUNPCKLBW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x600F ); }
+
+void SSE2_PUNPCKHBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x680F ); }
+void SSE2_PUNPCKHBW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x680F ); }
+
+void SSE2_PUNPCKLWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x610F ); }
+void SSE2_PUNPCKLWD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x610F ); }
+void SSE2_PUNPCKHWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x690F ); }
+void SSE2_PUNPCKHWD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x690F ); }
+
+void SSE2_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x620F ); }
+void SSE2_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x620F ); }
+void SSE2_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6A0F ); }
+void SSE2_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6A0F ); }
+
+void SSE2_PUNPCKLQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6C0F ); }
+void SSE2_PUNPCKLQDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6C0F ); }
+
+void SSE2_PUNPCKHQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6D0F ); }
+void SSE2_PUNPCKHQDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6D0F ); }
+
+void SSE2_PMULLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xD50F ); }
+void SSE2_PMULLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xD50F ); }
+void SSE2_PMULHW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xE50F ); }
+void SSE2_PMULHW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xE50F ); }
+
+void SSE2_PMULUDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xF40F ); }
+void SSE2_PMULUDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xF40F ); }
+
+void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0xD70F); }
+
+void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR(0x500F); }
+void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0x500F); }
+
+void SSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { write8(0xf2); SSERtoR( 0x7c0f ); }
+void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from){ SSEMtoRv( 3, 0x7c0fF2, 0 ); }
+
+void SSE3_MOVSLDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) {
+ write8(0xf3);
+ RexRB(0, to, from);
+ write16( 0x120f);
+ ModRM( 3, to, from );
+}
+
+void SSE3_MOVSLDUP_M128_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x120f, 0); }
+void SSE3_MOVSHDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSE_SS_RtoR(0x160f); }
+void SSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x160f, 0); }
+
+// SSE-X
+void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQA_M128_to_XMM(to, from);
+ else SSE_MOVAPS_M128_to_XMM(to, from);
+}
+
+void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_M128(to, from);
+ else SSE_MOVAPS_XMM_to_M128(to, from);
+}
+
+void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_XMM(to, from);
+ else SSE_MOVAPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQARmtoROffset(to, from, offset);
+ else SSE_MOVAPSRmtoROffset(to, from, offset);
+}
+
+void SSEX_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQARtoRmOffset(to, from, offset);
+ else SSE_MOVAPSRtoRmOffset(to, from, offset);
+}
+
+void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQU_M128_to_XMM(to, from);
+ else SSE_MOVAPS_M128_to_XMM(to, from);
+}
+
+void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_M128(to, from);
+ else SSE_MOVAPS_XMM_to_M128(to, from);
+}
+
+void SSEX_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_XMM(to, from);
+ else SSE_MOVAPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_M32_to_XMM(to, from);
+ else SSE_MOVSS_M32_to_XMM(to, from);
+}
+
+void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_M32(to, from);
+ else SSE_MOVSS_XMM_to_M32(to, from);
+}
+
+void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_Rm(to, from);
+ else SSE_MOVSS_XMM_to_Rm(to, from);
+}
+
+void SSEX_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_RmOffset_to_XMM(to, from, offset);
+ else SSE_MOVSS_RmOffset_to_XMM(to, from, offset);
+}
+
+void SSEX_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_RmOffset(to, from, offset);
+ else SSE_MOVSS_XMM_to_RmOffset(to, from, offset);
+}
+
+void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_POR_M128_to_XMM(to, from);
+ else SSE_ORPS_M128_to_XMM(to, from);
+}
+
+void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_POR_XMM_to_XMM(to, from);
+ else SSE_ORPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_PXOR_M128_to_XMM(to, from);
+ else SSE_XORPS_M128_to_XMM(to, from);
+}
+
+void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_PXOR_XMM_to_XMM(to, from);
+ else SSE_XORPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_PAND_M128_to_XMM(to, from);
+ else SSE_ANDPS_M128_to_XMM(to, from);
+}
+
+void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_PAND_XMM_to_XMM(to, from);
+ else SSE_ANDPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_PANDN_M128_to_XMM(to, from);
+ else SSE_ANDNPS_M128_to_XMM(to, from);
+}
+
+void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_PANDN_XMM_to_XMM(to, from);
+ else SSE_ANDNPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from)
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKLDQ_M128_to_XMM(to, from);
+ else SSE_UNPCKLPS_M128_to_XMM(to, from);
+}
+
+void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKLDQ_XMM_to_XMM(to, from);
+ else SSE_UNPCKLPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from)
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKHDQ_M128_to_XMM(to, from);
+ else SSE_UNPCKHPS_M128_to_XMM(to, from);
+}
+
+void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKHDQ_XMM_to_XMM(to, from);
+ else SSE_UNPCKHPS_XMM_to_XMM(to, from);
+}
+
+void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
+{
+ if( cpucaps.hasStreamingSIMD2Extensions && g_xmmtypes[from] == XMMT_INT ) {
+ SSE2_PUNPCKHQDQ_XMM_to_XMM(to, from);
+ if( to != from ) SSE2_PSHUFD_XMM_to_XMM(to, to, 0x4e);
+ }
+ else {
+ SSE_MOVHLPS_XMM_to_XMM(to, from);
+ }
+}
+
+// SSE2 emulation
+void SSE2EMU_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from)
+{
+ SSE_SHUFPS_XMM_to_XMM(to, from, 0x4e);
+ SSE_SHUFPS_XMM_to_XMM(to, to, 0x4e);
+}
+
+void SSE2EMU_MOVQ_M64_to_XMM( x86SSERegType to, uptr from)
+{
+ SSE_XORPS_XMM_to_XMM(to, to);
+ SSE_MOVLPS_M64_to_XMM(to, from);
+}
+
+void SSE2EMU_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from)
+{
+ SSE_XORPS_XMM_to_XMM(to, to);
+ SSE2EMU_MOVSD_XMM_to_XMM(to, from);
+}
+
+void SSE2EMU_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
+{
+ MOV32RmtoROffset(EAX, from, offset);
+ MOV32ItoM((uptr)p+4, 0);
+ MOV32ItoM((uptr)p+8, 0);
+ MOV32RtoM((uptr)p, EAX);
+ MOV32ItoM((uptr)p+12, 0);
+ SSE_MOVAPS_M128_to_XMM(to, (uptr)p);
+}
+
+void SSE2EMU_MOVD_XMM_to_RmOffset(x86IntRegType to, x86SSERegType from, int offset )
+{
+ SSE_MOVSS_XMM_to_M32((uptr)p, from);
+ MOV32MtoR(EAX, (uptr)p);
+ MOV32RtoRmOffset(to, EAX, offset);
+}
+
+#ifndef __x86_64__
+extern void SetMMXstate();
+
+void SSE2EMU_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from)
+{
+ SSE_MOVLPS_XMM_to_M64(p, from);
+ MOVQMtoR(to, p);
+ SetMMXstate();
+}
+
+void SSE2EMU_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from)
+{
+ MOVQRtoM(p, from);
+ SSE_MOVLPS_M64_to_XMM(to, p);
+ SetMMXstate();
+}
+#endif
+
+/****************************************************************************/
+/* SSE2 Emulated functions for SSE CPU's by kekko */
+/****************************************************************************/
+void SSE2EMU_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) {
+ MOV64ItoR(EAX, (uptr)&p);
+ MOV64ItoR(EBX, (uptr)&p2);
+ SSE_MOVUPSRtoRm(EAX, from);
+
+ MOV32ItoR(ECX, (u32)imm8);
+ AND32ItoR(ECX, 3);
+ SHL32ItoR(ECX, 2);
+ ADD32RtoR(ECX, EAX);
+ MOV32RmtoR(ECX, ECX);
+ MOV32RtoRm(EBX, ECX);
+
+ ADD32ItoR(EBX, 4);
+ MOV32ItoR(ECX, (u32)imm8);
+ SHR32ItoR(ECX, 2);
+ AND32ItoR(ECX, 3);
+ SHL32ItoR(ECX, 2);
+ ADD32RtoR(ECX, EAX);
+ MOV32RmtoR(ECX, ECX);
+ MOV32RtoRm(EBX, ECX);
+
+ ADD32ItoR(EBX, 4);
+ MOV32ItoR(ECX, (u32)imm8);
+ SHR32ItoR(ECX, 4);
+ AND32ItoR(ECX, 3);
+ SHL32ItoR(ECX, 2);
+ ADD32RtoR(ECX, EAX);
+ MOV32RmtoR(ECX, ECX);
+ MOV32RtoRm(EBX, ECX);
+
+ ADD32ItoR(EBX, 4);
+ MOV32ItoR(ECX, (u32)imm8);
+ SHR32ItoR(ECX, 6);
+ AND32ItoR(ECX, 3);
+ SHL32ItoR(ECX, 2);
+ ADD32RtoR(ECX, EAX);
+ MOV32RmtoR(ECX, ECX);
+ MOV32RtoRm(EBX, ECX);
+
+ SUB32ItoR(EBX, 12);
+
+ SSE_MOVUPSRmtoR(to, EBX);
+}
+
+void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) {
+ /* XXX? */
+ MOV64ItoR(to, (uptr)&p);
+ SSE_MOVUPSRtoRm(to, from);
+ MOV32RmtoR(to, to);
+}
+
+#ifndef __x86_64__
+extern void SetFPUstate();
+extern void _freeMMXreg(int mmxreg);
+#endif
+
+void SSE2EMU_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) {
+#ifndef __x86_64__
+ SetFPUstate();
+ _freeMMXreg(7);
+#endif
+ SSE_MOVAPS_XMM_to_M128((uptr)f, from);
+
+ FLD32((uptr)&f[0]);
+ FISTP32((uptr)&p2[0]);
+ FLD32((uptr)&f[1]);
+ FISTP32((uptr)&p2[1]);
+ FLD32((uptr)&f[2]);
+ FISTP32((uptr)&p2[2]);
+ FLD32((uptr)&f[3]);
+ FISTP32((uptr)&p2[3]);
+
+ SSE_MOVAPS_M128_to_XMM(to, (uptr)p2);
+}
+
+void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) {
+#ifndef __x86_64__
+ SetFPUstate();
+ _freeMMXreg(7);
+#endif
+ FILD32(from);
+ FSTP32((uptr)&f[0]);
+ FILD32(from+4);
+ FSTP32((uptr)&f[1]);
+ FILD32(from+8);
+ FSTP32((uptr)&f[2]);
+ FILD32(from+12);
+ FSTP32((uptr)&f[3]);
+
+ SSE_MOVAPS_M128_to_XMM(to, (uptr)f);
+}
+
+void SSE2EMU_MOVD_XMM_to_M32( uptr to, x86SSERegType from ) {
+ /* XXX? */
+ MOV64ItoR(EAX, (uptr)&p);
+ SSE_MOVUPSRtoRm(EAX, from);
+ MOV32RmtoR(EAX, EAX);
+ MOV32RtoM(to, EAX);
+}
+
+void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ) {
+ MOV32ItoM((uptr)p+4, 0);
+ MOV32ItoM((uptr)p+8, 0);
+ MOV32RtoM((uptr)p, from);
+ MOV32ItoM((uptr)p+12, 0);
+ SSE_MOVAPS_M128_to_XMM(to, (uptr)p);
+}
+
+#endif
diff --git a/libpcsxcore/mdec.c b/libpcsxcore/mdec.c
new file mode 100644
index 00000000..8ab8f4bf
--- /dev/null
+++ b/libpcsxcore/mdec.c
@@ -0,0 +1,522 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Movie decoder. Based on the FPSE v0.08 Mdec decoder.
+*/
+
+#include "mdec.h"
+
+#define FIXED
+
+#define CONST_BITS 8
+#define PASS1_BITS 2
+
+#define FIX_1_082392200 (277)
+#define FIX_1_414213562 (362)
+#define FIX_1_847759065 (473)
+#define FIX_2_613125930 (669)
+
+#define MULTIPLY(var,const) (DESCALE((var) * (const), CONST_BITS))
+
+#define DEQUANTIZE(coef,quantval) (coef)
+
+#define DESCALE(x,n) ((x)>>(n))
+#define RANGE(n) (n)
+
+#define DCTSIZE 8
+#define DCTSIZE2 64
+
+static void idct1(int *block)
+{
+ int val = RANGE(DESCALE(block[0], PASS1_BITS+3));
+ int i;
+ for(i=0;i<DCTSIZE2;i++) block[i]=val;
+}
+
+void idct(int *block,int k)
+{
+ int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ int z5, z10, z11, z12, z13;
+ int *ptr;
+ int i;
+
+ if (!k) { idct1(block); return; }
+
+ ptr = block;
+ for (i = 0; i< DCTSIZE; i++,ptr++) {
+
+ if ((ptr[DCTSIZE*1] | ptr[DCTSIZE*2] | ptr[DCTSIZE*3] |
+ ptr[DCTSIZE*4] | ptr[DCTSIZE*5] | ptr[DCTSIZE*6] |
+ ptr[DCTSIZE*7]) == 0) {
+ ptr[DCTSIZE*0] =
+ ptr[DCTSIZE*1] =
+ ptr[DCTSIZE*2] =
+ ptr[DCTSIZE*3] =
+ ptr[DCTSIZE*4] =
+ ptr[DCTSIZE*5] =
+ ptr[DCTSIZE*6] =
+ ptr[DCTSIZE*7] =
+ ptr[DCTSIZE*0];
+
+ continue;
+ }
+
+ z10 = ptr[DCTSIZE*0] + ptr[DCTSIZE*4];
+ z11 = ptr[DCTSIZE*0] - ptr[DCTSIZE*4];
+ z13 = ptr[DCTSIZE*2] + ptr[DCTSIZE*6];
+ z12 = MULTIPLY(ptr[DCTSIZE*2] - ptr[DCTSIZE*6], FIX_1_414213562) - z13;
+
+ tmp0 = z10 + z13;
+ tmp3 = z10 - z13;
+ tmp1 = z11 + z12;
+ tmp2 = z11 - z12;
+
+ z13 = ptr[DCTSIZE*3] + ptr[DCTSIZE*5];
+ z10 = ptr[DCTSIZE*3] - ptr[DCTSIZE*5];
+ z11 = ptr[DCTSIZE*1] + ptr[DCTSIZE*7];
+ z12 = ptr[DCTSIZE*1] - ptr[DCTSIZE*7];
+
+ z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
+ tmp7 = z11 + z13;
+ tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;
+ tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6;
+ tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5;
+
+ ptr[DCTSIZE*0] = (tmp0 + tmp7);
+ ptr[DCTSIZE*7] = (tmp0 - tmp7);
+ ptr[DCTSIZE*1] = (tmp1 + tmp6);
+ ptr[DCTSIZE*6] = (tmp1 - tmp6);
+ ptr[DCTSIZE*2] = (tmp2 + tmp5);
+ ptr[DCTSIZE*5] = (tmp2 - tmp5);
+ ptr[DCTSIZE*4] = (tmp3 + tmp4);
+ ptr[DCTSIZE*3] = (tmp3 - tmp4);
+
+ }
+
+ ptr = block;
+ for (i = 0; i < DCTSIZE; i++ ,ptr+=DCTSIZE) {
+
+ if ((ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] |
+ ptr[7]) == 0) {
+ ptr[0] =
+ ptr[1] =
+ ptr[2] =
+ ptr[3] =
+ ptr[4] =
+ ptr[5] =
+ ptr[6] =
+ ptr[7] =
+ RANGE(DESCALE(ptr[0], PASS1_BITS+3));;
+
+ continue;
+ }
+
+ z10 = ptr[0] + ptr[4];
+ z11 = ptr[0] - ptr[4];
+ z13 = ptr[2] + ptr[6];
+ z12 = MULTIPLY(ptr[2] - ptr[6], FIX_1_414213562) - z13;
+
+ tmp0 = z10 + z13;
+ tmp3 = z10 - z13;
+ tmp1 = z11 + z12;
+ tmp2 = z11 - z12;
+
+ z13 = ptr[3] + ptr[5];
+ z10 = ptr[3] - ptr[5];
+ z11 = ptr[1] + ptr[7];
+ z12 = ptr[1] - ptr[7];
+
+ z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
+ tmp7 = z11 + z13;
+ tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;
+ tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6;
+ tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5;
+
+ ptr[0] = RANGE(DESCALE(tmp0 + tmp7, PASS1_BITS+3));;
+ ptr[7] = RANGE(DESCALE(tmp0 - tmp7, PASS1_BITS+3));;
+ ptr[1] = RANGE(DESCALE(tmp1 + tmp6, PASS1_BITS+3));;
+ ptr[6] = RANGE(DESCALE(tmp1 - tmp6, PASS1_BITS+3));;
+ ptr[2] = RANGE(DESCALE(tmp2 + tmp5, PASS1_BITS+3));;
+ ptr[5] = RANGE(DESCALE(tmp2 - tmp5, PASS1_BITS+3));;
+ ptr[4] = RANGE(DESCALE(tmp3 + tmp4, PASS1_BITS+3));;
+ ptr[3] = RANGE(DESCALE(tmp3 - tmp4, PASS1_BITS+3));;
+
+ }
+}
+
+unsigned short* rl2blk(int *blk,unsigned short *mdec_rl);
+void iqtab_init(int *iqtab,unsigned char *iq_y);
+void yuv2rgb24(int *blk,unsigned char *image);
+void yuv2rgb15(int *blk,unsigned short *image);
+
+struct {
+ u32 command;
+ u32 status;
+ unsigned short *rl;
+ int rlsize;
+} mdec;
+
+int iq_y[DCTSIZE2],iq_uv[DCTSIZE2];
+
+void mdecInit(void) {
+ mdec.rl = (u16*)&psxM[0x100000];
+ mdec.command = 0;
+ mdec.status = 0;
+}
+
+
+void mdecWrite0(u32 data) {
+#ifdef CDR_LOG
+ CDR_LOG("mdec0 write %lx\n", data);
+#endif
+ mdec.command = data;
+ if ((data&0xf5ff0000)==0x30000000) {
+ mdec.rlsize = data&0xffff;
+ }
+}
+
+void mdecWrite1(u32 data) {
+#ifdef CDR_LOG
+ CDR_LOG("mdec1 write %lx\n", data);
+#endif
+ if (data&0x80000000) { // mdec reset
+ mdec.command = 0;
+ mdec.status = 0;
+ }
+}
+
+u32 mdecRead0(void) {
+#ifdef CDR_LOG
+ CDR_LOG("mdec0 read %lx\n", mdec.command);
+#endif
+ return mdec.command;
+}
+
+// mdec status:
+#define MDEC_BUSY 0x20000000
+#define MDEC_DREQ 0x18000000
+#define MDEC_FIFO 0xc0000000
+#define MDEC_RGB24 0x02000000
+#define MDEC_STP 0x00800000
+
+u32 mdecRead1(void) {
+#ifdef CDR_LOG
+ CDR_LOG("mdec1 read %lx\n", mdec.status);
+#endif
+ return mdec.status;
+}
+
+void psxDma0(u32 adr, u32 bcr, u32 chcr) {
+ int cmd = mdec.command;
+ int size;
+
+#ifdef CDR_LOG
+ CDR_LOG("DMA0 %lx %lx %lx\n", adr, bcr, chcr);
+#endif
+
+ if (chcr!=0x01000201) return;
+
+ size = (bcr>>16)*(bcr&0xffff);
+
+ if (cmd==0x60000000) {
+ } else
+ if (cmd==0x40000001) {
+ u8 *p = (u8*)PSXM(adr);
+ iqtab_init(iq_y,p);
+ iqtab_init(iq_uv,p+64);
+ } else
+ if ((cmd&0xf5ff0000)==0x30000000) {
+ mdec.rl = (u16*)PSXM(adr);
+ }
+ else {
+ }
+
+ HW_DMA0_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(0);
+}
+
+void psxDma1(u32 adr, u32 bcr, u32 chcr) {
+ int blk[DCTSIZE2*6];
+ unsigned short *image;
+ int size;
+
+#ifdef CDR_LOG
+ CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)\n", adr, bcr, chcr, mdec.command);
+#endif
+
+ if (chcr!=0x01000200) return;
+
+ size = (bcr>>16)*(bcr&0xffff);
+
+ image = (u16*)PSXM(adr);
+ if (mdec.command&0x08000000) {
+// MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/ / BIAS);
+ MDECOUTDMA_INT((size / 4) / BIAS);
+ size = size / ((16*16)/2);
+ for (;size>0;size--,image+=(16*16)) {
+ mdec.rl = rl2blk(blk,mdec.rl);
+ yuv2rgb15(blk,image);
+ }
+ } else {
+// MDECOUTDMA_INT(((size * (1000000 / 9000)) / 4) /** 4*/ / BIAS);
+ MDECOUTDMA_INT((size / 4) / BIAS);
+ size = size / ((24*16)/2);
+ for (;size>0;size--,image+=(24*16)) {
+ mdec.rl = rl2blk(blk,mdec.rl);
+ yuv2rgb24(blk,(u8 *)image);
+ }
+ }
+ mdec.status|= MDEC_BUSY;
+}
+
+void mdec1Interrupt() {
+#ifdef CDR_LOG
+ CDR_LOG("mdec1Interrupt\n");
+#endif
+ if (HW_DMA1_CHCR & SWAP32(0x01000000)) {
+ // Set a fixed value totaly arbitrarie
+ // another sound value is PSXCLK / 60 or
+ // PSXCLK / 50 since the bug happend
+ // at end of frame. PSXCLK / 1000 seems
+ // good for FF9.
+ // (for FF9 need < ~28000)
+ // CAUTION: commented interrupt-handling may lead to problems, keep an eye ;-)
+ MDECOUTDMA_INT(PSXCLK / 1000);
+ //psxRegs.interrupt|= 0x02000000;
+ //psxRegs.intCycle[5+24+1] *= 8;
+ //psxRegs.intCycle[5+24] = psxRegs.cycle;
+ HW_DMA1_CHCR&= SWAP32(~0x01000000);
+ DMA_INTERRUPT(1);
+ } else {
+ mdec.status&= ~MDEC_BUSY;
+ }
+}
+
+#define RUNOF(a) ((a)>>10)
+#define VALOF(a) (((int)(a)<<(32-10))>>(32-10))
+
+static int zscan[DCTSIZE2] = {
+ 0 ,1 ,8 ,16,9 ,2 ,3 ,10,
+ 17,24,32,25,18,11,4 ,5 ,
+ 12,19,26,33,40,48,41,34,
+ 27,20,13,6 ,7 ,14,21,28,
+ 35,42,49,56,57,50,43,36,
+ 29,22,15,23,30,37,44,51,
+ 58,59,52,45,38,31,39,46,
+ 53,60,61,54,47,55,62,63
+};
+
+static int aanscales[DCTSIZE2] = {
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
+ 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
+ 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
+ 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
+ 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
+};
+
+void iqtab_init(int *iqtab,unsigned char *iq_y) {
+#define CONST_BITS14 14
+#define IFAST_SCALE_BITS 2
+ int i;
+
+ for(i=0;i<DCTSIZE2;i++) {
+ iqtab[i] =iq_y[i] *aanscales[zscan[i]]>>(CONST_BITS14-IFAST_SCALE_BITS);
+ }
+}
+
+#define NOP 0xfe00
+unsigned short* rl2blk(int *blk,unsigned short *mdec_rl) {
+ int i,k,q_scale,rl;
+ int *iqtab;
+
+ memset (blk, 0, 6*DCTSIZE2*4);
+ iqtab = iq_uv;
+ for(i=0;i<6;i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4)
+ if (i>1) iqtab = iq_y;
+
+ // zigzag transformation
+ rl = SWAP16(*mdec_rl); mdec_rl++;
+ q_scale = RUNOF(rl);
+ blk[0] = iqtab[0]*VALOF(rl);
+ for(k = 0;;) {
+ rl = SWAP16(*mdec_rl); mdec_rl++;
+ if (rl==NOP) break;
+ k += RUNOF(rl)+1; // skip level zero-coefficients
+ if (k > 63) break;
+ blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16;
+ }
+// blk[0] = (blk[0] * iq_t[0] * 8) / 16;
+// for(int j=1;j<64;j++)
+// blk[j] = blk[j] * iq_t[j] * q_scale;
+
+ // idct
+ idct(blk,k+1);
+
+ blk+=DCTSIZE2;
+ }
+ return mdec_rl;
+}
+
+#ifdef FIXED
+#define MULR(a) ((((int)0x0000059B) * (a)) >> 10)
+#define MULG(a) ((((int)0xFFFFFEA1) * (a)) >> 10)
+#define MULG2(a) ((((int)0xFFFFFD25) * (a)) >> 10)
+#define MULB(a) ((((int)0x00000716) * (a)) >> 10)
+#else
+#define MULR(a) ((int)((float)1.40200 * (a)))
+#define MULG(a) ((int)((float)-0.3437 * (a)))
+#define MULG2(a) ((int)((float)-0.7143 * (a)))
+#define MULB(a) ((int)((float)1.77200 * (a)))
+#endif
+
+#define MAKERGB15(r, g, b) ( SWAP16((((r) >> 3) << 10)|(((g) >> 3) << 5)|((b) >> 3)) )
+#define ROUND(c) ( ((c) < -128) ? 0 : (((c) > (255 - 128)) ? 255 : ((c) + 128)) )
+
+#define RGB15(n, Y) \
+ image[n] = MAKERGB15(ROUND(Y + R),ROUND(Y + G),ROUND(Y + B));
+
+#define RGB15BW(n, Y) \
+ image[n] = MAKERGB15(ROUND(Y),ROUND(Y),ROUND(Y));
+
+#define RGB24(n, Y) \
+ image[n+2] = ROUND(Y + R); \
+ image[n+1] = ROUND(Y + G); \
+ image[n+0] = ROUND(Y + B);
+
+#define RGB24BW(n, Y) \
+ image[n+2] = ROUND(Y); \
+ image[n+1] = ROUND(Y); \
+ image[n+0] = ROUND(Y);
+
+void yuv2rgb15(int *blk,unsigned short *image) {
+ int x,y;
+ int *Yblk = blk+DCTSIZE2*2;
+ int Cb,Cr,R,G,B;
+ int *Cbblk = blk;
+ int *Crblk = blk+DCTSIZE2;
+
+ if (!Config.Mdec)
+ for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24) {
+ if (y==8) Yblk+=DCTSIZE2;
+ for (x=0;x<4;x++,image+=2,Crblk++,Cbblk++,Yblk+=2) {
+ Cr = *Crblk;
+ Cb = *Cbblk;
+ R = MULR(Cr);
+ G = MULG(Cb) + MULG2(Cr);
+ B = MULB(Cb);
+
+ RGB15(0, Yblk[0]);
+ RGB15(1, Yblk[1]);
+ RGB15(16, Yblk[8]);
+ RGB15(17, Yblk[9]);
+
+ Cr = *(Crblk+4);
+ Cb = *(Cbblk+4);
+ R = MULR(Cr);
+ G = MULG(Cb) + MULG2(Cr);
+ B = MULB(Cb);
+
+ RGB15(8, Yblk[DCTSIZE2+0]);
+ RGB15(9, Yblk[DCTSIZE2+1]);
+ RGB15(24, Yblk[DCTSIZE2+8]);
+ RGB15(25, Yblk[DCTSIZE2+9]);
+ }
+ } else
+ for (y=0;y<16;y+=2,Yblk+=8,image+=24) {
+ if (y==8) Yblk+=DCTSIZE2;
+ for (x=0;x<4;x++,image+=2,Yblk+=2) {
+ RGB15BW(0, Yblk[0]);
+ RGB15BW(1, Yblk[1]);
+ RGB15BW(16, Yblk[8]);
+ RGB15BW(17, Yblk[9]);
+
+ RGB15BW(8, Yblk[DCTSIZE2+0]);
+ RGB15BW(9, Yblk[DCTSIZE2+1]);
+ RGB15BW(24, Yblk[DCTSIZE2+8]);
+ RGB15BW(25, Yblk[DCTSIZE2+9]);
+ }
+ }
+}
+
+void yuv2rgb24(int *blk,unsigned char *image) {
+ int x,y;
+ int *Yblk = blk+DCTSIZE2*2;
+ int Cb,Cr,R,G,B;
+ int *Cbblk = blk;
+ int *Crblk = blk+DCTSIZE2;
+
+ if (!Config.Mdec)
+ for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24*3) {
+ if (y==8) Yblk+=DCTSIZE2;
+ for (x=0;x<4;x++,image+=6,Crblk++,Cbblk++,Yblk+=2) {
+ Cr = *Crblk;
+ Cb = *Cbblk;
+ R = MULR(Cr);
+ G = MULG(Cb) + MULG2(Cr);
+ B = MULB(Cb);
+
+ RGB24(0, Yblk[0]);
+ RGB24(1*3, Yblk[1]);
+ RGB24(16*3, Yblk[8]);
+ RGB24(17*3, Yblk[9]);
+
+ Cr = *(Crblk+4);
+ Cb = *(Cbblk+4);
+ R = MULR(Cr);
+ G = MULG(Cb) + MULG2(Cr);
+ B = MULB(Cb);
+
+ RGB24(8*3, Yblk[DCTSIZE2+0]);
+ RGB24(9*3, Yblk[DCTSIZE2+1]);
+ RGB24(24*3, Yblk[DCTSIZE2+8]);
+ RGB24(25*3, Yblk[DCTSIZE2+9]);
+ }
+ } else
+ for (y=0;y<16;y+=2,Yblk+=8,image+=24*3) {
+ if (y==8) Yblk+=DCTSIZE2;
+ for (x=0;x<4;x++,image+=6,Yblk+=2) {
+ RGB24BW(0, Yblk[0]);
+ RGB24BW(1*3, Yblk[1]);
+ RGB24BW(16*3, Yblk[8]);
+ RGB24BW(17*3, Yblk[9]);
+
+ RGB24BW(8*3, Yblk[DCTSIZE2+0]);
+ RGB24BW(9*3, Yblk[DCTSIZE2+1]);
+ RGB24BW(24*3, Yblk[DCTSIZE2+8]);
+ RGB24BW(25*3, Yblk[DCTSIZE2+9]);
+ }
+ }
+}
+
+int mdecFreeze(gzFile f, int Mode) {
+ char Unused[4096];
+
+ gzfreeze(&mdec, sizeof(mdec));
+ gzfreezel(iq_y);
+ gzfreezel(iq_uv);
+ gzfreezel(Unused);
+
+ return 0;
+}
+
diff --git a/libpcsxcore/mdec.h b/libpcsxcore/mdec.h
new file mode 100644
index 00000000..22484fb1
--- /dev/null
+++ b/libpcsxcore/mdec.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __MDEC_H__
+#define __MDEC_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxhw.h"
+#include "psxdma.h"
+
+void mdecInit();
+void mdecWrite0(u32 data);
+void mdecWrite1(u32 data);
+u32 mdecRead0();
+u32 mdecRead1();
+void psxDma0(u32 madr, u32 bcr, u32 chcr);
+void psxDma1(u32 madr, u32 bcr, u32 chcr);
+void mdec1Interrupt();
+int mdecFreeze(gzFile f, int Mode);
+
+#endif /* __MDEC_H__ */
diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c
new file mode 100644
index 00000000..400f9e7a
--- /dev/null
+++ b/libpcsxcore/misc.c
@@ -0,0 +1,627 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Miscellaneous functions, including savesates and CD-ROM loading.
+*/
+
+#include "misc.h"
+#include "cdrom.h"
+#include "mdec.h"
+
+int Log = 0;
+
+char CdromId[10] = "";
+char CdromLabel[33] = "";
+
+/* PSX Executable types */
+#define PSX_EXE 1
+#define CPE_EXE 2
+#define COFF_EXE 3
+#define INVALID_EXE 4
+
+#define ISODCL(from, to) (to - from + 1)
+
+struct iso_directory_record {
+ char length [ISODCL (1, 1)]; /* 711 */
+ char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ char extent [ISODCL (3, 10)]; /* 733 */
+ char size [ISODCL (11, 18)]; /* 733 */
+ char date [ISODCL (19, 25)]; /* 7 by 711 */
+ char flags [ISODCL (26, 26)];
+ char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ char interleave [ISODCL (28, 28)]; /* 711 */
+ char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ unsigned char name_len [ISODCL (33, 33)]; /* 711 */
+ char name [1];
+};
+
+#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
+#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
+
+void mmssdd( char *b, char *p )
+ {
+ int m, s, d;
+#if defined(__BIGENDIAN__)
+ int block = (b[0]&0xff) | ((b[1]&0xff)<<8) | ((b[2]&0xff)<<16) | (b[3]<<24);
+#else
+ int block = *((int*)b);
+#endif
+
+ block += 150;
+ m = block / 4500; // minuten
+ block = block - m * 4500; // minuten rest
+ s = block / 75; // sekunden
+ d = block - s * 75; // sekunden rest
+
+ m = ( ( m / 10 ) << 4 ) | m % 10;
+ s = ( ( s / 10 ) << 4 ) | s % 10;
+ d = ( ( d / 10 ) << 4 ) | d % 10;
+
+ p[0] = m;
+ p[1] = s;
+ p[2] = d;
+}
+
+#define incTime() \
+ time[0] = btoi(time[0]); time[1] = btoi(time[1]); time[2] = btoi(time[2]); \
+ time[2]++; \
+ if(time[2] == 75) { \
+ time[2] = 0; \
+ time[1]++; \
+ if (time[1] == 60) { \
+ time[1] = 0; \
+ time[0]++; \
+ } \
+ } \
+ time[0] = itob(time[0]); time[1] = itob(time[1]); time[2] = itob(time[2]);
+
+#define READTRACK() \
+ if (CDR_readTrack(time) == -1) return -1; \
+ buf = CDR_getBuffer(); if (buf == NULL) return -1;
+
+#define READDIR(_dir) \
+ READTRACK(); \
+ memcpy(_dir, buf+12, 2048); \
+ \
+ incTime(); \
+ READTRACK(); \
+ memcpy(_dir+2048, buf+12, 2048);
+
+int GetCdromFile(u8 *mdir, u8 *time, s8 *filename) {
+ struct iso_directory_record *dir;
+ char ddir[4096];
+ u8 *buf;
+ int i;
+
+ // only try to scan if a filename is given
+ if(!strlen(filename)) return -1;
+
+ i = 0;
+ while (i < 4096) {
+ dir = (struct iso_directory_record*) &mdir[i];
+ if (dir->length[0] == 0) {
+ return -1;
+ }
+ i += dir->length[0];
+
+ if (dir->flags[0] & 0x2) { // it's a dir
+ if (!strnicmp((char*)&dir->name[0], filename, dir->name_len[0])) {
+ if (filename[dir->name_len[0]] != '\\') continue;
+
+ filename+= dir->name_len[0] + 1;
+
+ mmssdd(dir->extent, (char*)time);
+ READDIR(ddir);
+ i = 0;
+ }
+ } else {
+ if (!strnicmp((char*)&dir->name[0], filename, strlen(filename))) {
+ mmssdd(dir->extent, (char*)time);
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+int LoadCdrom() {
+ EXE_HEADER tmpHead;
+ struct iso_directory_record *dir;
+ u8 time[4],*buf;
+ u8 mdir[4096];
+ s8 exename[256];
+
+ if (!Config.HLE) {
+ psxRegs.pc = psxRegs.GPR.n.ra;
+ return 0;
+ }
+
+ time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);
+
+ READTRACK();
+
+ // skip head and sub, and go to the root directory record
+ dir = (struct iso_directory_record*) &buf[12+156];
+
+ mmssdd(dir->extent, (char*)time);
+
+ READDIR(mdir);
+
+ // Load SYSTEM.CNF and scan for the main executable
+ if (GetCdromFile(mdir, time, "SYSTEM.CNF;1") == -1) {
+ // if SYSTEM.CNF is missing, start an existing PSX.EXE
+ if (GetCdromFile(mdir, time, "PSX.EXE;1") == -1) return -1;
+
+ READTRACK();
+ }
+ else {
+ // read the SYSTEM.CNF
+ READTRACK();
+
+ sscanf((char*)buf+12, "BOOT = cdrom:\\%256s", exename);
+ if (GetCdromFile(mdir, time, exename) == -1) {
+ sscanf((char*)buf+12, "BOOT = cdrom:%256s", exename);
+ if (GetCdromFile(mdir, time, exename) == -1) {
+ char *ptr = strstr(buf+12, "cdrom:");
+ if(ptr) {
+ strncpy(exename, ptr, 256);
+ if (GetCdromFile(mdir, time, exename) == -1)
+ return -1;
+ }
+ }
+ }
+
+ // Read the EXE-Header
+ READTRACK();
+ }
+
+
+ memcpy(&tmpHead, buf+12, sizeof(EXE_HEADER));
+
+ psxRegs.pc = SWAP32(tmpHead.pc0);
+ psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
+ psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
+ if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;
+
+ tmpHead.t_size = SWAP32(tmpHead.t_size);
+ tmpHead.t_addr = SWAP32(tmpHead.t_addr);
+
+ // Read the rest of the main executable
+ while (tmpHead.t_size) {
+ void *ptr = (void *)PSXM(tmpHead.t_addr);
+
+ incTime();
+ READTRACK();
+
+ if (ptr != NULL) memcpy(ptr, buf+12, 2048);
+
+ tmpHead.t_size -= 2048;
+ tmpHead.t_addr += 2048;
+ }
+
+ return 0;
+}
+
+int LoadCdromFile(char *filename, EXE_HEADER *head) {
+ struct iso_directory_record *dir;
+ u8 time[4],*buf;
+ u8 mdir[4096], exename[256];
+ u32 size, addr;
+
+ sscanf(filename, "cdrom:\\%256s", exename);
+
+ time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);
+
+ READTRACK();
+
+ // skip head and sub, and go to the root directory record
+ dir = (struct iso_directory_record*) &buf[12+156];
+
+ mmssdd(dir->extent, (char*)time);
+
+ READDIR(mdir);
+
+ if (GetCdromFile(mdir, time, exename) == -1) return -1;
+
+ READTRACK();
+
+ memcpy(head, buf+12, sizeof(EXE_HEADER));
+ size = head->t_size;
+ addr = head->t_addr;
+
+ while (size) {
+ incTime();
+ READTRACK();
+
+ memcpy((void *)PSXM(addr), buf+12, 2048);
+
+ size -= 2048;
+ addr += 2048;
+ }
+
+ return 0;
+}
+
+int CheckCdrom() {
+ struct iso_directory_record *dir;
+ unsigned char time[4],*buf;
+ unsigned char mdir[4096];
+ char exename[256];
+ int i, c;
+
+ time[0] = itob(0);
+ time[1] = itob(2);
+ time[2] = itob(0x10);
+
+ READTRACK();
+
+ CdromLabel[0] = 0;
+ CdromId[0] = 0;
+
+ strncpy(CdromLabel, buf + 52, 32);
+
+ // skip head and sub, and go to the root directory record
+ dir = (struct iso_directory_record*) &buf[12 + 156];
+
+ mmssdd(dir->extent, (char*)time);
+
+ READDIR(mdir);
+
+ if (GetCdromFile(mdir, time, "SYSTEM.CNF;1") != -1) {
+ READTRACK();
+
+ sscanf((char*)buf+12, "BOOT = cdrom:\\%256s", exename);
+ if (GetCdromFile(mdir, time, exename) == -1) {
+ sscanf((char*)buf+12, "BOOT = cdrom:%256s", exename);
+ if (GetCdromFile(mdir, time, exename) == -1) {
+ char *ptr = strstr(buf+12, "cdrom:"); // possibly the executable is in some subdir
+ for (i=0; i<32; i++) {
+ if (ptr[i] == ' ') continue;
+ if (ptr[i] == '\\') continue;
+ }
+ if(ptr) {
+ strncpy(exename, ptr, 256);
+ if (GetCdromFile(mdir, time, exename) == -1)
+ return -1; // main executable not found
+ }
+ }
+ }
+ } else
+ return -1; // SYSTEM.CNF not found
+
+ i = strlen(exename);
+ if (i >= 2) {
+ if (exename[i - 2] == ';') i-= 2;
+ c = 8; i--;
+ while (i >= 0 && c >= 0) {
+ if (isalnum(exename[i])) CdromId[c--] = exename[i];
+ i--;
+ }
+ }
+
+ if (Config.PsxAuto) { // autodetect system (pal or ntsc)
+ if (strstr(exename, "ES") != NULL)
+ Config.PsxType = 1; // pal
+ else Config.PsxType = 0; // ntsc
+ }
+ psxUpdateVSyncRate();
+ if (CdromLabel[0] == ' ') {
+ strncpy(CdromLabel, CdromId, 9);
+ }
+ SysPrintf("CD-ROM Label: %.32s\n", CdromLabel);
+ SysPrintf("CD-ROM ID: %.9s\n", CdromId);
+
+ return 0;
+}
+
+static int PSXGetFileType(FILE *f) {
+ unsigned long current;
+ u32 mybuf[2048];
+ EXE_HEADER *exe_hdr;
+ FILHDR *coff_hdr;
+
+ current = ftell(f);
+ fseek(f,0L,SEEK_SET);
+ fread(mybuf,2048,1,f);
+ fseek(f,current,SEEK_SET);
+
+ exe_hdr = (EXE_HEADER *)mybuf;
+ if (memcmp(exe_hdr->id,"PS-X EXE",8)==0)
+ return PSX_EXE;
+
+ if (mybuf[0]=='C' && mybuf[1]=='P' && mybuf[2]=='E')
+ return CPE_EXE;
+
+ coff_hdr = (FILHDR *)mybuf;
+ if (coff_hdr->f_magic == 0x0162)
+ return COFF_EXE;
+
+ return INVALID_EXE;
+}
+
+/* TODO Error handling - return integer for each error case below, defined in an enum. Pass variable on return */
+int Load(char *ExePath) {
+ FILE *tmpFile;
+ EXE_HEADER tmpHead;
+ int type;
+ int retval = 0;
+
+ strncpy(CdromId, "SLUS99999", 9);
+ strncpy(CdromLabel, "SLUS_999.99", 11);
+
+ tmpFile = fopen(ExePath,"rb");
+ if (tmpFile == NULL) {
+ SysMessage(_("Error opening file: %s"), ExePath);
+ retval = 0;
+ } else {
+ type = PSXGetFileType(tmpFile);
+ switch (type) {
+ case PSX_EXE:
+ fread(&tmpHead,sizeof(EXE_HEADER),1,tmpFile);
+ fseek(tmpFile, 0x800, SEEK_SET);
+ fread((void *)PSXM(SWAP32(tmpHead.t_addr)), SWAP32(tmpHead.t_size),1,tmpFile);
+ fclose(tmpFile);
+ psxRegs.pc = SWAP32(tmpHead.pc0);
+ psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
+ psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
+ if (psxRegs.GPR.n.sp == 0)
+ psxRegs.GPR.n.sp = 0x801fff00;
+ retval = 0;
+ break;
+ case CPE_EXE:
+ SysMessage(_("CPE files not supported."));
+ retval = -1;
+ break;
+ case COFF_EXE:
+ SysMessage(_("COFF files not supported."));
+ retval = -1;
+ break;
+ case INVALID_EXE:
+ SysMessage(_("This file does not appear to be a valid PSX file."));
+ retval = -1;
+ break;
+ }
+ }
+ return retval;
+}
+
+// STATES
+
+const char PcsxHeader[32] = "STv3 PCSX v" PACKAGE_VERSION;
+
+int SaveState(char *file) {
+ gzFile f;
+ GPUFreeze_t *gpufP;
+ SPUFreeze_t *spufP;
+ int Size;
+ unsigned char *pMem;
+
+ f = gzopen(file, "wb");
+ if (f == NULL) return -1;
+
+ gzwrite(f, (void*)PcsxHeader, 32);
+
+ pMem = (unsigned char *) malloc(128*96*3);
+ if (pMem == NULL) return -1;
+ GPU_getScreenPic(pMem);
+ gzwrite(f, pMem, 128*96*3);
+ free(pMem);
+
+ if (Config.HLE)
+ psxBiosFreeze(1);
+
+ gzwrite(f, psxM, 0x00200000);
+ gzwrite(f, psxR, 0x00080000);
+ gzwrite(f, psxH, 0x00010000);
+ gzwrite(f, (void*)&psxRegs, sizeof(psxRegs));
+
+ // gpu
+ gpufP = (GPUFreeze_t *) malloc(sizeof(GPUFreeze_t));
+ gpufP->ulFreezeVersion = 1;
+ GPU_freeze(1, gpufP);
+ gzwrite(f, gpufP, sizeof(GPUFreeze_t));
+ free(gpufP);
+
+ // spu
+ spufP = (SPUFreeze_t *) malloc(16);
+ SPU_freeze(2, spufP);
+ Size = spufP->Size; gzwrite(f, &Size, 4);
+ free(spufP);
+ spufP = (SPUFreeze_t *) malloc(Size);
+ SPU_freeze(1, spufP);
+ gzwrite(f, spufP, Size);
+ free(spufP);
+
+ sioFreeze(f, 1);
+ cdrFreeze(f, 1);
+ psxHwFreeze(f, 1);
+ psxRcntFreeze(f, 1);
+ mdecFreeze(f, 1);
+
+ gzclose(f);
+
+ return 0;
+}
+
+int LoadState(char *file) {
+ gzFile f;
+ GPUFreeze_t *gpufP;
+ SPUFreeze_t *spufP;
+ int Size;
+ char header[32];
+
+ f = gzopen(file, "rb");
+ if (f == NULL) return -1;
+
+ psxCpu->Reset();
+
+ gzread(f, header, 32);
+
+ if (strncmp("STv3 PCSX", header, 9)) { gzclose(f); return -1; }
+
+ gzseek(f, 128*96*3, SEEK_CUR);
+
+ gzread(f, psxM, 0x00200000);
+ gzread(f, psxR, 0x00080000);
+ gzread(f, psxH, 0x00010000);
+ gzread(f, (void*)&psxRegs, sizeof(psxRegs));
+
+ if (Config.HLE)
+ psxBiosFreeze(0);
+
+ // gpu
+ gpufP = (GPUFreeze_t *) malloc (sizeof(GPUFreeze_t));
+ gzread(f, gpufP, sizeof(GPUFreeze_t));
+ GPU_freeze(0, gpufP);
+ free(gpufP);
+
+ // spu
+ gzread(f, &Size, 4);
+ spufP = (SPUFreeze_t *) malloc (Size);
+ gzread(f, spufP, Size);
+ SPU_freeze(0, spufP);
+ free(spufP);
+
+ sioFreeze(f, 0);
+ cdrFreeze(f, 0);
+ psxHwFreeze(f, 0);
+ psxRcntFreeze(f, 0);
+ mdecFreeze(f, 0);
+
+ gzclose(f);
+
+ return 0;
+}
+
+int CheckState(char *file) {
+ gzFile f;
+ char header[32];
+
+ f = gzopen(file, "rb");
+ if (f == NULL) return -1;
+
+ psxCpu->Reset();
+
+ gzread(f, header, 32);
+
+ gzclose(f);
+
+ if (strncmp("STv3 PCSX", header, 9)) return -1;
+
+ return 0;
+}
+
+// NET Function Helpers
+
+int SendPcsxInfo() {
+ if (NET_recvData == NULL || NET_sendData == NULL)
+ return 0;
+
+// SysPrintf("SendPcsxInfo\n");
+
+ NET_sendData(&Config.Xa, sizeof(Config.Xa), PSE_NET_BLOCKING);
+ NET_sendData(&Config.Sio, sizeof(Config.Sio), PSE_NET_BLOCKING);
+ NET_sendData(&Config.SpuIrq, sizeof(Config.SpuIrq), PSE_NET_BLOCKING);
+ NET_sendData(&Config.RCntFix, sizeof(Config.RCntFix), PSE_NET_BLOCKING);
+ NET_sendData(&Config.PsxType, sizeof(Config.PsxType), PSE_NET_BLOCKING);
+ NET_sendData(&Config.Cpu, sizeof(Config.Cpu), PSE_NET_BLOCKING);
+
+// SysPrintf("Send OK\n");
+
+ return 0;
+}
+
+int RecvPcsxInfo() {
+ int tmp;
+
+ if (NET_recvData == NULL || NET_sendData == NULL)
+ return 0;
+
+// SysPrintf("RecvPcsxInfo\n");
+
+ NET_recvData(&Config.Xa, sizeof(Config.Xa), PSE_NET_BLOCKING);
+ NET_recvData(&Config.Sio, sizeof(Config.Sio), PSE_NET_BLOCKING);
+ NET_recvData(&Config.SpuIrq, sizeof(Config.SpuIrq), PSE_NET_BLOCKING);
+ NET_recvData(&Config.RCntFix, sizeof(Config.RCntFix), PSE_NET_BLOCKING);
+ NET_recvData(&Config.PsxType, sizeof(Config.PsxType), PSE_NET_BLOCKING);
+ psxUpdateVSyncRate();
+
+ SysUpdate();
+
+ tmp = Config.Cpu;
+ NET_recvData(&Config.Cpu, sizeof(Config.Cpu), PSE_NET_BLOCKING);
+ if (tmp != Config.Cpu) {
+ psxCpu->Shutdown();
+#ifdef PSXREC
+ if (Config.Cpu)
+ psxCpu = &psxInt;
+ else psxCpu = &psxRec;
+#else
+ psxCpu = &psxInt;
+#endif
+ if (psxCpu->Init() == -1) {
+ SysClose(); return -1;
+ }
+ psxCpu->Reset();
+ }
+
+// SysPrintf("Recv OK\n");
+
+ return 0;
+}
+
+
+void __Log(char *fmt, ...) {
+ va_list list;
+#ifdef LOG_STDOUT
+ char tmp[1024];
+#endif
+
+ va_start(list, fmt);
+#ifndef LOG_STDOUT
+ vfprintf(emuLog, fmt, list);
+#else
+ vsprintf(tmp, fmt, list);
+ SysPrintf(tmp);
+#endif
+ va_end(list);
+}
+
+// remove the leading and trailing spaces in a string
+void trim(char *str) {
+ int pos = 0;
+ char *dest = str;
+
+ // skip leading blanks
+ while (str[pos] <= ' ' && str[pos] > 0)
+ pos++;
+
+ while (str[pos]) {
+ *(dest++) = str[pos];
+ pos++;
+ }
+
+ *(dest--) = '\0'; // store the null
+
+ // remove trailing blanks
+ while (dest >= str && *dest <= ' ' && *dest > 0)
+ *(dest--) = '\0';
+}
diff --git a/libpcsxcore/misc.h b/libpcsxcore/misc.h
new file mode 100644
index 00000000..a71dfecd
--- /dev/null
+++ b/libpcsxcore/misc.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __MISC_H__
+#define __MISC_H__
+
+#include "psxcommon.h"
+#include "coff.h"
+#include "plugins.h"
+#include "r3000a.h"
+#include "psxmem.h"
+
+#undef s_addr
+
+typedef struct {
+ unsigned char id[8];
+ u32 text;
+ u32 data;
+ u32 pc0;
+ u32 gp0;
+ u32 t_addr;
+ u32 t_size;
+ u32 d_addr;
+ u32 d_size;
+ u32 b_addr;
+ u32 b_size;
+ u32 s_addr;
+ u32 s_size;
+ u32 SavedSP;
+ u32 SavedFP;
+ u32 SavedGP;
+ u32 SavedRA;
+ u32 SavedS0;
+} EXE_HEADER;
+
+extern char CdromId[10];
+extern char CdromLabel[33];
+
+int LoadCdrom();
+int LoadCdromFile(char *filename, EXE_HEADER *head);
+int CheckCdrom();
+int Load(char *ExePath);
+
+int SaveState(char *file);
+int LoadState(char *file);
+int CheckState(char *file);
+
+int SendPcsxInfo();
+int RecvPcsxInfo();
+
+void trim(char *str);
+
+extern char *LabelAuthors;
+extern char *LabelGreets;
+
+#endif /* __MISC_H__ */
diff --git a/libpcsxcore/plugins.c b/libpcsxcore/plugins.c
new file mode 100644
index 00000000..574f07e4
--- /dev/null
+++ b/libpcsxcore/plugins.c
@@ -0,0 +1,820 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Plugin library callback/access functions.
+*/
+
+#include "plugins.h"
+#include "cdriso.h"
+
+char cdrfilename[MAXPATHLEN] = "";
+int cdOpenCase = 0;
+
+#define CheckErr(func) \
+ err = SysLibError(); \
+ if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; }
+
+#if defined (__MACOSX__)
+#define LoadSym(dest, src, name, checkerr) \
+ dest = (src) SysLoadSym(drv, "_" name); \
+ if (checkerr == 0) { SysLibError(); /*clean error*/ } \
+ if (checkerr == 1) CheckErr(name); \
+ if (checkerr == 2) { err = SysLibError(); if (err != NULL) errval = 1; }
+#else
+#define LoadSym(dest, src, name, checkerr) \
+ dest = (src) SysLoadSym(drv, name); if (checkerr == 1) CheckErr(name); \
+ if (checkerr == 2) { err = SysLibError(); if (err != NULL) errval = 1; }
+#endif
+
+static const char *err;
+static int errval;
+
+void *hGPUDriver = NULL;
+
+void CALLBACK GPU__readDataMem(uint32_t *pMem, int iSize) {
+ while (iSize > 0) {
+ *pMem = SWAP32(GPU_readData());
+ iSize--;
+ pMem++;
+ }
+}
+
+void CALLBACK GPU__writeDataMem(uint32_t *pMem, int iSize) {
+ while (iSize > 0) {
+ GPU_writeData(SWAP32(*pMem));
+ iSize--;
+ pMem++;
+ }
+}
+
+void CALLBACK GPU__displayText(char *pText) {
+ SysPrintf("%s\n", pText);
+}
+
+extern int StatesC;
+long CALLBACK GPU__freeze(uint32_t ulGetFreezeData, GPUFreeze_t *pF) {
+ pF->ulFreezeVersion = 1;
+ if (ulGetFreezeData == 0) {
+ int val;
+
+ val = GPU_readStatus();
+ val = 0x04000000 | ((val >> 29) & 0x3);
+ GPU_writeStatus(0x04000003);
+ GPU_writeStatus(0x01000000);
+ GPU_writeData(0xa0000000);
+ GPU_writeData(0x00000000);
+ GPU_writeData(0x02000400);
+ GPU_writeDataMem((uint32_t*)pF->psxVRam, 0x100000/4);
+ GPU_writeStatus(val);
+
+ val = pF->ulStatus;
+ GPU_writeStatus(0x00000000);
+ GPU_writeData(0x01000000);
+ GPU_writeStatus(0x01000000);
+ GPU_writeStatus(0x03000000 | ((val>>24)&0x1));
+ GPU_writeStatus(0x04000000 | ((val>>29)&0x3));
+ GPU_writeStatus(0x08000000 | ((val>>17)&0x3f) | ((val>>10)&0x40));
+ GPU_writeData(0xe1000000 | (val&0x7ff));
+ GPU_writeData(0xe6000000 | ((val>>11)&3));
+
+/* GPU_writeData(0xe3000000 | pF->ulControl[0] & 0xffffff);
+ GPU_writeData(0xe4000000 | pF->ulControl[1] & 0xffffff);
+ GPU_writeData(0xe5000000 | pF->ulControl[2] & 0xffffff);*/
+ return 1;
+ }
+ if (ulGetFreezeData == 1) {
+ int val;
+
+ val = GPU_readStatus();
+ val = 0x04000000 | ((val >> 29) & 0x3);
+ GPU_writeStatus(0x04000003);
+ GPU_writeStatus(0x01000000);
+ GPU_writeData(0xc0000000);
+ GPU_writeData(0x00000000);
+ GPU_writeData(0x02000400);
+ GPU_readDataMem((uint32_t*)pF->psxVRam, 0x100000/4);
+ GPU_writeStatus(val);
+
+ pF->ulStatus = GPU_readStatus();
+
+/* GPU_writeStatus(0x10000003);
+ pF->ulControl[0] = GPU_readData();
+ GPU_writeStatus(0x10000004);
+ pF->ulControl[1] = GPU_readData();
+ GPU_writeStatus(0x10000005);
+ pF->ulControl[2] = GPU_readData();*/
+ return 1;
+ }
+ if(ulGetFreezeData==2) {
+ long lSlotNum=*((long *)pF);
+ char Text[32];
+
+ sprintf (Text, "Selected state %ld", lSlotNum+1);
+ GPU_displayText(Text);
+ return 1;
+ }
+ return 0;
+}
+
+long CALLBACK GPU__configure(void) { return 0; }
+long CALLBACK GPU__test(void) { return 0; }
+void CALLBACK GPU__about(void) {}
+void CALLBACK GPU__makeSnapshot(void) {}
+void CALLBACK GPU__keypressed(int key) {}
+long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
+long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
+void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) { }
+
+#define LoadGpuSym1(dest, name) \
+ LoadSym(GPU_##dest, GPU##dest, name, 1);
+
+#define LoadGpuSym0(dest, name) \
+ LoadSym(GPU_##dest, GPU##dest, name, 0); \
+ if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
+
+#define LoadGpuSymN(dest, name) \
+ LoadSym(GPU_##dest, GPU##dest, name, 0);
+
+int LoadGPUplugin(char *GPUdll) {
+ void *drv;
+
+ hGPUDriver = SysLoadLibrary(GPUdll);
+ if (hGPUDriver == NULL) {
+ GPU_configure = NULL;
+ SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
+ }
+ drv = hGPUDriver;
+ LoadGpuSym1(init, "GPUinit");
+ LoadGpuSym1(shutdown, "GPUshutdown");
+ LoadGpuSym1(open, "GPUopen");
+ LoadGpuSym1(close, "GPUclose");
+ LoadGpuSym1(readData, "GPUreadData");
+ LoadGpuSym0(readDataMem, "GPUreadDataMem");
+ LoadGpuSym1(readStatus, "GPUreadStatus");
+ LoadGpuSym1(writeData, "GPUwriteData");
+ LoadGpuSym0(writeDataMem, "GPUwriteDataMem");
+ LoadGpuSym1(writeStatus, "GPUwriteStatus");
+ LoadGpuSym1(dmaChain, "GPUdmaChain");
+ LoadGpuSym1(updateLace, "GPUupdateLace");
+ LoadGpuSym0(keypressed, "GPUkeypressed");
+ LoadGpuSym0(displayText, "GPUdisplayText");
+ LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
+ LoadGpuSym0(freeze, "GPUfreeze");
+ LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
+ LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
+ LoadGpuSym0(clearDynarec, "GPUclearDynarec");
+ LoadGpuSym0(configure, "GPUconfigure");
+ LoadGpuSym0(test, "GPUtest");
+ LoadGpuSym0(about, "GPUabout");
+
+ return 0;
+}
+
+void *hCDRDriver = NULL;
+
+long CALLBACK CDR__play(unsigned char *sector) { return 0; }
+long CALLBACK CDR__stop(void) { return 0; }
+
+long CALLBACK CDR__getStatus(struct CdrStat *stat) {
+ if (cdOpenCase < 0 || cdOpenCase > time(NULL))
+ stat->Status = 0x10;
+ else
+ stat->Status = 0;
+
+ return 0;
+}
+
+char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
+unsigned char* CALLBACK CDR__getBufferSub(void) { return NULL; }
+long CALLBACK CDR__configure(void) { return 0; }
+long CALLBACK CDR__test(void) { return 0; }
+void CALLBACK CDR__about(void) {}
+long CALLBACK CDR__setfilename(char*filename) { return 0; }
+
+#define LoadCdrSym1(dest, name) \
+ LoadSym(CDR_##dest, CDR##dest, name, 1);
+
+#define LoadCdrSym0(dest, name) \
+ LoadSym(CDR_##dest, CDR##dest, name, 0); \
+ if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
+
+#define LoadCdrSymN(dest, name) \
+ LoadSym(CDR_##dest, CDR##dest, name, 0);
+
+int LoadCDRplugin(char *CDRdll) {
+ void *drv;
+
+ hCDRDriver = SysLoadLibrary(CDRdll);
+ if (hCDRDriver == NULL) {
+ CDR_configure = NULL;
+ SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
+ }
+ drv = hCDRDriver;
+ LoadCdrSym1(init, "CDRinit");
+ LoadCdrSym1(shutdown, "CDRshutdown");
+ LoadCdrSym1(open, "CDRopen");
+ LoadCdrSym1(close, "CDRclose");
+ LoadCdrSym1(getTN, "CDRgetTN");
+ LoadCdrSym1(getTD, "CDRgetTD");
+ LoadCdrSym1(readTrack, "CDRreadTrack");
+ LoadCdrSym1(getBuffer, "CDRgetBuffer");
+ LoadCdrSym0(play, "CDRplay");
+ LoadCdrSym0(stop, "CDRstop");
+ LoadCdrSym0(getStatus, "CDRgetStatus");
+ LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
+ LoadCdrSym0(getBufferSub, "CDRgetBufferSub");
+ LoadCdrSym0(configure, "CDRconfigure");
+ LoadCdrSym0(test, "CDRtest");
+ LoadCdrSym0(about, "CDRabout");
+ LoadCdrSym0(setfilename, "CDRsetfilename");
+
+ return 0;
+}
+
+void *hSPUDriver = NULL;
+
+long CALLBACK SPU__configure(void) { return 0; }
+void CALLBACK SPU__about(void) {}
+long CALLBACK SPU__test(void) { return 0; }
+
+unsigned short regArea[10000];
+unsigned short spuCtrl,spuStat,spuIrq;
+unsigned long spuAddr;
+
+void CALLBACK SPU__writeRegister(uint32_t add,unsigned short value) { // Old Interface
+ uint32_t r=add&0xfff;
+ regArea[(r-0xc00)/2] = value;
+
+ if(r>=0x0c00 && r<0x0d80) {
+ unsigned char ch=(r>>4)-0xc0;
+ switch(r&0x0f) {//switch voices
+ case 0: //left volume
+ SPU_setVolumeL(ch,value);
+ return;
+ case 2: //right volume
+ SPU_setVolumeR(ch,value);
+ return;
+ case 4: //frequency
+ SPU_setPitch(ch,value);
+ return;
+ case 6://start address
+ SPU_setAddr(ch,value);
+ return;
+ //------------------------------------------------// level
+// case 8:
+// s_chan[ch].ADSRX.AttackModeExp = (val&0x8000)?TRUE:FALSE;
+// s_chan[ch].ADSRX.AttackRate = (float)((val>>8) & 0x007f)*1000.0f/240.0f;
+// s_chan[ch].ADSRX.DecayRate = (float)((val>>4) & 0x000f)*1000.0f/240.0f;
+// s_chan[ch].ADSRX.SustainLevel = (float)((val) & 0x000f);
+
+// return;
+// case 10:
+// s_chan[ch].ADSRX.SustainModeExp = (val&0x8000)?TRUE:FALSE;
+// s_chan[ch].ADSRX.ReleaseModeExp = (val&0x0020)?TRUE:FALSE;
+// s_chan[ch].ADSRX.SustainRate = ((float)((val>>6) & 0x007f))*R_SUSTAIN;
+// s_chan[ch].ADSRX.ReleaseRate = ((float)((val) & 0x001f))*R_RELEASE;
+// if(val & 0x4000) s_chan[ch].ADSRX.SustainModeDec=-1.0f;
+// else s_chan[ch].ADSRX.SustainModeDec=1.0f;
+// return;
+// case 12:
+// return;
+// case 14:
+// s_chan[ch].pRepeat=spuMemC+((unsigned long) val<<3);
+// return;
+ }
+ return;
+ }
+
+ switch(r) {
+ case H_SPUaddr://SPU-memory address
+ spuAddr = (uint32_t) value<<3;
+ // spuAddr=value * 8;
+ return;
+ case H_SPUdata://DATA to SPU
+// spuMem[spuAddr/2] = value;
+// spuAddr+=2;
+// if(spuAddr>0x7ffff) spuAddr=0;
+ SPU_putOne(spuAddr,value);
+ spuAddr+=2;
+ return;
+ case H_SPUctrl://SPU control 1
+ spuCtrl=value;
+ return;
+ case H_SPUstat://SPU status
+ spuStat=value & 0xf800;
+ return;
+ case H_SPUirqAddr://SPU irq
+ spuIrq = value;
+ return;
+ case H_SPUon1://start sound play channels 0-16
+ SPU_startChannels1(value);
+ return;
+ case H_SPUon2://start sound play channels 16-24
+ SPU_startChannels2(value);
+ return;
+ case H_SPUoff1://stop sound play channels 0-16
+ SPU_stopChannels1(value);
+ return;
+ case H_SPUoff2://stop sound play channels 16-24
+ SPU_stopChannels2(value);
+ return;
+ }
+}
+
+unsigned short CALLBACK SPU__readRegister(uint32_t add) {
+ switch(add&0xfff) {// Old Interface
+ case H_SPUctrl://spu control
+ return spuCtrl;
+ case H_SPUstat://spu status
+ return spuStat;
+ case H_SPUaddr://SPU-memory address
+ return (unsigned short)(spuAddr>>3);
+ case H_SPUdata://DATA to SPU
+ spuAddr+=2;
+// if(spuAddr>0x7ffff) spuAddr=0;
+// return spuMem[spuAddr/2];
+ return SPU_getOne(spuAddr);
+ case H_SPUirqAddr://spu irq
+ return spuIrq;
+ //case H_SPUIsOn1:
+ //return IsSoundOn(0,16);
+ //case H_SPUIsOn2:
+ //return IsSoundOn(16,24);
+ }
+ return regArea[((add&0xfff)-0xc00)/2];
+}
+
+void CALLBACK SPU__writeDMA(unsigned short val) {
+ SPU_putOne(spuAddr, val);
+ spuAddr += 2;
+ if (spuAddr > 0x7ffff) spuAddr = 0;
+}
+
+unsigned short CALLBACK SPU__readDMA(void) {
+ unsigned short tmp = SPU_getOne(spuAddr);
+ spuAddr += 2;
+ if (spuAddr > 0x7ffff) spuAddr = 0;
+ return tmp;
+}
+
+void CALLBACK SPU__writeDMAMem(unsigned short *pMem, int iSize) {
+ while (iSize > 0) {
+ SPU_writeDMA(*pMem);
+ iSize--;
+ pMem++;
+ }
+}
+
+void CALLBACK SPU__readDMAMem(unsigned short *pMem, int iSize) {
+ while (iSize > 0) {
+ *pMem = SPU_readDMA();
+ iSize--;
+ pMem++;
+ }
+}
+
+void CALLBACK SPU__playADPCMchannel(xa_decode_t *xap) {}
+
+long CALLBACK SPU__freeze(uint32_t ulFreezeMode, SPUFreeze_t *pF) {
+ if (ulFreezeMode == 2) {
+ memset(pF, 0, 16);
+ strcpy((char *)pF->PluginName, "Pcsx");
+ pF->PluginVersion = 1;
+ pF->Size = 0x200 + 0x80000 + 16 + sizeof(xa_decode_t);
+
+ return 1;
+ }
+ if (ulFreezeMode == 1) {
+ uint32_t addr;
+ unsigned short val;
+
+ val = SPU_readRegister(0x1f801da6);
+ SPU_writeRegister(0x1f801da6, 0);
+ SPU_readDMAMem((unsigned short *)pF->SPURam, 0x80000/2);
+ SPU_writeRegister(0x1f801da6, val);
+
+ for (addr = 0x1f801c00; addr < 0x1f801e00; addr+=2) {
+ if (addr == 0x1f801da8) { pF->SPUPorts[addr - 0x1f801c00] = 0; continue; }
+ pF->SPUPorts[addr - 0x1f801c00] = SPU_readRegister(addr);
+ }
+
+ return 1;
+ }
+ if (ulFreezeMode == 0) {
+ uint32_t addr;
+ unsigned short val;
+ unsigned short *regs = (unsigned short *)pF->SPUPorts;
+
+ val = SPU_readRegister(0x1f801da6);
+ SPU_writeRegister(0x1f801da6, 0);
+ SPU_writeDMAMem((unsigned short *)pF->SPURam, 0x80000/2);
+ SPU_writeRegister(0x1f801da6, val);
+
+ for (addr = 0x1f801c00; addr < 0x1f801e00; addr+=2) {
+ if (addr == 0x1f801da8) { regs++; continue; }
+ SPU_writeRegister(addr, *(regs++));
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void CALLBACK SPU__registerCallback(void (CALLBACK *callback)(void)) {}
+
+#define LoadSpuSym1(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, 1);
+
+#define LoadSpuSym2(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, 2);
+
+#define LoadSpuSym0(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, 0); \
+ if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
+
+#define LoadSpuSymE(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, errval); \
+ if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
+
+#define LoadSpuSymN(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, 0); \
+
+int LoadSPUplugin(char *SPUdll) {
+ void *drv;
+
+ hSPUDriver = SysLoadLibrary(SPUdll);
+ if (hSPUDriver == NULL) {
+ SPU_configure = NULL;
+ SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
+ }
+ drv = hSPUDriver;
+ LoadSpuSym1(init, "SPUinit");
+ LoadSpuSym1(shutdown, "SPUshutdown");
+ LoadSpuSym1(open, "SPUopen");
+ LoadSpuSym1(close, "SPUclose");
+ LoadSpuSym0(configure, "SPUconfigure");
+ LoadSpuSym0(about, "SPUabout");
+ LoadSpuSym0(test, "SPUtest");
+ errval = 0;
+ LoadSpuSym2(startChannels1, "SPUstartChannels1");
+ LoadSpuSym2(startChannels2, "SPUstartChannels2");
+ LoadSpuSym2(stopChannels1, "SPUstopChannels1");
+ LoadSpuSym2(stopChannels2, "SPUstopChannels2");
+ LoadSpuSym2(putOne, "SPUputOne");
+ LoadSpuSym2(getOne, "SPUgetOne");
+ LoadSpuSym2(setAddr, "SPUsetAddr");
+ LoadSpuSym2(setPitch, "SPUsetPitch");
+ LoadSpuSym2(setVolumeL, "SPUsetVolumeL");
+ LoadSpuSym2(setVolumeR, "SPUsetVolumeR");
+ LoadSpuSymE(writeRegister, "SPUwriteRegister");
+ LoadSpuSymE(readRegister, "SPUreadRegister");
+ LoadSpuSymE(writeDMA, "SPUwriteDMA");
+ LoadSpuSymE(readDMA, "SPUreadDMA");
+ LoadSpuSym0(writeDMAMem, "SPUwriteDMAMem");
+ LoadSpuSym0(readDMAMem, "SPUreadDMAMem");
+ LoadSpuSym0(playADPCMchannel, "SPUplayADPCMchannel");
+ LoadSpuSym0(freeze, "SPUfreeze");
+ LoadSpuSym0(registerCallback, "SPUregisterCallback");
+ LoadSpuSymN(async, "SPUasync");
+
+ return 0;
+}
+
+
+void *hPAD1Driver = NULL;
+void *hPAD2Driver = NULL;
+
+static unsigned char buf[256];
+unsigned char stdpar[10] = { 0x00, 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+unsigned char mousepar[8] = { 0x00, 0x12, 0x5a, 0xff, 0xff, 0xff, 0xff };
+unsigned char analogpar[9] = { 0x00, 0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+static int bufcount, bufc;
+
+PadDataS padd1, padd2;
+
+unsigned char _PADstartPoll(PadDataS *pad) {
+ bufc = 0;
+
+ switch (pad->controllerType) {
+ case PSE_PAD_TYPE_MOUSE:
+ mousepar[3] = pad->buttonStatus & 0xff;
+ mousepar[4] = pad->buttonStatus >> 8;
+ mousepar[5] = pad->moveX;
+ mousepar[6] = pad->moveY;
+
+ memcpy(buf, mousepar, 7);
+ bufcount = 6;
+ break;
+ case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
+ analogpar[1] = 0x23;
+ analogpar[3] = pad->buttonStatus & 0xff;
+ analogpar[4] = pad->buttonStatus >> 8;
+ analogpar[5] = pad->rightJoyX;
+ analogpar[6] = pad->rightJoyY;
+ analogpar[7] = pad->leftJoyX;
+ analogpar[8] = pad->leftJoyY;
+
+ memcpy(buf, analogpar, 9);
+ bufcount = 8;
+ break;
+ case PSE_PAD_TYPE_ANALOGPAD: // scph1150
+ analogpar[1] = 0x73;
+ analogpar[3] = pad->buttonStatus & 0xff;
+ analogpar[4] = pad->buttonStatus >> 8;
+ analogpar[5] = pad->rightJoyX;
+ analogpar[6] = pad->rightJoyY;
+ analogpar[7] = pad->leftJoyX;
+ analogpar[8] = pad->leftJoyY;
+
+ memcpy(buf, analogpar, 9);
+ bufcount = 8;
+ break;
+ case PSE_PAD_TYPE_ANALOGJOY: // scph1110
+ analogpar[1] = 0x53;
+ analogpar[3] = pad->buttonStatus & 0xff;
+ analogpar[4] = pad->buttonStatus >> 8;
+ analogpar[5] = pad->rightJoyX;
+ analogpar[6] = pad->rightJoyY;
+ analogpar[7] = pad->leftJoyX;
+ analogpar[8] = pad->leftJoyY;
+
+ memcpy(buf, analogpar, 9);
+ bufcount = 8;
+ break;
+ case PSE_PAD_TYPE_STANDARD:
+ default:
+ stdpar[3] = pad->buttonStatus & 0xff;
+ stdpar[4] = pad->buttonStatus >> 8;
+
+ memcpy(buf, stdpar, 5);
+ bufcount = 4;
+ }
+
+ return buf[bufc++];
+}
+
+unsigned char _PADpoll(unsigned char value) {
+ if (bufc > bufcount) return 0;
+ return buf[bufc++];
+}
+
+unsigned char CALLBACK PAD1__startPoll(int pad) {
+ PadDataS padd;
+
+ PAD1_readPort1(&padd);
+
+ return _PADstartPoll(&padd);
+}
+
+unsigned char CALLBACK PAD1__poll(unsigned char value) {
+ return _PADpoll(value);
+}
+
+long CALLBACK PAD1__configure(void) { return 0; }
+void CALLBACK PAD1__about(void) {}
+long CALLBACK PAD1__test(void) { return 0; }
+long CALLBACK PAD1__query(void) { return 3; }
+long CALLBACK PAD1__keypressed() { return 0; }
+
+#define LoadPad1Sym1(dest, name) \
+ LoadSym(PAD1_##dest, PAD##dest, name, 1);
+
+#define LoadPad1SymN(dest, name) \
+ LoadSym(PAD1_##dest, PAD##dest, name, 0);
+
+#define LoadPad1Sym0(dest, name) \
+ LoadSym(PAD1_##dest, PAD##dest, name, 0); \
+ if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
+
+int LoadPAD1plugin(char *PAD1dll) {
+ void *drv;
+
+ hPAD1Driver = SysLoadLibrary(PAD1dll);
+ if (hPAD1Driver == NULL) {
+ PAD1_configure = NULL;
+ SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
+ }
+ drv = hPAD1Driver;
+ LoadPad1Sym1(init, "PADinit");
+ LoadPad1Sym1(shutdown, "PADshutdown");
+ LoadPad1Sym1(open, "PADopen");
+ LoadPad1Sym1(close, "PADclose");
+ LoadPad1Sym0(query, "PADquery");
+ LoadPad1Sym1(readPort1, "PADreadPort1");
+ LoadPad1Sym0(configure, "PADconfigure");
+ LoadPad1Sym0(test, "PADtest");
+ LoadPad1Sym0(about, "PADabout");
+ LoadPad1Sym0(keypressed, "PADkeypressed");
+ LoadPad1Sym0(startPoll, "PADstartPoll");
+ LoadPad1Sym0(poll, "PADpoll");
+ LoadPad1SymN(setSensitive, "PADsetSensitive");
+
+ return 0;
+}
+
+unsigned char CALLBACK PAD2__startPoll(int pad) {
+ PadDataS padd;
+
+ PAD2_readPort2(&padd);
+
+ return _PADstartPoll(&padd);
+}
+
+unsigned char CALLBACK PAD2__poll(unsigned char value) {
+ return _PADpoll(value);
+}
+
+long CALLBACK PAD2__configure(void) { return 0; }
+void CALLBACK PAD2__about(void) {}
+long CALLBACK PAD2__test(void) { return 0; }
+long CALLBACK PAD2__query(void) { return 3; }
+long CALLBACK PAD2__keypressed() { return 0; }
+
+#define LoadPad2Sym1(dest, name) \
+ LoadSym(PAD2_##dest, PAD##dest, name, 1);
+
+#define LoadPad2Sym0(dest, name) \
+ LoadSym(PAD2_##dest, PAD##dest, name, 0); \
+ if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
+
+#define LoadPad2SymN(dest, name) \
+ LoadSym(PAD2_##dest, PAD##dest, name, 0);
+
+int LoadPAD2plugin(char *PAD2dll) {
+ void *drv;
+
+ hPAD2Driver = SysLoadLibrary(PAD2dll);
+ if (hPAD2Driver == NULL) {
+ PAD2_configure = NULL;
+ SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
+ }
+ drv = hPAD2Driver;
+ LoadPad2Sym1(init, "PADinit");
+ LoadPad2Sym1(shutdown, "PADshutdown");
+ LoadPad2Sym1(open, "PADopen");
+ LoadPad2Sym1(close, "PADclose");
+ LoadPad2Sym0(query, "PADquery");
+ LoadPad2Sym1(readPort2, "PADreadPort2");
+ LoadPad2Sym0(configure, "PADconfigure");
+ LoadPad2Sym0(test, "PADtest");
+ LoadPad2Sym0(about, "PADabout");
+ LoadPad2Sym0(keypressed, "PADkeypressed");
+ LoadPad2Sym0(startPoll, "PADstartPoll");
+ LoadPad2Sym0(poll, "PADpoll");
+ LoadPad2SymN(setSensitive, "PADsetSensitive");
+
+ return 0;
+}
+
+void *hNETDriver = NULL;
+
+void CALLBACK NET__setInfo(netInfo *info) {}
+void CALLBACK NET__keypressed(int key) {}
+long CALLBACK NET__configure(void) { return 0; }
+long CALLBACK NET__test(void) { return 0; }
+void CALLBACK NET__about(void) {}
+
+#define LoadNetSym1(dest, name) \
+ LoadSym(NET_##dest, NET##dest, name, 1);
+
+#define LoadNetSymN(dest, name) \
+ LoadSym(NET_##dest, NET##dest, name, 0);
+
+#define LoadNetSym0(dest, name) \
+ LoadSym(NET_##dest, NET##dest, name, 0); \
+ if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
+
+int LoadNETplugin(char *NETdll) {
+ void *drv;
+
+ hNETDriver = SysLoadLibrary(NETdll);
+ if (hNETDriver == NULL) {
+ SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
+ }
+ drv = hNETDriver;
+ LoadNetSym1(init, "NETinit");
+ LoadNetSym1(shutdown, "NETshutdown");
+ LoadNetSym1(open, "NETopen");
+ LoadNetSym1(close, "NETclose");
+ LoadNetSymN(sendData, "NETsendData");
+ LoadNetSymN(recvData, "NETrecvData");
+ LoadNetSym1(sendPadData, "NETsendPadData");
+ LoadNetSym1(recvPadData, "NETrecvPadData");
+ LoadNetSym1(queryPlayer, "NETqueryPlayer");
+ LoadNetSym1(pause, "NETpause");
+ LoadNetSym1(resume, "NETresume");
+ LoadNetSym0(setInfo, "NETsetInfo");
+ LoadNetSym0(keypressed, "NETkeypressed");
+ LoadNetSym0(configure, "NETconfigure");
+ LoadNetSym0(test, "NETtest");
+ LoadNetSym0(about, "NETabout");
+
+ return 0;
+}
+
+void CALLBACK clearDynarec(void) {
+ psxCpu->Reset();
+}
+
+/* TODO If there's an error, need to notify user which plugin failed, rather than silently fail */
+int LoadPlugins() {
+ int ret;
+ char Plugin[MAXPATHLEN];
+
+ ReleasePlugins();
+
+ if (cdrfilename[0] != '\0') {
+ imageReaderInit();
+ } else {
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
+ if (LoadCDRplugin(Plugin) == -1) return -1;
+ }
+
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
+ if (LoadGPUplugin(Plugin) == -1) return -1;
+
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
+ if (LoadSPUplugin(Plugin) == -1) return -1;
+
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
+ if (LoadPAD1plugin(Plugin) == -1) return -1;
+
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
+ if (LoadPAD2plugin(Plugin) == -1) return -1;
+
+ if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
+ Config.UseNet = 0;
+ else {
+ Config.UseNet = 1;
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
+ if (LoadNETplugin(Plugin) == -1) Config.UseNet = 0;
+ }
+
+ /* TODO Proper error code handling - report the appropriate error */
+ ret = CDR_init();
+ if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
+ ret = GPU_init();
+ if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
+ ret = SPU_init();
+ if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
+ ret = PAD1_init(1);
+ if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
+ ret = PAD2_init(2);
+ if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
+
+ if (Config.UseNet) {
+ ret = NET_init();
+ if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
+ }
+
+ SysPrintf(_("Plugins loaded.\n"));
+ return 0;
+}
+
+void ReleasePlugins() {
+ extern FILE *cdHandle;
+
+ if (Config.UseNet) {
+ int ret = NET_close();
+ if (ret < 0) Config.UseNet = 0;
+ NetOpened = 0;
+ }
+
+ if (hCDRDriver != NULL || cdHandle != NULL) CDR_shutdown();
+ if (hGPUDriver != NULL) GPU_shutdown();
+ if (hSPUDriver != NULL) SPU_shutdown();
+ if (hPAD1Driver != NULL) PAD1_shutdown();
+ if (hPAD2Driver != NULL) PAD2_shutdown();
+
+ if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
+
+ if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;
+ if (hGPUDriver != NULL) SysCloseLibrary(hGPUDriver); hGPUDriver = NULL;
+ if (hSPUDriver != NULL) SysCloseLibrary(hSPUDriver); hSPUDriver = NULL;
+ if (hPAD1Driver != NULL) SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL;
+ if (hPAD2Driver != NULL) SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL;
+
+ if (Config.UseNet && hNETDriver != NULL) {
+ SysCloseLibrary(hNETDriver); hNETDriver = NULL;
+ }
+}
diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h
new file mode 100644
index 00000000..7402a9bb
--- /dev/null
+++ b/libpcsxcore/plugins.h
@@ -0,0 +1,348 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PLUGINS_H__
+#define __PLUGINS_H__
+
+#include "psxcommon.h"
+#include "spu.h"
+
+#ifndef _WIN32
+
+typedef void* HWND;
+#define CALLBACK
+
+typedef long (* GPUopen)(unsigned long *, char *, char *);
+typedef long (* SPUopen)(void);
+typedef long (* PADopen)(unsigned long *);
+typedef long (* NETopen)(unsigned long *);
+
+#else
+
+#include <windows.h>
+
+typedef long (CALLBACK* GPUopen)(HWND);
+typedef long (CALLBACK* SPUopen)(HWND);
+typedef long (CALLBACK* PADopen)(HWND);
+typedef long (CALLBACK* NETopen)(HWND);
+
+#endif
+
+#include "psemu_plugin_defs.h"
+#include "decode_xa.h"
+
+int LoadPlugins();
+void ReleasePlugins();
+int OpenPlugins();
+void ClosePlugins();
+
+typedef unsigned long (CALLBACK* PSEgetLibType)(void);
+typedef unsigned long (CALLBACK* PSEgetLibVersion)(void);
+typedef char *(CALLBACK* PSEgetLibName)(void);
+
+///GPU PLUGIN STUFF
+typedef long (CALLBACK* GPUinit)(void);
+typedef long (CALLBACK* GPUshutdown)(void);
+typedef long (CALLBACK* GPUclose)(void);
+typedef void (CALLBACK* GPUwriteStatus)(uint32_t);
+typedef void (CALLBACK* GPUwriteData)(uint32_t);
+typedef void (CALLBACK* GPUwriteDataMem)(uint32_t *, int);
+typedef uint32_t (CALLBACK* GPUreadStatus)(void);
+typedef uint32_t (CALLBACK* GPUreadData)(void);
+typedef void (CALLBACK* GPUreadDataMem)(uint32_t *, int);
+typedef long (CALLBACK* GPUdmaChain)(uint32_t *,uint32_t);
+typedef void (CALLBACK* GPUupdateLace)(void);
+typedef long (CALLBACK* GPUconfigure)(void);
+typedef long (CALLBACK* GPUtest)(void);
+typedef void (CALLBACK* GPUabout)(void);
+typedef void (CALLBACK* GPUmakeSnapshot)(void);
+typedef void (CALLBACK* GPUkeypressed)(int);
+typedef void (CALLBACK* GPUdisplayText)(char *);
+typedef struct {
+ uint32_t ulFreezeVersion;
+ uint32_t ulStatus;
+ uint32_t ulControl[256];
+ unsigned char psxVRam[1024*512*2];
+} GPUFreeze_t;
+typedef long (CALLBACK* GPUfreeze)(uint32_t, GPUFreeze_t *);
+typedef long (CALLBACK* GPUgetScreenPic)(unsigned char *);
+typedef long (CALLBACK* GPUshowScreenPic)(unsigned char *);
+typedef void (CALLBACK* GPUclearDynarec)(void (CALLBACK *callback)(void));
+
+//plugin stuff From Shadow
+// *** walking in the valley of your darking soul i realize that i was alone
+//Gpu function pointers
+GPUupdateLace GPU_updateLace;
+GPUinit GPU_init;
+GPUshutdown GPU_shutdown;
+GPUconfigure GPU_configure;
+GPUtest GPU_test;
+GPUabout GPU_about;
+GPUopen GPU_open;
+GPUclose GPU_close;
+GPUreadStatus GPU_readStatus;
+GPUreadData GPU_readData;
+GPUreadDataMem GPU_readDataMem;
+GPUwriteStatus GPU_writeStatus;
+GPUwriteData GPU_writeData;
+GPUwriteDataMem GPU_writeDataMem;
+GPUdmaChain GPU_dmaChain;
+GPUkeypressed GPU_keypressed;
+GPUdisplayText GPU_displayText;
+GPUmakeSnapshot GPU_makeSnapshot;
+GPUfreeze GPU_freeze;
+GPUgetScreenPic GPU_getScreenPic;
+GPUshowScreenPic GPU_showScreenPic;
+GPUclearDynarec GPU_clearDynarec;
+
+//cd rom plugin ;)
+typedef long (CALLBACK* CDRinit)(void);
+typedef long (CALLBACK* CDRshutdown)(void);
+typedef long (CALLBACK* CDRopen)(void);
+typedef long (CALLBACK* CDRclose)(void);
+typedef long (CALLBACK* CDRgetTN)(unsigned char *);
+typedef long (CALLBACK* CDRgetTD)(unsigned char , unsigned char *);
+typedef long (CALLBACK* CDRreadTrack)(unsigned char *);
+typedef unsigned char * (CALLBACK* CDRgetBuffer)(void);
+typedef long (CALLBACK* CDRconfigure)(void);
+typedef long (CALLBACK* CDRtest)(void);
+typedef void (CALLBACK* CDRabout)(void);
+typedef long (CALLBACK* CDRplay)(unsigned char *);
+typedef long (CALLBACK* CDRstop)(void);
+typedef long (CALLBACK* CDRsetfilename)(char *);
+struct CdrStat {
+ uint32_t Type;
+ uint32_t Status;
+ unsigned char Time[3];
+};
+typedef long (CALLBACK* CDRgetStatus)(struct CdrStat *);
+typedef char* (CALLBACK* CDRgetDriveLetter)(void);
+struct SubQ {
+ char res0[11];
+ unsigned char ControlAndADR;
+ unsigned char TrackNumber;
+ unsigned char IndexNumber;
+ unsigned char TrackRelativeAddress[3];
+ unsigned char Filler;
+ unsigned char AbsoluteAddress[3];
+ char res1[72];
+};
+typedef unsigned char* (CALLBACK* CDRgetBufferSub)(void);
+
+//cd rom function pointers
+CDRinit CDR_init;
+CDRshutdown CDR_shutdown;
+CDRopen CDR_open;
+CDRclose CDR_close;
+CDRtest CDR_test;
+CDRgetTN CDR_getTN;
+CDRgetTD CDR_getTD;
+CDRreadTrack CDR_readTrack;
+CDRgetBuffer CDR_getBuffer;
+CDRplay CDR_play;
+CDRstop CDR_stop;
+CDRgetStatus CDR_getStatus;
+CDRgetDriveLetter CDR_getDriveLetter;
+CDRgetBufferSub CDR_getBufferSub;
+CDRconfigure CDR_configure;
+CDRabout CDR_about;
+CDRsetfilename CDR_setfilename;
+
+// spu plugin
+typedef long (CALLBACK* SPUinit)(void);
+typedef long (CALLBACK* SPUshutdown)(void);
+typedef long (CALLBACK* SPUclose)(void);
+typedef void (CALLBACK* SPUplaySample)(unsigned char);
+typedef void (CALLBACK* SPUstartChannels1)(unsigned short);
+typedef void (CALLBACK* SPUstartChannels2)(unsigned short);
+typedef void (CALLBACK* SPUstopChannels1)(unsigned short);
+typedef void (CALLBACK* SPUstopChannels2)(unsigned short);
+typedef void (CALLBACK* SPUputOne)(uint32_t,unsigned short);
+typedef unsigned short (CALLBACK* SPUgetOne)(uint32_t);
+typedef void (CALLBACK* SPUsetAddr)(unsigned char, unsigned short);
+typedef void (CALLBACK* SPUsetPitch)(unsigned char, unsigned short);
+typedef void (CALLBACK* SPUsetVolumeL)(unsigned char, short);
+typedef void (CALLBACK* SPUsetVolumeR)(unsigned char, short);
+//psemu pro 2 functions from now..
+typedef void (CALLBACK* SPUwriteRegister)(unsigned long, unsigned short);
+typedef unsigned short (CALLBACK* SPUreadRegister)(unsigned long);
+typedef void (CALLBACK* SPUwriteDMA)(unsigned short);
+typedef unsigned short (CALLBACK* SPUreadDMA)(void);
+typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int);
+typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int);
+typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *);
+typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void));
+typedef long (CALLBACK* SPUconfigure)(void);
+typedef long (CALLBACK* SPUtest)(void);
+typedef void (CALLBACK* SPUabout)(void);
+typedef struct {
+ unsigned char PluginName[8];
+ uint32_t PluginVersion;
+ uint32_t Size;
+ unsigned char SPUPorts[0x200];
+ unsigned char SPURam[0x80000];
+ xa_decode_t xa;
+ unsigned char *SPUInfo;
+} SPUFreeze_t;
+typedef long (CALLBACK* SPUfreeze)(uint32_t, SPUFreeze_t *);
+typedef void (CALLBACK* SPUasync)(uint32_t);
+
+//SPU POINTERS
+SPUconfigure SPU_configure;
+SPUabout SPU_about;
+SPUinit SPU_init;
+SPUshutdown SPU_shutdown;
+SPUtest SPU_test;
+SPUopen SPU_open;
+SPUclose SPU_close;
+SPUplaySample SPU_playSample;
+SPUstartChannels1 SPU_startChannels1;
+SPUstartChannels2 SPU_startChannels2;
+SPUstopChannels1 SPU_stopChannels1;
+SPUstopChannels2 SPU_stopChannels2;
+SPUputOne SPU_putOne;
+SPUgetOne SPU_getOne;
+SPUsetAddr SPU_setAddr;
+SPUsetPitch SPU_setPitch;
+SPUsetVolumeL SPU_setVolumeL;
+SPUsetVolumeR SPU_setVolumeR;
+SPUwriteRegister SPU_writeRegister;
+SPUreadRegister SPU_readRegister;
+SPUwriteDMA SPU_writeDMA;
+SPUreadDMA SPU_readDMA;
+SPUwriteDMAMem SPU_writeDMAMem;
+SPUreadDMAMem SPU_readDMAMem;
+SPUplayADPCMchannel SPU_playADPCMchannel;
+SPUfreeze SPU_freeze;
+SPUregisterCallback SPU_registerCallback;
+SPUasync SPU_async;
+
+// PAD Functions
+
+typedef long (CALLBACK* PADconfigure)(void);
+typedef void (CALLBACK* PADabout)(void);
+typedef long (CALLBACK* PADinit)(long);
+typedef long (CALLBACK* PADshutdown)(void);
+typedef long (CALLBACK* PADtest)(void);
+typedef long (CALLBACK* PADclose)(void);
+typedef long (CALLBACK* PADquery)(void);
+typedef long (CALLBACK* PADreadPort1)(PadDataS*);
+typedef long (CALLBACK* PADreadPort2)(PadDataS*);
+typedef long (CALLBACK* PADkeypressed)(void);
+typedef unsigned char (CALLBACK* PADstartPoll)(int);
+typedef unsigned char (CALLBACK* PADpoll)(unsigned char);
+typedef void (CALLBACK* PADsetSensitive)(int);
+
+//PAD POINTERS
+PADconfigure PAD1_configure;
+PADabout PAD1_about;
+PADinit PAD1_init;
+PADshutdown PAD1_shutdown;
+PADtest PAD1_test;
+PADopen PAD1_open;
+PADclose PAD1_close;
+PADquery PAD1_query;
+PADreadPort1 PAD1_readPort1;
+PADkeypressed PAD1_keypressed;
+PADstartPoll PAD1_startPoll;
+PADpoll PAD1_poll;
+PADsetSensitive PAD1_setSensitive;
+
+PADconfigure PAD2_configure;
+PADabout PAD2_about;
+PADinit PAD2_init;
+PADshutdown PAD2_shutdown;
+PADtest PAD2_test;
+PADopen PAD2_open;
+PADclose PAD2_close;
+PADquery PAD2_query;
+PADreadPort2 PAD2_readPort2;
+PADkeypressed PAD2_keypressed;
+PADstartPoll PAD2_startPoll;
+PADpoll PAD2_poll;
+PADsetSensitive PAD2_setSensitive;
+
+// NET plugin
+
+typedef long (CALLBACK* NETinit)(void);
+typedef long (CALLBACK* NETshutdown)(void);
+typedef long (CALLBACK* NETclose)(void);
+typedef long (CALLBACK* NETconfigure)(void);
+typedef long (CALLBACK* NETtest)(void);
+typedef void (CALLBACK* NETabout)(void);
+typedef void (CALLBACK* NETpause)(void);
+typedef void (CALLBACK* NETresume)(void);
+typedef long (CALLBACK* NETqueryPlayer)(void);
+typedef long (CALLBACK* NETsendData)(void *, int, int);
+typedef long (CALLBACK* NETrecvData)(void *, int, int);
+typedef long (CALLBACK* NETsendPadData)(void *, int);
+typedef long (CALLBACK* NETrecvPadData)(void *, int);
+
+typedef struct {
+ char EmuName[32];
+ char CdromID[9]; // ie. 'SCPH12345', no \0 trailing character
+ char CdromLabel[11];
+ void *psxMem;
+ GPUshowScreenPic GPU_showScreenPic;
+ GPUdisplayText GPU_displayText;
+ PADsetSensitive PAD_setSensitive;
+ char GPUpath[256]; // paths must be absolute
+ char SPUpath[256];
+ char CDRpath[256];
+ char MCD1path[256];
+ char MCD2path[256];
+ char BIOSpath[256]; // 'HLE' for internal bios
+ char Unused[1024];
+} netInfo;
+
+typedef long (CALLBACK* NETsetInfo)(netInfo *);
+typedef long (CALLBACK* NETkeypressed)(int);
+
+
+// NET function pointers
+NETinit NET_init;
+NETshutdown NET_shutdown;
+NETopen NET_open;
+NETclose NET_close;
+NETtest NET_test;
+NETconfigure NET_configure;
+NETabout NET_about;
+NETpause NET_pause;
+NETresume NET_resume;
+NETqueryPlayer NET_queryPlayer;
+NETsendData NET_sendData;
+NETrecvData NET_recvData;
+NETsendPadData NET_sendPadData;
+NETrecvPadData NET_recvPadData;
+NETsetInfo NET_setInfo;
+NETkeypressed NET_keypressed;
+
+int LoadCDRplugin(char *CDRdll);
+int LoadGPUplugin(char *GPUdll);
+int LoadSPUplugin(char *SPUdll);
+int LoadPAD1plugin(char *PAD1dll);
+int LoadPAD2plugin(char *PAD2dll);
+int LoadNETplugin(char *NETdll);
+
+void CALLBACK clearDynarec(void);
+
+extern char cdrfilename[MAXPATHLEN];
+
+#endif /* __PLUGINS_H__ */
diff --git a/libpcsxcore/ppc/pGte.h b/libpcsxcore/ppc/pGte.h
new file mode 100644
index 00000000..27894374
--- /dev/null
+++ b/libpcsxcore/ppc/pGte.h
@@ -0,0 +1,670 @@
+/* Pcsx - Pc Psx Emulator
+ * Copyright (C) 1999-2003 Pcsx Team
+ *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+
+int psxCP2time[64] = {
+ 2, 16 , 1 , 1, 1, 1 , 8, 1, // 00
+ 1 , 1 , 1 , 1, 6 , 1 , 1 , 1, // 08
+ 8 , 8, 8, 19, 13 , 1 , 44 , 1, // 10
+ 1 , 1 , 1 , 17, 11 , 1 , 14 , 1, // 18
+ 30 , 1 , 1 , 1, 1, 1 , 1 , 1, // 20
+ 5 , 8 , 17 , 1, 1, 5, 6, 1, // 28
+ 23 , 1 , 1 , 1, 1, 1 , 1 , 1, // 30
+ 1 , 1 , 1 , 1, 1, 6 , 5 , 39 // 38
+};
+
+#define CP2_FUNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ if (pc < cop2readypc) idlecyclecount += (cop2readypc - pc)>>2; \
+ iFlushRegs(0); \
+ LIW(0, (u32)psxRegs.code); \
+ STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
+ FlushAllHWReg(); \
+ CALLFunc ((u32)gte##f); \
+ cop2readypc = pc + psxCP2time[_fFunct_(psxRegs.code)]<<2; \
+}
+
+#define CP2_FUNCNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ if (pc < cop2readypc) idlecyclecount += (cop2readypc - pc)>>2; \
+ iFlushRegs(0); \
+ CALLFunc ((u32)gte##f); \
+/* branch = 2; */\
+ cop2readypc = pc + psxCP2time[_fFunct_(psxRegs.code)]; \
+}
+
+CP2_FUNC(MFC2);
+CP2_FUNC(MTC2);
+CP2_FUNC(CFC2);
+CP2_FUNC(CTC2);
+CP2_FUNC(LWC2);
+CP2_FUNC(SWC2);
+
+#if 0
+void gteMFC2();
+static void recMFC2() {
+// Rt = Cop2D->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+
+ switch (_Rd_) {
+ case 29:
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteMFC2);
+ break;
+
+ default:
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2D.r[_Rd_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ break;
+ }
+}
+
+void gteMTC2();
+static void recMTC2() {
+// Cop2D->Rd = Rt
+ int fixt = 0;
+
+// iFlushRegs();
+
+ switch (_Rd_) {
+ case 8: case 9: case 10: case 11:
+ fixt = 1; break;
+
+ case 16: case 17: case 18: case 19:
+ fixt = 2; break;
+
+ case 15:
+ case 28:
+ case 30:
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteMTC2);
+ break;
+ }
+
+ if (IsConst(_Rt_)) {
+ if (fixt == 1) MOV32ItoM((u32)&psxRegs.CP2D.r[_Rd_], (s16)iRegs[_Rt_].k);
+ else if (fixt == 2) MOV32ItoM((u32)&psxRegs.CP2D.r[_Rd_], iRegs[_Rt_].k & 0xffff);
+ else MOV32ItoM((u32)&psxRegs.CP2D.r[_Rd_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rd_], EAX);
+ }
+}
+
+void gteLWC2();
+static void recLWC2() {
+// Cop2D->Rt = mem[Rs + Im] (unsigned)
+ int fixt = 0;
+
+ switch (_Rt_) {
+ case 8: case 9: case 10: case 11:
+ fixt = 1; break;
+
+ case 16: case 17: case 18: case 19:
+ fixt = 2; break;
+
+ case 15:
+ case 28:
+ case 30:
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteLWC2);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead32);
+ if (fixt == 1) MOVSX32R16toR(EAX, EAX);
+ else if (fixt == 2) AND32ItoR(EAX, 0xffff);
+ MOV32RtoM((u32)&psxRegs.CP2D.r[_Rt_], EAX);
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+void gteSWC2();
+static void recSWC2() {
+// mem[Rs + Im] = Rt
+
+ switch (_Rt_) {
+ case 29:
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code);
+ CALLFunc ((u32)gteSWC2);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2D.r[_Rt_]);
+ MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2D.r[_Rt_]);
+ MOV32RtoM((u32)&psxH[addr & 0xfff], EAX);
+ return;
+ }
+ }
+
+ PUSH32M ((u32)&psxRegs.CP2D.r[_Rt_]);
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+static void recCFC2() {
+// Rt = Cop2C->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.CP2C.r[_Rd_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+}
+
+static void recCTC2() {
+// Cop2C->Rd = Rt
+
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxRegs.CP2C.r[_Rd_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.CP2C.r[_Rd_], EAX);
+ }
+}
+#endif
+
+CP2_FUNCNC(RTPS);
+CP2_FUNC(OP);
+CP2_FUNCNC(NCLIP);
+CP2_FUNCNC(DPCS);
+CP2_FUNCNC(INTPL);
+CP2_FUNC(MVMVA);
+CP2_FUNCNC(NCDS);
+CP2_FUNCNC(NCDT);
+CP2_FUNCNC(CDP);
+CP2_FUNCNC(NCCS);
+CP2_FUNCNC(CC);
+CP2_FUNCNC(NCS);
+CP2_FUNCNC(NCT);
+CP2_FUNC(SQR);
+CP2_FUNCNC(DCPL);
+CP2_FUNCNC(DPCT);
+CP2_FUNCNC(AVSZ3);
+CP2_FUNCNC(AVSZ4);
+CP2_FUNCNC(RTPT);
+CP2_FUNC(GPF);
+CP2_FUNC(GPL);
+CP2_FUNCNC(NCCT);
+
+#if 0
+
+#define gteVX0 ((s16*)psxRegs.CP2D.r)[0]
+#define gteVY0 ((s16*)psxRegs.CP2D.r)[1]
+#define gteVZ0 ((s16*)psxRegs.CP2D.r)[2]
+#define gteVX1 ((s16*)psxRegs.CP2D.r)[4]
+#define gteVY1 ((s16*)psxRegs.CP2D.r)[5]
+#define gteVZ1 ((s16*)psxRegs.CP2D.r)[6]
+#define gteVX2 ((s16*)psxRegs.CP2D.r)[8]
+#define gteVY2 ((s16*)psxRegs.CP2D.r)[9]
+#define gteVZ2 ((s16*)psxRegs.CP2D.r)[10]
+#define gteRGB psxRegs.CP2D.r[6]
+#define gteOTZ ((s16*)psxRegs.CP2D.r)[7*2]
+#define gteIR0 ((s32*)psxRegs.CP2D.r)[8]
+#define gteIR1 ((s32*)psxRegs.CP2D.r)[9]
+#define gteIR2 ((s32*)psxRegs.CP2D.r)[10]
+#define gteIR3 ((s32*)psxRegs.CP2D.r)[11]
+#define gteSX0 ((s16*)psxRegs.CP2D.r)[12*2]
+#define gteSY0 ((s16*)psxRegs.CP2D.r)[12*2+1]
+#define gteSX1 ((s16*)psxRegs.CP2D.r)[13*2]
+#define gteSY1 ((s16*)psxRegs.CP2D.r)[13*2+1]
+#define gteSX2 ((s16*)psxRegs.CP2D.r)[14*2]
+#define gteSY2 ((s16*)psxRegs.CP2D.r)[14*2+1]
+#define gteSXP ((s16*)psxRegs.CP2D.r)[15*2]
+#define gteSYP ((s16*)psxRegs.CP2D.r)[15*2+1]
+#define gteSZx ((u16*)psxRegs.CP2D.r)[16*2]
+#define gteSZ0 ((u16*)psxRegs.CP2D.r)[17*2]
+#define gteSZ1 ((u16*)psxRegs.CP2D.r)[18*2]
+#define gteSZ2 ((u16*)psxRegs.CP2D.r)[19*2]
+#define gteRGB0 psxRegs.CP2D.r[20]
+#define gteRGB1 psxRegs.CP2D.r[21]
+#define gteRGB2 psxRegs.CP2D.r[22]
+#define gteMAC0 psxRegs.CP2D.r[24]
+#define gteMAC1 ((s32*)psxRegs.CP2D.r)[25]
+#define gteMAC2 ((s32*)psxRegs.CP2D.r)[26]
+#define gteMAC3 ((s32*)psxRegs.CP2D.r)[27]
+#define gteIRGB psxRegs.CP2D.r[28]
+#define gteORGB psxRegs.CP2D.r[29]
+#define gteLZCS psxRegs.CP2D.r[30]
+#define gteLZCR psxRegs.CP2D.r[31]
+
+#define gteR ((u8 *)psxRegs.CP2D.r)[6*4]
+#define gteG ((u8 *)psxRegs.CP2D.r)[6*4+1]
+#define gteB ((u8 *)psxRegs.CP2D.r)[6*4+2]
+#define gteCODE ((u8 *)psxRegs.CP2D.r)[6*4+3]
+#define gteC gteCODE
+
+#define gteR0 ((u8 *)psxRegs.CP2D.r)[20*4]
+#define gteG0 ((u8 *)psxRegs.CP2D.r)[20*4+1]
+#define gteB0 ((u8 *)psxRegs.CP2D.r)[20*4+2]
+#define gteCODE0 ((u8 *)psxRegs.CP2D.r)[20*4+3]
+#define gteC0 gteCODE0
+
+#define gteR1 ((u8 *)psxRegs.CP2D.r)[21*4]
+#define gteG1 ((u8 *)psxRegs.CP2D.r)[21*4+1]
+#define gteB1 ((u8 *)psxRegs.CP2D.r)[21*4+2]
+#define gteCODE1 ((u8 *)psxRegs.CP2D.r)[21*4+3]
+#define gteC1 gteCODE1
+
+#define gteR2 ((u8 *)psxRegs.CP2D.r)[22*4]
+#define gteG2 ((u8 *)psxRegs.CP2D.r)[22*4+1]
+#define gteB2 ((u8 *)psxRegs.CP2D.r)[22*4+2]
+#define gteCODE2 ((u8 *)psxRegs.CP2D.r)[22*4+3]
+#define gteC2 gteCODE2
+
+
+
+#define gteR11 ((s16*)psxRegs.CP2C.r)[0]
+#define gteR12 ((s16*)psxRegs.CP2C.r)[1]
+#define gteR13 ((s16*)psxRegs.CP2C.r)[2]
+#define gteR21 ((s16*)psxRegs.CP2C.r)[3]
+#define gteR22 ((s16*)psxRegs.CP2C.r)[4]
+#define gteR23 ((s16*)psxRegs.CP2C.r)[5]
+#define gteR31 ((s16*)psxRegs.CP2C.r)[6]
+#define gteR32 ((s16*)psxRegs.CP2C.r)[7]
+#define gteR33 ((s16*)psxRegs.CP2C.r)[8]
+#define gteTRX ((s32*)psxRegs.CP2C.r)[5]
+#define gteTRY ((s32*)psxRegs.CP2C.r)[6]
+#define gteTRZ ((s32*)psxRegs.CP2C.r)[7]
+#define gteL11 ((s16*)psxRegs.CP2C.r)[16]
+#define gteL12 ((s16*)psxRegs.CP2C.r)[17]
+#define gteL13 ((s16*)psxRegs.CP2C.r)[18]
+#define gteL21 ((s16*)psxRegs.CP2C.r)[19]
+#define gteL22 ((s16*)psxRegs.CP2C.r)[20]
+#define gteL23 ((s16*)psxRegs.CP2C.r)[21]
+#define gteL31 ((s16*)psxRegs.CP2C.r)[22]
+#define gteL32 ((s16*)psxRegs.CP2C.r)[23]
+#define gteL33 ((s16*)psxRegs.CP2C.r)[24]
+#define gteRBK ((s32*)psxRegs.CP2C.r)[13]
+#define gteGBK ((s32*)psxRegs.CP2C.r)[14]
+#define gteBBK ((s32*)psxRegs.CP2C.r)[15]
+#define gteLR1 ((s16*)psxRegs.CP2C.r)[32]
+#define gteLR2 ((s16*)psxRegs.CP2C.r)[33]
+#define gteLR3 ((s16*)psxRegs.CP2C.r)[34]
+#define gteLG1 ((s16*)psxRegs.CP2C.r)[35]
+#define gteLG2 ((s16*)psxRegs.CP2C.r)[36]
+#define gteLG3 ((s16*)psxRegs.CP2C.r)[37]
+#define gteLB1 ((s16*)psxRegs.CP2C.r)[38]
+#define gteLB2 ((s16*)psxRegs.CP2C.r)[39]
+#define gteLB3 ((s16*)psxRegs.CP2C.r)[40]
+#define gteRFC ((s32*)psxRegs.CP2C.r)[21]
+#define gteGFC ((s32*)psxRegs.CP2C.r)[22]
+#define gteBFC ((s32*)psxRegs.CP2C.r)[23]
+#define gteOFX ((s32*)psxRegs.CP2C.r)[24]
+#define gteOFY ((s32*)psxRegs.CP2C.r)[25]
+#define gteH ((u16*)psxRegs.CP2C.r)[52]
+#define gteDQA ((s16*)psxRegs.CP2C.r)[54]
+#define gteDQB ((s32*)psxRegs.CP2C.r)[28]
+#define gteZSF3 ((s16*)psxRegs.CP2C.r)[58]
+#define gteZSF4 ((s16*)psxRegs.CP2C.r)[60]
+#define gteFLAG psxRegs.CP2C.r[31]
+
+//#define SUM_FLAG if(gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000;
+
+#define SUM_FLAG() { \
+ TEST32ItoM((u32)&gteFLAG, 0x7F87E000); \
+ j8Ptr[0] = JZ8(0); \
+ OR32ItoM((u32)&gteFLAG, 0x80000000); \
+ \
+ x86SetJ8(j8Ptr[0]); \
+}
+
+#define LIM32X8(reg, gteout, negv, posv, flagb) { \
+ CMP32ItoR(reg, negv); \
+ j8Ptr[0] = JL8(0); \
+ CMP32ItoR(reg, posv); \
+ j8Ptr[1] = JG8(0); \
+ \
+ MOV8RtoM((u32)&gteout, reg); \
+ j8Ptr[2] = JMP8(0); \
+ \
+ x86SetJ8(j8Ptr[0]); \
+ MOV8ItoM((u32)&gteout, negv); \
+ j8Ptr[3] = JMP8(0); \
+ \
+ x86SetJ8(j8Ptr[1]); \
+ MOV8ItoM((u32)&gteout, posv); \
+ \
+ x86SetJ8(j8Ptr[3]); \
+ OR32ItoM((u32)&gteFLAG, 1<<flagb); \
+ \
+ x86SetJ8(j8Ptr[2]); \
+}
+
+#define _LIM_B1(reg, gteout) LIM32X8(reg, gteout, 0, 255, 21);
+#define _LIM_B2(reg, gteout) LIM32X8(reg, gteout, 0, 255, 20);
+#define _LIM_B3(reg, gteout) LIM32X8(reg, gteout, 0, 255, 19);
+
+#define MAC2IRn(reg, ir, flagb, negv, posv) { \
+/* CMP32ItoR(reg, negv);*/ \
+/* j8Ptr[0] = JL8(0); */\
+/* CMP32ItoR(reg, posv);*/ \
+/* j8Ptr[1] = JG8(0);*/ \
+ \
+ MOV32RtoM((u32)&ir, reg); \
+/* j8Ptr[2] = JMP8(0);*/ \
+ \
+/* x86SetJ8(j8Ptr[0]);*/ \
+/* MOV32ItoM((u32)&ir, negv);*/ \
+/* j8Ptr[3] = JMP8(0);*/ \
+ \
+/* x86SetJ8(j8Ptr[1]);*/ \
+/* MOV32ItoM((u32)&ir, posv);*/ \
+ \
+/* x86SetJ8(j8Ptr[3]);*/ \
+/* OR32ItoR((u32)&gteFLAG, 1<<flagb);*/ \
+ \
+/* x86SetJ8(j8Ptr[2]);*/ \
+}
+
+
+
+#define gte_C11 gteLR1
+#define gte_C12 gteLR2
+#define gte_C13 gteLR3
+#define gte_C21 gteLG1
+#define gte_C22 gteLG2
+#define gte_C23 gteLG3
+#define gte_C31 gteLB1
+#define gte_C32 gteLB2
+#define gte_C33 gteLB3
+
+
+#define _MVMVA_FUNC(vn, mx) { \
+ MOVSX32M16toR(EAX, (u32)&mx##vn##1); \
+ IMUL32R(EBX); \
+/* j8Ptr[0] = JO8(0);*/ \
+ MOV32RtoR(ECX, EAX); \
+ \
+ MOVSX32M16toR(EAX, (u32)&mx##vn##2); \
+ IMUL32R(EDI); \
+/* j8Ptr[1] = JO8(0);*/ \
+ ADD32RtoR(ECX, EAX); \
+/* j8Ptr[2] = JO8(0);*/ \
+ \
+ MOVSX32M16toR(EAX, (u32)&mx##vn##3); \
+ IMUL32R(ESI); \
+/* j8Ptr[3] = JO8(0);*/ \
+ ADD32RtoR(ECX, EAX); \
+/* j8Ptr[4] = JO8(0);*/ \
+}
+
+/* SSX = (_v0) * mx##11 + (_v1) * mx##12 + (_v2) * mx##13;
+ SSY = (_v0) * mx##21 + (_v1) * mx##22 + (_v2) * mx##23;
+ SSZ = (_v0) * mx##31 + (_v1) * mx##32 + (_v2) * mx##33; */
+
+#define _MVMVA_ADD(_vx, jn) { \
+ ADD32MtoR(ECX, (u32)&_vx); \
+/* j8Ptr[jn] = JO8(0);*/ \
+}
+/* SSX+= gteRFC;
+ SSY+= gteGFC;
+ SSZ+= gteBFC;*/
+
+#define _MVMVA1(vn) { \
+ switch (psxRegs.code & 0x60000) { \
+ case 0x00000: /* R */ \
+ _MVMVA_FUNC(vn, gteR); break; \
+ case 0x20000: /* L */ \
+ _MVMVA_FUNC(vn, gteL); break; \
+ case 0x40000: /* C */ \
+ _MVMVA_FUNC(vn, gte_C); break; \
+ default: \
+ return; \
+ } \
+}
+
+#define _MVMVA_LOAD(_v0, _v1, _v2) { \
+ MOVSX32M16toR(EBX, (u32)&_v0); \
+ MOVSX32M16toR(EDI, (u32)&_v1); \
+ MOVSX32M16toR(ESI, (u32)&_v2); \
+}
+
+static void recMVMVA() {
+ int i;
+
+// SysPrintf("GTE_MVMVA %lx\n", psxRegs.code & 0x1ffffff);
+
+/* PUSH32R(ESI);
+ PUSH32R(EDI);
+ PUSH32R(EBX);
+*/
+ XOR32RtoR(EAX, EAX); /* gteFLAG = 0 */
+ MOV32RtoM((u32)&gteFLAG, EAX);
+
+ switch (psxRegs.code & 0x18000) {
+ case 0x00000: /* V0 */
+ _MVMVA_LOAD(gteVX0, gteVY0, gteVZ0); break;
+ case 0x08000: /* V1 */
+ _MVMVA_LOAD(gteVX1, gteVY1, gteVZ1); break;
+ case 0x10000: /* V2 */
+ _MVMVA_LOAD(gteVX2, gteVY2, gteVZ2); break;
+ case 0x18000: /* IR */
+ _MVMVA_LOAD(gteIR1, gteIR2, gteIR3); break;
+ }
+
+// MAC1
+ for (i=5; i<8; i++) j8Ptr[i] = 0;
+ _MVMVA1(1);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRX, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteRBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteRFC, 7); break;
+ }
+/*
+ j8Ptr[9] = JMP8(0);
+ for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);
+
+// TEST32ItoR(EDX, 0x80000000);
+ OR32ItoM((u32)&gteFLAG, 1<<29);
+ x86SetJ8(j8Ptr[9]);*/
+ MOV32RtoM((u32)&gteMAC1, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR1, 24, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR1, 24, -32768, 32767);
+ }
+
+// MAC2
+ _MVMVA1(2);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRY, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteGBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteGFC, 7); break;
+ }
+
+/* for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);*/
+ MOV32RtoM((u32)&gteMAC2, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR2, 23, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR2, 23, -32768, 32767);
+ }
+
+// MAC3
+ _MVMVA1(3);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(ECX, 12);
+// SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0;
+ }
+
+ switch (psxRegs.code & 0x6000) {
+ case 0x0000: // Add TR
+ _MVMVA_ADD(gteTRZ, 5); break;
+ case 0x2000: // Add BK
+ _MVMVA_ADD(gteBBK, 6); break;
+ case 0x4000: // Add FC
+ _MVMVA_ADD(gteBFC, 7); break;
+ }
+
+/* for (i=0; i<5; i++) x86SetJ8(j8Ptr[i]);
+ for (i=5; i<8; i++) if (j8Ptr[i]) x86SetJ8(j8Ptr[i]);*/
+ MOV32RtoM((u32)&gteMAC3, ECX);
+
+ if (psxRegs.code & 0x400) {
+ MAC2IRn(ECX, gteIR3, 22, 0, 32767);
+ } else {
+ MAC2IRn(ECX, gteIR3, 22, -32768, 32767);
+ }
+/* MAC2IR1()
+ else MAC2IR()*/
+
+// SUM_FLAG();
+
+/* POP32R(EBX);
+ POP32R(EDI);
+ POP32R(ESI);*/
+}
+
+#if 0
+
+#define _GPF1(vn) { \
+ MOV32MtoR(EAX, (u32)&gteIR##vn); \
+ IMUL32R(ECX); \
+/* MOV32RtoR(ECX, EAX); */\
+}
+
+static void recGPF() {
+// SysPrintf("GTE_GPF %lx\n", psxRegs.code & 0x1ffffff);
+
+ PUSH32R(EBX);
+
+ XOR32RtoR(EBX, EBX); /* gteFLAG = 0 */
+
+/* gteMAC1 = NC_OVERFLOW1(gteIR0 * gteIR1);
+ gteMAC2 = NC_OVERFLOW2(gteIR0 * gteIR2);
+ gteMAC3 = NC_OVERFLOW3(gteIR0 * gteIR3);*/
+ MOV32MtoR(ECX, (u32)&gteIR0);
+// MAC1
+ _GPF1(1);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR1, 24, -32768, 32767);
+ PUSH32R(EAX);
+
+// MAC2
+ _GPF1(2);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR2, 23, -32768, 32767);
+ PUSH32R(EAX);
+
+// MAC3
+ _GPF1(3);
+
+ if (psxRegs.code & 0x80000) {
+ SAR32ItoR(EAX, 12);
+ }
+ MAC2IRn(EAX, gteIR3, 22, -32768, 32767);
+// MAC2IR();
+
+// gteRGB0 = gteRGB1;
+// gteRGB1 = gteRGB2;
+ MOV32MtoR(EDX, (u32)&gteRGB1);
+ MOV32MtoR(ECX, (u32)&gteRGB2);
+ MOV32RtoM((u32)&gteRGB0, EDX);
+ MOV32RtoM((u32)&gteRGB1, ECX);
+
+ POP32R(EDX);
+ POP32R(ECX);
+ SAR32ItoR(ECX, 4);
+ SAR32ItoR(EDX, 4);
+ SAR32ItoR(EAX, 4);
+
+ _LIM_B1(ECX, gteR2);
+ _LIM_B2(EDX, gteG2);
+ _LIM_B3(EAX, gteB2);
+ MOV8MtoR(EAX, (u32)&gteCODE);
+ MOV8RtoM((u32)&gteCODE2, EAX);
+
+/* gteR2 = limB1(gteMAC1 / 16.0f);
+ gteG2 = limB2(gteMAC2 / 16.0f);
+ gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE;*/
+
+ SUM_FLAG();
+ MOV32RtoM((u32)&gteFLAG, EBX);
+
+// POP32R(EBX);
+}
+#endif
+#endif
diff --git a/libpcsxcore/ppc/pR3000A.c b/libpcsxcore/ppc/pR3000A.c
new file mode 100644
index 00000000..60225f98
--- /dev/null
+++ b/libpcsxcore/ppc/pR3000A.c
@@ -0,0 +1,3528 @@
+/* Pcsx - Pc Psx Emulator
+ * Copyright (C) 1999-2003 Pcsx Team
+ *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA
+ */
+
+#ifdef _MSC_VER_
+#pragma warning(disable:4244)
+#pragma warning(disable:4761)
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#include "../psxcommon.h"
+#include "ppc.h"
+#include "reguse.h"
+#include "../r3000a.h"
+#include "../psxhle.h"
+
+//#define NO_CONSTANT
+
+u32 *psxRecLUT;
+
+#undef _Op_
+#define _Op_ _fOp_(psxRegs.code)
+#undef _Funct_
+#define _Funct_ _fFunct_(psxRegs.code)
+#undef _Rd_
+#define _Rd_ _fRd_(psxRegs.code)
+#undef _Rt_
+#define _Rt_ _fRt_(psxRegs.code)
+#undef _Rs_
+#define _Rs_ _fRs_(psxRegs.code)
+#undef _Sa_
+#define _Sa_ _fSa_(psxRegs.code)
+#undef _Im_
+#define _Im_ _fIm_(psxRegs.code)
+#undef _Target_
+#define _Target_ _fTarget_(psxRegs.code)
+
+#undef _Imm_
+#define _Imm_ _fImm_(psxRegs.code)
+#undef _ImmU_
+#define _ImmU_ _fImmU_(psxRegs.code)
+
+#undef PC_REC
+#undef PC_REC8
+#undef PC_REC16
+#undef PC_REC32
+#define PC_REC(x) (psxRecLUT[x >> 16] + (x & 0xffff))
+#define PC_REC8(x) (*(u8 *)PC_REC(x))
+#define PC_REC16(x) (*(u16*)PC_REC(x))
+#define PC_REC32(x) (*(u32*)PC_REC(x))
+
+#define OFFSET(X,Y) ((u32)(Y)-(u32)(X))
+
+#define RECMEM_SIZE (12*1024*1024)
+
+static char *recMem; /* the recompiled blocks will be here */
+static char *recRAM; /* and the ptr to the blocks here */
+static char *recROM; /* and here */
+
+static u32 pc; /* recompiler pc */
+static u32 pcold; /* recompiler oldpc */
+static int count; /* recompiler intruction count */
+static int branch; /* set for branch */
+static u32 target; /* branch target */
+static u32 resp;
+
+u32 cop2readypc = 0;
+u32 idlecyclecount = 0;
+
+#define NUM_REGISTERS 34
+typedef struct {
+ int state;
+ u32 k;
+ int reg;
+} iRegisters;
+
+static iRegisters iRegs[34];
+
+#define ST_UNK 0x00
+#define ST_CONST 0x01
+#define ST_MAPPED 0x02
+
+#ifdef NO_CONSTANT
+#define IsConst(reg) 0
+#else
+#define IsConst(reg) (iRegs[reg].state & ST_CONST)
+#endif
+#define IsMapped(reg) (iRegs[reg].state & ST_MAPPED)
+
+static void (*recBSC[64])();
+static void (*recSPC[64])();
+static void (*recREG[32])();
+static void (*recCP0[32])();
+static void (*recCP2[64])();
+static void (*recCP2BSC[32])();
+
+#define REG_LO 32
+#define REG_HI 33
+
+// Hardware register usage
+#define HWUSAGE_NONE 0x00
+
+#define HWUSAGE_READ 0x01
+#define HWUSAGE_WRITE 0x02
+#define HWUSAGE_CONST 0x04
+#define HWUSAGE_ARG 0x08 /* used as an argument for a function call */
+
+#define HWUSAGE_RESERVED 0x10 /* won't get flushed when flushing all regs */
+#define HWUSAGE_SPECIAL 0x20 /* special purpose register */
+#define HWUSAGE_HARDWIRED 0x40 /* specific hardware register mapping that is never disposed */
+#define HWUSAGE_INITED 0x80
+#define HWUSAGE_PSXREG 0x100
+
+// Remember to invalidate the special registers if they are modified by compiler
+enum {
+ ARG1 = 3,
+ ARG2 = 4,
+ ARG3 = 5,
+ PSXREGS, // ptr
+ PSXMEM, // ptr
+ CYCLECOUNT, // ptr
+ PSXPC, // ptr
+ TARGETPTR, // ptr
+ TARGET, // ptr
+ RETVAL,
+ REG_RZERO,
+ REG_WZERO
+};
+
+typedef struct {
+ int code;
+ u32 k;
+ int usage;
+ int lastUsed;
+
+ void (*flush)(int hwreg);
+ int private;
+} HWRegister;
+static HWRegister HWRegisters[NUM_HW_REGISTERS];
+static int HWRegUseCount;
+static int DstCPUReg;
+static int UniqueRegAlloc;
+
+static int GetFreeHWReg();
+static void InvalidateCPURegs();
+static void DisposeHWReg(int index);
+static void FlushHWReg(int index);
+static void FlushAllHWReg();
+static void MapPsxReg32(int reg);
+static void FlushPsxReg32(int hwreg);
+static int UpdateHWRegUsage(int hwreg, int usage);
+static int GetHWReg32(int reg);
+static int PutHWReg32(int reg);
+static int GetSpecialIndexFromHWRegs(int which);
+static int GetHWRegFromCPUReg(int cpureg);
+static int MapRegSpecial(int which);
+static void FlushRegSpecial(int hwreg);
+static int GetHWRegSpecial(int which);
+static int PutHWRegSpecial(int which);
+static void recRecompile();
+static void recError();
+
+#pragma mark --- Generic register mapping ---
+
+static int GetFreeHWReg()
+{
+ int i, least, index;
+
+ if (DstCPUReg != -1) {
+ index = GetHWRegFromCPUReg(DstCPUReg);
+ DstCPUReg = -1;
+ } else {
+ // LRU algorith with a twist ;)
+ for (i=0; i<NUM_HW_REGISTERS; i++) {
+ if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) {
+ break;
+ }
+ }
+
+ least = HWRegisters[i].lastUsed; index = i;
+ for (; i<NUM_HW_REGISTERS; i++) {
+ if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) {
+ if (HWRegisters[i].usage == HWUSAGE_NONE && HWRegisters[i].code >= 13) {
+ index = i;
+ break;
+ }
+ else if (HWRegisters[i].lastUsed < least) {
+ least = HWRegisters[i].lastUsed;
+ index = i;
+ }
+ }
+ }
+
+ // Cycle the registers
+ if (HWRegisters[index].usage == HWUSAGE_NONE) {
+ for (; i<NUM_HW_REGISTERS; i++) {
+ if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) {
+ if (HWRegisters[i].usage == HWUSAGE_NONE &&
+ HWRegisters[i].code >= 13 &&
+ HWRegisters[i].lastUsed < least) {
+ least = HWRegisters[i].lastUsed;
+ index = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+/* if (HWRegisters[index].code < 13 && HWRegisters[index].code > 3) {
+ SysPrintf("Allocating volatile register %i\n", HWRegisters[index].code);
+ }
+ if (HWRegisters[index].usage != HWUSAGE_NONE) {
+ SysPrintf("RegUse too big. Flushing %i\n", HWRegisters[index].code);
+ }*/
+ if (HWRegisters[index].usage & (HWUSAGE_RESERVED | HWUSAGE_HARDWIRED)) {
+ if (HWRegisters[index].usage & HWUSAGE_RESERVED) {
+ SysPrintf("Error! Trying to map a new register to a reserved register (r%i)",
+ HWRegisters[index].code);
+ }
+ if (HWRegisters[index].usage & HWUSAGE_HARDWIRED) {
+ SysPrintf("Error! Trying to map a new register to a hardwired register (r%i)",
+ HWRegisters[index].code);
+ }
+ }
+
+ if (HWRegisters[index].lastUsed != 0) {
+ UniqueRegAlloc = 0;
+ }
+
+ // Make sure the register is really flushed!
+ FlushHWReg(index);
+ HWRegisters[index].usage = HWUSAGE_NONE;
+ HWRegisters[index].flush = NULL;
+
+ return index;
+}
+
+static void FlushHWReg(int index)
+{
+ if (index < 0) return;
+ if (HWRegisters[index].usage == HWUSAGE_NONE) return;
+
+ if (HWRegisters[index].flush) {
+ HWRegisters[index].usage |= HWUSAGE_RESERVED;
+ HWRegisters[index].flush(index);
+ HWRegisters[index].flush = NULL;
+ }
+
+ if (HWRegisters[index].usage & HWUSAGE_HARDWIRED) {
+ HWRegisters[index].usage &= ~(HWUSAGE_READ | HWUSAGE_WRITE);
+ } else {
+ HWRegisters[index].usage = HWUSAGE_NONE;
+ }
+}
+
+// get rid of a mapped register without flushing the contents to the memory
+static void DisposeHWReg(int index)
+{
+ if (index < 0) return;
+ if (HWRegisters[index].usage == HWUSAGE_NONE) return;
+
+ HWRegisters[index].usage &= ~(HWUSAGE_READ | HWUSAGE_WRITE);
+ if (HWRegisters[index].usage == HWUSAGE_NONE) {
+ SysPrintf("Error! not correctly disposing register (r%i)", HWRegisters[index].code);
+ }
+
+ FlushHWReg(index);
+}
+
+// operated on cpu registers
+__inline static void FlushCPURegRange(int start, int end)
+{
+ int i;
+
+ if (end <= 0) end = 31;
+ if (start <= 0) start = 0;
+
+ for (i=0; i<NUM_HW_REGISTERS; i++) {
+ if (HWRegisters[i].code >= start && HWRegisters[i].code <= end)
+ if (HWRegisters[i].flush)
+ FlushHWReg(i);
+ }
+
+ for (i=0; i<NUM_HW_REGISTERS; i++) {
+ if (HWRegisters[i].code >= start && HWRegisters[i].code <= end)
+ FlushHWReg(i);
+ }
+}
+
+static void FlushAllHWReg()
+{
+ FlushCPURegRange(0,31);
+}
+
+static void InvalidateCPURegs()
+{
+ FlushCPURegRange(0,12);
+}
+
+#pragma mark --- Mapping utility functions ---
+
+static void MoveHWRegToCPUReg(int cpureg, int hwreg)
+{
+ int dstreg;
+
+ if (HWRegisters[hwreg].code == cpureg)
+ return;
+
+ dstreg = GetHWRegFromCPUReg(cpureg);
+
+ HWRegisters[dstreg].usage &= ~(HWUSAGE_HARDWIRED | HWUSAGE_ARG);
+ if (HWRegisters[hwreg].usage & (HWUSAGE_READ | HWUSAGE_WRITE)) {
+ FlushHWReg(dstreg);
+ MR(HWRegisters[dstreg].code, HWRegisters[hwreg].code);
+ } else {
+ if (HWRegisters[dstreg].usage & (HWUSAGE_READ | HWUSAGE_WRITE)) {
+ MR(HWRegisters[hwreg].code, HWRegisters[dstreg].code);
+ }
+ else if (HWRegisters[dstreg].usage != HWUSAGE_NONE) {
+ FlushHWReg(dstreg);
+ }
+ }
+
+ HWRegisters[dstreg].code = HWRegisters[hwreg].code;
+ HWRegisters[hwreg].code = cpureg;
+}
+
+static int UpdateHWRegUsage(int hwreg, int usage)
+{
+ HWRegisters[hwreg].lastUsed = ++HWRegUseCount;
+ if (usage & HWUSAGE_WRITE) {
+ HWRegisters[hwreg].usage &= ~HWUSAGE_CONST;
+ }
+ if (!(usage & HWUSAGE_INITED)) {
+ HWRegisters[hwreg].usage &= ~HWUSAGE_INITED;
+ }
+ HWRegisters[hwreg].usage |= usage;
+
+ return HWRegisters[hwreg].code;
+}
+
+static int GetHWRegFromCPUReg(int cpureg)
+{
+ int i;
+ for (i=0; i<NUM_HW_REGISTERS; i++) {
+ if (HWRegisters[i].code == cpureg) {
+ return i;
+ }
+ }
+
+ SysPrintf("Error! Register location failure (r%i)", cpureg);
+ return 0;
+}
+
+// this function operates on cpu registers
+void SetDstCPUReg(int cpureg)
+{
+ DstCPUReg = cpureg;
+}
+
+static void ReserveArgs(int args)
+{
+ int index, i;
+
+ for (i=0; i<args; i++) {
+ index = GetHWRegFromCPUReg(3+i);
+ HWRegisters[index].usage |= HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG;
+ }
+}
+
+static void ReleaseArgs()
+{
+ int i;
+
+ for (i=0; i<NUM_HW_REGISTERS; i++) {
+ if (HWRegisters[i].usage & HWUSAGE_ARG) {
+ //HWRegisters[i].usage = HWUSAGE_NONE;
+ //HWRegisters[i].flush = NULL;
+ HWRegisters[i].usage &= ~(HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG);
+ FlushHWReg(i);
+ }
+ }
+}
+
+#pragma mark --- Psx register mapping ---
+
+static void MapPsxReg32(int reg)
+{
+ int hwreg = GetFreeHWReg();
+ HWRegisters[hwreg].flush = FlushPsxReg32;
+ HWRegisters[hwreg].private = reg;
+
+ if (iRegs[reg].reg != -1) {
+ SysPrintf("error: double mapped psx register");
+ }
+
+ iRegs[reg].reg = hwreg;
+ iRegs[reg].state |= ST_MAPPED;
+}
+
+static void FlushPsxReg32(int hwreg)
+{
+ int reg = HWRegisters[hwreg].private;
+
+ if (iRegs[reg].reg == -1) {
+ SysPrintf("error: flushing unmapped psx register");
+ }
+
+ if (HWRegisters[hwreg].usage & HWUSAGE_WRITE) {
+ if (branch) {
+ /*int reguse = nextPsxRegUse(pc-8, reg);
+ if (reguse == REGUSE_NONE || (reguse & REGUSE_READ))*/ {
+ STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS));
+ }
+ } else {
+ int reguse = nextPsxRegUse(pc-4, reg);
+ if (reguse == REGUSE_NONE || (reguse & REGUSE_READ)) {
+ STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS));
+ }
+ }
+ }
+
+ iRegs[reg].reg = -1;
+ iRegs[reg].state = ST_UNK;
+}
+
+static int GetHWReg32(int reg)
+{
+ int usage = HWUSAGE_PSXREG | HWUSAGE_READ;
+
+ if (reg == 0) {
+ return GetHWRegSpecial(REG_RZERO);
+ }
+ if (!IsMapped(reg)) {
+ usage |= HWUSAGE_INITED;
+ MapPsxReg32(reg);
+
+ HWRegisters[iRegs[reg].reg].usage |= HWUSAGE_RESERVED;
+ if (IsConst(reg)) {
+ LIW(HWRegisters[iRegs[reg].reg].code, iRegs[reg].k);
+ usage |= HWUSAGE_WRITE | HWUSAGE_CONST;
+ //iRegs[reg].state &= ~ST_CONST;
+ }
+ else {
+ LWZ(HWRegisters[iRegs[reg].reg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS));
+ }
+ HWRegisters[iRegs[reg].reg].usage &= ~HWUSAGE_RESERVED;
+ }
+ else if (DstCPUReg != -1) {
+ int dst = DstCPUReg;
+ DstCPUReg = -1;
+
+ if (HWRegisters[iRegs[reg].reg].code < 13) {
+ MoveHWRegToCPUReg(dst, iRegs[reg].reg);
+ } else {
+ MR(DstCPUReg, HWRegisters[iRegs[reg].reg].code);
+ }
+ }
+
+ DstCPUReg = -1;
+
+ return UpdateHWRegUsage(iRegs[reg].reg, usage);
+}
+
+static int PutHWReg32(int reg)
+{
+ int usage = HWUSAGE_PSXREG | HWUSAGE_WRITE;
+ if (reg == 0) {
+ return PutHWRegSpecial(REG_WZERO);
+ }
+
+ if (DstCPUReg != -1 && IsMapped(reg)) {
+ if (HWRegisters[iRegs[reg].reg].code != DstCPUReg) {
+ int tmp = DstCPUReg;
+ DstCPUReg = -1;
+ DisposeHWReg(iRegs[reg].reg);
+ DstCPUReg = tmp;
+ }
+ }
+ if (!IsMapped(reg)) {
+ usage |= HWUSAGE_INITED;
+ MapPsxReg32(reg);
+ }
+
+ DstCPUReg = -1;
+ iRegs[reg].state &= ~ST_CONST;
+
+ return UpdateHWRegUsage(iRegs[reg].reg, usage);
+}
+
+#pragma mark --- Special register mapping ---
+
+static int GetSpecialIndexFromHWRegs(int which)
+{
+ int i;
+ for (i=0; i<NUM_HW_REGISTERS; i++) {
+ if (HWRegisters[i].usage & HWUSAGE_SPECIAL) {
+ if (HWRegisters[i].private == which) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+static int MapRegSpecial(int which)
+{
+ int hwreg = GetFreeHWReg();
+ HWRegisters[hwreg].flush = FlushRegSpecial;
+ HWRegisters[hwreg].private = which;
+
+ return hwreg;
+}
+
+static void FlushRegSpecial(int hwreg)
+{
+ int which = HWRegisters[hwreg].private;
+
+ if (!(HWRegisters[hwreg].usage & HWUSAGE_WRITE))
+ return;
+
+ switch (which) {
+ case CYCLECOUNT:
+ STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.cycle), GetHWRegSpecial(PSXREGS));
+ break;
+ case PSXPC:
+ STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.pc), GetHWRegSpecial(PSXREGS));
+ break;
+ case TARGET:
+ STW(HWRegisters[hwreg].code, 0, GetHWRegSpecial(TARGETPTR));
+ break;
+ }
+}
+
+static int GetHWRegSpecial(int which)
+{
+ int index = GetSpecialIndexFromHWRegs(which);
+ int usage = HWUSAGE_READ | HWUSAGE_SPECIAL;
+
+ if (index == -1) {
+ usage |= HWUSAGE_INITED;
+ index = MapRegSpecial(which);
+
+ HWRegisters[index].usage |= HWUSAGE_RESERVED;
+ switch (which) {
+ case PSXREGS:
+ case PSXMEM:
+ SysPrintf("error! shouldn't be here!\n");
+ //HWRegisters[index].flush = NULL;
+ //LIW(HWRegisters[index].code, (u32)&psxRegs);
+ break;
+ case TARGETPTR:
+ HWRegisters[index].flush = NULL;
+ LIW(HWRegisters[index].code, (u32)&target);
+ break;
+ case REG_RZERO:
+ HWRegisters[index].flush = NULL;
+ LIW(HWRegisters[index].code, 0);
+ break;
+ case RETVAL:
+ MoveHWRegToCPUReg(3, index);
+ /*reg = GetHWRegFromCPUReg(3);
+ HWRegisters[reg].code = HWRegisters[index].code;
+ HWRegisters[index].code = 3;*/
+ HWRegisters[index].flush = NULL;
+
+ usage |= HWUSAGE_RESERVED;
+ break;
+
+ case CYCLECOUNT:
+ LWZ(HWRegisters[index].code, OFFSET(&psxRegs, &psxRegs.cycle), GetHWRegSpecial(PSXREGS));
+ break;
+ case PSXPC:
+ LWZ(HWRegisters[index].code, OFFSET(&psxRegs, &psxRegs.pc), GetHWRegSpecial(PSXREGS));
+ break;
+ case TARGET:
+ LWZ(HWRegisters[index].code, 0, GetHWRegSpecial(TARGETPTR));
+ break;
+ default:
+ SysPrintf("Error: Unknown special register in GetHWRegSpecial()\n");
+ break;
+ }
+ HWRegisters[index].usage &= ~HWUSAGE_RESERVED;
+ }
+ else if (DstCPUReg != -1) {
+ int dst = DstCPUReg;
+ DstCPUReg = -1;
+
+ MoveHWRegToCPUReg(dst, index);
+ }
+
+ return UpdateHWRegUsage(index, usage);
+}
+
+static int PutHWRegSpecial(int which)
+{
+ int index = GetSpecialIndexFromHWRegs(which);
+ int usage = HWUSAGE_WRITE | HWUSAGE_SPECIAL;
+
+ if (DstCPUReg != -1 && index != -1) {
+ if (HWRegisters[index].code != DstCPUReg) {
+ int tmp = DstCPUReg;
+ DstCPUReg = -1;
+ DisposeHWReg(index);
+ DstCPUReg = tmp;
+ }
+ }
+ switch (which) {
+ case PSXREGS:
+ case TARGETPTR:
+ SysPrintf("Error: Read-only special register in PutHWRegSpecial()\n");
+ case REG_WZERO:
+ if (index >= 0) {
+ if (HWRegisters[index].usage & HWUSAGE_WRITE)
+ break;
+ }
+ index = MapRegSpecial(which);
+ HWRegisters[index].flush = NULL;
+ break;
+ default:
+ if (index == -1) {
+ usage |= HWUSAGE_INITED;
+ index = MapRegSpecial(which);
+
+ HWRegisters[index].usage |= HWUSAGE_RESERVED;
+ switch (which) {
+ case ARG1:
+ case ARG2:
+ case ARG3:
+ MoveHWRegToCPUReg(3+(which-ARG1), index);
+ /*reg = GetHWRegFromCPUReg(3+(which-ARG1));
+
+ if (HWRegisters[reg].usage != HWUSAGE_NONE) {
+ HWRegisters[reg].usage &= ~(HWUSAGE_HARDWIRED | HWUSAGE_ARG);
+ if (HWRegisters[reg].flush != NULL && HWRegisters[reg].usage & (HWUSAGE_WRITE | HWUSAGE_READ)) {
+ MR(HWRegisters[index].code, HWRegisters[reg].code);
+ } else {
+ FlushHWReg(reg);
+ }
+ }
+ HWRegisters[reg].code = HWRegisters[index].code;
+ if (!(HWRegisters[index].code >= 3 && HWRegisters[index].code <=31))
+ SysPrintf("Error! Register allocation");
+ HWRegisters[index].code = 3+(which-ARG1);*/
+ HWRegisters[index].flush = NULL;
+
+ usage |= HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG;
+ break;
+ }
+ }
+ HWRegisters[index].usage &= ~HWUSAGE_RESERVED;
+ break;
+ }
+
+ DstCPUReg = -1;
+
+ return UpdateHWRegUsage(index, usage);
+}
+
+#pragma mark --- ---
+
+static void MapConst(int reg, u32 _const) {
+ if (reg == 0)
+ return;
+ if (IsConst(reg) && iRegs[reg].k == _const)
+ return;
+
+ DisposeHWReg(iRegs[reg].reg);
+ iRegs[reg].k = _const;
+ iRegs[reg].state = ST_CONST;
+}
+
+static void MapCopy(int dst, int src)
+{
+ // do it the lazy way for now
+ MR(PutHWReg32(dst), GetHWReg32(src));
+}
+
+static void iFlushReg(u32 nextpc, int reg) {
+ if (!IsMapped(reg) && IsConst(reg)) {
+ GetHWReg32(reg);
+ }
+ if (IsMapped(reg)) {
+ if (nextpc) {
+ int use = nextPsxRegUse(nextpc, reg);
+ if ((use & REGUSE_RW) == REGUSE_WRITE) {
+ DisposeHWReg(iRegs[reg].reg);
+ } else {
+ FlushHWReg(iRegs[reg].reg);
+ }
+ } else {
+ FlushHWReg(iRegs[reg].reg);
+ }
+ }
+}
+
+static void iFlushRegs(u32 nextpc) {
+ int i;
+
+ for (i=1; i<NUM_REGISTERS; i++) {
+ iFlushReg(nextpc, i);
+ }
+}
+
+static void Return()
+{
+ iFlushRegs(0);
+ FlushAllHWReg();
+ if (((u32)returnPC & 0x1fffffc) == (u32)returnPC) {
+ BA((u32)returnPC);
+ }
+ else {
+ LIW(0, (u32)returnPC);
+ MTLR(0);
+ BLR();
+ }
+}
+
+static void iRet() {
+ /* store cycle */
+ count = idlecyclecount + (pc - pcold)/4;
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+ Return();
+}
+
+static int iLoadTest() {
+ u32 tmp;
+
+ // check for load delay
+ tmp = psxRegs.code >> 26;
+ switch (tmp) {
+ case 0x10: // COP0
+ switch (_Rs_) {
+ case 0x00: // MFC0
+ case 0x02: // CFC0
+ return 1;
+ }
+ break;
+ case 0x12: // COP2
+ switch (_Funct_) {
+ case 0x00:
+ switch (_Rs_) {
+ case 0x00: // MFC2
+ case 0x02: // CFC2
+ return 1;
+ }
+ break;
+ }
+ break;
+ case 0x32: // LWC2
+ return 1;
+ default:
+ if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+/* set a pending branch */
+static void SetBranch() {
+ int treg;
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc+=4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs(0);
+ LIW(0, psxRegs.code);
+ STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS));
+ /* store cycle */
+ count = idlecyclecount + (pc - pcold)/4;
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+
+ treg = GetHWRegSpecial(TARGET);
+ MR(PutHWRegSpecial(ARG2), treg);
+ DisposeHWReg(GetHWRegFromCPUReg(treg));
+ LIW(PutHWRegSpecial(ARG1), _Rt_);
+ LIW(GetHWRegSpecial(PSXPC), pc);
+ FlushAllHWReg();
+ CALLFunc((u32)psxDelayTest);
+
+ Return();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs(0);
+ treg = GetHWRegSpecial(TARGET);
+ MR(PutHWRegSpecial(PSXPC), GetHWRegSpecial(TARGET)); // FIXME: this line should not be needed
+ DisposeHWReg(GetHWRegFromCPUReg(treg));
+ FlushAllHWReg();
+
+ count = idlecyclecount + (pc - pcold)/4;
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+ FlushAllHWReg();
+ CALLFunc((u32)psxBranchTest);
+
+ // TODO: don't return if target is compiled
+ Return();
+}
+
+static void iJump(u32 branchPC) {
+ u32 *b1, *b2;
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc+=4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs(0);
+ LIW(0, psxRegs.code);
+ STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS));
+ /* store cycle */
+ count = idlecyclecount + (pc - pcold)/4;
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+
+ LIW(PutHWRegSpecial(ARG2), branchPC);
+ LIW(PutHWRegSpecial(ARG1), _Rt_);
+ LIW(GetHWRegSpecial(PSXPC), pc);
+ FlushAllHWReg();
+ CALLFunc((u32)psxDelayTest);
+
+ Return();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs(branchPC);
+ LIW(PutHWRegSpecial(PSXPC), branchPC);
+ FlushAllHWReg();
+
+ count = idlecyclecount + (pc - pcold)/4;
+ //if (/*psxRegs.code == 0 &&*/ count == 2 && branchPC == pcold) {
+ // LIW(PutHWRegSpecial(CYCLECOUNT), 0);
+ //} else {
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+ //}
+ FlushAllHWReg();
+ CALLFunc((u32)psxBranchTest);
+
+ if (!Config.HLE && Config.PsxOut &&
+ ((branchPC & 0x1fffff) == 0xa0 ||
+ (branchPC & 0x1fffff) == 0xb0 ||
+ (branchPC & 0x1fffff) == 0xc0))
+ CALLFunc((u32)psxJumpTest);
+
+ // always return for now...
+ //Return();
+
+ // maybe just happened an interruption, check so
+ LIW(0, branchPC);
+ CMPLW(GetHWRegSpecial(PSXPC), 0);
+ BNE_L(b1);
+
+ LIW(3, PC_REC(branchPC));
+ LWZ(3, 0, 3);
+ CMPLWI(3, 0);
+ BNE_L(b2);
+
+ B_DST(b1);
+ Return();
+
+ // next bit is already compiled - jump right to it
+ B_DST(b2);
+ MTCTR(3);
+ BCTR();
+}
+
+static void iBranch(u32 branchPC, int savectx) {
+ HWRegister HWRegistersS[NUM_HW_REGISTERS];
+ iRegisters iRegsS[NUM_REGISTERS];
+ int HWRegUseCountS = 0;
+ u32 respold=0;
+ u32 *b1, *b2;
+
+ if (savectx) {
+ respold = resp;
+ memcpy(iRegsS, iRegs, sizeof(iRegs));
+ memcpy(HWRegistersS, HWRegisters, sizeof(HWRegisters));
+ HWRegUseCountS = HWRegUseCount;
+ }
+
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+
+ // the delay test is only made when the branch is taken
+ // savectx == 0 will mean that :)
+ if (savectx == 0 && iLoadTest() == 1) {
+ iFlushRegs(0);
+ LIW(0, psxRegs.code);
+ STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS));
+ /* store cycle */
+ count = idlecyclecount + ((pc+4) - pcold)/4;
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+
+ LIW(PutHWRegSpecial(ARG2), branchPC);
+ LIW(PutHWRegSpecial(ARG1), _Rt_);
+ LIW(GetHWRegSpecial(PSXPC), pc);
+ FlushAllHWReg();
+ CALLFunc((u32)psxDelayTest);
+
+ Return();
+ return;
+ }
+
+ pc+= 4;
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs(branchPC);
+ LIW(PutHWRegSpecial(PSXPC), branchPC);
+ FlushAllHWReg();
+
+ /* store cycle */
+ count = idlecyclecount + (pc - pcold)/4;
+ //if (/*psxRegs.code == 0 &&*/ count == 2 && branchPC == pcold) {
+ // LIW(PutHWRegSpecial(CYCLECOUNT), 0);
+ //} else {
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+ //}
+ FlushAllHWReg();
+ CALLFunc((u32)psxBranchTest);
+
+ // always return for now...
+ //Return();
+
+ LIW(0, branchPC);
+ CMPLW(GetHWRegSpecial(PSXPC), 0);
+ BNE_L(b1);
+
+ LIW(3, PC_REC(branchPC));
+ LWZ(3, 0, 3);
+ CMPLWI(3, 0);
+ BNE_L(b2);
+
+ B_DST(b1);
+ Return();
+
+ B_DST(b2);
+ MTCTR(3);
+ BCTR();
+
+ // maybe just happened an interruption, check so
+/* CMP32ItoM((u32)&psxRegs.pc, branchPC);
+ j8Ptr[1] = JE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[1]);
+ MOV32MtoR(EAX, PC_REC(branchPC));
+ TEST32RtoR(EAX, EAX);
+ j8Ptr[2] = JNE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[2]);
+ JMP32R(EAX);*/
+
+ pc-= 4;
+ if (savectx) {
+ resp = respold;
+ memcpy(iRegs, iRegsS, sizeof(iRegs));
+ memcpy(HWRegisters, HWRegistersS, sizeof(HWRegisters));
+ HWRegUseCount = HWRegUseCountS;
+ }
+}
+
+
+static void iDumpRegs() {
+ int i, j;
+
+ printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle);
+ for (i=0; i<4; i++) {
+ for (j=0; j<8; j++)
+ printf("%lx ", psxRegs.GPR.r[j*i]);
+ printf("\n");
+ }
+}
+
+void iDumpBlock(char *ptr) {
+/* FILE *f;
+ u32 i;
+
+ SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxCurrentCycle);
+
+ for (i = psxRegs.pc; i < pc; i+=4)
+ SysPrintf("%s\n", disR3000AF(PSXMu32(i), i));
+
+ fflush(stdout);
+ f = fopen("dump1", "w");
+ fwrite(ptr, 1, (u32)x86Ptr - (u32)ptr, f);
+ fclose(f);
+ system("ndisasmw -u dump1");
+ fflush(stdout);*/
+}
+
+#define REC_FUNC(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(0); \
+ LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \
+ STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
+ LIW(PutHWRegSpecial(PSXPC), (u32)pc); \
+ FlushAllHWReg(); \
+ CALLFunc((u32)psx##f); \
+/* branch = 2; */\
+}
+
+#define REC_SYS(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(0); \
+ LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \
+ STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
+ LIW(PutHWRegSpecial(PSXPC), (u32)pc); \
+ FlushAllHWReg(); \
+ CALLFunc((u32)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+#define REC_BRANCH(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(0); \
+ LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \
+ STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
+ LIW(PutHWRegSpecial(PSXPC), (u32)pc); \
+ FlushAllHWReg(); \
+ CALLFunc((u32)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+static void freeMem(int all)
+{
+ if (recMem) free(recMem);
+ if (recRAM) free(recRAM);
+ if (recROM) free(recROM);
+ recMem = recRAM = recROM = 0;
+
+ if (all && psxRecLUT) {
+ free(psxRecLUT); psxRecLUT = NULL;
+ }
+}
+
+static int allocMem() {
+ int i;
+
+ freeMem(0);
+
+ if (psxRecLUT==NULL)
+ psxRecLUT = (u32*) malloc(0x010000 * 4);
+
+ recMem = (char*) malloc(RECMEM_SIZE);
+ //recMem = mmap(NULL, RECMEM_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+ recRAM = (char*) malloc(0x200000);
+ recROM = (char*) malloc(0x080000);
+ if (recRAM == NULL || recROM == NULL || recMem == NULL/*(void *)-1*/ || psxRecLUT == NULL) {
+ freeMem(1);
+ SysMessage("Error allocating memory"); return -1;
+ }
+
+ for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16];
+ memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * 4);
+ memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * 4);
+
+ for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = (u32)&recROM[i << 16];
+
+ return 0;
+}
+
+static int recInit() {
+ return allocMem();
+}
+
+static void recReset() {
+ memset(recRAM, 0, 0x200000);
+ memset(recROM, 0, 0x080000);
+
+ ppcInit();
+ ppcSetPtr((u32 *)recMem);
+
+ branch = 0;
+ memset(iRegs, 0, sizeof(iRegs));
+ iRegs[0].state = ST_CONST;
+ iRegs[0].k = 0;
+}
+
+static void recShutdown() {
+ freeMem(1);
+ ppcShutdown();
+}
+
+static void recError() {
+ SysReset();
+ ClosePlugins();
+ SysMessage("Unrecoverable error while running recompiler\n");
+ SysRunGui();
+}
+
+__inline static void execute() {
+ void (**recFunc)();
+ char *p;
+
+ p = (char*)PC_REC(psxRegs.pc);
+ /*if (p != NULL)*/ recFunc = (void (**)()) (u32)p;
+ /*else { recError(); return; }*/
+
+ if (*recFunc == 0) {
+ recRecompile();
+ }
+ recRun(*recFunc, (u32)&psxRegs, (u32)&psxM);
+}
+
+static void recExecute() {
+ for (;;) execute();
+}
+
+static void recExecuteBlock() {
+ execute();
+}
+
+static void recClear(u32 Addr, u32 Size) {
+ memset((void*)PC_REC(Addr), 0, Size * 4);
+}
+
+static void recNULL() {
+// SysMessage("recUNK: %8.8x\n", psxRegs.code);
+}
+
+/*********************************************************
+* goes to opcodes tables... *
+* Format: table[something....] *
+*********************************************************/
+
+//REC_SYS(SPECIAL);
+static void recSPECIAL() {
+ recSPC[_Funct_]();
+}
+
+static void recREGIMM() {
+ recREG[_Rt_]();
+}
+
+static void recCOP0() {
+ recCP0[_Rs_]();
+}
+
+//REC_SYS(COP2);
+static void recCOP2() {
+ recCP2[_Funct_]();
+}
+
+static void recBASIC() {
+ recCP2BSC[_Rs_]();
+}
+
+//end of Tables opcodes...
+
+#pragma mark - Arithmetic with immediate operand -
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+
+#if 0
+/*REC_FUNC(ADDI);
+REC_FUNC(ADDIU);
+REC_FUNC(ANDI);
+REC_FUNC(ORI);
+REC_FUNC(XORI);
+REC_FUNC(SLTI);
+REC_FUNC(SLTIU);*/
+#else
+static void recADDIU() {
+// Rt = Rs + Im
+ if (!_Rt_) return;
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k + _Imm_);
+ } else {
+ if (_Imm_ == 0) {
+ MapCopy(_Rt_, _Rs_);
+ } else {
+ ADDI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _Imm_);
+ }
+ }
+}
+
+static void recADDI() {
+// Rt = Rs + Im
+ recADDIU();
+}
+
+//REC_FUNC(SLTI);
+//REC_FUNC(SLTIU);
+//CR0: SIGN | POSITIVE | ZERO | SOVERFLOW | SOVERFLOW | OVERFLOW | CARRY
+static void recSLTI() {
+// Rt = Rs < Im (signed)
+ if (!_Rt_) return;
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_);
+ } else {
+ if (_Imm_ == 0) {
+ SRWI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), 31);
+ } else {
+ int reg;
+ CMPWI(GetHWReg32(_Rs_), _Imm_);
+ reg = PutHWReg32(_Rt_);
+ LI(reg, 1);
+ BLT(1);
+ LI(reg, 0);
+ }
+ }
+}
+
+static void recSLTIU() {
+// Rt = Rs < Im (unsigned)
+ if (!_Rt_) return;
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_);
+ } else {
+ int reg;
+ CMPLWI(GetHWReg32(_Rs_), _Imm_);
+ reg = PutHWReg32(_Rt_);
+ LI(reg, 1);
+ BLT(1);
+ LI(reg, 0);
+ }
+}
+
+static void recANDI() {
+// Rt = Rs And Im
+ if (!_Rt_) return;
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_);
+ } else {
+ ANDI_(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_);
+ }
+}
+
+static void recORI() {
+// Rt = Rs Or Im
+ if (!_Rt_) return;
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_);
+ } else {
+ if (_Imm_ == 0) {
+ MapCopy(_Rt_, _Rs_);
+ } else {
+ ORI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_);
+ }
+ }
+}
+
+static void recXORI() {
+// Rt = Rs Xor Im
+ if (!_Rt_) return;
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_);
+ } else {
+ XORI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_);
+ }
+}
+#endif
+//end of * Arithmetic with immediate operand
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+//REC_FUNC(LUI);
+//#if 0*/
+static void recLUI() {
+// Rt = Imm << 16
+ if (!_Rt_) return;
+
+ MapConst(_Rt_, psxRegs.code << 16);
+}
+//#endif
+//End of Load Higher .....
+
+#pragma mark - Register arithmetic -
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+
+#if 0
+/*REC_FUNC(ADD);
+REC_FUNC(ADDU);
+REC_FUNC(SUB);
+REC_FUNC(SUBU);
+REC_FUNC(AND);
+REC_FUNC(OR);
+REC_FUNC(XOR);
+REC_FUNC(NOR);
+REC_FUNC(SLT);
+REC_FUNC(SLTU);*/
+#else
+static void recADDU() {
+// Rd = Rs + Rt
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) {
+ ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), (s16)iRegs[_Rs_].k);
+ } else if ((iRegs[_Rs_].k & 0xffff) == 0) {
+ ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k>>16);
+ } else {
+ ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) {
+ ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), (s16)iRegs[_Rt_].k);
+ } else if ((iRegs[_Rt_].k & 0xffff) == 0) {
+ ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k>>16);
+ } else {
+ ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else {
+ ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+}
+
+static void recADD() {
+// Rd = Rs + Rt
+ recADDU();
+}
+
+static void recSUBU() {
+// Rd = Rs - Rt
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k);
+ } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((s32)(s16)(-iRegs[_Rt_].k) == (s32)(-iRegs[_Rt_].k)) {
+ ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), -iRegs[_Rt_].k);
+ } else if (((-iRegs[_Rt_].k) & 0xffff) == 0) {
+ ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rs_), (-iRegs[_Rt_].k)>>16);
+ } else {
+ SUB(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else {
+ SUB(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+}
+
+static void recSUB() {
+// Rd = Rs - Rt
+ recSUBU();
+}
+
+static void recAND() {
+// Rd = Rs And Rt
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ // TODO: implement shifted (ANDIS) versions of these
+ if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
+ ANDI_(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
+ ANDI_(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ } else {
+ AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else {
+ AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+}
+
+static void recOR() {
+// Rd = Rs Or Rt
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k);
+ }
+ else {
+ if (_Rs_ == _Rt_) {
+ MapCopy(_Rd_, _Rs_);
+ }
+ else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
+ ORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
+ ORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ } else {
+ OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else {
+ OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+}
+
+static void recXOR() {
+// Rd = Rs Xor Rt
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
+ XORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
+ XORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ } else {
+ XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else {
+ XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+}
+
+static void recNOR() {
+// Rd = Rs Nor Rt
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k));
+ } /*else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
+ NORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
+ NORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ } else {
+ NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ } */else {
+ NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+}
+
+static void recSLT() {
+// Rd = Rs < Rt (signed)
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k);
+ } else { // TODO: add immidiate cases
+ int reg;
+ CMPW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ reg = PutHWReg32(_Rd_);
+ LI(reg, 1);
+ BLT(1);
+ LI(reg, 0);
+ }
+}
+
+static void recSLTU() {
+// Rd = Rs < Rt (unsigned)
+ if (!_Rd_) return;
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k);
+ } else { // TODO: add immidiate cases
+ SUBFC(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
+ SUBFE(PutHWReg32(_Rd_), GetHWReg32(_Rd_), GetHWReg32(_Rd_));
+ NEG(PutHWReg32(_Rd_), GetHWReg32(_Rd_));
+ }
+}
+#endif
+//End of * Register arithmetic
+
+#pragma mark - mult/div & Register trap logic -
+/*********************************************************
+* Register mult/div & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+
+#if 0
+REC_FUNC(MULT);
+REC_FUNC(MULTU);
+REC_FUNC(DIV);
+REC_FUNC(DIVU);
+#else
+
+int DoShift(u32 k)
+{
+ u32 i;
+ for (i=0; i<30; i++) {
+ if (k == (1ul << i))
+ return i;
+ }
+ return -1;
+}
+
+//REC_FUNC(MULT);
+
+// FIXME: doesn't work in GT - wrong way marker
+static void recMULT() {
+// Lo/Hi = Rs * Rt (signed)
+ s32 k; int r;
+ int usehi, uselo;
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ MapConst(REG_LO, 0);
+ MapConst(REG_HI, 0);
+ return;
+ }
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ u64 res = (s64)((s64)(s32)iRegs[_Rs_].k * (s64)(s32)iRegs[_Rt_].k);
+ MapConst(REG_LO, (res & 0xffffffff));
+ MapConst(REG_HI, ((res >> 32) & 0xffffffff));
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ k = (s32)iRegs[_Rs_].k;
+ r = _Rt_;
+ } else if (IsConst(_Rt_)) {
+ k = (s32)iRegs[_Rt_].k;
+ r = _Rs_;
+ } else {
+ r = -1;
+ k = 0;
+ }
+
+ // FIXME: this should not be needed!!!
+// uselo = isPsxRegUsed(pc, REG_LO);
+// usehi = isPsxRegUsed(pc, REG_HI);
+ uselo = 1; //isPsxRegUsed(pc, REG_LO);
+ usehi = 1; //isPsxRegUsed(pc, REG_HI);
+
+
+ if (r != -1) {
+ int shift = DoShift(k);
+ if (shift != -1) {
+ if (uselo) {
+ SLWI(PutHWReg32(REG_LO), GetHWReg32(r), shift)
+ }
+ if (usehi) {
+ SRAWI(PutHWReg32(REG_HI), GetHWReg32(r), 31-shift);
+ }
+ } else {
+ //if ((s32)(s16)k == k) {
+ // MULLWI(PutHWReg32(REG_LO), GetHWReg32(r), k);
+ // MULHWI(PutHWReg32(REG_HI), GetHWReg32(r), k);
+ //} else
+ {
+ if (uselo) {
+ MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ if (usehi) {
+ MULHW(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ }
+ } else {
+ if (uselo) {
+ MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ if (usehi) {
+ MULHW(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+}
+
+static void recMULTU() {
+// Lo/Hi = Rs * Rt (unsigned)
+ u32 k; int r;
+ int usehi, uselo;
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ MapConst(REG_LO, 0);
+ MapConst(REG_HI, 0);
+ return;
+ }
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ u64 res = (u64)((u64)(u32)iRegs[_Rs_].k * (u64)(u32)iRegs[_Rt_].k);
+ MapConst(REG_LO, (res & 0xffffffff));
+ MapConst(REG_HI, ((res >> 32) & 0xffffffff));
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ k = (s32)iRegs[_Rs_].k;
+ r = _Rt_;
+ } else if (IsConst(_Rt_)) {
+ k = (s32)iRegs[_Rt_].k;
+ r = _Rs_;
+ } else {
+ r = -1;
+ k = 0;
+ }
+
+ uselo = isPsxRegUsed(pc, REG_LO);
+ usehi = isPsxRegUsed(pc, REG_HI);
+
+ if (r != -1) {
+ int shift = DoShift(k);
+ if (shift != -1) {
+ if (uselo) {
+ SLWI(PutHWReg32(REG_LO), GetHWReg32(r), shift);
+ }
+ if (usehi) {
+ SRWI(PutHWReg32(REG_HI), GetHWReg32(r), 31-shift);
+ }
+ } else {
+ {
+ if (uselo) {
+ MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ if (usehi) {
+ MULHWU(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ }
+ } else {
+ if (uselo) {
+ MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ if (usehi) {
+ MULHWU(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+}
+
+static void recDIV() {
+// Lo/Hi = Rs / Rt (signed)
+ int usehi;
+
+ if (IsConst(_Rs_) && iRegs[_Rs_].k == 0) {
+ MapConst(REG_LO, 0);
+ MapConst(REG_HI, 0);
+ return;
+ }
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(REG_LO, (s32)iRegs[_Rs_].k / (s32)iRegs[_Rt_].k);
+ MapConst(REG_HI, (s32)iRegs[_Rs_].k % (s32)iRegs[_Rt_].k);
+ return;
+ }
+
+ usehi = isPsxRegUsed(pc, REG_HI);
+
+ if (IsConst(_Rt_)) {
+ int shift = DoShift(iRegs[_Rt_].k);
+ if (shift != -1) {
+ SRAWI(PutHWReg32(REG_LO), GetHWReg32(_Rs_), shift);
+ ADDZE(PutHWReg32(REG_LO), GetHWReg32(REG_LO));
+ if (usehi) {
+ RLWINM(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 0, 31-shift, 31);
+ }
+ } else if (iRegs[_Rt_].k == 3) {
+ // http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html
+ LIS(PutHWReg32(REG_HI), 0x5555);
+ ADDI(PutHWReg32(REG_HI), GetHWReg32(REG_HI), 0x5556);
+ MULHW(PutHWReg32(REG_LO), GetHWReg32(REG_HI), GetHWReg32(_Rs_));
+ SRWI(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 31);
+ ADD(PutHWReg32(REG_LO), GetHWReg32(REG_LO), GetHWReg32(REG_HI));
+ if (usehi) {
+ MULLI(PutHWReg32(REG_HI), GetHWReg32(REG_LO), 3);
+ SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
+ }
+ } else {
+ DIVW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ if (usehi) {
+ if ((iRegs[_Rt_].k & 0x7fff) == iRegs[_Rt_].k) {
+ MULLI(PutHWReg32(REG_HI), GetHWReg32(REG_LO), iRegs[_Rt_].k);
+ } else {
+ MULLW(PutHWReg32(REG_HI), GetHWReg32(REG_LO), GetHWReg32(_Rt_));
+ }
+ SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
+ }
+ }
+ } else {
+ DIVW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ if (usehi) {
+ MULLW(PutHWReg32(REG_HI), GetHWReg32(REG_LO), GetHWReg32(_Rt_));
+ SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
+ }
+ }
+}
+
+static void recDIVU() {
+// Lo/Hi = Rs / Rt (unsigned)
+ int usehi;
+
+ if (IsConst(_Rs_) && iRegs[_Rs_].k == 0) {
+ MapConst(REG_LO, 0);
+ MapConst(REG_HI, 0);
+ return;
+ }
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(REG_LO, (u32)iRegs[_Rs_].k / (u32)iRegs[_Rt_].k);
+ MapConst(REG_HI, (u32)iRegs[_Rs_].k % (u32)iRegs[_Rt_].k);
+ return;
+ }
+
+ usehi = isPsxRegUsed(pc, REG_HI);
+
+ if (IsConst(_Rt_)) {
+ int shift = DoShift(iRegs[_Rt_].k);
+ if (shift != -1) {
+ SRWI(PutHWReg32(REG_LO), GetHWReg32(_Rs_), shift);
+ if (usehi) {
+ RLWINM(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 0, 31-shift, 31);
+ }
+ } else {
+ DIVWU(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ if (usehi) {
+ MULLW(PutHWReg32(REG_HI), GetHWReg32(_Rt_), GetHWReg32(REG_LO));
+ SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
+ }
+ }
+ } else {
+ DIVWU(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ if (usehi) {
+ MULLW(PutHWReg32(REG_HI), GetHWReg32(_Rt_), GetHWReg32(REG_LO));
+ SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI));
+ }
+ }
+}
+#endif
+//End of * Register mult/div & Register trap logic
+
+#pragma mark - memory access -
+
+#if 0
+REC_FUNC(LB);
+REC_FUNC(LBU);
+REC_FUNC(LH);
+REC_FUNC(LHU);
+REC_FUNC(LW);
+
+REC_FUNC(SB);
+REC_FUNC(SH);
+REC_FUNC(SW);
+
+REC_FUNC(LWL);
+REC_FUNC(LWR);
+REC_FUNC(SWL);
+REC_FUNC(SWR);
+#else
+static void preMemRead()
+{
+ int rs;
+
+ ReserveArgs(1);
+ if (_Rs_ != _Rt_) {
+ DisposeHWReg(iRegs[_Rt_].reg);
+ }
+ rs = GetHWReg32(_Rs_);
+ if (rs != 3 || _Imm_ != 0) {
+ ADDI(PutHWRegSpecial(ARG1), rs, _Imm_);
+ }
+ if (_Rs_ == _Rt_) {
+ DisposeHWReg(iRegs[_Rt_].reg);
+ }
+ InvalidateCPURegs();
+ //FlushAllHWReg();
+}
+
+static void preMemWrite(int size)
+{
+ int rs;
+
+ ReserveArgs(2);
+ rs = GetHWReg32(_Rs_);
+ if (rs != 3 || _Imm_ != 0) {
+ ADDI(PutHWRegSpecial(ARG1), rs, _Imm_);
+ }
+ if (size == 1) {
+ RLWINM(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0, 24, 31);
+ //ANDI_(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0xff);
+ } else if (size == 2) {
+ RLWINM(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0, 16, 31);
+ //ANDI_(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0xffff);
+ } else {
+ MR(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_));
+ }
+
+ InvalidateCPURegs();
+ //FlushAllHWReg();
+}
+
+static void recLB() {
+// Rt = mem[Rs + Im] (signed)
+
+ /*if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRs8(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+
+ addr = (u32)&psxM[addr & 0x1fffff];
+ LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
+ LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
+ EXTSB(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+
+ addr = (u32)&psxH[addr & 0xfff];
+ LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
+ LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
+ EXTSB(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
+ return;
+ }
+ // SysPrintf("unhandled r8 %x\n", addr);
+ }*/
+
+ preMemRead();
+ CALLFunc((u32)psxMemRead8);
+ if (_Rt_) {
+ EXTSB(PutHWReg32(_Rt_), GetHWRegSpecial(RETVAL));
+ DisposeHWReg(GetSpecialIndexFromHWRegs(RETVAL));
+ }
+}
+
+static void recLBU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+ /*if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu8(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+
+ addr = (u32)&psxM[addr & 0x1fffff];
+ LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
+ LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+
+ addr = (u32)&psxH[addr & 0xfff];
+ LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct?
+ LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_));
+ return;
+ }
+ // SysPrintf("unhandled r8 %x\n", addr);
+ }*/
+
+ preMemRead();
+ CALLFunc((u32)psxMemRead8);
+
+ if (_Rt_) {
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ }
+}
+
+static void recLH() {
+// Rt = mem[Rs + Im] (signed)
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRs16(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]);
+ LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ EXTSH(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]);
+ LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ EXTSH(PutHWReg32(_Rt_), GetHWReg32(_Rt_));
+ return;
+ }
+ // SysPrintf("unhandled r16 %x\n", addr);
+ }
+
+ preMemRead();
+ CALLFunc((u32)psxMemRead16);
+ if (_Rt_) {
+ EXTSH(PutHWReg32(_Rt_), GetHWRegSpecial(RETVAL));
+ DisposeHWReg(GetSpecialIndexFromHWRegs(RETVAL));
+ }
+}
+
+static void recLHU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu16(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]);
+ LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]);
+ LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (!_Rt_) return;
+
+ ReserveArgs(1);
+ LIW(PutHWRegSpecial(ARG1), addr);
+ DisposeHWReg(iRegs[_Rt_].reg);
+ InvalidateCPURegs();
+ CALLFunc((u32)SPU_readRegister);
+
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ return;
+ }
+ switch (addr) {
+ case 0x1f801100: case 0x1f801110: case 0x1f801120:
+ if (!_Rt_) return;
+
+ ReserveArgs(1);
+ LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3);
+ DisposeHWReg(iRegs[_Rt_].reg);
+ InvalidateCPURegs();
+ CALLFunc((u32)psxRcntRcount);
+
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ return;
+
+ case 0x1f801104: case 0x1f801114: case 0x1f801124:
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxCounters[(addr >> 4) & 0x3].mode);
+ LWZ(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+
+ case 0x1f801108: case 0x1f801118: case 0x1f801128:
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxCounters[(addr >> 4) & 0x3].target);
+ LWZ(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+ }
+ }
+ // SysPrintf("unhandled r16u %x\n", addr);
+ }
+
+ preMemRead();
+ CALLFunc((u32)psxMemRead16);
+ if (_Rt_) {
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ }
+}
+
+static void recLW() {
+// Rt = mem[Rs + Im] (unsigned)
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ if (!_Rt_) return;
+ // since bios is readonly it won't change
+ MapConst(_Rt_, psxRu32(addr));
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]);
+ LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]);
+ LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+ }
+ if (t == 0x1f80) {
+ switch (addr) {
+ case 0x1f801080: case 0x1f801084: case 0x1f801088:
+ case 0x1f801090: case 0x1f801094: case 0x1f801098:
+ case 0x1f8010a0: case 0x1f8010a4: case 0x1f8010a8:
+ case 0x1f8010b0: case 0x1f8010b4: case 0x1f8010b8:
+ case 0x1f8010c0: case 0x1f8010c4: case 0x1f8010c8:
+ case 0x1f8010d0: case 0x1f8010d4: case 0x1f8010d8:
+ case 0x1f8010e0: case 0x1f8010e4: case 0x1f8010e8:
+ case 0x1f801070: case 0x1f801074:
+ case 0x1f8010f0: case 0x1f8010f4:
+ if (!_Rt_) return;
+
+ LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xffff]);
+ LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_));
+ return;
+
+ case 0x1f801810:
+ if (!_Rt_) return;
+
+ DisposeHWReg(iRegs[_Rt_].reg);
+ InvalidateCPURegs();
+ CALLFunc((u32)GPU_readData);
+
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ return;
+
+ case 0x1f801814:
+ if (!_Rt_) return;
+
+ DisposeHWReg(iRegs[_Rt_].reg);
+ InvalidateCPURegs();
+ CALLFunc((u32)GPU_readStatus);
+
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ return;
+ }
+ }
+// SysPrintf("unhandled r32 %x\n", addr);
+ }
+
+ preMemRead();
+ CALLFunc((u32)psxMemRead32);
+ if (_Rt_) {
+ SetDstCPUReg(3);
+ PutHWReg32(_Rt_);
+ }
+}
+
+REC_FUNC(LWL);
+REC_FUNC(LWR);
+REC_FUNC(SWL);
+REC_FUNC(SWR);
+/*extern u32 LWL_MASK[4];
+extern u32 LWL_SHIFT[4];
+
+void iLWLk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32ItoR(ECX, LWL_MASK[shift]);
+ SHL32ItoR(EAX, LWL_SHIFT[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recLWL() {
+// Rt = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iLWLk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iLWLk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+ CALLFunc((u32)psxMemRead32);
+
+ if (_Rt_) {
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)LWL_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ SHL32CLtoR(EAX); // mem(EAX) << LWL_SHIFT[shift]
+
+ MOV32ItoR(ECX, (u32)LWL_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32RtoR(EDX, ECX); // _rRt_ & LWL_MASK[shift]
+
+ OR32RtoR(EAX, EDX);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ } else {
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+ }
+}
+
+static void recLWBlock(int count) {
+ u32 *code = PSXM(pc);
+ int i, respsave;
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs(0);
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0xfff0) == 0xbfc0) {
+ // since bios is readonly it won't change
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (_fRt_(*code)) {
+ MapConst(_fRt_(*code), psxRu32(addr));
+ }
+ }
+ return;
+ }
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (!_fRt_(*code)) return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (!_fRt_(*code)) return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ }
+
+ SysPrintf("recLWBlock %d: %d\n", count, IsConst(_Rs_));
+ iPushOfB();
+ CALLFunc((u32)psxMemPointer);
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+
+ respsave = resp; resp = 0;
+ TEST32RtoR(EAX, EAX);
+ j32Ptr[4] = JZ32(0);
+ XOR32RtoR(ECX, ECX);
+ for (i=0; i<count; i++, code++) {
+ if (_fRt_(*code)) {
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32RmStoR(EDX, EAX, ECX, 2);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EDX);
+ }
+ if (i != (count-1)) INC32R(ECX);
+ }
+ j32Ptr[5] = JMP32(0);
+ x86SetJ32(j32Ptr[4]);
+ for (i=0, code = PSXM(pc); i<count; i++, code++) {
+ psxRegs.code = *code;
+ recLW();
+ }
+ ADD32ItoR(ESP, resp);
+ x86SetJ32(j32Ptr[5]);
+ resp = respsave;
+}
+
+extern u32 LWR_MASK[4];
+extern u32 LWR_SHIFT[4];
+
+void iLWRk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32ItoR(ECX, LWR_MASK[shift]);
+ SHR32ItoR(EAX, LWR_SHIFT[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recLWR() {
+// Rt = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iLWRk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iLWRk(addr & 3);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+ CALLFunc((u32)psxMemRead32);
+
+ if (_Rt_) {
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)LWR_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ SHR32CLtoR(EAX); // mem(EAX) >> LWR_SHIFT[shift]
+
+ MOV32ItoR(ECX, (u32)LWR_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ AND32RtoR(EDX, ECX); // _rRt_ & LWR_MASK[shift]
+
+ OR32RtoR(EAX, EDX);
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ } else {
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+ }
+}*/
+
+static void recSB() {
+// mem[Rs + Im] = Rt
+
+ /*if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV8ItoM((u32)&psxM[addr & 0x1fffff], (u8)iRegs[_Rt_].k);
+ } else {
+ MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV8RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV8ItoM((u32)&psxH[addr & 0xfff], (u8)iRegs[_Rt_].k);
+ } else {
+ MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV8RtoM((u32)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+// SysPrintf("unhandled w8 %x\n", addr);
+ }*/
+
+ preMemWrite(1);
+ CALLFunc((u32)psxMemWrite8);
+}
+
+static void recSH() {
+// mem[Rs + Im] = Rt
+
+ /*if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV16ItoM((u32)&psxM[addr & 0x1fffff], (u16)iRegs[_Rt_].k);
+ } else {
+ MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV16RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV16ItoM((u32)&psxH[addr & 0xfff], (u16)iRegs[_Rt_].k);
+ } else {
+ MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV16RtoM((u32)&psxH[addr & 0xfff], EAX);
+ }
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (IsConst(_Rt_)) {
+ PUSH32I(iRegs[_Rt_].k);
+ } else {
+ PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ PUSH32I (addr);
+ CALL32M ((u32)&SPU_writeRegister);
+#ifndef __WIN32__
+ resp+= 8;
+#endif
+ return;
+ }
+ }
+// SysPrintf("unhandled w16 %x\n", addr);
+ }*/
+
+ preMemWrite(2);
+ CALLFunc((u32)psxMemWrite16);
+}
+
+static void recSW() {
+// mem[Rs + Im] = Rt
+ u32 *b1, *b2;
+#if 0
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ LIW(0, addr & 0x1fffff);
+ STWBRX(GetHWReg32(_Rt_), GetHWRegSpecial(PSXMEM), 0);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ LIW(0, (u32)&psxH[addr & 0xfff]);
+ STWBRX(GetHWReg32(_Rt_), 0, 0);
+ return;
+ }
+ if (t == 0x1f80) {
+ switch (addr) {
+ case 0x1f801080: case 0x1f801084:
+ case 0x1f801090: case 0x1f801094:
+ case 0x1f8010a0: case 0x1f8010a4:
+ case 0x1f8010b0: case 0x1f8010b4:
+ case 0x1f8010c0: case 0x1f8010c4:
+ case 0x1f8010d0: case 0x1f8010d4:
+ case 0x1f8010e0: case 0x1f8010e4:
+ case 0x1f801074:
+ case 0x1f8010f0:
+ LIW(0, (u32)&psxH[addr & 0xffff]);
+ STWBRX(GetHWReg32(_Rt_), 0, 0);
+ return;
+
+/* case 0x1f801810:
+ if (IsConst(_Rt_)) {
+ PUSH32I(iRegs[_Rt_].k);
+ } else {
+ PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ CALL32M((u32)&GPU_writeData);
+#ifndef __WIN32__
+ resp+= 4;
+#endif
+ return;
+
+ case 0x1f801814:
+ if (IsConst(_Rt_)) {
+ PUSH32I(iRegs[_Rt_].k);
+ } else {
+ PUSH32M((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ CALL32M((u32)&GPU_writeStatus);
+#ifndef __WIN32__
+ resp+= 4;
+#endif*/
+ }
+ }
+// SysPrintf("unhandled w32 %x\n", addr);
+ }
+
+/* LIS(0, 0x0079 + ((_Imm_ <= 0) ? 1 : 0));
+ CMPLW(GetHWReg32(_Rs_), 0);
+ BGE_L(b1);
+
+ //SaveContext();
+ ADDI(0, GetHWReg32(_Rs_), _Imm_);
+ RLWINM(0, GetHWReg32(_Rs_), 0, 11, 31);
+ STWBRX(GetHWReg32(_Rt_), GetHWRegSpecial(PSXMEM), 0);
+ B_L(b2);
+
+ B_DST(b1);*/
+#endif
+ preMemWrite(4);
+ CALLFunc((u32)psxMemWrite32);
+
+ //B_DST(b2);
+}
+
+/*
+static void recSWBlock(int count) {
+ u32 *code;
+ int i, respsave;
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+ code = PSXM(pc);
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (IsConst(_fRt_(*code))) {
+ MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_fRt_(*code)].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_fRt_(*code)]);
+ MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+ }
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ for (i=0; i<count; i++, code++, addr+=4) {
+ if (!_fRt_(*code)) return;
+ iRegs[_fRt_(*code)].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX);
+ }
+ return;
+ }
+ }
+
+ SysPrintf("recSWBlock %d: %d\n", count, IsConst(_Rs_));
+ iPushOfB();
+ CALLFunc((u32)psxMemPointer);
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+
+ respsave = resp; resp = 0;
+ TEST32RtoR(EAX, EAX);
+ j32Ptr[4] = JZ32(0);
+ XOR32RtoR(ECX, ECX);
+ for (i=0, code = PSXM(pc); i<count; i++, code++) {
+ if (IsConst(_fRt_(*code))) {
+ MOV32ItoR(EDX, iRegs[_fRt_(*code)].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_fRt_(*code)]);
+ }
+ MOV32RtoRmS(EAX, ECX, 2, EDX);
+ if (i != (count-1)) INC32R(ECX);
+ }
+ j32Ptr[5] = JMP32(0);
+ x86SetJ32(j32Ptr[4]);
+ for (i=0, code = PSXM(pc); i<count; i++, code++) {
+ psxRegs.code = *code;
+ recSW();
+ }
+ ADD32ItoR(ESP, resp);
+ x86SetJ32(j32Ptr[5]);
+ resp = respsave;
+}
+
+extern u32 SWL_MASK[4];
+extern u32 SWL_SHIFT[4];
+
+void iSWLk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHR32ItoR(ECX, SWL_SHIFT[shift]);
+ AND32ItoR(EAX, SWL_MASK[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recSWL() {
+// mem[Rs + Im] = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((u32)&psxH[addr & 0xffc], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemRead32);
+
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)SWL_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ AND32RtoR(EAX, ECX); // mem & SWL_MASK[shift]
+
+ MOV32ItoR(ECX, (u32)SWL_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift]
+
+ OR32RtoR (EAX, EDX);
+ PUSH32R (EAX);
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+extern u32 SWR_MASK[4];
+extern u32 SWR_SHIFT[4];
+
+void iSWRk(u32 shift) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(ECX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHL32ItoR(ECX, SWR_SHIFT[shift]);
+ AND32ItoR(EAX, SWR_MASK[shift]);
+ OR32RtoR (EAX, ECX);
+}
+
+void recSWR() {
+// mem[Rs + Im] = Rt Merge mem[Rs + Im]
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((u32)&psxH[addr & 0xffc], EAX);
+ return;
+ }
+ }
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ PUSH32R (EAX);
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemRead32);
+
+ ADD32ItoR(ESP, 4);
+ POP32R (EDX);
+ AND32ItoR(EDX, 0x3); // shift = addr & 3;
+
+ MOV32ItoR(ECX, (u32)SWR_MASK);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ AND32RtoR(EAX, ECX); // mem & SWR_MASK[shift]
+
+ MOV32ItoR(ECX, (u32)SWR_SHIFT);
+ MOV32RmStoR(ECX, ECX, EDX, 2);
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift]
+
+ OR32RtoR (EAX, EDX);
+ PUSH32R (EAX);
+
+ if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
+ else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_) ADD32ItoR(EAX, _Imm_);
+ }
+ AND32ItoR(EAX, ~3);
+ PUSH32R (EAX);
+
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}*/
+#endif
+
+#if 0
+/*REC_FUNC(SLL);
+REC_FUNC(SRL);
+REC_FUNC(SRA);*/
+#else
+static void recSLL() {
+// Rd = Rt << Sa
+ if (!_Rd_) return;
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << _Sa_);
+ } else {
+ SLWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_);
+ }
+}
+
+static void recSRL() {
+// Rd = Rt >> Sa
+ if (!_Rd_) return;
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_);
+ } else {
+ SRWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_);
+ }
+}
+
+static void recSRA() {
+// Rd = Rt >> Sa
+ if (!_Rd_) return;
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_);
+ } else {
+ SRAWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_);
+ }
+}
+#endif
+
+#pragma mark - shift ops -
+#if 0
+/*REC_FUNC(SLLV);
+REC_FUNC(SRLV);
+REC_FUNC(SRAV);*/
+#else
+static void recSLLV() {
+// Rd = Rt << Rs
+ if (!_Rd_) return;
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ SLWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ SLW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
+ }
+}
+
+static void recSRLV() {
+// Rd = Rt >> Rs
+ if (!_Rd_) return;
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ SRWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ SRW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
+ }
+}
+
+static void recSRAV() {
+// Rd = Rt >> Rs
+ if (!_Rd_) return;
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ SRAWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ } else {
+ SRAW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_));
+ }
+}
+#endif
+
+//REC_SYS(SYSCALL);
+//REC_SYS(BREAK);
+
+//#if 0*/
+/*int dump;*/
+static void recSYSCALL() {
+// dump=1;
+ iFlushRegs(0);
+
+ ReserveArgs(2);
+ LIW(PutHWRegSpecial(PSXPC), pc - 4);
+ LIW(PutHWRegSpecial(ARG1), 0x20);
+ LIW(PutHWRegSpecial(ARG2), (branch == 1 ? 1 : 0));
+ FlushAllHWReg();
+ CALLFunc ((u32)psxException);
+
+ branch = 2;
+ iRet();
+}
+
+static void recBREAK() {
+}
+//#endif
+
+#if 0
+/*REC_FUNC(MFHI);
+REC_FUNC(MTHI);
+REC_FUNC(MFLO);
+REC_FUNC(MTLO);*/
+#else
+static void recMFHI() {
+// Rd = Hi
+ if (!_Rd_) return;
+
+ if (IsConst(REG_HI)) {
+ MapConst(_Rd_, iRegs[REG_HI].k);
+ } else {
+ MapCopy(_Rd_, REG_HI);
+ }
+}
+
+static void recMTHI() {
+// Hi = Rs
+
+ if (IsConst(_Rs_)) {
+ MapConst(REG_HI, iRegs[_Rs_].k);
+ } else {
+ MapCopy(REG_HI, _Rs_);
+ }
+}
+
+static void recMFLO() {
+// Rd = Lo
+ if (!_Rd_) return;
+
+ if (IsConst(REG_LO)) {
+ MapConst(_Rd_, iRegs[REG_LO].k);
+ } else {
+ MapCopy(_Rd_, REG_LO);
+ }
+}
+
+static void recMTLO() {
+// Lo = Rs
+
+ if (IsConst(_Rs_)) {
+ MapConst(REG_LO, iRegs[_Rs_].k);
+ } else {
+ MapCopy(REG_LO, _Rs_);
+ }
+}
+#endif
+
+#pragma mark - branch ops -
+#if 0
+/*REC_BRANCH(J);
+REC_BRANCH(JR);
+REC_BRANCH(JAL);
+REC_BRANCH(JALR);
+REC_BRANCH(BLTZ);
+REC_BRANCH(BGTZ);
+REC_BRANCH(BLTZAL);
+REC_BRANCH(BGEZAL);
+REC_BRANCH(BNE);
+REC_BRANCH(BEQ);
+REC_BRANCH(BLEZ);
+REC_BRANCH(BGEZ);*/
+#else
+static void recBLTZ() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMPWI(GetHWReg32(_Rs_), 0);
+ BLT_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBGTZ() {
+// Branch if Rs > 0
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k > 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMPWI(GetHWReg32(_Rs_), 0);
+ BGT_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBLTZAL() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ MapConst(31, pc + 4);
+
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMPWI(GetHWReg32(_Rs_), 0);
+ BLT_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ MapConst(31, pc + 4);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBGEZAL() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ MapConst(31, pc + 4);
+
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMPWI(GetHWReg32(_Rs_), 0);
+ BGE_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ MapConst(31, pc + 4);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recJ() {
+// j target
+
+ iJump(_Target_ * 4 + (pc & 0xf0000000));
+}
+
+static void recJAL() {
+// jal target
+ MapConst(31, pc + 4);
+
+ iJump(_Target_ * 4 + (pc & 0xf0000000));
+}
+
+static void recJR() {
+// jr Rs
+
+ if (IsConst(_Rs_)) {
+ iJump(iRegs[_Rs_].k);
+ //LIW(PutHWRegSpecial(TARGET), iRegs[_Rs_].k);
+ } else {
+ MR(PutHWRegSpecial(TARGET), GetHWReg32(_Rs_));
+ SetBranch();
+ }
+}
+
+static void recJALR() {
+// jalr Rs
+
+ if (_Rd_) {
+ MapConst(_Rd_, pc + 4);
+ }
+
+ if (IsConst(_Rs_)) {
+ iJump(iRegs[_Rs_].k);
+ //LIW(PutHWRegSpecial(TARGET), iRegs[_Rs_].k);
+ } else {
+ MR(PutHWRegSpecial(TARGET), GetHWReg32(_Rs_));
+ SetBranch();
+ }
+}
+
+static void recBEQ() {
+// Branch if Rs == Rt
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (_Rs_ == _Rt_) {
+ iJump(bpc);
+ }
+ else {
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k == iRegs[_Rt_].k) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+ else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
+ CMPLWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ }
+ else if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) {
+ CMPWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ }
+ else {
+ CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
+ CMPLWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ }
+ else if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) {
+ CMPWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ }
+ else {
+ CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ else {
+ CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+
+ BEQ_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ iBranch(bpc, 0);
+ pc+=4;
+ }
+}
+
+static void recBNE() {
+// Branch if Rs != Rt
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (_Rs_ == _Rt_) {
+ iJump(pc+4);
+ }
+ else {
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k != iRegs[_Rt_].k) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+ else if (IsConst(_Rs_) && !IsMapped(_Rs_)) {
+ if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) {
+ CMPLWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ }
+ else if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) {
+ CMPWI(GetHWReg32(_Rt_), iRegs[_Rs_].k);
+ }
+ else {
+ CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ else if (IsConst(_Rt_) && !IsMapped(_Rt_)) {
+ if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) {
+ CMPLWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ }
+ else if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) {
+ CMPWI(GetHWReg32(_Rs_), iRegs[_Rt_].k);
+ }
+ else {
+ CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+ }
+ else {
+ CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_));
+ }
+
+ BNE_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ iBranch(bpc, 0);
+ pc+=4;
+ }
+}
+
+static void recBLEZ() {
+// Branch if Rs <= 0
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k <= 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMPWI(GetHWReg32(_Rs_), 0);
+ BLE_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBGEZ() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+ u32 *b;
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMPWI(GetHWReg32(_Rs_), 0);
+ BGE_L(b);
+
+ iBranch(pc+4, 1);
+
+ B_DST(b);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+#endif
+
+#if 1
+//REC_FUNC(MFC0);
+//REC_SYS(MTC0);
+//REC_FUNC(CFC0);
+//REC_SYS(CTC0);
+REC_FUNC(RFE);
+//#else
+static void recMFC0() {
+// Rt = Cop0->Rd
+ if (!_Rt_) return;
+
+ LWZ(PutHWReg32(_Rt_), OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS));
+}
+
+static void recCFC0() {
+// Rt = Cop0->Rd
+
+ recMFC0();
+}
+
+static void recMTC0() {
+// Cop0->Rd = Rt
+
+ /*if (IsConst(_Rt_)) {
+ switch (_Rd_) {
+ case 12:
+ MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
+ break;
+ case 13:
+ MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k & ~(0xfc00));
+ break;
+ default:
+ MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k);
+ break;
+ }
+ } else*/ {
+ switch (_Rd_) {
+ case 13:
+ RLWINM(0,GetHWReg32(_Rt_),0,22,15); // & ~(0xfc00)
+ STW(0, OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS));
+ break;
+ default:
+ STW(GetHWReg32(_Rt_), OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS));
+ break;
+ }
+ }
+
+ if (_Rd_ == 12 || _Rd_ == 13) {
+ iFlushRegs(0);
+ LIW(PutHWRegSpecial(PSXPC), (u32)pc);
+ FlushAllHWReg();
+ CALLFunc((u32)psxTestSWInts);
+ if(_Rd_ == 12) {
+ LWZ(0, OFFSET(&psxRegs, &psxRegs.interrupt), GetHWRegSpecial(PSXREGS));
+ ORIS(0, 0, 0x8000);
+ STW(0, OFFSET(&psxRegs, &psxRegs.interrupt), GetHWRegSpecial(PSXREGS));
+ }
+ branch = 2;
+ iRet();
+ }
+}
+
+static void recCTC0() {
+// Cop0->Rd = Rt
+
+ recMTC0();
+}
+#else
+static void recRFE() {
+ // TODO: implement multiple temp registers or cop0 registers
+ RLWINM(t1,Status,0,0,27);
+ RLWINM(Status,Status,30,28,31);
+ OR(Status,t1,Status);
+
+ MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
+ MOV32RtoR(ECX, EAX);
+ AND32ItoR(EAX, 0xfffffff0);
+ AND32ItoR(ECX, 0x3c);
+ SHR32ItoR(ECX, 2);
+ OR32RtoR (EAX, ECX);
+ MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX);
+ CALLFunc((u32)psxExceptionTest);
+}
+#endif
+
+#if 0
+#define CP2_FUNC(f) \
+void gte##f(); \
+static void rec##f() { \
+ iFlushRegs(0); \
+ LIW(0, (u32)psxRegs.code); \
+ STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \
+ FlushAllHWReg(); \
+ CALLFunc ((u32)gte##f); \
+}
+CP2_FUNC(LWC2);
+CP2_FUNC(SWC2);
+
+#else
+#include "pGte.h"
+#endif
+//
+
+static void recHLE() {
+ iFlushRegs(0);
+ FlushAllHWReg();
+
+ if ((psxRegs.code & 0x3ffffff) == (psxRegs.code & 0x7)) {
+ CALLFunc((u32)psxHLEt[psxRegs.code & 0x7]);
+ } else {
+ // somebody else must have written to current opcode for this to happen!!!!
+ CALLFunc((u32)psxHLEt[0]); // call dummy function
+ }
+
+ count = idlecyclecount + (pc - pcold)/4 + 20;
+ ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count);
+ FlushAllHWReg();
+ CALLFunc((u32)psxBranchTest);
+ Return();
+
+ branch = 2;
+}
+
+//
+
+static void (*recBSC[64])() = {
+ recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
+ recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
+ recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL,
+ recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL,
+ recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recSPC[64])() = {
+ recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV,
+ recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL,
+ recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL,
+ recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL,
+ recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR ,
+ recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL
+};
+
+static void (*recREG[32])() = {
+ recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recCP0[32])() = {
+ recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void (*recCP2[64])() = {
+ recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00
+ recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08
+ recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10
+ recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18
+ recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20
+ recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28
+ recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30
+ recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38
+};
+
+static void (*recCP2BSC[32])() = {
+ recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
+ recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
+};
+
+static void recRecompile() {
+ //static int recCount = 0;
+ char *p;
+ u32 *ptr;
+ int i;
+
+ cop2readypc = 0;
+ idlecyclecount = 0;
+
+ // initialize state variables
+ UniqueRegAlloc = 1;
+ HWRegUseCount = 0;
+ DstCPUReg = -1;
+ memset(HWRegisters, 0, sizeof(HWRegisters));
+ for (i=0; i<NUM_HW_REGISTERS; i++)
+ HWRegisters[i].code = cpuHWRegisters[NUM_HW_REGISTERS-i-1];
+
+ // reserve the special psxReg register
+ HWRegisters[0].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED;
+ HWRegisters[0].private = PSXREGS;
+ HWRegisters[0].k = (u32)&psxRegs;
+
+ HWRegisters[1].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED;
+ HWRegisters[1].private = PSXMEM;
+ HWRegisters[1].k = (u32)&psxM;
+
+ // reserve the special psxRegs.cycle register
+ //HWRegisters[1].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED;
+ //HWRegisters[1].private = CYCLECOUNT;
+
+ //memset(iRegs, 0, sizeof(iRegs));
+ for (i=0; i<NUM_REGISTERS; i++) {
+ iRegs[i].state = ST_UNK;
+ iRegs[i].reg = -1;
+ }
+ iRegs[0].k = 0;
+ iRegs[0].state = ST_CONST;
+
+ /* if ppcPtr reached the mem limit reset whole mem */
+ if (((u32)ppcPtr - (u32)recMem) >= (RECMEM_SIZE - 0x10000))
+ recReset();
+
+ ppcAlign(/*32*/4);
+ ptr = ppcPtr;
+
+ // give us write access
+ //mprotect(recMem, RECMEM_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE);
+
+ // tell the LUT where to find us
+ PC_REC32(psxRegs.pc) = (u32)ppcPtr;
+
+ pcold = pc = psxRegs.pc;
+
+ //SysPrintf("RecCount: %i\n", recCount++);
+
+ for (count=0; count<500;) {
+ p = (char *)PSXM(pc);
+ if (p == NULL) recError();
+ psxRegs.code = SWAP32(*(u32 *)p);
+/*
+ if ((psxRegs.code >> 26) == 0x23) { // LW
+ int i;
+ u32 code;
+
+ for (i=1;; i++) {
+ p = (char *)PSXM(pc+i*4);
+ if (p == NULL) recError();
+ code = *(u32 *)p;
+
+ if ((code >> 26) != 0x23 ||
+ _fRs_(code) != _Rs_ ||
+ _fImm_(code) != (_Imm_+i*4))
+ break;
+ }
+ if (i > 1) {
+ recLWBlock(i);
+ pc = pc + i*4; continue;
+ }
+ }
+
+ if ((psxRegs.code >> 26) == 0x2b) { // SW
+ int i;
+ u32 code;
+
+ for (i=1;; i++) {
+ p = (char *)PSXM(pc+i*4);
+ if (p == NULL) recError();
+ code = *(u32 *)p;
+
+ if ((code >> 26) != 0x2b ||
+ _fRs_(code) != _Rs_ ||
+ _fImm_(code) != (_Imm_+i*4))
+ break;
+ }
+ if (i > 1) {
+ recSWBlock(i);
+ pc = pc + i*4; continue;
+ }
+ }*/
+
+ pc+=4; count++;
+// iFlushRegs(0); // test
+ recBSC[psxRegs.code>>26]();
+
+ if (branch) {
+ branch = 0;
+ //if (dump) iDumpBlock(ptr);
+ goto done;
+ }
+ }
+
+ iFlushRegs(pc);
+
+ LIW(PutHWRegSpecial(PSXPC), pc);
+
+ iRet();
+
+done:;
+#if 0
+ MakeDataExecutable(ptr, ((u8*)ppcPtr)-((u8*)ptr));
+#else
+ u32 a = (u32)(u8*)ptr;
+ while(a < (u32)(u8*)ppcPtr) {
+ __asm__ __volatile__("icbi 0,%0" : : "r" (a));
+ __asm__ __volatile__("dcbst 0,%0" : : "r" (a));
+ a += 4;
+ }
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+#endif
+
+#if 1
+ sprintf((char *)ppcPtr, "PC=%08x", pcold);
+ ppcPtr += strlen((char *)ppcPtr);
+#endif
+
+ //mprotect(recMem, RECMEM_SIZE, PROT_EXEC|PROT_READ/*|PROT_WRITE*/);
+}
+
+
+R3000Acpu psxRec = {
+ recInit,
+ recReset,
+ recExecute,
+ recExecuteBlock,
+ recClear,
+ recShutdown
+};
+
diff --git a/libpcsxcore/ppc/pasm.s b/libpcsxcore/ppc/pasm.s
new file mode 100644
index 00000000..96891b42
--- /dev/null
+++ b/libpcsxcore/ppc/pasm.s
@@ -0,0 +1,124 @@
+
+
+#define OLD_REGISTER_OFFSET (19*4)
+#define SP_SIZE (OLD_REGISTER_OFFSET+4+8)
+
+/*asm void recRun(register void (*func)(), register u32 hw1, register u32 hw2)*/
+ .text
+ .align 4
+ .globl recRun
+recRun:
+ /* prologue code */
+ mflr r0
+ stmw r13, -(32-13)*4(r1)
+ stw r0, 4(r1)
+ stwu r1, -((32-13)*4+8)(r1)
+
+ /* execute code */
+ mtctr r3
+ mr r31, r4
+ mr r30, r5
+ bctrl
+/*
+}
+asm void returnPC()
+{*/
+ .text
+ .align 4
+ .globl returnPC
+returnPC:
+ // end code
+ lwz r0, (32-13)*4+8+4(r1)
+ addi r1, r1, (32-13)*4+8
+ mtlr r0
+ lmw r13, -(32-13)*4(r1)
+ blr
+//}*/
+
+// Memory functions that only works with a linear memory
+
+ .text
+ .align 4
+ .globl dynMemRead8
+dynMemRead8:
+// assumes that memory pointer is in r30
+ addis r2,r3,-0x1f80
+ srwi. r4,r2,16
+ bne+ .norm8
+ cmplwi r2,0x1000
+ blt- .norm8
+ b psxHwRead8
+.norm8:
+ clrlwi r5,r3,3
+ lbzx r3,r5,r30
+ blr
+
+ .text
+ .align 4
+ .globl dynMemRead16
+dynMemRead16:
+// assumes that memory pointer is in r30
+ addis r2,r3,-0x1f80
+ srwi. r4,r2,16
+ bne+ .norm16
+ cmplwi r2,0x1000
+ blt- .norm16
+ b psxHwRead16
+.norm16:
+ clrlwi r5,r3,3
+ lhbrx r3,r5,r30
+ blr
+
+ .text
+ .align 4
+ .globl dynMemRead32
+dynMemRead32:
+// assumes that memory pointer is in r30
+ addis r2,r3,-0x1f80
+ srwi. r4,r2,16
+ bne+ .norm32
+ cmplwi r2,0x1000
+ blt- .norm32
+ b psxHwRead32
+.norm32:
+ clrlwi r5,r3,3
+ lwbrx r3,r5,r30
+ blr
+
+/*
+ N P Z
+ 0 0 0 X
+- 0 0 1 X
+ 1 0 0 X
+ 1 0 1 X
+
+P | (!N & Z)
+P | !(N | !Z)
+*/
+
+ .text
+ .align 4
+ .globl dynMemWrite32
+dynMemWrite32:
+// assumes that memory pointer is in r30
+ addis r2,r3,-0x1f80
+ srwi. r5,r2,16
+ bne+ .normw32
+ cmplwi r2,0x1000
+ blt .normw32
+ b psxHwWrite32
+.normw32:
+ mtcrf 0xFF, r3
+ clrlwi r5,r3,3
+ crandc 0, 2, 0
+ cror 2, 1, 0
+ bne+ .okw32
+ // write test
+ li r2,0x0130
+ addis r2,r2,0xfffe
+ cmplw r3,r2
+ bnelr
+.okw32:
+ stwbrx r4,r5,r30
+ blr
+
diff --git a/libpcsxcore/ppc/ppc.c b/libpcsxcore/ppc/ppc.c
new file mode 100644
index 00000000..efaf8b6d
--- /dev/null
+++ b/libpcsxcore/ppc/ppc.c
@@ -0,0 +1,32 @@
+/*
+ * ix86 core v0.5.1
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ppc.h"
+
+// General Purpose hardware registers
+int cpuHWRegisters[NUM_HW_REGISTERS] = {
+ 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
+};
+
+u32 *ppcPtr;
+
+void ppcInit() {
+}
+void ppcSetPtr(u32 *ptr) {
+ ppcPtr = ptr;
+}
+void ppcAlign(int bytes) {
+ // forward align
+ ppcPtr = (u32*)(((u32)ppcPtr + bytes) & ~(bytes - 1));
+}
+
+void ppcShutdown() {
+}
+
diff --git a/libpcsxcore/ppc/ppc.h b/libpcsxcore/ppc/ppc.h
new file mode 100644
index 00000000..8385da5b
--- /dev/null
+++ b/libpcsxcore/ppc/ppc.h
@@ -0,0 +1,74 @@
+/*
+ * ppc definitions v0.5.1
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ */
+
+#ifndef __PPC_H__
+#define __PPC_H__
+
+// include basic types
+#include "../psxcommon.h"
+#include "ppc_mnemonics.h"
+
+#define NUM_HW_REGISTERS 29
+
+/* general defines */
+#define write8(val) *(u8 *)ppcPtr = val; ppcPtr++;
+#define write16(val) *(u16*)ppcPtr = val; ppcPtr+=2;
+#define write32(val) *(u32*)ppcPtr = val; ppcPtr+=4;
+#define write64(val) *(u64*)ppcPtr = val; ppcPtr+=8;
+
+#define CALLFunc(FUNC) \
+{ \
+ u32 _func = (FUNC); \
+ ReleaseArgs(); \
+ if ((_func & 0x1fffffc) == _func) { \
+ BLA(_func); \
+ } else { \
+ LIW(0, _func); \
+ MTCTR(0); \
+ BCTRL(); \
+ } \
+}
+
+extern int cpuHWRegisters[NUM_HW_REGISTERS];
+
+extern u32 *ppcPtr;
+extern u8 *j8Ptr[32];
+extern u32 *j32Ptr[32];
+
+void ppcInit();
+void ppcSetPtr(u32 *ptr);
+void ppcShutdown();
+
+void ppcAlign(int bytes);
+void returnPC();
+void recRun(void (*func)(), u32 hw1, u32 hw2);
+u8 dynMemRead8(u32 mem);
+u16 dynMemRead16(u32 mem);
+u32 dynMemRead32(u32 mem);
+void dynMemWrite32(u32 mem, u32 val);
+
+#endif /* __PPC_H__ */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libpcsxcore/ppc/ppc_mnemonics.h b/libpcsxcore/ppc/ppc_mnemonics.h
new file mode 100644
index 00000000..3cc65258
--- /dev/null
+++ b/libpcsxcore/ppc/ppc_mnemonics.h
@@ -0,0 +1,529 @@
+// ppc_mnemonics.h
+
+#define INSTR (*(ppcPtr)++)
+
+/* Link register related */
+#define MFLR(REG) \
+ {int _reg = (REG); \
+ INSTR = (0x7C0802A6 | (_reg << 21));}
+
+#define MTLR(REG) \
+ {int _reg = (REG); \
+ INSTR = (0x7C0803A6 | (_reg << 21));}
+
+#define MTCTR(REG) \
+ {int _reg = (REG); \
+ INSTR = (0x7C0903A6 | (_reg << 21));}
+
+#define BLR() \
+ {INSTR = (0x4E800020);}
+
+#define BGTLR() \
+ {INSTR = (0x4D810020);}
+
+
+/* Load ops */
+#define LI(REG, IMM) \
+ {int _reg = (REG); \
+ INSTR = (0x38000000 | (_reg << 21) | ((IMM) & 0xffff));}
+
+#define LIS(REG_DST, IMM) \
+ {int _dst = (REG_DST); \
+ INSTR = (0x3C000000 | (_dst << 21) | ((IMM) & 0xffff));}
+
+#define LWZ(REG_DST, OFFSET, REG) \
+ {int _reg = (REG); int _dst=(REG_DST); \
+ INSTR = (0x80000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define LWZX(REG_DST, REG, REG_OFF) \
+ {int _reg = (REG), _off = (REG_OFF); int _dst=(REG_DST); \
+ INSTR = (0x7C00002E | (_dst << 21) | (_reg << 16) | (_off << 11));}
+
+#define LWBRX(REG_DST, REG, REG_OFF) \
+ {int _reg = (REG), _off = (REG_OFF); int _dst=(REG_DST); \
+ INSTR = (0x7C00042C | (_dst << 21) | (_reg << 16) | (_off << 11));}
+
+#define LHZ(REG_DST, OFFSET, REG) \
+ {int _reg = (REG); int _dst=(REG_DST); \
+ INSTR = (0xA0000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define LHA(REG_DST, OFFSET, REG) \
+ {int _reg = (REG); int _dst=(REG_DST); \
+ INSTR = (0xA8000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define LHBRX(REG_DST, REG, REG_OFF) \
+ {int _reg = (REG), _off = (REG_OFF); int _dst=(REG_DST); \
+ INSTR = (0x7C00062C | (_dst << 21) | (_reg << 16) | (_off << 11));}
+
+#define LBZ(REG_DST, OFFSET, REG) \
+ {int _reg = (REG); int _dst=(REG_DST); \
+ INSTR = (0x88000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define LMW(REG_DST, OFFSET, REG) \
+ {int _reg = (REG); int _dst=(REG_DST); \
+ INSTR = (0xB8000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+
+
+/* Store ops */
+#define STMW(REG_SRC, OFFSET, REG) \
+ {int _reg = (REG), _src=(REG_SRC); \
+ INSTR = (0xBC000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define STW(REG_SRC, OFFSET, REG) \
+ {int _reg = (REG), _src=(REG_SRC); \
+ INSTR = (0x90000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define STWBRX(REG_SRC, REG, REG_OFF) \
+ {int _reg = (REG), _src=(REG_SRC), _off = (REG_OFF); \
+ INSTR = (0x7C00052C | (_src << 21) | (_reg << 16) | (_off << 11));}
+
+#define STH(REG_SRC, OFFSET, REG) \
+ {int _reg = (REG), _src=(REG_SRC); \
+ INSTR = (0xB0000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define STHBRX(REG_SRC, REG, REG_OFF) \
+ {int _reg = (REG), _src=(REG_SRC), _off = (REG_OFF); \
+ INSTR = (0x7C00072C | (_src << 21) | (_reg << 16) | (_off << 11));}
+
+#define STB(REG_SRC, OFFSET, REG) \
+ {int _reg = (REG), _src=(REG_SRC); \
+ INSTR = (0x98000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+#define STWU(REG_SRC, OFFSET, REG) \
+ {int _reg = (REG), _src=(REG_SRC); \
+ INSTR = (0x94000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));}
+
+
+/* Arithmic ops */
+#define ADDI(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x38000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));}
+
+#define ADDIS(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x3C000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));}
+
+#define MR(REG_DST, REG_SRC) \
+ {int __src = (REG_SRC); int __dst=(REG_DST); \
+ if (__src != __dst) {ADDI(__dst, __src, 0)}}
+
+#define ADD(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000214 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define ADDO(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000614 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define ADDEO(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000514 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define ADDE(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000114 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define ADDCO(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000414 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define ADDIC(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x30000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));}
+
+#define ADDIC_(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x34000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));}
+
+#define ADDZE(REG_DST, REG_SRC) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x7C000194 | (_dst << 21) | (_src << 16));}
+
+#define SUBF(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000050 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define SUBFO(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000450 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define SUBFC(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000010 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define SUBFE(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000110 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define SUBFCO(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000410 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define SUBFCO_(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000411 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define SUB(REG_DST, REG1, REG2) \
+ {SUBF(REG_DST, REG2, REG1)}
+
+#define SUBO(REG_DST, REG1, REG2) \
+ {SUBFO(REG_DST, REG2, REG1)}
+
+#define SUBCO(REG_DST, REG1, REG2) \
+ {SUBFCO(REG_DST, REG2, REG1)}
+
+#define SUBCO_(REG_DST, REG1, REG2) \
+ {SUBFCO_(REG_DST, REG2, REG1)}
+
+#define SRAWI(REG_DST, REG_SRC, SHIFT) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x7C000670 | (_src << 21) | (_dst << 16) | (SHIFT << 11));}
+
+#define MULHW(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000096 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define MULLW(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C0001D6 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define MULHWU(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000016 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define MULLI(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x1C000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));}
+
+#define DIVW(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C0003D6 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+#define DIVWU(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000396 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));}
+
+
+/* Branch ops */
+#define B_FROM(VAR) VAR = ppcPtr
+#define B_DST(VAR) *VAR = *VAR | (((s16)((u32)ppcPtr - (u32)VAR)) & 0xfffc)
+
+#define B(DST) \
+ {INSTR = (0x48000000 | (((s32)(((DST)+1)<<2)) & 0x3fffffc));}
+
+#define B_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x48000000);}
+
+#define BA(DST) \
+ {INSTR = (0x48000002 | ((s32)((DST) & 0x3fffffc)));}
+
+#define BLA(DST) \
+ {INSTR = (0x48000003 | ((s32)((DST) & 0x3fffffc)));}
+
+#define BNS(DST) \
+ {INSTR = (0x40830000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BNE(DST) \
+ {INSTR = (0x40820000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BNE_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x40820000);}
+
+#define BEQ(DST) \
+ {INSTR = (0x41820000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BEQ_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x41820000);}
+
+#define BLT(DST) \
+ {INSTR = (0x41800000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BLT_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x41800000);}
+
+#define BGT(DST) \
+ {INSTR = (0x41810000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BGT_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x41810000);}
+
+#define BGE(DST) \
+ {INSTR = (0x40800000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BGE_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x40800000);}
+
+#define BLE(DST) \
+ {INSTR = (0x40810000 | (((s16)(((DST)+1)<<2)) & 0xfffc));}
+
+#define BLE_L(VAR) \
+ {B_FROM(VAR); INSTR = (0x40810000);}
+
+#define BCTRL() \
+ {INSTR = (0x4E800421);}
+
+#define BCTR() \
+ {INSTR = (0x4E800420);}
+
+
+/* compare ops */
+#define CMPLWI(REG, IMM) \
+ {int _reg = (REG); \
+ INSTR = (0x28000000 | (_reg << 16) | ((IMM) & 0xffff));}
+
+#define CMPLWI2(REG, IMM) \
+ {int _reg = (REG); \
+ INSTR = (0x29000000 | (_reg << 16) | ((IMM) & 0xffff));}
+
+#define CMPLWI7(REG, IMM) \
+ {int _reg = (REG); \
+ INSTR = (0x2B800000 | (_reg << 16) | ((IMM) & 0xffff));}
+
+#define CMPLW(REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); \
+ INSTR = (0x7C000040 | (_reg1 << 16) | (_reg2 << 11));}
+
+#define CMPLW1(REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); \
+ INSTR = (0x7C800040 | (_reg1 << 16) | (_reg2 << 11));}
+
+#define CMPLW2(REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); \
+ INSTR = (0x7D000040 | (_reg1 << 16) | (_reg2 << 11));}
+
+#define CMPW(REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); \
+ INSTR = (0x7C000000 | (_reg1 << 16) | (_reg2 << 11));}
+
+#define CMPW1(REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); \
+ INSTR = (0x7C800000 | (_reg1 << 16) | (_reg2 << 11));}
+
+#define CMPW2(REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); \
+ INSTR = (0x7D000000 | (_reg1 << 16) | (_reg2 << 11));}
+
+#define CMPWI(REG, IMM) \
+ {int _reg = (REG); \
+ INSTR = (0x2C000000 | (_reg << 16) | ((IMM) & 0xffff));}
+
+#define CMPWI2(REG, IMM) \
+ {int _reg = (REG); \
+ INSTR = (0x2D000000 | (_reg << 16) | ((IMM) & 0xffff));}
+
+#define MTCRF(MASK, REG) \
+ {int _reg = (REG); \
+ INSTR = (0x7C000120 | (_reg << 21) | (((MASK)&0xff)<<12));}
+
+#define MFCR(REG) \
+ {int _reg = (REG); \
+ INSTR = (0x7C000026 | (_reg << 21));}
+
+#define CROR(CR_DST, CR1, CR2) \
+ {INSTR = (0x4C000382 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));}
+
+#define CRXOR(CR_DST, CR1, CR2) \
+ {INSTR = (0x4C000182 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));}
+
+#define CRNAND(CR_DST, CR1, CR2) \
+ {INSTR = (0x4C0001C2 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));}
+
+#define CRANDC(CR_DST, CR1, CR2) \
+ {INSTR = (0x4C000102 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));}
+
+
+/* shift ops */
+#define RLWINM(REG_DST, REG_SRC, SHIFT, START, END) \
+ {int _src = (REG_SRC); int _dst = (REG_DST); \
+ INSTR = (0x54000000 | (_src << 21) | (_dst << 16) | (SHIFT << 11) | (START << 6) | (END << 1));}
+
+#define RLWINM_(REG_DST, REG_SRC, SHIFT, START, END) \
+ {int _src = (REG_SRC); int _dst = (REG_DST); \
+ INSTR = (0x54000001 | (_src << 21) | (_dst << 16) | (SHIFT << 11) | (START << 6) | (END << 1));}
+
+#define CLRRWI(REG_DST, REG_SRC, LEN) \
+ RLWINM(REG_DST, REG_SRC, 0, 0, 31-LEN)
+
+#define SLWI(REG_DST, REG_SRC, SHIFT) \
+ {int _shift = (SHIFT); \
+ if (_shift==0) {MR(REG_DST, REG_SRC)} else \
+ {RLWINM(REG_DST, REG_SRC, _shift, 0, 31-_shift)}}
+
+#define SRWI(REG_DST, REG_SRC, SHIFT) \
+ {int _shift = (SHIFT); \
+ if (_shift==0) {MR(REG_DST, REG_SRC)} else \
+ RLWINM(REG_DST, REG_SRC, 32-_shift, _shift, 31)}
+
+#define SLW(REG_DST, REG_SRC, REG_SHIFT) \
+ {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \
+ INSTR = (0x7C000030 | (_src << 21) | (_dst << 16) | (_shift << 11));}
+
+#define SRW(REG_DST, REG_SRC, REG_SHIFT) \
+ {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \
+ INSTR = (0x7C000430 | (_src << 21) | (_dst << 16) | (_shift << 11));}
+
+#define SRAW(REG_DST, REG_SRC, REG_SHIFT) \
+ {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \
+ INSTR = (0x7C000630 | (_src << 21) | (_dst << 16) | (_shift << 11));}
+
+#define SRAWI(REG_DST, REG_SRC, SHIFT) \
+ {int _src = (REG_SRC); int _dst = (REG_DST); int _shift = (SHIFT); \
+ if (_shift==0) {MR(REG_DST, REG_SRC)} else \
+ INSTR = (0x7C000670 | (_src << 21) | (_dst << 16) | (_shift << 11));}
+
+#define RLWNM(REG_DST, REG_SRC, REG_SHIFT, START, END) \
+ {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \
+ INSTR = (0x5C000000 | (_src << 21) | (_dst << 16) | (_shift << 11) | (START << 6) | (END << 1));}
+
+/* other ops */
+#define ORI(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC), _imm = (IMM); int _dst = (REG_DST); \
+ if (!((_imm == 0) && ((_src^_dst) == 0))) \
+ INSTR = (0x60000000 | (_src << 21) | (_dst << 16) | (_imm & 0xffff));}
+
+#define ORIS(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC), _imm = (IMM); int _dst = (REG_DST); \
+ if (!((_imm == 0) && ((_src^_dst) == 0))) \
+ INSTR = (0x64000000 | (_src << 21) | (_dst << 16) | (_imm & 0xffff));}
+
+#define OR(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000378 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));}
+
+#define OR_(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000379 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));}
+
+#define XORI(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x68000000 | (_src << 21) | (_dst << 16) | ((IMM) & 0xffff));}
+
+#define XOR(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000278 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));}
+
+#define XOR_(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000279 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));}
+
+#define ANDI_(REG_DST, REG_SRC, IMM) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x70000000 | (_src << 21) | (_dst << 16) | ((IMM) & 0xffff));}
+
+#define AND(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C000038 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));}
+
+#define NOR(REG_DST, REG1, REG2) \
+ {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \
+ INSTR = (0x7C0000f8 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));}
+
+#define NEG(REG_DST, REG_SRC) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x7C0000D0 | (_dst << 21) | (_src << 16));}
+
+#define NOP() \
+ {INSTR = 0x60000000;}
+
+#define MCRXR(CR_DST) \
+ {INSTR = (0x7C000400 | (CR_DST << 23));}
+
+#define EXTSB(REG_DST, REG_SRC) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x7C000774 | (_src << 21) | (_dst << 16));}
+
+#define EXTSH(REG_DST, REG_SRC) \
+ {int _src = (REG_SRC); int _dst=(REG_DST); \
+ INSTR = (0x7C000734 | (_src << 21) | (_dst << 16));}
+
+
+/* floating point ops */
+#define FDIVS(FPR_DST, FPR1, FPR2) \
+ {INSTR = (0xEC000024 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));}
+
+#define FDIV(FPR_DST, FPR1, FPR2) \
+ {INSTR = (0xFC000024 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));}
+
+#define FMULS(FPR_DST, FPR1, FPR2) \
+ {INSTR = (0xEC000032 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));}
+
+#define FMUL(FPR_DST, FPR1, FPR2) \
+ {INSTR = (0xFC000032 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));}
+
+#define FADDS(FPR_DST, FPR1, FPR2) \
+ {INSTR = (0xEC00002A | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));}
+
+#define FADD(FPR_DST, FPR1, FPR2) \
+ {INSTR = (0xFC00002A | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));}
+
+#define FRSP(FPR_DST, FPR_SRC) \
+ {INSTR = (0xFC000018 | (FPR_DST << 21) | (FPR_SRC << 11));}
+
+#define FCTIW(FPR_DST, FPR_SRC) \
+ {INSTR = (0xFC00001C | (FPR_DST << 21) | (FPR_SRC << 11));}
+
+
+#define LFS(FPR_DST, OFFSET, REG) \
+ {INSTR = (0xC0000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));}
+
+#define STFS(FPR_DST, OFFSET, REG) \
+ {INSTR = (0xD0000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));}
+
+#define LFD(FPR_DST, OFFSET, REG) \
+ {INSTR = (0xC8000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));}
+
+#define STFD(FPR_DST, OFFSET, REG) \
+ {INSTR = (0xD8000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));}
+
+
+
+/* extra combined opcodes */
+#if 1
+#define LIW(REG, IMM) /* Load Immidiate Word */ \
+{ \
+ int __reg = (REG); u32 __imm = (u32)(IMM); \
+ if ((s32)__imm == (s32)((s16)__imm)) \
+ { \
+ LI(__reg, (s32)((s16)__imm)); \
+ } else if (__reg == 0) { \
+ LIS(__reg, (((u32)__imm)>>16)); \
+ if ((((u32)__imm) & 0xffff) != 0) \
+ { \
+ ORI(__reg, __reg, __imm); \
+ } \
+ } else { \
+ if ((((u32)__imm) & 0xffff) == 0) { \
+ LIS(__reg, (((u32)__imm)>>16)); \
+ } else { \
+ LI(__reg, __imm); \
+ if ((__imm & 0x8000) == 0) { \
+ ADDIS(__reg, __reg, ((u32)__imm)>>16); \
+ } else { \
+ ADDIS(__reg, __reg, ((((u32)__imm)>>16) & 0xffff) + 1); \
+ } \
+ } \
+ /*if ((((u32)__imm) & 0xffff) != 0) \
+ { \
+ ORI(__reg, __reg, __imm); \
+ }*/ \
+ } \
+}
+#else
+#define LIW(REG, IMM) /* Load Immidiate Word */ \
+{ \
+ int __reg = (REG); u32 __imm = (u32)(IMM); \
+ if ((s32)__imm == (s32)((s16)__imm)) \
+ { \
+ LI(__reg, (s32)((s16)__imm)); \
+ } \
+ else \
+ { \
+ LIS(__reg, (((u32)__imm)>>16)); \
+ if ((((u32)__imm) & 0xffff) != 0) \
+ { \
+ ORI(__reg, __reg, __imm); \
+ } \
+ } \
+}
+#endif
diff --git a/libpcsxcore/ppc/reguse.c b/libpcsxcore/ppc/reguse.c
new file mode 100644
index 00000000..47d70a54
--- /dev/null
+++ b/libpcsxcore/ppc/reguse.c
@@ -0,0 +1,419 @@
+
+#include "../psxcommon.h"
+#include "reguse.h"
+
+#include "../r3000a.h"
+
+//#define SAME_CYCLE_MODE
+
+static const int useBSC[64] = {
+ /*recSPECIAL*/ REGUSE_SUB | REGUSE_SPECIAL,
+ /*recREGIMM*/ REGUSE_SUB | REGUSE_REGIMM,
+ /*recJ*/ REGUSE_JUMP,
+ /*recJAL*/ REGUSE_JUMP | REGUSE_R31_W,
+ /*recBEQ*/ REGUSE_BRANCH | REGUSE_RS_R | REGUSE_RT_R,
+ /*recBNE*/ REGUSE_BRANCH | REGUSE_RS_R | REGUSE_RT_R,
+ /*recBLEZ*/ REGUSE_BRANCH | REGUSE_RS_R,
+ /*recBGTZ*/ REGUSE_BRANCH | REGUSE_RS_R,
+ /*recADDI*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recADDIU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recSLTI*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recSLTIU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recANDI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recORI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recXORI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W,
+ /*recLUI*/ REGUSE_ACC | REGUSE_RT_W,
+ /*recCOP0*/ REGUSE_SUB | REGUSE_COP0,
+ REGUSE_NONE,
+ /*recCOP2*/ REGUSE_SUB | REGUSE_COP2,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recLB*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W,
+ /*recLH*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W,
+ /*recLWL*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT,
+ /*recLW*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W,
+ /*recLBU*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W,
+ /*recLHU*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W,
+ /*recLWR*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT,
+ REGUSE_NONE,
+ /*recSB*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R,
+ /*recSH*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R,
+ /*recSWL*/ REGUSE_MEM | REGUSE_RS_R | REGUSE_RT_R,
+ /*recSW*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R,
+ REGUSE_NONE, REGUSE_NONE,
+ /*recSWR*/ REGUSE_MEM | REGUSE_RS_R | REGUSE_RT_R,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recLWC2*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_COP2_RT_W,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE,
+ /*recSWC2*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_COP2_RT_R,
+ /*recHLE*/ REGUSE_UNKNOWN, // TODO: can this be done in a better way
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE
+};
+
+static const int useSPC[64] = {
+ /*recSLL*/ REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W,
+ REGUSE_NONE,
+ /*recSRL*/ REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W,
+ /*recSRA*/ REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W,
+ /*recSLLV*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ REGUSE_NONE,
+ /*recSRLV*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recSRAV*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recJR*/ REGUSE_JUMPR | REGUSE_RS_R,
+ /*recJALR*/ REGUSE_JUMPR | REGUSE_RS_R | REGUSE_RD_W,
+ REGUSE_NONE, REGUSE_NONE,
+ /*rSYSCALL*/ REGUSE_SYS | REGUSE_PC | REGUSE_COP0_STATUS | REGUSE_EXCEPTION,
+ /*recBREAK*/ REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE,
+ /*recMFHI*/ REGUSE_LOGIC | REGUSE_RD_W | REGUSE_HI_R,
+ /*recMTHI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_HI_W,
+ /*recMFLO*/ REGUSE_LOGIC | REGUSE_RD_W | REGUSE_LO_R,
+ /*recMTLO*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_LO_W,
+ REGUSE_NONE, REGUSE_NONE , REGUSE_NONE, REGUSE_NONE,
+ /*recMULT*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W,
+ /*recMULTU*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W,
+ /*recDIV*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W,
+ /*recDIVU*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recADD*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recADDU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recSUB*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recSUBU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recAND*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recOR*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recXOR*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recNOR*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ REGUSE_NONE, REGUSE_NONE,
+ /*recSLT*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ /*recSLTU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE
+};
+
+static const int useREGIMM[32] = {
+ /*recBLTZ*/ REGUSE_BRANCH | REGUSE_RS_R,
+ /*recBGEZ*/ REGUSE_BRANCH | REGUSE_RS_R,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE,
+ /*recBLTZAL*/REGUSE_BRANCH | REGUSE_RS_R | REGUSE_R31_W,
+ /*recBGEZAL*/REGUSE_BRANCH | REGUSE_RS_R | REGUSE_R31_W,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE
+};
+
+static const int useCP0[32] = {
+ /*recMFC0*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP0_RD_R,
+ REGUSE_NONE,
+ /*recCFC0*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP0_RD_R,
+ REGUSE_NONE,
+ /*recMTC0*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP0_RD_W,
+ REGUSE_NONE,
+ /*recCTC0*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP0_RD_W,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recRFE*/ REGUSE_LOGIC | REGUSE_COP0_STATUS,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE
+};
+
+// TODO: make more explicit
+static const int useCP2[64] = {
+ /*recBASIC*/ REGUSE_SUB | REGUSE_BASIC,
+ /*recRTPS*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recNCLIP*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recOP*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recDPCS*/ REGUSE_GTE,
+ /*recINTPL*/ REGUSE_GTE,
+ /*recMVMVA*/ REGUSE_GTE,
+ /*recNCDS*/ REGUSE_GTE,
+ /*recCDP*/ REGUSE_GTE,
+ REGUSE_NONE,
+ /*recNCDT*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recNCCS*/ REGUSE_GTE,
+ /*recCC*/ REGUSE_GTE,
+ REGUSE_NONE,
+ /*recNCS*/ REGUSE_GTE,
+ REGUSE_NONE,
+ /*recNCT*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE,
+ /*recSQR*/ REGUSE_GTE,
+ /*recDCPL*/ REGUSE_GTE,
+ /*recDPCT*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE,
+ /*recAVSZ3*/ REGUSE_GTE,
+ /*recAVSZ4*/ REGUSE_GTE,
+ REGUSE_NONE,
+ /*recRTPT*/ REGUSE_GTE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE,
+ /*recGPF*/ REGUSE_GTE,
+ /*recGPL*/ REGUSE_GTE,
+ /*recNCCT*/ REGUSE_GTE
+};
+
+static const int useCP2BSC[32] = {
+ /*recMFC2*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP2_RD_R,
+ REGUSE_NONE,
+ /*recCFC2*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP2_RD_R,
+ REGUSE_NONE,
+ /*recMTC2*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP2_RD_W,
+ REGUSE_NONE,
+ /*recCTC2*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP2_RD_W,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE,
+ REGUSE_NONE
+};
+
+static int getRegUse(u32 code) __attribute__ ((__pure__));
+static int getRegUse(u32 code)
+{
+ int use = useBSC[code>>26];
+
+ switch (use & REGUSE_SUBMASK) {
+ case REGUSE_NONE:
+ break;
+ case REGUSE_SPECIAL:
+ use = useSPC[_fFunct_(code)];
+ break;
+ case REGUSE_REGIMM:
+ use = useREGIMM[_fRt_(code)];
+ break;
+ case REGUSE_COP0:
+ use = useCP0[_fRs_(code)];
+ break;
+ case REGUSE_COP2:
+ use = useCP2[_fFunct_(code)];
+ if ((use & REGUSE_SUBMASK) == REGUSE_BASIC)
+ use = useCP2BSC[_fRs_(code)];
+ break;
+ default:
+ use = REGUSE_UNKNOWN;
+ break;
+ }
+
+ if ((use & REGUSE_COP0_RD_W)) {
+ if (_fRd_(code) == 12 || _fRd_(code) == 13) {
+ use = REGUSE_UNKNOWN;
+ }
+ }
+
+ return use;
+}
+
+/* returns how psxreg is used in the code instruction */
+int useOfPsxReg(u32 code, int use, int psxreg)
+{
+ int retval = REGUSE_NONE;
+
+ // get use if it wasn't supplied
+ if (-1 == use) use = getRegUse(code);
+
+ // if we don't know what the usage is, assume it's read from
+ if (REGUSE_UNKNOWN == use) return REGUSE_READ;
+
+ if (psxreg < 32) {
+ // check for 3 standard types
+ if ((use & REGUSE_RT) && _fRt_(code) == (u32)psxreg) {
+ retval |= ((use & REGUSE_RT_R) ? REGUSE_READ:0) | ((use & REGUSE_RT_W) ? REGUSE_WRITE:0);
+ }
+ if ((use & REGUSE_RS) && _fRs_(code) == (u32)psxreg) {
+ retval |= ((use & REGUSE_RS_R) ? REGUSE_READ:0) | ((use & REGUSE_RS_W) ? REGUSE_WRITE:0);
+ }
+ if ((use & REGUSE_RD) && _fRd_(code) == (u32)psxreg) {
+ retval |= ((use & REGUSE_RD_R) ? REGUSE_READ:0) | ((use & REGUSE_RD_W) ? REGUSE_WRITE:0);
+ }
+ // some instructions explicitly writes to r31
+ if ((use & REGUSE_R31_W) && 31 == psxreg) {
+ retval |= REGUSE_WRITE;
+ }
+ } else if (psxreg == 32) { // Special register LO
+ retval |= ((use & REGUSE_LO_R) ? REGUSE_READ:0) | ((use & REGUSE_LO_W) ? REGUSE_WRITE:0);
+ } else if (psxreg == 33) { // Special register HI
+ retval |= ((use & REGUSE_HI_R) ? REGUSE_READ:0) | ((use & REGUSE_HI_W) ? REGUSE_WRITE:0);
+ }
+
+ return retval;
+}
+
+//#define NOREGUSE_FOLLOW
+
+static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr) __attribute__ ((__pure__, __unused__));
+static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr)
+{
+ u32 *ptr, code, bPC = 0;
+ int i, use, reguse = 0;
+
+ for (i=0; i<numInstr; ) {
+ // load current instruction
+ ptr = PSXM(pc);
+ if (ptr==NULL) {
+ // going nowhere... might as well assume a write, since we will hopefully never reach here
+ reguse = REGUSE_WRITE;
+ break;
+ }
+ code = SWAP32(*ptr);
+ // get usage patterns for instruction
+ use = getRegUse(code);
+ // find the use of psxreg in the instruction
+ reguse = useOfPsxReg(code, use, psxreg);
+
+ // return if we have found a use
+ if (reguse != REGUSE_NONE)
+ break;
+
+ // goto next instruction
+ pc += 4;
+ i++;
+
+ // check for code branches/jumps
+ if (i != numInstr) {
+ if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) {
+#ifndef NOREGUSE_FOLLOW
+ // check delay slot
+ reguse = _nextPsxRegUse(pc, psxreg, 1);
+ if (reguse != REGUSE_NONE) break;
+
+ bPC = _fImm_(code) * 4 + pc;
+ reguse = _nextPsxRegUse(pc+4, psxreg, (numInstr-i-1)/2);
+ if (reguse != REGUSE_NONE) {
+ int reguse2 = _nextPsxRegUse(bPC, psxreg, (numInstr-i-1)/2);
+ if (reguse2 != REGUSE_NONE)
+ reguse |= reguse2;
+ else
+ reguse = REGUSE_NONE;
+ }
+#endif
+ break;
+ } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) {
+#ifndef NOREGUSE_FOLLOW
+ // check delay slot
+ reguse = _nextPsxRegUse(pc, psxreg, 1);
+ if (reguse != REGUSE_NONE) break;
+
+ bPC = _fTarget_(code) * 4 + (pc & 0xf0000000);
+ reguse = _nextPsxRegUse(bPC, psxreg, numInstr-i-1);
+#endif
+ break;
+ } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR) {
+#ifndef NOREGUSE_FOLLOW
+ // jump to unknown location - bail after checking delay slot
+ reguse = _nextPsxRegUse(pc, psxreg, 1);
+#endif
+ break;
+ } else if ((use & REGUSE_TYPEM) == REGUSE_SYS) {
+ break;
+ }
+ }
+ }
+
+ return reguse;
+}
+
+
+int nextPsxRegUse(u32 pc, int psxreg)
+{
+#if 1
+ if (psxreg == 0)
+ return REGUSE_WRITE; // pretend we are writing to it to fool compiler
+
+#ifdef SAME_CYCLE_MODE
+ return REGUSE_READ;
+#else
+ return _nextPsxRegUse(pc, psxreg, 80);
+#endif
+#else
+ u32 code, bPC = 0;
+ int use, reguse = 0, reguse1 = 0, b = 0, i, index = 0;
+
+retry:
+ for (i=index; i<80; i++) {
+ code = PSXMu32(pc);
+ use = getRegUse(code);
+ reguse = useOfPsxReg(code, use, psxreg);
+
+ if (reguse != REGUSE_NONE) break;
+
+ pc += 4;
+ if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) {
+ if (b == 0) {
+ bPC = _fImm_(code) * 4 + pc;
+ index = i+1;
+ }
+ b += 1; // TODO: follow branches
+ continue;
+ } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) {
+ if (b == 0) {
+ bPC = _fTarget_(code) * 4 + (pc & 0xf0000000);
+ }
+ b = 2;
+ continue;
+ } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR ||
+ (use & REGUSE_TYPEM) == REGUSE_SYS) {
+ b = 2;
+ continue;
+ }
+
+ if (b == 2 && bPC && index == 0) {
+ pc = bPC; bPC = 0;
+ b = 1;
+ }
+ if (b >= 2) break; // only follow 1 branch
+ }
+ if (reguse == REGUSE_NONE) return reguse;
+
+ if (bPC) {
+ reguse1 = reguse;
+ pc = bPC; bPC = 0;
+ b = 1;
+ goto retry;
+ }
+
+ return reguse1 | reguse;
+#endif
+}
+
+int isPsxRegUsed(u32 pc, int psxreg)
+{
+ int use = nextPsxRegUse(pc, psxreg);
+
+ if (use == REGUSE_NONE)
+ return 2; // unknown use - assume it is used
+ else if (use & REGUSE_READ)
+ return 1; // the next use is a read
+ else
+ return 0; // the next use is a write, i.e. current value is not important
+}
diff --git a/libpcsxcore/ppc/reguse.h b/libpcsxcore/ppc/reguse.h
new file mode 100644
index 00000000..69001ef3
--- /dev/null
+++ b/libpcsxcore/ppc/reguse.h
@@ -0,0 +1,77 @@
+
+#ifndef __REGUSE_H__
+#define __REGUSE_H__
+
+// include basic types
+#include "../psxcommon.h"
+
+#define REGUSE_NONE 0x0000
+#define REGUSE_UNKNOWN 0x0001
+
+//sub functions
+#define REGUSE_SPECIAL 0x0002
+#define REGUSE_REGIMM 0x0004
+#define REGUSE_COP0 0x0006
+#define REGUSE_COP2 0x0008
+#define REGUSE_BASIC 0x000a
+#define REGUSE_SUBMASK 0x000e /* sub function mask */
+
+#define REGUSE_ACC 0x0010 /* accumulator */
+#define REGUSE_LOGIC 0x0020 /* logic operations */
+#define REGUSE_MULT 0x0030 /* multiplier */
+#define REGUSE_JUMP 0x0040 /* jump to dest */
+#define REGUSE_JUMPR 0x0050 /* jump to reg */
+#define REGUSE_BRANCH 0x0060 /* branch */
+#define REGUSE_MEM_R 0x0070 /* read from memory */
+#define REGUSE_MEM_W 0x0080 /* write to memory */
+#define REGUSE_MEM 0x0090 /* read and write to memory */
+#define REGUSE_SYS 0x00a0 /* syscall */
+#define REGUSE_GTE 0x00b0 /* gte operation */
+#define REGUSE_SUB 0x00f0 /* sub usage */
+#define REGUSE_TYPEM 0x00f0 /* type mask */
+
+
+#define REGUSE_RS_R 0x0100
+#define REGUSE_RS_W 0x0200
+#define REGUSE_RS (REGUSE_RS_R | REGUSE_RS_W)
+#define REGUSE_RT_R 0x0400
+#define REGUSE_RT_W 0x0800
+#define REGUSE_RT (REGUSE_RT_R | REGUSE_RT_W)
+#define REGUSE_RD_R 0x1000
+#define REGUSE_RD_W 0x2000
+#define REGUSE_RD (REGUSE_RD_R | REGUSE_RD_W)
+
+#define REGUSE_R31_W 0x4000 /* writes to link register (r31) */
+#define REGUSE_PC 0x8000 /* reads pc */
+
+#define REGUSE_LO_R 0x10000
+#define REGUSE_LO_W 0x20000
+#define REGUSE_LO (REGUSE_LO_R | REGUSE_LO_W)
+#define REGUSE_HI_R 0x40000
+#define REGUSE_HI_W 0x80000
+#define REGUSE_HI (REGUSE_HI_R | REGUSE_HI_W)
+
+#define REGUSE_COP0_RD_R 0x100000
+#define REGUSE_COP0_RD_W 0x200000
+#define REGUSE_COP0_RD (REGUSE_COP0_RD_R | REGUSE_COP0_RD_W)
+#define REGUSE_COP0_STATUS 0x400000
+#define REGUSE_EXCEPTION 0x800000
+
+#define REGUSE_COP2_RT_R 0x1000000
+#define REGUSE_COP2_RT_W 0x2000000
+#define REGUSE_COP2_RT (REGUSE_COP2_RT_R | REGUSE_COP2_RT_W)
+#define REGUSE_COP2_RD_R 0x4000000
+#define REGUSE_COP2_RD_W 0x8000000
+#define REGUSE_COP2_RD (REGUSE_COP2_RD_R | REGUSE_COP2_RD_W)
+
+
+// specific register use
+#define REGUSE_READ 1
+#define REGUSE_WRITE 2
+#define REGUSE_RW 3
+
+int useOfPsxReg(u32 code, int use, int psxreg) __attribute__ ((__pure__));;
+int nextPsxRegUse(u32 pc, int psxreg) __attribute__ ((__pure__));;
+int isPsxRegUsed(u32 pc, int psxreg) __attribute__ ((__pure__));;
+
+#endif /* __REGUSE_H__ */
diff --git a/libpcsxcore/psemu_plugin_defs.h b/libpcsxcore/psemu_plugin_defs.h
new file mode 100644
index 00000000..baaf7836
--- /dev/null
+++ b/libpcsxcore/psemu_plugin_defs.h
@@ -0,0 +1,279 @@
+#ifndef _PSEMU_PLUGIN_DEFS_H
+#define _PSEMU_PLUGIN_DEFS_H
+
+// header version
+#define _PPDK_HEADER_VERSION 3
+
+#define PLUGIN_VERSION 1
+
+// plugin type returned by PSEgetLibType (types can be merged if plugin is multi type!)
+#define PSE_LT_CDR 1
+#define PSE_LT_GPU 2
+#define PSE_LT_SPU 4
+#define PSE_LT_PAD 8
+#define PSE_LT_NET 16
+
+// DLL function return codes
+#define PSE_ERR_SUCCESS 0 // every function in DLL if completed sucessfully should return this value
+#define PSE_ERR_FATAL -1 // undefined error but fatal one, that kills all functionality
+
+// XXX_Init return values
+// Those return values apply to all libraries
+// currently obsolete - preserved for compatibilty
+
+#define PSE_INIT_ERR_SUCCESS 0 // initialization went OK
+#define PSE_INIT_ERR_NOTCONFIGURED -2 // this driver is not configured
+#define PSE_INIT_ERR_NOHARDWARE -3 // this driver can not operate properly on this hardware or hardware is not detected
+
+/* GPU PlugIn */
+
+// GPU_Test return values
+
+// sucess, everything configured, and went OK.
+#define PSE_GPU_ERR_SUCCESS 0
+
+// ERRORS
+// this error might be returned as critical error but none of below
+#define PSE_GPU_ERR -20
+
+
+// this driver is not configured
+#define PSE_GPU_ERR_NOTCONFIGURED PSE_GPU_ERR - 1
+// this driver failed Init
+#define PSE_GPU_ERR_INIT PSE_GPU_ERR - 2
+
+// WARNINGS
+// this warning might be returned as undefined warning but allowing driver to continue
+#define PSE_GPU_WARN 20
+
+// GPU_Query - will be implemented soon
+
+typedef struct
+{
+ uint32_t flags;
+ uint32_t status;
+ void* window;
+ unsigned char reserved[100];
+} gpuQueryS;
+
+// gpuQueryS.flags
+// if driver can operate in both modes it must support GPU_changeMode();
+#define PSE_GPU_FLAGS_FULLSCREEN 1 // this driver can operate in fullscreen mode
+#define PSE_GPU_FLAGS_WINDOWED 2 // this driver can operate in windowed mode
+
+// gpuQueryS.status
+#define PSE_GPU_STATUS_WINDOWWRONG 1 // this driver cannot operate in this windowed mode
+
+// GPU_Query End - will be implemented in v2
+
+
+/* CDR PlugIn */
+
+// CDR_Test return values
+
+// sucess, everything configured, and went OK.
+#define PSE_CDR_ERR_SUCCESS 0
+
+// general failure (error undefined)
+#define PSE_CDR_ERR_FAILURE -1
+
+// ERRORS
+#define PSE_CDR_ERR -40
+// this driver is not configured
+#define PSE_CDR_ERR_NOTCONFIGURED PSE_CDR_ERR - 0
+// if this driver is unable to read data from medium
+#define PSE_CDR_ERR_NOREAD PSE_CDR_ERR - 1
+
+// WARNINGS
+#define PSE_CDR_WARN 40
+// if this driver emulates lame mode ie. can read only 2048 tracks and sector header is emulated
+// this might happen to CDROMS that do not support RAW mode reading - surelly it will kill many games
+#define PSE_CDR_WARN_LAMECD PSE_CDR_WARN + 0
+
+
+
+
+/* SPU PlugIn */
+
+// some info retricted (now!)
+
+// sucess, everything configured, and went OK.
+#define PSE_SPU_ERR_SUCCESS 0
+
+// ERRORS
+// this error might be returned as critical error but none of below
+#define PSE_SPU_ERR -60
+
+// this driver is not configured
+#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1
+// this driver failed Init
+#define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2
+
+
+// WARNINGS
+// this warning might be returned as undefined warning but allowing driver to continue
+#define PSE_SPU_WARN 60
+
+
+
+
+/* PAD PlugIn */
+
+/*
+
+ functions that must be exported from PAD Plugin
+
+ long PADinit(long flags); // called only once when PSEmu Starts
+ void PADshutdown(void); // called when PSEmu exits
+ long PADopen(PadInitS *); // called when PSEmu is running program
+ long PADclose(void);
+ long PADconfigure(void);
+ void PADabout(void);
+ long PADtest(void); // called from Configure Dialog and after PADopen();
+ long PADquery(void);
+
+ long PADreadPort1(PadDataS *);
+ long PADreadPort2(PadDataS *);
+
+*/
+
+// PADquery responses (notice - values ORed)
+// PSEmu will use them also in PADinit to tell Plugin which Ports will use
+// notice that PSEmu will call PADinit and PADopen only once when they are from
+// same plugin
+
+// might be used in port 1 (must support PADreadPort1() function)
+#define PSE_PAD_USE_PORT1 1
+// might be used in port 2 (must support PADreadPort2() function)
+#define PSE_PAD_USE_PORT2 2
+
+
+
+// MOUSE SCPH-1030
+#define PSE_PAD_TYPE_MOUSE 1
+// NEGCON - 16 button analog controller SLPH-00001
+#define PSE_PAD_TYPE_NEGCON 2
+// GUN CONTROLLER - gun controller SLPH-00014 from Konami
+#define PSE_PAD_TYPE_GUN 3
+// STANDARD PAD SCPH-1080, SCPH-1150
+#define PSE_PAD_TYPE_STANDARD 4
+// ANALOG JOYSTICK SCPH-1110
+#define PSE_PAD_TYPE_ANALOGJOY 5
+// GUNCON - gun controller SLPH-00034 from Namco
+#define PSE_PAD_TYPE_GUNCON 6
+// ANALOG CONTROLLER SCPH-1150
+#define PSE_PAD_TYPE_ANALOGPAD 7
+
+
+// sucess, everything configured, and went OK.
+#define PSE_PAD_ERR_SUCCESS 0
+// general plugin failure (undefined error)
+#define PSE_PAD_ERR_FAILURE -1
+
+
+// ERRORS
+// this error might be returned as critical error but none of below
+#define PSE_PAD_ERR -80
+// this driver is not configured
+#define PSE_PAD_ERR_NOTCONFIGURED PSE_PAD_ERR - 1
+// this driver failed Init
+#define PSE_PAD_ERR_INIT PSE_PAD_ERR - 2
+
+
+// WARNINGS
+// this warning might be returned as undefined warning but allowing driver to continue
+#define PSE_PAD_WARN 80
+
+
+typedef struct
+{
+ // controler type - fill it withe predefined values above
+ unsigned char controllerType;
+
+ // status of buttons - every controller fills this field
+ unsigned short buttonStatus;
+
+ // for analog pad fill those next 4 bytes
+ // values are analog in range 0-255 where 128 is center position
+ unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY;
+
+ // for mouse fill those next 2 bytes
+ // values are in range -128 - 127
+ unsigned char moveX, moveY;
+
+ unsigned char reserved[91];
+
+} PadDataS;
+
+/* NET PlugIn v2 */
+/* Added by linuzappz@pcsx.net */
+
+/* Modes bits for NETsendData/NETrecvData */
+#define PSE_NET_BLOCKING 0x00000000
+#define PSE_NET_NONBLOCKING 0x00000001
+
+/* note: unsupported fields should be zeroed.
+
+typedef struct {
+ char EmuName[32];
+ char CdromID[9]; // ie. 'SCPH12345', no \0 trailing character
+ char CdromLabel[11];
+ void *psxMem;
+ GPUshowScreenPic GPU_showScreenPic;
+ GPUdisplayText GPU_displayText;
+ PADsetSensitive PAD_setSensitive;
+ char GPUpath[256];
+ char SPUpath[256];
+ char CDRpath[256];
+ char MCD1path[256];
+ char MCD2path[256];
+ char BIOSpath[256]; // 'HLE' for internal bios
+ char Unused[1024];
+} netInfo;
+
+*/
+
+/*
+ basic funcs:
+
+ long NETopen(HWND hWnd)
+ opens the connection.
+ shall return 0 on success, else -1.
+ -1 is also returned if the user selects offline mode.
+
+ long NETclose()
+ closes the connection.
+ shall return 0 on success, else -1.
+
+ void NETpause()
+ this is called when the user paused the emulator.
+
+ void NETresume()
+ this is called when the user resumed the emulator.
+
+ long NETqueryPlayer()
+ returns player number
+
+ long NETsendPadData(void *pData, int Size)
+ this should be called for the first pad only on each side.
+
+ long NETrecvPadData(void *pData, int Pad)
+ call this for Pad 1/2 to get the data sent by the above func.
+
+ extended funcs:
+
+ long NETsendData(void *pData, int Size, int Mode)
+ sends Size bytes from pData to the other side.
+
+ long NETrecvData(void *pData, int Size, int Mode)
+ receives Size bytes from pData to the other side.
+
+ void NETsetInfo(netInfo *info);
+ sets the netInfo struct.
+
+ void NETkeypressed(int key) (linux only)
+ key is a XK_?? (X11) keycode.
+*/
+
+
+#endif // _PSEMU_PLUGIN_DEFS_H
diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c
new file mode 100644
index 00000000..38e7649e
--- /dev/null
+++ b/libpcsxcore/psxbios.c
@@ -0,0 +1,2399 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Internal emulated HLE BIOS.
+*/
+
+#include "psxbios.h"
+#include "psxhw.h"
+
+//We try to emulate bios :) HELP US :P
+
+char *biosA0n[256] = {
+// 0x00
+ "open", "lseek", "read", "write",
+ "close", "ioctl", "exit", "sys_a0_07",
+ "getc", "putc", "todigit", "atof",
+ "strtoul", "strtol", "abs", "labs",
+// 0x10
+ "atoi", "atol", "atob", "setjmp",
+ "longjmp", "strcat", "strncat", "strcmp",
+ "strncmp", "strcpy", "strncpy", "strlen",
+ "index", "rindex", "strchr", "strrchr",
+// 0x20
+ "strpbrk", "strspn", "strcspn", "strtok",
+ "strstr", "toupper", "tolower", "bcopy",
+ "bzero", "bcmp", "memcpy", "memset",
+ "memmove", "memcmp", "memchr", "rand",
+// 0x30
+ "srand", "qsort", "strtod", "malloc",
+ "free", "lsearch", "bsearch", "calloc",
+ "realloc", "InitHeap", "_exit", "getchar",
+ "putchar", "gets", "puts", "printf",
+// 0x40
+ "sys_a0_40", "LoadTest", "Load", "Exec",
+ "FlushCache", "InstallInterruptHandler", "GPU_dw", "mem2vram",
+ "SendGPUStatus", "GPU_cw", "GPU_cwb", "SendPackets",
+ "sys_a0_4c", "GetGPUStatus", "GPU_sync", "sys_a0_4f",
+// 0x50
+ "sys_a0_50", "LoadExec", "GetSysSp", "sys_a0_53",
+ "_96_init()", "_bu_init()", "_96_remove()", "sys_a0_57",
+ "sys_a0_58", "sys_a0_59", "sys_a0_5a", "dev_tty_init",
+ "dev_tty_open", "sys_a0_5d", "dev_tty_ioctl","dev_cd_open",
+// 0x60
+ "dev_cd_read", "dev_cd_close", "dev_cd_firstfile", "dev_cd_nextfile",
+ "dev_cd_chdir", "dev_card_open", "dev_card_read", "dev_card_write",
+ "dev_card_close", "dev_card_firstfile", "dev_card_nextfile","dev_card_erase",
+ "dev_card_undelete","dev_card_format", "dev_card_rename", "dev_card_6f",
+// 0x70
+ "_bu_init", "_96_init", "_96_remove", "sys_a0_73",
+ "sys_a0_74", "sys_a0_75", "sys_a0_76", "sys_a0_77",
+ "_96_CdSeekL", "sys_a0_79", "sys_a0_7a", "sys_a0_7b",
+ "_96_CdGetStatus", "sys_a0_7d", "_96_CdRead", "sys_a0_7f",
+// 0x80
+ "sys_a0_80", "sys_a0_81", "sys_a0_82", "sys_a0_83",
+ "sys_a0_84", "_96_CdStop", "sys_a0_86", "sys_a0_87",
+ "sys_a0_88", "sys_a0_89", "sys_a0_8a", "sys_a0_8b",
+ "sys_a0_8c", "sys_a0_8d", "sys_a0_8e", "sys_a0_8f",
+// 0x90
+ "sys_a0_90", "sys_a0_91", "sys_a0_92", "sys_a0_93",
+ "sys_a0_94", "sys_a0_95", "AddCDROMDevice", "AddMemCardDevide",
+ "DisableKernelIORedirection", "EnableKernelIORedirection", "sys_a0_9a", "sys_a0_9b",
+ "SetConf", "GetConf", "sys_a0_9e", "SetMem",
+// 0xa0
+ "_boot", "SystemError", "EnqueueCdIntr", "DequeueCdIntr",
+ "sys_a0_a4", "ReadSector", "get_cd_status", "bufs_cb_0",
+ "bufs_cb_1", "bufs_cb_2", "bufs_cb_3", "_card_info",
+ "_card_load", "_card_auto", "bufs_cd_4", "sys_a0_af",
+// 0xb0
+ "sys_a0_b0", "sys_a0_b1", "do_a_long_jmp", "sys_a0_b3",
+ "?? sub_function",
+};
+
+char *biosB0n[256] = {
+// 0x00
+ "SysMalloc", "sys_b0_01", "sys_b0_02", "sys_b0_03",
+ "sys_b0_04", "sys_b0_05", "sys_b0_06", "DeliverEvent",
+ "OpenEvent", "CloseEvent", "WaitEvent", "TestEvent",
+ "EnableEvent", "DisableEvent", "OpenTh", "CloseTh",
+// 0x10
+ "ChangeTh", "sys_b0_11", "InitPAD", "StartPAD",
+ "StopPAD", "PAD_init", "PAD_dr", "ReturnFromExecption",
+ "ResetEntryInt", "HookEntryInt", "sys_b0_1a", "sys_b0_1b",
+ "sys_b0_1c", "sys_b0_1d", "sys_b0_1e", "sys_b0_1f",
+// 0x20
+ "UnDeliverEvent", "sys_b0_21", "sys_b0_22", "sys_b0_23",
+ "sys_b0_24", "sys_b0_25", "sys_b0_26", "sys_b0_27",
+ "sys_b0_28", "sys_b0_29", "sys_b0_2a", "sys_b0_2b",
+ "sys_b0_2c", "sys_b0_2d", "sys_b0_2e", "sys_b0_2f",
+// 0x30
+ "sys_b0_30", "sys_b0_31", "open", "lseek",
+ "read", "write", "close", "ioctl",
+ "exit", "sys_b0_39", "getc", "putc",
+ "getchar", "putchar", "gets", "puts",
+// 0x40
+ "cd", "format", "firstfile", "nextfile",
+ "rename", "delete", "undelete", "AddDevice",
+ "RemoteDevice", "PrintInstalledDevices", "InitCARD", "StartCARD",
+ "StopCARD", "sys_b0_4d", "_card_write", "_card_read",
+// 0x50
+ "_new_card", "Krom2RawAdd", "sys_b0_52", "sys_b0_53",
+ "_get_errno", "_get_error", "GetC0Table", "GetB0Table",
+ "_card_chan", "sys_b0_59", "sys_b0_5a", "ChangeClearPAD",
+ "_card_status", "_card_wait",
+};
+
+char *biosC0n[256] = {
+// 0x00
+ "InitRCnt", "InitException", "SysEnqIntRP", "SysDeqIntRP",
+ "get_free_EvCB_slot", "get_free_TCB_slot", "ExceptionHandler", "InstallExeptionHandler",
+ "SysInitMemory", "SysInitKMem", "ChangeClearRCnt", "SystemError",
+ "InitDefInt", "sys_c0_0d", "sys_c0_0e", "sys_c0_0f",
+// 0x10
+ "sys_c0_10", "sys_c0_11", "InstallDevices", "FlushStfInOutPut",
+ "sys_c0_14", "_cdevinput", "_cdevscan", "_circgetc",
+ "_circputc", "ioabort", "sys_c0_1a", "KernelRedirect",
+ "PatchAOTable",
+};
+
+//#define r0 (psxRegs.GPR.n.r0)
+#define at (psxRegs.GPR.n.at)
+#define v0 (psxRegs.GPR.n.v0)
+#define v1 (psxRegs.GPR.n.v1)
+#define a0 (psxRegs.GPR.n.a0)
+#define a1 (psxRegs.GPR.n.a1)
+#define a2 (psxRegs.GPR.n.a2)
+#define a3 (psxRegs.GPR.n.a3)
+#define t0 (psxRegs.GPR.n.t0)
+#define t1 (psxRegs.GPR.n.t1)
+#define t2 (psxRegs.GPR.n.t2)
+#define t3 (psxRegs.GPR.n.t3)
+#define t4 (psxRegs.GPR.n.t4)
+#define t5 (psxRegs.GPR.n.t5)
+#define t6 (psxRegs.GPR.n.t6)
+#define t7 (psxRegs.GPR.n.t7)
+#define s0 (psxRegs.GPR.n.s0)
+#define s1 (psxRegs.GPR.n.s1)
+#define s2 (psxRegs.GPR.n.s2)
+#define s3 (psxRegs.GPR.n.s3)
+#define s4 (psxRegs.GPR.n.s4)
+#define s5 (psxRegs.GPR.n.s5)
+#define s6 (psxRegs.GPR.n.s6)
+#define s7 (psxRegs.GPR.n.s7)
+#define t8 (psxRegs.GPR.n.t6)
+#define t9 (psxRegs.GPR.n.t7)
+#define k0 (psxRegs.GPR.n.k0)
+#define k1 (psxRegs.GPR.n.k1)
+#define gp (psxRegs.GPR.n.gp)
+#define sp (psxRegs.GPR.n.sp)
+#define fp (psxRegs.GPR.n.s8)
+#define ra (psxRegs.GPR.n.ra)
+#define pc0 (psxRegs.pc)
+
+#define Ra0 ((char*)PSXM(a0))
+#define Ra1 ((char*)PSXM(a1))
+#define Ra2 ((char*)PSXM(a2))
+#define Ra3 ((char*)PSXM(a3))
+#define Rv0 ((char*)PSXM(v0))
+#define Rsp ((char*)PSXM(sp))
+
+
+typedef struct {
+ u32 desc;
+ s32 status;
+ s32 mode;
+ u32 fhandler;
+} EvCB[32];
+
+#define EvStUNUSED 0x0000
+#define EvStWAIT 0x1000
+#define EvStACTIVE 0x2000
+#define EvStALREADY 0x4000
+
+#define EvMdINTR 0x1000
+#define EvMdNOINTR 0x2000
+
+/*
+typedef struct {
+ long next;
+ long func1;
+ long func2;
+ long pad;
+} SysRPst;
+*/
+
+typedef struct {
+ s32 status;
+ s32 mode;
+ u32 reg[32];
+ u32 func;
+} TCB;
+
+typedef struct {
+ u32 _pc0;
+ u32 gp0;
+ u32 t_addr;
+ u32 t_size;
+ u32 d_addr;
+ u32 d_size;
+ u32 b_addr;
+ u32 b_size;
+ u32 S_addr;
+ u32 s_size;
+ u32 _sp,_fp,_gp,ret,base;
+} EXEC;
+
+struct DIRENTRY {
+ char name[20];
+ long attr;
+ long size;
+ struct DIRENTRY *next;
+ long head;
+ char system[4];
+};
+
+typedef struct {
+ char name[32];
+ u32 mode;
+ u32 offset;
+ u32 size;
+ u32 mcfile;
+} FileDesc;
+
+static u32 *jmp_int = NULL;
+static int *pad_buf = NULL;
+static char *pad_buf1, *pad_buf2;//shadow add
+static int pad_buf1len, pad_buf2len;//shadow add
+
+static u32 regs[35];
+static EvCB *Event;
+static EvCB *HwEV; // 0xf0
+static EvCB *EvEV; // 0xf1
+static EvCB *RcEV; // 0xf2
+static EvCB *UeEV; // 0xf3
+static EvCB *SwEV; // 0xf4
+static EvCB *ThEV; // 0xff
+static u32 *heap_addr = NULL;
+static u32 *heap_end = NULL;
+static u32 SysIntRP[8];
+static int CardState = -1;
+static TCB Thread[8];
+static int CurThread = 0;
+static FileDesc FDesc[32];
+
+static __inline void softCall(u32 pc) {
+ pc0 = pc;
+ ra = 0x80001000;
+ while (pc0 != 0x80001000) psxCpu->ExecuteBlock();
+}
+
+static __inline void softCall2(u32 pc) {
+ u32 sra = ra;
+ pc0 = pc;
+ ra = 0x80001000;
+ while (pc0 != 0x80001000) psxCpu->ExecuteBlock();
+ ra = sra;
+}
+
+static __inline void DeliverEvent(u32 ev, u32 spec) {
+ if (Event[ev][spec].status != EvStACTIVE) return;
+
+// Event[ev][spec].status = EvStALREADY;
+ if (Event[ev][spec].mode == EvMdINTR) {
+ softCall2(Event[ev][spec].fhandler);
+ } else Event[ev][spec].status = EvStALREADY;
+}
+
+/* *
+// *
+// *
+// System calls A0 */
+
+
+void psxBios_abs() { // 0x0e
+ v0 = abs(a0);
+ pc0 = ra;
+}
+
+void psxBios_labs() { // 0x0f
+ v0 = labs(a0);
+ pc0 = ra;
+}
+
+void psxBios_atoi() { // 0x10
+ v0 = atoi((char *)Ra0);
+ pc0 = ra;
+}
+
+void psxBios_atol() { // 0x11
+ v0 = atoi((char *)Ra0);
+ pc0 = ra;
+}
+
+void psxBios_setjmp() { // 13
+ u32 *jmp_buf= (u32*)Ra0;
+ int i;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x13]);
+#endif
+
+ jmp_buf[0] = ra;
+ jmp_buf[1] = sp;
+ jmp_buf[2] = fp;
+ for (i=0; i<8; i++) // s0-s7
+ jmp_buf[3+i] = psxRegs.GPR.r[16+i];
+ jmp_buf[11] = gp;
+
+ v0 = 0; pc0 = ra;
+}
+
+void psxBios_longjmp() { //14
+ u32 *jmp_buf= (u32*)Ra0;
+ int i;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x14]);
+#endif
+
+ ra = jmp_buf[0]; /* ra */
+ sp = jmp_buf[1]; /* sp */
+ fp = jmp_buf[2]; /* fp */
+ for (i=0; i<8; i++) // s0-s7
+ psxRegs.GPR.r[16+i] = jmp_buf[3+i];
+ gp = jmp_buf[11]; /* gp */
+
+ v0 = a1; pc0 = ra;
+}
+
+void psxBios_strcat() { // 0x15
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s, %s\n", biosA0n[0x15], Ra0, Ra1);
+#endif
+
+ strcat(Ra0, Ra1);
+ v0 = a0; pc0 = ra;
+}
+
+/*0x16*/void psxBios_strncat() { strncat(Ra0, Ra1, a2); v0 = a0; pc0 = ra;}
+
+void psxBios_strcmp() { // 0x17
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s (%lx), %s (%lx)\n", biosA0n[0x17], Ra0, a0, Ra1, a1);
+#endif
+
+ v0 = strcmp(Ra0, Ra1);
+ pc0 = ra;
+}
+
+void psxBios_strncmp() { // 0x18
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s (%lx), %s (%lx), %d\n", biosA0n[0x18], Ra0, a0, Ra1, a1, a2);
+#endif
+
+ v0 = strncmp(Ra0, Ra1, a2);
+ pc0 = ra;
+}
+
+/*0x19*/void psxBios_strcpy() { strcpy(Ra0, Ra1); v0 = a0; pc0 = ra;}
+/*0x1a*/void psxBios_strncpy() { strncpy(Ra0, Ra1, a2); v0 = a0; pc0 = ra;}
+/*0x1b*/void psxBios_strlen() { v0 = strlen(Ra0); pc0 = ra;}
+
+void psxBios_index() { // 0x1c
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strchr(pcA0, a1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_rindex() { // 0x1d
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strrchr(pcA0, a1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_strchr() { // 0x1e
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strchr(pcA0, a1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_strrchr() { // 0x1f
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strrchr(pcA0, a1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_strpbrk() { // 0x20
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strpbrk(pcA0, (char *)Ra1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_strspn() { v0 = strspn ((char *)Ra0, (char *)Ra1); pc0 = ra;}/*21*/
+void psxBios_strcspn() { v0 = strcspn((char *)Ra0, (char *)Ra1); pc0 = ra;}/*22*/
+
+void psxBios_strtok() { // 0x23
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strtok(pcA0, (char *)Ra1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_strstr() { // 0x24
+ char *pcA0 = (char *)Ra0;
+ char *pcRet = strstr(pcA0, (char *)Ra1);
+ if(pcRet)
+ v0 = a0 + pcRet - pcA0;
+ else
+ v0 = 0;
+ pc0 = ra;
+}
+
+/*0x25*/void psxBios_toupper() {v0 = toupper(a0); pc0 = ra;}
+/*0x26*/void psxBios_tolower() {v0 = tolower(a0); pc0 = ra;}
+/*0x27*/void psxBios_bcopy() {memcpy(Ra1,Ra0,a2); pc0=ra;}
+/*0x28*/void psxBios_bzero() {memset(Ra0,0,a1); pc0=ra;}
+/*0x29*/void psxBios_bcmp() {v0 = memcmp(Ra0,Ra1,a2); pc0=ra; }
+/*0x2a*/void psxBios_memcpy() {memcpy(Ra0, Ra1, a2); v0 = a0; pc0 = ra;}
+/*0x2b*/void psxBios_memset() {memset(Ra0, a1, a2); v0 = a0; pc0 = ra;}
+/*0x2c*/void psxBios_memmove() {memmove(Ra0, Ra1, a2); v0 = a0; pc0 = ra;}
+/*0x2d*/void psxBios_memcmp() {v0 = memcmp(Ra0, Ra1, a2); pc0 = ra;}
+
+void psxBios_memchr() { // 2e
+ void *ret = memchr(Ra0, a1, a2);
+ if (ret != NULL) v0 = (u32)((char*)ret - Ra0) + a0;
+ else v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_rand() { // 2f
+ v0 = 1+(int) (32767.0*rand()/(RAND_MAX+1.0));
+ pc0 = ra;
+}
+
+void psxBios_srand() { // 30
+ srand(a0); pc0 = ra;
+}
+
+
+void psxBios_malloc() { // 33
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
+#endif
+ unsigned int *chunk, *newchunk;
+ unsigned int dsize, csize, cstat;
+ int colflag;
+
+ // scan through heap and combine free chunks of space
+ chunk = heap_addr;
+ colflag = 0;
+ while(chunk < heap_end) {
+ // get size and status of actual chunk
+ csize = ((u32)*chunk) & 0xfffffffc;
+ cstat = ((u32)*chunk) & 1;
+
+ // it's a free chunk
+ if(cstat == 1) {
+ if(colflag == 0) {
+ newchunk = chunk;
+ dsize = csize;
+ colflag = 1; // let's begin a new collection of free memory
+ }
+ else dsize += (csize+4); // add the new size including header
+ }
+ // not a free chunk: did we start a collection ?
+ else {
+ if(colflag == 1) { // collection is over
+ colflag = 0;
+ *newchunk = SWAP32(dsize | 1);
+ }
+ }
+
+ // next chunk
+ chunk = (u32*)((uptr)chunk + csize + 4);
+ }
+ // if neccessary free memory on end of heap
+ if (colflag == 1)
+ *newchunk = SWAP32(dsize | 1);
+
+ chunk = heap_addr;
+ csize = ((u32)*chunk) & 0xfffffffc;
+ cstat = ((u32)*chunk) & 1;
+ dsize = (a0 + 3) & 0xfffffffc;
+
+ // exit on uninitialized heap
+ if (chunk == NULL) {
+ SysPrintf("malloc %lx,%lx: Uninitialized Heap!\n", v0, a0);
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+
+ // search an unused chunk that is big enough until the end of the heap
+ while ((dsize > csize || cstat==0) && chunk < heap_end ) {
+ chunk = (u32*)((uptr)chunk + csize + 4);
+ csize = ((u32)*chunk) & 0xfffffffc;
+ cstat = ((u32)*chunk) & 1;
+ }
+
+ // catch out of memory
+ if(chunk >= heap_end) { SysPrintf("malloc %lx,%lx: Out of memory error!\n", v0, a0); v0 = 0; pc0 = ra; return; }
+
+ // allocate memory
+ if(dsize == csize) {
+ // chunk has same size
+ *chunk &= 0xfffffffc;
+ }
+ else {
+ // split free chunk
+ *chunk = SWAP32(dsize);
+ newchunk = (u32*)((uptr)chunk + dsize + 4);
+ *newchunk = SWAP32((csize - dsize - 4) & 0xfffffffc | 1);
+ }
+
+ // return pointer to allocated memory
+ v0 = ((unsigned long)chunk - (unsigned long)psxM) + 4;
+ v0|= 0x80000000;
+ SysPrintf ("malloc %lx,%lx\n", v0, a0);
+ pc0 = ra;
+}
+
+void psxBios_free() { // 34
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x34]);
+#endif
+
+ SysPrintf("free %lx: %lx bytes\n", a0, *(u32*)(Ra0-4));
+
+ *(u32*)(Ra0-4) |= 1; // set chunk to free
+ pc0 = ra;
+}
+
+void psxBios_calloc() { // 37
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x37]);
+#endif
+
+ a0 = a0 * a1;
+ psxBios_malloc();
+ memset(Rv0, 0, a0);
+}
+
+void psxBios_realloc() { // 38
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x38]);
+#endif
+
+ u32 block = a0;
+ u32 size = a1;
+
+ a0 = block;
+ psxBios_free();
+ a0 = size;
+ psxBios_malloc();
+}
+
+
+/* InitHeap(void *block , int n) */
+void psxBios_InitHeap() { // 39
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x39]);
+#endif
+
+ unsigned int size;
+
+ if (((a0 & 0x1fffff) + a1)>= 0x200000) size = 0x1ffffc - (a0 & 0x1fffff);
+ else size = a1;
+
+ size &= 0xfffffffc;
+
+ heap_addr = (u32*)Ra0;
+ heap_end = (u32*)((u32)heap_addr + size);
+ *heap_addr = SWAP32(size | 1);
+
+ SysPrintf("InitHeap %lx,%lx : %lx %lx\n",a0,a1, (uptr)heap_addr-(uptr)psxM, size);
+
+ pc0 = ra;
+}
+
+void psxBios_getchar(){ v0 = getchar(); pc0=ra;} //0x3b
+
+void psxBios_printf() { // 3f
+ char tmp[1024];
+ char tmp2[1024];
+ u32 save[4];
+ char *ptmp = tmp;
+ int n=1, i=0, j;
+
+ memcpy(save, (char*)PSXM(sp), 4*4);
+ psxMu32ref(sp) = SWAP32((u32)a0);
+ psxMu32ref(sp + 4) = SWAP32((u32)a1);
+ psxMu32ref(sp + 8) = SWAP32((u32)a2);
+ psxMu32ref(sp + 12) = SWAP32((u32)a3);
+
+ while (Ra0[i]) {
+ switch (Ra0[i]) {
+ case '%':
+ j = 0;
+ tmp2[j++] = '%';
+_start:
+ switch (Ra0[++i]) {
+ case '.':
+ case 'l':
+ tmp2[j++] = Ra0[i]; goto _start;
+ default:
+ if (Ra0[i] >= '0' && Ra0[i] <= '9') {
+ tmp2[j++] = Ra0[i];
+ goto _start;
+ }
+ break;
+ }
+ tmp2[j++] = Ra0[i];
+ tmp2[j] = 0;
+
+ switch (Ra0[i]) {
+ case 'f': case 'F':
+ ptmp+= sprintf(ptmp, tmp2, (float)psxMu32(sp + n * 4)); n++; break;
+ case 'a': case 'A':
+ case 'e': case 'E':
+ case 'g': case 'G':
+ ptmp+= sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break;
+ case 'p':
+ case 'i':
+ case 'd': case 'D':
+ case 'o': case 'O':
+ case 'x': case 'X':
+ ptmp+= sprintf(ptmp, tmp2, (unsigned int)psxMu32(sp + n * 4)); n++; break;
+ case 'c':
+ ptmp+= sprintf(ptmp, tmp2, (unsigned char)psxMu32(sp + n * 4)); n++; break;
+ case 's':
+ ptmp+= sprintf(ptmp, tmp2, (char*)PSXM(psxMu32(sp + n * 4))); n++; break;
+ case '%':
+ *ptmp++ = Ra0[i]; break;
+ }
+ i++;
+ break;
+ default:
+ *ptmp++ = Ra0[i++];
+ }
+ }
+ *ptmp = 0;
+
+ memcpy((char*)PSXM(sp), save, 4*4);
+
+ SysPrintf(tmp);
+
+ pc0 = ra;
+}
+
+/*
+ * long Load(char *name, struct EXEC *header);
+ */
+
+void psxBios_Load() { // 42
+ EXE_HEADER eheader;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s, %x\n", biosA0n[0x42], Ra0, a1);
+#endif
+
+ if (LoadCdromFile(Ra0, &eheader) == 0) {
+ memcpy(Ra1, ((char*)&eheader)+16, sizeof(EXEC));
+ v0 = 1;
+ } else v0 = 0;
+
+ pc0 = ra;
+}
+
+/*
+ * int Exec(struct EXEC *header , int argc , char **argv);
+ */
+
+void psxBios_Exec() { // 43
+ EXEC *header = (EXEC*)Ra0;
+ u32 tmp;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosA0n[0x43], a0, a1, a2);
+#endif
+
+ header->_sp = sp;
+ header->_fp = fp;
+ header->_sp = sp;
+ header->_gp = gp;
+ header->ret = ra;
+ header->base = s0;
+
+ if (header->S_addr != 0) {
+ tmp = header->S_addr + header->s_size;
+ sp = tmp;
+ fp = sp;
+ }
+
+ gp = header->gp0;
+
+ s0 = a0;
+
+ a0 = a1;
+ a1 = a2;
+
+ ra = 0x8000;
+ pc0 = header->_pc0;
+}
+
+void psxBios_FlushCache() { // 44
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x44]);
+#endif
+
+ pc0 = ra;
+}
+
+void psxBios_GPU_dw() { // 0x46
+ int size;
+ s32 *ptr;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x46]);
+#endif
+
+ GPU_writeData(0xa0000000);
+ GPU_writeData((a1<<16)|(a0&0xffff));
+ GPU_writeData((a3<<16)|(a2&0xffff));
+ size = (a2*a3+1)/2;
+ ptr = (s32*)PSXM(Rsp[4]); //that is correct?
+ do {
+ GPU_writeData(SWAP32(*ptr));
+ ptr++;
+ } while(--size);
+
+ pc0 = ra;
+}
+
+void psxBios_mem2vram() { // 0x47
+ int size;
+
+ GPU_writeData(0xa0000000);
+ GPU_writeData((a1<<16)|(a0&0xffff));
+ GPU_writeData((a3<<16)|(a2&0xffff));
+ size = (a2*a3+1)/2;
+ GPU_writeStatus(0x04000002);
+ psxHwWrite32(0x1f8010f4,0);
+ psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800);
+ psxHwWrite32(0x1f8010a0,Rsp[4]);//might have a buggy...
+ psxHwWrite32(0x1f8010a4,((size/16)<<16)|16);
+ psxHwWrite32(0x1f8010a8,0x01000201);
+
+ pc0 = ra;
+}
+
+void psxBios_SendGPU() { // 0x48
+ GPU_writeStatus(a0);
+ pc0 = ra;
+}
+
+void psxBios_GPU_cw() { // 0x49
+ GPU_writeData(a0);
+ pc0 = ra;
+}
+
+void psxBios_GPU_cwb() { // 0x4a
+ s32 *ptr = (s32*)Ra0;
+ int size = a1;
+ while(size--) {
+ GPU_writeData(SWAP32(*ptr));
+ ptr++;
+ }
+
+ pc0 = ra;
+}
+
+void psxBios_GPU_SendPackets() { //4b:
+ GPU_writeStatus(0x04000002);
+ psxHwWrite32(0x1f8010f4,0);
+ psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800);
+ psxHwWrite32(0x1f8010a0,a0);
+ psxHwWrite32(0x1f8010a4,0);
+ psxHwWrite32(0x1f8010a8,0x010000401);
+ pc0 = ra;
+}
+
+void psxBios_sys_a0_4c() { // 0x4c GPU relate
+ psxHwWrite32(0x1f8010a8,0x00000401);
+ GPU_writeData(0x0400000);
+ GPU_writeData(0x0200000);
+ GPU_writeData(0x0100000);
+
+ pc0 = ra;
+}
+
+void psxBios_GPU_GetGPUStatus() { // 0x4d
+ v0 = GPU_readStatus();
+ pc0 = ra;
+}
+
+#undef s_addr
+
+void psxBios_LoadExec() { // 51
+ EXEC *header = (EXEC*)PSXM(0xf000);
+ u32 s_addr, s_size;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s: %x,%x\n", biosA0n[0x51], Ra0, a1, a2);
+#endif
+ s_addr = a1; s_size = a2;
+
+ a1 = 0xf000;
+ psxBios_Load();
+
+ header->S_addr = s_addr;
+ header->s_size = s_size;
+
+ a0 = 0xf000; a1 = 0; a2 = 0;
+ psxBios_Exec();
+}
+
+void psxBios__bu_init() { // 70
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x70]);
+#endif
+
+ DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+ DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+
+ pc0 = ra;
+}
+
+void psxBios__96_init() { // 71
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x71]);
+#endif
+
+ pc0 = ra;
+}
+
+void psxBios__96_remove() { // 72
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x72]);
+#endif
+
+ pc0 = ra;
+}
+
+void psxBios_SetMem() { // 9f
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x, %x\n", biosA0n[0x9f], a0, a1);
+#endif
+
+ u32 new = psxHu32(0x1060);
+ switch(a0) {
+ case 2:
+ psxHu32ref(0x1060) = SWAP32(new);
+ psxMu32ref(0x060) = a0;
+ SysPrintf("Change effective memory : %d MBytes\n",a0);
+ break;
+
+ case 8:
+ psxHu32ref(0x1060) = SWAP32(new | 0x300);
+ psxMu32ref(0x060) = a0;
+ SysPrintf("Change effective memory : %d MBytes\n",a0);
+
+ default:
+ SysPrintf("Effective memory must be 2/8 MBytes\n");
+ break;
+ }
+
+ pc0 = ra;
+}
+
+void psxBios__card_info() { // ab
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0);
+#endif
+
+// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+ DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios__card_load() { // ac
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xac], a0);
+#endif
+
+// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+ DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+
+ v0 = 1; pc0 = ra;
+}
+
+/* System calls B0 */
+
+void psxBios_SetRCnt() { // 02
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x02]);
+#endif
+
+ a0&= 0x3;
+ if (a0 != 3) {
+ u32 mode=0;
+
+ psxRcntWtarget(a0, a1);
+ if (a2&0x1000) mode|= 0x050; // Interrupt Mode
+ if (a2&0x0100) mode|= 0x008; // Count to 0xffff
+ if (a2&0x0010) mode|= 0x001; // Timer stop mode
+ if (a0 == 2) { if (a2&0x0001) mode|= 0x200; } // System Clock mode
+ else { if (a2&0x0001) mode|= 0x100; } // System Clock mode
+
+ psxRcntWmode(a0, mode);
+ }
+ pc0 = ra;
+}
+
+void psxBios_GetRCnt() { // 03
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x03]);
+#endif
+
+ a0&= 0x3;
+ if (a0 != 3) v0 = psxRcntRcount(a0);
+ else v0 = 0;
+ pc0 = ra;
+}
+
+void psxBios_StartRCnt() { // 04
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x04]);
+#endif
+
+ a0&= 0x3;
+ if (a0 != 3) psxHu32ref(0x1074)|= SWAP32((u32)((1<<(a0+4))));
+ else psxHu32ref(0x1074)|= SWAPu32(0x1);
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios_StopRCnt() { // 05
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x05]);
+#endif
+
+ a0&= 0x3;
+ if (a0 != 3) psxHu32ref(0x1074)&= SWAP32((u32)(~(1<<(a0+4))));
+ else psxHu32ref(0x1074)&= SWAPu32(~0x1);
+ pc0 = ra;
+}
+
+void psxBios_ResetRCnt() { // 06
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x06]);
+#endif
+
+ a0&= 0x3;
+ if (a0 != 3) {
+ psxRcntWmode(a0, 0);
+ psxRcntWtarget(a0, 0);
+ psxRcntWcount(a0, 0);
+ }
+ pc0 = ra;
+}
+
+
+/* gets ev for use with Event */
+#define GetEv() \
+ ev = (a0 >> 24) & 0xf; \
+ if (ev == 0xf) ev = 0x5; \
+ ev*= 32; \
+ ev+= a0&0x1f;
+
+/* gets spec for use with Event */
+#define GetSpec() \
+ spec = 0; \
+ switch (a1) { \
+ case 0x0301: spec = 16; break; \
+ case 0x0302: spec = 17; break; \
+ default: \
+ for (i=0; i<16; i++) if (a1 & (1 << i)) { spec = i; break; } \
+ break; \
+ }
+
+void psxBios_DeliverEvent() { // 07
+ int ev, spec;
+ int i;
+
+ GetEv();
+ GetSpec();
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x07], ev, spec);
+#endif
+
+ DeliverEvent(ev, spec);
+
+ pc0 = ra;
+}
+
+void psxBios_OpenEvent() { // 08
+ int ev, spec;
+ int i;
+
+ GetEv();
+ GetSpec();
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x (class:%x, spec:%x, mode:%x, func:%x)\n", biosB0n[0x08], ev, spec, a0, a1, a2, a3);
+#endif
+
+ Event[ev][spec].status = EvStWAIT;
+ Event[ev][spec].mode = a2;
+ Event[ev][spec].fhandler = a3;
+
+ v0 = ev | (spec << 8);
+ pc0 = ra;
+}
+
+void psxBios_CloseEvent() { // 09
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x09], ev, spec);
+#endif
+
+ Event[ev][spec].status = EvStUNUSED;
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios_WaitEvent() { // 0a
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0a], ev, spec);
+#endif
+
+ Event[ev][spec].status = EvStACTIVE;
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios_TestEvent() { // 0b
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+ if (Event[ev][spec].status == EvStALREADY) {
+ Event[ev][spec].status = EvStACTIVE; v0 = 1;
+ } else v0 = 0;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x: %x\n", biosB0n[0x0b], ev, spec, v0);
+#endif
+
+ pc0 = ra;
+}
+
+void psxBios_EnableEvent() { // 0c
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0c], ev, spec);
+#endif
+
+ Event[ev][spec].status = EvStACTIVE;
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios_DisableEvent() { // 0d
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0d], ev, spec);
+#endif
+
+ Event[ev][spec].status = EvStWAIT;
+
+ v0 = 1; pc0 = ra;
+}
+
+/*
+ * long OpenTh(long (*func)(), unsigned long sp, unsigned long gp);
+ */
+
+void psxBios_OpenTh() { // 0e
+ int th;
+
+ for (th=1; th<8; th++)
+ if (Thread[th].status == 0) break;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0e], th);
+#endif
+
+ Thread[th].status = 1;
+ Thread[th].func = a0;
+ Thread[th].reg[29] = a1;
+ Thread[th].reg[28] = a2;
+
+ v0 = th; pc0 = ra;
+}
+
+/*
+ * int CloseTh(long thread);
+ */
+
+void psxBios_CloseTh() { // 0f
+ int th = a0 & 0xff;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0f], th);
+#endif
+
+ if (Thread[th].status == 0) {
+ v0 = 0;
+ } else {
+ Thread[th].status = 0;
+ v0 = 1;
+ }
+
+ pc0 = ra;
+}
+
+/*
+ * int ChangeTh(long thread);
+ */
+
+void psxBios_ChangeTh() { // 10
+ int th = a0 & 0xff;
+
+#ifdef PSXBIOS_LOG
+// PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x10], th);
+#endif
+
+ if (Thread[th].status == 0 || CurThread == th) {
+ v0 = 0;
+
+ pc0 = ra;
+ } else {
+ v0 = 1;
+
+ if (Thread[CurThread].status == 2) {
+ Thread[CurThread].status = 1;
+ Thread[CurThread].func = ra;
+ memcpy(Thread[CurThread].reg, psxRegs.GPR.r, 32*4);
+ }
+
+ memcpy(psxRegs.GPR.r, Thread[th].reg, 32*4);
+ pc0 = Thread[th].func;
+ Thread[th].status = 2;
+ CurThread = th;
+ }
+}
+
+void psxBios_InitPAD() { // 0x12
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x12]);
+#endif
+
+ pad_buf1 = (char*)Ra0;
+ pad_buf1len = a1;
+ pad_buf2 = (char*)Ra2;
+ pad_buf2len = a3;
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios_StartPAD() { // 13
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x13]);
+#endif
+
+ psxHwWrite16(0x1f801074, (unsigned short)(psxHwRead16(0x1f801074) | 0x1));
+ psxRegs.CP0.n.Status |= 0x401;
+ pc0 = ra;
+}
+
+void psxBios_StopPAD() { // 14
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]);
+#endif
+
+ pad_buf1 = NULL;
+ pad_buf2 = NULL;
+ pc0 = ra;
+}
+
+void psxBios_PAD_init() { // 15
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x15]);
+#endif
+
+ psxHwWrite16(0x1f801074, (u16)(psxHwRead16(0x1f801074) | 0x1));
+ pad_buf = (int*)Ra1;
+ *pad_buf = -1;
+ psxRegs.CP0.n.Status |= 0x401;
+ pc0 = ra;
+}
+
+void psxBios_PAD_dr() { // 16
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x16]);
+#endif
+
+ v0 = -1; pc0 = ra;
+}
+
+void psxBios_ReturnFromException() { // 17
+ memcpy(psxRegs.GPR.r, regs, 32*4);
+ psxRegs.GPR.n.lo = regs[32];
+ psxRegs.GPR.n.hi = regs[33];
+
+ pc0 = psxRegs.CP0.n.EPC;
+ if (psxRegs.CP0.n.Cause & 0x80000000) pc0+=4;
+
+ psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
+ ((psxRegs.CP0.n.Status & 0x3c) >> 2);
+}
+
+void psxBios_ResetEntryInt() { // 18
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x18]);
+#endif
+
+ jmp_int = NULL;
+ pc0 = ra;
+}
+
+void psxBios_HookEntryInt() { // 19
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x19]);
+#endif
+
+ jmp_int = (u32*)Ra0;
+ pc0 = ra;
+}
+
+void psxBios_UnDeliverEvent() { // 0x20
+ int ev, spec;
+ int i;
+
+ GetEv();
+ GetSpec();
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x20], ev, spec);
+#endif
+
+ if (Event[ev][spec].status == EvStALREADY &&
+ Event[ev][spec].mode == EvMdNOINTR)
+ Event[ev][spec].status = EvStACTIVE;
+
+ pc0 = ra;
+}
+
+#define buopen(mcd) { \
+ strcpy(FDesc[1 + mcd].name, Ra0+5); \
+ FDesc[1 + mcd].offset = 0; \
+ FDesc[1 + mcd].mode = a1; \
+ \
+ for (i=1; i<16; i++) { \
+ ptr = Mcd##mcd##Data + 128 * i; \
+ if ((*ptr & 0xF0) != 0x50) continue; \
+ if (strcmp(FDesc[1 + mcd].name, ptr+0xa)) continue; \
+ FDesc[1 + mcd].mcfile = i; \
+ SysPrintf("open %s\n", ptr+0xa); \
+ v0 = 1 + mcd; \
+ break; \
+ } \
+ if (a1 & 0x200 && v0 == -1) { /* FCREAT */ \
+ for (i=1; i<16; i++) { \
+ int j, xor = 0; \
+ \
+ ptr = Mcd##mcd##Data + 128 * i; \
+ if ((*ptr & 0xF0) == 0x50) continue; \
+ ptr[0] = 0x50 | (u8)(a1 >> 16); \
+ ptr[4] = 0x00; \
+ ptr[5] = 0x20; \
+ ptr[6] = 0x00; \
+ ptr[7] = 0x00; \
+ ptr[8] = 'B'; \
+ ptr[9] = 'I'; \
+ strcpy(ptr+0xa, FDesc[1 + mcd].name); \
+ for (j=0; j<127; j++) xor^= ptr[j]; \
+ ptr[127] = xor; \
+ FDesc[1 + mcd].mcfile = i; \
+ SysPrintf("openC %s\n", ptr); \
+ v0 = 1 + mcd; \
+ SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, 128 * i, 128); \
+ break; \
+ } \
+ } \
+}
+
+/*
+ * int open(char *name , int mode);
+ */
+
+void psxBios_open() { // 0x32
+ int i;
+ char *ptr;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s,%x\n", biosB0n[0x32], Ra0, a1);
+#endif
+
+ v0 = -1;
+
+ if (!strncmp(Ra0, "bu00", 4)) {
+ buopen(1);
+ }
+
+ if (!strncmp(Ra0, "bu10", 4)) {
+ buopen(2);
+ }
+
+ pc0 = ra;
+}
+
+/*
+ * int lseek(int fd , int offset , int whence);
+ */
+
+void psxBios_lseek() { // 0x33
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosB0n[0x33], a0, a1, a2);
+#endif
+
+ switch (a2) {
+ case 0: // SEEK_SET
+ FDesc[a0].offset = a1;
+ v0 = a1;
+// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+ break;
+
+ case 1: // SEEK_CUR
+ FDesc[a0].offset+= a1;
+ v0 = FDesc[a0].offset;
+ break;
+ }
+
+ pc0 = ra;
+}
+
+#define buread(mcd) { \
+ SysPrintf("read %d: %x,%x (%s)\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2, Mcd##mcd##Data + 128 * FDesc[1 + mcd].mcfile + 0xa); \
+ ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
+ memcpy(Ra1, ptr, a2); \
+ if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \
+ else v0 = a2; \
+ DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
+ DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
+}
+
+/*
+ * int read(int fd , void *buf , int nbytes);
+ */
+
+void psxBios_read() { // 0x34
+ char *ptr;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosB0n[0x34], a0, a1, a2);
+#endif
+
+ v0 = -1;
+
+ switch (a0) {
+ case 2: buread(1); break;
+ case 3: buread(2); break;
+ }
+
+ pc0 = ra;
+}
+
+#define buwrite(mcd) { \
+ u32 offset = + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
+ SysPrintf("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \
+ ptr = Mcd##mcd##Data + offset; \
+ memcpy(ptr, Ra1, a2); \
+ SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, offset, a2); \
+ if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \
+ else v0 = a2; \
+ DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \
+ DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \
+}
+
+/*
+ * int write(int fd , void *buf , int nbytes);
+ */
+
+void psxBios_write() { // 0x35/0x03
+ char *ptr;
+
+ if (a0 == 1) { // stdout
+ char *ptr = Ra1;
+
+ while (a2 > 0) {
+ SysPrintf("%c", *ptr++); a2--;
+ }
+ pc0 = ra; return;
+ }
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
+#endif
+
+ v0 = -1;
+
+ switch (a0) {
+ case 2: buwrite(1); break;
+ case 3: buwrite(2); break;
+ }
+
+ pc0 = ra;
+}
+
+/*
+ * int close(int fd);
+ */
+
+void psxBios_close() { // 0x36
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x36], a0);
+#endif
+
+ v0 = a0;
+ pc0 = ra;
+}
+
+void psxBios_putchar() { // 3d
+ SysPrintf("%c", (char)a0);
+ pc0 = ra;
+}
+
+void psxBios_puts() { // 3e/3f
+ SysPrintf(Ra0);
+ pc0 = ra;
+}
+
+char ffile[64], *pfile;
+int nfile;
+
+#define bufile(mcd) { \
+ while (nfile < 16) { \
+ int match=1; \
+ \
+ ptr = Mcd##mcd##Data + 128 * nfile; \
+ nfile++; \
+ if ((*ptr & 0xF0) != 0x50) continue; \
+ ptr+= 0xa; \
+ for (i=0; i<20; i++) { \
+ if (pfile[i] == ptr[i]) { \
+ dir->name[i] = ptr[i]; \
+ if (ptr[i] == 0) break; else continue; } \
+ if (pfile[i] == '?') { \
+ dir->name[i] = ptr[i]; continue; } \
+ if (pfile[i] == '*') { \
+ strcpy(dir->name+i, ptr+i); break; } \
+ match = 0; break; \
+ } \
+ SysPrintf("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \
+ if (match == 0) continue; \
+ dir->size = 8192; \
+ v0 = _dir; \
+ break; \
+ } \
+}
+
+/*
+ * struct DIRENTRY* firstfile(char *name,struct DIRENTRY *dir);
+ */
+
+void psxBios_firstfile() { // 42
+ struct DIRENTRY *dir = (struct DIRENTRY *)Ra1;
+ u32 _dir = a1;
+ char *ptr;
+ int i;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x42], Ra0);
+#endif
+
+ v0 = 0;
+
+ strcpy(ffile, Ra0);
+ pfile = ffile+5;
+ nfile = 1;
+ if (!strncmp(Ra0, "bu00", 4)) {
+ bufile(1);
+ v0 = _dir;
+ }
+
+ if (!strncmp(Ra0, "bu10", 4)) {
+ bufile(2);
+ v0 = _dir;
+ }
+
+ pc0 = ra;
+}
+
+/*
+ * struct DIRENTRY* nextfile(struct DIRENTRY *dir);
+ */
+
+void psxBios_nextfile() { // 43
+ struct DIRENTRY *dir = (struct DIRENTRY *)Ra0;
+ u32 _dir = a0;
+ char *ptr;
+ int i;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x43], dir->name);
+#endif
+
+ v0 = 0;
+
+ if (!strncmp(ffile, "bu00", 4)) {
+ bufile(1);
+ }
+
+ if (!strncmp(ffile, "bu10", 4)) {
+ bufile(2);
+ }
+
+ pc0 = ra;
+}
+
+#define budelete(mcd) { \
+ for (i=1; i<16; i++) { \
+ ptr = Mcd##mcd##Data + 128 * i; \
+ if ((*ptr & 0xF0) != 0x50) continue; \
+ if (strcmp(Ra0+5, ptr+0xa)) continue; \
+ *ptr = (*ptr & 0xf) | 0xA0; \
+ SysPrintf("delete %s\n", ptr+0xa); \
+ v0 = 1; \
+ break; \
+ } \
+}
+
+/*
+ * int delete(char *name);
+ */
+
+void psxBios_delete() { // 45
+ char *ptr;
+ int i;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x45], Ra0);
+#endif
+
+ v0 = 0;
+
+ if (!strncmp(Ra0, "bu00", 4)) {
+ budelete(1);
+ }
+
+ if (!strncmp(Ra0, "bu10", 4)) {
+ budelete(2);
+ }
+
+ pc0 = ra;
+}
+
+void psxBios_InitCARD() { // 4a
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x4a], a0);
+#endif
+
+ CardState = 0;
+
+ pc0 = ra;
+}
+
+void psxBios_StartCARD() { // 4b
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4b]);
+#endif
+
+ if (CardState == 0) CardState = 1;
+
+ pc0 = ra;
+}
+
+void psxBios_StopCARD() { // 4c
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4c]);
+#endif
+
+ if (CardState == 1) CardState = 0;
+
+ pc0 = ra;
+}
+
+void psxBios__card_write() { // 0x4e
+ int port;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x4e], a0, a1, a2);
+#endif
+
+ port = a0 >> 4;
+
+ if (port == 0) {
+ memcpy(Mcd1Data + a1 * 128, Ra2, 128);
+ SaveMcd(Config.Mcd1, Mcd1Data, a1 * 128, 128);
+ } else {
+ memcpy(Mcd2Data + a1 * 128, Ra2, 128);
+ SaveMcd(Config.Mcd2, Mcd2Data, a1 * 128, 128);
+ }
+
+ DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios__card_read() { // 0x4f
+ int port;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x4f]);
+#endif
+
+ port = a0 >> 4;
+
+ if (port == 0) {
+ memcpy(Ra2, Mcd1Data + a1 * 128, 128);
+ } else {
+ memcpy(Ra2, Mcd2Data + a1 * 128, 128);
+ }
+
+ DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
+
+ v0 = 1; pc0 = ra;
+}
+
+void psxBios__new_card() { // 0x50
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x50]);
+#endif
+
+ pc0 = ra;
+}
+
+void psxBios_GetC0Table() { // 56
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x56]);
+#endif
+
+ v0 = 0x674; pc0 = ra;
+}
+
+void psxBios_GetB0Table() { // 57
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x57]);
+#endif
+
+ v0 = 0x874; pc0 = ra;
+}
+
+void psxBios_ChangeClearPad() { // 5b
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5b], a0);
+#endif
+
+ pc0 = ra;
+}
+
+/* System calls C0 */
+
+/*
+ * int SysEnqIntRP(int index , long *queue);
+ */
+
+void psxBios_SysEnqIntRP() { // 02
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosC0n[0x02] ,a0);
+#endif
+
+ SysIntRP[a0] = a1;
+
+ v0 = 0; pc0 = ra;
+}
+
+/*
+ * int SysDeqIntRP(int index , long *queue);
+ */
+
+void psxBios_SysDeqIntRP() { // 03
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x\n", biosC0n[0x03], a0);
+#endif
+
+ SysIntRP[a0] = 0;
+
+ v0 = 0; pc0 = ra;
+}
+
+void psxBios_ChangeClearRCnt() { // 0a
+ u32 *ptr;
+
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("psxBios_%s: %x, %x\n", biosC0n[0x0a], a0, a1);
+#endif
+
+ ptr = (u32*)PSXM((a0 << 2) + 0x8600);
+ v0 = *ptr;
+ *ptr = a1;
+
+// psxRegs.CP0.n.Status|= 0x404;
+ pc0 = ra;
+}
+
+void psxBios_dummy() {
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("unk %lx call: %lx\n", pc0 & 0x1fffff, t1);
+#endif
+ pc0 = ra;
+}
+
+void (*biosA0[256])();
+void (*biosB0[256])();
+void (*biosC0[256])();
+
+void psxBiosInit() {
+ u32 base, size;
+ u32 *ptr;
+ int i;
+
+ for(i = 0; i < 256; i++) {
+ biosA0[i] = NULL;
+ biosB0[i] = NULL;
+ biosC0[i] = NULL;
+ }
+ biosA0[0x3e] = psxBios_puts;
+ biosA0[0x3f] = psxBios_printf;
+
+ biosB0[0x3d] = psxBios_putchar;
+ biosB0[0x3f] = psxBios_puts;
+
+ if (!Config.HLE) return;
+
+ for(i = 0; i < 256; i++) {
+ if (biosA0[i] == NULL) biosA0[i] = psxBios_dummy;
+ if (biosB0[i] == NULL) biosB0[i] = psxBios_dummy;
+ if (biosC0[i] == NULL) biosC0[i] = psxBios_dummy;
+ }
+
+ biosA0[0x00] = psxBios_open;
+ biosA0[0x01] = psxBios_lseek;
+ biosA0[0x02] = psxBios_read;
+ biosA0[0x03] = psxBios_write;
+ biosA0[0x04] = psxBios_close;
+ //biosA0[0x05] = psxBios_ioctl;
+ //biosA0[0x06] = psxBios_exit;
+ //biosA0[0x07] = psxBios_sys_a0_07;
+ //biosA0[0x08] = psxBios_getc;
+ //biosA0[0x09] = psxBios_putc;
+ //biosA0[0x0a] = psxBios_todigit;
+ //biosA0[0x0b] = psxBios_atof;
+ //biosA0[0x0c] = psxBios_strtoul;
+ //biosA0[0x0d] = psxBios_strtol;
+ biosA0[0x0e] = psxBios_abs;
+ biosA0[0x0f] = psxBios_labs;
+ biosA0[0x10] = psxBios_atoi;
+ biosA0[0x11] = psxBios_atol;
+ //biosA0[0x12] = psxBios_atob;
+ biosA0[0x13] = psxBios_setjmp;
+ biosA0[0x14] = psxBios_longjmp;
+ biosA0[0x15] = psxBios_strcat;
+ biosA0[0x16] = psxBios_strncat;
+ biosA0[0x17] = psxBios_strcmp;
+ biosA0[0x18] = psxBios_strncmp;
+ biosA0[0x19] = psxBios_strcpy;
+ biosA0[0x1a] = psxBios_strncpy;
+ biosA0[0x1b] = psxBios_strlen;
+ biosA0[0x1c] = psxBios_index;
+ biosA0[0x1d] = psxBios_rindex;
+ biosA0[0x1e] = psxBios_strchr;
+ biosA0[0x1f] = psxBios_strrchr;
+ biosA0[0x20] = psxBios_strpbrk;
+ biosA0[0x21] = psxBios_strspn;
+ biosA0[0x22] = psxBios_strcspn;
+ biosA0[0x23] = psxBios_strtok;
+ biosA0[0x24] = psxBios_strstr;
+ biosA0[0x25] = psxBios_toupper;
+ biosA0[0x26] = psxBios_tolower;
+ biosA0[0x27] = psxBios_bcopy;
+ biosA0[0x28] = psxBios_bzero;
+ biosA0[0x29] = psxBios_bcmp;
+ biosA0[0x2a] = psxBios_memcpy;
+ biosA0[0x2b] = psxBios_memset;
+ biosA0[0x2c] = psxBios_memmove;
+ biosA0[0x2d] = psxBios_memcmp;
+ biosA0[0x2e] = psxBios_memchr;
+ biosA0[0x2f] = psxBios_rand;
+ biosA0[0x30] = psxBios_srand;
+ //biosA0[0x31] = psxBios_qsort;
+ //biosA0[0x32] = psxBios_strtod;
+ biosA0[0x33] = psxBios_malloc;
+ biosA0[0x34] = psxBios_free;
+ //biosA0[0x35] = psxBios_lsearch;
+ //biosA0[0x36] = psxBios_bsearch;
+ biosA0[0x37] = psxBios_calloc;
+ biosA0[0x38] = psxBios_realloc;
+ biosA0[0x39] = psxBios_InitHeap;
+ //biosA0[0x3a] = psxBios__exit;
+ biosA0[0x3b] = psxBios_getchar;
+ biosA0[0x3c] = psxBios_putchar;
+ //biosA0[0x3d] = psxBios_gets;
+ //biosA0[0x40] = psxBios_sys_a0_40;
+ //biosA0[0x41] = psxBios_LoadTest;
+ biosA0[0x42] = psxBios_Load;
+ biosA0[0x43] = psxBios_Exec;
+ biosA0[0x44] = psxBios_FlushCache;
+ //biosA0[0x45] = psxBios_InstallInterruptHandler;
+ biosA0[0x46] = psxBios_GPU_dw;
+ biosA0[0x47] = psxBios_mem2vram;
+ biosA0[0x48] = psxBios_SendGPU;
+ biosA0[0x49] = psxBios_GPU_cw;
+ biosA0[0x4a] = psxBios_GPU_cwb;
+ biosA0[0x4b] = psxBios_GPU_SendPackets;
+ biosA0[0x4c] = psxBios_sys_a0_4c;
+ biosA0[0x4d] = psxBios_GPU_GetGPUStatus;
+ //biosA0[0x4e] = psxBios_GPU_sync;
+ //biosA0[0x4f] = psxBios_sys_a0_4f;
+ //biosA0[0x50] = psxBios_sys_a0_50;
+ biosA0[0x51] = psxBios_LoadExec;
+ //biosA0[0x52] = psxBios_GetSysSp;
+ //biosA0[0x53] = psxBios_sys_a0_53;
+ //biosA0[0x54] = psxBios__96_init_a54;
+ //biosA0[0x55] = psxBios__bu_init_a55;
+ //biosA0[0x56] = psxBios__96_remove_a56;
+ //biosA0[0x57] = psxBios_sys_a0_57;
+ //biosA0[0x58] = psxBios_sys_a0_58;
+ //biosA0[0x59] = psxBios_sys_a0_59;
+ //biosA0[0x5a] = psxBios_sys_a0_5a;
+ //biosA0[0x5b] = psxBios_dev_tty_init;
+ //biosA0[0x5c] = psxBios_dev_tty_open;
+ //biosA0[0x5d] = psxBios_sys_a0_5d;
+ //biosA0[0x5e] = psxBios_dev_tty_ioctl;
+ //biosA0[0x5f] = psxBios_dev_cd_open;
+ //biosA0[0x60] = psxBios_dev_cd_read;
+ //biosA0[0x61] = psxBios_dev_cd_close;
+ //biosA0[0x62] = psxBios_dev_cd_firstfile;
+ //biosA0[0x63] = psxBios_dev_cd_nextfile;
+ //biosA0[0x64] = psxBios_dev_cd_chdir;
+ //biosA0[0x65] = psxBios_dev_card_open;
+ //biosA0[0x66] = psxBios_dev_card_read;
+ //biosA0[0x67] = psxBios_dev_card_write;
+ //biosA0[0x68] = psxBios_dev_card_close;
+ //biosA0[0x69] = psxBios_dev_card_firstfile;
+ //biosA0[0x6a] = psxBios_dev_card_nextfile;
+ //biosA0[0x6b] = psxBios_dev_card_erase;
+ //biosA0[0x6c] = psxBios_dev_card_undelete;
+ //biosA0[0x6d] = psxBios_dev_card_format;
+ //biosA0[0x6e] = psxBios_dev_card_rename;
+ //biosA0[0x6f] = psxBios_dev_card_6f;
+ biosA0[0x70] = psxBios__bu_init;
+ biosA0[0x71] = psxBios__96_init;
+ biosA0[0x72] = psxBios__96_remove;
+ //biosA0[0x73] = psxBios_sys_a0_73;
+ //biosA0[0x74] = psxBios_sys_a0_74;
+ //biosA0[0x75] = psxBios_sys_a0_75;
+ //biosA0[0x76] = psxBios_sys_a0_76;
+ //biosA0[0x77] = psxBios_sys_a0_77;
+ //biosA0[0x78] = psxBios__96_CdSeekL;
+ //biosA0[0x79] = psxBios_sys_a0_79;
+ //biosA0[0x7a] = psxBios_sys_a0_7a;
+ //biosA0[0x7b] = psxBios_sys_a0_7b;
+ //biosA0[0x7c] = psxBios__96_CdGetStatus;
+ //biosA0[0x7d] = psxBios_sys_a0_7d;
+ //biosA0[0x7e] = psxBios__96_CdRead;
+ //biosA0[0x7f] = psxBios_sys_a0_7f;
+ //biosA0[0x80] = psxBios_sys_a0_80;
+ //biosA0[0x81] = psxBios_sys_a0_81;
+ //biosA0[0x82] = psxBios_sys_a0_82;
+ //biosA0[0x83] = psxBios_sys_a0_83;
+ //biosA0[0x84] = psxBios_sys_a0_84;
+ //biosA0[0x85] = psxBios__96_CdStop;
+ //biosA0[0x86] = psxBios_sys_a0_86;
+ //biosA0[0x87] = psxBios_sys_a0_87;
+ //biosA0[0x88] = psxBios_sys_a0_88;
+ //biosA0[0x89] = psxBios_sys_a0_89;
+ //biosA0[0x8a] = psxBios_sys_a0_8a;
+ //biosA0[0x8b] = psxBios_sys_a0_8b;
+ //biosA0[0x8c] = psxBios_sys_a0_8c;
+ //biosA0[0x8d] = psxBios_sys_a0_8d;
+ //biosA0[0x8e] = psxBios_sys_a0_8e;
+ //biosA0[0x8f] = psxBios_sys_a0_8f;
+ //biosA0[0x90] = psxBios_sys_a0_90;
+ //biosA0[0x91] = psxBios_sys_a0_91;
+ //biosA0[0x92] = psxBios_sys_a0_92;
+ //biosA0[0x93] = psxBios_sys_a0_93;
+ //biosA0[0x94] = psxBios_sys_a0_94;
+ //biosA0[0x95] = psxBios_sys_a0_95;
+ //biosA0[0x96] = psxBios_AddCDROMDevice;
+ //biosA0[0x97] = psxBios_AddMemCardDevide;
+ //biosA0[0x98] = psxBios_DisableKernelIORedirection;
+ //biosA0[0x99] = psxBios_EnableKernelIORedirection;
+ //biosA0[0x9a] = psxBios_sys_a0_9a;
+ //biosA0[0x9b] = psxBios_sys_a0_9b;
+ //biosA0[0x9c] = psxBios_SetConf;
+ //biosA0[0x9d] = psxBios_GetConf;
+ //biosA0[0x9e] = psxBios_sys_a0_9e;
+ biosA0[0x9f] = psxBios_SetMem;
+ //biosA0[0xa0] = psxBios__boot;
+ //biosA0[0xa1] = psxBios_SystemError;
+ //biosA0[0xa2] = psxBios_EnqueueCdIntr;
+ //biosA0[0xa3] = psxBios_DequeueCdIntr;
+ //biosA0[0xa4] = psxBios_sys_a0_a4;
+ //biosA0[0xa5] = psxBios_ReadSector;
+ //biosA0[0xa6] = psxBios_get_cd_status;
+ //biosA0[0xa7] = psxBios_bufs_cb_0;
+ //biosA0[0xa8] = psxBios_bufs_cb_1;
+ //biosA0[0xa9] = psxBios_bufs_cb_2;
+ //biosA0[0xaa] = psxBios_bufs_cb_3;
+ biosA0[0xab] = psxBios__card_info;
+ biosA0[0xac] = psxBios__card_load;
+ //biosA0[0axd] = psxBios__card_auto;
+ //biosA0[0xae] = psxBios_bufs_cd_4;
+ //biosA0[0xaf] = psxBios_sys_a0_af;
+ //biosA0[0xb0] = psxBios_sys_a0_b0;
+ //biosA0[0xb1] = psxBios_sys_a0_b1;
+ //biosA0[0xb2] = psxBios_do_a_long_jmp
+ //biosA0[0xb3] = psxBios_sys_a0_b3;
+ //biosA0[0xb4] = psxBios_sub_function;
+//*******************B0 CALLS****************************
+ //biosB0[0x00] = psxBios_SysMalloc;
+ //biosB0[0x01] = psxBios_sys_b0_01;
+ biosB0[0x02] = psxBios_SetRCnt;
+ biosB0[0x03] = psxBios_GetRCnt;
+ biosB0[0x04] = psxBios_StartRCnt;
+ biosB0[0x05] = psxBios_StopRCnt;
+ biosB0[0x06] = psxBios_ResetRCnt;
+ biosB0[0x07] = psxBios_DeliverEvent;
+ biosB0[0x08] = psxBios_OpenEvent;
+ biosB0[0x09] = psxBios_CloseEvent;
+ biosB0[0x0a] = psxBios_WaitEvent;
+ biosB0[0x0b] = psxBios_TestEvent;
+ biosB0[0x0c] = psxBios_EnableEvent;
+ biosB0[0x0d] = psxBios_DisableEvent;
+ biosB0[0x0e] = psxBios_OpenTh;
+ biosB0[0x0f] = psxBios_CloseTh;
+ biosB0[0x10] = psxBios_ChangeTh;
+ //biosB0[0x11] = psxBios_psxBios_b0_11;
+ biosB0[0x12] = psxBios_InitPAD;
+ biosB0[0x13] = psxBios_StartPAD;
+ biosB0[0x14] = psxBios_StopPAD;
+ biosB0[0x15] = psxBios_PAD_init;
+ biosB0[0x16] = psxBios_PAD_dr;
+ biosB0[0x17] = psxBios_ReturnFromException;
+ biosB0[0x18] = psxBios_ResetEntryInt;
+ biosB0[0x19] = psxBios_HookEntryInt;
+ //biosB0[0x1a] = psxBios_sys_b0_1a;
+ //biosB0[0x1b] = psxBios_sys_b0_1b;
+ //biosB0[0x1c] = psxBios_sys_b0_1c;
+ //biosB0[0x1d] = psxBios_sys_b0_1d;
+ //biosB0[0x1e] = psxBios_sys_b0_1e;
+ //biosB0[0x1f] = psxBios_sys_b0_1f;
+ biosB0[0x20] = psxBios_UnDeliverEvent;
+ //biosB0[0x21] = psxBios_sys_b0_21;
+ //biosB0[0x22] = psxBios_sys_b0_22;
+ //biosB0[0x23] = psxBios_sys_b0_23;
+ //biosB0[0x24] = psxBios_sys_b0_24;
+ //biosB0[0x25] = psxBios_sys_b0_25;
+ //biosB0[0x26] = psxBios_sys_b0_26;
+ //biosB0[0x27] = psxBios_sys_b0_27;
+ //biosB0[0x28] = psxBios_sys_b0_28;
+ //biosB0[0x29] = psxBios_sys_b0_29;
+ //biosB0[0x2a] = psxBios_sys_b0_2a;
+ //biosB0[0x2b] = psxBios_sys_b0_2b;
+ //biosB0[0x2c] = psxBios_sys_b0_2c;
+ //biosB0[0x2d] = psxBios_sys_b0_2d;
+ //biosB0[0x2e] = psxBios_sys_b0_2e;
+ //biosB0[0x2f] = psxBios_sys_b0_2f;
+ //biosB0[0x30] = psxBios_sys_b0_30;
+ //biosB0[0x31] = psxBios_sys_b0_31;
+ biosB0[0x32] = psxBios_open;
+ biosB0[0x33] = psxBios_lseek;
+ biosB0[0x34] = psxBios_read;
+ biosB0[0x35] = psxBios_write;
+ biosB0[0x36] = psxBios_close;
+ //biosB0[0x37] = psxBios_ioctl;
+ //biosB0[0x38] = psxBios_exit;
+ //biosB0[0x39] = psxBios_sys_b0_39;
+ //biosB0[0x3a] = psxBios_getc;
+ //biosB0[0x3b] = psxBios_putc;
+ biosB0[0x3c] = psxBios_getchar;
+ //biosB0[0x3e] = psxBios_gets;
+ //biosB0[0x40] = psxBios_cd;
+ //biosB0[0x41] = psxBios_format;
+ biosB0[0x42] = psxBios_firstfile;
+ biosB0[0x43] = psxBios_nextfile;
+ //biosB0[0x44] = psxBios_rename;
+ biosB0[0x45] = psxBios_delete;
+ //biosB0[0x46] = psxBios_undelete;
+ //biosB0[0x47] = psxBios_AddDevice;
+ //biosB0[0x48] = psxBios_RemoteDevice;
+ //biosB0[0x49] = psxBios_PrintInstalledDevices;
+ biosB0[0x4a] = psxBios_InitCARD;
+ biosB0[0x4b] = psxBios_StartCARD;
+ biosB0[0x4c] = psxBios_StopCARD;
+ //biosB0[0x4d] = psxBios_sys_b0_4d;
+ biosB0[0x4e] = psxBios__card_write;
+ biosB0[0x4f] = psxBios__card_read;
+ biosB0[0x50] = psxBios__new_card;
+ //biosB0[0x51] = psxBios_Krom2RawAdd;
+ //biosB0[0x52] = psxBios_sys_b0_52;
+ //biosB0[0x53] = psxBios_sys_b0_53;
+ //biosB0[0x54] = psxBios__get_errno;
+ //biosB0[0x55] = psxBios__get_error;
+ biosB0[0x56] = psxBios_GetC0Table;
+ biosB0[0x57] = psxBios_GetB0Table;
+ //biosB0[0x58] = psxBios__card_chan;
+ //biosB0[0x59] = psxBios_sys_b0_59;
+ //biosB0[0x5a] = psxBios_sys_b0_5a;
+ biosB0[0x5b] = psxBios_ChangeClearPad;
+ //biosB0[0x5c] = psxBios__card_status;
+ //biosB0[0x5d] = psxBios__card_wait;
+//*******************C0 CALLS****************************
+ //biosC0[0x00] = psxBios_InitRCnt;
+ //biosC0[0x01] = psxBios_InitException;
+ biosC0[0x02] = psxBios_SysEnqIntRP;
+ biosC0[0x03] = psxBios_SysDeqIntRP;
+ //biosC0[0x04] = psxBios_get_free_EvCB_slot;
+ //biosC0[0x05] = psxBios_get_free_TCB_slot;
+ //biosC0[0x06] = psxBios_ExceptionHandler;
+ //biosC0[0x07] = psxBios_InstallExeptionHandler;
+ //biosC0[0x08] = psxBios_SysInitMemory;
+ //biosC0[0x09] = psxBios_SysInitKMem;
+ biosC0[0x0a] = psxBios_ChangeClearRCnt;
+ //biosC0[0x0b] = psxBios_SystemError;
+ //biosC0[0x0c] = psxBios_InitDefInt;
+ //biosC0[0x0d] = psxBios_sys_c0_0d;
+ //biosC0[0x0e] = psxBios_sys_c0_0e;
+ //biosC0[0x0f] = psxBios_sys_c0_0f;
+ //biosC0[0x10] = psxBios_sys_c0_10;
+ //biosC0[0x11] = psxBios_sys_c0_11;
+ //biosC0[0x12] = psxBios_InstallDevices;
+ //biosC0[0x13] = psxBios_FlushStfInOutPut;
+ //biosC0[0x14] = psxBios_sys_c0_14;
+ //biosC0[0x15] = psxBios__cdevinput;
+ //biosC0[0x16] = psxBios__cdevscan;
+ //biosC0[0x17] = psxBios__circgetc;
+ //biosC0[0x18] = psxBios__circputc;
+ //biosC0[0x19] = psxBios_ioabort;
+ //biosC0[0x1a] = psxBios_sys_c0_1a
+ //biosC0[0x1b] = psxBios_KernelRedirect;
+ //biosC0[0x1c] = psxBios_PatchAOTable;
+//************** THE END ***************************************
+/**/
+ base = 0x1000;
+ size = sizeof(EvCB) * 32;
+ Event = (void *)&psxR[base]; base+= size*6;
+ memset(Event, 0, size * 6);
+ HwEV = Event;
+ EvEV = Event + 32;
+ RcEV = Event + 32*2;
+ UeEV = Event + 32*3;
+ SwEV = Event + 32*4;
+ ThEV = Event + 32*5;
+
+ ptr = (u32*)&psxM[0x0874]; // b0 table
+ ptr[0] = SWAPu32(0x4c54 - 0x884);
+
+ ptr = (u32*)&psxM[0x0674]; // c0 table
+ ptr[6] = SWAPu32(0xc80);
+
+ memset(SysIntRP, 0, sizeof(SysIntRP));
+ memset(Thread, 0, sizeof(Thread));
+ Thread[0].status = 2; // main thread
+
+ psxMu32ref(0x0150) = SWAPu32(0x160);
+ psxMu32ref(0x0154) = SWAPu32(0x320);
+ psxMu32ref(0x0160) = SWAPu32(0x248);
+ strcpy(&psxM[0x248], "bu");
+/* psxMu32ref(0x0ca8) = SWAPu32(0x1f410004);
+ psxMu32ref(0x0cf0) = SWAPu32(0x3c020000);
+ psxMu32ref(0x0cf4) = SWAPu32(0x2442641c);
+ psxMu32ref(0x09e0) = SWAPu32(0x43d0);
+ psxMu32ref(0x4d98) = SWAPu32(0x946f000a);
+*/
+ // opcode HLE
+ psxRu32ref(0x0000) = SWAPu32((0x3b << 26) | 4);
+ psxMu32ref(0x0000) = SWAPu32((0x3b << 26) | 0);
+ psxMu32ref(0x00a0) = SWAPu32((0x3b << 26) | 1);
+ psxMu32ref(0x00b0) = SWAPu32((0x3b << 26) | 2);
+ psxMu32ref(0x00c0) = SWAPu32((0x3b << 26) | 3);
+ psxMu32ref(0x4c54) = SWAPu32((0x3b << 26) | 0);
+ psxMu32ref(0x8000) = SWAPu32((0x3b << 26) | 5);
+ psxMu32ref(0x07a0) = SWAPu32((0x3b << 26) | 0);
+ psxMu32ref(0x0884) = SWAPu32((0x3b << 26) | 0);
+ psxMu32ref(0x0894) = SWAPu32((0x3b << 26) | 0);
+
+ // memory size 2 MB
+ psxHu32ref(0x1060) = SWAPu32(0x00000b88);
+}
+
+void psxBiosShutdown() {
+}
+
+__inline void SaveRegs() {
+ memcpy(regs, psxRegs.GPR.r, 32*4);
+ regs[32] = psxRegs.GPR.n.lo;
+ regs[33] = psxRegs.GPR.n.hi;
+ regs[34] = psxRegs.pc;
+}
+
+__inline void LoadRegs() {
+ memcpy(psxRegs.GPR.r, regs, 32*4);
+ psxRegs.GPR.n.lo = regs[32];
+ psxRegs.GPR.n.hi = regs[33];
+}
+
+
+#define psxBios_PADpoll(pad) { \
+ PAD##pad##_startPoll(pad); \
+ pad_buf##pad[0] = 0; \
+ pad_buf##pad[1] = PAD##pad##_poll(0x42); \
+ if (!(pad_buf##pad[1] & 0x0f)) { \
+ bufcount = 32; \
+ } else { \
+ bufcount = (pad_buf##pad[1] & 0x0f) * 2; \
+ } \
+ PAD##pad##_poll(0); \
+ i = 2; \
+ while (bufcount--) { \
+ pad_buf##pad[i++] = PAD##pad##_poll(0); \
+ } \
+}
+
+void netError();
+
+void biosInterrupt() {
+ int i, bufcount;
+
+// if (psxHu32(0x1070) & 0x1) { // Vsync
+ if (pad_buf) {
+ u32 *buf = (u32*)pad_buf;
+
+ if (!Config.UseNet) {
+ PAD1_startPoll(1);
+ if (PAD1_poll(0x42) == 0x23) {
+ PAD1_poll(0);
+ *buf = PAD1_poll(0) << 8;
+ *buf|= PAD1_poll(0);
+ PAD1_poll(0);
+ *buf&= ~((PAD1_poll(0)>0x20)?1<<6:0);
+ *buf&= ~((PAD1_poll(0)>0x20)?1<<7:0);
+ } else {
+ PAD1_poll(0);
+ *buf = PAD1_poll(0) << 8;
+ *buf|= PAD1_poll(0);
+ }
+
+ PAD2_startPoll(2);
+ if (PAD2_poll(0x42) == 0x23) {
+ PAD2_poll(0);
+ *buf|= PAD2_poll(0) << 24;
+ *buf|= PAD2_poll(0) << 16;
+ PAD2_poll(0);
+ *buf&= ~((PAD2_poll(0)>0x20)?1<<22:0);
+ *buf&= ~((PAD2_poll(0)>0x20)?1<<23:0);
+ } else {
+ PAD2_poll(0);
+ *buf|= PAD2_poll(0) << 24;
+ *buf|= PAD2_poll(0) << 16;
+ }
+ } else {
+ u16 data;
+
+ PAD1_startPoll(1);
+ PAD1_poll(0x42);
+ PAD1_poll(0);
+ data = PAD1_poll(0) << 8;
+ data|= PAD1_poll(0);
+
+ if (NET_sendPadData(&data, 2) == -1)
+ netError();
+
+ if (NET_recvPadData(&((u16*)buf)[0], 1) == -1)
+ netError();
+ if (NET_recvPadData(&((u16*)buf)[1], 2) == -1)
+ netError();
+ }
+
+ }
+ if (Config.UseNet && pad_buf1 && pad_buf2) {
+ psxBios_PADpoll(1);
+
+ if (NET_sendPadData(pad_buf1, i) == -1)
+ netError();
+
+ if (NET_recvPadData(pad_buf1, 1) == -1)
+ netError();
+ if (NET_recvPadData(pad_buf2, 2) == -1)
+ netError();
+ } else {
+ if (pad_buf1) {
+ psxBios_PADpoll(1);
+ }
+
+ if (pad_buf2) {
+ psxBios_PADpoll(2);
+ }
+ }
+
+ if (psxHu32(0x1070) & 0x1) { // Vsync
+ if (RcEV[3][1].status == EvStACTIVE) {
+ softCall(RcEV[3][1].fhandler);
+// hwWrite32(0x1f801070, ~(1));
+ }
+ }
+
+ if (psxHu32(0x1070) & 0x70) { // Rcnt 0,1,2
+ int i;
+
+ for (i=0; i<3; i++) {
+ if (psxHu32(0x1070) & (1 << (i+4))) {
+ if (RcEV[i][1].status == EvStACTIVE) {
+ softCall(RcEV[i][1].fhandler);
+ }
+ psxHwWrite32(0x1f801070, ~(1 << (i+4)));
+ }
+ }
+ }
+}
+
+void psxBiosException() {
+ int i;
+
+ switch (psxRegs.CP0.n.Cause & 0x3c) {
+ case 0x00: // Interrupt
+#ifdef PSXCPU_LOG
+// PSXCPU_LOG("interrupt\n");
+#endif
+ SaveRegs();
+
+ biosInterrupt();
+
+ for (i=0; i<8; i++) {
+ if (SysIntRP[i]) {
+ u32 *queue = (u32*)PSXM(SysIntRP[i]);
+
+ s0 = queue[2];
+ softCall(queue[1]);
+ }
+ }
+
+ if (jmp_int != NULL) {
+ int i;
+
+ psxHwWrite32(0x1f801070, 0xffffffff);
+
+ ra = jmp_int[0];
+ sp = jmp_int[1];
+ fp = jmp_int[2];
+ for (i=0; i<8; i++) // s0-s7
+ psxRegs.GPR.r[16+i] = jmp_int[3+i];
+ gp = jmp_int[11];
+
+ v0 = 1;
+ pc0 = ra;
+ return;
+ }
+ psxHwWrite16(0x1f801070, 0);
+ break;
+
+ case 0x20: // Syscall
+#ifdef PSXCPU_LOG
+ PSXCPU_LOG("syscall exp %x\n", a0);
+#endif
+ switch (a0) {
+ case 1: // EnterCritical - disable irq's
+ psxRegs.CP0.n.Status&=~0x404;
+v0=1; // HDHOSHY experimental patch: Spongebob, Coldblood, fearEffect, Medievil2, Martian Gothic
+ break;
+
+ case 2: // ExitCritical - enable irq's
+ psxRegs.CP0.n.Status|= 0x404;
+ break;
+ }
+ pc0 = psxRegs.CP0.n.EPC + 4;
+
+ psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
+ ((psxRegs.CP0.n.Status & 0x3c) >> 2);
+ return;
+
+ default:
+#ifdef PSXCPU_LOG
+ PSXCPU_LOG("unknown bios exception!\n");
+#endif
+ break;
+ }
+
+ pc0 = psxRegs.CP0.n.EPC;
+ if (psxRegs.CP0.n.Cause & 0x80000000) pc0+=4;
+
+ psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
+ ((psxRegs.CP0.n.Status & 0x3c) >> 2);
+}
+
+#define bfreeze(ptr, size) \
+ if (Mode == 1) memcpy(&psxR[base], ptr, size); \
+ if (Mode == 0) memcpy(ptr, &psxR[base], size); \
+ base+=size;
+
+#define bfreezes(ptr) bfreeze(ptr, sizeof(ptr))
+#define bfreezel(ptr) bfreeze(ptr, sizeof(*ptr))
+//#define bfreezel(ptr) bfreeze(ptr, sizeof(uintptr_t))
+
+#define bfreezepsxMptr(ptr) \
+ if (Mode == 1) { \
+ if (ptr) psxRu32ref(base) = SWAPu32((uintptr_t)ptr - (uintptr_t)psxM); \
+ else psxRu32ref(base) = 0; \
+ } else { \
+ if (psxRu32(base)) *(u8**)&ptr = (u8*)(psxM + psxRu32(base)); \
+ else ptr = NULL; \
+ } \
+ base += sizeof(uintptr_t);
+
+void psxBiosFreeze(int Mode) {
+ u32 base = 0x40000;
+
+ bfreezepsxMptr(jmp_int);
+ bfreezepsxMptr(pad_buf);
+ bfreezepsxMptr(pad_buf1);
+ bfreezepsxMptr(pad_buf2);
+ bfreezepsxMptr(heap_addr);
+ bfreezel(&pad_buf1len);
+ bfreezel(&pad_buf2len);
+ bfreezes(regs);
+ bfreezes(SysIntRP);
+ bfreezel(&CardState);
+ bfreezes(Thread);
+ bfreezel(&CurThread);
+ bfreezes(FDesc);
+}
+
+
+
diff --git a/libpcsxcore/psxbios.h b/libpcsxcore/psxbios.h
new file mode 100644
index 00000000..86d22663
--- /dev/null
+++ b/libpcsxcore/psxbios.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PSXBIOS_H__
+#define __PSXBIOS_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxmem.h"
+#include "misc.h"
+#include "sio.h"
+
+extern char *biosA0n[256];
+extern char *biosB0n[256];
+extern char *biosC0n[256];
+
+void psxBiosInit();
+void psxBiosShutdown();
+void psxBiosException();
+void psxBiosFreeze(int Mode);
+
+extern void (*biosA0[256])();
+extern void (*biosB0[256])();
+extern void (*biosC0[256])();
+
+#endif /* __PSXBIOS_H__ */
diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h
new file mode 100644
index 00000000..c3f21ffe
--- /dev/null
+++ b/libpcsxcore/psxcommon.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* This file contains common definitions and includes for all parts of the
+* emulator core.
+*/
+
+#ifndef __PSXCOMMON_H__
+#define __PSXCOMMON_H__
+
+#include "config.h"
+
+/* System includes */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <zlib.h>
+
+/* Define types */
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+typedef intptr_t sptr;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uintptr_t uptr;
+
+/* Local includes */
+#include "system.h"
+#include "debug.h"
+
+/* Ryan TODO WTF is this? */
+#if defined (__LINUX__) || defined (__MACOSX__)
+#define strnicmp strncasecmp
+#endif
+#define __inline inline
+
+/* Enables NLS/internationalization if active */
+#ifdef ENABLE_NLS
+
+#include <libintl.h>
+
+#undef _
+#define _(String) gettext(String)
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+# define N_(String) (String)
+#endif
+
+#else
+
+#define _(msgid) msgid
+#define N_(msgid) msgid
+
+#endif
+
+extern int Log;
+void __Log(char *fmt, ...);
+
+typedef struct {
+ char Gpu[256];
+ char Spu[256];
+ char Cdr[256];
+ char Pad1[256];
+ char Pad2[256];
+ char Net[256];
+ char Mcd1[256];
+ char Mcd2[256];
+ char Bios[256];
+ char BiosDir[MAXPATHLEN];
+ char PluginsDir[MAXPATHLEN];
+ long Xa;
+ long Sio;
+ long Mdec;
+ long PsxAuto;
+ long PsxType; /* NTSC or PAL */
+ long Cdda;
+ long HLE;
+ long Cpu;
+ long Dbg;
+ long PsxOut;
+ long SpuIrq;
+ long RCntFix;
+ long UseNet;
+ long VSyncWA;
+#ifdef _WIN32
+ char Lang[256];
+#endif
+} PcsxConfig;
+
+PcsxConfig Config;
+
+extern int StatesC;
+extern int cdOpenCase;
+extern int NetOpened;
+
+#define gzfreeze(ptr, size) \
+ if (Mode == 1) gzwrite(f, ptr, size); \
+ if (Mode == 0) gzread(f, ptr, size);
+
+#define gzfreezel(ptr) gzfreeze(ptr, sizeof(ptr))
+
+//#define BIAS 4
+#define BIAS 2
+#define PSXCLK 33868800 /* 33.8688 Mhz */
+
+enum {
+ BIOS_USER_DEFINED,
+ BIOS_HLE
+}; /* BIOS Types */
+
+enum {
+ PSX_TYPE_NTSC,
+ PSX_TYPE_PAL
+}; /* PSX Type */
+
+
+#endif /* __PSXCOMMON_H__ */
diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c
new file mode 100644
index 00000000..0daf3cb8
--- /dev/null
+++ b/libpcsxcore/psxcounters.c
@@ -0,0 +1,247 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Internal PSX counters.
+*/
+
+#include "psxcounters.h"
+#include "cheat.h"
+
+static int cnts = 4;
+psxCounter psxCounters[5];
+
+static void psxRcntUpd(unsigned long index) {
+ psxCounters[index].sCycle = psxRegs.cycle;
+ if (((!(psxCounters[index].mode & 1)) || (index!=2)) &&
+ psxCounters[index].mode & 0x30) {
+ if (psxCounters[index].mode & 0x10) { // Interrupt on target
+ psxCounters[index].Cycle = ((psxCounters[index].target - psxCounters[index].count) * psxCounters[index].rate) / BIAS;
+ } else { // Interrupt on 0xffff
+ psxCounters[index].Cycle = ((0xffff - psxCounters[index].count) * psxCounters[index].rate) / BIAS;
+ }
+ } else psxCounters[index].Cycle = 0xffffffff;
+// if (index == 2) SysPrintf("Cycle %x\n", psxCounters[index].Cycle);
+}
+
+static void psxRcntReset(unsigned long index) {
+// SysPrintf("psxRcntReset %x (mode=%x)\n", index, psxCounters[index].mode);
+ psxCounters[index].count = 0;
+ psxRcntUpd(index);
+
+// if (index == 2) SysPrintf("rcnt2 %x\n", psxCounters[index].mode);
+ psxHu32ref(0x1070)|= SWAPu32(psxCounters[index].interrupt);
+ psxRegs.interrupt|= 0x80000000;
+ if (!(psxCounters[index].mode & 0x40)) { // Only 1 interrupt
+ psxCounters[index].Cycle = 0xffffffff;
+ } // else Continuos interrupt mode
+}
+
+static void psxRcntSet() {
+ int i;
+
+ psxNextCounter = 0x7fffffff;
+ psxNextsCounter = psxRegs.cycle;
+
+ for (i=0; i<cnts; i++) {
+ s32 count;
+
+ if (psxCounters[i].Cycle == 0xffffffff) continue;
+
+ count = psxCounters[i].Cycle - (psxRegs.cycle - psxCounters[i].sCycle);
+
+ if (count < 0) {
+ psxNextCounter = 0; break;
+ }
+
+ if (count < (s32)psxNextCounter) {
+ psxNextCounter = count;
+ }
+ }
+}
+
+void psxRcntInit() {
+
+ memset(psxCounters, 0, sizeof(psxCounters));
+
+ psxCounters[0].rate = 1; psxCounters[0].interrupt = 0x10;
+ psxCounters[1].rate = 1; psxCounters[1].interrupt = 0x20;
+ psxCounters[2].rate = 1; psxCounters[2].interrupt = 0x40;
+
+ psxCounters[3].interrupt = 1;
+ psxCounters[3].mode = 0x58; // The VSync counter mode
+ psxCounters[3].target = 1;
+ psxUpdateVSyncRate();
+
+ if (SPU_async != NULL) {
+ cnts = 5;
+
+ psxCounters[4].rate = 768 * 64;
+ psxCounters[4].target = 1;
+ psxCounters[4].mode = 0x58;
+ } else cnts = 4;
+
+ psxRcntUpd(0); psxRcntUpd(1); psxRcntUpd(2); psxRcntUpd(3);
+ psxRcntSet();
+}
+
+void psxUpdateVSyncRate() {
+ if (Config.PsxType) // ntsc - 0 | pal - 1
+ psxCounters[3].rate = (PSXCLK / 50);// / BIAS;
+ else psxCounters[3].rate = (PSXCLK / 60);// / BIAS;
+ psxCounters[3].rate-= (psxCounters[3].rate / 262) * 22;
+ if (Config.VSyncWA) psxCounters[3].rate/= 2;
+}
+
+void psxUpdateVSyncRateEnd() {
+ if (Config.PsxType) // ntsc - 0 | pal - 1
+ psxCounters[3].rate = (PSXCLK / 50);// / BIAS;
+ else psxCounters[3].rate = (PSXCLK / 60);// / BIAS;
+ psxCounters[3].rate = (psxCounters[3].rate / 262) * 22;
+ if (Config.VSyncWA) psxCounters[3].rate/= 2;
+}
+
+void psxRcntUpdate() {
+ if ((psxRegs.cycle - psxCounters[3].sCycle) >= psxCounters[3].Cycle) {
+ if (psxCounters[3].mode & 0x10000) { // VSync End (22 hsyncs)
+ psxCounters[3].mode&=~0x10000;
+ psxUpdateVSyncRate();
+ psxRcntUpd(3);
+ GPU_updateLace(); // updateGPU
+ SysUpdate();
+ ApplyCheats();
+#ifdef GTE_LOG
+ GTE_LOG("VSync\n");
+#endif
+ } else { // VSync Start (240 hsyncs)
+ psxCounters[3].mode|= 0x10000;
+ psxUpdateVSyncRateEnd();
+ psxRcntUpd(3);
+ psxHu32ref(0x1070)|= SWAPu32(1);
+ psxRegs.interrupt|= 0x80000000;
+ }
+ }
+
+ if ((psxRegs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) {
+ psxRcntReset(0);
+ }
+
+ if ((psxRegs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) {
+ psxRcntReset(1);
+ }
+
+ if ((psxRegs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) {
+ psxRcntReset(2);
+ }
+
+ if (cnts >= 5) {
+ if ((psxRegs.cycle - psxCounters[4].sCycle) >= psxCounters[4].Cycle) {
+ SPU_async((psxRegs.cycle - psxCounters[4].sCycle) * BIAS);
+ psxRcntReset(4);
+ }
+ }
+
+ psxRcntSet();
+}
+
+void psxRcntWcount(u32 index, u32 value) {
+// SysPrintf("writeCcount[%d] = %x\n", index, value);
+// PSXCPU_LOG("writeCcount[%d] = %x\n", index, value);
+ psxCounters[index].count = value;
+ psxRcntUpd(index);
+ psxRcntSet();
+}
+
+void psxRcntWmode(u32 index, u32 value) {
+// SysPrintf("writeCmode[%ld] = %lx\n", index, value);
+ psxCounters[index].mode = value;
+ psxCounters[index].count = 0;
+ if(index == 0) {
+ switch (value & 0x300) {
+ case 0x100:
+ psxCounters[index].rate = ((psxCounters[3].rate /** BIAS*/) / 386) / 262; // seems ok
+ break;
+ default:
+ psxCounters[index].rate = 1;
+ }
+ }
+ else if(index == 1) {
+ switch (value & 0x300) {
+ case 0x100:
+ psxCounters[index].rate = (psxCounters[3].rate /** BIAS*/) / 262; // seems ok
+ break;
+ default:
+ psxCounters[index].rate = 1;
+ }
+ }
+ else if(index == 2) {
+ switch (value & 0x300) {
+ case 0x200:
+ psxCounters[index].rate = 8; // 1/8 speed
+ break;
+ default:
+ psxCounters[index].rate = 1; // normal speed
+ }
+ }
+
+ // Need to set a rate and target
+ psxRcntUpd(index);
+ psxRcntSet();
+}
+
+void psxRcntWtarget(u32 index, u32 value) {
+// SysPrintf("writeCtarget[%ld] = %lx\n", index, value);
+ psxCounters[index].target = value;
+ psxRcntUpd(index);
+ psxRcntSet();
+}
+
+u32 psxRcntRcount(u32 index) {
+ u32 ret;
+
+// if ((!(psxCounters[index].mode & 1)) || (index!=2)) {
+ if (psxCounters[index].mode & 0x08) { // Wrap at target
+ if (Config.RCntFix) { // Parasite Eve 2
+ ret = (psxCounters[index].count + /*BIAS **/ ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff;
+ } else {
+ ret = (psxCounters[index].count + BIAS * ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff;
+ }
+ } else { // Wrap at 0xffff
+ ret = (psxCounters[index].count + BIAS * (psxRegs.cycle / psxCounters[index].rate)) & 0xffff;
+ if (Config.RCntFix) { // Vandal Hearts 1/2
+ ret/= 16;
+ }
+ }
+// return (psxCounters[index].count + BIAS * ((psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate)) & 0xffff;
+// } else return 0;
+
+// SysPrintf("readCcount[%ld] = %lx (mode %lx, target %lx, cycle %lx)\n", index, ret, psxCounters[index].mode, psxCounters[index].target, psxRegs.cycle);
+
+ return ret;
+}
+
+int psxRcntFreeze(gzFile f, int Mode) {
+ char Unused[4096 - sizeof(psxCounter)];
+
+ gzfreezel(psxCounters);
+ gzfreezel(Unused);
+
+ return 0;
+}
diff --git a/libpcsxcore/psxcounters.h b/libpcsxcore/psxcounters.h
new file mode 100644
index 00000000..de7a5cdd
--- /dev/null
+++ b/libpcsxcore/psxcounters.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PSXCOUNTERS_H__
+#define __PSXCOUNTERS_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxmem.h"
+#include "plugins.h"
+
+typedef struct {
+ u32 count, mode, target;
+ u32 sCycle, Cycle, rate, interrupt;
+} psxCounter;
+
+extern psxCounter psxCounters[5];
+
+u32 psxNextCounter, psxNextsCounter;
+
+void psxRcntInit();
+void psxRcntUpdate();
+void psxRcntWcount(u32 index, u32 value);
+void psxRcntWmode(u32 index, u32 value);
+void psxRcntWtarget(u32 index, u32 value);
+u32 psxRcntRcount(u32 index);
+int psxRcntFreeze(gzFile f, int Mode);
+
+void psxUpdateVSyncRate();
+
+#endif /* __PSXCOUNTERS_H__ */
diff --git a/libpcsxcore/psxdma.c b/libpcsxcore/psxdma.c
new file mode 100644
index 00000000..1a004d8f
--- /dev/null
+++ b/libpcsxcore/psxdma.c
@@ -0,0 +1,170 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Handles PSX DMA functions.
+*/
+
+#include "psxdma.h"
+
+// Dma0/1 in Mdec.c
+// Dma3 in CdRom.c
+
+void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
+ u16 *ptr;
+ u32 size;
+
+ switch (chcr) {
+ case 0x01000201: //cpu to spu transfer
+#ifdef PSXDMA_LOG
+ PSXDMA_LOG("*** DMA4 SPU - mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+ ptr = (u16 *)PSXM(madr);
+ if (ptr == NULL) {
+#ifdef CPU_LOG
+ CPU_LOG("*** DMA4 SPU - mem2spu *** NULL Pointer!!!\n");
+#endif
+ break;
+ }
+ SPU_writeDMAMem(ptr, (bcr >> 16) * (bcr & 0xffff) * 2);
+ break;
+
+ case 0x01000200: //spu to cpu transfer
+#ifdef PSXDMA_LOG
+ PSXDMA_LOG("*** DMA4 SPU - spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+ ptr = (u16 *)PSXM(madr);
+ if (ptr == NULL) {
+#ifdef CPU_LOG
+ CPU_LOG("*** DMA4 SPU - spu2mem *** NULL Pointer!!!\n");
+#endif
+ break;
+ }
+ size = (bcr >> 16) * (bcr & 0xffff) * 2;
+ SPU_readDMAMem(ptr, size);
+ psxCpu->Clear(madr, size);
+ break;
+
+#ifdef PSXDMA_LOG
+ default:
+ PSXDMA_LOG("*** DMA4 SPU - unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+ break;
+#endif
+ }
+
+ HW_DMA4_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(4);
+}
+
+void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU
+ u32 *ptr;
+ u32 size;
+
+ switch(chcr) {
+ case 0x01000200: // vram2mem
+#ifdef PSXDMA_LOG
+ PSXDMA_LOG("*** DMA2 GPU - vram2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+ ptr = (u32 *)PSXM(madr);
+ if (ptr == NULL) {
+#ifdef CPU_LOG
+ CPU_LOG("*** DMA2 GPU - vram2mem *** NULL Pointer!!!\n");
+#endif
+ break;
+ }
+ size = (bcr >> 16) * (bcr & 0xffff);
+ GPU_readDataMem(ptr, size);
+ psxCpu->Clear(madr, size);
+ break;
+
+ case 0x01000201: // mem2vram
+#ifdef PSXDMA_LOG
+ PSXDMA_LOG("*** DMA 2 - GPU mem2vram *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+ ptr = (u32 *)PSXM(madr);
+ if (ptr == NULL) {
+#ifdef CPU_LOG
+ CPU_LOG("*** DMA2 GPU - mem2vram *** NULL Pointer!!!\n");
+#endif
+ break;
+ }
+ size = (bcr >> 16) * (bcr & 0xffff);
+ GPU_writeDataMem(ptr, size);
+ GPUDMA_INT((size / 4) / BIAS);
+ return;
+// break;
+
+ case 0x01000401: // dma chain
+#ifdef PSXDMA_LOG
+ PSXDMA_LOG("*** DMA 2 - GPU dma chain *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+ GPU_dmaChain((u32 *)psxM, madr & 0x1fffff);
+ break;
+
+#ifdef PSXDMA_LOG
+ default:
+ PSXDMA_LOG("*** DMA 2 - GPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+ break;
+#endif
+ }
+
+ HW_DMA2_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(2);
+}
+
+void gpuInterrupt() {
+ HW_DMA2_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(2);
+}
+
+void psxDma6(u32 madr, u32 bcr, u32 chcr) {
+ u32 *mem = (u32 *)PSXM(madr);
+
+#ifdef PSXDMA_LOG
+ PSXDMA_LOG("*** DMA6 OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+#endif
+
+ if (chcr == 0x11000002) {
+ if (mem == NULL) {
+#ifdef CPU_LOG
+ CPU_LOG("*** DMA6 OT *** NULL Pointer!!!\n");
+#endif
+ HW_DMA6_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(6);
+ return;
+ }
+
+ while (bcr--) {
+ *mem-- = SWAP32((madr - 4) & 0xffffff);
+ madr -= 4;
+ }
+ mem++; *mem = 0xffffff;
+ }
+#ifdef PSXDMA_LOG
+ else {
+ // Unknown option
+ PSXDMA_LOG("*** DMA6 OT - unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
+ }
+#endif
+
+ HW_DMA6_CHCR &= SWAP32(~0x01000000);
+ DMA_INTERRUPT(6);
+}
+
diff --git a/libpcsxcore/psxdma.h b/libpcsxcore/psxdma.h
new file mode 100644
index 00000000..404aee06
--- /dev/null
+++ b/libpcsxcore/psxdma.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PSXDMA_H__
+#define __PSXDMA_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxhw.h"
+#include "psxmem.h"
+
+#define GPUDMA_INT(eCycle) { \
+ psxRegs.interrupt |= 0x01000000; \
+ psxRegs.intCycle[3+24+1] = eCycle; \
+ psxRegs.intCycle[3+24] = psxRegs.cycle; \
+}
+
+#define MDECOUTDMA_INT(eCycle) { \
+ psxRegs.interrupt |= 0x02000000; \
+ psxRegs.intCycle[5+24+1] = eCycle; \
+ psxRegs.intCycle[5+24] = psxRegs.cycle; \
+}
+
+void psxDma2(u32 madr, u32 bcr, u32 chcr);
+void psxDma3(u32 madr, u32 bcr, u32 chcr);
+void psxDma4(u32 madr, u32 bcr, u32 chcr);
+void psxDma6(u32 madr, u32 bcr, u32 chcr);
+void gpuInterrupt();
+
+#endif /* __PSXDMA_H__ */
diff --git a/libpcsxcore/psxhle.c b/libpcsxcore/psxhle.c
new file mode 100644
index 00000000..816e94bc
--- /dev/null
+++ b/libpcsxcore/psxhle.c
@@ -0,0 +1,97 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Internal PSX HLE functions.
+*/
+
+#include "psxhle.h"
+
+static void hleDummy() {
+ psxRegs.pc = psxRegs.GPR.n.ra;
+
+ psxBranchTest();
+}
+
+static void hleA0() {
+ u32 call = psxRegs.GPR.n.t1 & 0xff;
+
+ if (biosA0[call]) biosA0[call]();
+
+ psxBranchTest();
+}
+
+static void hleB0() {
+ u32 call = psxRegs.GPR.n.t1 & 0xff;
+
+ if (biosB0[call]) biosB0[call]();
+
+ psxBranchTest();
+}
+
+static void hleC0() {
+ u32 call = psxRegs.GPR.n.t1 & 0xff;
+
+ if (biosC0[call]) biosC0[call]();
+
+ psxBranchTest();
+}
+
+static void hleBootstrap() { // 0xbfc00000
+ SysPrintf("hleBootstrap\n");
+ CheckCdrom();
+ LoadCdrom();
+ SysPrintf("CdromLabel: \"%s\": PC = %8.8lx (SP = %8.8lx)\n", CdromLabel, psxRegs.pc, psxRegs.GPR.n.sp);
+}
+
+typedef struct {
+ u32 _pc0;
+ u32 gp0;
+ u32 t_addr;
+ u32 t_size;
+ u32 d_addr;
+ u32 d_size;
+ u32 b_addr;
+ u32 b_size;
+ u32 S_addr;
+ u32 s_size;
+ u32 _sp,_fp,_gp,ret,base;
+} EXEC;
+
+static void hleExecRet() {
+ EXEC *header = (EXEC*)PSXM(psxRegs.GPR.n.s0);
+
+ SysPrintf("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret);
+
+ psxRegs.GPR.n.ra = header->ret;
+ psxRegs.GPR.n.sp = header->_sp;
+ psxRegs.GPR.n.s8 = header->_fp;
+ psxRegs.GPR.n.gp = header->_gp;
+ psxRegs.GPR.n.s0 = header->base;
+
+ psxRegs.GPR.n.v0 = 1;
+ psxRegs.pc = psxRegs.GPR.n.ra;
+}
+
+void (*psxHLEt[256])() = {
+ hleDummy, hleA0, hleB0, hleC0,
+ hleBootstrap, hleExecRet,
+ hleDummy, hleDummy
+};
diff --git a/libpcsxcore/psxhle.h b/libpcsxcore/psxhle.h
new file mode 100644
index 00000000..16b37c86
--- /dev/null
+++ b/libpcsxcore/psxhle.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PSXHLE_H__
+#define __PSXHLE_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "plugins.h"
+
+extern void (*psxHLEt[256])();
+
+#endif /* __PSXHLE_H__ */
diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c
new file mode 100644
index 00000000..27e69ec8
--- /dev/null
+++ b/libpcsxcore/psxhw.c
@@ -0,0 +1,723 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Functions for PSX hardware control.
+*/
+
+#include "psxhw.h"
+#include "mdec.h"
+#include "cdrom.h"
+
+void psxHwReset() {
+ if (Config.Sio) psxHu32ref(0x1070) |= SWAP32(0x80);
+ if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAP32(0x200);
+
+ memset(psxH, 0, 0x10000);
+
+ mdecInit(); //intialize mdec decoder
+ cdrReset();
+ psxRcntInit();
+}
+
+u8 psxHwRead8(u32 add) {
+ unsigned char hard;
+
+ switch (add) {
+ case 0x1f801040: hard = sioRead8();break;
+ // case 0x1f801050: hard = serial_read8(); break;//for use of serial port ignore for now
+ case 0x1f801800: hard = cdrRead0(); break;
+ case 0x1f801801: hard = cdrRead1(); break;
+ case 0x1f801802: hard = cdrRead2(); break;
+ case 0x1f801803: hard = cdrRead3(); break;
+ default:
+ hard = psxHu8(add);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Unkwnown 8bit read at address %lx\n", add);
+#endif
+ return hard;
+ }
+
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Known 8bit read at address %lx value %x\n", add, hard);
+#endif
+ return hard;
+}
+
+u16 psxHwRead16(u32 add) {
+ unsigned short hard;
+
+ switch (add) {
+#ifdef PSXHW_LOG
+ case 0x1f801070: PSXHW_LOG("IREG 16bit read %x\n", psxHu16(0x1070));
+ return psxHu16(0x1070);
+#endif
+#ifdef PSXHW_LOG
+ case 0x1f801074: PSXHW_LOG("IMASK 16bit read %x\n", psxHu16(0x1074));
+ return psxHu16(0x1074);
+#endif
+
+ case 0x1f801040:
+ hard = sioRead8();
+ hard|= sioRead8() << 8;
+#ifdef PAD_LOG
+ PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard);
+#endif
+ return hard;
+ case 0x1f801044:
+ hard = StatReg;
+#ifdef PAD_LOG
+ PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard);
+#endif
+ return hard;
+ case 0x1f801048:
+ hard = ModeReg;
+#ifdef PAD_LOG
+ PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard);
+#endif
+ return hard;
+ case 0x1f80104a:
+ hard = CtrlReg;
+#ifdef PAD_LOG
+ PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard);
+#endif
+ return hard;
+ case 0x1f80104e:
+ hard = BaudReg;
+#ifdef PAD_LOG
+ PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard);
+#endif
+ return hard;
+
+ //Serial port stuff not support now ;P
+ // case 0x1f801050: hard = serial_read16(); break;
+ // case 0x1f801054: hard = serial_status_read(); break;
+ // case 0x1f80105a: hard = serial_control_read(); break;
+ // case 0x1f80105e: hard = serial_baud_read(); break;
+
+ case 0x1f801100:
+ hard = psxRcntRcount(0);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T0 count read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801104:
+ hard = psxCounters[0].mode;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T0 mode read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801108:
+ hard = psxCounters[0].target;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T0 target read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801110:
+ hard = psxRcntRcount(1);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T1 count read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801114:
+ hard = psxCounters[1].mode;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T1 mode read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801118:
+ hard = psxCounters[1].target;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T1 target read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801120:
+ hard = psxRcntRcount(2);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T2 count read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801124:
+ hard = psxCounters[2].mode;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T2 mode read16: %x\n", hard);
+#endif
+ return hard;
+ case 0x1f801128:
+ hard = psxCounters[2].target;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T2 target read16: %x\n", hard);
+#endif
+ return hard;
+
+ //case 0x1f802030: hard = //int_2000????
+ //case 0x1f802040: hard =//dip switches...??
+
+ default:
+ if (add>=0x1f801c00 && add<0x1f801e00) {
+ hard = SPU_readRegister(add);
+ } else {
+ hard = psxHu16(add);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Unkwnown 16bit read at address %lx\n", add);
+#endif
+ }
+ return hard;
+ }
+
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Known 16bit read at address %lx value %x\n", add, hard);
+#endif
+ return hard;
+}
+
+u32 psxHwRead32(u32 add) {
+ u32 hard;
+
+ switch (add) {
+ case 0x1f801040:
+ hard = sioRead8();
+ hard|= sioRead8() << 8;
+ hard|= sioRead8() << 16;
+ hard|= sioRead8() << 24;
+#ifdef PAD_LOG
+ PAD_LOG("sio read32 ;ret = %lx\n", hard);
+#endif
+ return hard;
+
+ // case 0x1f801050: hard = serial_read32(); break;//serial port
+#ifdef PSXHW_LOG
+ case 0x1f801060:
+ PSXHW_LOG("RAM size read %lx\n", psxHu32(0x1060));
+ return psxHu32(0x1060);
+#endif
+#ifdef PSXHW_LOG
+ case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070));
+ return psxHu32(0x1070);
+#endif
+#ifdef PSXHW_LOG
+ case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074));
+ return psxHu32(0x1074);
+#endif
+
+ case 0x1f801810:
+ hard = GPU_readData();
+#ifdef PSXHW_LOG
+ PSXHW_LOG("GPU DATA 32bit read %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801814:
+ hard = GPU_readStatus();
+#ifdef PSXHW_LOG
+ PSXHW_LOG("GPU STATUS 32bit read %lx\n", hard);
+#endif
+ return hard;
+
+ case 0x1f801820: hard = mdecRead0(); break;
+ case 0x1f801824: hard = mdecRead1(); break;
+
+#ifdef PSXHW_LOG
+ case 0x1f8010a0:
+ PSXHW_LOG("DMA2 MADR 32bit read %lx\n", psxHu32(0x10a0));
+ return SWAPu32(HW_DMA2_MADR);
+ case 0x1f8010a4:
+ PSXHW_LOG("DMA2 BCR 32bit read %lx\n", psxHu32(0x10a4));
+ return SWAPu32(HW_DMA2_BCR);
+ case 0x1f8010a8:
+ PSXHW_LOG("DMA2 CHCR 32bit read %lx\n", psxHu32(0x10a8));
+ return SWAPu32(HW_DMA2_CHCR);
+#endif
+
+#ifdef PSXHW_LOG
+ case 0x1f8010b0:
+ PSXHW_LOG("DMA3 MADR 32bit read %lx\n", psxHu32(0x10b0));
+ return SWAPu32(HW_DMA3_MADR);
+ case 0x1f8010b4:
+ PSXHW_LOG("DMA3 BCR 32bit read %lx\n", psxHu32(0x10b4));
+ return SWAPu32(HW_DMA3_BCR);
+ case 0x1f8010b8:
+ PSXHW_LOG("DMA3 CHCR 32bit read %lx\n", psxHu32(0x10b8));
+ return SWAPu32(HW_DMA3_CHCR);
+#endif
+
+#ifdef PSXHW_LOG
+/* case 0x1f8010f0:
+ PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0));
+ return SWAPu32(HW_DMA_PCR); // dma rest channel
+ case 0x1f8010f4:
+ PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4));
+ return SWAPu32(HW_DMA_ICR); // interrupt enabler?*/
+#endif
+
+ // time for rootcounters :)
+ case 0x1f801100:
+ hard = psxRcntRcount(0);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T0 count read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801104:
+ hard = psxCounters[0].mode;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T0 mode read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801108:
+ hard = psxCounters[0].target;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T0 target read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801110:
+ hard = psxRcntRcount(1);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T1 count read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801114:
+ hard = psxCounters[1].mode;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T1 mode read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801118:
+ hard = psxCounters[1].target;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T1 target read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801120:
+ hard = psxRcntRcount(2);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T2 count read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801124:
+ hard = psxCounters[2].mode;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T2 mode read32: %lx\n", hard);
+#endif
+ return hard;
+ case 0x1f801128:
+ hard = psxCounters[2].target;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("T2 target read32: %lx\n", hard);
+#endif
+ return hard;
+
+ default:
+ hard = psxHu32(add);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Unkwnown 32bit read at address %lx\n", add);
+#endif
+ return hard;
+ }
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Known 32bit read at address %lx\n", add);
+#endif
+ return hard;
+}
+
+void psxHwWrite8(u32 add, u8 value) {
+ switch (add) {
+ case 0x1f801040: sioWrite8(value); break;
+ // case 0x1f801050: serial_write8(value); break;//serial port
+ case 0x1f801800: cdrWrite0(value); break;
+ case 0x1f801801: cdrWrite1(value); break;
+ case 0x1f801802: cdrWrite2(value); break;
+ case 0x1f801803: cdrWrite3(value); break;
+
+ default:
+ psxHu8(add) = value;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Unknown 8bit write at address %lx value %x\n", add, value);
+#endif
+ return;
+ }
+ psxHu8(add) = value;
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Known 8bit write at address %lx value %x\n", add, value);
+#endif
+}
+
+void psxHwWrite16(u32 add, u16 value) {
+ switch (add) {
+ case 0x1f801040:
+ sioWrite8((unsigned char)value);
+ sioWrite8((unsigned char)(value>>8));
+#ifdef PAD_LOG
+ PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value);
+#endif
+ return;
+ case 0x1f801044:
+#ifdef PAD_LOG
+ PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value);
+#endif
+ return;
+ case 0x1f801048:
+ ModeReg = value;
+#ifdef PAD_LOG
+ PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value);
+#endif
+ return;
+ case 0x1f80104a: // control register
+ sioWriteCtrl16(value);
+#ifdef PAD_LOG
+ PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value);
+#endif
+ return;
+ case 0x1f80104e: // baudrate register
+ BaudReg = value;
+#ifdef PAD_LOG
+ PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value);
+#endif
+ return;
+
+ //serial port ;P
+ // case 0x1f801050: serial_write16(value); break;
+ // case 0x1f80105a: serial_control_write(value);break;
+ // case 0x1f80105e: serial_baud_write(value); break;
+ // case 0x1f801054: serial_status_write(value); break;
+
+ case 0x1f801070:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("IREG 16bit write %x\n", value);
+#endif
+ if (Config.Sio) psxHu16ref(0x1070) |= SWAPu16(0x80);
+ if (Config.SpuIrq) psxHu16ref(0x1070) |= SWAPu16(0x200);
+ psxHu16ref(0x1070) &= SWAPu16((psxHu16(0x1074) & value));
+ return;
+
+ case 0x1f801074:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("IMASK 16bit write %x\n", value);
+#endif
+ psxHu16ref(0x1074) = SWAPu16(value);
+ psxRegs.interrupt |= 0x80000000;
+ return;
+
+ case 0x1f801100:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value);
+#endif
+ psxRcntWcount(0, value); return;
+ case 0x1f801104:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value);
+#endif
+ psxRcntWmode(0, value); return;
+ case 0x1f801108:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value);
+#endif
+ psxRcntWtarget(0, value); return;
+
+ case 0x1f801110:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value);
+#endif
+ psxRcntWcount(1, value); return;
+ case 0x1f801114:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value);
+#endif
+ psxRcntWmode(1, value); return;
+ case 0x1f801118:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value);
+#endif
+ psxRcntWtarget(1, value); return;
+
+ case 0x1f801120:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value);
+#endif
+ psxRcntWcount(2, value); return;
+ case 0x1f801124:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value);
+#endif
+ psxRcntWmode(2, value); return;
+ case 0x1f801128:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value);
+#endif
+ psxRcntWtarget(2, value); return;
+
+ default:
+ if (add>=0x1f801c00 && add<0x1f801e00) {
+ SPU_writeRegister(add, value);
+ return;
+ }
+
+ psxHu16ref(add) = SWAPu16(value);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Unknown 16bit write at address %lx value %x\n", add, value);
+#endif
+ return;
+ }
+ psxHu16ref(add) = SWAPu16(value);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Known 16bit write at address %lx value %x\n", add, value);
+#endif
+}
+
+#define DmaExec(n) { \
+ if (SWAPu32(HW_DMA##n##_CHCR) & 0x01000000) return; \
+ HW_DMA##n##_CHCR = SWAPu32(value); \
+ \
+ if (SWAPu32(HW_DMA##n##_CHCR) & 0x01000000 && SWAPu32(HW_DMA_PCR) & (8 << (n * 4))) { \
+ psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), SWAPu32(HW_DMA##n##_CHCR)); \
+ } \
+}
+
+void psxHwWrite32(u32 add, u32 value) {
+ switch (add) {
+ case 0x1f801040:
+ sioWrite8((unsigned char)value);
+ sioWrite8((unsigned char)((value&0xff) >> 8));
+ sioWrite8((unsigned char)((value&0xff) >> 16));
+ sioWrite8((unsigned char)((value&0xff) >> 24));
+#ifdef PAD_LOG
+ PAD_LOG("sio write32 %lx\n", value);
+#endif
+ return;
+ // case 0x1f801050: serial_write32(value); break;//serial port
+#ifdef PSXHW_LOG
+ case 0x1f801060:
+ PSXHW_LOG("RAM size write %lx\n", value);
+ psxHu32ref(add) = SWAPu32(value);
+ return; // Ram size
+#endif
+
+ case 0x1f801070:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("IREG 32bit write %lx\n", value);
+#endif
+ if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80);
+ if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200);
+ psxHu32ref(0x1070) &= SWAPu32((psxHu32(0x1074) & value));
+ return;
+ case 0x1f801074:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("IMASK 32bit write %lx\n", value);
+#endif
+ psxHu32ref(0x1074) = SWAPu32(value);
+ psxRegs.interrupt|= 0x80000000;
+ return;
+
+#ifdef PSXHW_LOG
+ case 0x1f801080:
+ PSXHW_LOG("DMA0 MADR 32bit write %lx\n", value);
+ HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr
+ case 0x1f801084:
+ PSXHW_LOG("DMA0 BCR 32bit write %lx\n", value);
+ HW_DMA0_BCR = SWAPu32(value); return; // DMA0 bcr
+#endif
+ case 0x1f801088:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA0 CHCR 32bit write %lx\n", value);
+#endif
+ DmaExec(0); // DMA0 chcr (MDEC in DMA)
+ return;
+
+#ifdef PSXHW_LOG
+ case 0x1f801090:
+ PSXHW_LOG("DMA1 MADR 32bit write %lx\n", value);
+ HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr
+ case 0x1f801094:
+ PSXHW_LOG("DMA1 BCR 32bit write %lx\n", value);
+ HW_DMA1_BCR = SWAPu32(value); return; // DMA1 bcr
+#endif
+ case 0x1f801098:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA1 CHCR 32bit write %lx\n", value);
+#endif
+ DmaExec(1); // DMA1 chcr (MDEC out DMA)
+ return;
+
+#ifdef PSXHW_LOG
+ case 0x1f8010a0:
+ PSXHW_LOG("DMA2 MADR 32bit write %lx\n", value);
+ HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr
+ case 0x1f8010a4:
+ PSXHW_LOG("DMA2 BCR 32bit write %lx\n", value);
+ HW_DMA2_BCR = SWAPu32(value); return; // DMA2 bcr
+#endif
+ case 0x1f8010a8:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA2 CHCR 32bit write %lx\n", value);
+#endif
+ DmaExec(2); // DMA2 chcr (GPU DMA)
+ return;
+
+#ifdef PSXHW_LOG
+ case 0x1f8010b0:
+ PSXHW_LOG("DMA3 MADR 32bit write %lx\n", value);
+ HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr
+ case 0x1f8010b4:
+ PSXHW_LOG("DMA3 BCR 32bit write %lx\n", value);
+ HW_DMA3_BCR = SWAPu32(value); return; // DMA3 bcr
+#endif
+ case 0x1f8010b8:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA3 CHCR 32bit write %lx\n", value);
+#endif
+ DmaExec(3); // DMA3 chcr (CDROM DMA)
+
+ return;
+
+#ifdef PSXHW_LOG
+ case 0x1f8010c0:
+ PSXHW_LOG("DMA4 MADR 32bit write %lx\n", value);
+ HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr
+ case 0x1f8010c4:
+ PSXHW_LOG("DMA4 BCR 32bit write %lx\n", value);
+ HW_DMA4_BCR = SWAPu32(value); return; // DMA4 bcr
+#endif
+ case 0x1f8010c8:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA4 CHCR 32bit write %lx\n", value);
+#endif
+ DmaExec(4); // DMA4 chcr (SPU DMA)
+ return;
+
+#if 0
+ case 0x1f8010d0: break; //DMA5write_madr();
+ case 0x1f8010d4: break; //DMA5write_bcr();
+ case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed
+#endif
+
+#ifdef PSXHW_LOG
+ case 0x1f8010e0:
+ PSXHW_LOG("DMA6 MADR 32bit write %lx\n", value);
+ HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr
+ case 0x1f8010e4:
+ PSXHW_LOG("DMA6 BCR 32bit write %lx\n", value);
+ HW_DMA6_BCR = SWAPu32(value); return; // DMA6 bcr
+#endif
+ case 0x1f8010e8:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA6 CHCR 32bit write %lx\n", value);
+#endif
+ DmaExec(6); // DMA6 chcr (OT clear)
+ return;
+
+#ifdef PSXHW_LOG
+ case 0x1f8010f0:
+ PSXHW_LOG("DMA PCR 32bit write %lx\n", value);
+ HW_DMA_PCR = SWAPu32(value);
+ return;
+#endif
+
+ case 0x1f8010f4:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("DMA ICR 32bit write %lx\n", value);
+#endif
+ {
+ u32 tmp = (~value) & SWAPu32(HW_DMA_ICR);
+ HW_DMA_ICR = SWAPu32(((tmp ^ value) & 0xffffff) ^ tmp);
+ return;
+ }
+
+ case 0x1f801810:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("GPU DATA 32bit write %lx\n", value);
+#endif
+ GPU_writeData(value); return;
+ case 0x1f801814:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("GPU STATUS 32bit write %lx\n", value);
+#endif
+ GPU_writeStatus(value); return;
+
+ case 0x1f801820:
+ mdecWrite0(value); break;
+ case 0x1f801824:
+ mdecWrite1(value); break;
+
+ case 0x1f801100:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 0 COUNT 32bit write %lx\n", value);
+#endif
+ psxRcntWcount(0, value & 0xffff); return;
+ case 0x1f801104:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 0 MODE 32bit write %lx\n", value);
+#endif
+ psxRcntWmode(0, value); return;
+ case 0x1f801108:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 0 TARGET 32bit write %lx\n", value);
+#endif
+ psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= SWAP32((~value)&0xff000000);
+
+ case 0x1f801110:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 1 COUNT 32bit write %lx\n", value);
+#endif
+ psxRcntWcount(1, value & 0xffff); return;
+ case 0x1f801114:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 1 MODE 32bit write %lx\n", value);
+#endif
+ psxRcntWmode(1, value); return;
+ case 0x1f801118:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 1 TARGET 32bit write %lx\n", value);
+#endif
+ psxRcntWtarget(1, value & 0xffff); return;
+
+ case 0x1f801120:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 2 COUNT 32bit write %lx\n", value);
+#endif
+ psxRcntWcount(2, value & 0xffff); return;
+ case 0x1f801124:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 2 MODE 32bit write %lx\n", value);
+#endif
+ psxRcntWmode(2, value); return;
+ case 0x1f801128:
+#ifdef PSXHW_LOG
+ PSXHW_LOG("COUNTER 2 TARGET 32bit write %lx\n", value);
+#endif
+ psxRcntWtarget(2, value & 0xffff); return;
+
+ default:
+ psxHu32ref(add) = SWAPu32(value);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Unknown 32bit write at address %lx value %lx\n", add, value);
+#endif
+ return;
+ }
+ psxHu32ref(add) = SWAPu32(value);
+#ifdef PSXHW_LOG
+ PSXHW_LOG("*Known 32bit write at address %lx value %lx\n", add, value);
+#endif
+}
+
+int psxHwFreeze(gzFile f, int Mode) {
+ char Unused[4096];
+
+ gzfreezel(Unused);
+
+ return 0;
+}
diff --git a/libpcsxcore/psxhw.h b/libpcsxcore/psxhw.h
new file mode 100644
index 00000000..92c66f90
--- /dev/null
+++ b/libpcsxcore/psxhw.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PSXHW_H__
+#define __PSXHW_H__
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxmem.h"
+#include "sio.h"
+#include "psxcounters.h"
+
+#define HW_DMA0_MADR (psxHu32ref(0x1080)) // MDEC in DMA
+#define HW_DMA0_BCR (psxHu32ref(0x1084))
+#define HW_DMA0_CHCR (psxHu32ref(0x1088))
+
+#define HW_DMA1_MADR (psxHu32ref(0x1090)) // MDEC out DMA
+#define HW_DMA1_BCR (psxHu32ref(0x1094))
+#define HW_DMA1_CHCR (psxHu32ref(0x1098))
+
+#define HW_DMA2_MADR (psxHu32ref(0x10a0)) // GPU DMA
+#define HW_DMA2_BCR (psxHu32ref(0x10a4))
+#define HW_DMA2_CHCR (psxHu32ref(0x10a8))
+
+#define HW_DMA3_MADR (psxHu32ref(0x10b0)) // CDROM DMA
+#define HW_DMA3_BCR (psxHu32ref(0x10b4))
+#define HW_DMA3_CHCR (psxHu32ref(0x10b8))
+
+#define HW_DMA4_MADR (psxHu32ref(0x10c0)) // SPU DMA
+#define HW_DMA4_BCR (psxHu32ref(0x10c4))
+#define HW_DMA4_CHCR (psxHu32ref(0x10c8))
+
+#define HW_DMA6_MADR (psxHu32ref(0x10e0)) // GPU DMA (OT)
+#define HW_DMA6_BCR (psxHu32ref(0x10e4))
+#define HW_DMA6_CHCR (psxHu32ref(0x10e8))
+
+#define HW_DMA_PCR (psxHu32ref(0x10f0))
+#define HW_DMA_ICR (psxHu32ref(0x10f4))
+
+#define DMA_INTERRUPT(n) \
+ if (SWAPu32(HW_DMA_ICR) & (1 << (16 + n))) { \
+ HW_DMA_ICR|= SWAP32(1 << (24 + n)); \
+ psxHu32ref(0x1070) |= SWAP32(8); \
+ psxRegs.interrupt|= 0x80000000; \
+ }
+
+
+void psxHwReset();
+u8 psxHwRead8 (u32 add);
+u16 psxHwRead16(u32 add);
+u32 psxHwRead32(u32 add);
+void psxHwWrite8 (u32 add, u8 value);
+void psxHwWrite16(u32 add, u16 value);
+void psxHwWrite32(u32 add, u32 value);
+int psxHwFreeze(gzFile f, int Mode);
+
+#endif /* __PSXHW_H__ */
diff --git a/libpcsxcore/psxinterpreter.c b/libpcsxcore/psxinterpreter.c
new file mode 100644
index 00000000..2eabc16e
--- /dev/null
+++ b/libpcsxcore/psxinterpreter.c
@@ -0,0 +1,857 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+ * PSX assembly interpreter.
+ */
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "gte.h"
+#include "psxhle.h"
+/*FIXME*/
+#include "../gui/hdebug.h"
+
+static int branch = 0;
+static int branch2 = 0;
+static u32 branchPC;
+
+// These macros are used to assemble the repassembler functions
+
+#ifdef PSXCPU_LOG
+#define debugI() PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc));
+#else
+#define debugI()
+#endif
+
+inline void execI();
+inline void execIDbg();
+
+// Subsets
+void (*psxBSC[64])();
+void (*psxSPC[64])();
+void (*psxREG[32])();
+void (*psxCP0[32])();
+void (*psxCP2[64])();
+void (*psxCP2BSC[32])();
+
+static void delayRead(int reg, u32 bpc) {
+ u32 rold, rnew;
+
+// SysPrintf("delayRead at %x!\n", psxRegs.pc);
+
+ rold = psxRegs.GPR.r[reg];
+ psxBSC[psxRegs.code >> 26](); // branch delay load
+ rnew = psxRegs.GPR.r[reg];
+
+ psxRegs.pc = bpc;
+
+ psxBranchTest();
+
+ psxRegs.GPR.r[reg] = rold;
+ execI(); // first branch opcode
+ psxRegs.GPR.r[reg] = rnew;
+
+ branch = 0;
+}
+
+static void delayWrite(int reg, u32 bpc) {
+
+/* SysPrintf("delayWrite at %x!\n", psxRegs.pc);
+
+ SysPrintf("%s\n", disR3000AF(psxRegs.code, psxRegs.pc-4));
+ SysPrintf("%s\n", disR3000AF(PSXMu32(bpc), bpc));*/
+
+ // no changes from normal behavior
+
+ psxBSC[psxRegs.code >> 26]();
+
+ branch = 0;
+ psxRegs.pc = bpc;
+
+ psxBranchTest();
+}
+
+static void delayReadWrite(int reg, u32 bpc) {
+
+// SysPrintf("delayReadWrite at %x!\n", psxRegs.pc);
+
+ // the branch delay load is skipped
+
+ branch = 0;
+ psxRegs.pc = bpc;
+
+ psxBranchTest();
+}
+
+// this defines shall be used with the tmp
+// of the next func (instead of _Funct_...)
+#define _tFunct_ ((tmp ) & 0x3F) // The funct part of the instruction register
+#define _tRd_ ((tmp >> 11) & 0x1F) // The rd part of the instruction register
+#define _tRt_ ((tmp >> 16) & 0x1F) // The rt part of the instruction register
+#define _tRs_ ((tmp >> 21) & 0x1F) // The rs part of the instruction register
+#define _tSa_ ((tmp >> 6) & 0x1F) // The sa part of the instruction register
+
+int psxTestLoadDelay(int reg, u32 tmp) {
+ if (tmp == 0) return 0; // NOP
+ switch (tmp >> 26) {
+ case 0x00: // SPECIAL
+ switch (_tFunct_) {
+ case 0x00: // SLL
+ case 0x02: case 0x03: // SRL/SRA
+ if (_tRd_ == reg && _tRt_ == reg) return 1; else
+ if (_tRt_ == reg) return 2; else
+ if (_tRd_ == reg) return 3;
+ break;
+
+ case 0x08: // JR
+ if (_tRs_ == reg) return 2;
+ break;
+ case 0x09: // JALR
+ if (_tRd_ == reg && _tRs_ == reg) return 1; else
+ if (_tRs_ == reg) return 2; else
+ if (_tRd_ == reg) return 3;
+ break;
+
+ // SYSCALL/BREAK just a break;
+
+ case 0x20: case 0x21: case 0x22: case 0x23:
+ case 0x24: case 0x25: case 0x26: case 0x27:
+ case 0x2a: case 0x2b: // ADD/ADDU...
+ case 0x04: case 0x06: case 0x07: // SLLV...
+ if (_tRd_ == reg && (_tRt_ == reg || _tRs_ == reg)) return 1; else
+ if (_tRt_ == reg || _tRs_ == reg) return 2; else
+ if (_tRd_ == reg) return 3;
+ break;
+
+ case 0x10: case 0x12: // MFHI/MFLO
+ if (_tRd_ == reg) return 3;
+ break;
+ case 0x11: case 0x13: // MTHI/MTLO
+ if (_tRs_ == reg) return 2;
+ break;
+
+ case 0x18: case 0x19:
+ case 0x1a: case 0x1b: // MULT/DIV...
+ if (_tRt_ == reg || _tRs_ == reg) return 2;
+ break;
+ }
+ break;
+
+ case 0x01: // REGIMM
+ switch (_tRt_) {
+ case 0x00: case 0x02:
+ case 0x10: case 0x12: // BLTZ/BGEZ...
+ if (_tRs_ == reg) return 2;
+ break;
+ }
+ break;
+
+ // J would be just a break;
+ case 0x03: // JAL
+ if (31 == reg) return 3;
+ break;
+
+ case 0x04: case 0x05: // BEQ/BNE
+ if (_tRs_ == reg || _tRt_ == reg) return 2;
+ break;
+
+ case 0x06: case 0x07: // BLEZ/BGTZ
+ if (_tRs_ == reg) return 2;
+ break;
+
+ case 0x08: case 0x09: case 0x0a: case 0x0b:
+ case 0x0c: case 0x0d: case 0x0e: // ADDI/ADDIU...
+ if (_tRt_ == reg && _tRs_ == reg) return 1; else
+ if (_tRs_ == reg) return 2; else
+ if (_tRt_ == reg) return 3;
+ break;
+
+ case 0x0f: // LUI
+ if (_tRt_ == reg) return 3;
+ break;
+
+ case 0x10: // COP0
+ switch (_tFunct_) {
+ case 0x00: // MFC0
+ if (_tRt_ == reg) return 3;
+ break;
+ case 0x02: // CFC0
+ if (_tRt_ == reg) return 3;
+ break;
+ case 0x04: // MTC0
+ if (_tRt_ == reg) return 2;
+ break;
+ case 0x06: // CTC0
+ if (_tRt_ == reg) return 2;
+ break;
+ // RFE just a break;
+ }
+ break;
+
+ case 0x12: // COP2
+ switch (_tFunct_) {
+ case 0x00:
+ switch (_tRs_) {
+ case 0x00: // MFC2
+ if (_tRt_ == reg) return 3;
+ break;
+ case 0x02: // CFC2
+ if (_tRt_ == reg) return 3;
+ break;
+ case 0x04: // MTC2
+ if (_tRt_ == reg) return 2;
+ break;
+ case 0x06: // CTC2
+ if (_tRt_ == reg) return 2;
+ break;
+ }
+ break;
+ // RTPS... break;
+ }
+ break;
+
+ case 0x22: case 0x26: // LWL/LWR
+ if (_tRt_ == reg) return 3; else
+ if (_tRs_ == reg) return 2;
+ break;
+
+ case 0x20: case 0x21: case 0x23:
+ case 0x24: case 0x25: // LB/LH/LW/LBU/LHU
+ if (_tRt_ == reg && _tRs_ == reg) return 1; else
+ if (_tRs_ == reg) return 2; else
+ if (_tRt_ == reg) return 3;
+ break;
+
+ case 0x28: case 0x29: case 0x2a:
+ case 0x2b: case 0x2e: // SB/SH/SWL/SW/SWR
+ if (_tRt_ == reg || _tRs_ == reg) return 2;
+ break;
+
+ case 0x32: case 0x3a: // LWC2/SWC2
+ if (_tRs_ == reg) return 2;
+ break;
+ }
+
+ return 0;
+}
+
+void psxDelayTest(int reg, u32 bpc) {
+ u32 *code;
+ u32 tmp;
+
+ code = (u32 *)PSXM(bpc);
+ tmp = ((code == NULL) ? 0 : SWAP32(*code));
+ branch = 1;
+
+ switch (psxTestLoadDelay(reg, tmp)) {
+ case 1:
+ delayReadWrite(reg, bpc); return;
+ case 2:
+ delayRead(reg, bpc); return;
+ case 3:
+ delayWrite(reg, bpc); return;
+ }
+ psxBSC[psxRegs.code >> 26]();
+
+ branch = 0;
+ psxRegs.pc = bpc;
+
+ psxBranchTest();
+}
+
+__inline void doBranch(u32 tar) {
+ u32 *code;
+ u32 tmp;
+
+ branch2 = branch = 1;
+ branchPC = tar;
+
+ code = (u32 *)PSXM(psxRegs.pc);
+ psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
+
+ debugI();
+
+ psxRegs.pc += 4;
+ psxRegs.cycle++;
+
+ // check for load delay
+ tmp = psxRegs.code >> 26;
+ switch (tmp) {
+ case 0x10: // COP0
+ switch (_Rs_) {
+ case 0x00: // MFC0
+ case 0x02: // CFC0
+ psxDelayTest(_Rt_, branchPC);
+ return;
+ }
+ break;
+ case 0x12: // COP2
+ switch (_Funct_) {
+ case 0x00:
+ switch (_Rs_) {
+ case 0x00: // MFC2
+ case 0x02: // CFC2
+ psxDelayTest(_Rt_, branchPC);
+ return;
+ }
+ break;
+ }
+ break;
+ case 0x32: // LWC2
+ psxDelayTest(_Rt_, branchPC);
+ return;
+ default:
+ if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
+ psxDelayTest(_Rt_, branchPC);
+ return;
+ }
+ break;
+ }
+
+ psxBSC[psxRegs.code >> 26]();
+
+ branch = 0;
+ psxRegs.pc = branchPC;
+
+ psxBranchTest();
+}
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+void psxADDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; } // Rt = Rs + Im (Exception on Integer Overflow)
+void psxADDIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; } // Rt = Rs + Im
+void psxANDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; } // Rt = Rs And Im
+void psxORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; } // Rt = Rs Or Im
+void psxXORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; } // Rt = Rs Xor Im
+void psxSLTI() { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; } // Rt = Rs < Im (Signed)
+void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < ((u32)_Imm_); } // Rt = Rs < Im (Unsigned)
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+void psxADD() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); } // Rd = Rs + Rt (Exception on Integer Overflow)
+void psxADDU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); } // Rd = Rs + Rt
+void psxSUB() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); } // Rd = Rs - Rt (Exception on Integer Overflow)
+void psxSUBU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); } // Rd = Rs - Rt
+void psxAND() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) & _u32(_rRt_); } // Rd = Rs And Rt
+void psxOR() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) | _u32(_rRt_); } // Rd = Rs Or Rt
+void psxXOR() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) ^ _u32(_rRt_); } // Rd = Rs Xor Rt
+void psxNOR() { if (!_Rd_) return; _rRd_ =~(_u32(_rRs_) | _u32(_rRt_)); }// Rd = Rs Nor Rt
+void psxSLT() { if (!_Rd_) return; _rRd_ = _i32(_rRs_) < _i32(_rRt_); } // Rd = Rs < Rt (Signed)
+void psxSLTU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) < _u32(_rRt_); } // Rd = Rs < Rt (Unsigned)
+
+/*********************************************************
+* Register mult/div & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+void psxDIV() {
+ if (_i32(_rRt_) != 0) {
+ _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_);
+ _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_);
+ }
+}
+
+void psxDIVU() {
+ if (_rRt_ != 0) {
+ _rLo_ = _rRs_ / _rRt_;
+ _rHi_ = _rRs_ % _rRt_;
+ }
+}
+
+void psxMULT() {
+ u64 res = (s64)((s64)_i32(_rRs_) * (s64)_i32(_rRt_));
+
+ psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
+ psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
+}
+
+void psxMULTU() {
+ u64 res = (u64)((u64)_u32(_rRs_) * (u64)_u32(_rRt_));
+
+ psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
+ psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
+}
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, offset *
+*********************************************************/
+#define RepZBranchi32(op) if(_i32(_rRs_) op 0) doBranch(_BranchTarget_);
+#define RepZBranchLinki32(op) if(_i32(_rRs_) op 0) { _SetLink(31); doBranch(_BranchTarget_); }
+
+void psxBGEZ() { RepZBranchi32(>=) } // Branch if Rs >= 0
+void psxBGEZAL() { RepZBranchLinki32(>=) } // Branch if Rs >= 0 and link
+void psxBGTZ() { RepZBranchi32(>) } // Branch if Rs > 0
+void psxBLEZ() { RepZBranchi32(<=) } // Branch if Rs <= 0
+void psxBLTZ() { RepZBranchi32(<) } // Branch if Rs < 0
+void psxBLTZAL() { RepZBranchLinki32(<) } // Branch if Rs < 0 and link
+
+/*********************************************************
+* Shift arithmetic with constant shift *
+* Format: OP rd, rt, sa *
+*********************************************************/
+void psxSLL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa
+void psxSRA() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic)
+void psxSRL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical)
+
+/*********************************************************
+* Shift arithmetic with variant register shift *
+* Format: OP rd, rt, rs *
+*********************************************************/
+void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _u32(_rRs_); } // Rd = Rt << rs
+void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (arithmetic)
+void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (logical)
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+void psxLUI() { if (!_Rt_) return; _u32(_rRt_) = psxRegs.code << 16; } // Upper halfword of Rt = Im
+
+/*********************************************************
+* Move from HI/LO to GPR *
+* Format: OP rd *
+*********************************************************/
+void psxMFHI() { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi
+void psxMFLO() { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo
+
+/*********************************************************
+* Move to GPR to HI/LO & Register jump *
+* Format: OP rs *
+*********************************************************/
+void psxMTHI() { _rHi_ = _rRs_; } // Hi = Rs
+void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs
+
+/*********************************************************
+* Special purpose instructions *
+* Format: OP *
+*********************************************************/
+void psxBREAK() {
+ // Break exception - psx rom doens't handles this
+}
+
+void psxSYSCALL() {
+ psxRegs.pc -= 4;
+ psxException(0x20, branch);
+}
+
+void psxRFE() {
+// SysPrintf("psxRFE\n");
+ psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
+ ((psxRegs.CP0.n.Status & 0x3c) >> 2);
+}
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, rt, offset *
+*********************************************************/
+#define RepBranchi32(op) if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_);
+
+void psxBEQ() { RepBranchi32(==) } // Branch if Rs == Rt
+void psxBNE() { RepBranchi32(!=) } // Branch if Rs != Rt
+
+/*********************************************************
+* Jump to target *
+* Format: OP target *
+*********************************************************/
+void psxJ() { doBranch(_JumpTarget_); }
+void psxJAL() { _SetLink(31); doBranch(_JumpTarget_); }
+
+/*********************************************************
+* Register jump *
+* Format: OP rs, rd *
+*********************************************************/
+void psxJR() {
+ doBranch(_u32(_rRs_));
+ psxJumpTest();
+}
+
+void psxJALR() {
+ u32 temp = _u32(_rRs_);
+ if (_Rd_) { _SetLink(_Rd_); }
+ doBranch(temp);
+}
+
+/*********************************************************
+* Load and store for GPR *
+* Format: OP rt, offset(base) *
+*********************************************************/
+
+#define _oB_ (_u32(_rRs_) + _Imm_)
+
+void psxLB() {
+ if (_Rt_) {
+ _i32(_rRt_) = (signed char)psxMemRead8(_oB_);
+ } else {
+ psxMemRead8(_oB_);
+ }
+}
+
+void psxLBU() {
+ if (_Rt_) {
+ _u32(_rRt_) = psxMemRead8(_oB_);
+ } else {
+ psxMemRead8(_oB_);
+ }
+}
+
+void psxLH() {
+ if (_Rt_) {
+ _i32(_rRt_) = (short)psxMemRead16(_oB_);
+ } else {
+ psxMemRead16(_oB_);
+ }
+}
+
+void psxLHU() {
+ if (_Rt_) {
+ _u32(_rRt_) = psxMemRead16(_oB_);
+ } else {
+ psxMemRead16(_oB_);
+ }
+}
+
+void psxLW() {
+ if (_Rt_) {
+ _u32(_rRt_) = psxMemRead32(_oB_);
+ } else {
+ psxMemRead32(_oB_);
+ }
+}
+
+u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
+u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
+
+void psxLWL() {
+ u32 addr = _oB_;
+ u32 shift = addr & 3;
+ u32 mem = psxMemRead32(addr & ~3);
+
+ if (!_Rt_) return;
+ _u32(_rRt_) = ( _u32(_rRt_) & LWL_MASK[shift]) |
+ ( mem << LWL_SHIFT[shift]);
+
+ /*
+ Mem = 1234. Reg = abcd
+
+ 0 4bcd (mem << 24) | (reg & 0x00ffffff)
+ 1 34cd (mem << 16) | (reg & 0x0000ffff)
+ 2 234d (mem << 8) | (reg & 0x000000ff)
+ 3 1234 (mem ) | (reg & 0x00000000)
+ */
+}
+
+u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
+u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
+
+void psxLWR() {
+ u32 addr = _oB_;
+ u32 shift = addr & 3;
+ u32 mem = psxMemRead32(addr & ~3);
+
+ if (!_Rt_) return;
+ _u32(_rRt_) = ( _u32(_rRt_) & LWR_MASK[shift]) |
+ ( mem >> LWR_SHIFT[shift]);
+
+ /*
+ Mem = 1234. Reg = abcd
+
+ 0 1234 (mem ) | (reg & 0x00000000)
+ 1 a123 (mem >> 8) | (reg & 0xff000000)
+ 2 ab12 (mem >> 16) | (reg & 0xffff0000)
+ 3 abc1 (mem >> 24) | (reg & 0xffffff00)
+ */
+}
+
+void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); }
+void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); }
+void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); }
+
+u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 };
+u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
+
+void psxSWL() {
+ u32 addr = _oB_;
+ u32 shift = addr & 3;
+ u32 mem = psxMemRead32(addr & ~3);
+
+ psxMemWrite32(addr & ~3, (_u32(_rRt_) >> SWL_SHIFT[shift]) |
+ ( mem & SWL_MASK[shift]) );
+ /*
+ Mem = 1234. Reg = abcd
+
+ 0 123a (reg >> 24) | (mem & 0xffffff00)
+ 1 12ab (reg >> 16) | (mem & 0xffff0000)
+ 2 1abc (reg >> 8) | (mem & 0xff000000)
+ 3 abcd (reg ) | (mem & 0x00000000)
+ */
+}
+
+u32 SWR_MASK[4] = { 0, 0xff, 0xffff, 0xffffff };
+u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
+
+void psxSWR() {
+ u32 addr = _oB_;
+ u32 shift = addr & 3;
+ u32 mem = psxMemRead32(addr & ~3);
+
+ psxMemWrite32(addr & ~3, (_u32(_rRt_) << SWR_SHIFT[shift]) |
+ ( mem & SWR_MASK[shift]) );
+
+ /*
+ Mem = 1234. Reg = abcd
+
+ 0 abcd (reg ) | (mem & 0x00000000)
+ 1 bcd4 (reg << 8) | (mem & 0x000000ff)
+ 2 cd34 (reg << 16) | (mem & 0x0000ffff)
+ 3 d234 (reg << 24) | (mem & 0x00ffffff)
+ */
+}
+
+/*********************************************************
+* Moves between GPR and COPx *
+* Format: OP rt, fs *
+*********************************************************/
+void psxMFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
+void psxCFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; }
+
+void psxTestSWInts() {
+ // the next code is untested, if u know please
+ // tell me if it works ok or not (linuzappz)
+ if (psxRegs.CP0.n.Cause & psxRegs.CP0.n.Status & 0x0300 &&
+ psxRegs.CP0.n.Status & 0x1) {
+ psxException(psxRegs.CP0.n.Cause, branch);
+ }
+}
+
+__inline void MTC0(int reg, u32 val) {
+// SysPrintf("MTC0 %d: %x\n", reg, val);
+ switch (reg) {
+ case 12: // Status
+ psxRegs.CP0.r[12] = val;
+ psxTestSWInts();
+ psxRegs.interrupt|= 0x80000000;
+ break;
+
+ case 13: // Cause
+ psxRegs.CP0.n.Cause = val & ~(0xfc00);
+ psxTestSWInts();
+ break;
+
+ default:
+ psxRegs.CP0.r[reg] = val;
+ break;
+ }
+}
+
+void psxMTC0() { MTC0(_Rd_, _u32(_rRt_)); }
+void psxCTC0() { MTC0(_Rd_, _u32(_rRt_)); }
+
+/*********************************************************
+* Unknow instruction (would generate an exception) *
+* Format: ? *
+*********************************************************/
+void psxNULL() {
+#ifdef PSXCPU_LOG
+ PSXCPU_LOG("psx: Unimplemented op %x\n", psxRegs.code);
+#endif
+}
+
+void psxSPECIAL() {
+ psxSPC[_Funct_]();
+}
+
+void psxREGIMM() {
+ psxREG[_Rt_]();
+}
+
+void psxCOP0() {
+ psxCP0[_Rs_]();
+}
+
+void psxCOP2() {
+ psxCP2[_Funct_]();
+}
+
+void psxBASIC() {
+ psxCP2BSC[_Rs_]();
+}
+
+void psxHLE() {
+// psxHLEt[psxRegs.code & 0xffff]();
+ psxHLEt[psxRegs.code & 0x07](); // HDHOSHY experimental patch
+}
+
+void (*psxBSC[64])() = {
+ psxSPECIAL, psxREGIMM, psxJ , psxJAL , psxBEQ , psxBNE , psxBLEZ, psxBGTZ,
+ psxADDI , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI ,
+ psxCOP0 , psxNULL , psxCOP2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL , psxNULL , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
+ psxLB , psxLH , psxLWL , psxLW , psxLBU , psxLHU , psxLWR , psxNULL,
+ psxSB , psxSH , psxSWL , psxSW , psxNULL, psxNULL, psxSWR , psxNULL,
+ psxNULL , psxNULL , gteLWC2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL , psxNULL , gteSWC2, psxHLE , psxNULL, psxNULL, psxNULL, psxNULL
+};
+
+
+void (*psxSPC[64])() = {
+ psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV , psxNULL , psxSRLV, psxSRAV,
+ psxJR , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL,
+ psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL , psxNULL , psxNULL, psxNULL,
+ psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL , psxNULL , psxNULL, psxNULL,
+ psxADD , psxADDU , psxSUB , psxSUBU, psxAND , psxOR , psxXOR , psxNOR ,
+ psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL , psxNULL , psxNULL, psxNULL,
+ psxNULL, psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, psxNULL,
+ psxNULL, psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, psxNULL
+};
+
+void (*psxREG[32])() = {
+ psxBLTZ , psxBGEZ , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxBLTZAL, psxBGEZAL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
+};
+
+void (*psxCP0[32])() = {
+ psxMFC0, psxNULL, psxCFC0, psxNULL, psxMTC0, psxNULL, psxCTC0, psxNULL,
+ psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxRFE , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
+};
+
+void (*psxCP2[64])() = {
+ psxBASIC, gteRTPS , psxNULL , psxNULL, psxNULL, psxNULL , gteNCLIP, psxNULL, // 00
+ psxNULL , psxNULL , psxNULL , psxNULL, gteOP , psxNULL , psxNULL , psxNULL, // 08
+ gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , psxNULL , gteNCDT , psxNULL, // 10
+ psxNULL , psxNULL , psxNULL , gteNCCS, gteCC , psxNULL , gteNCS , psxNULL, // 18
+ gteNCT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 20
+ gteSQR , gteDCPL , gteDPCT , psxNULL, psxNULL, gteAVSZ3, gteAVSZ4, psxNULL, // 28
+ gteRTPT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 30
+ psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, gteGPF , gteGPL , gteNCCT // 38
+};
+
+void (*psxCP2BSC[32])() = {
+ gteMFC2, psxNULL, gteCFC2, psxNULL, gteMTC2, psxNULL, gteCTC2, psxNULL,
+ psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
+ psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
+};
+
+
+///////////////////////////////////////////
+
+static int intInit() {
+ return 0;
+}
+
+static void intReset() {
+}
+
+static void intExecute() {
+ for (;;)
+ execI();
+}
+
+static void intExecuteDbg() {
+ for (;;)
+ execIDbg();
+}
+
+static void intExecuteBlock() {
+ branch2 = 0;
+ while (!branch2) execI();
+}
+
+static void intExecuteBlockDbg() {
+ branch2 = 0;
+ while (!branch2) execIDbg();
+}
+
+static void intClear(u32 Addr, u32 Size) {
+}
+
+static void intShutdown() {
+}
+
+// interpreter execution
+inline void execI() {
+ u32 *code = (u32 *)PSXM(psxRegs.pc);
+ psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
+
+ debugI();
+
+ psxRegs.pc += 4;
+ psxRegs.cycle++;
+
+ psxBSC[psxRegs.code >> 26]();
+}
+
+/* debugger version */
+inline void execIDbg() {
+ u32 *code = (u32 *)PSXM(psxRegs.pc);
+ psxRegs.code = ((code == NULL) ? 0 : SWAP32(*code));
+
+ // dump opcode when LOG_CPU is enabled
+ debugI();
+
+ // normal execution
+ if (!hdb_pause) {
+ psxRegs.pc += 4;
+ psxRegs.cycle++;
+ psxBSC[psxRegs.code >> 26]();
+ }
+
+ // trace one instruction
+ if(hdb_pause == 2) {
+ psxRegs.pc += 4;
+ psxRegs.cycle++;
+ psxBSC[psxRegs.code >> 26]();
+ hdb_pause = 1;
+ }
+
+ // wait for breakpoint
+ if(hdb_pause == 3) {
+ psxRegs.pc+= 4; psxRegs.cycle++;
+ psxBSC[psxRegs.code >> 26]();
+ if(psxRegs.pc == hdb_break) hdb_pause = 1;
+ }
+}
+
+R3000Acpu psxInt = {
+ intInit,
+ intReset,
+ intExecute,
+ intExecuteBlock,
+ intClear,
+ intShutdown
+};
+
+R3000Acpu psxIntDbg = {
+ intInit,
+ intReset,
+ intExecuteDbg,
+ intExecuteBlockDbg,
+ intClear,
+ intShutdown
+};
diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c
new file mode 100644
index 00000000..8dfc00e6
--- /dev/null
+++ b/libpcsxcore/psxmem.c
@@ -0,0 +1,324 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* PSX memory functions.
+*/
+
+#include "psxmem.h"
+#include "r3000a.h"
+#include "psxhw.h"
+#include <sys/mman.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/* Playstation Memory Map (from Playstation doc by Joshua Walker)
+0x0000_0000-0x0000_ffff Kernel (64K)
+0x0001_0000-0x001f_ffff User Memory (1.9 Meg)
+
+0x1f00_0000-0x1f00_ffff Parallel Port (64K)
+
+0x1f80_0000-0x1f80_03ff Scratch Pad (1024 bytes)
+
+0x1f80_1000-0x1f80_2fff Hardware Registers (8K)
+
+0x8000_0000-0x801f_ffff Kernel and User Memory Mirror (2 Meg) Cached
+
+0xa000_0000-0xa01f_ffff Kernel and User Memory Mirror (2 Meg) Uncached
+
+0xbfc0_0000-0xbfc7_ffff BIOS (512K)
+*/
+
+int psxMemInit() {
+ int i;
+
+ psxMemRLUT = (u8**)malloc(0x10000 * sizeof(void*));
+ psxMemWLUT = (u8**)malloc(0x10000 * sizeof(void*));
+ memset(psxMemRLUT, 0, 0x10000 * sizeof(void*));
+ memset(psxMemWLUT, 0, 0x10000 * sizeof(void*));
+
+ psxM = mmap(0, 0x00220000,
+ PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ psxP = &psxM[0x200000];
+ psxH = &psxM[0x210000];
+
+ psxR = (char*)malloc(0x00080000);
+
+ if (psxMemRLUT == NULL || psxMemWLUT == NULL ||
+ psxM == NULL || psxP == NULL || psxH == NULL) {
+ SysMessage(_("Error allocating memory!"));
+ return -1;
+ }
+
+// MemR
+ for (i=0; i<0x80; i++) psxMemRLUT[i + 0x0000] = (u8*)&psxM[(i & 0x1f) << 16];
+
+ memcpy(psxMemRLUT + 0x8000, psxMemRLUT, 0x80 * sizeof(void*));
+ memcpy(psxMemRLUT + 0xa000, psxMemRLUT, 0x80 * sizeof(void*));
+
+ for (i=0; i<0x01; i++) psxMemRLUT[i + 0x1f00] = (u8*)&psxP[i << 16];
+
+ for (i=0; i<0x01; i++) psxMemRLUT[i + 0x1f80] = (u8*)&psxH[i << 16];
+
+ for (i=0; i<0x08; i++) psxMemRLUT[i + 0xbfc0] = (u8*)&psxR[i << 16];
+
+// MemW
+ for (i=0; i<0x80; i++) psxMemWLUT[i + 0x0000] = (u8*)&psxM[(i & 0x1f) << 16];
+ memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void*));
+ memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void*));
+
+ for (i=0; i<0x01; i++) psxMemWLUT[i + 0x1f00] = (u8*)&psxP[i << 16];
+
+ for (i=0; i<0x01; i++) psxMemWLUT[i + 0x1f80] = (u8*)&psxH[i << 16];
+
+ return 0;
+}
+
+void psxMemReset() {
+ FILE *f = NULL;
+ char bios[1024];
+
+ memset(psxM, 0, 0x00200000);
+ memset(psxP, 0, 0x00010000);
+
+ if (strcmp(Config.Bios, "HLE")) {
+ sprintf(bios, "%s/%s", Config.BiosDir, Config.Bios);
+ f = fopen(bios, "rb");
+
+ if (f == NULL) {
+ SysMessage (_("Could not open BIOS:\"%s\". Enabling HLE Bios!\n"), bios);
+ memset(psxR, 0, 0x80000);
+ Config.HLE = BIOS_HLE;
+ }
+ else {
+ fread(psxR, 1, 0x80000, f);
+ fclose(f);
+ Config.HLE = BIOS_USER_DEFINED;
+ }
+ } else Config.HLE = BIOS_HLE;
+}
+
+void psxMemShutdown() {
+ munmap(psxM, 0x00220000);
+
+ free(psxR);
+ free(psxMemRLUT);
+ free(psxMemWLUT);
+}
+
+static int writeok = 1;
+
+u8 psxMemRead8(u32 mem) {
+ char *p;
+ u32 t;
+
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ return psxHu8(mem);
+ else
+ return psxHwRead8(mem);
+ } else {
+ p = (char *)(psxMemRLUT[t]);
+ if (p != NULL) {
+ return *(u8 *)(p + (mem & 0xffff));
+ } else {
+#ifdef PSXMEM_LOG
+ PSXMEM_LOG("err lb %8.8lx\n", mem);
+#endif
+ return 0;
+ }
+ }
+}
+
+u16 psxMemRead16(u32 mem) {
+ char *p;
+ u32 t;
+
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ return psxHu16(mem);
+ else
+ return psxHwRead16(mem);
+ } else {
+ p = (char *)(psxMemRLUT[t]);
+ if (p != NULL) {
+ return SWAPu16(*(u16 *)(p + (mem & 0xffff)));
+ } else {
+#ifdef PSXMEM_LOG
+ PSXMEM_LOG("err lh %8.8lx\n", mem);
+#endif
+ return 0;
+ }
+ }
+}
+
+u32 psxMemRead32(u32 mem) {
+ char *p;
+ u32 t;
+
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ return psxHu32(mem);
+ else
+ return psxHwRead32(mem);
+ } else {
+ p = (char *)(psxMemRLUT[t]);
+ if (p != NULL) {
+ return SWAPu32(*(u32 *)(p + (mem & 0xffff)));
+ } else {
+#ifdef PSXMEM_LOG
+ if (writeok) { PSXMEM_LOG("err lw %8.8lx\n", mem); }
+#endif
+ return 0;
+ }
+ }
+}
+
+void psxMemWrite8(u32 mem, u8 value) {
+ char *p;
+ u32 t;
+
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ psxHu8(mem) = value;
+ else
+ psxHwWrite8(mem, value);
+ } else {
+ p = (char *)(psxMemWLUT[t]);
+ if (p != NULL) {
+ *(u8 *)(p + (mem & 0xffff)) = value;
+#ifdef PSXREC
+ psxCpu->Clear((mem & (~3)), 1);
+#endif
+ } else {
+#ifdef PSXMEM_LOG
+ PSXMEM_LOG("err sb %8.8lx\n", mem);
+#endif
+ }
+ }
+}
+
+void psxMemWrite16(u32 mem, u16 value) {
+ char *p;
+ u32 t;
+
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ psxHu16ref(mem) = SWAPu16(value);
+ else
+ psxHwWrite16(mem, value);
+ } else {
+ p = (char *)(psxMemWLUT[t]);
+ if (p != NULL) {
+ *(u16 *)(p + (mem & 0xffff)) = SWAPu16(value);
+#ifdef PSXREC
+ psxCpu->Clear((mem & (~1)), 1);
+#endif
+ } else {
+#ifdef PSXMEM_LOG
+ PSXMEM_LOG("err sh %8.8lx\n", mem);
+#endif
+ }
+ }
+}
+
+void psxMemWrite32(u32 mem, u32 value) {
+ char *p;
+ u32 t;
+
+// if ((mem&0x1fffff) == 0x71E18 || value == 0x48088800) SysPrintf("t2fix!!\n");
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ psxHu32ref(mem) = SWAPu32(value);
+ else
+ psxHwWrite32(mem, value);
+ } else {
+ p = (char *)(psxMemWLUT[t]);
+ if (p != NULL) {
+ *(u32 *)(p + (mem & 0xffff)) = SWAPu32(value);
+#ifdef PSXREC
+ psxCpu->Clear(mem, 1);
+#endif
+ } else {
+ if (mem != 0xfffe0130) {
+#ifdef PSXREC
+ if (!writeok)
+ psxCpu->Clear(mem, 1);
+#endif
+
+#ifdef PSXMEM_LOG
+ if (writeok) { PSXMEM_LOG("err sw %8.8lx\n", mem); }
+#endif
+ } else {
+ int i;
+
+ switch (value) {
+ case 0x800: case 0x804:
+ if (writeok == 0) break;
+ writeok = 0;
+ memset(psxMemWLUT + 0x0000, 0, 0x80 * sizeof(void*));
+ memset(psxMemWLUT + 0x8000, 0, 0x80 * sizeof(void*));
+ memset(psxMemWLUT + 0xa000, 0, 0x80 * sizeof(void*));
+ break;
+ case 0x1e988:
+ if (writeok == 1) break;
+ writeok = 1;
+ for (i=0; i<0x80; i++) psxMemWLUT[i + 0x0000] = (void*)&psxM[(i & 0x1f) << 16];
+ memcpy(psxMemWLUT + 0x8000, psxMemWLUT, 0x80 * sizeof(void*));
+ memcpy(psxMemWLUT + 0xa000, psxMemWLUT, 0x80 * sizeof(void*));
+ break;
+ default:
+#ifdef PSXMEM_LOG
+ PSXMEM_LOG("unk %8.8lx = %x\n", mem, value);
+#endif
+ break;
+ }
+ }
+ }
+ }
+}
+
+void *psxMemPointer(u32 mem) {
+ char *p;
+ u32 t;
+
+ t = mem >> 16;
+ if (t == 0x1f80) {
+ if (mem < 0x1f801000)
+ return (void *)&psxH[mem];
+ else
+ return NULL;
+ } else {
+ p = (char *)(psxMemWLUT[t]);
+ if (p != NULL) {
+ return (void *)(p + (mem & 0xffff));
+ }
+ return NULL;
+ }
+}
diff --git a/libpcsxcore/psxmem.h b/libpcsxcore/psxmem.h
new file mode 100644
index 00000000..cc4616c6
--- /dev/null
+++ b/libpcsxcore/psxmem.h
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __PSXMEMORY_H__
+#define __PSXMEMORY_H__
+
+#include "psxcommon.h"
+
+#if defined(__BIGENDIAN__)
+
+#define _SWAP16(b) ((((unsigned char*)&(b))[0]&0xff) | (((unsigned char*)&(b))[1]&0xff)<<8)
+#define _SWAP32(b) ((((unsigned char*)&(b))[0]&0xff) | ((((unsigned char*)&(b))[1]&0xff)<<8) | ((((unsigned char*)&(b))[2]&0xff)<<16) | (((unsigned char*)&(b))[3]<<24))
+
+#define SWAP16(v) ((((v)&0xff00)>>8) +(((v)&0xff)<<8))
+#define SWAP32(v) ((((v)&0xff000000ul)>>24) + (((v)&0xff0000ul)>>8) + (((v)&0xff00ul)<<8) +(((v)&0xfful)<<24))
+#define SWAPu32(v) SWAP32((u32)(v))
+#define SWAPs32(v) SWAP32((s32)(v))
+
+#define SWAPu16(v) SWAP16((u16)(v))
+#define SWAPs16(v) SWAP16((s16)(v))
+
+#else
+
+#define SWAP16(b) (b)
+#define SWAP32(b) (b)
+
+#define SWAPu16(b) (b)
+#define SWAPu32(b) (b)
+
+#endif
+
+s8 *psxM;
+#define psxMs8(mem) psxM[(mem) & 0x1fffff]
+#define psxMs16(mem) (SWAP16(*(s16*)&psxM[(mem) & 0x1fffff]))
+#define psxMs32(mem) (SWAP32(*(s32*)&psxM[(mem) & 0x1fffff]))
+#define psxMu8(mem) (*(u8*)&psxM[(mem) & 0x1fffff]))
+#define psxMu16(mem) (SWAP16(*(u16*)&psxM[(mem) & 0x1fffff]))
+#define psxMu32(mem) (SWAP32(*(u32*)&psxM[(mem) & 0x1fffff]))
+
+#define psxMs8ref(mem) psxM[(mem) & 0x1fffff]
+#define psxMs16ref(mem) (*(s16*)&psxM[(mem) & 0x1fffff])
+#define psxMs32ref(mem) (*(s32*)&psxM[(mem) & 0x1fffff])
+#define psxMu8ref(mem) (*(u8*) &psxM[(mem) & 0x1fffff])
+#define psxMu16ref(mem) (*(u16*)&psxM[(mem) & 0x1fffff])
+#define psxMu32ref(mem) (*(u32*)&psxM[(mem) & 0x1fffff])
+
+s8 *psxP;
+#define psxPs8(mem) psxP[(mem) & 0xffff]
+#define psxPs16(mem) (SWAP16(*(s16*)&psxP[(mem) & 0xffff]))
+#define psxPs32(mem) (SWAP32(*(s32*)&psxP[(mem) & 0xffff]))
+#define psxPu8(mem) (*(u8*) &psxP[(mem) & 0xffff])
+#define psxPu16(mem) (SWAP16(*(u16*)&psxP[(mem) & 0xffff]))
+#define psxPu32(mem) (SWAP32(*(u32*)&psxP[(mem) & 0xffff]))
+
+#define psxPs8ref(mem) psxP[(mem) & 0xffff]
+#define psxPs16ref(mem) (*(s16*)&psxP[(mem) & 0xffff])
+#define psxPs32ref(mem) (*(s32*)&psxP[(mem) & 0xffff])
+#define psxPu8ref(mem) (*(u8*) &psxP[(mem) & 0xffff])
+#define psxPu16ref(mem) (*(u16*)&psxP[(mem) & 0xffff])
+#define psxPu32ref(mem) (*(u32*)&psxP[(mem) & 0xffff])
+
+s8 *psxR;
+#define psxRs8(mem) psxR[(mem) & 0x7ffff]
+#define psxRs16(mem) (SWAP16(*(s16*)&psxR[(mem) & 0x7ffff]))
+#define psxRs32(mem) (SWAP32(*(s32*)&psxR[(mem) & 0x7ffff]))
+#define psxRu8(mem) (*(u8* )&psxR[(mem) & 0x7ffff])
+#define psxRu16(mem) (SWAP16(*(u16*)&psxR[(mem) & 0x7ffff]))
+#define psxRu32(mem) (SWAP32(*(u32*)&psxR[(mem) & 0x7ffff]))
+
+#define psxRs8ref(mem) psxR[(mem) & 0x7ffff]
+#define psxRs16ref(mem) (*(s16*)&psxR[(mem) & 0x7ffff])
+#define psxRs32ref(mem) (*(s32*)&psxR[(mem) & 0x7ffff])
+#define psxRu8ref(mem) (*(u8* )&psxR[(mem) & 0x7ffff])
+#define psxRu16ref(mem) (*(u16*)&psxR[(mem) & 0x7ffff])
+#define psxRu32ref(mem) (*(u32*)&psxR[(mem) & 0x7ffff])
+
+s8 *psxH;
+#define psxHs8(mem) psxH[(mem) & 0xffff]
+#define psxHs16(mem) (SWAP16(*(s16*)&psxH[(mem) & 0xffff]))
+#define psxHs32(mem) (SWAP32(*(s32*)&psxH[(mem) & 0xffff]))
+#define psxHu8(mem) (*(u8*) &psxH[(mem) & 0xffff])
+#define psxHu16(mem) (SWAP16(*(u16*)&psxH[(mem) & 0xffff]))
+#define psxHu32(mem) (SWAP32(*(u32*)&psxH[(mem) & 0xffff]))
+
+#define psxHs8ref(mem) psxH[(mem) & 0xffff]
+#define psxHs16ref(mem) (*(s16*)&psxH[(mem) & 0xffff])
+#define psxHs32ref(mem) (*(s32*)&psxH[(mem) & 0xffff])
+#define psxHu8ref(mem) (*(u8*) &psxH[(mem) & 0xffff])
+#define psxHu16ref(mem) (*(u16*)&psxH[(mem) & 0xffff])
+#define psxHu32ref(mem) (*(u32*)&psxH[(mem) & 0xffff])
+
+u8** psxMemWLUT;
+u8** psxMemRLUT;
+
+#define PSXM(mem) (psxMemRLUT[(mem) >> 16] == 0 ? NULL : (u8*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)))
+#define PSXMs8(mem) (*(s8 *)PSXM(mem))
+#define PSXMs16(mem) (SWAP16(*(s16*)PSXM(mem)))
+#define PSXMs32(mem) (SWAP32(*(s32*)PSXM(mem)))
+#define PSXMu8(mem) (*(u8 *)PSXM(mem))
+#define PSXMu16(mem) (SWAP16(*(u16*)PSXM(mem)))
+#define PSXMu32(mem) (SWAP32(*(u32*)PSXM(mem)))
+
+#define PSXMu32ref(mem) (*(u32*)PSXM(mem))
+
+
+#if !defined(PSXREC) && (defined(__x86_64__) || defined(__i386__) || defined(__sh__) || defined(__ppc__)) && !defined(NOPSXREC)
+#define PSXREC
+#endif
+
+int psxMemInit();
+void psxMemReset();
+void psxMemShutdown();
+
+u8 psxMemRead8 (u32 mem);
+u16 psxMemRead16(u32 mem);
+u32 psxMemRead32(u32 mem);
+void psxMemWrite8 (u32 mem, u8 value);
+void psxMemWrite16(u32 mem, u16 value);
+void psxMemWrite32(u32 mem, u32 value);
+void *psxMemPointer(u32 mem);
+
+#endif /* __PSXMEMORY_H__ */
+
diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c
new file mode 100644
index 00000000..b46ec124
--- /dev/null
+++ b/libpcsxcore/r3000a.c
@@ -0,0 +1,209 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* R3000A CPU functions.
+*/
+
+#include "r3000a.h"
+#include "cdrom.h"
+#include "mdec.h"
+#include "gte.h"
+#include "cheat.h"
+
+psxRegisters psxRegs;
+
+int psxInit() {
+ SysPrintf(_("Running PCSX Version %s (%s).\n"), PACKAGE_VERSION, __DATE__);
+
+#ifdef PSXREC
+ if (Config.Cpu) {
+ if (Config.Dbg) psxCpu = &psxIntDbg;
+ else psxCpu = &psxInt;
+ } else psxCpu = &psxRec;
+#else
+ if (Config.Dbg) psxCpu = &psxIntDbg;
+ else psxCpu = &psxInt;
+#endif
+
+ Log = 0;
+
+ if (psxMemInit() == -1) return -1;
+
+ return psxCpu->Init();
+}
+
+void psxReset() {
+ psxCpu->Reset();
+
+ psxMemReset();
+
+ memset(&psxRegs, 0, sizeof(psxRegs));
+
+ psxRegs.pc = 0xbfc00000; // Start in bootstrap
+
+ psxRegs.CP0.r[12] = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1
+ psxRegs.CP0.r[15] = 0x00000002; // PRevID = Revision ID, same as R3000A
+
+ psxHwReset();
+ psxBiosInit();
+
+ if (!Config.HLE)
+ psxExecuteBios();
+
+#ifdef EMU_LOG
+ EMU_LOG("*BIOS END*\n");
+#endif
+ Log = 0;
+}
+
+void psxShutdown() {
+ psxMemShutdown();
+ psxBiosShutdown();
+
+ psxCpu->Shutdown();
+
+ ClearAllCheats();
+}
+
+void psxException(u32 code, u32 bd) {
+ // Set the Cause
+ psxRegs.CP0.n.Cause = code;
+
+ // Set the EPC & PC
+ if (bd) {
+#ifdef PSXCPU_LOG
+ PSXCPU_LOG("bd set!!!\n");
+#endif
+ SysPrintf("bd set!!!\n");
+ psxRegs.CP0.n.Cause|= 0x80000000;
+ psxRegs.CP0.n.EPC = (psxRegs.pc - 4);
+ } else
+ psxRegs.CP0.n.EPC = (psxRegs.pc);
+
+ if (psxRegs.CP0.n.Status & 0x400000)
+ psxRegs.pc = 0xbfc00180;
+ else
+ psxRegs.pc = 0x80000080;
+
+ // Set the Status
+ psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status &~0x3f) |
+ ((psxRegs.CP0.n.Status & 0xf) << 2);
+
+ if (!Config.HLE && (((PSXMu32(psxRegs.CP0.n.EPC) >> 24) & 0xfe) == 0x4a)) {
+ // "hokuto no ken" / "Crash Bandicot 2" ... fix
+ PSXMu32ref(psxRegs.CP0.n.EPC)&= SWAPu32(~0x02000000);
+ }
+
+ if (Config.HLE) psxBiosException();
+}
+
+void psxBranchTest() {
+ if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter)
+ psxRcntUpdate();
+
+ if (psxRegs.interrupt) {
+ if ((psxRegs.interrupt & 0x80) && (!Config.Sio)) { // sio
+ if ((psxRegs.cycle - psxRegs.intCycle[7]) >= psxRegs.intCycle[7+1]) {
+ psxRegs.interrupt&=~0x80;
+ sioInterrupt();
+ }
+ }
+ if (psxRegs.interrupt & 0x04) { // cdr
+ if ((psxRegs.cycle - psxRegs.intCycle[2]) >= psxRegs.intCycle[2+1]) {
+ psxRegs.interrupt&=~0x04;
+ cdrInterrupt();
+ }
+ }
+ if (psxRegs.interrupt & 0x040000) { // cdr read
+ if ((psxRegs.cycle - psxRegs.intCycle[2+16]) >= psxRegs.intCycle[2+16+1]) {
+ psxRegs.interrupt&=~0x040000;
+ cdrReadInterrupt();
+ }
+ }
+ if (psxRegs.interrupt & 0x01000000) { // gpu dma
+ if ((psxRegs.cycle - psxRegs.intCycle[3+24]) >= psxRegs.intCycle[3+24+1]) {
+ psxRegs.interrupt&=~0x01000000;
+ gpuInterrupt();
+ }
+ }
+ if (psxRegs.interrupt & 0x02000000) { // mdec out dma
+ if ((psxRegs.cycle - psxRegs.intCycle[5+24]) >= psxRegs.intCycle[5+24+1]) {
+ psxRegs.interrupt&=~0x02000000;
+ mdec1Interrupt();
+ }
+ }
+
+ if (psxRegs.interrupt & 0x80000000) {
+ psxRegs.interrupt&=~0x80000000;
+ psxTestHWInts();
+ }
+ }
+// if (psxRegs.cycle > 0xd29c6500) Log=1;
+}
+
+void psxTestHWInts() {
+ if (psxHu32(0x1070) & psxHu32(0x1074)) {
+ if ((psxRegs.CP0.n.Status & 0x401) == 0x401) {
+#ifdef PSXCPU_LOG
+ PSXCPU_LOG("Interrupt: %x %x\n", psxHu32(0x1070), psxHu32(0x1074));
+#endif
+// SysPrintf("Interrupt (%x): %x %x\n", psxRegs.cycle, psxHu32(0x1070), psxHu32(0x1074));
+ psxException(0x400, 0);
+ }
+ }
+}
+
+void psxJumpTest() {
+ if (!Config.HLE && Config.PsxOut) {
+ u32 call = psxRegs.GPR.n.t1 & 0xff;
+ switch (psxRegs.pc & 0x1fffff) {
+ case 0xa0:
+#ifdef PSXBIOS_LOG
+ if (call != 0x28 && call != 0xe) {
+ PSXBIOS_LOG("Bios call a0: %s (%x) %x,%x,%x,%x\n", biosA0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); }
+#endif
+ if (biosA0[call])
+ biosA0[call]();
+ break;
+ case 0xb0:
+#ifdef PSXBIOS_LOG
+ if (call != 0x17 && call != 0xb) {
+ PSXBIOS_LOG("Bios call b0: %s (%x) %x,%x,%x,%x\n", biosB0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); }
+#endif
+ if (biosB0[call])
+ biosB0[call]();
+ break;
+ case 0xc0:
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("Bios call c0: %s (%x) %x,%x,%x,%x\n", biosC0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3);
+#endif
+ if (biosC0[call])
+ biosC0[call]();
+ break;
+ }
+ }
+}
+
+void psxExecuteBios() {
+ while (psxRegs.pc != 0x80030000)
+ psxCpu->ExecuteBlock();
+}
+
diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h
new file mode 100644
index 00000000..56c965fc
--- /dev/null
+++ b/libpcsxcore/r3000a.h
@@ -0,0 +1,224 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __R3000A_H__
+#define __R3000A_H__
+
+#include "psxcommon.h"
+#include "psxmem.h"
+#include "psxcounters.h"
+#include "psxbios.h"
+
+typedef struct {
+ int (*Init)();
+ void (*Reset)();
+ void (*Execute)(); /* executes up to a break */
+ void (*ExecuteBlock)(); /* executes up to a jump */
+ void (*Clear)(u32 Addr, u32 Size);
+ void (*Shutdown)();
+} R3000Acpu;
+
+R3000Acpu *psxCpu;
+extern R3000Acpu psxInt;
+extern R3000Acpu psxIntDbg;
+#if (defined(__x86_64__) || defined(__i386__) || defined(__sh__) || defined(__ppc__)) && !defined(NOPSXREC)
+extern R3000Acpu psxRec;
+#define PSXREC
+#endif
+
+typedef union {
+ struct {
+ u32 r0, at, v0, v1, a0, a1, a2, a3,
+ t0, t1, t2, t3, t4, t5, t6, t7,
+ s0, s1, s2, s3, s4, s5, s6, s7,
+ t8, t9, k0, k1, gp, sp, s8, ra, lo, hi;
+ } n;
+ u32 r[34]; /* Lo, Hi in r[33] and r[34] */
+} psxGPRRegs;
+
+typedef union {
+ struct {
+ u32 Index, Random, EntryLo0, EntryLo1,
+ Context, PageMask, Wired, Reserved0,
+ BadVAddr, Count, EntryHi, Compare,
+ Status, Cause, EPC, PRid,
+ Config, LLAddr, WatchLO, WatchHI,
+ XContext, Reserved1, Reserved2, Reserved3,
+ Reserved4, Reserved5, ECC, CacheErr,
+ TagLo, TagHi, ErrorEPC, Reserved6;
+ } n;
+ u32 r[32];
+} psxCP0Regs;
+
+typedef struct {
+ short x, y;
+} SVector2D;
+
+typedef struct {
+ short z, pad;
+} SVector2Dz;
+
+typedef struct {
+ short x, y, z, pad;
+} SVector3D;
+
+typedef struct {
+ short x, y, z, pad;
+} LVector3D;
+
+typedef struct {
+ unsigned char r, g, b, c;
+} CBGR;
+
+typedef struct {
+ short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad;
+} SMatrix3D;
+
+typedef union {
+ struct {
+ SVector3D v0, v1, v2;
+ CBGR rgb;
+ s32 otz;
+ s32 ir0, ir1, ir2, ir3;
+ SVector2D sxy0, sxy1, sxy2, sxyp;
+ SVector2Dz sz0, sz1, sz2, sz3;
+ CBGR rgb0, rgb1, rgb2;
+ s32 reserved;
+ s32 mac0, mac1, mac2, mac3;
+ u32 irgb, orgb;
+ s32 lzcs, lzcr;
+ } n;
+ u32 r[32];
+} psxCP2Data;
+
+typedef union {
+ struct {
+ SMatrix3D rMatrix;
+ s32 trX, trY, trZ;
+ SMatrix3D lMatrix;
+ s32 rbk, gbk, bbk;
+ SMatrix3D cMatrix;
+ s32 rfc, gfc, bfc;
+ s32 ofx, ofy;
+ s32 h;
+ s32 dqa, dqb;
+ s32 zsf3, zsf4;
+ s32 flag;
+ } n;
+ u32 r[32];
+} psxCP2Ctrl;
+
+typedef struct {
+ psxGPRRegs GPR; /* General Purpose Registers */
+ psxCP0Regs CP0; /* Coprocessor0 Registers */
+ psxCP2Data CP2D; /* Cop2 data registers */
+ psxCP2Ctrl CP2C; /* Cop2 control registers */
+ u32 pc; /* Program counter */
+ u32 code; /* The instruction */
+ u32 cycle;
+ u32 interrupt;
+ u32 intCycle[32];
+} psxRegisters;
+
+extern psxRegisters psxRegs;
+
+#if defined(__BIGENDIAN__)
+
+#define _i32(x) *(s32 *)&x
+#define _u32(x) x
+
+#define _i16(x) (((short *)&x)[1])
+#define _u16(x) (((unsigned short *)&x)[1])
+
+#define _i8(x) (((char *)&x)[3])
+#define _u8(x) (((unsigned char *)&x)[3])
+
+#else
+
+#define _i32(x) *(s32 *)&x
+#define _u32(x) x
+
+#define _i16(x) *(short *)&x
+#define _u16(x) *(unsigned short *)&x
+
+#define _i8(x) *(char *)&x
+#define _u8(x) *(unsigned char *)&x
+
+#endif
+
+/**** R3000A Instruction Macros ****/
+#define _PC_ psxRegs.pc // The next PC to be executed
+
+#define _fOp_(code) ((code >> 26) ) // The opcode part of the instruction register
+#define _fFunct_(code) ((code ) & 0x3F) // The funct part of the instruction register
+#define _fRd_(code) ((code >> 11) & 0x1F) // The rd part of the instruction register
+#define _fRt_(code) ((code >> 16) & 0x1F) // The rt part of the instruction register
+#define _fRs_(code) ((code >> 21) & 0x1F) // The rs part of the instruction register
+#define _fSa_(code) ((code >> 6) & 0x1F) // The sa part of the instruction register
+#define _fIm_(code) ((u16)code) // The immediate part of the instruction register
+#define _fTarget_(code) (code & 0x03ffffff) // The target part of the instruction register
+
+#define _fImm_(code) ((s16)code) // sign-extended immediate
+#define _fImmU_(code) (code&0xffff) // zero-extended immediate
+
+#define _Op_ _fOp_(psxRegs.code)
+#define _Funct_ _fFunct_(psxRegs.code)
+#define _Rd_ _fRd_(psxRegs.code)
+#define _Rt_ _fRt_(psxRegs.code)
+#define _Rs_ _fRs_(psxRegs.code)
+#define _Sa_ _fSa_(psxRegs.code)
+#define _Im_ _fIm_(psxRegs.code)
+#define _Target_ _fTarget_(psxRegs.code)
+
+#define _Imm_ _fImm_(psxRegs.code)
+#define _ImmU_ _fImmU_(psxRegs.code)
+
+#define _rRs_ psxRegs.GPR.r[_Rs_] // Rs register
+#define _rRt_ psxRegs.GPR.r[_Rt_] // Rt register
+#define _rRd_ psxRegs.GPR.r[_Rd_] // Rd register
+#define _rSa_ psxRegs.GPR.r[_Sa_] // Sa register
+#define _rFs_ psxRegs.CP0.r[_Rd_] // Fs register
+
+#define _c2dRs_ psxRegs.CP2D.r[_Rs_] // Rs cop2 data register
+#define _c2dRt_ psxRegs.CP2D.r[_Rt_] // Rt cop2 data register
+#define _c2dRd_ psxRegs.CP2D.r[_Rd_] // Rd cop2 data register
+#define _c2dSa_ psxRegs.CP2D.r[_Sa_] // Sa cop2 data register
+
+#define _rHi_ psxRegs.GPR.n.hi // The HI register
+#define _rLo_ psxRegs.GPR.n.lo // The LO register
+
+#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction
+#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction
+
+#define _SetLink(x) psxRegs.GPR.r[x] = _PC_ + 4; // Sets the return address in the link register
+
+int psxInit();
+void psxReset();
+void psxShutdown();
+void psxException(u32 code, u32 bd);
+void psxBranchTest();
+void psxExecuteBios();
+int psxTestLoadDelay(int reg, u32 tmp);
+void psxDelayTest(int reg, u32 bpc);
+void psxTestSWInts();
+void psxTestHWInts();
+void psxJumpTest();
+
+#endif /* __R3000A_H__ */
diff --git a/libpcsxcore/sio.c b/libpcsxcore/sio.c
new file mode 100644
index 00000000..6e98d1fb
--- /dev/null
+++ b/libpcsxcore/sio.c
@@ -0,0 +1,673 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* SIO functions.
+*/
+
+#include "sio.h"
+#include <sys/stat.h>
+
+// *** FOR WORKS ON PADS AND MEMORY CARDS *****
+
+static unsigned char buf[256];
+unsigned char cardh[4] = { 0x00, 0x00, 0x5a, 0x5d };
+
+//static unsigned short StatReg = 0x002b;
+// Transfer Ready and the Buffer is Empty
+unsigned short StatReg = TX_RDY | TX_EMPTY;
+unsigned short ModeReg;
+unsigned short CtrlReg;
+unsigned short BaudReg;
+
+static unsigned int bufcount;
+static unsigned int parp;
+static unsigned int mcdst,rdwr;
+static unsigned char adrH,adrL;
+static unsigned int padst;
+
+PadDataS pad;
+
+char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE];
+
+// clk cycle byte
+// 4us * 8bits = ((PSXCLK / 1000000) * 32) / BIAS; (linuzappz)
+#define SIO_INT() { \
+ if (!Config.Sio) { \
+ psxRegs.interrupt|= 0x80; \
+ psxRegs.intCycle[7+1] = 200; /*270;*/ \
+ psxRegs.intCycle[7] = psxRegs.cycle; \
+ } \
+}
+
+unsigned char sioRead8() {
+ unsigned char ret = 0;
+
+ if ((StatReg & RX_RDY)/* && (CtrlReg & RX_PERM)*/) {
+// StatReg &= ~RX_OVERRUN;
+ ret = buf[parp];
+ if (parp == bufcount) {
+ StatReg &= ~RX_RDY; // Receive is not Ready now
+ if (mcdst == 5) {
+ mcdst = 0;
+ if (rdwr == 2) {
+ switch (CtrlReg&0x2002) {
+ case 0x0002:
+ memcpy(Mcd1Data + (adrL | (adrH << 8)) * 128, &buf[1], 128);
+ SaveMcd(Config.Mcd1, Mcd1Data, (adrL | (adrH << 8)) * 128, 128);
+ break;
+ case 0x2002:
+ memcpy(Mcd2Data + (adrL | (adrH << 8)) * 128, &buf[1], 128);
+ SaveMcd(Config.Mcd2, Mcd2Data, (adrL | (adrH << 8)) * 128, 128);
+ break;
+ }
+ }
+ }
+ if (padst == 2) padst = 0;
+ if (mcdst == 1) {
+ mcdst = 2;
+ StatReg|= RX_RDY;
+ }
+ }
+ }
+
+#ifdef PAD_LOG
+ PAD_LOG("sio read8 ;ret = %x\n", ret);
+#endif
+ return ret;
+}
+
+void netError() {
+ ClosePlugins();
+ SysMessage(_("Connection closed!\n"));
+ SysRunGui();
+}
+
+void sioWrite8(unsigned char value) {
+#ifdef PAD_LOG
+ PAD_LOG("sio write8 %x\n", value);
+#endif
+ switch (padst) {
+ case 1: SIO_INT();
+ if ((value&0x40) == 0x40) {
+ padst = 2; parp = 1;
+ if (!Config.UseNet) {
+ switch (CtrlReg&0x2002) {
+ case 0x0002:
+ buf[parp] = PAD1_poll(value);
+ break;
+ case 0x2002:
+ buf[parp] = PAD2_poll(value);
+ break;
+ }
+ }/* else {
+// SysPrintf("%x: %x, %x, %x, %x\n", CtrlReg&0x2002, buf[2], buf[3], buf[4], buf[5]);
+ }*/
+
+ if (!(buf[parp] & 0x0f)) {
+ bufcount = 2 + 32;
+ } else {
+ bufcount = 2 + (buf[parp] & 0x0f) * 2;
+ }
+ if (buf[parp] == 0x41) {
+ switch (value) {
+ case 0x43:
+ buf[1] = 0x43;
+ break;
+ case 0x45:
+ buf[1] = 0xf3;
+ break;
+ }
+ }
+ }
+ else padst = 0;
+ return;
+ case 2:
+ parp++;
+/* if (buf[1] == 0x45) {
+ buf[parp] = 0;
+ SIO_INT();
+ return;
+ }*/
+ if (!Config.UseNet) {
+ switch (CtrlReg&0x2002) {
+ case 0x0002: buf[parp] = PAD1_poll(value); break;
+ case 0x2002: buf[parp] = PAD2_poll(value); break;
+ }
+ }
+
+ if (parp == bufcount) { padst = 0; return; }
+ SIO_INT();
+ return;
+ }
+
+ switch (mcdst) {
+ case 1:
+ SIO_INT();
+ if (rdwr) { parp++; return; }
+ parp = 1;
+ switch (value) {
+ case 0x52: rdwr = 1; break;
+ case 0x57: rdwr = 2; break;
+ default: mcdst = 0;
+ }
+ return;
+ case 2: // address H
+ SIO_INT();
+ adrH = value;
+ *buf = 0;
+ parp = 0;
+ bufcount = 1;
+ mcdst = 3;
+ return;
+ case 3: // address L
+ SIO_INT();
+ adrL = value;
+ *buf = adrH;
+ parp = 0;
+ bufcount = 1;
+ mcdst = 4;
+ return;
+ case 4:
+ SIO_INT();
+ parp = 0;
+ switch (rdwr) {
+ case 1: // read
+ buf[0] = 0x5c;
+ buf[1] = 0x5d;
+ buf[2] = adrH;
+ buf[3] = adrL;
+ switch (CtrlReg&0x2002) {
+ case 0x0002:
+ memcpy(&buf[4], Mcd1Data + (adrL | (adrH << 8)) * 128, 128);
+ break;
+ case 0x2002:
+ memcpy(&buf[4], Mcd2Data + (adrL | (adrH << 8)) * 128, 128);
+ break;
+ }
+ {
+ char xor = 0;
+ int i;
+ for (i=2;i<128+4;i++)
+ xor^=buf[i];
+ buf[132] = xor;
+ }
+ buf[133] = 0x47;
+ bufcount = 133;
+ break;
+ case 2: // write
+ buf[0] = adrL;
+ buf[1] = value;
+ buf[129] = 0x5c;
+ buf[130] = 0x5d;
+ buf[131] = 0x47;
+ bufcount = 131;
+ break;
+ }
+ mcdst = 5;
+ return;
+ case 5:
+ parp++;
+ if (rdwr == 2) {
+ if (parp < 128) buf[parp+1] = value;
+ }
+ SIO_INT();
+ return;
+ }
+
+ switch (value) {
+ case 0x01: // start pad
+ StatReg |= RX_RDY; // Transfer is Ready
+
+ if (!Config.UseNet) {
+ switch (CtrlReg&0x2002) {
+ case 0x0002: buf[0] = PAD1_startPoll(1); break;
+ case 0x2002: buf[0] = PAD2_startPoll(2); break;
+ }
+ } else {
+ if ((CtrlReg & 0x2002) == 0x0002) {
+ int i, j;
+
+ PAD1_startPoll(1);
+ buf[0] = 0;
+ buf[1] = PAD1_poll(0x42);
+ if (!(buf[1] & 0x0f)) {
+ bufcount = 32;
+ } else {
+ bufcount = (buf[1] & 0x0f) * 2;
+ }
+ buf[2] = PAD1_poll(0);
+ i = 3;
+ j = bufcount;
+ while (j--) {
+ buf[i++] = PAD1_poll(0);
+ }
+ bufcount+= 3;
+
+ if (NET_sendPadData(buf, bufcount) == -1)
+ netError();
+
+ if (NET_recvPadData(buf, 1) == -1)
+ netError();
+ if (NET_recvPadData(buf+128, 2) == -1)
+ netError();
+ } else {
+ memcpy(buf, buf+128, 32);
+ }
+ }
+
+ bufcount = 2;
+ parp = 0;
+ padst = 1;
+ SIO_INT();
+ return;
+ case 0x81: // start memcard
+ StatReg |= RX_RDY;
+ memcpy(buf, cardh, 4);
+ parp = 0;
+ bufcount = 3;
+ mcdst = 1;
+ rdwr = 0;
+ SIO_INT();
+ return;
+ }
+}
+
+void sioWriteCtrl16(unsigned short value) {
+ CtrlReg = value & ~RESET_ERR;
+ if (value & RESET_ERR) StatReg &= ~IRQ;
+ if ((CtrlReg & SIO_RESET) || (!CtrlReg)) {
+ padst = 0; mcdst = 0; parp = 0;
+ StatReg = TX_RDY | TX_EMPTY;
+ psxRegs.interrupt&=~0x80;
+ }
+}
+
+void sioInterrupt() {
+#ifdef PAD_LOG
+ PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status);
+#endif
+// SysPrintf("Sio Interrupt\n");
+ StatReg|= IRQ;
+ psxHu32ref(0x1070)|= SWAPu32(0x80);
+ psxRegs.interrupt|= 0x80000000;
+}
+
+void LoadMcd(int mcd, char *str) {
+ FILE *f;
+ char *data = NULL;
+
+ if (mcd == 1) data = Mcd1Data;
+ if (mcd == 2) data = Mcd2Data;
+
+ if (*str == 0) {
+ sprintf(str, "memcards/card%d.mcd", mcd);
+ SysPrintf(_("No memory card value was specified - creating a default card %s\n"), str);
+ }
+ f = fopen(str, "rb");
+ if (f == NULL) {
+ SysPrintf(_("The memory card %s doesn't exist - creating it\n"), str);
+ CreateMcd(str);
+ f = fopen(str, "rb");
+ if (f != NULL) {
+ struct stat buf;
+
+ if (stat(str, &buf) != -1) {
+ if (buf.st_size == MCD_SIZE + 64)
+ fseek(f, 64, SEEK_SET);
+ else if(buf.st_size == MCD_SIZE + 3904)
+ fseek(f, 3904, SEEK_SET);
+ }
+ fread(data, 1, MCD_SIZE, f);
+ fclose(f);
+ }
+ else
+ SysMessage(_("Memory card %s failed to load!\n"), str);
+ }
+ else {
+ struct stat buf;
+ SysPrintf(_("Loading memory card %s\n"), str);
+ if (stat(str, &buf) != -1) {
+ if (buf.st_size == MCD_SIZE + 64)
+ fseek(f, 64, SEEK_SET);
+ else if(buf.st_size == MCD_SIZE + 3904)
+ fseek(f, 3904, SEEK_SET);
+ }
+ fread(data, 1, MCD_SIZE, f);
+ fclose(f);
+ }
+}
+
+void LoadMcds(char *mcd1, char *mcd2) {
+ LoadMcd(1, mcd1);
+ LoadMcd(2, mcd2);
+}
+
+void SaveMcd(char *mcd, char *data, uint32_t adr, int size) {
+ FILE *f;
+
+ f = fopen(mcd, "r+b");
+ if (f != NULL) {
+ struct stat buf;
+
+ if (stat(mcd, &buf) != -1) {
+ if (buf.st_size == MCD_SIZE + 64)
+ fseek(f, adr + 64, SEEK_SET);
+ else if (buf.st_size == MCD_SIZE + 3904)
+ fseek(f, adr + 3904, SEEK_SET);
+ else
+ fseek(f, adr, SEEK_SET);
+ } else
+ fseek(f, adr, SEEK_SET);
+
+ fwrite(data + adr, 1, size, f);
+ fclose(f);
+ return;
+ }
+
+#if 0
+ // try to create it again if we can't open it
+ f = fopen(mcd, "wb");
+ if (f != NULL) {
+ fwrite(data, 1, MCD_SIZE, f);
+ fclose(f);
+ }
+#endif
+
+ ConvertMcd(mcd, data);
+}
+
+void CreateMcd(char *mcd) {
+ FILE *f;
+ struct stat buf;
+ int s = MCD_SIZE;
+ int i = 0, j;
+
+ f = fopen(mcd, "wb");
+ if (f == NULL)
+ return;
+
+ if (stat(mcd, &buf)!=-1) {
+ if ((buf.st_size == MCD_SIZE + 3904) || strstr(mcd, ".gme")) {
+ s = s + 3904;
+ fputc('1', f);
+ s--;
+ fputc('2', f);
+ s--;
+ fputc('3', f);
+ s--;
+ fputc('-', f);
+ s--;
+ fputc('4', f);
+ s--;
+ fputc('5', f);
+ s--;
+ fputc('6', f);
+ s--;
+ fputc('-', f);
+ s--;
+ fputc('S', f);
+ s--;
+ fputc('T', f);
+ s--;
+ fputc('D', f);
+ s--;
+ for (i = 0; i < 7; i++) {
+ fputc(0, f);
+ s--;
+ }
+ fputc(1, f);
+ s--;
+ fputc(0, f);
+ s--;
+ fputc(1, f);
+ s--;
+ fputc('M', f);
+ s--;
+ fputc('Q', f);
+ s--;
+ for (i = 0; i < 14; i++) {
+ fputc(0xa0, f);
+ s--;
+ }
+ fputc(0, f);
+ s--;
+ fputc(0xff, f);
+ while (s-- > (MCD_SIZE + 1))
+ fputc(0, f);
+ } else if ((buf.st_size == MCD_SIZE + 64) || strstr(mcd, ".mem") || strstr(mcd, ".vgs")) {
+ s = s + 64;
+ fputc('V', f);
+ s--;
+ fputc('g', f);
+ s--;
+ fputc('s', f);
+ s--;
+ fputc('M', f);
+ s--;
+ for (i = 0; i < 3; i++) {
+ fputc(1, f);
+ s--;
+ fputc(0, f);
+ s--;
+ fputc(0, f);
+ s--;
+ fputc(0, f);
+ s--;
+ }
+ fputc(0, f);
+ s--;
+ fputc(2, f);
+ while (s-- > (MCD_SIZE + 1))
+ fputc(0, f);
+ }
+ }
+ fputc('M', f);
+ s--;
+ fputc('C', f);
+ s--;
+ while (s-- > (MCD_SIZE - 127))
+ fputc(0, f);
+ fputc(0xe, f);
+ s--;
+
+ for (i = 0; i < 15; i++) { // 15 blocks
+ fputc(0xa0, f);
+ s--;
+ for (j = 0; j < 126; j++) {
+ fputc(0x00, f);
+ s--;
+ }
+ fputc(0xa0, f);
+ s--;
+ }
+
+ while ((s--) >= 0)
+ fputc(0, f);
+ fclose(f);
+}
+
+void ConvertMcd(char *mcd, char *data) {
+ FILE *f;
+ int i = 0;
+ int s = MCD_SIZE;
+
+ if (strstr(mcd, ".gme")) {
+ f = fopen(mcd, "wb");
+ if (f != NULL) {
+ fwrite(data-3904, 1, MCD_SIZE+3904, f);
+ fclose(f);
+ }
+ f = fopen(mcd, "r+");
+ s = s + 3904;
+ fputc('1', f); s--;
+ fputc('2', f); s--;
+ fputc('3', f); s--;
+ fputc('-', f); s--;
+ fputc('4', f); s--;
+ fputc('5', f); s--;
+ fputc('6', f); s--;
+ fputc('-', f); s--;
+ fputc('S', f); s--;
+ fputc('T', f); s--;
+ fputc('D', f); s--;
+ for(i=0;i<7;i++) {
+ fputc(0, f); s--;
+ }
+ fputc(1, f); s--;
+ fputc(0, f); s--;
+ fputc(1, f); s--;
+ fputc('M', f); s--;
+ fputc('Q', f); s--;
+ for(i=0;i<14;i++) {
+ fputc(0xa0, f); s--;
+ }
+ fputc(0, f); s--;
+ fputc(0xff, f);
+ while (s-- > (MCD_SIZE+1)) fputc(0, f);
+ fclose(f);
+ } else if(strstr(mcd, ".mem") || strstr(mcd,".vgs")) {
+ f = fopen(mcd, "wb");
+ if (f != NULL) {
+ fwrite(data-64, 1, MCD_SIZE+64, f);
+ fclose(f);
+ }
+ f = fopen(mcd, "r+");
+ s = s + 64;
+ fputc('V', f); s--;
+ fputc('g', f); s--;
+ fputc('s', f); s--;
+ fputc('M', f); s--;
+ for(i=0;i<3;i++) {
+ fputc(1, f); s--;
+ fputc(0, f); s--;
+ fputc(0, f); s--;
+ fputc(0, f); s--;
+ }
+ fputc(0, f); s--;
+ fputc(2, f);
+ while (s-- > (MCD_SIZE+1)) fputc(0, f);
+ fclose(f);
+ } else {
+ f = fopen(mcd, "wb");
+ if (f != NULL) {
+ fwrite(data, 1, MCD_SIZE, f);
+ fclose(f);
+ }
+ }
+}
+
+void GetMcdBlockInfo(int mcd, int block, McdBlock *Info) {
+ unsigned char *data = NULL, *ptr, *str;
+ unsigned short clut[16];
+ unsigned short c;
+ int i, x;
+
+ memset(Info, 0, sizeof(McdBlock));
+
+ str = Info->Title;
+
+ if (mcd == 1) data = Mcd1Data;
+ if (mcd == 2) data = Mcd2Data;
+
+ ptr = data + block * 8192 + 2;
+
+ Info->IconCount = *ptr & 0x3;
+
+ ptr+= 2;
+
+ i=0;
+ memcpy(Info->sTitle, ptr, 48*2);
+
+ for (i=0; i < 48; i++) {
+ c = *(ptr) << 8;
+ c|= *(ptr+1);
+ if (!c) break;
+
+ if (c >= 0x8281 && c <= 0x8298)
+ c = (c - 0x8281) + 'a';
+ else if (c >= 0x824F && c <= 0x827A)
+ c = (c - 0x824F) + '0';
+ else if (c == 0x8144) c = '.';
+ else if (c == 0x8146) c = ':';
+ else if (c == 0x8168) c = '"';
+ else if (c == 0x8169) c = '(';
+ else if (c == 0x816A) c = ')';
+ else if (c == 0x816D) c = '[';
+ else if (c == 0x816E) c = ']';
+ else if (c == 0x817C) c = '-';
+ else {
+ c = ' ';
+ }
+
+ str[i] = c;
+ ptr+=2;
+ }
+ str[i] = 0;
+
+ ptr = data + block * 8192 + 0x60; // icon palete data
+
+ for (i = 0; i < 16; i++) {
+ clut[i] = *((unsigned short*)ptr);
+ ptr += 2;
+ }
+
+ for (i = 0; i < Info->IconCount; i++) {
+ short *icon = &Info->Icon[i*16*16];
+
+ ptr = data + block * 8192 + 128 + 128 * i; // icon data
+
+ for (x = 0; x < 16 * 16; x++) {
+ icon[x++] = clut[*ptr & 0xf];
+ icon[x] = clut[*ptr >> 4];
+ ptr++;
+ }
+ }
+
+ ptr = data + block * 128;
+
+ Info->Flags = *ptr;
+
+ ptr += 0xa;
+ strncpy(Info->ID, ptr, 12);
+ Info->ID[12] = 0;
+ ptr += 12;
+ strncpy(Info->Name, ptr, 16);
+}
+
+int sioFreeze(gzFile f, int Mode) {
+ char Unused[4096];
+
+ gzfreezel(buf);
+ gzfreezel(&StatReg);
+ gzfreezel(&ModeReg);
+ gzfreezel(&CtrlReg);
+ gzfreezel(&BaudReg);
+ gzfreezel(&bufcount);
+ gzfreezel(&parp);
+ gzfreezel(&mcdst);
+ gzfreezel(&rdwr);
+ gzfreezel(&adrH);
+ gzfreezel(&adrL);
+ gzfreezel(&padst);
+ gzfreezel(Unused);
+
+ return 0;
+}
diff --git a/libpcsxcore/sio.h b/libpcsxcore/sio.h
new file mode 100644
index 00000000..082c5447
--- /dev/null
+++ b/libpcsxcore/sio.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+
+#ifndef _SIO_H_
+#define _SIO_H_
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "psxmem.h"
+#include "plugins.h"
+#include "psemu_plugin_defs.h"
+
+#define MCD_SIZE (1024 * 8 * 16)
+
+// Status Flags
+#define TX_RDY 0x0001
+#define RX_RDY 0x0002
+#define TX_EMPTY 0x0004
+#define PARITY_ERR 0x0008
+#define RX_OVERRUN 0x0010
+#define FRAMING_ERR 0x0020
+#define SYNC_DETECT 0x0040
+#define DSR 0x0080
+#define CTS 0x0100
+#define IRQ 0x0200
+
+// Control Flags
+#define TX_PERM 0x0001
+#define DTR 0x0002
+#define RX_PERM 0x0004
+#define BREAK 0x0008
+#define RESET_ERR 0x0010
+#define RTS 0x0020
+#define SIO_RESET 0x0040
+
+extern unsigned short StatReg;
+extern unsigned short ModeReg;
+extern unsigned short CtrlReg;
+extern unsigned short BaudReg;
+
+extern char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE];
+
+unsigned char sioRead8();
+void sioWrite8(unsigned char value);
+void sioWriteCtrl16(unsigned short value);
+void sioInterrupt();
+int sioFreeze(gzFile f, int Mode);
+
+void LoadMcd(int mcd, char *str);
+void LoadMcds(char *mcd1, char *mcd2);
+void SaveMcd(char *mcd, char *data, uint32_t adr, int size);
+void CreateMcd(char *mcd);
+void ConvertMcd(char *mcd, char *data);
+
+typedef struct {
+ char Title[48];
+ short sTitle[48];
+ char ID[14];
+ char Name[16];
+ int IconCount;
+ short Icon[16*16*3];
+ unsigned char Flags;
+} McdBlock;
+
+void GetMcdBlockInfo(int mcd, int block, McdBlock *info);
+
+#endif
diff --git a/libpcsxcore/spu.c b/libpcsxcore/spu.c
new file mode 100644
index 00000000..c3ad8b67
--- /dev/null
+++ b/libpcsxcore/spu.c
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Sound (SPU) functions.
+*/
+
+#include "spu.h"
+
+void CALLBACK SPUirq(void) {
+ psxHu32ref(0x1070)|= SWAPu32(0x200);
+ psxRegs.interrupt|= 0x80000000;
+}
diff --git a/libpcsxcore/spu.h b/libpcsxcore/spu.h
new file mode 100644
index 00000000..12a8e475
--- /dev/null
+++ b/libpcsxcore/spu.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __SPU_H__
+#define __SPU_H__
+
+#include "psxcommon.h"
+#include "plugins.h"
+#include "r3000a.h"
+#include "psxmem.h"
+
+#ifndef _WIN32
+#define CALLBACK
+#endif
+
+#define H_SPUirqAddr 0x0da4
+#define H_SPUaddr 0x0da6
+#define H_SPUdata 0x0da8
+#define H_SPUctrl 0x0daa
+#define H_SPUstat 0x0dae
+#define H_SPUon1 0x0d88
+#define H_SPUon2 0x0d8a
+#define H_SPUoff1 0x0d8c
+#define H_SPUoff2 0x0d8e
+
+void CALLBACK SPUirq(void);
+
+#endif /* __SPU_H__ */
diff --git a/libpcsxcore/system.h b/libpcsxcore/system.h
new file mode 100644
index 00000000..124a1cd6
--- /dev/null
+++ b/libpcsxcore/system.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * schultz.ryan@gmail.com, http://rschultz.ath.cx/code.php *
+ * *
+ * 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 Steet, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#ifndef __SYSTEM_H__
+#define __SYSTEM_H__
+
+int SysInit(); // Init mem and plugins
+void SysReset(); // Resets mem
+void SysPrintf(char *fmt, ...); // Printf used by bios syscalls
+void SysMessage(char *fmt, ...); // Message used to print msg to users
+void *SysLoadLibrary(char *lib); // Loads Library
+void *SysLoadSym(void *lib, char *sym); // Loads Symbol from Library
+const char *SysLibError(); // Gets previous error loading sysbols
+void SysCloseLibrary(void *lib); // Closes Library
+void SysUpdate(); // Called on VBlank (to update i.e. pads)
+void SysRunGui(); // Returns to the Gui
+void SysClose(); // Close mem and plugins
+
+#endif /* __SYSTEM_H__ */