diff --git a/Makefile b/Makefile index 5ccf0a07..dd06d4fe 100644 --- a/Makefile +++ b/Makefile @@ -140,7 +140,7 @@ WARNINGS := -Wall \ -Wno-overflow FLAGS += $(ENDIANNESS_DEFINES) -DSIZEOF_DOUBLE=8 $(WARNINGS) \ - -DMEDNAFEN_VERSION=\"0.9.25\" -DPACKAGE=\"mednafen\" -DMEDNAFEN_VERSION_NUMERIC=925 -DPSS_STYLE=1 -DMPC_FIXED_POINT -DARCH_X86 -DWANT_PSX_EMU -DSTDC_HEADERS -D__STDC_LIMIT_MACROS -D__LIBRETRO__ -DNDEBUG + -DMEDNAFEN_VERSION=\"0.9.26\" -DPACKAGE=\"mednafen\" -DMEDNAFEN_VERSION_NUMERIC=926 -DPSS_STYLE=1 -DMPC_FIXED_POINT -DARCH_X86 -DWANT_PSX_EMU -DSTDC_HEADERS -D__STDC_LIMIT_MACROS -D__LIBRETRO__ -DNDEBUG CXXFLAGS += $(FLAGS) CFLAGS += $(FLAGS) -std=gnu99 diff --git a/libretro.cpp b/libretro.cpp index 77adb0f3..2a2e0cd6 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -332,7 +332,7 @@ void retro_get_system_info(struct retro_system_info *info) { memset(info, 0, sizeof(*info)); info->library_name = "Mednafen PSX"; - info->library_version = "0.9.25"; + info->library_version = "0.9.26"; info->need_fullpath = true; info->valid_extensions = "cue|CUE"; } diff --git a/mednafen/mpcdec/Makefile.am b/mednafen/mpcdec/Makefile.am deleted file mode 100644 index 445c9acf..00000000 --- a/mednafen/mpcdec/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -DEFS = @DEFS@ @CFLAG_VISIBILITY@ - -noinst_LIBRARIES = libmpcdec.a - -libmpcdec_a_SOURCES = huffman.c mpc_decoder.c mpc_reader.c \ - requant.c streaminfo.c synth_filter.c mpc_bits_reader.c mpc_demux.c \ - mpc_bits_reader.h huffman.h decoder.h internal.h requant.h mpcdec_math.h \ - crc32.c huffman-bcl.c - diff --git a/mednafen/mpcdec/Makefile.in b/mednafen/mpcdec/Makefile.in deleted file mode 100644 index 90efe51a..00000000 --- a/mednafen/mpcdec/Makefile.in +++ /dev/null @@ -1,609 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@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@ -subdir = src/mpcdec -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - AUTHORS COPYING ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_gcc_option.m4 \ - $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/fcntl-o.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \ - $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \ - $(top_srcdir)/m4/inttypes-pri.m4 \ - $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \ - $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/uintmax_t.m4 \ - $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/m4/wchar_t.m4 \ - $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xsize.m4 \ - $(top_srcdir)/acinclude.m4 $(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 = -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -AM_V_AR = $(am__v_AR_$(V)) -am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) -am__v_AR_0 = @echo " AR " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -libmpcdec_a_AR = $(AR) $(ARFLAGS) -libmpcdec_a_LIBADD = -am_libmpcdec_a_OBJECTS = huffman.$(OBJEXT) mpc_decoder.$(OBJEXT) \ - mpc_reader.$(OBJEXT) requant.$(OBJEXT) streaminfo.$(OBJEXT) \ - synth_filter.$(OBJEXT) mpc_bits_reader.$(OBJEXT) \ - mpc_demux.$(OBJEXT) crc32.$(OBJEXT) huffman-bcl.$(OBJEXT) -libmpcdec_a_OBJECTS = $(am_libmpcdec_a_OBJECTS) -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) -am__v_lt_0 = --silent -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) -am__v_CC_0 = @echo " CC " $@; -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libmpcdec_a_SOURCES) -DIST_SOURCES = $(libmpcdec_a_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CXXFLAGS = @AM_CXXFLAGS@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ @CFLAG_VISIBILITY@ -DEPDIR = @DEPDIR@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GBA_EXTRA_FLAGS = @GBA_EXTRA_FLAGS@ -GENCAT = @GENCAT@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GLIBC2 = @GLIBC2@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GREP = @GREP@ -HAVE_ASPRINTF = @HAVE_ASPRINTF@ -HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ -HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ -HAVE_SNPRINTF = @HAVE_SNPRINTF@ -HAVE_VISIBILITY = @HAVE_VISIBILITY@ -HAVE_WPRINTF = @HAVE_WPRINTF@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_DEFAULT_VERBOSITY = @INTL_DEFAULT_VERBOSITY@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -JACK_CFLAGS = @JACK_CFLAGS@ -JACK_LIBS = @JACK_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@ -LIBCDIO_LIBS = @LIBCDIO_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBMULTITHREAD = @LIBMULTITHREAD@ -LIBOBJS = @LIBOBJS@ -LIBPTH = @LIBPTH@ -LIBPTH_PREFIX = @LIBPTH_PREFIX@ -LIBS = @LIBS@ -LIBTHREAD = @LIBTHREAD@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBC = @LTLIBC@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ -LTLIBOBJS = @LTLIBOBJS@ -LTLIBPTH = @LTLIBPTH@ -LTLIBTHREAD = @LTLIBTHREAD@ -MAKEINFO = @MAKEINFO@ -MATH_OPTIMIZER_FLAGS = @MATH_OPTIMIZER_FLAGS@ -MKDIR_P = @MKDIR_P@ -MMX_CFLAGS = @MMX_CFLAGS@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POSUB = @POSUB@ -PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ -SNDFILE_LIBS = @SNDFILE_LIBS@ -SNES_EXTRA_CXXFLAGS = @SNES_EXTRA_CXXFLAGS@ -SNES_EXTRA_FLAGS = @SNES_EXTRA_FLAGS@ -SSE2_CFLAGS = @SSE2_CFLAGS@ -SSE3_CFLAGS = @SSE3_CFLAGS@ -SSE_CFLAGS = @SSE_CFLAGS@ -STRIP = @STRIP@ -TRIO_CFLAGS = @TRIO_CFLAGS@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WARNING_FLAGS = @WARNING_FLAGS@ -WINDRES = @WINDRES@ -WOE32 = @WOE32@ -WOE32DLL = @WOE32DLL@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -XMKMF = @XMKMF@ -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_DUMPBIN = @ac_ct_DUMPBIN@ -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@ -lt_ECHO = @lt_ECHO@ -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@ -noinst_LIBRARIES = libmpcdec.a -libmpcdec_a_SOURCES = huffman.c mpc_decoder.c mpc_reader.c \ - requant.c streaminfo.c synth_filter.c mpc_bits_reader.c mpc_demux.c \ - mpc_bits_reader.h huffman.h decoder.h internal.h requant.h mpcdec_math.h \ - crc32.c huffman-bcl.c - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/mpcdec/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/mpcdec/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: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libmpcdec.a: $(libmpcdec_a_OBJECTS) $(libmpcdec_a_DEPENDENCIES) - $(AM_V_at)-rm -f libmpcdec.a - $(AM_V_AR)$(libmpcdec_a_AR) libmpcdec.a $(libmpcdec_a_OBJECTS) $(libmpcdec_a_LIBADD) - $(AM_V_at)$(RANLIB) libmpcdec.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc32.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman-bcl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpc_bits_reader.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpc_decoder.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpc_demux.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpc_reader.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/requant.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/streaminfo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synth_filter.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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 $@ $< - -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; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - 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; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - 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)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__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 "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$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) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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 - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -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/mednafen/psx/Makefile.am b/mednafen/psx-0925/Makefile.am similarity index 100% rename from mednafen/psx/Makefile.am rename to mednafen/psx-0925/Makefile.am diff --git a/mednafen/psx/Makefile.in b/mednafen/psx-0925/Makefile.in similarity index 100% rename from mednafen/psx/Makefile.in rename to mednafen/psx-0925/Makefile.in diff --git a/mednafen/psx-0925/NOTES b/mednafen/psx-0925/NOTES new file mode 100644 index 00000000..f0cf1068 --- /dev/null +++ b/mednafen/psx-0925/NOTES @@ -0,0 +1,3 @@ +Capcom games(MMX4, MMX5, etc) - Sensitive about CD access and XA timing(XA playback problems). + +Viewpoint - Extra-sensitive about GPU LL DMA timing? (It was generating exceptions for some timings...) diff --git a/mednafen/psx-0925/PSX-TODO b/mednafen/psx-0925/PSX-TODO new file mode 100644 index 00000000..9d19939b --- /dev/null +++ b/mednafen/psx-0925/PSX-TODO @@ -0,0 +1,51 @@ +Soul Reaver - Legacy of Kain has CD load time pauses where it probably shouldn't. + +Battle Arena Toshinden, Final Fantasy 7 have some kind of GPU timing issues. + +Zero Divide runs too fast(related to CPU emulation speed?). + +Chrono Cross has several-second freezes during some large special attack/magic sequences. + +Tiny Toon Adventures - Plucky's Big Adventure is failing and BREAK'ing for some reason, maybe memcard related. + +Shadow Master has broken startup images. + +Crusaders of Might and Magic - The CD-XA buffering increase for ToD II is apparently exacerbating the early voice cutoff problem in this game. + +Crash Team Racing - Noticed a game lockup once in the arcade mode stage select screen, having trouble reproducing it. + +Misadventures of Trone Bonne - Voice problems, lockup, possibly due to excessively long seek delays? + +Dance Dance Revolution - The music is...totally wonky. + +Medal of Honor - Sound issues. + +Fuuraiki - Hangs at black screen when trying to start a new game. + + +Test time delta between GPU LL DMA end and GPU non-busy status for various primitive types in sequence on a PS1. + +Test IRQ and COP0 latencies; PSX IRQ controller latency, software IRQ bit latency, latency of both relevant COP0 IRQ enable bits. + +Test IRQ with LWC2. + +Test IRQ with COP0 instructions(interrupted execution or not?). + +Determine maximum quad height and width. See if drawing is an all-or-nothing thing, or if one triangle of the pair will still be drawn +if it's not too large. + +Test 0x0 and 1x1 polygon throughput for all triangle and quad drawing commands. + +Fix line drawing algorithm to match test results on the real thing. + +Instruction cache emulation(MAYBE). + + +Test time between voice on and envelope reset; test time between voice on and first ADPCM block memory fetch. + +The SPU in the PS1 might sometimes drop voice on events when playing an ADPCM block that loops to itself(and was also the first and only +ADPCM block, at least in the test program I noticed the issue in); investigate further. + + + +Make sure debugger COPn disassembly is correct(no typos or whatnot). diff --git a/mednafen/psx-0925/README.NOW b/mednafen/psx-0925/README.NOW new file mode 100644 index 00000000..1c616a60 --- /dev/null +++ b/mednafen/psx-0925/README.NOW @@ -0,0 +1,2 @@ +This PSX emulation code is horribly unfinished! Please don't take and use any pieces of it in any other project unless you have +a very good reason to! diff --git a/mednafen/psx-0925/SOURCES b/mednafen/psx-0925/SOURCES new file mode 100644 index 00000000..2dcae228 --- /dev/null +++ b/mednafen/psx-0925/SOURCES @@ -0,0 +1,38 @@ +Sources of helpful information used in PS1 emulation(though some of it, especially older compiled information, +is wrong to some degree or incomplete, but it's still useful): + +PCSX(and derivatives/forks) +MAME/MESS +P.E.Op.S + +Blade Lib +psxsdk + +doomed's PSX documents +bITmASTER's document +Neill Corlett's SPU documents +T.Fujita's SIO documents +ChrlyMac +Exophase +mizvekov +notaz +pSXAuthor +smf(blog) +shalma(forum posts, changelogs) +drhell's site +jac's CD-XA document +"The PlayStation 1 Video (STR) Format" - M. Sabin +Various PS1 emulator compatibility lists(for identifying problematic games) + + +MIPS RISC Architecture - Gerry Kane (1st and 2nd editions) +MIPS Programmer's Handbook, The + +----------- +General(non-PS1-specific) CD/CDROM information and code: + +SCSI-3 Multimedia Commands Revision 10A +ECMA-130 + +cdrdao +dvdisaster diff --git a/mednafen/psx-0925/cdc.cpp b/mednafen/psx-0925/cdc.cpp new file mode 100644 index 00000000..1b7cf7bb --- /dev/null +++ b/mednafen/psx-0925/cdc.cpp @@ -0,0 +1,2107 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// TODO: async command counter and async command phase? +/* + + TODO: + Implement missing commands. + + SPU CD-DA and CD-XA streaming semantics. +*/ + +/* + After eject(doesn't appear to occur when drive is in STOP state): + * Does not appear to occur in STOP state. + * Does not appear to occur in PAUSE state. + * DOES appear to occur in STANDBY state. (TODO: retest) + +% Result 0: 16 +% Result 1: 08 +% IRQ Result: e5 +% 19 e0 + + Command abortion tests(NOP tested): + Does not appear to occur when in STOP or PAUSE states(STOP or PAUSE command just executed). + + DOES occur after a ReadTOC completes, if ReadTOC is not followed by a STOP or PAUSE. Odd. +*/ + +#include "psx.h" +#include "cdc.h" +#include "spu.h" + +using namespace CDUtility; + +namespace MDFN_IEN_PSX +{ + +PS_CDC::PS_CDC() : DMABuffer(4096) +{ + IsPSXDisc = false; + Cur_CDIF = NULL; +} + +PS_CDC::~PS_CDC() +{ + +} + +void PS_CDC::SetDisc(bool tray_open, CDIF *cdif, const char *disc_id) +{ + if(tray_open) + cdif = NULL; + + Cur_CDIF = cdif; + IsPSXDisc = false; + memset(DiscID, 0, sizeof(DiscID)); + + if(!Cur_CDIF) + { + PSRCounter = 0; + + if((DriveStatus != DS_PAUSED && DriveStatus != DS_STOPPED) || PendingCommandPhase > 0) + { + PendingCommand = 0x00; + PendingCommandCounter = 0; + PendingCommandPhase = 0; + } + + HeaderBufValid = false; + DriveStatus = DS_STOPPED; + ClearAIP(); + } + else + { + HeaderBufValid = false; + DiscStartupDelay = (int64)1000 * 33868800 / 1000; + DiscChanged = true; + + Cur_CDIF->ReadTOC(&toc); + + if(disc_id) + { + strncpy((char *)DiscID, disc_id, 4); + IsPSXDisc = true; + } + } +} + +int32 PS_CDC::CalcNextEvent(void) +{ + int32 next_event = SPUCounter; + + if(PSRCounter > 0 && next_event > PSRCounter) + next_event = PSRCounter; + + if(PendingCommandCounter > 0 && next_event > PendingCommandCounter) + next_event = PendingCommandCounter; + + if(!IRQBuffer) + { + if(CDCReadyReceiveCounter > 0 && next_event > CDCReadyReceiveCounter) + next_event = CDCReadyReceiveCounter; + } + + if(DiscStartupDelay > 0 && next_event > DiscStartupDelay) + next_event = DiscStartupDelay; + + //fprintf(stderr, "%d %d %d %d --- %d\n", PSRCounter, PendingCommandCounter, CDCReadyReceiveCounter, DiscStartupDelay, next_event); + + return(next_event); +} + +void PS_CDC::SoftReset(void) +{ + ClearAudioBuffers(); + + // Not sure about initial volume state + Pending_DecodeVolume[0][0] = 0x80; + Pending_DecodeVolume[0][1] = 0x00; + Pending_DecodeVolume[1][0] = 0x00; + Pending_DecodeVolume[1][1] = 0x80; + memcpy(DecodeVolume, Pending_DecodeVolume, sizeof(DecodeVolume)); + + RegSelector = 0; + memset(ArgsBuf, 0, sizeof(ArgsBuf)); + ArgsIn = 0; + + memset(ResultsBuffer, 0, sizeof(ResultsBuffer)); + ResultsWP = 0; + ResultsRP = 0; + ResultsIn = 0; + + CDCReadyReceiveCounter = 0; + + IRQBuffer = 0; + IRQOutTestMask = 0; + RecalcIRQ(); + + DMABuffer.Flush(); + SB_In = 0; + + memset(SubQBuf, 0, sizeof(SubQBuf)); + memset(SubQBuf_Safe, 0, sizeof(SubQBuf_Safe)); + SubQChecksumOK = false; + + memset(HeaderBuf, 0, sizeof(HeaderBuf)); + + + FilterFile = 0; + FilterChan = 0; + + PendingCommand = 0; + PendingCommandPhase = 0; + PendingCommandCounter = 0; + + Mode = 0; + + HeaderBufValid = false; + DriveStatus = DS_STOPPED; + ClearAIP(); + StatusAfterSeek = DS_STOPPED; + + Forward = false; + Backward = false; + Muted = false; + + PlayTrackMatch = 0; + + PSRCounter = 0; + + CurSector = 0; + + ClearAIP(); + + SeekTarget = 0; + + CommandLoc = 0; + CommandLoc_Dirty = true; + + DiscChanged = true; +} + +void PS_CDC::Power(void) +{ + SPU->Power(); + + SoftReset(); + + DiscStartupDelay = 0; + + SPUCounter = SPU->UpdateFromCDC(0); + lastts = 0; +} + +int PS_CDC::StateAction(StateMem *sm, int load, int data_only) +{ + assert(AudioBuffer_Count == 4); + + SFORMAT StateRegs[] = + { + SFVAR(DiscChanged), + SFVAR(DiscStartupDelay), + +#define SFAB(n) SFARRAY16N(&AudioBuffer[n].Samples[0][0], sizeof(AudioBuffer[n].Samples) / sizeof(AudioBuffer[n].Samples[0][0]), #n "Samples"), \ + SFVARN(AudioBuffer[n].Size, #n "Size"), \ + SFVARN(AudioBuffer[n].Freq, #n "Freq") + + SFAB(0), + SFAB(1), + SFAB(2), + SFAB(3), + + SFVAR(AudioBuffer_ReadPos), + SFVAR(AudioBuffer_WritePos), + SFVAR(AudioBuffer_UsedCount), + SFVAR(AudioBuffer_InPrebuffer), + + SFARRAY(&Pending_DecodeVolume[0][0], 2 * 2), + SFARRAY(&DecodeVolume[0][0], 2 * 2), + + SFVAR(RegSelector), + SFARRAY(ArgsBuf, 16), + SFVAR(ArgsIn), + + SFARRAY(ResultsBuffer, 16), + SFVAR(ResultsIn), + SFVAR(ResultsWP), + SFVAR(ResultsRP), + +// +// +// + SFARRAY(&DMABuffer.data[0], DMABuffer.data.size()), + SFVAR(DMABuffer.read_pos), + SFVAR(DMABuffer.write_pos), + SFVAR(DMABuffer.in_count), +// +// +// + + SFARRAY(SB, sizeof(SB) / sizeof(SB[0])), + SFVAR(SB_In), + SFARRAY(SubQBuf, sizeof(SubQBuf) / sizeof(SubQBuf[0])), + SFARRAY(SubQBuf_Safe, sizeof(SubQBuf_Safe) / sizeof(SubQBuf_Safe[0])), + + SFVAR(SubQChecksumOK), + SFARRAY(HeaderBuf, sizeof(HeaderBuf) / sizeof(HeaderBuf[0])), + + SFVAR(IRQBuffer), + SFVAR(IRQOutTestMask), + SFVAR(CDCReadyReceiveCounter), + + + + SFVAR(FilterFile), + SFVAR(FilterChan), + + + SFVAR(PendingCommand), + SFVAR(PendingCommandPhase), + SFVAR(PendingCommandCounter), + + SFVAR(SPUCounter), + + SFVAR(Mode), + SFVAR(DriveStatus), + SFVAR(StatusAfterSeek), + SFVAR(Forward), + SFVAR(Backward), + SFVAR(Muted), + + SFVAR(PlayTrackMatch), + + SFVAR(PSRCounter), + + SFVAR(CurSector), + + SFVAR(AsyncIRQPending), + SFARRAY(AsyncResultsPending, sizeof(AsyncResultsPending) / sizeof(AsyncResultsPending[0])), + SFVAR(AsyncResultsPendingCount), + + + SFVAR(SeekTarget), + + SFVAR(lastts), + +#if 0 + CDUtility::TOC toc; + bool IsPSXDisc; + uint8 DiscID[4]; +#endif + SFVAR(CommandLoc), + SFVAR(CommandLoc_Dirty), + SFARRAY16(&xa_previous[0][0], sizeof(xa_previous) / sizeof(xa_previous[0][0])), + + SFVAR(xa_cur_set), + SFVAR(xa_cur_file), + SFVAR(xa_cur_chan), + SFEND + }; + + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "CDC"); + + if(load) + { + + } + return(ret); +} + +void PS_CDC::ResetTS(void) +{ + lastts = 0; +} + +void PS_CDC::RecalcIRQ(void) +{ + IRQ_Assert(IRQ_CD, (bool)(IRQBuffer & (IRQOutTestMask & 0x1F))); +} + +void PS_CDC::WriteIRQ(uint8 V) +{ + assert(CDCReadyReceiveCounter <= 0); + assert(!IRQBuffer); + + CDCReadyReceiveCounter = 1024; + + IRQBuffer = V; + RecalcIRQ(); +} + +void PS_CDC::BeginResults(void) +{ + //if(ResultsIn) + // { + // printf("Cleared %d results. IRQBuffer=0x%02x\n", ResultsIn, IRQBuffer); + //} + + // TODO: test semantics on real thing. + ResultsIn = 0; + ResultsWP = 0; + ResultsRP = 0; +} + +void PS_CDC::WriteResult(uint8 V) +{ + ResultsBuffer[ResultsWP] = V; + ResultsWP = (ResultsWP + 1) & 0xF; + ResultsIn = (ResultsIn + 1) & 0x1F; + + if(!ResultsIn) + PSX_WARNING("[CDC] Results buffer overflow!"); +} + +uint8 PS_CDC::ReadResult(void) +{ + uint8 ret = ResultsBuffer[ResultsRP]; + + ResultsRP = (ResultsRP + 1) & 0xF; + ResultsIn = (ResultsIn - 1) & 0x1F; + + return ret; +} + +uint8 PS_CDC::MakeStatus(bool cmd_error) +{ + uint8 ret = 0; + + // Are these bit positions right? + + if(DriveStatus == DS_PLAYING) + ret |= 0x80; + + if(DriveStatus == DS_SEEKING || DriveStatus == DS_SEEKING_LOGICAL) + ret |= 0x40; + + if(DriveStatus == DS_READING) + ret |= 0x20; + + // TODO: shell open and seek error + if(!Cur_CDIF || DiscChanged) + ret |= 0x10; + + if(DriveStatus != DS_STOPPED) + ret |= 0x02; + + if(cmd_error) + ret |= 0x01; + + DiscChanged = false; + + return(ret); +} + +bool PS_CDC::DecodeSubQ(uint8 *subpw) +{ + uint8 tmp_q[0xC]; + + memset(tmp_q, 0, 0xC); + + for(int i = 0; i < 96; i++) + tmp_q[i >> 3] |= ((subpw[i] & 0x40) >> 6) << (7 - (i & 7)); + + if((tmp_q[0] & 0xF) == 1) + { + memcpy(SubQBuf, tmp_q, 0xC); + SubQChecksumOK = subq_check_checksum(tmp_q); + + if(SubQChecksumOK) + { + memcpy(SubQBuf_Safe, tmp_q, 0xC); + return(true); + } + } + + return(false); +} + +struct XA_Subheader +{ + uint8 file; + uint8 channel; + uint8 submode; + uint8 coding; + + uint8 file_dup; + uint8 channel_dup; + uint8 submode_dup; + uint8 coding_dup; +} __attribute__((__packed__)); + +struct XA_SoundGroup +{ + uint8 params[16]; + uint8 samples[112]; +} __attribute__((__packed__)); + +#define XA_SUBMODE_EOF 0x80 +#define XA_SUBMODE_REALTIME 0x40 +#define XA_SUBMODE_FORM 0x20 +#define XA_SUBMODE_TRIGGER 0x10 +#define XA_SUBMODE_DATA 0x08 +#define XA_SUBMODE_AUDIO 0x04 +#define XA_SUBMODE_VIDEO 0x02 +#define XA_SUBMODE_EOR 0x01 + +#define XA_CODING_EMPHASIS 0x40 + +//#define XA_CODING_BPS_MASK 0x30 +//#define XA_CODING_BPS_4BIT 0x00 +//#define XA_CODING_BPS_8BIT 0x10 +//#define XA_CODING_SR_MASK 0x0C +//#define XA_CODING_SR_378 0x00 +//#define XA_CODING_SR_ + +#define XA_CODING_8BIT 0x10 +#define XA_CODING_189 0x04 +#define XA_CODING_STEREO 0x01 + +// Special regression prevention test cases: +// Um Jammer Lammy (start doing poorly) +// Yarudora Series Vol.1 - Double Cast (non-FMV speech) + +bool PS_CDC::XA_Test(const uint8 *sdata) +{ + const XA_Subheader *sh = (const XA_Subheader *)&sdata[12 + 4]; + + if(!(Mode & MODE_STRSND)) + return false; + + if(!(sh->submode & XA_SUBMODE_AUDIO)) + return false; + + //printf("Test File: 0x%02x 0x%02x - Channel: 0x%02x 0x%02x - Submode: 0x%02x 0x%02x - Coding: 0x%02x 0x%02x - \n", sh->file, sh->file_dup, sh->channel, sh->channel_dup, sh->submode, sh->submode_dup, sh->coding, sh->coding_dup); + + if((Mode & MODE_SF) && (sh->file != FilterFile || sh->channel != FilterChan)) + return false; + + if(!xa_cur_set || (Mode & MODE_SF)) + { + xa_cur_set = true; + xa_cur_file = sh->file; + xa_cur_chan = sh->channel; + } + else if(sh->file != xa_cur_file || sh->channel != xa_cur_chan) + return false; + + if(sh->submode & XA_SUBMODE_EOF) + { + //puts("YAY"); + xa_cur_set = false; + xa_cur_file = 0; + xa_cur_chan = 0; + } + + return true; +} + +void PS_CDC::ClearAudioBuffers(void) +{ + memset(AudioBuffer, 0, sizeof(AudioBuffer)); + memset(xa_previous, 0, sizeof(xa_previous)); + + xa_cur_set = false; + xa_cur_file = 0; + xa_cur_chan = 0; + + AudioBuffer_ReadPos = 0; + AudioBuffer_WritePos = 0; + AudioBuffer_UsedCount = 0; + + AudioBuffer_InPrebuffer = true; +} + +void PS_CDC::XA_ProcessSector(const uint8 *sdata, CD_Audio_Buffer *ab) +{ + const XA_Subheader *sh = (const XA_Subheader *)&sdata[12 + 4]; + const unsigned unit_index_shift = (sh->coding & XA_CODING_8BIT) ? 0 : 1; + + //printf("File: 0x%02x 0x%02x - Channel: 0x%02x 0x%02x - Submode: 0x%02x 0x%02x - Coding: 0x%02x 0x%02x - \n", sh->file, sh->file_dup, sh->channel, sh->channel_dup, sh->submode, sh->submode_dup, sh->coding, sh->coding_dup); + + ab->Size = 18 * (4 << unit_index_shift) * 28; + + if(sh->coding & XA_CODING_STEREO) + ab->Size >>= 1; + + ab->Freq = (sh->coding & XA_CODING_189) ? 3 : 6; + + //fprintf(stderr, "Coding: %02x %02x\n", sh->coding, sh->coding_dup); + + for(unsigned group = 0; group < 18; group++) + { + const XA_SoundGroup *sg = (const XA_SoundGroup *)&sdata[12 + 4 + 8 + group * 128]; + + for(unsigned unit = 0; unit < (4U << unit_index_shift); unit++) + { + const uint8 param = sg->params[(unit & 3) | ((unit & 4) << 1)]; + const uint8 param_copy = sg->params[4 | (unit & 3) | ((unit & 4) << 1)]; + uint8 ibuffer[28]; + int16 obuffer[2 + 28]; + + //if(param != param_copy) + // printf("%d %02x %02x\n", unit, param, param_copy); + + for(unsigned i = 0; i < 28; i++) + { + uint8 tmp = sg->samples[i * 4 + (unit >> unit_index_shift)]; + + if(unit_index_shift) + { + tmp <<= (unit & 1) ? 0 : 4; + tmp &= 0xf0; + } + + ibuffer[i] = tmp; + } + + const bool ocn = (bool)(unit & 1) && (sh->coding & XA_CODING_STEREO); + + obuffer[0] = xa_previous[ocn][0]; + obuffer[1] = xa_previous[ocn][1]; + + PS_SPU::DecodeADPCM(ibuffer, &obuffer[2], param & 0x0F, param >> 4); + + xa_previous[ocn][0] = obuffer[28]; + xa_previous[ocn][1] = obuffer[29]; + + if(param != param_copy) + memset(obuffer, 0, sizeof(obuffer)); + + if(sh->coding & XA_CODING_STEREO) + { + for(unsigned s = 0; s < 28; s++) + { + ab->Samples[ocn][group * (2 << unit_index_shift) * 28 + (unit >> 1) * 28 + s] = obuffer[2 + s]; + } + } + else + { + for(unsigned s = 0; s < 28; s++) + { + ab->Samples[0][group * (4 << unit_index_shift) * 28 + unit * 28 + s] = obuffer[2 + s]; + ab->Samples[1][group * (4 << unit_index_shift) * 28 + unit * 28 + s] = obuffer[2 + s]; + } + } + } + } +} + +void PS_CDC::ClearAIP(void) +{ + AsyncResultsPendingCount = 0; + AsyncIRQPending = 0; +} + +void PS_CDC::CheckAIP(void) +{ + if(AsyncIRQPending && CDCReadyReceiveCounter <= 0) + { + BeginResults(); + + for(unsigned i = 0; i < AsyncResultsPendingCount; i++) + WriteResult(AsyncResultsPending[i]); + + WriteIRQ(AsyncIRQPending); + + ClearAIP(); + } +} + +void PS_CDC::SetAIP(unsigned irq, unsigned result_count, uint8 *r) +{ + if(AsyncIRQPending) + { + PSX_WARNING("***WARNING*** Previous notification skipped: CurSector=%d, old_notification=0x%02x", CurSector, AsyncIRQPending); + } + ClearAIP(); + + AsyncResultsPendingCount = result_count; + + for(unsigned i = 0; i < result_count; i++) + AsyncResultsPending[i] = r[i]; + + AsyncIRQPending = irq; + + CheckAIP(); +} + +void PS_CDC::SetAIP(unsigned irq, uint8 result0) +{ + uint8 tr[1] = { result0 }; + SetAIP(irq, 1, tr); +} + +void PS_CDC::SetAIP(unsigned irq, uint8 result0, uint8 result1) +{ + uint8 tr[2] = { result0, result1 }; + SetAIP(irq, 2, tr); +} + + +pscpu_timestamp_t PS_CDC::Update(const pscpu_timestamp_t timestamp) +{ + int32 clocks = timestamp - lastts; + + while(clocks > 0) + { + int32 chunk_clocks = clocks; + + if(PSRCounter > 0 && chunk_clocks > PSRCounter) + chunk_clocks = PSRCounter; + + if(PendingCommandCounter > 0 && chunk_clocks > PendingCommandCounter) + chunk_clocks = PendingCommandCounter; + + if(chunk_clocks > SPUCounter) + chunk_clocks = SPUCounter; + + if(DiscStartupDelay > 0) + { + if(chunk_clocks > DiscStartupDelay) + chunk_clocks = DiscStartupDelay; + + DiscStartupDelay -= chunk_clocks; + + if(DiscStartupDelay <= 0) + { + DriveStatus = DS_PAUSED; // or is it supposed to be DS_STANDBY? + } + } + + //MDFN_DispMessage("%02x %d -- %d %d -- %02x", IRQBuffer, CDCReadyReceiveCounter, PSRCounter, PendingCommandCounter, PendingCommand); + + if(!IRQBuffer) + { + if(CDCReadyReceiveCounter > 0 && chunk_clocks > CDCReadyReceiveCounter) + chunk_clocks = CDCReadyReceiveCounter; + + if(CDCReadyReceiveCounter > 0) + CDCReadyReceiveCounter -= chunk_clocks; + } + + CheckAIP(); + + if(PSRCounter > 0) + { + uint8 buf[2352 + 96]; + + PSRCounter -= chunk_clocks; + + if(PSRCounter <= 0) + { + if(DriveStatus == DS_RESETTING) + { + SetAIP(CDCIRQ_COMPLETE, MakeStatus()); + + Muted = false; // Does it get reset here? + ClearAudioBuffers(); + + SB_In = 0; + + Mode = 0; + CurSector = 0; + CommandLoc = 0; + + DriveStatus = DS_PAUSED; // or DS_STANDBY? + ClearAIP(); + } + else if(DriveStatus == DS_SEEKING) + { + CurSector = SeekTarget; + Cur_CDIF->ReadRawSector(buf, CurSector); + DecodeSubQ(buf + 2352); + + DriveStatus = StatusAfterSeek; + + if(DriveStatus != DS_PAUSED && DriveStatus != DS_STANDBY) + { + PSRCounter = 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1)); + } + } + else if(DriveStatus == DS_SEEKING_LOGICAL) + { + CurSector = SeekTarget; + Cur_CDIF->ReadRawSector(buf, CurSector); + DecodeSubQ(buf + 2352); + memcpy(HeaderBuf, buf + 12, 12); + + DriveStatus = StatusAfterSeek; + + if(DriveStatus != DS_PAUSED && DriveStatus != DS_STANDBY) + { + PSRCounter = 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1)); + } + } + else if(DriveStatus == DS_READING) + { + if(CurSector >= (int32)toc.tracks[100].lba) + { + PSX_WARNING("[CDC] Beyond end!"); + DriveStatus = DS_STOPPED; + + SetAIP(CDCIRQ_DISC_ERROR, MakeStatus() | 0x04, 0x04); + } + else if((Mode & MODE_STRSND) && AudioBuffer_UsedCount == AudioBuffer_Count) + { + PSRCounter += 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1)) / 4; + } + else + { + //PSX_WARNING("Read sector: %d", CurSector); + + Cur_CDIF->ReadRawSector(buf, CurSector); // FIXME: error out on error. + DecodeSubQ(buf + 2352); + + memcpy(HeaderBuf, buf + 12, 12); + HeaderBufValid = true; + + if((Mode & MODE_STRSND) && (buf[12 + 3] == 0x2) && (buf[12 + 6] & 0x20) && (buf[12 + 6] & 0x04)) + { + if(XA_Test(buf)) + { + //if(AudioBuffer_ReadPos & 0xFFF) + //printf("readpos=%04x(rabl=%04x) writepos=%04x\n", AudioBuffer_ReadPos, AudioBuffer[AudioBuffer_ReadPos >> 12].Size, AudioBuffer_WritePos); + + //if(AudioBuffer_UsedCount == 0) + // AudioBuffer_InPrebuffer = true; + + XA_ProcessSector(buf, &AudioBuffer[AudioBuffer_WritePos >> 12]); + AudioBuffer_UsedCount++; + + if(AudioBuffer_UsedCount == AudioBuffer_PreBufferCount) + AudioBuffer_InPrebuffer = false; + + AudioBuffer_WritePos = (AudioBuffer_WritePos & 0xFFF) | ((((AudioBuffer_WritePos >> 12) + 1) % AudioBuffer_Count) << 12); + } + } + else + { + // maybe if(!(Mode & 0x30)) too? + if(!(buf[12 + 6] & 0x20)) + { + if(!edc_lec_check_correct(buf, true)) + { + MDFN_DispMessage("Bad sector? - %d", CurSector); + } + } + + if(!(Mode & 0x30) && (buf[12 + 6] & 0x20)) + PSX_WARNING("BORK: %d", CurSector); + + { + int32 offs = (Mode & 0x20) ? 0 : 12; + int32 size = (Mode & 0x20) ? 2340 : 2048; + + if(Mode & 0x10) + { + offs = 12; + size = 2328; + } + + memcpy(SB, buf + 12 + offs, size); + SB_In = size; + } + + SetAIP(CDCIRQ_DATA_READY, MakeStatus()); + } + + PSRCounter += 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1)); + CurSector++; + } + } + else if(DriveStatus == DS_PLAYING) + { + if(CurSector >= (int32)toc.tracks[100].lba) + { + HeaderBufValid = false; + DriveStatus = DS_STOPPED; + SetAIP(CDCIRQ_DISC_ERROR, MakeStatus() | 0x04, 0x04); // TODO: Verify + } + else + { + if(AudioBuffer_UsedCount < AudioBuffer_Count) + { + Cur_CDIF->ReadRawSector(buf, CurSector); // FIXME: error out on error. + DecodeSubQ(buf + 2352); + + // Note: Some game(s) start playing in the pregap of a track(so don't replace this with a simple subq index == 0 check for autopause). + if(PlayTrackMatch == -1 && SubQChecksumOK) + PlayTrackMatch = SubQBuf_Safe[0x1]; + + if(1) //if(Mode & MODE_CDDA) MODE_CDDA doesn't seem to be required for CD-DA playback, so then what is it for? + { + CD_Audio_Buffer *ab = &AudioBuffer[AudioBuffer_WritePos >> 12]; + + ab->Freq = 7 * ((Mode & MODE_SPEED) ? 2 : 1); + ab->Size = 588; + + if(SubQBuf_Safe[0] & 0x40) + { + for(int i = 0; i < 588; i++) + { + ab->Samples[0][i] = 0; + ab->Samples[1][i] = 0; + } + } + else + { + for(int i = 0; i < 588; i++) + { + ab->Samples[0][i] = (int16)MDFN_de16lsb(&buf[i * sizeof(int16) * 2 + 0]); + ab->Samples[1][i] = (int16)MDFN_de16lsb(&buf[i * sizeof(int16) * 2 + 2]); + } + } + + //if(AudioBuffer_UsedCount == 0) + // AudioBuffer_InPrebuffer = true; + + AudioBuffer_UsedCount++; + + if(AudioBuffer_UsedCount == AudioBuffer_PreBufferCount) + AudioBuffer_InPrebuffer = false; + + AudioBuffer_WritePos = (AudioBuffer_WritePos & 0xFFF) | ((((AudioBuffer_WritePos >> 12) + 1) % AudioBuffer_Count) << 12); + } + + PSRCounter += 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1)); + + if((Mode & MODE_AUTOPAUSE) && PlayTrackMatch != -1 && SubQBuf_Safe[0x1] != PlayTrackMatch) + { + // Status needs to be taken before we're paused(IE it should still report playing). + SetAIP(CDCIRQ_DATA_END, MakeStatus()); + + DriveStatus = DS_PAUSED; + PSRCounter = 0; + } + else if((Mode & MODE_REPORT) && (!(SubQBuf_Safe[0x9] & 0xF) || Forward || Backward) && SubQChecksumOK) // Not sure about accurate notification behavior for corrupt SubQ data + { + uint8 tr[8]; + + tr[0] = MakeStatus(); + tr[1] = SubQBuf_Safe[0x1]; // Track + tr[2] = SubQBuf_Safe[0x2]; // Index + + if(SubQBuf_Safe[0x9] & 0x10) + { + tr[3] = SubQBuf_Safe[0x3]; // R M + tr[4] = SubQBuf_Safe[0x4] | 0x80; // R S + tr[5] = SubQBuf_Safe[0x5]; // R F + } + else + { + tr[3] = SubQBuf_Safe[0x7]; // A M + tr[4] = SubQBuf_Safe[0x8]; // A S + tr[5] = SubQBuf_Safe[0x9]; // A F + } + + tr[6] = 0; // ?? + tr[7] = 0; // ?? + + SetAIP(CDCIRQ_DATA_READY, 8, tr); + } + + // FIXME: What's the real fast-forward and backward speed? + if(Forward) + CurSector += 12; + else if(Backward) + { + CurSector -= 12; + + if(CurSector < 0) // FIXME: How does a real PS handle this condition? + CurSector = 0; + } + else + CurSector++; + } + else + PSX_WARNING("[CDC] BUG CDDA buffer full"); + + } + } // end if playing + } + } + + if(PendingCommandCounter > 0) + { + PendingCommandCounter -= chunk_clocks; + + if(PendingCommandCounter <= 0 && CDCReadyReceiveCounter > 0) + { + PendingCommandCounter = CDCReadyReceiveCounter; //256; + } + //else if(PendingCommandCounter <= 0 && PSRCounter > 0 && PSRCounter < 2000) + //{ + // PendingCommandCounter = PSRCounter + 1; + //} + else if(PendingCommandCounter <= 0) + { + int32 next_time = 0; + + BeginResults(); + + if(PendingCommandPhase) + { + const CDC_CTEntry *command = &Commands[PendingCommand]; + + next_time = (this->*(command->func2))(); + } + else if(PendingCommand >= 0x20 || !Commands[PendingCommand].func) + { + PSX_WARNING("[CDC] Unknown command: 0x%02x", PendingCommand); + + WriteResult(MakeStatus(true)); + WriteResult(ERRCODE_BAD_COMMAND); + WriteIRQ(CDCIRQ_DISC_ERROR); + + ArgsIn = 0; + } + else if(ArgsIn < Commands[PendingCommand].args_min || ArgsIn > Commands[PendingCommand].args_max) + { + PSX_WARNING("[CDC] Bad number(%d) of args(first check) for command 0x%02x", ArgsIn, PendingCommand); + + WriteResult(MakeStatus(true)); + WriteResult(ERRCODE_BAD_NUMARGS); + WriteIRQ(CDCIRQ_DISC_ERROR); + + ArgsIn = 0; + } + else + { + const CDC_CTEntry *command = &Commands[PendingCommand]; + //PSX_WARNING("[CDC] Command: %s --- %d", command->name, Results.CanRead()); + +#if 0 + printf("[CDC] Command: %s --- ", command->name); + for(unsigned int i = 0; i < ArgsIn; i++) + printf(" 0x%02x", ArgsBuf[i]); + printf("\n"); +#endif + next_time = (this->*(command->func))(ArgsIn, ArgsBuf); + PendingCommandPhase = 1; + ArgsIn = 0; + } + + if(!next_time) + PendingCommandCounter = 0; + else + PendingCommandCounter += next_time; + } + } + + SPUCounter = SPU->UpdateFromCDC(chunk_clocks); + + clocks -= chunk_clocks; + } // end while(clocks > 0) + + lastts = timestamp; + + return(timestamp + CalcNextEvent()); +} + +void PS_CDC::Write(const pscpu_timestamp_t timestamp, uint32 A, uint8 V) +{ + A &= 0x3; + + //printf("Write: %08x %02x\n", A, V); + + if(A == 0x00) + { + RegSelector = V & 0x3; + } + else + { + const unsigned reg_index = ((RegSelector & 0x3) * 3) + (A - 1); + + Update(timestamp); + //PSX_WARNING("[CDC] Write to register 0x%02x: 0x%02x @ %d --- 0x%02x\n", reg_index, V, timestamp, DMABuffer.CanRead()); + + switch(reg_index) + { + default: + PSX_WARNING("[CDC] Unknown write to register 0x%02x: 0x%02x\n", reg_index, V); + break; + + case 0x00: + if(PendingCommandCounter > 0) + { + PSX_WARNING("[CDC] WARNING: Interrupting command 0x%02x, phase=%d, timeleft=%d with command=0x%02x", PendingCommand, PendingCommandPhase, + PendingCommandCounter, V); + } + + if(IRQBuffer) + { + PSX_WARNING("[CDC] Attempting to start command(0x%02x) while IRQBuffer is not clear.", V); + } + + if(ResultsIn > 0) + { + PSX_WARNING("[CDC] Attempting to start command(0x%02x) while command results(count=%d) still in buffer.", V, ResultsIn); + } + + PendingCommandCounter = 8192; //1024; //128; //256; //16; //1024; + PendingCommand = V; + PendingCommandPhase = 0; + break; + + case 0x01: + ArgsBuf[ArgsIn & 0xF] = V; + ArgsIn = (ArgsIn + 1) & 0x1F; + + if(!(ArgsIn & 0x0F)) + { + PSX_WARNING("[CDC] Argument buffer overflow"); + } + break; + + case 0x02: + if(V & 0x80) + { + if(!DMABuffer.CanRead()) + { + if(!SB_In) + { + PSX_WARNING("[CDC] Data read begin when no data to read!"); + + DMABuffer.Write(SB, 2340); + + while(DMABuffer.CanWrite()) + DMABuffer.WriteByte(0x00); + } + else + { + DMABuffer.Write(SB, SB_In); + SB_In = 0; + } + } + else + { + //PSX_WARNING("[CDC] Attempt to start data transfer via 0x80->1803 when %d bytes still in buffer", DMABuffer.CanRead()); + } + } + else if(V & 0x40) // Something CD-DA related(along with & 0x20 ???)? + { + for(unsigned i = 0; i < 4 && DMABuffer.CanRead(); i++) + DMABuffer.ReadByte(); + } + else + { + DMABuffer.Flush(); + } + + if(V & 0x20) + { + PSX_WARNING("[CDC] Mystery IRQ trigger bit set."); + IRQBuffer |= 0x10; + } + break; + + case 0x04: + IRQOutTestMask = V; + RecalcIRQ(); + break; + + case 0x05: + IRQBuffer &= ~V; + RecalcIRQ(); + + if(V & 0x80) // Forced CD hardware reset of some kind(interface, controller, and drive?) Seems to take a while(relatively speaking) to complete. + { + PSX_WARNING("[CDC] Soft Reset"); + SoftReset(); + } + + if(V & 0x40) // Does it clear more than arguments buffer? Doesn't appear to clear results buffer. + { + ArgsIn = 0; + } + break; + + case 0x07: + Pending_DecodeVolume[0][0] = V; + break; + + case 0x08: + Pending_DecodeVolume[0][1] = V; + break; + + case 0x09: + Pending_DecodeVolume[1][1] = V; + break; + + case 0x0A: + Pending_DecodeVolume[1][0] = V; + break; + + case 0x0B: + if(V & 0x20) + { + memcpy(DecodeVolume, Pending_DecodeVolume, sizeof(DecodeVolume)); + + for(int i = 0; i < 2; i++) + { + for(int o = 0; o < 2; o++) + { + //fprintf(stderr, "Input Channel %d, Output Channel %d -- Volume=%d\n", i, o, DecodeVolume[i][o]); + } + } + } + break; + } + PSX_SetEventNT(PSX_EVENT_CDC, timestamp + CalcNextEvent()); + } +} + +uint8 PS_CDC::Read(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint8 ret = 0; + + A &= 0x03; + + //printf("Read %08x\n", A); + + if(A == 0x00) + { + ret = RegSelector & 0x3; + + ret |= 0x18; // Unknown purpose + + if(ResultsIn) + ret |= 0x20; + + if(DMABuffer.CanRead()) + ret |= 0x40; + + if(PendingCommandCounter > 0 && PendingCommandPhase == 0) + ret |= 0x80; + } + else + { + switch(A & 0x3) + { + case 0x01: + ret = ReadResult(); + break; + + case 0x02: + if(DMABuffer.CanRead()) + ret = DMABuffer.ReadByte(); + else + { + PSX_WARNING("[CDC] CD data transfer port read, but no data present!"); + } + break; + + case 0x03: + if(RegSelector & 0x1) + { + ret = 0xE0 | IRQBuffer; + } + else + { + ret = 0xFF; + } + break; + } + } + + return(ret); +} + + +bool PS_CDC::DMACanRead(void) +{ + return(DMABuffer.CanRead()); +} + +uint32 PS_CDC::DMARead(void) +{ + uint32 data = 0; + + for(int i = 0; i < 4; i++) + { + if(DMABuffer.CanRead()) + data |= DMABuffer.ReadByte() << (i * 8); + else + { + //assert(0); + } + } + + return(data); +} + +bool PS_CDC::CommandCheckDiscPresent(void) +{ + if(!Cur_CDIF || DiscStartupDelay > 0) + { + WriteResult(MakeStatus(true)); + WriteResult(ERRCODE_NOT_READY); + + WriteIRQ(CDCIRQ_DISC_ERROR); + + return(false); + } + + return(true); +} + +int32 PS_CDC::Command_Sync(const int arg_count, const uint8 *args) +{ + PSX_WARNING("[CDC] Unimplemented command: 0x%02x", PendingCommand); + return(0); +} + +int32 PS_CDC::Command_Nop(const int arg_count, const uint8 *args) +{ + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_Setloc(const int arg_count, const uint8 *args) +{ + uint8 m, s, f; + + m = BCD_to_U8(args[0] & 0x7F); + s = BCD_to_U8(args[1]); + f = BCD_to_U8(args[2]); + + CommandLoc = f + 75 * s + 75 * 60 * m - 150; + CommandLoc_Dirty = true; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::CalcSeekTime(int32 initial, int32 target, bool motor_on, bool paused) +{ + int32 ret = 0; + + if(!motor_on) + { + initial = 0; + ret += 33868800; + } + + ret += std::max((int64)abs(initial - target) * 33868800 * 1000 / (72 * 60 * 75) / 1000, 10000); + + if(abs(initial - target) >= 2250) + ret += (int64)33868800 * 300 / 1000; + else if(paused) + { + // The delay to restart from a Pause state is...very....WEIRD. The time it takes is related to the amount of time that has passed since the pause, and + // where on the disc the laser head is, with generally more time passed = longer to resume, except that there's a window of time where it takes a + // ridiculous amount of time when not much time has passed. + // + // What we have here will be EXTREMELY simplified. + + // + // + + //if(time_passed >= 67737) + //{ + //} + //else + { + // Take twice as long for 1x mode. + ret += 1247952 * ((Mode & MODE_SPEED) ? 1 : 2); + } + } + + //printf("%d\n", ret); + + return(ret); +} + +#if 0 +void PS_CDC::BeginSeek(uint32 target, int after_seek) +{ + SeekTarget = target; + StatusAfterSeek = after_seek; + + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); +} +#endif + +// Remove this function when we have better seek emulation; it's here because the Rockman complete works games(at least 2 and 4) apparently have finicky fubared CD +// access code. +void PS_CDC::PreSeekHack(uint32 target) +{ + uint8 buf[2352 + 96]; + int max_try = 32; + + CurSector = target; + + if(target < toc.tracks[100].lba) + { + do + { + Cur_CDIF->ReadRawSector(buf, target++); + } while(!DecodeSubQ(buf + 2352) && --max_try > 0 && target < toc.tracks[100].lba); + } +} + +int32 PS_CDC::Command_Play(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + ClearAIP(); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + Forward = Backward = false; + + if(arg_count && args[0]) + { + int track = BCD_to_U8(args[0]); + + if(track < toc.first_track) + { + PSX_WARNING("[CDC] Attempt to play track before first track."); + track = toc.first_track; + } + else if(track > toc.last_track) + { + PSX_WARNING("[CDC] Attempt to play track before first track."); + track = toc.last_track; + } + + ClearAudioBuffers(); + + PlayTrackMatch = track; + + printf("[CDC] Play track: %d\n", track); + SeekTarget = toc.tracks[track].lba; + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); + HeaderBufValid = false; + PreSeekHack(SeekTarget); + + DriveStatus = DS_SEEKING; + StatusAfterSeek = DS_PLAYING; + } + else + { + if(CommandLoc_Dirty || (DriveStatus != DS_PLAYING && DriveStatus != DS_PAUSED && DriveStatus != DS_STANDBY)) + { + ClearAudioBuffers(); + SeekTarget = CommandLoc; + PlayTrackMatch = -1; + + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); + HeaderBufValid = false; + PreSeekHack(SeekTarget); + + DriveStatus = DS_SEEKING; + StatusAfterSeek = DS_PLAYING; + } + else if(DriveStatus != DS_PLAYING) + { + ClearAudioBuffers(); + SeekTarget = CurSector; + PlayTrackMatch = -1; + + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); + HeaderBufValid = false; + PreSeekHack(SeekTarget); + + DriveStatus = DS_SEEKING; + StatusAfterSeek = DS_PLAYING; + } + } + + CommandLoc_Dirty = false; + return(0); +} + +int32 PS_CDC::Command_Forward(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + Backward = false; + Forward = true; + + return(0); +} + +int32 PS_CDC::Command_Backward(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + Backward = true; + Forward = false; + + return(0); +} + + +void PS_CDC::ReadBase(void) +{ + if(!CommandCheckDiscPresent()) + return; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + if(DriveStatus == DS_SEEKING_LOGICAL && SeekTarget == CommandLoc && StatusAfterSeek == DS_READING) + { + CommandLoc_Dirty = false; + return; + } + + if(CommandLoc_Dirty || DriveStatus != DS_READING) + { + CommandLoc_Dirty = false; + + + ClearAIP(); + ClearAudioBuffers(); + DMABuffer.Flush(); + SB_In = 0; + + // TODO: separate motor start from seek phase? + + SeekTarget = CommandLoc; + + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); + HeaderBufValid = false; + PreSeekHack(SeekTarget); + + DriveStatus = DS_SEEKING_LOGICAL; + StatusAfterSeek = DS_READING; + } +} + +int32 PS_CDC::Command_ReadN(const int arg_count, const uint8 *args) +{ + ReadBase(); + return 0; +} + +int32 PS_CDC::Command_ReadS(const int arg_count, const uint8 *args) +{ + ReadBase(); + return 0; +} + +int32 PS_CDC::Command_Stop(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + if(DriveStatus == DS_STOPPED) + { + return(5000); + } + else + { + ClearAudioBuffers(); + ClearAIP(); + DriveStatus = DS_STOPPED; + HeaderBufValid = false; + + return(33868); // FIXME, should be much higher. + } +} + +int32 PS_CDC::Command_Stop_Part2(void) +{ + PSRCounter = 0; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); +} + +int32 PS_CDC::Command_Standby(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + if(DriveStatus != DS_STOPPED) + { + WriteResult(MakeStatus(true)); + WriteResult(0x20); + WriteIRQ(CDCIRQ_DISC_ERROR); + return(0); + } + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + ClearAudioBuffers(); + ClearAIP(); + DriveStatus = DS_STANDBY; + + return((int64)33868800 * 100 / 1000); // No idea, FIXME. +} + +int32 PS_CDC::Command_Standby_Part2(void) +{ + PSRCounter = 0; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); +} + +int32 PS_CDC::Command_Pause(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + if(DriveStatus == DS_PAUSED || DriveStatus == DS_STOPPED) + { + return(5000); + } + else + { + // "Viewpoint" flips out and crashes if reading isn't stopped (almost?) immediately. + ClearAudioBuffers(); + ClearAIP(); + DriveStatus = DS_PAUSED; + + // An approximation. + return((1124584 + ((int64)CurSector * 42596 / (75 * 60))) * ((Mode & MODE_SPEED) ? 1 : 2)); + } +} + +int32 PS_CDC::Command_Pause_Part2(void) +{ + PSRCounter = 0; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); +} + +int32 PS_CDC::Command_Reset(const int arg_count, const uint8 *args) +{ + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + if(DriveStatus != DS_RESETTING) + { + HeaderBufValid = false; + DriveStatus = DS_RESETTING; + PSRCounter = 1136000; + } + + return(0); +} + +int32 PS_CDC::Command_Mute(const int arg_count, const uint8 *args) +{ + Muted = true; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_Demute(const int arg_count, const uint8 *args) +{ + Muted = false; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_Setfilter(const int arg_count, const uint8 *args) +{ + FilterFile = args[0]; + FilterChan = args[1]; + + //PSX_WARNING("[CDC] Setfilter: %02x %02x", args[0], args[1]); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_Setmode(const int arg_count, const uint8 *args) +{ + PSX_DBGINFO("[CDC] Set mode 0x%02x", args[0]); + Mode = args[0]; + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_Getparam(const int arg_count, const uint8 *args) +{ + WriteResult(MakeStatus()); + WriteResult(Mode); + WriteResult(0x00); + WriteResult(FilterFile); + WriteResult(FilterChan); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + + return(0); +} + +int32 PS_CDC::Command_GetlocL(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + if(!HeaderBufValid) + { + WriteResult(MakeStatus(true)); + WriteResult(0x80); + WriteIRQ(CDCIRQ_DISC_ERROR); + return(0); + } + + for(unsigned i = 0; i < 8; i++) + { + //printf("%d %d: %02x\n", DriveStatus, i, HeaderBuf[i]); + WriteResult(HeaderBuf[i]); + } + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_GetlocP(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(SubQBuf_Safe[0x1]); // Track + WriteResult(SubQBuf_Safe[0x2]); // Index + WriteResult(SubQBuf_Safe[0x3]); // R M + WriteResult(SubQBuf_Safe[0x4]); // R S + WriteResult(SubQBuf_Safe[0x5]); // R F + WriteResult(SubQBuf_Safe[0x7]); // A M + WriteResult(SubQBuf_Safe[0x8]); // A S + WriteResult(SubQBuf_Safe[0x9]); // A F + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_ReadT(const int arg_count, const uint8 *args) +{ + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(44100 * 768 / 1000); +} + +int32 PS_CDC::Command_ReadT_Part2(void) +{ + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); +} + +int32 PS_CDC::Command_GetTN(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteResult(U8_to_BCD(toc.first_track)); + WriteResult(U8_to_BCD(toc.last_track)); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_GetTD(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + int track; + uint8 m, s, f; + + if(!args[0] || args[0] == 0xAA) + track = 100; + else + { + track= BCD_to_U8(args[0]); + + if(track < toc.first_track || track > toc.last_track) // Error + { + WriteResult(MakeStatus(true)); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + return(0); + } + } + + LBA_to_AMSF(toc.tracks[track].lba, &m, &s, &f); + + WriteResult(MakeStatus()); + WriteResult(U8_to_BCD(m)); + WriteResult(U8_to_BCD(s)); + //WriteResult(U8_to_BCD(f)); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return(0); +} + +int32 PS_CDC::Command_SeekL(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + SeekTarget = CommandLoc; + + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); + HeaderBufValid = false; + PreSeekHack(SeekTarget); + DriveStatus = DS_SEEKING_LOGICAL; + StatusAfterSeek = DS_STANDBY; + ClearAIP(); + + return(PSRCounter); +} + +int32 PS_CDC::Command_SeekP(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + SeekTarget = CommandLoc; + + PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED); + HeaderBufValid = false; + PreSeekHack(SeekTarget); + DriveStatus = DS_SEEKING; + StatusAfterSeek = DS_STANDBY; + ClearAIP(); + + return(PSRCounter); +} + +int32 PS_CDC::Command_Seek_PartN(void) +{ + if(DriveStatus == DS_STANDBY) + { + BeginResults(); + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); + } + else + { + return(std::max(PSRCounter, 256)); + } +} + +int32 PS_CDC::Command_Test(const int arg_count, const uint8 *args) +{ + //PSX_WARNING("[CDC] Test command sub-operation: 0x%02x", args[0]); + + switch(args[0]) + { + default: + PSX_WARNING("[CDC] Unknown Test command sub-operation: 0x%02x", args[0]); + WriteResult(MakeStatus(true)); + WriteResult(0x10); + WriteIRQ(CDCIRQ_DISC_ERROR); + break; + + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1A: + PSX_WARNING("[CDC] Unknown Test command sub-operation: 0x%02x", args[0]); + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + break; + +#if 0 + case 0x50: // *Need to retest this test command, it takes additional arguments??? Or in any case, it generates a different error code(0x20) than most other Test + // sub-commands that generate an error code(0x10). + break; + + // Same with 0x60, 0x71-0x76 + +#endif + + case 0x51: // *Need to retest this test command + PSX_WARNING("[CDC] Unknown Test command sub-operation: 0x%02x", args[0]); + WriteResult(0x01); + WriteResult(0x00); + WriteResult(0x00); + break; + + case 0x75: // *Need to retest this test command + PSX_WARNING("[CDC] Unknown Test command sub-operation: 0x%02x", args[0]); + WriteResult(0x00); + WriteResult(0xC0); + WriteResult(0x00); + WriteResult(0x00); + break; + + // + // SCEx counters not reset by command 0x0A. + // + + case 0x04: // Reset SCEx counters + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + break; + + case 0x05: // Read SCEx counters + WriteResult(0x00); // Number of TOC/leadin reads? (apparently increases by 1 or 2 per ReadTOC, even on non-PSX music CD) + WriteResult(0x00); // Number of SCEx strings received? (Stays at zero on music CD) + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + break; + + case 0x20: + { + WriteResult(0x97); + WriteResult(0x01); + WriteResult(0x10); + WriteResult(0xC2); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + } + break; + + case 0x21: // *Need to retest this test command. + { + WriteResult(0x01); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + } + break; + + case 0x22: + { + static const uint8 td[7] = { 0x66, 0x6f, 0x72, 0x20, 0x55, 0x2f, 0x43 }; + + for(unsigned i = 0; i < 7; i++) + WriteResult(td[i]); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + } + break; + + case 0x23: + case 0x24: + { + static const uint8 td[8] = { 0x43, 0x58, 0x44, 0x32, 0x35, 0x34, 0x35, 0x51 }; + + for(unsigned i = 0; i < 8; i++) + WriteResult(td[i]); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + } + break; + + case 0x25: + { + static const uint8 td[8] = { 0x43, 0x58, 0x44, 0x31, 0x38, 0x31, 0x35, 0x51 }; + + for(unsigned i = 0; i < 8; i++) + WriteResult(td[i]); + + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + } + break; + } + return(0); +} + +int32 PS_CDC::Command_ID(const int arg_count, const uint8 *args) +{ + if(!CommandCheckDiscPresent()) + return(0); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + HeaderBufValid = false; + PSRCounter = 0; + DriveStatus = DS_PAUSED; // or DS_STANDBY? + ClearAIP(); + + return(33868); +} + +int32 PS_CDC::Command_ID_Part2(void) +{ + if(IsPSXDisc) + { + WriteResult(MakeStatus()); + WriteResult(0x00); + WriteResult(0x20); + WriteResult(0x00); + } + else + { + WriteResult(MakeStatus() | 0x08); + WriteResult(0x90); + WriteResult(0x00); + WriteResult(0x00); + } + + if(IsPSXDisc) + { + WriteResult(DiscID[0]); + WriteResult(DiscID[1]); + WriteResult(DiscID[2]); + WriteResult(DiscID[3]); + } + else + { + WriteResult(0xff); + WriteResult(0); + WriteResult(0); + WriteResult(0); + } + + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); +} + +int32 PS_CDC::Command_Init(const int arg_count, const uint8 *args) +{ + return(0); +} + +int32 PS_CDC::Command_ReadTOC(const int arg_count, const uint8 *args) +{ + // Tested; ReadTOC doesn't error out if the tray is open, and it completes rather quickly in that case. + // + //if(!CommandCheckDiscPresent()) + // return(0); + + HeaderBufValid = false; + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + + return((int64)33868800 * 500 / 1000); +} + +int32 PS_CDC::Command_ReadTOC_Part2(void) +{ + DriveStatus = DS_PAUSED; // or DS_STANDBY? + ClearAIP(); + + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_COMPLETE); + + return(0); +} + +int32 PS_CDC::Command_0x1d(const int arg_count, const uint8 *args) +{ + WriteResult(MakeStatus()); + WriteIRQ(CDCIRQ_ACKNOWLEDGE); + return(0); +} + +PS_CDC::CDC_CTEntry PS_CDC::Commands[0x20] = +{ + { /* 0x00, */ 0, 0, "Sync", &PS_CDC::Command_Sync, NULL }, + { /* 0x01, */ 0, 0, "Nop", &PS_CDC::Command_Nop, NULL }, + { /* 0x02, */ 3, 3, "Setloc", &PS_CDC::Command_Setloc, NULL }, + { /* 0x03, */ 0, 1, "Play", &PS_CDC::Command_Play, NULL }, + { /* 0x04, */ 0, 0, "Forward", &PS_CDC::Command_Forward, NULL }, + { /* 0x05, */ 0, 0, "Backward", &PS_CDC::Command_Backward, NULL }, + { /* 0x06, */ 0, 0, "ReadN", &PS_CDC::Command_ReadN, NULL }, + { /* 0x07, */ 0, 0, "Standby", &PS_CDC::Command_Standby, &PS_CDC::Command_Standby_Part2 }, + { /* 0x08, */ 0, 0, "Stop", &PS_CDC::Command_Stop, &PS_CDC::Command_Stop_Part2 }, + { /* 0x09, */ 0, 0, "Pause", &PS_CDC::Command_Pause, &PS_CDC::Command_Pause_Part2 }, + { /* 0x0A, */ 0, 0, "Reset", &PS_CDC::Command_Reset, NULL }, + { /* 0x0B, */ 0, 0, "Mute", &PS_CDC::Command_Mute, NULL }, + { /* 0x0C, */ 0, 0, "Demute", &PS_CDC::Command_Demute, NULL }, + { /* 0x0D, */ 2, 2, "Setfilter", &PS_CDC::Command_Setfilter, NULL }, + { /* 0x0E, */ 1, 1, "Setmode", &PS_CDC::Command_Setmode, NULL }, + { /* 0x0F, */ 0, 0, "Getparam", &PS_CDC::Command_Getparam, NULL }, + { /* 0x10, */ 0, 0, "GetlocL", &PS_CDC::Command_GetlocL, NULL }, + { /* 0x11, */ 0, 0, "GetlocP", &PS_CDC::Command_GetlocP, NULL }, + { /* 0x12, */ 1, 1, "ReadT", &PS_CDC::Command_ReadT, &PS_CDC::Command_ReadT_Part2 }, + { /* 0x13, */ 0, 0, "GetTN", &PS_CDC::Command_GetTN, NULL }, + { /* 0x14, */ 1, 1, "GetTD", &PS_CDC::Command_GetTD, NULL }, + { /* 0x15, */ 0, 0, "SeekL", &PS_CDC::Command_SeekL, &PS_CDC::Command_Seek_PartN }, + { /* 0x16, */ 0, 0, "SeekP", &PS_CDC::Command_SeekP, &PS_CDC::Command_Seek_PartN }, + + { /* 0x17, */ 0, 0, NULL, NULL, NULL }, + { /* 0x18, */ 0, 0, NULL, NULL, NULL }, + + { /* 0x19, */ 1, 1/* ??? */, "Test", &PS_CDC::Command_Test, NULL }, + { /* 0x1A, */ 0, 0, "ID", &PS_CDC::Command_ID, &PS_CDC::Command_ID_Part2 }, + { /* 0x1B, */ 0, 0, "ReadS", &PS_CDC::Command_ReadS, NULL }, + { /* 0x1C, */ 0, 0, "Init", &PS_CDC::Command_Init, NULL }, + { /* 0x1D, */ 2, 2, "Unknown 0x1D", &PS_CDC::Command_0x1d, NULL }, + { /* 0x1E, */ 0, 0, "ReadTOC", &PS_CDC::Command_ReadTOC, &PS_CDC::Command_ReadTOC_Part2 }, + { /* 0x1F, */ 0, 0, NULL, NULL, NULL }, +}; + + +} diff --git a/mednafen/psx-0925/cdc.h b/mednafen/psx-0925/cdc.h new file mode 100644 index 00000000..9f9da3d6 --- /dev/null +++ b/mednafen/psx-0925/cdc.h @@ -0,0 +1,311 @@ +#ifndef __MDFN_PSX_CDC_H +#define __MDFN_PSX_CDC_H + +#include "../cdrom/cdromif.h" +#include "../cdrom/SimpleFIFO.h" +#include "../clamp.h" + +namespace MDFN_IEN_PSX +{ + +struct CD_Audio_Buffer +{ + int16 Samples[2][0x1000]; // [0][...] = l, [1][...] = r + int32 Size; + uint32 Freq; +}; + +class PS_CDC +{ + public: + + PS_CDC(); + ~PS_CDC(); + + void SetDisc(bool tray_open, CDIF *cdif, const char disc_id[4]); + + void Power(void); + int StateAction(StateMem *sm, int load, int data_only); + void ResetTS(void); + + int32 CalcNextEvent(void); // Returns in master cycles to next event. + + pscpu_timestamp_t Update(const pscpu_timestamp_t timestamp); + + void Write(const pscpu_timestamp_t timestamp, uint32 A, uint8 V); + uint8 Read(const pscpu_timestamp_t timestamp, uint32 A); + + bool DMACanRead(void); + uint32 DMARead(void); + + INLINE uint32 GetCDAudioFreq(void) + { + if(AudioBuffer_UsedCount && !AudioBuffer_InPrebuffer) + { + const unsigned wb = AudioBuffer_ReadPos >> 12; + return AudioBuffer[wb].Freq; + } + return 0; + } + + private: + inline void ApplyVolume(int32 samples[2]) + { + int32 left_source = samples[0]; //(int16)MDFN_de16lsb(&buf[i * sizeof(int16) * 2 + 0]); + int32 right_source = samples[1]; //(int16)MDFN_de16lsb(&buf[i * sizeof(int16) * 2 + 2]); + int32 left_out = ((left_source * DecodeVolume[0][0]) >> 7) + ((right_source * DecodeVolume[1][0]) >> 7); + int32 right_out = ((left_source * DecodeVolume[0][1]) >> 7) + ((right_source * DecodeVolume[1][1]) >> 7); + + clamp(&left_out, -32768, 32767); + clamp(&right_out, -32768, 32767); + + if(Muted) + { + left_out = right_out = 0; + } + + samples[0] = left_out; + samples[1] = right_out; + } + public: + + INLINE void GetCDAudio(int32 &l, int32 &r) + { + if(AudioBuffer_UsedCount && !AudioBuffer_InPrebuffer) + { + const unsigned wb = AudioBuffer_ReadPos >> 12; + int32 samples[2] = { AudioBuffer[wb].Samples[0][AudioBuffer_ReadPos & 0xFFF], AudioBuffer[wb].Samples[1][AudioBuffer_ReadPos & 0xFFF] }; + + ApplyVolume(samples); + + l = samples[0]; + r = samples[1]; + + AudioBuffer_ReadPos = ((AudioBuffer_ReadPos + 1) & 0xFFF) | (AudioBuffer_ReadPos & ~0xFFF); + + if((AudioBuffer_ReadPos & 0xFFF) == (AudioBuffer[wb].Size & 0xFFF)) + { + //printf("RP == size; usedcount(predec)= %d, PSRCounter=%d\n", AudioBuffer_UsedCount, PSRCounter); + AudioBuffer_ReadPos = ((((AudioBuffer_ReadPos >> 12) + 1) % AudioBuffer_Count) << 12); + AudioBuffer_UsedCount--; + } + } + } + + private: + + void SoftReset(void); + + CDIF *Cur_CDIF; + bool DiscChanged; + int32 DiscStartupDelay; + + + enum { AudioBuffer_PreBufferCount = 2 }; + enum { AudioBuffer_Count = 4 }; + + CD_Audio_Buffer AudioBuffer[AudioBuffer_Count]; + uint32 AudioBuffer_ReadPos; + uint32 AudioBuffer_WritePos; + uint32 AudioBuffer_UsedCount; + bool AudioBuffer_InPrebuffer; + + uint8 Pending_DecodeVolume[2][2], DecodeVolume[2][2]; // [data_source][output_port] + + void ClearAudioBuffers(void); + + uint8 RegSelector; + uint8 ArgsBuf[16]; + uint32 ArgsIn; // 5-bit(0 ... 31) + + uint8 ResultsBuffer[16]; + uint8 ResultsIn; // 5-bit(0 ... 31) + uint8 ResultsWP; // Write position, 4 bit(0 ... 15). + uint8 ResultsRP; // Read position, 4 bit(0 ... 15). + + SimpleFIFO DMABuffer; + uint8 SB[2340]; + uint32 SB_In; + + + uint8 SubQBuf[0xC]; + uint8 SubQBuf_Safe[0xC]; + bool SubQChecksumOK; + + bool HeaderBufValid; + uint8 HeaderBuf[12]; + + void RecalcIRQ(void); + enum + { + CDCIRQ_NONE = 0, + CDCIRQ_DATA_READY = 1, + CDCIRQ_COMPLETE = 2, + CDCIRQ_ACKNOWLEDGE = 3, + CDCIRQ_DATA_END = 4, + CDCIRQ_DISC_ERROR = 5 + }; + + // Names are just guessed for these based on what conditions cause them: + enum + { + ERRCODE_BAD_ARGVAL = 0x10, + ERRCODE_BAD_NUMARGS = 0x20, + ERRCODE_BAD_COMMAND = 0x40, + ERRCODE_NOT_READY = 0x80, // 0x80 (happens with getlocl when drive isn't reading, pause when tray is open, and MAYBE when trying to run an async + // command while another async command is currently in its asynch phase being executed[pause when in readtoc, todo test more]) + }; + + uint8 IRQBuffer; + uint8 IRQOutTestMask; + int32 CDCReadyReceiveCounter; // IRQBuffer being non-zero prevents new results and new IRQ from coming in and erasing the current results, + // but apparently at least one CONFOUNDED game is clearing the IRQ state BEFORE reading the results, so we need to have a delay + // between IRQBuffer being cleared to when we allow new results to come in. (The real thing should be like this too, + // but the mechanism is probably more nuanced and complex and ugly and I like anchovy pizza) + + void BeginResults(void); + void WriteIRQ(uint8); + void WriteResult(uint8); + uint8 ReadResult(void); + + uint8 FilterFile; + uint8 FilterChan; + + + uint8 PendingCommand; + bool PendingCommandPhase; + int32 PendingCommandCounter; + + int32 SPUCounter; + + enum { MODE_SPEED = 0x80 }; + enum { MODE_STRSND = 0x40 }; + enum { MODE_SIZE = 0x20 }; + enum { MODE_SIZE2 = 0x10 }; + enum { MODE_SF = 0x08 }; + enum { MODE_REPORT = 0x04 }; + enum { MODE_AUTOPAUSE = 0x02 }; + enum { MODE_CDDA = 0x01 }; + uint8 Mode; + + enum + { + DS_STANDBY = -2, + DS_PAUSED = -1, + DS_STOPPED = 0, + DS_SEEKING, + DS_SEEKING_LOGICAL, + DS_PLAY_SEEKING, + DS_PLAYING, + DS_READING, + DS_RESETTING + }; + int DriveStatus; + int StatusAfterSeek; + bool Forward; + bool Backward; + bool Muted; + + int32 PlayTrackMatch; + + int32 PSRCounter; + + int32 CurSector; + + unsigned AsyncIRQPending; + uint8 AsyncResultsPending[16]; + uint8 AsyncResultsPendingCount; + + int32 CalcSeekTime(int32 initial, int32 target, bool motor_on, bool paused); + + void ClearAIP(void); + void CheckAIP(void); + void SetAIP(unsigned irq, unsigned result_count, uint8 *r); + void SetAIP(unsigned irq, uint8 result0); + void SetAIP(unsigned irq, uint8 result0, uint8 result1); + + int32 SeekTarget; + + pscpu_timestamp_t lastts; + + CDUtility::TOC toc; + bool IsPSXDisc; + uint8 DiscID[4]; + + int32 CommandLoc; + bool CommandLoc_Dirty; + + uint8 MakeStatus(bool cmd_error = false); + bool DecodeSubQ(uint8 *subpw); + bool CommandCheckDiscPresent(void); + + bool XA_Test(const uint8 *sdata); + void XA_ProcessSector(const uint8 *sdata, CD_Audio_Buffer *ab); + int16 xa_previous[2][2]; + bool xa_cur_set; + uint8 xa_cur_file; + uint8 xa_cur_chan; + + struct CDC_CTEntry + { + uint8 args_min; + uint8 args_max; + const char *name; + int32 (PS_CDC::*func)(const int arg_count, const uint8 *args); + int32 (PS_CDC::*func2)(void); + }; + + void BeginSeek(uint32 target); + void PreSeekHack(uint32 target); + void ReadBase(void); + + static CDC_CTEntry Commands[0x20]; + + int32 Command_Sync(const int arg_count, const uint8 *args); + int32 Command_Nop(const int arg_count, const uint8 *args); + int32 Command_Setloc(const int arg_count, const uint8 *args); + int32 Command_Play(const int arg_count, const uint8 *args); + int32 Command_Forward(const int arg_count, const uint8 *args); + int32 Command_Backward(const int arg_count, const uint8 *args); + int32 Command_ReadN(const int arg_count, const uint8 *args); + int32 Command_Standby(const int arg_count, const uint8 *args); + int32 Command_Standby_Part2(void); + int32 Command_Stop(const int arg_count, const uint8 *args); + int32 Command_Stop_Part2(void); + int32 Command_Pause(const int arg_count, const uint8 *args); + int32 Command_Pause_Part2(void); + int32 Command_Reset(const int arg_count, const uint8 *args); + int32 Command_Mute(const int arg_count, const uint8 *args); + int32 Command_Demute(const int arg_count, const uint8 *args); + int32 Command_Setfilter(const int arg_count, const uint8 *args); + int32 Command_Setmode(const int arg_count, const uint8 *args); + int32 Command_Getparam(const int arg_count, const uint8 *args); + int32 Command_GetlocL(const int arg_count, const uint8 *args); + int32 Command_GetlocP(const int arg_count, const uint8 *args); + + int32 Command_ReadT(const int arg_count, const uint8 *args); + int32 Command_ReadT_Part2(void); + + int32 Command_GetTN(const int arg_count, const uint8 *args); + int32 Command_GetTD(const int arg_count, const uint8 *args); + int32 Command_SeekL(const int arg_count, const uint8 *args); + int32 Command_SeekP(const int arg_count, const uint8 *args); + int32 Command_Seek_PartN(void); + + int32 Command_Test(const int arg_count, const uint8 *args); + + int32 Command_ID(const int arg_count, const uint8 *args); + int32 Command_ID_Part2(void); + + int32 Command_ReadS(const int arg_count, const uint8 *args); + int32 Command_Init(const int arg_count, const uint8 *args); + + int32 Command_ReadTOC(const int arg_count, const uint8 *args); + int32 Command_ReadTOC_Part2(void); + + int32 Command_0x1d(const int arg_count, const uint8 *args); +}; + +} + +#endif diff --git a/mednafen/psx-0925/cpu.cpp b/mednafen/psx-0925/cpu.cpp new file mode 100644 index 00000000..b6fbe57f --- /dev/null +++ b/mednafen/psx-0925/cpu.cpp @@ -0,0 +1,1942 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "cpu.h" + +/* TODO + Make sure load delays are correct. + + Consider preventing IRQs being taken while in a branch delay slot, to prevent potential problems with games that like to be too clever and perform + un-restartable sequences of instructions. +*/ + +namespace MDFN_IEN_PSX +{ + + +PS_CPU::PS_CPU() +{ + Halted = false; + + memset(FastMap, 0, sizeof(FastMap)); + memset(DummyPage, 0xFF, sizeof(DummyPage)); // 0xFF to trigger an illegal instruction exception, so we'll know what's up when debugging. + + for(uint64 a = 0x00000000; a < (1ULL << 32); a += FAST_MAP_PSIZE) + SetFastMap(DummyPage, a, FAST_MAP_PSIZE); + + CPUHook = NULL; + ADDBT = NULL; +} + +PS_CPU::~PS_CPU() +{ + + +} + +void PS_CPU::SetFastMap(void *region_mem, uint32 region_address, uint32 region_size) +{ + // FAST_MAP_SHIFT + // FAST_MAP_PSIZE + + for(uint64 A = region_address; A < region_address + region_size; A += FAST_MAP_PSIZE) + { + FastMap[A >> FAST_MAP_SHIFT] = ((uint8 *)region_mem - region_address); + } +} + +INLINE void PS_CPU::RecalcIPCache(void) +{ + IPCache = 0; + + if((CP0.SR & CP0.CAUSE & 0xFF00) && (CP0.SR & 1)) + IPCache = 0x80; + + if(Halted) + IPCache = 0x80; +} + +void PS_CPU::SetHalt(bool status) +{ + Halted = status; + RecalcIPCache(); +} + +void PS_CPU::Power(void) +{ + memset(GPR, 0, sizeof(GPR)); + memset(&CP0, 0, sizeof(CP0)); + LO = 0; + HI = 0; + + gte_ts_done = 0; + + BACKED_PC = 0xBFC00000; + BACKED_new_PC = 4; + BACKED_new_PC_mask = ~0U; + + BACKED_LDWhich = 0x20; + BACKED_LDValue = 0; + + CP0.SR |= (1 << 22); // BEV + CP0.SR |= (1 << 21); // TS + + CP0.PRID = 0x300; // PRId: FIXME(test on real thing) + + RecalcIPCache(); + + GTE_Power(); +} + +int PS_CPU::StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { + SFARRAY32(GPR, 32), + SFVAR(LO), + SFVAR(HI), + SFVAR(BACKED_PC), + SFVAR(BACKED_new_PC), + SFVAR(BACKED_new_PC_mask), + + SFVAR(IPCache), + SFVAR(Halted), + + SFVAR(BACKED_LDWhich), + SFVAR(BACKED_LDValue), + + SFVAR(next_event_ts), + SFVAR(gte_ts_done), + + SFARRAY32(CP0.Regs, 32), + + SFEND + }; + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "CPU"); + + ret &= GTE_StateAction(sm, load, data_only); + + if(load) + { + + } + + return(ret); +} + +void PS_CPU::AssertIRQ(int which, bool asserted) +{ + assert(which >= 0 && which <= 5); + + CP0.CAUSE &= ~(1 << (10 + which)); + + if(asserted) + CP0.CAUSE |= 1 << (10 + which); + + RecalcIPCache(); +} + +template +INLINE T PS_CPU::ReadMemory(pscpu_timestamp_t ×tamp, uint32 address, bool DS24) +{ + T ret; + + timestamp += 2; + //timestamp++; + //assert(!(CP0.SR & 0x10000)); + + if(sizeof(T) == 1) + ret = PSX_MemRead8(timestamp, address); + else if(sizeof(T) == 2) + ret = PSX_MemRead16(timestamp, address); + else + { + if(DS24) + ret = PSX_MemRead24(timestamp, address) & 0xFFFFFF; + else + ret = PSX_MemRead32(timestamp, address); + } + + return(ret); +} + +template +INLINE void PS_CPU::WriteMemory(pscpu_timestamp_t ×tamp, uint32 address, uint32 value, bool DS24) +{ + if(!(CP0.SR & 0x10000)) + { + if(sizeof(T) == 1) + PSX_MemWrite8(timestamp, address, value); + else if(sizeof(T) == 2) + PSX_MemWrite16(timestamp, address, value); + else + { + if(DS24) + PSX_MemWrite24(timestamp, address, value); + else + PSX_MemWrite32(timestamp, address, value); + } + } + //else + // printf("ISC WRITE%d %08x %08x\n", (int)sizeof(T), address, value); +} + +uint32 PS_CPU::Exception(uint32 code, uint32 PC, const uint32 NPM) +{ + const bool InBDSlot = !(NPM & 0x3); + uint32 handler = 0x80000080; + + assert(code < 16); + + if(code != EXCEPTION_INT && code != EXCEPTION_BP && code != EXCEPTION_SYSCALL) + { + printf("Exception: %08x @ PC=0x%08x(IBDS=%d) -- IPCache=0x%02x -- IPEND=0x%02x -- SR=0x%08x ; IRQC_Status=0x%04x -- IRQC_Mask=0x%04x\n", code, PC, InBDSlot, IPCache, (CP0.CAUSE >> 8) & 0xFF, CP0.SR, + IRQ_GetRegister(IRQ_GSREG_STATUS, NULL, 0), IRQ_GetRegister(IRQ_GSREG_MASK, NULL, 0)); + //assert(0); + } + + if(CP0.SR & (1 << 22)) // BEV + handler = 0xBFC00180; + + CP0.EPC = PC; + if(InBDSlot) + CP0.EPC -= 4; + + if(ADDBT) + ADDBT(PC, handler, true); + + // "Push" IEc and KUc(so that the new IEc and KUc are 0) + CP0.SR = (CP0.SR & ~0x3F) | ((CP0.SR << 2) & 0x3F); + + // Setup cause register + CP0.CAUSE &= 0x0000FF00; + CP0.CAUSE |= code << 2; + + // If EPC was adjusted -= 4 because we were in a branch delay slot, set the bit. + if(InBDSlot) + CP0.CAUSE |= 0x80000000; + + RecalcIPCache(); + + return(handler); +} + +#define BACKING_TO_ACTIVE \ + PC = BACKED_PC; \ + new_PC = BACKED_new_PC; \ + new_PC_mask = BACKED_new_PC_mask; \ + LDWhich = BACKED_LDWhich; \ + LDValue = BACKED_LDValue; + +#define ACTIVE_TO_BACKING \ + BACKED_PC = PC; \ + BACKED_new_PC = new_PC; \ + BACKED_new_PC_mask = new_PC_mask; \ + BACKED_LDWhich = LDWhich; \ + BACKED_LDValue = LDValue; + + +template +pscpu_timestamp_t PS_CPU::RunReal(pscpu_timestamp_t timestamp_in) +{ + register pscpu_timestamp_t timestamp = timestamp_in; + + register uint32 PC; + register uint32 new_PC; + register uint32 new_PC_mask; + register uint32 LDWhich; + register uint32 LDValue; + + BACKING_TO_ACTIVE; + + do + { + //printf("Running: %d %d\n", timestamp, next_event_ts); + while(timestamp < next_event_ts) + { + uint32 instr; + uint32 opf; + + // Zero must be zero...until the Master Plan is enacted. + GPR[0] = 0; + + if(DebugMode && CPUHook) + { + ACTIVE_TO_BACKING; + + CPUHook(PC); + + BACKING_TO_ACTIVE; + } + + if(!ILHMode) + { + if(PC == 0xB0) + { + if(GPR[9] == 0x3D) + { + //if(GPR[4] == 'L') + // DBG_Break(); + fputc(GPR[4], stderr); + //if(GPR[4] == '\n') + //{ + // fputc('%', stderr); + // fputc(' ', stderr); + //} + } + } + } + +/* + if(PC == 0xB0) + { + if(GPR[9] != 0xB) + PSX_WARNING("[BIOS] 0xB0 t1=0x%02x", GPR[9]); + } +*/ + instr = LoadU32_LE((uint32 *)&FastMap[PC >> FAST_MAP_SHIFT][PC]); + + //printf("PC=%08x, SP=%08x - op=0x%02x - funct=0x%02x - instr=0x%08x\n", PC, GPR[29], instr >> 26, instr & 0x3F, instr); + //for(int i = 0; i < 32; i++) + // printf("%02x : %08x\n", i, GPR[i]); + //printf("\n"); + + opf = instr & 0x3F; + + if(instr & (0x3F << 26)) + opf = 0x40 | (instr >> 26); + + opf |= IPCache; + + timestamp++; + + #define DO_LDS() { GPR[LDWhich] = LDValue; LDWhich = 0x20; } + #define BEGIN_OPF(name, arg_op, arg_funct) { op_##name: /*assert( ((arg_op) ? (0x40 | (arg_op)) : (arg_funct)) == opf); */ + #define END_OPF goto OpDone; } + + #define DO_BRANCH(offset, mask) \ + { \ + if(ILHMode) \ + { \ + uint32 old_PC = PC; \ + PC = (PC & new_PC_mask) + new_PC; \ + if(old_PC == ((PC & (mask)) + (offset))) \ + { \ + if(*(uint32 *)&FastMap[PC >> FAST_MAP_SHIFT][PC] == 0) \ + { \ + if(next_event_ts > timestamp) /* Necessary since next_event_ts might be set to something like "0" to force a call to the event handler. */ \ + { \ + timestamp = next_event_ts; \ + } \ + } \ + } \ + } \ + else \ + PC = (PC & new_PC_mask) + new_PC; \ + new_PC = (offset); \ + new_PC_mask = (mask) & ~3; \ + /* Lower bits of new_PC_mask being clear signifies being in a branch delay slot. (overloaded behavior for performance) */ \ + \ + if(DebugMode && ADDBT) \ + { \ + ADDBT(PC, (PC & new_PC_mask) + new_PC, false); \ + } \ + goto SkipNPCStuff; \ + } + + #define ITYPE uint32 rs __attribute__((unused)) = (instr >> 21) & 0x1F; uint32 rt __attribute__((unused)) = (instr >> 16) & 0x1F; int32 immediate = (int16)(instr & 0xFFFF); /*printf(" rs=%02x(%08x), rt=%02x(%08x), immediate=(%08x) ", rs, GPR[rs], rt, GPR[rt], immediate);*/ + #define ITYPE_ZE uint32 rs __attribute__((unused)) = (instr >> 21) & 0x1F; uint32 rt __attribute__((unused)) = (instr >> 16) & 0x1F; uint32 immediate = instr & 0xFFFF; /*printf(" rs=%02x(%08x), rt=%02x(%08x), immediate=(%08x) ", rs, GPR[rs], rt, GPR[rt], immediate);*/ + #define JTYPE uint32 target = instr & ((1 << 26) - 1); /*printf(" target=(%08x) ", target);*/ + #define RTYPE uint32 rs __attribute__((unused)) = (instr >> 21) & 0x1F; uint32 rt __attribute__((unused)) = (instr >> 16) & 0x1F; uint32 rd __attribute__((unused)) = (instr >> 11) & 0x1F; uint32 shamt __attribute__((unused)) = (instr >> 6) & 0x1F; /*printf(" rs=%02x(%08x), rt=%02x(%08x), rd=%02x(%08x) ", rs, GPR[rs], rt, GPR[rt], rd, GPR[rd]);*/ + + static const void *const op_goto_table[256] = + { + &&op_SLL, &&op_ILL, &&op_SRL, &&op_SRA, &&op_SLLV, &&op_ILL, &&op_SRLV, &&op_SRAV, + &&op_JR, &&op_JALR, &&op_ILL, &&op_ILL, &&op_SYSCALL, &&op_BREAK, &&op_ILL, &&op_ILL, + &&op_MFHI, &&op_MTHI, &&op_MFLO, &&op_MTLO, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_MULT, &&op_MULTU, &&op_DIV, &&op_DIVU, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_ADD, &&op_ADDU, &&op_SUB, &&op_SUBU, &&op_AND, &&op_OR, &&op_XOR, &&op_NOR, + &&op_ILL, &&op_ILL, &&op_SLT, &&op_SLTU, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + + NULL, &&op_BCOND, &&op_J, &&op_JAL, &&op_BEQ, &&op_BNE, &&op_BLEZ, &&op_BGTZ, + &&op_ADDI, &&op_ADDIU, &&op_SLTI, &&op_SLTIU, &&op_ANDI, &&op_ORI, &&op_XORI, &&op_LUI, + &&op_COP0, &&op_COP1, &&op_COP2, &&op_COP3, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_LB, &&op_LH, &&op_LWL, &&op_LW, &&op_LBU, &&op_LHU, &&op_LWR, &&op_ILL, + &&op_SB, &&op_SH, &&op_SWL, &&op_SW, &&op_ILL, &&op_ILL, &&op_SWR, &&op_ILL, + &&op_LWC0, &&op_LWC1, &&op_LWC2, &&op_LWC3, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + &&op_SWC0, &&op_SWC1, &&op_SWC2, &&op_SWC3, &&op_ILL, &&op_ILL, &&op_ILL, &&op_ILL, + + // Interrupt portion of this table is constructed so that an interrupt won't be taken when the PC is pointing to a GTE instruction, + // to avoid problems caused by pipeline vs coprocessor nuances that aren't emulated. + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + + NULL, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_COP2, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, &&op_INTERRUPT, + }; + + goto *op_goto_table[opf]; + + { + BEGIN_OPF(ILL, 0, 0); + PSX_WARNING("[CPU] Unknown instruction @%08x = %08x, op=%02x, funct=%02x", PC, instr, instr >> 26, (instr & 0x3F)); + DO_LDS(); + new_PC = Exception(EXCEPTION_RI, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // ADD - Add Word + // + BEGIN_OPF(ADD, 0, 0x20); + RTYPE; + uint32 result = GPR[rs] + GPR[rt]; + bool ep = ((~(GPR[rs] ^ GPR[rt])) & (GPR[rs] ^ result)) & 0x80000000; + + DO_LDS(); + + if(ep) + { + new_PC = Exception(EXCEPTION_OV, PC, new_PC_mask); + new_PC_mask = 0; + } + else + GPR[rd] = result; + + END_OPF; + + // + // ADDI - Add Immediate Word + // + BEGIN_OPF(ADDI, 0x08, 0); + ITYPE; + uint32 result = GPR[rs] + immediate; + bool ep = ((~(GPR[rs] ^ immediate)) & (GPR[rs] ^ result)) & 0x80000000; + + DO_LDS(); + + if(ep) + { + new_PC = Exception(EXCEPTION_OV, PC, new_PC_mask); + new_PC_mask = 0; + } + else + GPR[rt] = result; + + END_OPF; + + // + // ADDIU - Add Immediate Unsigned Word + // + BEGIN_OPF(ADDIU, 0x09, 0); + ITYPE; + uint32 result = GPR[rs] + immediate; + + DO_LDS(); + + GPR[rt] = result; + + END_OPF; + + // + // ADDU - Add Unsigned Word + // + BEGIN_OPF(ADDU, 0, 0x21); + RTYPE; + uint32 result = GPR[rs] + GPR[rt]; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + // + // AND - And + // + BEGIN_OPF(AND, 0, 0x24); + RTYPE; + uint32 result = GPR[rs] & GPR[rt]; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + // + // ANDI - And Immediate + // + BEGIN_OPF(ANDI, 0x0C, 0); + ITYPE_ZE; + uint32 result = GPR[rs] & immediate; + + DO_LDS(); + + GPR[rt] = result; + + END_OPF; + + // + // BEQ - Branch on Equal + // + BEGIN_OPF(BEQ, 0x04, 0); + ITYPE; + bool result = (GPR[rs] == GPR[rt]); + + DO_LDS(); + + if(result) + { + DO_BRANCH((immediate << 2), ~0U); + } + END_OPF; + + // Bah, why does MIPS encoding have to be funky like this. :( + // Handles BGEZ, BGEZAL, BLTZ, BLTZAL + BEGIN_OPF(BCOND, 0x01, 0); + const uint32 tv = GPR[(instr >> 21) & 0x1F]; + uint32 riv = (instr >> 16) & 0x1F; + int32 immediate = (int16)(instr & 0xFFFF); + bool result = (int32)(tv ^ (riv << 31)) < 0; + //if(riv & ~(0x11)) + //PSX_WARNING("[CPU] Unknown instruction %08x, op=%02x, funct=%02x", instr, instr >> 26, (instr & 0x3F)) + + DO_LDS(); + + if(riv & 0x10) // Unconditional link reg setting. + GPR[31] = PC + 8; + + if(result) + { + DO_BRANCH((immediate << 2), ~0U); + } + + END_OPF; + + + // + // BGTZ - Branch on Greater than Zero + // + BEGIN_OPF(BGTZ, 0x07, 0); + ITYPE; + bool result = (int32)GPR[rs] > 0; + + DO_LDS(); + + if(result) + { + DO_BRANCH((immediate << 2), ~0U); + } + END_OPF; + + // + // BLEZ - Branch on Less Than or Equal to Zero + // + BEGIN_OPF(BLEZ, 0x06, 0); + ITYPE; + bool result = (int32)GPR[rs] <= 0; + + DO_LDS(); + + if(result) + { + DO_BRANCH((immediate << 2), ~0U); + } + + END_OPF; + + // + // BNE - Branch on Not Equal + // + BEGIN_OPF(BNE, 0x05, 0); + ITYPE; + bool result = GPR[rs] != GPR[rt]; + + DO_LDS(); + + if(result) + { + DO_BRANCH((immediate << 2), ~0U); + } + + END_OPF; + + // + // BREAK - Breakpoint + // + BEGIN_OPF(BREAK, 0, 0x0D); + PSX_WARNING("[CPU] BREAK BREAK BREAK BREAK DAAANCE -- PC=0x%08x", PC); + + DO_LDS(); + new_PC = Exception(EXCEPTION_BP, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // Cop "instructions": CFCz(no CP0), COPz, CTCz(no CP0), LWCz(no CP0), MFCz, MTCz, SWCz(no CP0) + // + // COP0 instructions + BEGIN_OPF(COP0, 0x10, 0); + uint32 sub_op = (instr >> 21) & 0x1F; + + if(sub_op & 0x10) + sub_op = 0x10 + (instr & 0x3F); + + //printf("COP0 thing: %02x\n", sub_op); + switch(sub_op) + { + default: + DO_LDS(); + break; + + case 0x00: // MFC0 - Move from Coprocessor + { + uint32 rt = (instr >> 16) & 0x1F; + uint32 rd = (instr >> 11) & 0x1F; + + //printf("MFC0: rt=%d <- rd=%d(%08x)\n", rt, rd, CP0.Regs[rd]); + DO_LDS(); + + LDWhich = rt; + LDValue = CP0.Regs[rd]; + } + break; + + case 0x04: // MTC0 - Move to Coprocessor + { + uint32 rt = (instr >> 16) & 0x1F; + uint32 rd = (instr >> 11) & 0x1F; + uint32 val = GPR[rt]; + + if(rd != CP0REG_CAUSE && rd != CP0REG_SR && val) + { + PSX_WARNING("[CPU] Unimplemented MTC0: rt=%d(%08x) -> rd=%d", rt, GPR[rt], rd); + } + + switch(rd) + { + case CP0REG_BPC: + CP0.BPC = val; + break; + + case CP0REG_BDA: + CP0.BDA = val; + break; + + case CP0REG_TAR: + CP0.TAR = val; + break; + + case CP0REG_DCIC: + CP0.DCIC = val & 0xFF80003F; + break; + + case CP0REG_BDAM: + CP0.BDAM = val; + break; + + case CP0REG_BPCM: + CP0.BPCM = val; + break; + + case CP0REG_CAUSE: + CP0.CAUSE &= ~(0x3 << 8); + CP0.CAUSE |= val & (0x3 << 8); + RecalcIPCache(); + break; + + case CP0REG_SR: + CP0.SR = val & ~( (0x3 << 26) | (0x3 << 23) | (0x3 << 6)); + RecalcIPCache(); + + if(CP0.SR & 0x10000) + PSX_WARNING("[CPU] IsC set"); + break; + } + } + DO_LDS(); + break; + + case (0x10 + 0x10): // RFE + // "Pop" + DO_LDS(); + CP0.SR = (CP0.SR & ~0x0F) | ((CP0.SR >> 2) & 0x0F); + RecalcIPCache(); + break; + } + END_OPF; + + // + // COP1 + // + BEGIN_OPF(COP1, 0x11, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // COP2 + // + BEGIN_OPF(COP2, 0x12, 0); + uint32 sub_op = (instr >> 21) & 0x1F; + + switch(sub_op) + { + default: + DO_LDS(); + break; + + case 0x00: // MFC2 - Move from Coprocessor + { + uint32 rt = (instr >> 16) & 0x1F; + uint32 rd = (instr >> 11) & 0x1F; + + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + + DO_LDS(); + + LDWhich = rt; + LDValue = GTE_ReadDR(rd); + } + break; + + case 0x04: // MTC2 - Move to Coprocessor + { + uint32 rt = (instr >> 16) & 0x1F; + uint32 rd = (instr >> 11) & 0x1F; + uint32 val = GPR[rt]; + + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + + //printf("GTE WriteDR: %d %d\n", rd, val); + GTE_WriteDR(rd, val); + DO_LDS(); + } + break; + + case 0x02: // CFC2 + { + uint32 rt = (instr >> 16) & 0x1F; + uint32 rd = (instr >> 11) & 0x1F; + + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + + DO_LDS(); + + LDWhich = rt; + LDValue = GTE_ReadCR(rd); + //printf("GTE ReadCR: %d %d\n", rd, GPR[rt]); + } + break; + + case 0x06: // CTC2 + { + uint32 rt = (instr >> 16) & 0x1F; + uint32 rd = (instr >> 11) & 0x1F; + uint32 val = GPR[rt]; + + //printf("GTE WriteCR: %d %d\n", rd, val); + + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + + GTE_WriteCR(rd, val); + DO_LDS(); + } + break; + + case 0x10 ... 0x1F: + //printf("%08x\n", PC); + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + gte_ts_done = timestamp + GTE_Instruction(instr); + DO_LDS(); + break; + } + END_OPF; + + // + // COP3 + // + BEGIN_OPF(COP3, 0x13, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // LWC0 + // + BEGIN_OPF(LWC0, 0x30, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // LWC1 + // + BEGIN_OPF(LWC1, 0x31, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // LWC2 + // + BEGIN_OPF(LWC2, 0x32, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + if(address & 3) + { + new_PC = Exception(EXCEPTION_ADEL, PC, new_PC_mask); + new_PC_mask = 0; + } + else + { + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + + GTE_WriteDR(rt, PSX_MemRead32(timestamp, address)); + } + DO_LDS(); + // GTE stuff here + END_OPF; + + // + // LWC3 + // + BEGIN_OPF(LWC3, 0x33, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + + // + // SWC0 + // + BEGIN_OPF(SWC0, 0x38, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // SWC1 + // + BEGIN_OPF(SWC1, 0x39, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_COPU, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + // + // SWC2 + // + BEGIN_OPF(SWC2, 0x3A, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + if(address & 0x3) + { + new_PC = Exception(EXCEPTION_ADES, PC, new_PC_mask); + new_PC_mask = 0; + } + else if(!(CP0.SR & 0x10000)) + { + if(timestamp < gte_ts_done) + timestamp = gte_ts_done; + + PSX_MemWrite32(timestamp, address, GTE_ReadDR(rt)); + } + DO_LDS(); + END_OPF; + + // + // SWC3 + /// + BEGIN_OPF(SWC3, 0x3B, 0); + DO_LDS(); + new_PC = Exception(EXCEPTION_RI, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + + // + // DIV - Divide Word + // + BEGIN_OPF(DIV, 0, 0x1A); + RTYPE; + + if(!GPR[rt]) + { + //PSX_WARNING("[CPU] Division(signed) by zero at PC=%08x", PC); + + if(GPR[rs] & 0x80000000) + LO = 1; + else + LO = 0xFFFFFFFF; + + HI = GPR[rs]; + } + else if(GPR[rs] == 0x80000000 && GPR[rt] == 0xFFFFFFFF) + { + LO = 0x80000000; + HI = 0; + } + else + { + LO = (int32)GPR[rs] / (int32)GPR[rt]; + HI = (int32)GPR[rs] % (int32)GPR[rt]; + } + + DO_LDS(); + + END_OPF; + + + // + // DIVU - Divide Unsigned Word + // + BEGIN_OPF(DIVU, 0, 0x1B); + RTYPE; + + if(!GPR[rt]) + { + //PSX_WARNING("[CPU] Division(unsigned) by zero at PC=%08x", PC); + + LO = 0xFFFFFFFF; + HI = GPR[rs]; + } + else + { + LO = GPR[rs] / GPR[rt]; + HI = GPR[rs] % GPR[rt]; + } + + DO_LDS(); + END_OPF; + + // + // J - Jump + // + BEGIN_OPF(J, 0x02, 0); + JTYPE; + + DO_LDS(); + + DO_BRANCH(target << 2, 0xF0000000); + END_OPF; + + // + // JAL - Jump and Link + // + BEGIN_OPF(JAL, 0x03, 0); + JTYPE; + + DO_LDS(); + + GPR[31] = PC + 8; + + DO_BRANCH(target << 2, 0xF0000000); + END_OPF; + + // + // JALR - Jump and Link Register + // + BEGIN_OPF(JALR, 0, 0x09); + RTYPE; + uint32 tmp = GPR[rs]; + + DO_LDS(); + + GPR[rd] = PC + 8; + + DO_BRANCH(tmp, 0); + + END_OPF; + + // + // JR - Jump Register + // + BEGIN_OPF(JR, 0, 0x08); + RTYPE; + uint32 bt = GPR[rs]; + + DO_LDS(); + + DO_BRANCH(bt, 0); + + END_OPF; + + // + // LUI - Load Upper Immediate + // + BEGIN_OPF(LUI, 0x0F, 0); + ITYPE_ZE; // Actually, probably would be sign-extending...if we were emulating a 64-bit MIPS chip :b + + DO_LDS(); + + GPR[rt] = immediate << 16; + + END_OPF; + + // + // MFHI - Move from HI + // + BEGIN_OPF(MFHI, 0, 0x10); + RTYPE; + + DO_LDS(); + + GPR[rd] = HI; + + END_OPF; + + + // + // MFLO - Move from LO + // + BEGIN_OPF(MFLO, 0, 0x12); + RTYPE; + + DO_LDS(); + + GPR[rd] = LO; + + END_OPF; + + + // + // MTHI - Move to HI + // + BEGIN_OPF(MTHI, 0, 0x11); + RTYPE; + + HI = GPR[rs]; + + DO_LDS(); + + END_OPF; + + // + // MTLO - Move to LO + // + BEGIN_OPF(MTLO, 0, 0x13); + RTYPE; + + LO = GPR[rs]; + + DO_LDS(); + + END_OPF; + + + // + // MULT - Multiply Word + // + BEGIN_OPF(MULT, 0, 0x18); + RTYPE; + uint64 result; + + result = (int64)(int32)GPR[rs] * (int32)GPR[rt]; + + DO_LDS(); + + LO = result; + HI = result >> 32; + + END_OPF; + + // + // MULTU - Multiply Unsigned Word + // + BEGIN_OPF(MULTU, 0, 0x19); + RTYPE; + uint64 result; + + result = (uint64)GPR[rs] * GPR[rt]; + + DO_LDS(); + + LO = result; + HI = result >> 32; + + END_OPF; + + + // + // NOR - NOR + // + BEGIN_OPF(NOR, 0, 0x27); + RTYPE; + uint32 result = ~(GPR[rs] | GPR[rt]); + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + // + // OR - OR + // + BEGIN_OPF(OR, 0, 0x25); + RTYPE; + uint32 result = GPR[rs] | GPR[rt]; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // ORI - OR Immediate + // + BEGIN_OPF(ORI, 0x0D, 0); + ITYPE_ZE; + uint32 result = GPR[rs] | immediate; + + DO_LDS(); + + GPR[rt] = result; + + END_OPF; + + + // + // SLL - Shift Word Left Logical + // + BEGIN_OPF(SLL, 0, 0x00); // SLL + RTYPE; + uint32 result = GPR[rt] << shamt; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SLLV - Shift Word Left Logical Variable + // + BEGIN_OPF(SLLV, 0, 0x04); + RTYPE; + uint32 result = GPR[rt] << (GPR[rs] & 0x1F); + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + // + // SLT - Set on Less Than + // + BEGIN_OPF(SLT, 0, 0x2A); + RTYPE; + uint32 result = (bool)((int32)GPR[rs] < (int32)GPR[rt]); + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SLTI - Set on Less Than Immediate + // + BEGIN_OPF(SLTI, 0x0A, 0); + ITYPE; + uint32 result = (bool)((int32)GPR[rs] < immediate); + + DO_LDS(); + + GPR[rt] = result; + + END_OPF; + + + // + // SLTIU - Set on Less Than Immediate, Unsigned + // + BEGIN_OPF(SLTIU, 0x0B, 0); + ITYPE; + uint32 result = (bool)(GPR[rs] < (uint32)immediate); + + DO_LDS(); + + GPR[rt] = result; + + END_OPF; + + + // + // SLTU - Set on Less Than, Unsigned + // + BEGIN_OPF(SLTU, 0, 0x2B); + RTYPE; + uint32 result = (bool)(GPR[rs] < GPR[rt]); + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SRA - Shift Word Right Arithmetic + // + BEGIN_OPF(SRA, 0, 0x03); + RTYPE; + uint32 result = ((int32)GPR[rt]) >> shamt; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SRAV - Shift Word Right Arithmetic Variable + // + BEGIN_OPF(SRAV, 0, 0x07); + RTYPE; + uint32 result = ((int32)GPR[rt]) >> (GPR[rs] & 0x1F); + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SRL - Shift Word Right Logical + // + BEGIN_OPF(SRL, 0, 0x02); + RTYPE; + uint32 result = GPR[rt] >> shamt; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + // + // SRLV - Shift Word Right Logical Variable + // + BEGIN_OPF(SRLV, 0, 0x06); + RTYPE; + uint32 result = GPR[rt] >> (GPR[rs] & 0x1F); + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SUB - Subtract Word + // + BEGIN_OPF(SUB, 0, 0x22); + RTYPE; + uint32 result = GPR[rs] - GPR[rt]; + bool ep = (((GPR[rs] ^ GPR[rt])) & (GPR[rs] ^ result)) & 0x80000000; + + DO_LDS(); + + if(ep) + { + new_PC = Exception(EXCEPTION_OV, PC, new_PC_mask); + new_PC_mask = 0; + } + else + GPR[rd] = result; + + END_OPF; + + + // + // SUBU - Subtract Unsigned Word + // + BEGIN_OPF(SUBU, 0, 0x23); // SUBU + RTYPE; + uint32 result = GPR[rs] - GPR[rt]; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + + // + // SYSCALL + // + BEGIN_OPF(SYSCALL, 0, 0x0C); + DO_LDS(); + + new_PC = Exception(EXCEPTION_SYSCALL, PC, new_PC_mask); + new_PC_mask = 0; + END_OPF; + + + // + // XOR + // + BEGIN_OPF(XOR, 0, 0x26); + RTYPE; + uint32 result = GPR[rs] ^ GPR[rt]; + + DO_LDS(); + + GPR[rd] = result; + + END_OPF; + + // + // XORI - Exclusive OR Immediate + // + BEGIN_OPF(XORI, 0x0E, 0); + ITYPE_ZE; + uint32 result = GPR[rs] ^ immediate; + + DO_LDS(); + + GPR[rt] = result; + END_OPF; + + // + // Memory access instructions(besides the coprocessor ones) follow: + // + + // + // LB - Load Byte + // + BEGIN_OPF(LB, 0x20, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + DO_LDS(); + + LDWhich = rt; + LDValue = (int32)ReadMemory(timestamp, address); + END_OPF; + + // + // LBU - Load Byte Unsigned + // + BEGIN_OPF(LBU, 0x24, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + DO_LDS(); + + LDWhich = rt; + LDValue = ReadMemory(timestamp, address); + END_OPF; + + // + // LH - Load Halfword + // + BEGIN_OPF(LH, 0x21, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + DO_LDS(); + + if(address & 1) + { + new_PC = Exception(EXCEPTION_ADEL, PC, new_PC_mask); + new_PC_mask = 0; + } + else + { + LDWhich = rt; + LDValue = (int32)ReadMemory(timestamp, address); + } + END_OPF; + + // + // LHU - Load Halfword Unsigned + // + BEGIN_OPF(LHU, 0x25, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + DO_LDS(); + + if(address & 1) + { + new_PC = Exception(EXCEPTION_ADEL, PC, new_PC_mask); + new_PC_mask = 0; + } + else + { + LDWhich = rt; + LDValue = ReadMemory(timestamp, address); + } + END_OPF; + + + // + // LW - Load Word + // + BEGIN_OPF(LW, 0x23, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + DO_LDS(); + + if(address & 3) + { + new_PC = Exception(EXCEPTION_ADEL, PC, new_PC_mask); + new_PC_mask = 0; + } + else + { + LDWhich = rt; + LDValue = ReadMemory(timestamp, address); + } + END_OPF; + + // + // SB - Store Byte + // + BEGIN_OPF(SB, 0x28, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + WriteMemory(timestamp, address, GPR[rt]); + + DO_LDS(); + END_OPF; + + // + // SH - Store Halfword + // + BEGIN_OPF(SH, 0x29, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + if(address & 0x1) + { + new_PC = Exception(EXCEPTION_ADES, PC, new_PC_mask); + new_PC_mask = 0; + } + else + WriteMemory(timestamp, address, GPR[rt]); + + DO_LDS(); + END_OPF; + + // + // SW - Store Word + // + BEGIN_OPF(SW, 0x2B, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + if(address & 0x3) + { + new_PC = Exception(EXCEPTION_ADES, PC, new_PC_mask); + new_PC_mask = 0; + } + else + WriteMemory(timestamp, address, GPR[rt]); + + DO_LDS(); + END_OPF; + + // LWL and LWR load delay slot tomfoolery appears to apply even to MFC0! (and probably MFCn and CFCn as well, though they weren't explicitly tested) + + // + // LWL - Load Word Left + // + BEGIN_OPF(LWL, 0x22, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + uint32 v = GPR[rt]; + + if(LDWhich == rt) + { + v = LDValue; + } + else + { + DO_LDS(); + } + + LDWhich = rt; + switch(address & 0x3) + { + case 0: LDValue = (v & ~(0xFF << 24)) | (ReadMemory(timestamp, address & ~3) << 24); + break; + + case 1: LDValue = (v & ~(0xFFFF << 16)) | (ReadMemory(timestamp, address & ~3) << 16); + break; + + case 2: LDValue = (v & ~(0xFFFFFF << 8)) | (ReadMemory(timestamp, address & ~3, true) << 8); + break; + + case 3: LDValue = (v & ~(0xFFFFFFFF << 0)) | (ReadMemory(timestamp, address & ~3) << 0); + break; + } + END_OPF; + + // + // SWL - Store Word Left + // + BEGIN_OPF(SWL, 0x2A, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + switch(address & 0x3) + { + case 0: WriteMemory(timestamp, address & ~3, GPR[rt] >> 24); + break; + + case 1: WriteMemory(timestamp, address & ~3, GPR[rt] >> 16); + break; + + case 2: WriteMemory(timestamp, address & ~3, GPR[rt] >> 8, true); + break; + + case 3: WriteMemory(timestamp, address & ~3, GPR[rt] >> 0); + break; + } + DO_LDS(); + + END_OPF; + + // + // LWR - Load Word Right + // + BEGIN_OPF(LWR, 0x26, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + uint32 v = GPR[rt]; + + if(LDWhich == rt) + { + v = LDValue; + } + else + { + DO_LDS(); + } + + LDWhich = rt; + switch(address & 0x3) + { + case 0: LDValue = (v & ~(0xFFFFFFFF)) | ReadMemory(timestamp, address); + break; + + case 1: LDValue = (v & ~(0xFFFFFF)) | ReadMemory(timestamp, address, true); + break; + + case 2: LDValue = (v & ~(0xFFFF)) | ReadMemory(timestamp, address); + break; + + case 3: LDValue = (v & ~(0xFF)) | ReadMemory(timestamp, address); + break; + } + END_OPF; + + // + // SWR - Store Word Right + // + BEGIN_OPF(SWR, 0x2E, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + switch(address & 0x3) + { + case 0: WriteMemory(timestamp, address, GPR[rt]); + break; + + case 1: WriteMemory(timestamp, address, GPR[rt], true); + break; + + case 2: WriteMemory(timestamp, address, GPR[rt]); + break; + + case 3: WriteMemory(timestamp, address, GPR[rt]); + break; + } + + DO_LDS(); + + END_OPF; + + // + // Mednafen special instruction + // + BEGIN_OPF(INTERRUPT, 0x3F, 0); + if(Halted) + { + goto SkipNPCStuff; + } + else + { + DO_LDS(); + + new_PC = Exception(EXCEPTION_INT, PC, new_PC_mask); + new_PC_mask = 0; + } + END_OPF; + } + + OpDone: ; + + PC = (PC & new_PC_mask) + new_PC; + new_PC_mask = ~0U; + new_PC = 4; + + SkipNPCStuff: ; + + //printf("\n"); + } + } while(PSX_EventHandler(timestamp)); + + if(gte_ts_done > 0) + gte_ts_done -= timestamp; + + ACTIVE_TO_BACKING; + + return(timestamp); +} + +pscpu_timestamp_t PS_CPU::Run(pscpu_timestamp_t timestamp_in, bool ILHMode) +{ + if(CPUHook || ADDBT) + return(RunReal(timestamp_in)); + else + { + if(ILHMode) + return(RunReal(timestamp_in)); + else + return(RunReal(timestamp_in)); + } +} + +void PS_CPU::SetCPUHook(void (*cpuh)(uint32 pc), void (*addbt)(uint32 from, uint32 to, bool exception)) +{ + ADDBT = addbt; + CPUHook = cpuh; +} + +uint32 PS_CPU::GetRegister(unsigned int which, char *special, const uint32 special_len) +{ + uint32 ret = 0; + + if(which >= GSREG_GPR && which < (GSREG_GPR + 32)) + ret = GPR[which]; + else switch(which) + { + case GSREG_PC: + ret = BACKED_PC; + break; + + case GSREG_PC_NEXT: + ret = BACKED_new_PC; + break; + + case GSREG_IN_BD_SLOT: + ret = !(BACKED_new_PC_mask & 3); + break; + + case GSREG_LO: + ret = LO; + break; + + case GSREG_HI: + ret = HI; + break; + + case GSREG_SR: + ret = CP0.SR; + break; + + case GSREG_CAUSE: + ret = CP0.CAUSE; + break; + + case GSREG_EPC: + ret = CP0.EPC; + break; + + } + + return(ret); +} + +void PS_CPU::SetRegister(unsigned int which, uint32 value) +{ + if(which >= GSREG_GPR && which < (GSREG_GPR + 32)) + { + if(which != (GSREG_GPR + 0)) + GPR[which] = value; + } + else switch(which) + { + case GSREG_PC: + BACKED_PC = value & ~0x3; // Remove masking if we ever add proper misaligned PC exception + break; + + case GSREG_LO: + LO = value; + break; + + case GSREG_HI: + HI = value; + break; + + case GSREG_SR: + CP0.SR = value; // TODO: mask + break; + + case GSREG_CAUSE: + CP0.CAUSE = value; + break; + + case GSREG_EPC: + CP0.EPC = value & ~0x3U; + break; + + + } +} + +#undef BEGIN_OPF +#undef END_OPF +#undef MK_OPF + +#define MK_OPF(op, funct) ((op) ? (0x40 | (op)) : (funct)) +#define BEGIN_OPF(op, funct) case MK_OPF(op, funct): { +#define END_OPF } break; + +// FIXME: should we breakpoint on an illegal address? And with LWC2/SWC2 if CP2 isn't enabled? +void PS_CPU::CheckBreakpoints(void (*callback)(bool write, uint32 address, unsigned int len), uint32 instr) +{ + uint32 opf; + + opf = instr & 0x3F; + + if(instr & (0x3F << 26)) + opf = 0x40 | (instr >> 26); + + + switch(opf) + { + default: + break; + + // + // LB - Load Byte + // + BEGIN_OPF(0x20, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(false, address, 1); + END_OPF; + + // + // LBU - Load Byte Unsigned + // + BEGIN_OPF(0x24, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(false, address, 1); + END_OPF; + + // + // LH - Load Halfword + // + BEGIN_OPF(0x21, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(false, address, 2); + END_OPF; + + // + // LHU - Load Halfword Unsigned + // + BEGIN_OPF(0x25, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(false, address, 2); + END_OPF; + + + // + // LW - Load Word + // + BEGIN_OPF(0x23, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(false, address, 4); + END_OPF; + + // + // SB - Store Byte + // + BEGIN_OPF(0x28, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(true, address, 1); + END_OPF; + + // + // SH - Store Halfword + // + BEGIN_OPF(0x29, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(true, address, 2); + END_OPF; + + // + // SW - Store Word + // + BEGIN_OPF(0x2B, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(true, address, 4); + END_OPF; + + // + // LWL - Load Word Left + // + BEGIN_OPF(0x22, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + do + { + callback(false, address, 1); + } while((address--) & 0x3); + + END_OPF; + + // + // SWL - Store Word Left + // + BEGIN_OPF(0x2A, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + do + { + callback(true, address, 1); + } while((address--) & 0x3); + + END_OPF; + + // + // LWR - Load Word Right + // + BEGIN_OPF(0x26, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + do + { + callback(false, address, 1); + } while((++address) & 0x3); + + END_OPF; + + // + // SWR - Store Word Right + // + BEGIN_OPF(0x2E, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + do + { + callback(true, address, 1); + } while((++address) & 0x3); + + END_OPF; + + // + // LWC2 + // + BEGIN_OPF(0x32, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(false, address, 4); + END_OPF; + + // + // SWC2 + // + BEGIN_OPF(0x3A, 0); + ITYPE; + uint32 address = GPR[rs] + immediate; + + callback(true, address, 4); + END_OPF; + + } +} + + +} diff --git a/mednafen/psx-0925/cpu.h b/mednafen/psx-0925/cpu.h new file mode 100644 index 00000000..ac3f0d02 --- /dev/null +++ b/mednafen/psx-0925/cpu.h @@ -0,0 +1,167 @@ +#ifndef __MDFN_PSX_CPU_H +#define __MDFN_PSX_CPU_H + +#include "gte.h" + +namespace MDFN_IEN_PSX +{ + +class PS_CPU +{ + public: + + PS_CPU(); + ~PS_CPU(); + + // FAST_MAP_* enums are in BYTES(8-bit), not in 32-bit units("words" in MIPS context), but the sizes + // will always be multiples of 4. + enum { FAST_MAP_SHIFT = 16 }; + enum { FAST_MAP_PSIZE = 1 << FAST_MAP_SHIFT }; + + void SetFastMap(void *region_mem, uint32 region_address, uint32 region_size); + + INLINE void SetEventNT(const pscpu_timestamp_t next_event_ts_arg) + { + next_event_ts = next_event_ts_arg; + } + + pscpu_timestamp_t Run(pscpu_timestamp_t timestamp_in, bool ILHMode); + + void Power(void); + + // which ranges 0-5, inclusive + void AssertIRQ(int which, bool asserted); + + void SetHalt(bool status); + + int StateAction(StateMem *sm, int load, int data_only); + + private: + + struct + { + uint32 GPR[32]; + uint32 GPR_dummy; // Used in load delay simulation(indexing past the end of GPR) + }; + uint32 LO; + uint32 HI; + + + uint32 BACKED_PC; + uint32 BACKED_new_PC; + uint32 BACKED_new_PC_mask; + + uint32 IPCache; + void RecalcIPCache(void); + bool Halted; + + uint32 BACKED_LDWhich; + uint32 BACKED_LDValue; + + pscpu_timestamp_t next_event_ts; + pscpu_timestamp_t gte_ts_done; + + uint8 *FastMap[1 << (32 - FAST_MAP_SHIFT)]; + uint8 DummyPage[FAST_MAP_PSIZE]; + + enum + { + CP0REG_BPC = 3, // PC breakpoint address. + CP0REG_BDA = 5, // Data load/store breakpoint address. + CP0REG_TAR = 6, // Target address(???) + CP0REG_DCIC = 7, // Cache control + CP0REG_BDAM = 9, // Data load/store address mask. + CP0REG_BPCM = 11, // PC breakpoint address mask. + CP0REG_SR = 12, + CP0REG_CAUSE = 13, + CP0REG_EPC = 14, + CP0REG_PRID = 15, // Product ID + CP0REG_ERREG = 16 + }; + + struct + { + union + { + uint32 Regs[32]; + struct + { + uint32 Unused00; + uint32 Unused01; + uint32 Unused02; + uint32 BPC; // RW + uint32 Unused04; + uint32 BDA; // RW + uint32 TAR; + uint32 DCIC; // RW + uint32 Unused08; + uint32 BDAM; // R/W + uint32 Unused0A; + uint32 BPCM; // R/W + uint32 SR; // R/W + uint32 CAUSE; // R/W(partial) + uint32 EPC; // R + uint32 PRID; // R + uint32 ERREG; // ?(may not exist, test) + }; + }; + } CP0; + + //PS_GTE GTE; + + enum + { + EXCEPTION_INT = 0, + EXCEPTION_MOD = 1, + EXCEPTION_TLBL = 2, + EXCEPTION_TLBS = 3, + EXCEPTION_ADEL = 4, // Address error on load + EXCEPTION_ADES = 5, // Address error on store + EXCEPTION_IBE = 6, // Instruction bus error + EXCEPTION_DBE = 7, // Data bus error + EXCEPTION_SYSCALL = 8, // System call + EXCEPTION_BP = 9, // Breakpoint + EXCEPTION_RI = 10, // Reserved instruction + EXCEPTION_COPU = 11, // Coprocessor unusable + EXCEPTION_OV = 12 // Arithmetic overflow + }; + + uint32 Exception(uint32 code, uint32 PC, const uint32 NPM) MDFN_WARN_UNUSED_RESULT; + + template pscpu_timestamp_t RunReal(pscpu_timestamp_t timestamp_in); + + template T ReadMemory(pscpu_timestamp_t ×tamp, uint32 address, bool DS24 = false); + template void WriteMemory(pscpu_timestamp_t ×tamp, uint32 address, uint32 value, bool DS24 = false); + + + // + // Mednafen debugger stuff follows: + // + public: + void SetCPUHook(void (*cpuh)(uint32 pc), void (*addbt)(uint32 from, uint32 to, bool exception)); + void CheckBreakpoints(void (*callback)(bool write, uint32 address, unsigned int len), uint32 instr); + + enum + { + GSREG_GPR = 0, + GSREG_PC = 32, + GSREG_PC_NEXT, + GSREG_IN_BD_SLOT, + GSREG_LO, + GSREG_HI, + GSREG_SR, + GSREG_CAUSE, + GSREG_EPC, + }; + + uint32 GetRegister(unsigned int which, char *special, const uint32 special_len); + void SetRegister(unsigned int which, uint32 value); + + private: + void (*CPUHook)(uint32 pc); + void (*ADDBT)(uint32 from, uint32 to, bool exception); +}; + +} + +#endif diff --git a/mednafen/psx-0925/debug.cpp b/mednafen/psx-0925/debug.cpp new file mode 100644 index 00000000..5d5fb9e4 --- /dev/null +++ b/mednafen/psx-0925/debug.cpp @@ -0,0 +1,669 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "timer.h" +#include "cdc.h" +#include "spu.h" + +namespace MDFN_IEN_PSX +{ + +extern PS_GPU *GPU; +extern PS_SPU *SPU; + +static void (*CPUHook)(uint32) = NULL; +static void (*BPCallB)(uint32 PC) = NULL; + +struct PSX_BPOINT +{ + uint32 A[2]; + int type; +}; + +static std::vector BreakPointsPC, BreakPointsRead, BreakPointsWrite; +static bool FoundBPoint; + +static int BTIndex = 0; + +struct BTEntry +{ + uint32 from; + uint32 to; + uint32 branch_count; + bool exception; +}; + +#define NUMBT 24 +static BTEntry BTEntries[NUMBT]; + +void DBG_Break(void) +{ + FoundBPoint = true; +} + +static void AddBranchTrace(uint32 from, uint32 to, bool exception) +{ + BTEntry *prevbt = &BTEntries[(BTIndex + NUMBT - 1) % NUMBT]; + + //if(BTEntries[(BTIndex - 1) & 0xF] == PC) return; + + if(prevbt->from == from && prevbt->to == to && prevbt->exception == exception && prevbt->branch_count < 0xFFFFFFFF) + prevbt->branch_count++; + else + { + BTEntries[BTIndex].from = from; + BTEntries[BTIndex].to = to; + BTEntries[BTIndex].exception = exception; + BTEntries[BTIndex].branch_count = 1; + + BTIndex = (BTIndex + 1) % NUMBT; + } +} + +static std::vector GetBranchTrace(void) +{ + BranchTraceResult tmp; + std::vector ret; + + for(int x = 0; x < NUMBT; x++) + { + const BTEntry *bt = &BTEntries[(x + BTIndex) % NUMBT]; + + tmp.count = bt->branch_count; + trio_snprintf(tmp.from, sizeof(tmp.from), "%08x", bt->from); + trio_snprintf(tmp.to, sizeof(tmp.to), "%08x", bt->to); + trio_snprintf(tmp.code, sizeof(tmp.code), "%s", bt->exception ? "e" : ""); + + ret.push_back(tmp); + } + return(ret); +} + +void CheckCPUBPCallB(bool write, uint32 address, unsigned int len) +{ + std::vector::iterator bpit; + std::vector::iterator bpit_end; + + if(write) + { + bpit = BreakPointsWrite.begin(); + bpit_end = BreakPointsWrite.end(); + } + else + { + bpit = BreakPointsRead.begin(); + bpit_end = BreakPointsRead.end(); + } + + while(bpit != bpit_end) + { + if(address >= bpit->A[0] && address <= bpit->A[1]) + { + FoundBPoint = true; + break; + } + bpit++; + } +} + +static void CPUHandler(uint32 PC) +{ + std::vector::iterator bpit; + + if(PC == 0xB0 && CPU->GetRegister(PS_CPU::GSREG_GPR + 9, NULL, 0) == 0x3D) + { + putchar(CPU->GetRegister(PS_CPU::GSREG_GPR + 4, NULL, 0)); + //exit(1); + //puts((const char *)&MainRAM[CPU->GetRegister(PS_CPU::GSREG_GPR + 4, NULL, 0) & 0x1FFFFF]); + } + + + // FIXME/TODO: Call ForceEventUpdates() somewhere + + for(bpit = BreakPointsPC.begin(); bpit != BreakPointsPC.end(); bpit++) + { + if(PC >= bpit->A[0] && PC <= bpit->A[1]) + { + FoundBPoint = true; + break; + } + } + + CPU->CheckBreakpoints(CheckCPUBPCallB, PSX_MemPeek32(PC)); + + if(FoundBPoint) + { + BPCallB(PC); + FoundBPoint = 0; + } + + if(CPUHook) + CPUHook(PC); +} + + +static void RedoCPUHook(void) +{ + const bool HappyTest = BreakPointsPC.size() || BreakPointsRead.size() || BreakPointsWrite.size(); + void (*cpuh)(uint32); + + cpuh = HappyTest ? CPUHandler : CPUHook; + + CPU->SetCPUHook(cpuh, cpuh ? AddBranchTrace : NULL); +} + +static void FlushBreakPoints(int type) +{ + if(type == BPOINT_READ) + BreakPointsRead.clear(); + else if(type == BPOINT_WRITE) + BreakPointsWrite.clear(); + else if(type == BPOINT_PC) + BreakPointsPC.clear(); + + RedoCPUHook(); +} + +static void AddBreakPoint(int type, unsigned int A1, unsigned int A2, bool logical) +{ + PSX_BPOINT tmp; + + tmp.A[0] = A1; + tmp.A[1] = A2; + tmp.type = type; + + if(type == BPOINT_READ) + BreakPointsRead.push_back(tmp); + else if(type == BPOINT_WRITE) + BreakPointsWrite.push_back(tmp); + else if(type == BPOINT_PC) + BreakPointsPC.push_back(tmp); + + RedoCPUHook(); +} + +static void SetCPUCallback(void (*callb)(uint32 PC)) +{ + CPUHook = callb; + RedoCPUHook(); +} + +static void SetBPCallback(void (*callb)(uint32 PC)) +{ + BPCallB = callb; +} + + +static void GetAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint8 *Buffer) +{ + if(!strcmp(name, "cpu")) + { + while(Length--) + { + Address &= 0xFFFFFFFF; + *Buffer = PSX_MemPeek8(Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "ram")) + { + while(Length--) + { + Address &= 0x1FFFFF; + *Buffer = PSX_MemPeek8(Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "spu")) + { + while(Length--) + { + Address &= 0x7FFFF; + *Buffer = SPU->PeekSPURAM(Address >> 1) >> ((Address & 1) * 8); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "gpu")) + { + while(Length--) + { + Address &= 0xFFFFF; + *Buffer = GPU->PeekRAM(Address >> 1) >> ((Address & 1) * 8); + Address++; + Buffer++; + } + } +} + + +static void PutAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer) +{ + if(!strcmp(name, "cpu")) + { + while(Length--) + { + Address &= 0xFFFFFFFF; + + // TODO + PSX_MemWrite8(0, Address, *Buffer); + + Address++; + Buffer++; + } + } + else if(!strcmp(name, "gpu")) + { + while(Length--) + { + Address &= 0xFFFFF; + + uint16 peeko = GPU->PeekRAM(Address >> 1); + + GPU->PokeRAM(Address >> 1, (*Buffer << ((Address & 1) * 8)) | (peeko & (0xFF00 >> ((Address & 1) * 8))) ); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "spu")) + { + while(Length--) + { + Address &= 0x7FFFF; + + uint16 peeko = SPU->PeekSPURAM(Address >> 1); + + SPU->PokeSPURAM(Address >> 1, (*Buffer << ((Address & 1) * 8)) | (peeko & (0xFF00 >> ((Address & 1) * 8))) ); + Address++; + Buffer++; + } + } + +} + +static uint32 MemPeek(uint32 A, unsigned int bsize, bool hl, bool logical) +{ + uint32 ret = 0; + + for(unsigned int i = 0; i < bsize; i++) + ret |= PSX_MemPeek8(A + i) << (i * 8); + + return(ret); +} + +static void Disassemble(uint32 &A, uint32 SpecialA, char *TextBuf) +{ + assert(!(A & 0x3)); + + const uint32 instr = PSX_MemPeek32(A); + + + strncpy(TextBuf, DisassembleMIPS(A, instr).c_str(), 256); + TextBuf[255] = 0; + +// trio_snprintf(TextBuf, 256, "0x%08x", instr); + + A += 4; +} + +static MDFN_Surface *GfxDecode_Buf = NULL; +static int GfxDecode_Line = -1; +static int GfxDecode_Layer = 0; +static int GfxDecode_Scroll = 0; +static int GfxDecode_PBN = 0; + +static void DoGfxDecode(void) +{ + unsigned tp_w, tp_h; + + tp_w = 256; + tp_h = 256; + + if(GfxDecode_Buf) + { + for(int sy = 0; sy < GfxDecode_Buf->h; sy++) + { + for(int sx = 0; sx < GfxDecode_Buf->w; sx++) + { + unsigned fb_x = ((sx % GfxDecode_Buf->w) + ((sy + GfxDecode_Scroll) / GfxDecode_Buf->w * GfxDecode_Buf->w)) & 1023; + unsigned fb_y = (((sy + GfxDecode_Scroll) % GfxDecode_Buf->w) + ((((sx % GfxDecode_Buf->w) + ((sy + GfxDecode_Scroll) / GfxDecode_Buf->w * GfxDecode_Buf->w)) / 1024) * 256)) & 511; + + uint16 pixel = GPU->PeekRAM(fb_y * 1024 + fb_x); + + GfxDecode_Buf->pixels[(sy * GfxDecode_Buf->w * 3) + sx] = GfxDecode_Buf->MakeColor(((pixel >> 0) & 0x1F) * 255 / 31, + ((pixel >> 5) & 0x1F) * 255 / 31, + ((pixel >> 10) & 0x1F) * 255 / 31, 0xFF); + } + } + } +} + + +void DBG_GPUScanlineHook(unsigned scanline) +{ + if((int)scanline == GfxDecode_Line) + { + DoGfxDecode(); + } +} + + +static void SetGraphicsDecode(MDFN_Surface *surface, int line, int which, int xscroll, int yscroll, int pbn) +{ + GfxDecode_Buf = surface; + GfxDecode_Line = line; + GfxDecode_Layer = which; + GfxDecode_Scroll = yscroll; + GfxDecode_PBN = pbn; + + if(GfxDecode_Buf && GfxDecode_Line == -1) + DoGfxDecode(); +} + +DebuggerInfoStruct PSX_DBGInfo = +{ + "shift_jis", + 4, // Max instruction byte size + 4, // Instruction alignment(bytes) + 32, // Logical address bits + 32, // Physical address bits + 0x00000000, // Default watch addr + ~0U, // ZP addr + + MemPeek, + Disassemble, + NULL, + NULL, //ForceIRQ, + NULL, //NESDBG_GetVector, + FlushBreakPoints, + AddBreakPoint, + SetCPUCallback, + SetBPCallback, + GetBranchTrace, + SetGraphicsDecode, + NULL, //PCFXDBG_SetLogFunc, +}; + +static RegType Regs_Misc[] = +{ + { TIMER_GSREG_COUNTER0, "COUNTER0", "Counter 0", 2 }, + { TIMER_GSREG_MODE0, "MODE0", "Mode 0", 2 }, + { TIMER_GSREG_TARGET0, "TARGET0", "Target 0", 2 }, + + { 0, "------", "", 0xFFFF }, + + + { TIMER_GSREG_COUNTER1, "COUNTER1", "Counter 1", 2 }, + { TIMER_GSREG_MODE1, "MODE1", "Mode 1", 2 }, + { TIMER_GSREG_TARGET1, "TARGET1", "Target 1", 2 }, + + { 0, "------", "", 0xFFFF }, + + { TIMER_GSREG_COUNTER2, "COUNTER2", "Counter 2", 2 }, + { TIMER_GSREG_MODE2, "MODE2", "Mode 2", 2 }, + { TIMER_GSREG_TARGET2, "TARGET2", "Target 2", 2 }, + + { 0, "------", "", 0xFFFF }, + { 0, "------", "", 0xFFFF }, + + { 0x10000 | IRQ_GSREG_ASSERTED, "ASSERTED", "IRQ Asserted", 2 }, + { 0x10000 | IRQ_GSREG_STATUS, "STATUS", "IRQ Status", 2 }, + { 0x10000 | IRQ_GSREG_MASK, "MASK", "IRQ Mask", 2 }, + + { 0, "", "", 0 } +}; + + +static uint32 GetRegister_Misc(const unsigned int id, char *special, const uint32 special_len) +{ + if(id & 0x10000) + return(IRQ_GetRegister(id & 0xFFFF, special, special_len)); + else + return(TIMER_GetRegister(id & 0xFFFF, special, special_len)); +} + +static void SetRegister_Misc(const unsigned int id, uint32 value) +{ + if(id & 0x10000) + IRQ_SetRegister(id & 0xFFFF, value); + else + TIMER_SetRegister(id & 0xFFFF, value); +} + +static RegGroupType MiscRegsGroup = +{ + NULL, + Regs_Misc, + GetRegister_Misc, + SetRegister_Misc +}; + +static RegType Regs_SPU[] = +{ + { PS_SPU::GSREG_SPUCONTROL, "SPUCTRL", "SPU Control", 2 }, + + { PS_SPU::GSREG_FM_ON, "FMOn", "FM Enable", 3 }, + { PS_SPU::GSREG_NOISE_ON, "NoiseOn", "Noise Enable", 3 }, + { PS_SPU::GSREG_REVERB_ON, "ReverbOn", "Reverb Enable", 3 }, + + { PS_SPU::GSREG_CDVOL_L, "CDVolL", "CD Volume Left", 2 }, + { PS_SPU::GSREG_CDVOL_R, "CDVolR", "CD Volume Right", 2 }, + + { PS_SPU::GSREG_DRYVOL_CTRL_L, "DryVolCL", "Dry Volume Control Left", 2 }, + { PS_SPU::GSREG_DRYVOL_CTRL_R, "DryVolCR", "Dry Volume Control Right", 2 }, + + { PS_SPU::GSREG_DRYVOL_L, "DryVolL", "Dry Volume Left", 2 }, + { PS_SPU::GSREG_DRYVOL_R, "DryVolR", "Dry Volume Right", 2 }, + + { PS_SPU::GSREG_WETVOL_L, "WetVolL", "Wet Volume Left", 2 }, + { PS_SPU::GSREG_WETVOL_R, "WetVolR", "Wet Volume Right", 2 }, + + { PS_SPU::GSREG_RWADDR, "RWAddr", "SPURAM Read/Write Address", 3 }, + + { PS_SPU::GSREG_IRQADDR, "IRQAddr", "IRQ Compare Address", 3 }, + + { PS_SPU::GSREG_REVERBWA, "ReverbWA", "Reverb Work Area(Raw)", 2 }, + + { PS_SPU::GSREG_VOICEON, "VoiceOn", "Voice On", 3 }, + { PS_SPU::GSREG_VOICEOFF, "VoiceOff", "Voice Off", 3 }, + { PS_SPU::GSREG_BLOCKEND, "BlockEnd", "Block End", 3 }, + + + { 0, "------", "", 0xFFFF }, + + { PS_SPU::GSREG_FB_SRC_A, "FB_SRC_A", "", 2 }, + { PS_SPU::GSREG_FB_SRC_B, "FB_SRC_B", "", 2 }, + { PS_SPU::GSREG_IIR_ALPHA, "IIR_ALPHA", "", 2 }, + { PS_SPU::GSREG_ACC_COEF_A, "ACC_COEF_A", "", 2 }, + { PS_SPU::GSREG_ACC_COEF_B, "ACC_COEF_B", "", 2 }, + { PS_SPU::GSREG_ACC_COEF_C, "ACC_COEF_C", "", 2 }, + { PS_SPU::GSREG_ACC_COEF_D, "ACC_COEF_D", "", 2 }, + { PS_SPU::GSREG_IIR_COEF, "IIR_COEF", "", 2 }, + { PS_SPU::GSREG_FB_ALPHA, "FB_ALPHA", "", 2 }, + { PS_SPU::GSREG_FB_X, "FB_X", "", 2 }, + { PS_SPU::GSREG_IIR_DEST_A0, "IIR_DEST_A0", "", 2 }, + { PS_SPU::GSREG_IIR_DEST_A1, "IIR_DEST_A1", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_A0, "ACC_SRC_A0", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_A1, "ACC_SRC_A1", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_B0, "ACC_SRC_B0", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_B1, "ACC_SRC_B1", "", 2 }, + { PS_SPU::GSREG_IIR_SRC_A0, "IIR_SRC_A0", "", 2 }, + { PS_SPU::GSREG_IIR_SRC_A1, "IIR_SRC_A1", "", 2 }, + { PS_SPU::GSREG_IIR_DEST_B0, "IIR_DEST_B0", "", 2 }, + { PS_SPU::GSREG_IIR_DEST_B1, "IIR_DEST_B1", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_C0, "ACC_SRC_C0", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_C1, "ACC_SRC_C1", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_D0, "ACC_SRC_D0", "", 2 }, + { PS_SPU::GSREG_ACC_SRC_D1, "ACC_SRC_D1", "", 2 }, + { PS_SPU::GSREG_IIR_SRC_B1, "IIR_SRC_B1", "", 2 }, + { PS_SPU::GSREG_IIR_SRC_B0, "IIR_SRC_B0", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_A0, "MIX_DEST_A0", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_A1, "MIX_DEST_A1", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_B0, "MIX_DEST_B0", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_B1, "MIX_DEST_B1", "", 2 }, + { PS_SPU::GSREG_IN_COEF_L, "IN_COEF_L", "", 2 }, + { PS_SPU::GSREG_IN_COEF_R, "IN_COEF_R", "", 2 }, + + { 0, "", "", 0 }, +}; + +#define VOICE_HELPER(v) \ + { 0, "--V"#v"--", "", 0xFFFF }, \ + { PS_SPU:: GSREG_V0_VOL_CTRL_L + v * 256, "VolCL", "Volume Control Left", 2 }, \ + { PS_SPU:: GSREG_V0_VOL_CTRL_R + v * 256, "VolCR", "Volume Control Right", 2 }, \ + { PS_SPU:: GSREG_V0_VOL_L + v * 256, "VolL", "Volume Left", 2 }, \ + { PS_SPU:: GSREG_V0_VOL_R + v * 256, "VolR", "Volume Right", 2 }, \ + { PS_SPU:: GSREG_V0_PITCH + v * 256, "Pitch", "Pitch", 2 }, \ + { PS_SPU:: GSREG_V0_STARTADDR + v * 256, "SAddr", "Start Address", 3 }, \ + { PS_SPU:: GSREG_V0_ADSR_CTRL + v * 256, "ADSRCTRL", "ADSR Control", 4 }, \ + { PS_SPU:: GSREG_V0_ADSR_LEVEL + v * 256, "ADSRLev", "ADSR Level", 2 }, \ + { PS_SPU:: GSREG_V0_LOOP_ADDR + v * 256, "LAddr", "Loop Address", 3 }, \ + { PS_SPU:: GSREG_V0_READ_ADDR + v * 256, "RAddr", "Read Address", 3 } + + +static RegType Regs_SPU_Voices[] = +{ +#if 1 + VOICE_HELPER(0), + VOICE_HELPER(1), + VOICE_HELPER(2), + VOICE_HELPER(3), +#else + VOICE_HELPER(20), + VOICE_HELPER(21), + VOICE_HELPER(22), + VOICE_HELPER(23), +#endif + { 0, "", "", 0 }, +}; + + +static uint32 GetRegister_SPU(const unsigned int id, char *special, const uint32 special_len) +{ + return(SPU->GetRegister(id, special, special_len)); +} + +static void SetRegister_SPU(const unsigned int id, uint32 value) +{ + SPU->SetRegister(id, value); +} + +static RegGroupType SPURegsGroup = +{ + NULL, + Regs_SPU, + GetRegister_SPU, + SetRegister_SPU +}; + + +static RegGroupType SPUVoicesRegsGroup = +{ + NULL, + Regs_SPU_Voices, + GetRegister_SPU, + SetRegister_SPU +}; + +static RegType Regs_CPU[] = +{ + { PS_CPU::GSREG_PC, "PC", "PC", 4 }, + { PS_CPU::GSREG_PC_NEXT, "NPC", "Next PC", 4 }, + { PS_CPU::GSREG_IN_BD_SLOT, "INBD", "In Branch Delay Slot", 1 }, + { 0, "------", "", 0xFFFF }, + { PS_CPU::GSREG_GPR + 1, "at", "Assembler Temporary", 4 }, + { PS_CPU::GSREG_GPR + 2, "v0", "Return Value 0", 4 }, + { PS_CPU::GSREG_GPR + 3, "v1", "Return Value 1", 4 }, + { PS_CPU::GSREG_GPR + 4, "a0", "Argument 0", 4 }, + { PS_CPU::GSREG_GPR + 5, "a1", "Argument 1", 4 }, + { PS_CPU::GSREG_GPR + 6, "a2", "Argument 2", 4 }, + { PS_CPU::GSREG_GPR + 7, "a3", "Argument 3", 4 }, + { PS_CPU::GSREG_GPR + 8, "t0", "Temporary 0", 4 }, + { PS_CPU::GSREG_GPR + 9, "t1", "Temporary 1", 4 }, + { PS_CPU::GSREG_GPR + 10, "t2", "Temporary 2", 4 }, + { PS_CPU::GSREG_GPR + 11, "t3", "Temporary 3", 4 }, + { PS_CPU::GSREG_GPR + 12, "t4", "Temporary 4", 4 }, + { PS_CPU::GSREG_GPR + 13, "t5", "Temporary 5", 4 }, + { PS_CPU::GSREG_GPR + 14, "t6", "Temporary 6", 4 }, + { PS_CPU::GSREG_GPR + 15, "t7", "Temporary 7", 4 }, + { PS_CPU::GSREG_GPR + 16, "s0", "Subroutine Reg Var 0", 4 }, + { PS_CPU::GSREG_GPR + 17, "s1", "Subroutine Reg Var 1", 4 }, + { PS_CPU::GSREG_GPR + 18, "s2", "Subroutine Reg Var 2", 4 }, + { PS_CPU::GSREG_GPR + 19, "s3", "Subroutine Reg Var 3", 4 }, + { PS_CPU::GSREG_GPR + 20, "s4", "Subroutine Reg Var 4", 4 }, + { PS_CPU::GSREG_GPR + 21, "s5", "Subroutine Reg Var 5", 4 }, + { PS_CPU::GSREG_GPR + 22, "s6", "Subroutine Reg Var 6", 4 }, + { PS_CPU::GSREG_GPR + 23, "s7", "Subroutine Reg Var 7", 4 }, + { PS_CPU::GSREG_GPR + 24, "t8", "Temporary 8", 4 }, + { PS_CPU::GSREG_GPR + 25, "t9", "Temporary 9", 4 }, + { PS_CPU::GSREG_GPR + 26, "k0", "Interrupt/Trap Handler Reg 0", 4 }, + { PS_CPU::GSREG_GPR + 27, "k1", "Interrupt/Trap Handler Reg 1", 4 }, + { PS_CPU::GSREG_GPR + 28, "gp", "Global Pointer", 4 }, + { PS_CPU::GSREG_GPR + 29, "sp", "Stack Pointer", 4 }, + { PS_CPU::GSREG_GPR + 30, "s8", "Subroutine Reg Var 8/Frame Pointer", 4 }, + { PS_CPU::GSREG_GPR + 31, "ra", "Return Address", 4 }, + { 0, "------", "", 0xFFFF }, + + { PS_CPU::GSREG_SR, "SR", "Status Register", 4 }, + { PS_CPU::GSREG_CAUSE, "CAU","Cause Register", 4 }, + { PS_CPU::GSREG_EPC, "EPC", "EPC Register", 4 }, + { 0, "", "", 0 } +}; + +static uint32 GetRegister_CPU(const unsigned int id, char *special, const uint32 special_len) +{ + return(CPU->GetRegister(id, special, special_len)); +} + +static void SetRegister_CPU(const unsigned int id, uint32 value) +{ + CPU->SetRegister(id, value); +} + +static RegGroupType CPURegsGroup = +{ + NULL, + Regs_CPU, + GetRegister_CPU, + SetRegister_CPU +}; + + +bool DBG_Init(void) +{ + CPUHook = NULL; + BPCallB = NULL; + FoundBPoint = false; + + MDFNDBG_AddRegGroup(&CPURegsGroup); + MDFNDBG_AddRegGroup(&MiscRegsGroup); + MDFNDBG_AddRegGroup(&SPURegsGroup); + MDFNDBG_AddRegGroup(&SPUVoicesRegsGroup); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "cpu", "CPU Physical", 32); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ram", "CPU Main Ram", 21); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "spu", "SPU RAM", 19); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "gpu", "GPU RAM", 20); + return(true); +} + + + +} + diff --git a/mednafen/psx-0925/debug.h b/mednafen/psx-0925/debug.h new file mode 100644 index 00000000..18035d66 --- /dev/null +++ b/mednafen/psx-0925/debug.h @@ -0,0 +1,21 @@ +#ifndef __MDFN_PSX_DEBUG_H +#define __MDFN_PSX_DEBUG_H + +#ifdef WANT_DEBUGGER + +namespace MDFN_IEN_PSX +{ + +extern DebuggerInfoStruct PSX_DBGInfo; + +bool DBG_Init(void); + +void DBG_Break(void); + +void DBG_GPUScanlineHook(unsigned scanline); + +} + +#endif + +#endif diff --git a/mednafen/psx-0925/dis.cpp b/mednafen/psx-0925/dis.cpp new file mode 100644 index 00000000..3da0a36f --- /dev/null +++ b/mednafen/psx-0925/dis.cpp @@ -0,0 +1,408 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" + +namespace MDFN_IEN_PSX +{ + +struct OpEntry +{ + uint32 mask; + uint32 value; + const char *mnemonic; + const char *format; +}; + +#define MASK_OP (0x3F << 26) +#define MASK_FUNC (0x3F) +#define MASK_RS (0x1F << 21) +#define MASK_RT (0x1F << 16) +#define MASK_RD (0x1F << 11) +#define MASK_SA (0x1F << 6) + +#define MK_OP(mnemonic, format, op, func, extra_mask) { MASK_OP | (op ? 0 : MASK_FUNC) | extra_mask, (op << 26) | func, mnemonic, format } + +#define MK_OP_REGIMM(mnemonic, regop) { MASK_OP | MASK_RT, (0x01 << 26) | (regop << 16), mnemonic, "s, p" } + + +#define MK_COPZ(z) { MASK_OP | (0x1 << 25), (0x1 << 25) | ((0x10 | z) << 26), "cop" #z, "F" } +#define MK_COP0_FUNC(mnemonic, func) { MASK_OP | (0x1 << 25) | MASK_FUNC, (0x10 << 26) | (0x1 << 25) | func, mnemonic, "" } + +#define MK_COPZ_XFER(z, mnemonic, format, xf) { MASK_OP | (0x1F << 21), ((0x10 | z) << 26) | (xf << 21), mnemonic, format } + +#define MK_GTE(mnemonic, format, func) { MASK_OP | (0x1 << 25) | MASK_FUNC, (0x1 << 25) | (0x12 << 26) | func, mnemonic, format } + +static OpEntry ops[] = +{ + MK_OP("nop", "", 0, 0, MASK_RT | MASK_RD | MASK_SA), + + // + // + // + MK_OP("sll", "d, t, a", 0, 0, 0), + MK_OP("srl", "d, t, a", 0, 2, 0), + MK_OP("sra", "d, t, a", 0, 3, 0), + + MK_OP("sllv", "d, t, s", 0, 4, 0), + MK_OP("srlv", "d, t, s", 0, 6, 0), + MK_OP("srav", "d, t, s", 0, 7, 0), + + MK_OP("jr", "s", 0, 8, 0), + MK_OP("jalr", "d, s", 0, 9, 0), + + MK_OP("syscall", "", 0, 12, 0), // TODO + MK_OP("break", "", 0, 13, 0), // TODO + + MK_OP("mfhi", "d", 0, 16, 0), + MK_OP("mthi", "s", 0, 17, 0), + MK_OP("mflo", "d", 0, 18, 0), + MK_OP("mtlo", "s", 0, 19, 0), + + MK_OP("mult", "s, t", 0, 24, 0), + MK_OP("multu", "s, t", 0, 25, 0), + MK_OP("div", "s, t", 0, 26, 0), + MK_OP("divu", "s, t", 0, 27, 0), + + MK_OP("add", "d, s, t", 0, 32, 0), + MK_OP("addu", "d, s, t", 0, 33, 0), + MK_OP("sub", "d, s, t", 0, 34, 0), + MK_OP("subu", "d, s, t", 0, 35, 0), + MK_OP("and", "d, s, t", 0, 36, 0), + MK_OP("or", "d, s, t", 0, 37, 0), + MK_OP("xor", "d, s, t", 0, 38, 0), + MK_OP("nor", "d, s, t", 0, 39, 0), + MK_OP("slt", "d, s, t", 0, 42, 0), + MK_OP("sltu", "d, s, t", 0, 43, 0), + + MK_OP_REGIMM("bgez", 0x01), + MK_OP_REGIMM("bgezal", 0x11), + MK_OP_REGIMM("bltz", 0x00), + MK_OP_REGIMM("bltzal", 0x10), + + + MK_OP("j", "P", 2, 0, 0), + MK_OP("jal", "P", 3, 0, 0), + + MK_OP("beq", "s, t, p", 4, 0, 0), + MK_OP("bne", "s, t, p", 5, 0, 0), + MK_OP("blez", "s, p", 6, 0, 0), + MK_OP("bgtz", "s, p", 7, 0, 0), + + MK_OP("addi", "t, s, i", 8, 0, 0), + MK_OP("addiu", "t, s, i", 9, 0, 0), + MK_OP("slti", "t, s, i", 10, 0, 0), + MK_OP("sltiu", "t, s, i", 11, 0, 0), + + MK_OP("andi", "t, s, z", 12, 0, 0), + + MK_OP("ori", "t, s, z", 13, 0, 0), + MK_OP("xori", "t, s, z", 14, 0, 0), + MK_OP("lui", "t, z", 15, 0, 0), + + MK_COPZ_XFER(0, "mfc0", "t, 0", 0x00), + MK_COPZ_XFER(1, "mfc1", "t, ?", 0x00), + MK_COPZ_XFER(2, "mfc2", "t, g", 0x00), + MK_COPZ_XFER(3, "mfc3", "t, ?", 0x00), + + MK_COPZ_XFER(0, "mtc0", "t, 0", 0x04), + MK_COPZ_XFER(1, "mtc1", "t, ?", 0x04), + MK_COPZ_XFER(2, "mtc2", "t, g", 0x04), + MK_COPZ_XFER(3, "mtc3", "t, ?", 0x04), + + MK_COPZ_XFER(0, "cfc0", "t, ?", 0x02), + MK_COPZ_XFER(1, "cfc1", "t, ?", 0x02), + MK_COPZ_XFER(2, "cfc2", "t, G", 0x02), + MK_COPZ_XFER(3, "cfc3", "t, ?", 0x02), + + MK_COPZ_XFER(0, "ctc0", "t, ?", 0x06), + MK_COPZ_XFER(1, "ctc1", "t, ?", 0x06), + MK_COPZ_XFER(2, "ctc2", "t, G", 0x06), + MK_COPZ_XFER(3, "ctc3", "t, ?", 0x06), + + // COP0 stuff here + MK_COP0_FUNC("rfe", 0x10), + + MK_OP("lwc0", "?, i(s)", 0x30, 0, 0), + MK_OP("lwc1", "?, i(s)", 0x31, 0, 0), + MK_OP("lwc2", "h, i(s)", 0x32, 0, 0), + MK_OP("lwc3", "?, i(s)", 0x33, 0, 0), + + MK_OP("swc0", "?, i(s)", 0x38, 0, 0), + MK_OP("swc1", "?, i(s)", 0x39, 0, 0), + MK_OP("swc2", "h, i(s)", 0x3A, 0, 0), + MK_OP("swc3", "?, i(s)", 0x3B, 0, 0), + + MK_OP("lb", "t, i(s)", 0x20, 0, 0), + MK_OP("lh", "t, i(s)", 0x21, 0, 0), + MK_OP("lwl", "t, i(s)", 0x22, 0, 0), + MK_OP("lw", "t, i(s)", 0x23, 0, 0), + MK_OP("lbu", "t, i(s)", 0x24, 0, 0), + MK_OP("lhu", "t, i(s)", 0x25, 0, 0), + MK_OP("lwr", "t, i(s)", 0x26, 0, 0), + + MK_OP("sb", "t, i(s)", 0x28, 0, 0), + MK_OP("sh", "t, i(s)", 0x29, 0, 0), + MK_OP("swl", "t, i(s)", 0x2A, 0, 0), + MK_OP("sw", "t, i(s)", 0x2B, 0, 0), + MK_OP("swr", "t, i(s)", 0x2E, 0, 0), + + // + // GTE specific instructions + // + // sf mx v cv lm + // + MK_GTE("rtps", "#sf# #lm#", 0x00), + MK_GTE("rtps", "#sf# #lm#", 0x01), + MK_GTE("nclip", "", 0x06), + MK_GTE("op", "#sf# #lm#", 0x0C), + + MK_GTE("dpcs", "#sf# #lm#", 0x10), + MK_GTE("intpl", "#sf# #lm#", 0x11), + MK_GTE("mvmva", "#sf# #mx# #v# #cv# #lm#", 0x12), + MK_GTE("ncds", "#sf# #lm#", 0x13), + MK_GTE("cdp", "#sf# #lm#", 0x14), + MK_GTE("ncdt", "#sf# #lm#", 0x16), + MK_GTE("dcpl", "#sf# #lm#", 0x1A), + MK_GTE("nccs", "#sf# #lm#", 0x1B), + MK_GTE("cc", "#sf# #lm#", 0x1C), + MK_GTE("ncs", "#sf# #lm#", 0x1E), + MK_GTE("nct", "#sf# #lm#", 0x20), + MK_GTE("sqr", "#sf# #lm#", 0x28), + MK_GTE("dcpl", "#sf# #lm#", 0x29), + MK_GTE("dpct", "#sf# #lm#", 0x2A), + MK_GTE("avsz3", "", 0x2D), + MK_GTE("avsz4", "", 0x2E), + MK_GTE("rtpt", "#sf# #lm#", 0x30), + MK_GTE("gpf", "#sf# #lm#", 0x3D), + MK_GTE("gpl", "#sf# #lm#", 0x3E), + MK_GTE("ncct", "#sf# #lm#", 0x3F), + + + // + // + // + MK_COPZ(0), + MK_COPZ(1), + MK_COPZ(2), + MK_COPZ(3), + + { 0, 0, NULL, NULL } +}; + +std::string DisassembleMIPS(uint32 PC, uint32 instr) +{ + std::string ret = "UNKNOWN"; + unsigned int rs = (instr >> 21) & 0x1F; + unsigned int rt = (instr >> 16) & 0x1F; + unsigned int rd = (instr >> 11) & 0x1F; + unsigned int shamt = (instr >> 6) & 0x1F; + unsigned int immediate = (int32)(int16)(instr & 0xFFFF); + unsigned int immediate_ze = (instr & 0xFFFF); + unsigned int jt = instr & ((1 << 26) - 1); + + static const char *gpr_names[32] = + { + "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" + }; + + static const char *cop0_names[32] = + { + "CPR0", "CPR1", "CPR2", "BPC", "CPR4", "BDA", "TAR", "DCIC", "CPR8", "BDAM", "CPR10", "BPCM", "SR", "CAUSE", "EPC", "PRID", + "ERREG", "CPR17", "CPR18", "CPR19", "CPR20", "CPR21", "CPR22", "CPR23", "CPR24", "CPR25", "CPR26", "CPR27", "CPR28", "CPR29", "CPR30", "CPR31" + }; + + static const char *gte_cr_names[32] = + { + "R11R12", "R13R21", "R22R23", "R31R32", "R33", "TRX", "TRY", "TRZ", "L11L12", "L13L21", "L22L23", "L31L32", "L33", "RBK", "GBK", "BBK", + "LR1LR2", "LR3LG1", "LG2LG3", "LB1LB2", "LB3", "RFC", "GFC", "BFC", "OFX", "OFY", "H", "DQA", "DQB", "ZSF3", "ZSF4", "FLAG" + }; + + static const char *gte_dr_names[32] = + { + "VXY0", "VZ0", "VXY1", "VZ1", "VXY2", "VZ2", "RGB", "OTZ", "IR0", "IR1", "IR2", "IR3", "SXY0", "SXY1", "SXY2", "SXYP", + "SZ0", "SZ1", "SZ2", "SZ3", "RGB0", "RGB1", "RGB2", "RES1", "MAC0", "MAC1", "MAC2", "MAC3", "IRGB", "ORGB", "LZCS", "LZCR" + }; + + OpEntry *op = ops; + + while(op->mnemonic) + { + if((instr & op->mask) == op->value) + { + // a = shift amount + // s = rs + // t = rt + // d = rd + // i = immediate + // z = immediate, zero-extended + // p = PC + 4 + immediate + // P = ((PC + 4) & 0xF0000000) | (26bitval << 2) + // + // 0 = rd(cop0 registers) + // c = rd(copz data registers) + // C = rd(copz control registers) + // g = rd(GTE data registers) + // G = rd(GTE control registers) + // h = rt(GTE data registers) + + char s_a[16]; + char s_i[16]; + char s_z[16]; + char s_p[16]; + char s_P[16]; + char s_c[16]; + char s_C[16]; + + snprintf(s_a, sizeof(s_a), "%d", shamt); + + if(immediate < 0) + snprintf(s_i, sizeof(s_i), "%d", immediate); + else + snprintf(s_i, sizeof(s_i), "0x%04x", (uint32)immediate); + + snprintf(s_z, sizeof(s_z), "0x%04x", immediate_ze); + + snprintf(s_p, sizeof(s_p), "0x%08x", PC + 4 + (immediate << 2)); + + snprintf(s_P, sizeof(s_P), "0x%08x", ((PC + 4) & 0xF0000000) | (jt << 2)); + + snprintf(s_c, sizeof(s_c), "CPR%d", rd); + snprintf(s_C, sizeof(s_C), "CCR%d", rd); + + ret = std::string(op->mnemonic); + ret.append(10 - ret.size(), ' '); + + for(unsigned int i = 0; i < strlen(op->format); i++) + { + switch(op->format[i]) + { + case '#': + // sf mx v cv lm + { + char as[16]; + + as[0] = 0; + if(!strncmp(&op->format[i], "#sf#", 4)) + { + i += 3; + snprintf(as, 16, "sf=%d", (int)(bool)(instr & (1 << 19))); + } + else if(!strncmp(&op->format[i], "#mx#", 4)) + { + i += 3; + snprintf(as, 16, "mx=%d", (instr >> 17) & 0x3); + } + else if(!strncmp(&op->format[i], "#v#", 3)) + { + i += 2; + snprintf(as, 16, "v=%d", (instr >> 15) & 0x3); + } + else if(!strncmp(&op->format[i], "#cv#", 4)) + { + i += 3; + snprintf(as, 16, "cv=%d", (instr >> 13) & 0x3); + } + else if(!strncmp(&op->format[i], "#lm#", 4)) + { + i += 3; + snprintf(as, 16, "lm=%d", (int)(bool)(instr & (1 << 10))); + } + ret.append(as); + } + break; + case 'F': + { + char s_F[16]; + + snprintf(s_F, 16, "0x%07x", instr & 0x1FFFFFF); + ret.append(s_F); + } + break; + + case 'h': + ret.append(gte_dr_names[rt]); + break; + + case 'g': + ret.append(gte_dr_names[rd]); + break; + + case 'G': + ret.append(gte_cr_names[rd]); + break; + + case '0': + ret.append(cop0_names[rd]); + break; + + case 'c': + ret.append(s_c); + break; + + case 'C': + ret.append(s_C); + break; + + case 'a': + ret.append(s_a); + break; + + case 'i': + ret.append(s_i); + break; + + case 'z': + ret.append(s_z); + break; + + case 'p': + ret.append(s_p); + break; + + case 'P': + ret.append(s_P); + break; + + case 's': + ret.append(gpr_names[rs]); + break; + + case 't': + ret.append(gpr_names[rt]); + break; + + case 'd': + ret.append(gpr_names[rd]); + break; + + default: + ret.append(1, op->format[i]); + break; + } + } + break; + } + op++; + } + + return(ret); +} + +} + diff --git a/mednafen/psx-0925/dis.h b/mednafen/psx-0925/dis.h new file mode 100644 index 00000000..d2648949 --- /dev/null +++ b/mednafen/psx-0925/dis.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_DIS_H +#define __MDFN_PSX_DIS_H + +namespace MDFN_IEN_PSX +{ + +std::string DisassembleMIPS(uint32 PC, uint32 instr); + +} + +#endif diff --git a/mednafen/psx-0925/dma.cpp b/mednafen/psx-0925/dma.cpp new file mode 100644 index 00000000..82b76278 --- /dev/null +++ b/mednafen/psx-0925/dma.cpp @@ -0,0 +1,638 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "mdec.h" +#include "cdc.h" +#include "spu.h" + +// FIXME: 0-length block count? + + +/* Notes: + + Channel 4(SPU): + Write: + Doesn't seem to work properly with CHCR=0x01000001 + Hung when CHCR=0x11000601 + + Channel 6: + DMA hangs if D28 of CHCR is 0? + D1 did not have an apparent effect. + +*/ + +enum +{ + CH_MDEC_IN = 0, + CH_MDEC_OUT = 1, + CH_GPU = 2, + CH_CDC = 3, + CH_SPU = 4, + CH_OT = 6, +}; + + +// RunChannels(128 - whatevercounter); +// +// GPU next event, std::max<128, wait_time>, or something similar, for handling FIFO. + +namespace MDFN_IEN_PSX +{ + +static int32 DMACycleCounter; + +static uint32 DMAControl; +static uint32 DMAIntControl; +static uint8 DMAIntStatus; +static bool IRQOut; + +struct Channel +{ + uint32 BaseAddr; + uint32 BlockControl; + uint32 ChanControl; + + // + // + // + uint32 CurAddr; + uint32 NextAddr; + + uint16 BlockCounter; + uint16 WordCounter; + + int32 ClockCounter; +}; + +static Channel DMACH[7]; +static pscpu_timestamp_t lastts; + + +static const char *PrettyChannelNames[7] = { "MDEC IN", "MDEC OUT", "GPU", "CDC", "SPU", "PIO", "OTC" }; + +void DMA_Init(void) +{ + +} + +void DMA_Kill(void) +{ + +} + +static INLINE void RecalcIRQOut(void) +{ + bool irqo; + + irqo = (bool)(DMAIntStatus & ((DMAIntControl >> 16) & 0x7F)); + irqo &= (DMAIntControl >> 23) & 1; + + // I think it's logical OR, not XOR/invert. Still kind of weird, maybe it actually does something more complicated? + //irqo ^= (DMAIntControl >> 15) & 1; + irqo |= (DMAIntControl >> 15) & 1; + + IRQOut = irqo; + IRQ_Assert(IRQ_DMA, irqo); +} + +void DMA_ResetTS(void) +{ + lastts = 0; +} + +void DMA_Power(void) +{ + lastts = 0; + + memset(DMACH, 0, sizeof(DMACH)); + + DMACycleCounter = 128; + + DMAControl = 0; + DMAIntControl = 0; + DMAIntStatus = 0; + RecalcIRQOut(); +} + +static void RecalcHalt(void) +{ + bool Halt = false; + + if((DMACH[0].WordCounter || (DMACH[0].ChanControl & (1 << 24))) && (DMACH[0].ChanControl & 0x200) /*&& MDEC_DMACanWrite()*/) + Halt = true; + + if((DMACH[1].WordCounter || (DMACH[1].ChanControl & (1 << 24))) && (DMACH[1].ChanControl & 0x200) && (DMACH[1].WordCounter || MDEC_DMACanRead())) + Halt = true; + + if((DMACH[2].WordCounter || (DMACH[2].ChanControl & (1 << 24))) && (DMACH[2].ChanControl & 0x200) && ((DMACH[2].ChanControl & 0x1) && (DMACH[2].WordCounter || GPU->DMACanWrite()))) + Halt = true; + + if((DMACH[3].WordCounter || (DMACH[3].ChanControl & (1 << 24))) && !(DMACH[3].ChanControl & 0x100)) + Halt = true; + + if(DMACH[6].WordCounter || (DMACH[6].ChanControl & (1 << 24))) + Halt = true; + + //printf("Halt: %d\n", Halt); + + CPU->SetHalt(Halt); +} + +template +static INLINE bool ChCan(void) +{ +#if 0 + if(ch != 3) + { + if((DMACH[3].WordCounter || (DMACH[3].ChanControl & (1 << 24))) && !(DMACH[3].ChanControl & 0x100)) + { + return(false); + } + } +#endif + + switch(ch) + { + case 0: return(true); // MDEC IN + case 1: return(MDEC_DMACanRead()); // MDEC out + case 2: + if(write_mode) + return(GPU->DMACanWrite()); + else + return(true); // GPU + case 3: return(true); // CDC + case 4: return(true); // SPU + case 5: return(true); // ?? + case 6: return(true); // OT + } + abort(); +} + +template +static INLINE void ChRW(int32 timestamp, uint32 *V) +{ + switch(ch) + { + default: + abort(); + + case CH_MDEC_IN: + MDEC_DMAWrite(*V); + break; + + case CH_MDEC_OUT: + *V = MDEC_DMARead(); + break; + + case CH_GPU: + if(write_mode) + GPU->WriteDMA(*V); + else + *V = GPU->Read(timestamp, 0); + break; + + case CH_CDC: + // 0x1f801018 affects CDC DMA timing. +#if 0 + if(DMACH[ch].ChanControl & 0x100) // For CDC DMA(at least): When this bit is set, DMA controller doesn't appear to hog the (RAM?) bus. + { + if(DMACH[ch].ChanControl & 0x00400000) // For CDC DMA(at least): When this bit is set, DMA controller appears to get even less bus time(or has a lower priority??) + { + DMACH[ch].ClockCounter -= 44 * 20 / 12; + } + else + { + DMACH[ch].ClockCounter -= 29 * 20 / 12; + } + } + else + { + DMACH[ch].ClockCounter -= 23 * 20 / 12; // (23 + 1) = 24. (Though closer to 24.5 or 24.4 on average per tests on a PS1) + } +#endif + *V = CDC->DMARead(); + break; + + case CH_SPU: + // 0x1f801014 affects SPU DMA timing. + // Wild conjecture about 0x1f801014: + // + // & 0x0000000F + // & 0x000001E0 --- Used if (& 0x20000000) == 0? + // & 0x00001000 --- Double total bus cycle time if value == 0? + // & 0x0f000000 --- (value << 1) 33MHz cycles, bus cycle extension(added to 4?)? + // & 0x20000000 --- + // + // + // TODO?: SPU DMA will "complete" much faster if there's a mismatch between the CHCR read/write mode bit and the SPU control register DMA mode. + // + // + // Investigate: SPU DMA doesn't seem to work right if the value written to 0x1F801DAA doesn't have the upper bit set to 1(0x8000) on a PS1. + + DMACH[ch].ClockCounter -= 47; // Should be closer to 69, average, but actual timing is...complicated. + if(write_mode) + SPU->WriteDMA(*V); + else + *V = SPU->ReadDMA(); + break; + + case CH_OT: + if(DMACH[ch].WordCounter == 1) + *V = 0xFFFFFF; + else + *V = (DMACH[ch].CurAddr - 4) & 0x1FFFFF; + break; + } +} + +template +static INLINE void RunChannelT(pscpu_timestamp_t timestamp, int32 clocks) +{ + //const uint32 dc = (DMAControl >> (ch * 4)) & 0xF; + + DMACH[ch].ClockCounter += clocks; + + while(DMACH[ch].ClockCounter > 0) + { + if(!DMACH[ch].WordCounter) + { + if(!(DMACH[ch].ChanControl & (1 << 24))) + { + break; + } + + if(DMACH[ch].NextAddr & 0x800000) + { + //if(ch == 2) + // PSX_WARNING("[DMA] LL Channel 2 ended normally: %d\n", GPU->GetScanlineNum()); + DMACH[ch].ChanControl &= ~(0x11 << 24); + if(DMAIntControl & (1 << (16 + ch))) + { + DMAIntStatus |= 1 << ch; + RecalcIRQOut(); + } + break; + } + + if(!ChCan()) + break; + + if((DMACH[ch].ChanControl & (1 << 10)) && write_mode) + { + uint32 header; + + DMACH[ch].CurAddr = DMACH[ch].NextAddr & 0x1FFFFC; + header = MainRAM.ReadU32(DMACH[ch].CurAddr); + DMACH[ch].CurAddr = (DMACH[ch].CurAddr + 4) & 0x1FFFFF; + + DMACH[ch].WordCounter = header >> 24; + DMACH[ch].NextAddr = header & 0xFFFFFF; + + if(DMACH[ch].WordCounter > 0x10) + printf("What the lala? 0x%02x @ 0x%08x\n", DMACH[ch].WordCounter, DMACH[ch].CurAddr - 4); + + if(DMACH[ch].WordCounter) + DMACH[ch].ClockCounter -= 15; + else + DMACH[ch].ClockCounter -= 10; + + continue; + } + else + { + DMACH[ch].CurAddr = DMACH[ch].NextAddr & 0x1FFFFC; + DMACH[ch].WordCounter = DMACH[ch].BlockControl & 0xFFFF; + DMACH[ch].BlockCounter--; + + if(!DMACH[ch].BlockCounter || ch == 6 || ch == 3) + DMACH[ch].NextAddr = 0xFFFFFF; + else + DMACH[ch].NextAddr = (DMACH[ch].CurAddr + ((DMACH[ch].BlockControl & 0xFFFF) << 2)) & 0x1FFFFF; + } + } + + if(ch != 2 && ch != 1) + { + if(!ChCan()) + break; + } + + + { + uint32 vtmp; + + if(write_mode) + vtmp = MainRAM.ReadU32(DMACH[ch].CurAddr); + + ChRW(timestamp, &vtmp); + + if(!write_mode) + MainRAM.WriteU32(DMACH[ch].CurAddr, vtmp); + } + + if(ch == 6) + DMACH[ch].CurAddr = (DMACH[ch].CurAddr - 4) & 0x1FFFFF; + else + DMACH[ch].CurAddr = (DMACH[ch].CurAddr + 4) & 0x1FFFFF; + + DMACH[ch].WordCounter--; + DMACH[ch].ClockCounter--; + } + + + if(DMACH[ch].ClockCounter > 0) + DMACH[ch].ClockCounter = 0; +} + +static INLINE void RunChannel(pscpu_timestamp_t timestamp, int32 clocks, int ch) +{ + switch(ch) + { + default: abort(); + + case 0: + RunChannelT<0, true>(timestamp, clocks); + break; + + case 1: + RunChannelT<1, false>(timestamp, clocks); + break; + + case 2: + if(DMACH[2].ChanControl & 0x1) + RunChannelT<2, true>(timestamp, clocks); + else + RunChannelT<2, false>(timestamp, clocks); + break; + + case 3: + RunChannelT<3, false>(timestamp, clocks); + break; + + case 4: + if(DMACH[4].ChanControl & 0x1) + RunChannelT<4, true>(timestamp, clocks); + else + RunChannelT<4, false>(timestamp, clocks); + break; + + case 6: + RunChannelT<6, false>(timestamp, clocks); + break; + } +} + +static INLINE int32 CalcNextEvent(int32 next_event) +{ + if(DMACycleCounter < next_event) + next_event = DMACycleCounter; + + return(next_event); +} + +pscpu_timestamp_t DMA_Update(const pscpu_timestamp_t timestamp) +{ +// uint32 dc = (DMAControl >> (ch * 4)) & 0xF; + int32 clocks = timestamp - lastts; + lastts = timestamp; + + GPU->Update(timestamp); + MDEC_Run(clocks); + + RunChannel(timestamp, clocks, 0); + RunChannel(timestamp, clocks, 1); + RunChannel(timestamp, clocks, 2); + RunChannel(timestamp, clocks, 3); + RunChannel(timestamp, clocks, 4); + RunChannel(timestamp, clocks, 6); + + DMACycleCounter -= clocks; + while(DMACycleCounter <= 0) + DMACycleCounter += 128; + + RecalcHalt(); + + return(timestamp + CalcNextEvent(0x10000000)); +} + +void DMA_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + int ch = (A & 0x7F) >> 4; + + //PSX_WARNING("[DMA] Write: %08x %08x, DMAIntStatus=%08x", A, V, DMAIntStatus); + + // FIXME if we ever have "accurate" bus emulation + V <<= (A & 3) * 8; + + DMA_Update(timestamp); + + if(ch == 7) + { + switch(A & 0xC) + { + case 0x0: //fprintf(stderr, "Global DMA control: 0x%08x\n", V); + DMAControl = V; + RecalcHalt(); + break; + + case 0x4: + //for(int x = 0; x < 7; x++) + //{ + // if(DMACH[x].WordCounter || (DMACH[x].ChanControl & (1 << 24))) + // { + // fprintf(stderr, "Write DMAIntControl while channel %d active: 0x%08x\n", x, V); + // } + //} + DMAIntControl = V & 0x00ff803f; + DMAIntStatus &= ~(V >> 24); + + //if(DMAIntStatus ^ (DMAIntStatus & (V >> 16))) + // fprintf(stderr, "DMAINT Fudge: %02x\n", DMAIntStatus ^ (DMAIntStatus & (V >> 16))); + DMAIntStatus &= (V >> 16); // THIS IS ALMOST CERTAINLY WRONG AND A HACK. Remove when CDC emulation is better. + RecalcIRQOut(); + break; + + default: PSX_WARNING("[DMA] Unknown write: %08x %08x", A, V); + assert(0); + break; + } + return; + } + switch(A & 0xC) + { + case 0x0: DMACH[ch].BaseAddr = V & 0xFFFFFF; + break; + + case 0x4: DMACH[ch].BlockControl = V; + break; + + case 0xC: + case 0x8: + { + uint32 OldCC = DMACH[ch].ChanControl; + + // + // Kludge for DMA timing granularity and other issues. Needs to occur before setting all bits of ChanControl to the new value, to accommodate the + // case of a game cancelling DMA and changing the type of DMA(read/write, etc.) at the same time. + // + if((DMACH[ch].ChanControl & (1 << 24)) && !(V & (1 << 24))) + { + DMACH[ch].ChanControl &= ~(1 << 24); // Clear bit before RunChannel(), so it will only finish the block it's on at most. + RunChannel(timestamp, 128 * 16, ch); + DMACH[ch].BlockCounter = 0; + DMACH[ch].WordCounter = 0; + +#if 0 // TODO(maybe, need to work out worst-case performance for abnormally/brokenly large block sizes) + DMACH[ch].ClockCounter = (1 << 30); + RunChannel(timestamp, 1, ch); + DMACH[ch].ClockCounter = 0; +#endif + + if(ch == 2) + { + GPU->AbortDMA(); + } + + PSX_WARNING("[DMA] Forced stop for channel %d -- scanline=%d", ch, GPU->GetScanlineNum()); + //MDFN_DispMessage("[DMA] Forced stop for channel %d", ch); + } + + if(ch == 6) + DMACH[ch].ChanControl = V & 0x51000002; // Not 100% sure, but close. + else + DMACH[ch].ChanControl = V & 0x71770703; + + if(!(OldCC & (1 << 24)) && (V & (1 << 24))) + { + //if(ch == 2) + //if(ch == 4) + //PSX_WARNING("[DMA] Started DMA for channel=%d --- CHCR=0x%08x --- BCR=0x%08x --- scanline=%d", ch, DMACH[ch].ChanControl, DMACH[ch].BlockControl, GPU->GetScanlineNum()); + + DMACH[ch].ClockCounter = 0; + DMACH[ch].NextAddr = DMACH[ch].BaseAddr & 0x1FFFFC; + DMACH[ch].BlockCounter = DMACH[ch].BlockControl >> 16; + + // + // Viewpoint starts a short MEM->GPU LL DMA and apparently has race conditions that can cause a crash if it doesn't finish almost immediately( + // or at least very quickly, which the current DMA granularity has issues with, so run the channel ahead a bit to take of this issue and potentially + // games with similar issues). + // + // Though, Viewpoint isn't exactly a good game, so maybe we shouldn't bother? ;) + // + RunChannel(timestamp, 64, ch); //std::max(128 - DMACycleCounter, 1)); //64); //1); //128 - DMACycleCounter); + } + + RecalcHalt(); + } + break; + } + PSX_SetEventNT(PSX_EVENT_DMA, timestamp + CalcNextEvent(0x10000000)); +} + +uint32 DMA_Read(const pscpu_timestamp_t timestamp, uint32 A) +{ + int ch = (A & 0x7F) >> 4; + uint32 ret = 0; + + //assert(!(A & 3)); + + //if(ch == 2) + // printf("DMA Read: %08x --- %d\n", A, GPU->GetScanlineNum()); + + if(ch == 7) + { + switch(A & 0xC) + { + default: PSX_WARNING("[DMA] Unknown read: %08x", A); + assert(0); + break; + + case 0x0: ret = DMAControl; + break; + + case 0x4: ret = DMAIntControl | (DMAIntStatus << 24) | (IRQOut << 31); + break; + } + } + else switch(A & 0xC) + { + case 0x0: ret = DMACH[ch].BaseAddr; + break; + + case 0x4: ret = DMACH[ch].BlockControl; + break; + + case 0xC: + case 0x8: ret = DMACH[ch].ChanControl; + break; + + } + + ret >>= (A & 3) * 8; + + //PSX_WARNING("[DMA] Read: %08x %08x", A, ret); + + return(ret); +} + + +int DMA_StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { + SFVAR(DMACycleCounter), + SFVAR(DMAControl), + SFVAR(DMAIntControl), + SFVAR(DMAIntStatus), + SFVAR(IRQOut), + +#define SFDMACH(n) SFVARN(DMACH[n].BaseAddr, #n "BaseAddr"), \ + SFVARN(DMACH[n].BlockControl, #n "BlockControl"), \ + SFVARN(DMACH[n].ChanControl, #n "ChanControl"), \ + SFVARN(DMACH[n].CurAddr, #n "CurAddr"), \ + SFVARN(DMACH[n].NextAddr, #n "NextAddr"), \ + SFVARN(DMACH[n].BlockCounter, #n "BlockCounter"), \ + SFVARN(DMACH[n].WordCounter, #n "WordCounter"), \ + SFVARN(DMACH[n].ClockCounter, #n "ClockCounter") + + SFDMACH(0), + SFDMACH(1), + SFDMACH(2), + SFDMACH(3), + SFDMACH(4), + SFDMACH(5), + SFDMACH(6), + +#undef SFDMACH + + SFVAR(lastts), + + SFEND + }; + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "DMA"); + + if(load) + { + + } + + return(ret); +} + + +} diff --git a/mednafen/psx-0925/dma.h b/mednafen/psx-0925/dma.h new file mode 100644 index 00000000..abfeeb41 --- /dev/null +++ b/mednafen/psx-0925/dma.h @@ -0,0 +1,24 @@ +#ifndef __MDFN_PSX_DMA_H +#define __MDFN_PSX_DMA_H + +namespace MDFN_IEN_PSX +{ + +bool DMA_GPUWriteActive(void); + +pscpu_timestamp_t DMA_Update(const pscpu_timestamp_t timestamp); +void DMA_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); +uint32 DMA_Read(const pscpu_timestamp_t timestamp, uint32 A); + +void DMA_ResetTS(void); + +void DMA_Power(void); + +void DMA_Init(void); +void DMA_Kill(void); + +int DMA_StateAction(StateMem *sm, int load, int data_only); + +} + +#endif diff --git a/mednafen/psx-0925/frontio.cpp b/mednafen/psx-0925/frontio.cpp new file mode 100644 index 00000000..263f3499 --- /dev/null +++ b/mednafen/psx-0925/frontio.cpp @@ -0,0 +1,906 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "frontio.h" +#include "../FileWrapper.h" + +#include "input/gamepad.h" +#include "input/dualanalog.h" +#include "input/dualshock.h" +#include "input/mouse.h" +#include "input/negcon.h" +#include "input/guncon.h" +#include "input/justifier.h" + +#include "input/memcard.h" + +#include "input/multitap.h" + +#define PSX_FIODBGINFO(format, ...) { /* printf(format " -- timestamp=%d -- PAD temp\n", ## __VA_ARGS__, timestamp); */ } + +namespace MDFN_IEN_PSX +{ + +InputDevice::InputDevice() +{ +} + +InputDevice::~InputDevice() +{ +} + +void InputDevice::Power(void) +{ +} + +void InputDevice::Update(const pscpu_timestamp_t timestamp) +{ + +} + +void InputDevice::ResetTS(void) +{ + +} + +void InputDevice::SetAMCT(bool) +{ + +} + +void InputDevice::SetCrosshairsColor(uint32 color) +{ + +} + +bool InputDevice::RequireNoFrameskip(void) +{ + return(false); +} + +pscpu_timestamp_t InputDevice::GPULineHook(const pscpu_timestamp_t timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock) +{ + return(PSX_EVENT_MAXTS); +} + + +void InputDevice::UpdateInput(const void *data) +{ +} + + +void InputDevice::SetDTR(bool new_dtr) +{ + +} + +bool InputDevice::GetDSR(void) +{ + return(0); +} + +bool InputDevice::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + dsr_pulse_delay = 0; + + return(1); +} + +uint32 InputDevice::GetNVSize(void) +{ + return(0); +} + +void InputDevice::ReadNV(uint8 *buffer, uint32 offset, uint32 count) +{ + +} + +void InputDevice::WriteNV(const uint8 *buffer, uint32 offset, uint32 count) +{ + +} + +uint64 InputDevice::GetNVDirtyCount(void) +{ + return(0); +} + +void InputDevice::ResetNVDirtyCount(void) +{ + +} + +static INLINE unsigned EP_to_MP(unsigned ep) +{ +#if 0 + return((bool)(ep & 0x4)); +#else + return(ep == 1 || ep >= 5); +#endif +} + +static INLINE unsigned EP_to_SP(unsigned ep) +{ +#if 0 + return(ep & 0x3); +#else + if(ep < 2) + return(0); + else if(ep < 5) + return(ep - 2 + 1); + else + return(ep - 5 + 1); +#endif +} + +void FrontIO::MapDevicesToPorts(void) +{ + for(unsigned i = 0; i < 2; i++) + { + if(emulate_multitap[i]) + { + Ports[i] = DevicesTap[i]; + MCPorts[i] = DummyDevice; + } + else + { + Ports[i] = Devices[i]; + MCPorts[i] = emulate_memcards[i] ? DevicesMC[i] : DummyDevice; + } + } + + for(unsigned i = 0; i < 8; i++) + { + unsigned mp = EP_to_MP(i); + + if(emulate_multitap[mp]) + DevicesTap[mp]->SetSubDevice(EP_to_SP(i), Devices[i], emulate_memcards[i] ? DevicesMC[i] : DummyDevice); + else + DevicesTap[mp]->SetSubDevice(EP_to_SP(i), DummyDevice, DummyDevice); + } +} + +FrontIO::FrontIO(bool emulate_memcards_[8], bool emulate_multitap_[2]) +{ + memcpy(emulate_memcards, emulate_memcards_, sizeof(emulate_memcards)); + memcpy(emulate_multitap, emulate_multitap_, sizeof(emulate_multitap)); + + DummyDevice = new InputDevice(); + + for(unsigned i = 0; i < 8; i++) + { + DeviceData[i] = NULL; + Devices[i] = new InputDevice(); + DevicesMC[i] = Device_Memcard_Create(); + chair_colors[i] = 1 << 24; + Devices[i]->SetCrosshairsColor(chair_colors[i]); + } + + for(unsigned i = 0; i < 2; i++) + { + DevicesTap[i] = new InputDevice_Multitap(); + } + + MapDevicesToPorts(); +} + +void FrontIO::SetAMCT(bool enabled) +{ + for(unsigned i = 0; i < 8; i++) + { + Devices[i]->SetAMCT(enabled); + } + amct_enabled = enabled; +} + +void FrontIO::SetCrosshairsColor(unsigned port, uint32 color) +{ + assert(port >= 0 && port < 8); + + chair_colors[port] = color; + Devices[port]->SetCrosshairsColor(color); +} + +FrontIO::~FrontIO() +{ + for(int i = 0; i < 8; i++) + { + if(Devices[i]) + { + delete Devices[i]; + Devices[i] = NULL; + } + if(DevicesMC[i]) + { + delete DevicesMC[i]; + DevicesMC[i] = NULL; + } + } + + for(unsigned i = 0; i < 2; i++) + { + if(DevicesTap[i]) + { + delete DevicesTap[i]; + DevicesTap[i] = NULL; + } + } + + if(DummyDevice) + { + delete DummyDevice; + DummyDevice = NULL; + } +} + +pscpu_timestamp_t FrontIO::CalcNextEventTS(pscpu_timestamp_t timestamp, int32 next_event) +{ + pscpu_timestamp_t ret; + + if(ClockDivider > 0 && ClockDivider < next_event) + next_event = ClockDivider; + + for(int i = 0; i < 4; i++) + if(dsr_pulse_delay[i] > 0 && next_event > dsr_pulse_delay[i]) + next_event = dsr_pulse_delay[i]; + + ret = timestamp + next_event; + + if(irq10_pulse_ts[0] < ret) + ret = irq10_pulse_ts[0]; + + if(irq10_pulse_ts[1] < ret) + ret = irq10_pulse_ts[1]; + + return(ret); +} + +void FrontIO::CheckStartStopPending(pscpu_timestamp_t timestamp, bool skip_event_set) +{ + //const bool prior_ReceiveInProgress = ReceiveInProgress; + //const bool prior_TransmitInProgress = TransmitInProgress; + bool trigger_condition = false; + + trigger_condition = (ReceivePending && (Control & 0x4)) || (TransmitPending && (Control & 0x1)); + + if(trigger_condition) + { + if(ReceivePending) + { + ReceivePending = false; + ReceiveInProgress = true; + ReceiveBufferAvail = false; + ReceiveBuffer = 0; + ReceiveBitCounter = 0; + } + + if(TransmitPending) + { + TransmitPending = false; + TransmitInProgress = true; + TransmitBitCounter = 0; + } + + ClockDivider = 0x44; + } + + if(!(Control & 0x5)) + { + ReceiveInProgress = false; + TransmitInProgress = false; + } + + if(!ReceiveInProgress && !TransmitInProgress) + ClockDivider = 0; + + if(!(skip_event_set)) + PSX_SetEventNT(PSX_EVENT_FIO, CalcNextEventTS(timestamp, 0x10000000)); +} + +// DSR IRQ bit setting appears(from indirect tests on real PS1) to be level-sensitive, not edge-sensitive +INLINE void FrontIO::DoDSRIRQ(void) +{ + if(Control & 0x1000) + { + PSX_FIODBGINFO("[DSR] IRQ"); + istatus = true; + IRQ_Assert(IRQ_SIO, true); + } +} + + +void FrontIO::Write(pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + assert(!(A & 0x1)); + + PSX_FIODBGINFO("[FIO] Write: %08x %08x", A, V); + + Update(timestamp); + + switch(A & 0xF) + { + case 0x0: + TransmitBuffer = V; + TransmitPending = true; + TransmitInProgress = false; + break; + + case 0x8: + Mode = V & 0x013F; + break; + + case 0xa: + if(ClockDivider > 0 && ((V & 0x2000) != (Control & 0x2000)) && ((Control & 0x2) == (V & 0x2)) ) + fprintf(stderr, "FIO device selection changed during comm %04x->%04x", Control, V); + + //printf("Control: %d, %04x\n", timestamp, V); + Control = V & 0x3F2F; + + if(V & 0x10) + { + istatus = false; + IRQ_Assert(IRQ_SIO, false); + } + + if(V & 0x40) // Reset + { + istatus = false; + IRQ_Assert(IRQ_SIO, false); + + ClockDivider = 0; + ReceivePending = false; + TransmitPending = false; + + ReceiveInProgress = false; + TransmitInProgress = false; + + ReceiveBufferAvail = false; + + TransmitBuffer = 0; + ReceiveBuffer = 0; + + ReceiveBitCounter = 0; + TransmitBitCounter = 0; + + Mode = 0; + Control = 0; + Baudrate = 0; + } + + Ports[0]->SetDTR((Control & 0x2) && !(Control & 0x2000)); + MCPorts[0]->SetDTR((Control & 0x2) && !(Control & 0x2000)); + Ports[1]->SetDTR((Control & 0x2) && (Control & 0x2000)); + MCPorts[1]->SetDTR((Control & 0x2) && (Control & 0x2000)); + +#if 1 +if(!((Control & 0x2) && !(Control & 0x2000))) +{ + dsr_pulse_delay[0] = 0; + dsr_pulse_delay[2] = 0; + dsr_active_until_ts[0] = -1; + dsr_active_until_ts[2] = -1; +} + +if(!((Control & 0x2) && (Control & 0x2000))) +{ + dsr_pulse_delay[1] = 0; + dsr_pulse_delay[3] = 0; + dsr_active_until_ts[1] = -1; + dsr_active_until_ts[3] = -1; +} + +#endif + // TODO: Uncomment out in the future once our CPU emulation is a bit more accurate with timing, to prevent causing problems with games + // that may clear the IRQ in an unsafe pattern that only works because its execution was slow enough to allow DSR to go inactive. (Whether or not + // such games even exist though is unknown!) + //if(timestamp < dsr_active_until_ts[0] || timestamp < dsr_active_until_ts[1] || timestamp < dsr_active_until_ts[2] || timestamp < dsr_active_until_ts[3]) + // DoDSRIRQ(); + + break; + + case 0xe: + Baudrate = V; + //MDFN_DispMessage("%02x\n", V); + break; + } + + CheckStartStopPending(timestamp, false); +} + + +uint32 FrontIO::Read(pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 ret = 0; + + assert(!(A & 0x1)); + + Update(timestamp); + + switch(A & 0xF) + { + case 0x0: + ret = ReceiveBuffer | (ReceiveBuffer << 8) | (ReceiveBuffer << 16) | (ReceiveBuffer << 24); + ReceiveBufferAvail = false; + ReceivePending = true; + ReceiveInProgress = false; + CheckStartStopPending(timestamp, false); + break; + + case 0x4: + ret = 0; + + if(!TransmitPending && !TransmitInProgress) + ret |= 0x1; + + if(ReceiveBufferAvail) + ret |= 0x2; + + if(timestamp < dsr_active_until_ts[0] || timestamp < dsr_active_until_ts[1] || timestamp < dsr_active_until_ts[2] || timestamp < dsr_active_until_ts[3]) + ret |= 0x80; + + if(istatus) + ret |= 0x200; + + break; + + case 0x8: + ret = Mode; + break; + + case 0xa: + ret = Control; + break; + + case 0xe: + ret = Baudrate; + break; + } + + if((A & 0xF) != 0x4) + PSX_FIODBGINFO("[FIO] Read: %08x %08x", A, ret); + + return(ret); +} + +pscpu_timestamp_t FrontIO::Update(pscpu_timestamp_t timestamp) +{ + int32 clocks = timestamp - lastts; + bool need_start_stop_check = false; + + for(int i = 0; i < 4; i++) + if(dsr_pulse_delay[i] > 0) + { + dsr_pulse_delay[i] -= clocks; + if(dsr_pulse_delay[i] <= 0) + { + dsr_active_until_ts[i] = timestamp + 32 + dsr_pulse_delay[i]; + DoDSRIRQ(); + } + } + + for(int i = 0; i < 2; i++) + { + if(timestamp >= irq10_pulse_ts[i]) + { + //printf("Yay: %d %u\n", i, timestamp); + irq10_pulse_ts[i] = PSX_EVENT_MAXTS; + IRQ_Assert(IRQ_PIO, true); + IRQ_Assert(IRQ_PIO, false); + } + } + + if(ClockDivider > 0) + { + ClockDivider -= clocks; + + while(ClockDivider <= 0) + { + if(ReceiveInProgress || TransmitInProgress) + { + bool rxd = 0, txd = 0; + const uint32 BCMask = 0x07; + + if(TransmitInProgress) + { + txd = (TransmitBuffer >> TransmitBitCounter) & 1; + TransmitBitCounter = (TransmitBitCounter + 1) & BCMask; + if(!TransmitBitCounter) + { + need_start_stop_check = true; + PSX_FIODBGINFO("[FIO] Data transmitted: %08x", TransmitBuffer); + TransmitInProgress = false; + + if(Control & 0x400) + { + istatus = true; + IRQ_Assert(IRQ_SIO, true); + } + } + } + + rxd = Ports[0]->Clock(txd, dsr_pulse_delay[0]) & Ports[1]->Clock(txd, dsr_pulse_delay[1]) & + MCPorts[0]->Clock(txd, dsr_pulse_delay[2]) & MCPorts[1]->Clock(txd, dsr_pulse_delay[3]); + + if(ReceiveInProgress) + { + ReceiveBuffer &= ~(1 << ReceiveBitCounter); + ReceiveBuffer |= rxd << ReceiveBitCounter; + + ReceiveBitCounter = (ReceiveBitCounter + 1) & BCMask; + + if(!ReceiveBitCounter) + { + need_start_stop_check = true; + PSX_FIODBGINFO("[FIO] Data received: %08x", ReceiveBuffer); + + ReceiveInProgress = false; + ReceiveBufferAvail = true; + + if(Control & 0x800) + { + istatus = true; + IRQ_Assert(IRQ_SIO, true); + } + } + } + ClockDivider += 0x44; //88; //99; + } + else + break; + } + } + + + lastts = timestamp; + + + if(need_start_stop_check) + { + CheckStartStopPending(timestamp, true); + } + + return(CalcNextEventTS(timestamp, 0x10000000)); +} + +void FrontIO::ResetTS(void) +{ + for(int i = 0; i < 8; i++) + { + Devices[i]->Update(lastts); // Maybe eventually call Update() from FrontIO::Update() and remove this(but would hurt speed)? + Devices[i]->ResetTS(); + + DevicesMC[i]->Update(lastts); // Maybe eventually call Update() from FrontIO::Update() and remove this(but would hurt speed)? + DevicesMC[i]->ResetTS(); + } + + for(int i = 0; i < 2; i++) + { + DevicesTap[i]->Update(lastts); + DevicesTap[i]->ResetTS(); + } + + for(int i = 0; i < 2; i++) + { + if(irq10_pulse_ts[i] != PSX_EVENT_MAXTS) + irq10_pulse_ts[i] -= lastts; + } + + for(int i = 0; i < 4; i++) + { + if(dsr_active_until_ts[i] >= 0) + { + dsr_active_until_ts[i] -= lastts; + //printf("SPOOONY: %d %d\n", i, dsr_active_until_ts[i]); + } + } + lastts = 0; +} + + +void FrontIO::Power(void) +{ + for(int i = 0; i < 4; i++) + { + dsr_pulse_delay[i] = 0; + dsr_active_until_ts[i] = -1; + } + + for(int i = 0; i < 2; i++) + { + irq10_pulse_ts[i] = PSX_EVENT_MAXTS; + } + + lastts = 0; + + // + // + + ClockDivider = 0; + + ReceivePending = false; + TransmitPending = false; + + ReceiveInProgress = false; + TransmitInProgress = false; + + ReceiveBufferAvail = false; + + TransmitBuffer = 0; + ReceiveBuffer = 0; + + ReceiveBitCounter = 0; + TransmitBitCounter = 0; + + Mode = 0; + Control = 0; + Baudrate = 0; + + for(int i = 0; i < 8; i++) + { + Devices[i]->Power(); + DevicesMC[i]->Power(); + } + + istatus = false; +} + +void FrontIO::UpdateInput(void) +{ + for(int i = 0; i < 8; i++) + Devices[i]->UpdateInput(DeviceData[i]); +} + +void FrontIO::SetInput(unsigned int port, const char *type, void *ptr) +{ + delete Devices[port]; + Devices[port] = NULL; + + if(port < 2) + irq10_pulse_ts[port] = PSX_EVENT_MAXTS; + + if(!strcmp(type, "gamepad")) + Devices[port] = Device_Gamepad_Create(); + else if(!strcmp(type, "dualanalog")) + Devices[port] = Device_DualAnalog_Create(false); + else if(!strcmp(type, "analogjoy")) + Devices[port] = Device_DualAnalog_Create(true); + else if(!strcmp(type, "dualshock")) + { + char name[256]; + trio_snprintf(name, 256, _("DualShock on port %u"), port + 1); + Devices[port] = Device_DualShock_Create(std::string(name)); + } + else if(!strcmp(type, "mouse")) + Devices[port] = Device_Mouse_Create(); + else if(!strcmp(type, "negcon")) + Devices[port] = Device_neGcon_Create(); + else if(!strcmp(type, "guncon")) + Devices[port] = Device_GunCon_Create(); + else if(!strcmp(type, "justifier")) + Devices[port] = Device_Justifier_Create(); + else + Devices[port] = new InputDevice(); + + Devices[port]->SetAMCT(amct_enabled); + Devices[port]->SetCrosshairsColor(chair_colors[port]); + DeviceData[port] = ptr; + + MapDevicesToPorts(); +} + +uint64 FrontIO::GetMemcardDirtyCount(unsigned int which) +{ + assert(which < 8); + + return(DevicesMC[which]->GetNVDirtyCount()); +} + +void FrontIO::LoadMemcard(unsigned int which, const char *path) +{ + assert(which < 8); + + try + { + if(DevicesMC[which]->GetNVSize()) + { + FileWrapper mf(path, FileWrapper::MODE_READ); + std::vector tmpbuf; + + tmpbuf.resize(DevicesMC[which]->GetNVSize()); + + if(mf.size() != (int64)tmpbuf.size()) + throw(MDFN_Error(0, _("Memory card file \"%s\" is an incorrect size(%d bytes). The correct size is %d bytes."), path, (int)mf.size(), (int)tmpbuf.size())); + + mf.read(&tmpbuf[0], tmpbuf.size()); + + DevicesMC[which]->WriteNV(&tmpbuf[0], 0, tmpbuf.size()); + DevicesMC[which]->ResetNVDirtyCount(); // There's no need to rewrite the file if it's the same data. + } + } + catch(MDFN_Error &e) + { + if(e.GetErrno() != ENOENT) + throw(e); + } +} + +void FrontIO::SaveMemcard(unsigned int which, const char *path) +{ + assert(which < 8); + + if(DevicesMC[which]->GetNVSize() && DevicesMC[which]->GetNVDirtyCount()) + { + FileWrapper mf(path, FileWrapper::MODE_WRITE); // TODO: MODE_WRITE_ATOMIC_OVERWRITE + std::vector tmpbuf; + + tmpbuf.resize(DevicesMC[which]->GetNVSize()); + + DevicesMC[which]->ReadNV(&tmpbuf[0], 0, tmpbuf.size()); + mf.write(&tmpbuf[0], tmpbuf.size()); + + mf.close(); // Call before resetting the NV dirty count! + + DevicesMC[which]->ResetNVDirtyCount(); + } +} + +bool FrontIO::RequireNoFrameskip(void) +{ + for(unsigned i = 0; i < 8; i++) + if(Devices[i]->RequireNoFrameskip()) + return(true); + + return(false); +} + +void FrontIO::GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock) +{ + Update(timestamp); + + for(unsigned i = 0; i < 8; i++) + { + pscpu_timestamp_t plts = Devices[i]->GPULineHook(line_timestamp, vsync, pixels, format, width, pix_clock_offset, pix_clock); + + if(i < 2) + { + irq10_pulse_ts[i] = plts; + + if(irq10_pulse_ts[i] <= timestamp) + { + irq10_pulse_ts[i] = PSX_EVENT_MAXTS; + IRQ_Assert(IRQ_PIO, true); + IRQ_Assert(IRQ_PIO, false); + } + } + } + + PSX_SetEventNT(PSX_EVENT_FIO, CalcNextEventTS(timestamp, 0x10000000)); +} + +static InputDeviceInfoStruct InputDeviceInfoPSXPort[] = +{ + // None + { + "none", + "none", + NULL, + NULL, + 0, + NULL + }, + + // Gamepad(SCPH-1080) + { + "gamepad", + "Digital Gamepad", + "PlayStation digital gamepad; SCPH-1080.", + NULL, + sizeof(Device_Gamepad_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_Gamepad_IDII, + }, + + // Dual Shock Gamepad(SCPH-1200) + { + "dualshock", + "DualShock", + "DualShock gamepad; SCPH-1200. Emulation in Mednafen includes the analog mode toggle button.", + NULL, + sizeof(Device_DualShock_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_DualShock_IDII, + }, + + // Dual Analog Gamepad(SCPH-1180), forced to analog mode. + { + "dualanalog", + "Dual Analog", + "Dual Analog gamepad; SCPH-1180. It is the predecessor/prototype to the more advanced DualShock. Emulated in Mednafen as forced to analog mode, and without rumble.", + NULL, + sizeof(Device_DualAnalog_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_DualAnalog_IDII, + }, + + + // Analog joystick(SCPH-1110), forced to analog mode - emulated through a tweak to dual analog gamepad emulation. + { + "analogjoy", + "Analog Joystick", + "Flight-game-oriented dual-joystick controller; SCPH-1110. Emulated in Mednafen as forced to analog mode.", + NULL, + sizeof(Device_AnalogJoy_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_AnalogJoy_IDII, + }, + + { + "mouse", + "Mouse", + NULL, + NULL, + sizeof(Device_Mouse_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_Mouse_IDII, + }, + + { + "negcon", + "neGcon", + "Namco's unconventional twisty racing-game-oriented gamepad; NPC-101.", + NULL, + sizeof(Device_neGcon_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_neGcon_IDII, + }, + + { + "guncon", + "GunCon", + "Namco's light gun; NPC-103.", + NULL, + sizeof(Device_GunCon_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_GunCon_IDII, + }, + + { + "justifier", + "Konami Justifier", + "Konami's light gun; SLUH-00017. Rumored to be wrought of the coagulated rage of all who tried to shoot The Dog. If the game you want to play supports the \"GunCon\", you should use that instead. NOTE: Currently does not work properly when on any of ports 1B-1D and 2B-2D.", + NULL, + sizeof(Device_Justifier_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_Justifier_IDII, + }, + +}; + +static const InputPortInfoStruct PortInfo[] = +{ + { "port1", "Port 1/1A", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port2", "Port 2/2A", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port3", "Port 1B", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port4", "Port 1C", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port5", "Port 1D", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port6", "Port 2B", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port7", "Port 2C", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, + { "port8", "Port 2D", sizeof(InputDeviceInfoPSXPort) / sizeof(InputDeviceInfoStruct), InputDeviceInfoPSXPort, "gamepad" }, +}; + +InputInfoStruct FIO_InputInfo = +{ + sizeof(PortInfo) / sizeof(InputPortInfoStruct), + PortInfo +}; + + +} diff --git a/mednafen/psx-0925/frontio.h b/mednafen/psx-0925/frontio.h new file mode 100644 index 00000000..bb80bbf5 --- /dev/null +++ b/mednafen/psx-0925/frontio.h @@ -0,0 +1,142 @@ +#ifndef __MDFN_PSX_FRONTIO_H +#define __MDFN_PSX_FRONTIO_H + +namespace MDFN_IEN_PSX +{ + +class InputDevice_Multitap; + +class InputDevice +{ + public: + + InputDevice(); + virtual ~InputDevice(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + + virtual bool RequireNoFrameskip(void); + virtual pscpu_timestamp_t GPULineHook(const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock); + + virtual void Update(const pscpu_timestamp_t timestamp); // Partially-implemented, don't rely on for timing any more fine-grained than a video frame for now. + virtual void ResetTS(void); + + // + // + // + virtual void SetAMCT(bool enabled); + virtual void SetCrosshairsColor(uint32 color); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); // Currently unused. + + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + // + // + virtual uint32 GetNVSize(void); + virtual void ReadNV(uint8 *buffer, uint32 offset, uint32 count); + virtual void WriteNV(const uint8 *buffer, uint32 offset, uint32 count); + + // + // Dirty count should be incremented on each call to a method this class that causes at least 1 write to occur to the + // nonvolatile memory(IE Clock() in the correct command phase, and WriteNV()). + // + virtual uint64 GetNVDirtyCount(void); + virtual void ResetNVDirtyCount(void); +}; + +class FrontIO +{ + public: + + FrontIO(bool emulate_memcards_[8], bool emulate_multitap_[2]); + ~FrontIO(); + + void Power(void); + void Write(pscpu_timestamp_t timestamp, uint32 A, uint32 V); + uint32 Read(pscpu_timestamp_t timestamp, uint32 A); + pscpu_timestamp_t CalcNextEventTS(pscpu_timestamp_t timestamp, int32 next_event); + pscpu_timestamp_t Update(pscpu_timestamp_t timestamp); + void ResetTS(void); + + bool RequireNoFrameskip(void); + void GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock); + + void UpdateInput(void); + void SetInput(unsigned int port, const char *type, void *ptr); + void SetAMCT(bool enabled); + void SetCrosshairsColor(unsigned port, uint32 color); + + uint64 GetMemcardDirtyCount(unsigned int which); + void LoadMemcard(unsigned int which, const char *path); + void SaveMemcard(unsigned int which, const char *path); //, bool force_save = false); + + private: + + void DoDSRIRQ(void); + void CheckStartStopPending(pscpu_timestamp_t timestamp, bool skip_event_set = false); + + void MapDevicesToPorts(void); + + bool emulate_memcards[8]; + bool emulate_multitap[2]; + + InputDevice *Ports[2]; + InputDevice *MCPorts[2]; + + InputDevice *DummyDevice; + InputDevice_Multitap *DevicesTap[2]; + + InputDevice *Devices[8]; + void *DeviceData[8]; + + InputDevice *DevicesMC[8]; + + // + // + // + + int32 ClockDivider; + + bool ReceivePending; + bool TransmitPending; + + bool ReceiveInProgress; + bool TransmitInProgress; + + bool ReceiveBufferAvail; + + uint8 ReceiveBuffer; + uint8 TransmitBuffer; + + int32 ReceiveBitCounter; + int32 TransmitBitCounter; + + uint16 Mode; + uint16 Control; + uint16 Baudrate; + + + bool istatus; + // + // + pscpu_timestamp_t irq10_pulse_ts[2]; + + int32 dsr_pulse_delay[4]; + int32 dsr_active_until_ts[4]; + int32 lastts; + // + // + bool amct_enabled; + uint32 chair_colors[8]; +}; + +extern InputInfoStruct FIO_InputInfo; + +} +#endif diff --git a/mednafen/psx-0925/gpu.cpp b/mednafen/psx-0925/gpu.cpp new file mode 100644 index 00000000..3b036588 --- /dev/null +++ b/mednafen/psx-0925/gpu.cpp @@ -0,0 +1,1365 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "timer.h" + +/* + TODO: + Test and clean up line, particularly polyline, drawing. + + "abe" transparency testing might be not correct, the transparency in regards to mask bit setting and evaluation may not be correct. + + Not everything is returned in the status port read yet(double check). + + "dfe" bit of drawing mode is probably not implemented 100% correctly. + + Initialize more stuff in the Power() function. + + Fix triangle span rendering order(it's bottom-to-up sometimes on the real thing, to avoid negative x step/increment values). +*/ + +/* + GPU display timing master clock is nominally 53.693182 MHz for NTSC PlayStations, and 53.203425 MHz for PAL PlayStations. + + Non-interlaced NTSC mode line timing notes(real-world times calculated via PS1 timer and math with nominal CPU clock value): + + 263 lines per frame + + ~16714.85 us per frame, average. + ~63.55456 us per line, average. + + Multiplying the results of counter 0 in pixel clock mode by the clock divider of the current dot clock mode/width gives a result that's slightly less + than expected; the dot clock divider is probably being reset each scanline. + + Non-interlaced PAL mode(but with an NTSC source clock in an NTSC PS1; calculated same way as NTSC values): + + 314 lines per frame + + ~19912.27 us per frame, average. + ~63.41486 us per line, average. + + FB X and Y display positions can be changed during active display; and Y display position appears to be treated as an offset to the current Y readout + position that gets reset around vsync time. + +*/ + +/* + Known problematic games to do regression testing on: + + Dukes of Hazzard: Racing For Home + Sensitive about the GPU busy status flag being set long enough; double-check if we ever make CPU emulation more timing-accurate( + the fix will likely just involve reducing the timing granularity for DMA and GPU updates). + + Final Fantasy 7 + WHERE DO I BEGIN?! (Currently broken as of Jan. 1, 2012) + + Pro Pinball (series) + Sensitive to correct interlace and draw line skipping emulation. + + Valkyrie Profile + Battle scenes will go all kaka with no graphics updates if GPU LL DMA completes too soon. + +*/ + +namespace MDFN_IEN_PSX +{ +//FILE *fp; + +static const int32 dither_table[4][4] = +{ + { -4, 0, -3, 1 }, + { 2, -2, 3, -1 }, + { -3, 1, -4, 0 }, + { 3, -1, 2, -2 }, +}; + +PS_GPU::PS_GPU(bool pal_clock_and_tv) : BlitterFIFO(0x20) // 0x10 on actual PS1 GPU, 0x20 here(see comment at top of gpu.h) // 0x10) +{ + HardwarePALType = pal_clock_and_tv; + + for(int y = 0; y < 4; y++) + for(int x = 0; x < 4; x++) + for(int v = 0; v < 512; v++) + { + int value = v + dither_table[y][x]; + + value >>= 3; + + if(value < 0) + value = 0; + + if(value > 0x1F) + value = 0x1F; + + DitherLUT[y][x][v] = value; + } + + if(HardwarePALType == false) // NTSC clock + { + GPUClockRatio = 103896; // 65536 * 53693181.818 / (44100 * 768) + } + else // PAL clock + { + GPUClockRatio = 102948; // 65536 * 53203425 / (44100 * 768) + } + + memset(RGB8SAT_Under, 0, sizeof(RGB8SAT_Under)); + + for(int i = 0; i < 256; i++) + RGB8SAT[i] = i; + + memset(RGB8SAT_Over, 0xFF, sizeof(RGB8SAT_Over)); +} + +PS_GPU::~PS_GPU() +{ + +} + +void PS_GPU::SoftReset(void) // Control command 0x00 +{ + DMAControl = 0; + + if(DrawTimeAvail < 0) + DrawTimeAvail = 0; + + BlitterFIFO.Flush(); + InCmd = INCMD_NONE; + + DisplayMode = 0; + DisplayOff = 1; + DisplayFB_XStart = 0; + DisplayFB_YStart = 0; + + HorizStart = 0; + HorizEnd = 0; + + VertStart = 0; + VertEnd = 0; +} + +void PS_GPU::Power(void) +{ + memset(GPURAM, 0, sizeof(GPURAM)); + + DMAControl = 0; + + ClipX0 = 0; + ClipY0 = 0; + ClipX1 = 1023; + ClipY1 = 1023; + + OffsX = 0; + OffsY = 0; + + dtd = false; + dfe = false; + + MaskSetOR = 0; + MaskEvalAND = 0; + + tww = 0; + twh = 0; + twx = 0; + twy = 0; + + RecalcTexWindowLUT(); + + TexPageX = 0; + TexPageY = 0; + SpriteFlip = 0; + + abr = 0; + TexMode = 0; + + BlitterFIFO.Flush(); + + InCmd = INCMD_NONE; + FBRW_X = 0; + FBRW_Y = 0; + FBRW_W = 0; + FBRW_H = 0; + FBRW_CurY = 0; + FBRW_CurX = 0; + + DisplayMode = 0; + DisplayOff = 1; + DisplayFB_XStart = 0; + DisplayFB_YStart = 0; + + HorizStart = 0; + HorizEnd = 0; + + VertStart = 0; + VertEnd = 0; + + // + // + // + DisplayFB_CurYOffset = 0; + DisplayFB_CurLineYReadout = 0; + DisplayHeightCounter = 0; + + + // TODO: factor out in a separate function. + LinesPerField = 263; + VisibleStartLine = 23; + + // + // + // + FrameInterlaced = false; + PALMode = false; + HeightMode = false; + scanline = 0; + field = 0; + field_atvs = 0; + PhaseChange = 0; + + // + // + // + DotClockCounter = 0; + GPUClockCounter = 0; + LineClockCounter = 3412 - 200; + LinePhase = 0; + + DrawTimeAvail = 0; + + lastts = 0; +} + +void PS_GPU::ResetTS(void) +{ + lastts = 0; +} + +#define COORD_FBS 20 +#define COORD_MF_INT(n) ((n) << COORD_FBS) + +static INLINE int32 COORD_GET_INT(int32 n) +{ + return(n >> COORD_FBS); +} + + +template +INLINE void PS_GPU::PlotPixel(int32 x, int32 y, uint16 fore_pix) +{ + y &= 511; // More Y precision bits than GPU RAM installed in (non-arcade, at least) Playstation hardware. + + if(BlendMode >= 0 && (fore_pix & 0x8000)) + { + uint16 bg_pix = GPURAM[y][x]; // Don't use bg_pix for mask evaluation, it's modified in blending code paths. + uint16 pix; // = fore_pix & 0x8000; + +/* + static const int32 tab[4][2] = + { + { 2, 2 }, + { 4, 4 }, + { 4, -4 }, + { 4, 1 } + }; +*/ + // Efficient 15bpp pixel math algorithms from blargg + switch(BlendMode) + { + case 0: + bg_pix |= 0x8000; + pix = ((fore_pix + bg_pix) - ((fore_pix ^ bg_pix) & 0x0421)) >> 1; + break; + + case 1: + { + bg_pix &= ~0x8000; + + uint32 sum = fore_pix + bg_pix; + uint32 carry = (sum - ((fore_pix ^ bg_pix) & 0x8421)) & 0x8420; + + pix = (sum - carry) | (carry - (carry >> 5)); + } + break; + + case 2: + { + bg_pix |= 0x8000; + fore_pix &= ~0x8000; + + uint32 diff = bg_pix - fore_pix + 0x108420; + uint32 borrow = (diff - ((bg_pix ^ fore_pix) & 0x108420)) & 0x108420; + + pix = (diff - borrow) & (borrow - (borrow >> 5)); + } + break; + + case 3: + { + bg_pix &= ~0x8000; + fore_pix = ((fore_pix >> 2) & 0x1CE7) | 0x8000; + + uint32 sum = fore_pix + bg_pix; + uint32 carry = (sum - ((fore_pix ^ bg_pix) & 0x8421)) & 0x8420; + + pix = (sum - carry) | (carry - (carry >> 5)); + } + break; + } + + if(!MaskEval_TA || !(GPURAM[y][x] & 0x8000)) + GPURAM[y][x] = (textured ? pix : (pix & 0x7FFF)) | MaskSetOR; + } + else + { + if(!MaskEval_TA || !(GPURAM[y][x] & 0x8000)) + GPURAM[y][x] = (textured ? fore_pix : (fore_pix & 0x7FFF)) | MaskSetOR; + } +} + +INLINE uint16 PS_GPU::ModTexel(uint16 texel, int32 r, int32 g, int32 b, const int32 dither_x, const int32 dither_y) +{ + uint16 ret = texel & 0x8000; + + ret |= DitherLUT[dither_y][dither_x][(((texel & 0x1F) * r) >> (5 - 1))] << 0; + ret |= DitherLUT[dither_y][dither_x][(((texel & 0x3E0) * g) >> (10 - 1))] << 5; + ret |= DitherLUT[dither_y][dither_x][(((texel & 0x7C00) * b) >> (15 - 1))] << 10; + + return(ret); +} + +template +INLINE uint16 PS_GPU::GetTexel(const uint32 clut_offset, int32 u_arg, int32 v_arg) +{ + uint32 u = TexWindowXLUT[u_arg]; + uint32 v = TexWindowYLUT[v_arg]; + uint32 fbtex_x = TexPageX + (u >> (2 - TexMode_TA)); + uint32 fbtex_y = TexPageY + v; + uint16 fbw = GPURAM[fbtex_y][fbtex_x & 1023]; + + if(TexMode_TA != 2) + { + if(TexMode_TA == 0) + fbw = (fbw >> ((u & 3) * 4)) & 0xF; + else + fbw = (fbw >> ((u & 1) * 8)) & 0xFF; + + fbw = GPURAM[(clut_offset >> 10) & 511][(clut_offset + fbw) & 1023]; + } + + return(fbw); +} + +INLINE bool PS_GPU::LineSkipTest(unsigned y) +{ + //DisplayFB_XStart >= OffsX && DisplayFB_YStart >= OffsY && + // ((y & 1) == (DisplayFB_CurLineYReadout & 1)) + + if((DisplayMode & 0x24) != 0x24) + return false; + + if(HeightMode && !dfe && ((y & 1) == ((DisplayFB_YStart + !field_atvs) & 1))/* && !DisplayOff*/) //&& (y >> 1) >= DisplayFB_YStart && (y >> 1) < (DisplayFB_YStart + (VertEnd - VertStart))) + return true; + + return false; +} + +#include "gpu_polygon.inc" +#include "gpu_sprite.inc" +#include "gpu_line.inc" + +// Special RAM write mode(16 pixels at a time), does *not* appear to use mask drawing environment settings. +void PS_GPU::Command_FBFill(const uint32 *cb) +{ + int32 r = cb[0] & 0xFF; + int32 g = (cb[0] >> 8) & 0xFF; + int32 b = (cb[0] >> 16) & 0xFF; + const uint16 fill_value = ((r >> 3) << 0) | ((g >> 3) << 5) | ((b >> 3) << 10); + + int32 destX = (cb[1] >> 0) & 0x3F0; + int32 destY = (cb[1] >> 16) & 0x3FF; + + int32 width = (((cb[2] >> 0) & 0x3FF) + 0xF) & ~0xF; + int32 height = (cb[2] >> 16) & 0x1FF; + + //printf("[GPU] FB Fill %d:%d w=%d, h=%d\n", destX, destY, width, height); + DrawTimeAvail -= 46; // Approximate + DrawTimeAvail -= ((width * height) >> 3) + (height * 9); + + for(int32 y = 0; y < height; y++) + { + const int32 d_y = (y + destY) & 511; + + if(LineSkipTest(d_y)) + continue; + + for(int32 x = 0; x < width; x++) + { + const int32 d_x = (x + destX) & 1023; + + GPURAM[d_y][d_x] = fill_value; + } + } + +} + +void PS_GPU::Command_FBCopy(const uint32 *cb) +{ + int32 sourceX = (cb[1] >> 0) & 0x3FF; + int32 sourceY = (cb[1] >> 16) & 0x3FF; + int32 destX = (cb[2] >> 0) & 0x3FF; + int32 destY = (cb[2] >> 16) & 0x3FF; + + int32 width = (cb[3] >> 0) & 0x3FF; + int32 height = (cb[3] >> 16) & 0x1FF; + + if(!width) + width = 0x400; + + if(!height) + height = 0x200; + + //printf("FB Copy: %d %d %d %d %d %d\n", sourceX, sourceY, destX, destY, width, height); + + DrawTimeAvail -= (width * height) * 2; + + for(int32 y = 0; y < height; y++) + { + for(int32 x = 0; x < width; x++) + { + int32 s_y = (y + sourceY) & 511; + int32 s_x = (x + sourceX) & 1023; + int32 d_y = (y + destY) & 511; + int32 d_x = (x + destX) & 1023; + + if(!(GPURAM[d_y][d_x] & MaskEvalAND)) + GPURAM[d_y][d_x] = GPURAM[s_y][s_x] | MaskSetOR; + } + } + +} + +void PS_GPU::Command_FBWrite(const uint32 *cb) +{ + assert(InCmd == INCMD_NONE); + + FBRW_X = (cb[1] >> 0) & 0x3FF; + FBRW_Y = (cb[1] >> 16) & 0x3FF; + + FBRW_W = (cb[2] >> 0) & 0x7FF; + FBRW_H = (cb[2] >> 16) & 0x3FF; + + if(FBRW_W > 0x400) + FBRW_W &= 0x3FF; + + if(FBRW_H > 0x200) + FBRW_H &= 0x1FF; + + FBRW_CurX = FBRW_X; + FBRW_CurY = FBRW_Y; + + if(FBRW_W != 0 && FBRW_H != 0) + InCmd = INCMD_FBWRITE; +} + +void PS_GPU::Command_FBRead(const uint32 *cb) +{ + assert(InCmd == INCMD_NONE); + + FBRW_X = (cb[1] >> 0) & 0x3FF; + FBRW_Y = (cb[1] >> 16) & 0x3FF; + + FBRW_W = (cb[2] >> 0) & 0x7FF; + FBRW_H = (cb[2] >> 16) & 0x3FF; + + if(FBRW_W > 0x400) + FBRW_W &= 0x3FF; + + if(FBRW_H > 0x200) + FBRW_H &= 0x1FF; + + FBRW_CurX = FBRW_X; + FBRW_CurY = FBRW_Y; + + if(FBRW_W != 0 && FBRW_H != 0) + InCmd = INCMD_FBREAD; +} + + +void PS_GPU::RecalcTexWindowLUT(void) +{ + const unsigned TexWindowX_AND = ~(tww << 3); + const unsigned TexWindowX_OR = (twx & tww) << 3; + + const unsigned TexWindowY_AND = ~(twh << 3); + const unsigned TexWindowY_OR = (twy & twh) << 3; + +// printf("TWX: 0x%02x, TWW: 0x%02x\n", twx, tww); +// printf("TWY: 0x%02x, TWH: 0x%02x\n", twy, twh); + + for(unsigned x = 0; x < 256; x++) + { + TexWindowXLUT[x] = (x & TexWindowX_AND) | TexWindowX_OR; + } + + for(unsigned y = 0; y < 256; y++) + { + TexWindowYLUT[y] = (y & TexWindowY_AND) | TexWindowY_OR; + } + + memset(TexWindowXLUT_Pre, TexWindowXLUT[0], sizeof(TexWindowXLUT_Pre)); + memset(TexWindowXLUT_Post, TexWindowXLUT[255], sizeof(TexWindowXLUT_Post)); + + memset(TexWindowYLUT_Pre, TexWindowYLUT[0], sizeof(TexWindowYLUT_Pre)); + memset(TexWindowYLUT_Post, TexWindowYLUT[255], sizeof(TexWindowYLUT_Post)); +} + +void PS_GPU::Command_DrawMode(const uint32 *cb) +{ + TexPageX = (*cb & 0xF) * 64; + TexPageY = (*cb & 0x10) * 16; + + SpriteFlip = *cb & 0x3000; + + abr = (*cb >> 5) & 0x3; + TexMode = (*cb >> 7) & 0x3; + + dtd = (*cb >> 9) & 1; + dfe = (*cb >> 10) & 1; + //printf("*******************DFE: %d -- scanline=%d\n", dfe, scanline); +} + +void PS_GPU::Command_TexWindow(const uint32 *cb) +{ + tww = (*cb & 0x1F); + twh = ((*cb >> 5) & 0x1F); + twx = ((*cb >> 10) & 0x1F); + twy = ((*cb >> 15) & 0x1F); + + RecalcTexWindowLUT(); +} + +void PS_GPU::Command_Clip0(const uint32 *cb) +{ + ClipX0 = *cb & 1023; + ClipY0 = (*cb >> 10) & 1023; +} + +void PS_GPU::Command_Clip1(const uint32 *cb) +{ + ClipX1 = *cb & 1023; + ClipY1 = (*cb >> 10) & 1023; +} + +void PS_GPU::Command_DrawingOffset(const uint32 *cb) +{ + OffsX = sign_x_to_s32(11, (*cb & 2047)); + OffsY = sign_x_to_s32(11, ((*cb >> 11) & 2047)); + + //fprintf(stderr, "[GPU] Drawing offset: %d(raw=%d) %d(raw=%d) -- %d\n", OffsX, *cb, OffsY, *cb >> 11, scanline); +} + +void PS_GPU::Command_MaskSetting(const uint32 *cb) +{ + //printf("Mask setting: %08x\n", *cb); + MaskSetOR = (*cb & 1) ? 0x8000 : 0x0000; + MaskEvalAND = (*cb & 2) ? 0x8000 : 0x0000; +} + +void PS_GPU::Command_ClearCache(const uint32 *cb) +{ + +} + +CTEntry PS_GPU::Commands[4][256] = +{ + #define BLENDMODE_MAC 0 + { + #include "gpu_command_table.inc" + }, + #undef BLENDMODE_MAC + + #define BLENDMODE_MAC 1 + { + #include "gpu_command_table.inc" + }, + #undef BLENDMODE_MAC + + #define BLENDMODE_MAC 2 + { + #include "gpu_command_table.inc" + }, + #undef BLENDMODE_MAC + + #define BLENDMODE_MAC 3 + { + #include "gpu_command_table.inc" + }, + #undef BLENDMODE_MAC +}; + +static uint64 PrimitiveCounter[256] = { 0 }; // Debug + +void PS_GPU::ProcessFIFO(void) +{ + if(!BlitterFIFO.CanRead()) + return; + + switch(InCmd) + { + default: + abort(); + break; + + case INCMD_NONE: + break; + + case INCMD_FBREAD: + puts("BOGUS SALAMANDERS, CAPTAIN!"); + return; + + case INCMD_FBWRITE: + { + uint32 InData = BlitterFIFO.ReadUnit(); + + for(int i = 0; i < 2; i++) + { + if(!(GPURAM[FBRW_CurY & 511][FBRW_CurX & 1023] & MaskEvalAND)) + GPURAM[FBRW_CurY & 511][FBRW_CurX & 1023] = InData | MaskSetOR; + + FBRW_CurX++; + if(FBRW_CurX == (FBRW_X + FBRW_W)) + { + FBRW_CurX = FBRW_X; + FBRW_CurY++; + if(FBRW_CurY == (FBRW_Y + FBRW_H)) + { + InCmd = INCMD_NONE; + break; // Break out of the for() loop. + } + } + InData >>= 16; + } + return; + } + break; + + case INCMD_QUAD: + { + if(DrawTimeAvail < 0) + return; + + const uint32 cc = InCmd_CC; + const CTEntry *command = &Commands[abr][cc]; + unsigned vl = 1 + (bool)(cc & 0x4) + (bool)(cc & 0x10); + uint32 CB[3]; + + if(BlitterFIFO.CanRead() >= vl) + { + for(unsigned i = 0; i < vl; i++) + { + CB[i] = BlitterFIFO.ReadUnit(); + } + + ((this)->*(command->func[TexMode | (MaskEvalAND ? 0x4 : 0x0)]))(CB); + } + return; + } + break; + + case INCMD_PLINE: + { + if(DrawTimeAvail < 0) + return; + + const uint32 cc = InCmd_CC; + const CTEntry *command = &Commands[abr][cc]; + unsigned vl = 1 + (bool)(InCmd_CC & 0x10); + uint32 CB[2]; + + if((BlitterFIFO.ReadUnit(true) & 0xF000F000) == 0x50005000) + { + BlitterFIFO.ReadUnit(); + InCmd = INCMD_NONE; + return; + } + + if(BlitterFIFO.CanRead() >= vl) + { + for(unsigned i = 0; i < vl; i++) + { + CB[i] = BlitterFIFO.ReadUnit(); + } + + ((this)->*(command->func[TexMode | (MaskEvalAND ? 0x4 : 0x0)]))(CB); + } + return; + } + break; + } + + const uint32 cc = BlitterFIFO.ReadUnit(true) >> 24; + const CTEntry *command = &Commands[0][cc]; + + if(DrawTimeAvail < 0 && !command->ss_cmd) + return; + + if(BlitterFIFO.CanRead() >= command->len) + { + uint32 CB[0x10]; + + for(unsigned i = 0; i < command->len; i++) + CB[i] = BlitterFIFO.ReadUnit(); + + if(!command->ss_cmd) + DrawTimeAvail -= 2; + + PrimitiveCounter[cc]++; + + if(!command->func[TexMode]) + { + //if(CB[0]) + // PSX_WARNING("[GPU] Unknown command: %08x, %d", CB[0], scanline); + } + else + { +#if 0 + PSX_WARNING("[GPU] Command: %08x %s %d %d %d", CB[0], command->name, command->len, scanline, DrawTimeAvail); + if(1) + { + printf("[GPU] "); + for(unsigned i = 0; i < command->len; i++) + printf("0x%08x ", CB[i]); + printf("\n"); + } +#endif + // A very very ugly kludge to support texture mode specialization. fixme/cleanup/SOMETHING in the future. + if(cc >= 0x20 && cc <= 0x3F && (cc & 0x4)) + { + uint32 tpage; + + tpage = CB[4 + ((cc >> 4) & 0x1)] >> 16; + + TexPageX = (tpage & 0xF) * 64; + TexPageY = (tpage & 0x10) * 16; + + SpriteFlip = tpage & 0x3000; + + abr = (tpage >> 5) & 0x3; + TexMode = (tpage >> 7) & 0x3; + } + + command = &Commands[abr][cc]; + + //int32 olddt = DrawTimeAvail; + ((this)->*(command->func[TexMode | (MaskEvalAND ? 0x4 : 0x0)]))(CB); + //printf("COMMAND: %08x -- %8d ---- scanline=%d -- adta=%8d\n", CB[0], DrawTimeAvail - olddt, scanline, DrawTimeAvail); + } + } +} + +INLINE void PS_GPU::WriteCB(uint32 InData) +{ + if(BlitterFIFO.CanRead() >= 0x10 && (InCmd != INCMD_NONE || (BlitterFIFO.CanRead() - 0x10) >= Commands[0][BlitterFIFO.ReadUnit(true) >> 24].fifo_fb_len)) + { + MDFN_DispMessage("GPU FIFO overflow!!!"); + fprintf(stderr, "GPU FIFO overflow!!!"); + return; + } + + BlitterFIFO.WriteUnit(InData); + ProcessFIFO(); +} + +void PS_GPU::Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + if(A & 4) // GP1 ("Control") + { + uint32 command = V >> 24; + + //fputc(1, fp); + //fwrite(&V, 1, 4, fp); + + + V &= 0x00FFFFFF; + + //PSX_WARNING("[GPU] Control command: %02x %06x %d", command, V, scanline); + + switch(command) + { + default: PSX_WARNING("[GPU] Unknown control command %02x - %06x", command, V); + break; + + case 0x00: // Reset GPU + SoftReset(); + break; + + case 0x01: // Reset command buffer + if(DrawTimeAvail < 0) + DrawTimeAvail = 0; + BlitterFIFO.Flush(); + InCmd = INCMD_NONE; + break; + + case 0x02: // Reset IRQ ??? + break; + + case 0x03: // Display enable + DisplayOff = V & 1; + break; + + case 0x04: // DMA Setup + DMAControl = V & 0x3; + break; + + case 0x05: // Start of display area in framebuffer + DisplayFB_XStart = V & 0x3FF; + DisplayFB_YStart = (V >> 10) & 0x1FF; + //printf("Xstart: %d -- Ystart: %d -- scanline=%d\n", DisplayFB_XStart, DisplayFB_YStart, scanline); + break; + + case 0x06: // Horizontal display range + HorizStart = V & 0xFFF; + HorizEnd = (V >> 12) & 0xFFF; + break; + + case 0x07: + VertStart = V & 0x3FF; + VertEnd = (V >> 10) & 0x3FF; // & 0x3FF or & 0x7FF? + //printf("VS: %04x\n", VertStart); + break; + + case 0x08: + DisplayMode = V & 0xFF; + //printf("DM: %02x, %d\n", V, scanline); + break; + + case 0x10: // GPU info(?) + switch(V & 0xF) + { + default: PSX_WARNING("[GPU] Unknown control command GPU info param - %01x", V & 0xF); + DataReadBuffer = 0; + //assert(0); + break; + + case 0x2: DataReadBuffer = (tww << 0) | (twh << 5) | (twx << 10) | (twy << 15); + break; + + case 0x3: DataReadBuffer = (ClipY0 << 10) | ClipX0; + break; + + case 0x4: DataReadBuffer = (ClipY1 << 10) | ClipX1; + break; + + case 0x5: + case 0x6: DataReadBuffer = (OffsX & 2047) | ((OffsY & 2047) << 11); + break; + + case 0x7: DataReadBuffer = 2; + break; + } + break; + + } + } + else // GP0 ("Data") + { + //uint32 command = V >> 24; + //printf("Meow command: %02x\n", command); + //assert(!(DMAControl & 2)); + WriteCB(V); + } +} + + +void PS_GPU::WriteDMA(uint32 V) +{ + WriteCB(V); +} + +uint32 PS_GPU::Read(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 ret = 0; + + if(A & 4) // Status + { + ret = (((DisplayMode << 1) & 0x7F) | ((DisplayMode >> 6) & 1)) << 16; + + ret |= DMAControl << 29; + + ret |= (DisplayFB_CurLineYReadout & 1) << 31; + + ret |= field << 13; + + if(DMAControl & 0x02) + ret |= 1 << 25; + + ret |= DisplayOff << 23; + + if(InCmd == INCMD_NONE && DrawTimeAvail >= 0 && BlitterFIFO.CanRead() == 0x00) // GPU idle bit. + ret |= 1 << 26; + + if(InCmd == INCMD_FBREAD) // Might want to more accurately emulate this in the future? + ret |= (1 << 27); + + ret |= CalcFIFOReadyBit() << 28; // FIFO has room bit? (kinda). + + // + // + ret |= TexPageX >> 6; + ret |= TexPageY >> 4; + ret |= abr << 5; + ret |= TexMode << 7; + + ret |= dtd << 9; + ret |= dfe << 10; + + if(MaskSetOR) + ret |= 1 << 11; + + if(MaskEvalAND) + ret |= 1 << 12; + } + else // "Data" + { + if(InCmd == INCMD_FBREAD) + { + DataReadBuffer = 0; + for(int i = 0; i < 2; i++) + { + DataReadBuffer |= GPURAM[FBRW_CurY & 511][FBRW_CurX & 1023] << (i * 16); + + FBRW_CurX++; + if(FBRW_CurX == (FBRW_X + FBRW_W)) + { + FBRW_CurX = FBRW_X; + FBRW_CurY++; + if(FBRW_CurY == (FBRW_Y + FBRW_H)) + { + InCmd = INCMD_NONE; + break; + } + } + } + } + + ret = DataReadBuffer; + } + + if(DMAControl & 2) + { + //PSX_WARNING("[GPU READ WHEN (DMACONTROL&2)] 0x%08x - ret=0x%08x, scanline=%d", A, ret, scanline); + } + + return(ret); +} + +INLINE void PS_GPU::ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift, bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x) +{ + if(bpp24) // 24bpp + { + for(int32 x = dx_start; x < dx_end; x++) + { + uint32 srcpix; + + srcpix = src[(fb_x >> 1) + 0] | (src[((fb_x >> 1) + 1) & 0x7FF] << 16); + srcpix >>= (fb_x & 1) * 8; + + dest[x] = (((srcpix >> 0) << out_Rshift) & (0xFF << out_Rshift)) | (((srcpix >> 8) << out_Gshift) & (0xFF << out_Gshift)) | + (((srcpix >> 16) << out_Bshift) & (0xFF << out_Bshift)); + + fb_x = (fb_x + 3) & 0x7FF; + } + } // 15bpp + else + { + for(int32 x = dx_start; x < dx_end; x++) + { + uint32 srcpix = src[fb_x >> 1]; + + //dest[x] = (((srcpix >> 0) << out_Rshift) & (0xFF << out_Rshift)) | (((srcpix >> 8) << out_Gshift) & (0xFF << out_Gshift)) | + // (((srcpix >> 16) << out_Bshift) & (0xFF << out_Bshift)); + dest[x] = OutputLUT[srcpix & 0x7FFF]; + + fb_x = (fb_x + 2) & 0x7FF; + } + } + +} + + +template +void PS_GPU::ReorderRGB(bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x) +{ + ReorderRGB_Var(out_Rshift, out_Gshift, out_Bshift, bpp24, src, dest, dx_start, dx_end, fb_x); +} + +pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp) +{ + static const uint32 DotClockRatios[5] = { 10, 8, 5, 4, 7 }; + const uint32 dmc = (DisplayMode & 0x40) ? 4 : (DisplayMode & 0x3); + const uint32 dmw = 2720 / DotClockRatios[dmc]; // Must be <= 768 + + int32 sys_clocks = sys_timestamp - lastts; + int32 gpu_clocks; + + //printf("GPUISH: %d\n", sys_timestamp - lastts); + + if(!sys_clocks) + goto TheEnd; + + DrawTimeAvail += sys_clocks << 1; + + if(DrawTimeAvail > 256) + DrawTimeAvail = 256; + + ProcessFIFO(); + + //puts("GPU Update Start"); + + GPUClockCounter += (uint64)sys_clocks * GPUClockRatio; + + gpu_clocks = GPUClockCounter >> 16; + GPUClockCounter -= gpu_clocks << 16; + + while(gpu_clocks > 0) + { + int32 chunk_clocks = gpu_clocks; + int32 dot_clocks; + + if(chunk_clocks > LineClockCounter) + { + //printf("Chunk: %u, LCC: %u\n", chunk_clocks, LineClockCounter); + chunk_clocks = LineClockCounter; + } + + gpu_clocks -= chunk_clocks; + LineClockCounter -= chunk_clocks; + + DotClockCounter += chunk_clocks; + dot_clocks = DotClockCounter / DotClockRatios[DisplayMode & 0x3]; + DotClockCounter -= dot_clocks * DotClockRatios[DisplayMode & 0x3]; + + TIMER_AddDotClocks(dot_clocks); + + + if(!LineClockCounter) + { + PSX_SetEventNT(PSX_EVENT_TIMER, TIMER_Update(sys_timestamp)); // We could just call this at the top of GPU_Update(), but do it here for slightly less CPU usage(presumably). + + LinePhase = (LinePhase + 1) & 1; + + if(LinePhase) + { + TIMER_SetHRetrace(true); + LineClockCounter = 200; + TIMER_ClockHRetrace(); + } + else + { + TIMER_SetHRetrace(false); + if(PALMode) + LineClockCounter = 3405 - 200; + else + LineClockCounter = 3412 + PhaseChange - 200; + + scanline = (scanline + 1) % LinesPerField; + PhaseChange = !PhaseChange; + + if(scanline == (LinesPerField - 1)) + { + //printf("Exit: scanline=%u, st=%u\n", scanline, sys_timestamp); + PSX_RequestMLExit(); + } + +#ifdef WANT_DEBUGGER + DBG_GPUScanlineHook(scanline); +#endif + + // printf("[GPU] DTA scanline=%3d --- %8d\n", scanline, DrawTimeAvail); + + if(scanline == 0) + { +#if 0 + printf("Primitive Counts for previous frame:\n"); + for(unsigned i = 0; i < 256; i++) + if(PrimitiveCounter[i]) + { + printf("0x%02x: %8u\n", i, (unsigned int)PrimitiveCounter[i]); + } + + printf("\n"); + memset(PrimitiveCounter, 0, sizeof(PrimitiveCounter)); +#endif + + IRQ_Assert(IRQ_VSYNC, true); + IRQ_Assert(IRQ_VSYNC, false); + } + + // Might not be right: + if(scanline == 0) + TIMER_SetVBlank(true); + else if(scanline == VisibleStartLine) + TIMER_SetVBlank(false); + + + if(scanline == 0) + { + field_atvs = field; + DisplayHeightCounter = 0; + + PALMode = (bool)(DisplayMode & 0x08); + + if(PALMode) // PAL + VisibleStartLine = 26; + else // NTSC + VisibleStartLine = 22; + + FrameInterlaced = (bool)(DisplayMode & 0x20); + HeightMode = (bool)(DisplayMode & 0x04) && FrameInterlaced; + + if(espec) + { + if(PALMode != HardwarePALType) + { + const uint32 black = surface->MakeColor(0, 0, 0); + + DisplayRect->w = 384; + DisplayRect->h = (HardwarePALType ? 288 : 240); + + for(int32 y = 0; y < DisplayRect->h; y++) + { + uint32 *dest = surface->pixels + y * surface->pitch32; + + LineWidths[y].x = 0; + LineWidths[y].w = 384; + + for(int32 x = 0; x < 384; x++) + { + dest[x] = black; + } + } + char buffer[256]; + + trio_snprintf(buffer, sizeof(buffer), _("VIDEO STANDARD MISMATCH")); +#ifndef __LIBRETRO__ + DrawTextTrans(surface->pixels + ((DisplayRect->h / 2) - (13 / 2)) * surface->pitch32, surface->pitch32 << 2, DisplayRect->w, (UTF8*)buffer, + surface->MakeColor(0x00, 0xFF, 0x00), true, MDFN_FONT_6x13_12x13); +#endif + } + else + { + espec->InterlaceOn = FrameInterlaced; + espec->InterlaceField = !field; + DisplayRect->h = (HardwarePALType ? 288 : 240) << FrameInterlaced; + } + } + + DisplayFB_CurYOffset = 0; + } + + const uint32 VS_Adjust = 7; //PALMode ? (34 - 6) : 7; + + if(scanline == (5U + field_atvs)) + { + if(FrameInterlaced) + { + skip = false; + field = !field; + + if(PALMode) // PAL + LinesPerField = 313 - field; + else // NTSC + LinesPerField = 263 - field; + } + else + { + field = 0; // May not be correct. + + if(PALMode) // PAL + LinesPerField = 314; + else // NTSC + LinesPerField = 263; + } + } + + if(scanline == (VertStart + VS_Adjust)) + { + DisplayHeightCounter = (VertEnd - VertStart); + + // Note to self: X-Men Mutant Academy relies on this being set on the proper scanline in 480i mode(otherwise it locks up on startup). + if(HeightMode) + DisplayFB_CurYOffset = field; + + //printf("%d\n", DisplayFB_CurYOffset); + } + + // Needs to occur even in vblank. + DisplayFB_CurLineYReadout = (DisplayFB_YStart + DisplayFB_CurYOffset) & 0x1FF; + + if(scanline >= VisibleStartLine && scanline < (VisibleStartLine + (HardwarePALType ? 288 : 240)) && !skip && espec && PALMode == HardwarePALType) + { + uint32 *dest; // = surface->pixels + (scanline - VisibleStartLine) * surface->pitch32; + int32 dest_line; + int32 fb_x = DisplayFB_XStart * 2; + int32 dx_start = HorizStart, dx_end = HorizEnd; + + dest_line = ((scanline - VisibleStartLine) << FrameInterlaced) + field; + dest = surface->pixels + dest_line * surface->pitch32; + + if(dx_end < dx_start) + dx_end = dx_start; + + dx_start = dx_start / DotClockRatios[dmc]; + dx_end = dx_end / DotClockRatios[dmc]; + + dx_start -= 528 / DotClockRatios[dmc]; + dx_end -= 528 / DotClockRatios[dmc]; + + if(dx_start < 0) + { + fb_x -= dx_start * ((DisplayMode & 0x10) ? 3 : 2); + fb_x &= 0x7FF; //0x3FF; + dx_start = 0; + } + + if((uint32)dx_end > dmw) + dx_end = dmw; + + if(!DisplayHeightCounter || DisplayOff) + dx_start = dx_end = 0; + + // TODO, but there are problems with this, as not all blitter busy cycles(crudely abstracted with DrawTimeAvail) are GPU RAM access cycles. + // Also, it shouldn't be here per-se, since this code won't be all if we're frameskipping or there's a video standard mismatch + //DrawTimeAvail -= (dx_end - dx_start) + ((DisplayMode & 0x10) ? ((dx_end - dx_start + 1) >> 1) : 0); + + LineWidths[dest_line].x = 0; + LineWidths[dest_line].w = dmw; + + { + const uint16 *src = GPURAM[DisplayFB_CurLineYReadout]; + const uint32 black = surface->MakeColor(0, 0, 0); + + for(int32 x = 0; x < dx_start; x++) + dest[x] = black; + + //printf("%d %d %d - %d %d\n", scanline, dx_start, dx_end, HorizStart, HorizEnd); + if(surface->format.Rshift == 0 && surface->format.Gshift == 8 && surface->format.Bshift == 16) + ReorderRGB<0, 8, 16>(DisplayMode & 0x10, src, dest, dx_start, dx_end, fb_x); + else if(surface->format.Rshift == 8 && surface->format.Gshift == 16 && surface->format.Bshift == 24) + ReorderRGB<8, 16, 24>(DisplayMode & 0x10, src, dest, dx_start, dx_end, fb_x); + else if(surface->format.Rshift == 16 && surface->format.Gshift == 8 && surface->format.Bshift == 0) + ReorderRGB<16, 8, 0>(DisplayMode & 0x10, src, dest, dx_start, dx_end, fb_x); + else if(surface->format.Rshift == 24 && surface->format.Gshift == 16 && surface->format.Bshift == 8) + ReorderRGB<24, 16, 8>(DisplayMode & 0x10, src, dest, dx_start, dx_end, fb_x); + else + ReorderRGB_Var(surface->format.Rshift, surface->format.Gshift, surface->format.Bshift, DisplayMode & 0x10, src, dest, dx_start, dx_end, fb_x); + + for(uint32 x = dx_end; x < dmw; x++) + dest[x] = black; + } + + //if(scanline == 64) + // printf("%u\n", sys_timestamp - ((uint64)gpu_clocks * 65536) / GPUClockRatio); + + PSX_GPULineHook(sys_timestamp, sys_timestamp - ((uint64)gpu_clocks * 65536) / GPUClockRatio, scanline == 0, dest, &surface->format, dmw, (528 - 146) / DotClockRatios[dmc], (HardwarePALType ? 53203425 : 53693182) / DotClockRatios[dmc]); + } + else + { + PSX_GPULineHook(sys_timestamp, sys_timestamp - ((uint64)gpu_clocks * 65536) / GPUClockRatio, scanline == 0, NULL, &surface->format, 0, 0, 0); + } + + if(DisplayHeightCounter) + { + if(HeightMode) + DisplayFB_CurYOffset = (DisplayFB_CurYOffset + 2) & 0x1FF; + else + DisplayFB_CurYOffset = (DisplayFB_CurYOffset + 1) & 0x1FF; + + DisplayHeightCounter--; + } + } + } + } + + //puts("GPU Update End"); + + TheEnd: + lastts = sys_timestamp; + + { + int32 next_dt = LineClockCounter; + + next_dt = (((int64)next_dt << 16) - GPUClockCounter + GPUClockRatio - 1) / GPUClockRatio; + + next_dt = std::max(1, next_dt); + next_dt = std::min(128, next_dt); + + //printf("%d\n", next_dt); + + return(sys_timestamp + next_dt); + } +} + +void PS_GPU::StartFrame(EmulateSpecStruct *espec_arg) +{ + if(!espec_arg) + { + espec = NULL; + surface = NULL; + DisplayRect = NULL; + LineWidths = NULL; + skip = true; + return; + } + + espec = espec_arg; + + surface = espec->surface; + DisplayRect = &espec->DisplayRect; + LineWidths = espec->LineWidths; + skip = espec->skip; + + DisplayRect->x = 0; + DisplayRect->y = 0; + DisplayRect->w = 256; + DisplayRect->h = 240; + + // Clear ~0 state. + LineWidths[0].x = LineWidths[0].w = 0; + + for(int i = 0; i < 240; i++) + { + LineWidths[i].x = 0; + LineWidths[i].w = 0; + } + + if(espec->VideoFormatChanged) + { + for(int rc = 0; rc < 0x8000; rc++) + { + uint32 r, g, b; + + r = ((rc >> 0) & 0x1F) * 255 / 31; + g = ((rc >> 5) & 0x1F) * 255 / 31; + b = ((rc >> 10) & 0x1F) * 255 / 31; + OutputLUT[rc] = espec->surface->format.MakeColor(r, g, b, 0); + } + } +} + +} diff --git a/mednafen/psx-0925/gpu.h b/mednafen/psx-0925/gpu.h new file mode 100644 index 00000000..1b9292b0 --- /dev/null +++ b/mednafen/psx-0925/gpu.h @@ -0,0 +1,325 @@ +// WARNING WARNING WARNING: ONLY use CanRead() method of BlitterFIFO, and NOT CanWrite(), since the FIFO is larger than the actual PS1 GPU FIFO to accommodate +// our lack of fancy superscalarish command sequencer. + +#ifndef __MDFN_PSX_GPU_H +#define __MDFN_PSX_GPU_H + +#include "../cdrom/SimpleFIFO.h" + +namespace MDFN_IEN_PSX +{ + +class PS_GPU; + +struct CTEntry +{ + uint8 len; + uint8 fifo_fb_len; + bool ss_cmd; + const char *name; + void (PS_GPU::*func[8])(const uint32 *cb); +}; + +struct tri_vertex +{ + int32 x, y; + int32 u, v; + int32 r, g, b; +}; + +struct i_group; +struct i_deltas; + +struct line_point +{ + int32 x, y; + uint8 r, g, b; +}; + +class PS_GPU +{ + public: + + PS_GPU(bool pal_clock_and_tv); + ~PS_GPU(); + + void Power(void); + + void ResetTS(void); + + void StartFrame(EmulateSpecStruct *espec); + + pscpu_timestamp_t Update(const pscpu_timestamp_t timestamp); + + void Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); + + INLINE bool CalcFIFOReadyBit(void) + { + if(InCmd & (INCMD_PLINE | INCMD_QUAD)) + return(false); + + if(BlitterFIFO.CanRead() == 0) + return(true); + + if(InCmd & (INCMD_FBREAD | INCMD_FBWRITE)) + return(false); + + if(BlitterFIFO.CanRead() >= Commands[0][BlitterFIFO.ReadUnit(true) >> 24].fifo_fb_len) + return(false); + + return(true); + } + + INLINE bool DMACanWrite(void) + { + return CalcFIFOReadyBit(); + } + + INLINE void AbortDMA(void) + { + BlitterFIFO.Flush(); + InCmd = INCMD_NONE; + } + + void WriteDMA(uint32 V); + + uint32 Read(const pscpu_timestamp_t timestamp, uint32 A); + + inline int32 GetScanlineNum(void) + { + return(scanline); + } + + INLINE uint16 PeekRAM(uint32 A) + { + return(GPURAM[(A >> 10) & 0x1FF][A & 0x3FF]); + } + + INLINE void PokeRAM(uint32 A, uint16 V) + { + GPURAM[(A >> 10) & 0x1FF][A & 0x3FF] = V; + } + + private: + + void ProcessFIFO(void); + void WriteCB(uint32 data); + void SoftReset(void); + + // Y, X + uint16 GPURAM[512][1024]; + + uint32 DMAControl; + + // + // Drawing stuff + // + //int32 TexPageX; // 0, 64, 128, 192, etc up to 960 + //int32 TexPageY; // 0 or 256 + //uint32 abr; // Semi-transparency mode(0~3) + //bool dtd; // Dithering enable + + int32 ClipX0; + int32 ClipY0; + int32 ClipX1; + int32 ClipY1; + + int32 OffsX; + int32 OffsY; + + bool dtd; + bool dfe; + + uint32 MaskSetOR; + uint32 MaskEvalAND; + + uint8 tww, twh, twx, twy; + struct + { + uint8 TexWindowXLUT_Pre[16]; + uint8 TexWindowXLUT[256]; + uint8 TexWindowXLUT_Post[16]; + }; + + struct + { + uint8 TexWindowYLUT_Pre[16]; + uint8 TexWindowYLUT[256]; + uint8 TexWindowYLUT_Post[16]; + }; + void RecalcTexWindowLUT(void); + + int32 TexPageX; + int32 TexPageY; + + uint32 SpriteFlip; + + uint32 abr; + uint32 TexMode; + + struct + { + uint8 RGB8SAT_Under[256]; + uint8 RGB8SAT[256]; + uint8 RGB8SAT_Over[256]; + }; + + uint8 DitherLUT[4][4][512]; // Y, X, 8-bit source value(256 extra for saturation) + + bool LineSkipTest(unsigned y); + + template + void PlotPixel(int32 x, int32 y, uint16 pix); + + template + uint16 GetTexel(uint32 clut_offset, int32 u, int32 v); + + uint16 ModTexel(uint16 texel, int32 r, int32 g, int32 b, const int32 dither_x, const int32 dither_y); + + template + void DrawSpan(int y, uint32 clut_offset, const int32 x_start, const int32 x_bound, const int32 bv_x, i_group ig, const i_deltas &idl); + + template + void DrawTriangle(tri_vertex *vertices, uint32 clut); + + template + void Command_DrawPolygon(const uint32 *cb); + + template + void DrawSprite(int32 x_arg, int32 y_arg, int32 w, int32 h, uint8 u_arg, uint8 v_arg, uint32 color, uint32 clut_offset); + + template + void Command_DrawSprite(const uint32 *cb); + + template + void DrawLine(line_point *vertices); + + template + void Command_DrawLine(const uint32 *cb); + + void Command_ClearCache(const uint32 *cb); + + void Command_FBFill(const uint32 *cb); + void Command_FBCopy(const uint32 *cb); + void Command_FBWrite(const uint32 *cb); + void Command_FBRead(const uint32 *cb); + + void Command_DrawMode(const uint32 *cb); + void Command_TexWindow(const uint32 *cb); + void Command_Clip0(const uint32 *cb); + void Command_Clip1(const uint32 *cb); + void Command_DrawingOffset(const uint32 *cb); + void Command_MaskSetting(const uint32 *cb); + + static CTEntry Commands[4][256]; + + SimpleFIFO BlitterFIFO; + + uint32 DataReadBuffer; + + // + // + // + // Powers of 2 for faster multiple equality testing(just for multi-testing; InCmd itself will only contain 0, or a power of 2). + enum + { + INCMD_NONE = 0, + INCMD_PLINE = (1 << 0), + INCMD_QUAD = (1 << 1), + INCMD_FBWRITE = (1 << 2), + INCMD_FBREAD = (1 << 3) + }; + uint8 InCmd; + uint8 InCmd_CC; + + tri_vertex InQuad_F3Vertices[3]; + uint32 InQuad_clut; + + line_point InPLine_PrevPoint; + + uint32 FBRW_X; + uint32 FBRW_Y; + uint32 FBRW_W; + uint32 FBRW_H; + uint32 FBRW_CurY; + uint32 FBRW_CurX; + + // + // Display Parameters + // + uint32 DisplayMode; + + bool DisplayOff; + uint32 DisplayFB_XStart; + uint32 DisplayFB_YStart; + + uint32 HorizStart; + uint32 HorizEnd; + + uint32 VertStart; + uint32 VertEnd; + + // + // Display work vars + // +/* + uint32 DisplayMode_Latch; + + bool DisplayOff_Latch; + uint32 DisplayFB_XStart_Latch; + uint32 DisplayFB_YStart_Latch; + + uint32 HorizStart_Latch; + uint32 HorizEnd_Latch; + + uint32 VertStart_Latch; + uint32 VertEnd_Latch; +*/ + uint32 DisplayFB_CurYOffset; + uint32 DisplayFB_CurLineYReadout; + + uint32 DisplayHeightCounter; + + // + // + // + uint32 LinesPerField; + uint32 VisibleStartLine; + bool FrameInterlaced; + bool PALMode; + bool HeightMode; + uint32 scanline; + bool field; + bool field_atvs; + bool PhaseChange; + + uint32 DotClockCounter; + + uint64 GPUClockCounter; + uint32 GPUClockRatio; + int32 LineClockCounter; + int32 LinePhase; + + int32 DrawTimeAvail; + + pscpu_timestamp_t lastts; + + // + // + // + EmulateSpecStruct *espec; + MDFN_Surface *surface; + MDFN_Rect *DisplayRect; + MDFN_Rect *LineWidths; + bool skip; + bool HardwarePALType; + + uint32 OutputLUT[32768]; + void ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift, bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x); + + template + void ReorderRGB(bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x) NO_INLINE; +}; + +} +#endif diff --git a/mednafen/psx-0925/gpu_command_table.inc b/mednafen/psx-0925/gpu_command_table.inc new file mode 100644 index 00000000..9e71da27 --- /dev/null +++ b/mednafen/psx-0925/gpu_command_table.inc @@ -0,0 +1,195 @@ +#define POLY_HELPER_SUB(cv, tm, mam) \ + &PS_GPU::Command_DrawPolygon<3 + ((cv & 0x8) >> 3), ((cv & 0x10) >> 4), ((cv & 0x4) >> 2), ((cv & 0x2) >> 1) ? BLENDMODE_MAC : -1, ((cv & 1) ^ 1) & ((cv & 0x4) >> 2), tm, mam > + +#define POLY_HELPER(cv) { 1 + (3 /*+ ((cv & 0x8) >> 3)*/) * ( 1 + ((cv & 0x4) >> 2) + ((cv & 0x10) >> 4) ) - ((cv & 0x10) >> 4), \ + 1, false, "Polygon", { POLY_HELPER_SUB(cv, ((cv & 0x4) ? 0 : 0), 0), POLY_HELPER_SUB(cv, ((cv & 0x4) ? 1 : 0), 0), \ + POLY_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 0), POLY_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 0), \ + POLY_HELPER_SUB(cv, ((cv & 0x4) ? 0 : 0), 1), POLY_HELPER_SUB(cv, ((cv & 0x4) ? 1 : 0), 1), \ + POLY_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 1), POLY_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 1), \ + } } + +// +// + +#define SPR_HELPER_SUB(cv, tm, mam) &PS_GPU::Command_DrawSprite<(cv >> 3) & 0x3, ((cv & 0x4) >> 2), ((cv & 0x2) >> 1) ? BLENDMODE_MAC : -1, ((cv & 1) ^ 1) & ((cv & 0x4) >> 2), tm, mam> + +#define SPR_HELPER(cv) { 2 + ((cv & 0x4) >> 2) + ((cv & 0x18) ? 0 : 1), 2 | ((cv & 0x4) >> 2) | ((cv & 0x18) ? 0 : 1), false, "Sprite", { \ + SPR_HELPER_SUB(cv, ((cv & 0x4) ? 0 : 0), 0), SPR_HELPER_SUB(cv, ((cv & 0x4) ? 1 : 0), 0), \ + SPR_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 0), SPR_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 0), \ + SPR_HELPER_SUB(cv, ((cv & 0x4) ? 0 : 0), 1), SPR_HELPER_SUB(cv, ((cv & 0x4) ? 1 : 0), 1), \ + SPR_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 1), SPR_HELPER_SUB(cv, ((cv & 0x4) ? 2 : 0), 1), \ + } } + +// +// + +#define LINE_HELPER_SUB(cv, mam) &PS_GPU::Command_DrawLine<((cv & 0x08) >> 3), ((cv & 0x10) >> 4), ((cv & 0x2) >> 1) ? BLENDMODE_MAC : -1, mam> + +#define LINE_HELPER(cv) { 3 + ((cv & 0x10) >> 4), 1, false, "Line", \ + { LINE_HELPER_SUB(cv, 0), LINE_HELPER_SUB(cv, 0), LINE_HELPER_SUB(cv, 0), LINE_HELPER_SUB(cv, 0), \ + LINE_HELPER_SUB(cv, 1), LINE_HELPER_SUB(cv, 1), LINE_HELPER_SUB(cv, 1), LINE_HELPER_SUB(cv, 1), } } + +// +// + +#define OTHER_HELPER(arg_cs, arg_fbcs, arg_ss, arg_name, arg_ptr) { arg_cs, arg_fbcs, arg_ss, arg_name, { arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr, arg_ptr } } + +#define NULLCMD() { 1, 1, true, NULL, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } } + + + /* 0x00 */ + NULLCMD(), + OTHER_HELPER(1, 2, false, "Clear Cache", &PS_GPU::Command_ClearCache), + OTHER_HELPER(3, 3, false, "FB Fill", &PS_GPU::Command_FBFill), + + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0x10 */ + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0x20 */ + POLY_HELPER(0x20), + POLY_HELPER(0x21), + POLY_HELPER(0x22), + POLY_HELPER(0x23), + POLY_HELPER(0x24), + POLY_HELPER(0x25), + POLY_HELPER(0x26), + POLY_HELPER(0x27), + POLY_HELPER(0x28), + POLY_HELPER(0x29), + POLY_HELPER(0x2a), + POLY_HELPER(0x2b), + POLY_HELPER(0x2c), + POLY_HELPER(0x2d), + POLY_HELPER(0x2e), + POLY_HELPER(0x2f), + POLY_HELPER(0x30), + POLY_HELPER(0x31), + POLY_HELPER(0x32), + POLY_HELPER(0x33), + POLY_HELPER(0x34), + POLY_HELPER(0x35), + POLY_HELPER(0x36), + POLY_HELPER(0x37), + POLY_HELPER(0x38), + POLY_HELPER(0x39), + POLY_HELPER(0x3a), + POLY_HELPER(0x3b), + POLY_HELPER(0x3c), + POLY_HELPER(0x3d), + POLY_HELPER(0x3e), + POLY_HELPER(0x3f), + + LINE_HELPER(0x40), + LINE_HELPER(0x41), + LINE_HELPER(0x42), + LINE_HELPER(0x43), + LINE_HELPER(0x44), + LINE_HELPER(0x45), + LINE_HELPER(0x46), + LINE_HELPER(0x47), + LINE_HELPER(0x48), + LINE_HELPER(0x49), + LINE_HELPER(0x4a), + LINE_HELPER(0x4b), + LINE_HELPER(0x4c), + LINE_HELPER(0x4d), + LINE_HELPER(0x4e), + LINE_HELPER(0x4f), + LINE_HELPER(0x50), + LINE_HELPER(0x51), + LINE_HELPER(0x52), + LINE_HELPER(0x53), + LINE_HELPER(0x54), + LINE_HELPER(0x55), + LINE_HELPER(0x56), + LINE_HELPER(0x57), + LINE_HELPER(0x58), + LINE_HELPER(0x59), + LINE_HELPER(0x5a), + LINE_HELPER(0x5b), + LINE_HELPER(0x5c), + LINE_HELPER(0x5d), + LINE_HELPER(0x5e), + LINE_HELPER(0x5f), + + SPR_HELPER(0x60), + SPR_HELPER(0x61), + SPR_HELPER(0x62), + SPR_HELPER(0x63), + SPR_HELPER(0x64), + SPR_HELPER(0x65), + SPR_HELPER(0x66), + SPR_HELPER(0x67), + SPR_HELPER(0x68), + SPR_HELPER(0x69), + SPR_HELPER(0x6a), + SPR_HELPER(0x6b), + SPR_HELPER(0x6c), + SPR_HELPER(0x6d), + SPR_HELPER(0x6e), + SPR_HELPER(0x6f), + SPR_HELPER(0x70), + SPR_HELPER(0x71), + SPR_HELPER(0x72), + SPR_HELPER(0x73), + SPR_HELPER(0x74), + SPR_HELPER(0x75), + SPR_HELPER(0x76), + SPR_HELPER(0x77), + SPR_HELPER(0x78), + SPR_HELPER(0x79), + SPR_HELPER(0x7a), + SPR_HELPER(0x7b), + SPR_HELPER(0x7c), + SPR_HELPER(0x7d), + SPR_HELPER(0x7e), + SPR_HELPER(0x7f), + + /* 0x80 */ + OTHER_HELPER(4, 2, false, "FB Copy", &PS_GPU::Command_FBCopy), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0x90 */ + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0xA0 */ + OTHER_HELPER(3, 2, false, "FB Write", &PS_GPU::Command_FBWrite), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0xB0 */ + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0xC0 */ + OTHER_HELPER(3, 2, false, "FB Read", &PS_GPU::Command_FBRead), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0xD0 */ + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0xE0 */ + + NULLCMD(), + OTHER_HELPER(1, 2, false, "Draw mode settings", &PS_GPU::Command_DrawMode), + OTHER_HELPER(1, 2, false, "Texture window settings", &PS_GPU::Command_TexWindow), + OTHER_HELPER(1, 1, true, "Drawing area top left", &PS_GPU::Command_Clip0), + OTHER_HELPER(1, 1, true, "Drawing area bottom right", &PS_GPU::Command_Clip1), + OTHER_HELPER(1, 1, true, "Drawing offset", &PS_GPU::Command_DrawingOffset), + OTHER_HELPER(1, 2, false, "Mask settings", &PS_GPU::Command_MaskSetting), + + NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + + /* 0xF0 */ + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), NULLCMD(), + diff --git a/mednafen/psx-0925/gpu_line.inc b/mednafen/psx-0925/gpu_line.inc new file mode 100644 index 00000000..4a419313 --- /dev/null +++ b/mednafen/psx-0925/gpu_line.inc @@ -0,0 +1,249 @@ +struct line_fxp_coord +{ + int64 x, y; + int32 r, g, b; +}; + +struct line_fxp_step +{ + int64 dx_dk, dy_dk; + int32 dr_dk, dg_dk, db_dk; +}; + +enum { Line_XY_FractBits = 32 }; +enum { Line_RGB_FractBits = 12 }; + +template +static INLINE void LinePointToFXPCoord(const line_point &point, const line_fxp_step &step, line_fxp_coord &coord) +{ + coord.x = ((int64)point.x << Line_XY_FractBits) | (1LL << (Line_XY_FractBits - 1)); + coord.y = ((int64)point.y << Line_XY_FractBits) | (1LL << (Line_XY_FractBits - 1)); + + if(goraud) + { + coord.r = (point.r << Line_RGB_FractBits) | (1 << (Line_RGB_FractBits - 1)); + coord.g = (point.g << Line_RGB_FractBits) | (1 << (Line_RGB_FractBits - 1)); + coord.b = (point.b << Line_RGB_FractBits) | (1 << (Line_RGB_FractBits - 1)); + } + + // Not sure if this is correct or just roughly corresponds to behavior of real system(need more testing): + if(step.dx_dk < 0) + coord.x--; + + if(step.dy_dk < 0) + coord.y--; + + if(step.dr_dk < 0) + coord.r--; + + if(step.dg_dk < 0) + coord.g--; + + if(step.db_dk < 0) + coord.b--; +} + +template +static INLINE T LineDivide(T delta, int32 dk) +{ + delta <<= bits; + + if(delta < 0) + delta -= dk - 1; + if(delta > 0) + delta += dk - 1; + + return(delta / dk); +} + +template +static INLINE void LinePointsToFXPStep(const line_point &point0, const line_point &point1, const int32 dk, line_fxp_step &step) +{ + if(!dk) + { + step.dx_dk = 0; + step.dy_dk = 0; + + if(goraud) + { + step.dr_dk = 0; + step.dg_dk = 0; + step.db_dk = 0; + } + return; + } + + step.dx_dk = LineDivide(point1.x - point0.x, dk); + step.dy_dk = LineDivide(point1.y - point0.y, dk); + + if(goraud) + { + step.dr_dk = LineDivide(point1.r - point0.r, dk); + step.dg_dk = LineDivide(point1.g - point0.g, dk); + step.db_dk = LineDivide(point1.b - point0.b, dk); + } +} + +template +static INLINE void AddLineStep(line_fxp_coord &point, const line_fxp_step &step, int32 count = 1) +{ + point.x += step.dx_dk * count; + point.y += step.dy_dk * count; + + if(goraud) + { + point.r += step.dr_dk * count; + point.g += step.dg_dk * count; + point.b += step.db_dk * count; + } +} + +template +void PS_GPU::DrawLine(line_point *points) +{ + int32 i_dx; + int32 i_dy; + int32 k; + line_fxp_coord cur_point; + line_fxp_step step; + + i_dx = abs(points[1].x - points[0].x); + i_dy = abs(points[1].y - points[0].y); + k = (i_dx > i_dy) ? i_dx : i_dy; + + if(i_dx >= 1024) + { + //PSX_WARNING("[GPU] Line too long: i_dx=%d", i_dx); + return; + } + + if(i_dy >= 512) + { + //PSX_WARNING("[GPU] Line too long: i_dy=%d", i_dy); + return; + } + + // May not be correct(do tests for the case of k == i_dy on real thing. + if(points[0].x > points[1].x) + { + line_point tmp = points[1]; + + points[1] = points[0]; + points[0] = tmp; + } + + DrawTimeAvail -= k * ((BlendMode >= 0) ? 2 : 1); + + // + // + // + + LinePointsToFXPStep(points[0], points[1], k, step); + LinePointToFXPCoord(points[0], step, cur_point); + + // + // + // + for(int32 i = 0; i <= k; i++) // <= is not a typo. + { + // Sign extension is not necessary here for x and y, due to the maximum values that ClipX1 and ClipY1 can contain. + const int32 x = (cur_point.x >> Line_XY_FractBits) & 2047; + const int32 y = (cur_point.y >> Line_XY_FractBits) & 2047; + uint16 pix = 0x8000; + + if(!LineSkipTest(y)) + { + uint8 r, g, b; + + if(goraud) + { + r = cur_point.r >> Line_RGB_FractBits; + g = cur_point.g >> Line_RGB_FractBits; + b = cur_point.b >> Line_RGB_FractBits; + } + else + { + r = points[0].r; + g = points[0].g; + b = points[0].b; + } + + if(goraud && dtd) + { + pix |= DitherLUT[y & 3][x & 3][r] << 0; + pix |= DitherLUT[y & 3][x & 3][g] << 5; + pix |= DitherLUT[y & 3][x & 3][b] << 10; + } + else + { + pix |= (r >> 3) << 0; + pix |= (g >> 3) << 5; + pix |= (b >> 3) << 10; + } + + // FIXME: There has to be a faster way than checking for being inside the drawing area for each pixel. + if(x >= ClipX0 && x <= ClipX1 && y >= ClipY0 && y <= ClipY1) + PlotPixel(x, y, pix); + } + + AddLineStep(cur_point, step); + } +} + +template +void PS_GPU::Command_DrawLine(const uint32 *cb) +{ + const uint8 cc = cb[0] >> 24; // For pline handling later. + line_point points[2]; + + DrawTimeAvail -= 16; // FIXME, correct time. + + if(polyline && InCmd == INCMD_PLINE) + { + //printf("PLINE N\n"); + points[0] = InPLine_PrevPoint; + } + else + { + points[0].r = (*cb >> 0) & 0xFF; + points[0].g = (*cb >> 8) & 0xFF; + points[0].b = (*cb >> 16) & 0xFF; + cb++; + + points[0].x = sign_x_to_s32(11, ((*cb >> 0) & 0xFFFF)) + OffsX; + points[0].y = sign_x_to_s32(11, ((*cb >> 16) & 0xFFFF)) + OffsY; + cb++; + } + + if(goraud) + { + points[1].r = (*cb >> 0) & 0xFF; + points[1].g = (*cb >> 8) & 0xFF; + points[1].b = (*cb >> 16) & 0xFF; + cb++; + } + else + { + points[1].r = points[0].r; + points[1].g = points[0].g; + points[1].b = points[0].b; + } + + points[1].x = sign_x_to_s32(11, ((*cb >> 0) & 0xFFFF)) + OffsX; + points[1].y = sign_x_to_s32(11, ((*cb >> 16) & 0xFFFF)) + OffsY; + cb++; + + if(polyline) + { + InPLine_PrevPoint = points[1]; + + if(InCmd != INCMD_PLINE) + { + InCmd = INCMD_PLINE; + InCmd_CC = cc; + } + } + + DrawLine(points); +} + diff --git a/mednafen/psx-0925/gpu_polygon.inc b/mednafen/psx-0925/gpu_polygon.inc new file mode 100644 index 00000000..c5c3c002 --- /dev/null +++ b/mednafen/psx-0925/gpu_polygon.inc @@ -0,0 +1,489 @@ +struct i_group +{ + int32 u, v; + int32 r, g, b; + int32 dummy0[3]; +}; + +struct i_deltas +{ + int32 du_dx, dv_dx; + int32 dr_dx, dg_dx, db_dx; + int32 dummy0[3]; + + int32 du_dy, dv_dy; + int32 dr_dy, dg_dy, db_dy; + int32 dummy1[3]; +}; + +static INLINE int64 MakePolyXFP(int32 x) +{ + return ((int64)x << 32) + ((1LL << 32) - (1 << 11)); +} + +static INLINE int64 MakePolyXFPStep(int32 dx, int32 dy) +{ + int64 ret; + int64 dx_ex = (int64)dx << 32; + + if(dx_ex < 0) + dx_ex -= dy - 1; + + if(dx_ex > 0) + dx_ex += dy - 1; + + ret = dx_ex / dy; + + return(ret); +} + +static INLINE int32 GetPolyXFP_Int(int64 xfp) +{ + return(xfp >> 32); +} + +//#define CALCIS(x,y) ( A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y) ) +#define CALCIS(x,y) (((B.x - A.x) * (C.y - B.y)) - ((C.x - B.x) * (B.y - A.y))) +static INLINE bool CalcIDeltas(i_deltas &idl, const tri_vertex &A, const tri_vertex &B, const tri_vertex &C) +{ + int64 num = ((int64)COORD_MF_INT(1)) << 32; + int64 denom = CALCIS(x, y); + int64 one_div; + + if(!denom) + return(false); + +//num -= abs(denom) - 1; +// num += abs(denom) >> 1; + + one_div = num / denom; + + idl.dr_dx = ((one_div * CALCIS(r, y)) + 0x00000000) >> 32; + idl.dr_dy = ((one_div * CALCIS(x, r)) + 0x00000000) >> 32; + + idl.dg_dx = ((one_div * CALCIS(g, y)) + 0x00000000) >> 32; + idl.dg_dy = ((one_div * CALCIS(x, g)) + 0x00000000) >> 32; + + idl.db_dx = ((one_div * CALCIS(b, y)) + 0x00000000) >> 32; + idl.db_dy = ((one_div * CALCIS(x, b)) + 0x00000000) >> 32; + + idl.du_dx = ((one_div * CALCIS(u, y)) + 0x00000000) >> 32; + idl.du_dy = ((one_div * CALCIS(x, u)) + 0x00000000) >> 32; + + idl.dv_dx = ((one_div * CALCIS(v, y)) + 0x00000000) >> 32; + idl.dv_dy = ((one_div * CALCIS(x, v)) + 0x00000000) >> 32; + +// printf(" du_dx=%08x, du_dy=%08x\n", idl.du_dx, idl.du_dy); + + return(true); +} +#undef CALCIS + +template +static INLINE void AddIDeltas_DX(i_group &ig, const i_deltas &idl) +{ + if(textured) + { + ig.u += idl.du_dx; + ig.v += idl.dv_dx; + } + + if(goraud) + { + ig.r += idl.dr_dx; + ig.g += idl.dg_dx; + ig.b += idl.db_dx; + } +} + +template +static INLINE void AddIDeltas_DY(i_group &ig, const i_deltas &idl, int32 count = 1) +{ + if(textured) + { + ig.u += idl.du_dy * count; + ig.v += idl.dv_dy * count; + } + + if(goraud) + { + ig.r += idl.dr_dy * count; + ig.g += idl.dg_dy * count; + ig.b += idl.db_dy * count; + } +} + +template +INLINE void PS_GPU::DrawSpan(int y, uint32 clut_offset, const int32 x_start, const int32 x_bound, const int32 bv_x, i_group ig, const i_deltas &idl) +{ + int32 xs = x_start, xb = x_bound; + + if(LineSkipTest(y)) + return; + + if(xs < xb) // (xs != xb) + { + if(xs < ClipX0) + xs = ClipX0; + + if(xb > (ClipX1 + 1)) + xb = ClipX1 + 1; + + if(xs < xb) + { + DrawTimeAvail -= (xb - xs); + + if(goraud || textured) + { + DrawTimeAvail -= (xb - xs); + } + else if((BlendMode >= 0) || MaskEval_TA) + { + DrawTimeAvail -= (((xb + 1) & ~1) - (xs & ~1)) >> 1; + } + } + + if(textured) + { + ig.u += (xs - bv_x) * idl.du_dx; + ig.v += (xs - bv_x) * idl.dv_dx; + } + + if(goraud) + { + ig.r += (xs - bv_x) * idl.dr_dx; + ig.g += (xs - bv_x) * idl.dg_dx; + ig.b += (xs - bv_x) * idl.db_dx; + } + + for(int32 x = xs; x < xb; x++) + { + uint32 r, g, b; + + if(goraud) + { + r = RGB8SAT[COORD_GET_INT(ig.r)]; + g = RGB8SAT[COORD_GET_INT(ig.g)]; + b = RGB8SAT[COORD_GET_INT(ig.b)]; + } + else + { + r = COORD_GET_INT(ig.r); + g = COORD_GET_INT(ig.g); + b = COORD_GET_INT(ig.b); + } + + if(textured) + { + uint16 fbw = GetTexel(clut_offset, COORD_GET_INT(ig.u), COORD_GET_INT(ig.v)); + + if(fbw) + { + if(TexMult) + { + if(dtd) + fbw = ModTexel(fbw, r, g, b, x & 3, y & 3); + else + fbw = ModTexel(fbw, r, g, b, 3, 2); //x & 3, y & 3); + } + PlotPixel(x, y, fbw); + } + } + else + { + uint16 pix = 0x8000; + + if(goraud && dtd) + { + pix |= DitherLUT[y & 3][x & 3][r] << 0; + pix |= DitherLUT[y & 3][x & 3][g] << 5; + pix |= DitherLUT[y & 3][x & 3][b] << 10; + } + else + { + pix |= (r >> 3) << 0; + pix |= (g >> 3) << 5; + pix |= (b >> 3) << 10; + } + + PlotPixel(x, y, pix); + } + + AddIDeltas_DX(ig, idl); + //AddStep(perp_coord, perp_step); + } + } +} + +template +void PS_GPU::DrawTriangle(tri_vertex *vertices, uint32 clut) +{ + i_deltas idl; + +#if 0 + vertices[0].y = COORD_MF_INT(rand()); + vertices[1].y = COORD_MF_INT(rand()); + vertices[2].y = COORD_MF_INT(rand()); + + vertices[0].x = COORD_MF_INT(rand()); + vertices[1].x = COORD_MF_INT(rand()); + vertices[2].x = COORD_MF_INT(rand()); +#endif + + if(vertices[2].y < vertices[1].y) + { + tri_vertex tmp = vertices[1]; + vertices[1] = vertices[2]; + vertices[2] = tmp; + } + + if(vertices[1].y < vertices[0].y) + { + tri_vertex tmp = vertices[0]; + vertices[0] = vertices[1]; + vertices[1] = tmp; + } + + if(vertices[2].y < vertices[1].y) + { + tri_vertex tmp = vertices[1]; + vertices[1] = vertices[2]; + vertices[2] = tmp; + } + + if(vertices[0].y == vertices[2].y) + return; + + if((vertices[2].y - vertices[0].y) >= 512) + { + //PSX_WARNING("[GPU] Triangle height too large: %d", (vertices[2].y - vertices[0].y)); + return; + } + + if(abs(vertices[2].x - vertices[0].x) >= 1024 || + abs(vertices[2].x - vertices[1].x) >= 1024 || + abs(vertices[1].x - vertices[0].x) >= 1024) + { + //PSX_WARNING("[GPU] Triangle width too large: %d %d %d", abs(vertices[2].x - vertices[0].x), abs(vertices[2].x - vertices[1].x), abs(vertices[1].x - vertices[0].x)); + return; + } + + if(!CalcIDeltas(idl, vertices[0], vertices[1], vertices[2])) + return; + + // [0] should be top vertex, [2] should be bottom vertex, [1] should be off to the side vertex. + // + // + int32 y_start = vertices[0].y; + int32 y_middle = vertices[1].y; + int32 y_bound = vertices[2].y; + + int64 base_coord; + int64 base_step; + + int64 bound_coord_ul; + int64 bound_coord_us; + + int64 bound_coord_ll; + int64 bound_coord_ls; + + bool right_facing; + //bool bottom_up; + i_group ig; + + ig.u = COORD_MF_INT(vertices[0].u) + (1 << (COORD_FBS - 1)); + ig.v = COORD_MF_INT(vertices[0].v) + (1 << (COORD_FBS - 1)); + ig.r = COORD_MF_INT(vertices[0].r); + ig.g = COORD_MF_INT(vertices[0].g); + ig.b = COORD_MF_INT(vertices[0].b); + + base_coord = MakePolyXFP(vertices[0].x); //COORD_MF_INT(vertices[0].x) + ((1 << COORD_FBS) - 1); + base_step = MakePolyXFPStep((vertices[2].x - vertices[0].x), (vertices[2].y - vertices[0].y)); //ROUND_HELPER(COORD_MF_INT(vertices[2].x - vertices[0].x), (vertices[2].y - vertices[0].y)); + + bound_coord_ul = MakePolyXFP(vertices[0].x); // + ((1 << COORD_FBS) - 1); + bound_coord_ll = MakePolyXFP(vertices[1].x); // + ((1 << COORD_FBS) - 1); + + // + // + // + + + if(vertices[1].y == vertices[0].y) + { + bound_coord_us = 0; + right_facing = (bool)(vertices[1].x > vertices[0].x); + } + else + { + bound_coord_us = MakePolyXFPStep((vertices[1].x - vertices[0].x), (vertices[1].y - vertices[0].y)); + right_facing = (bool)(bound_coord_us > base_step); + } + + if(vertices[2].y == vertices[1].y) + bound_coord_ls = 0; + else + bound_coord_ls = MakePolyXFPStep((vertices[2].x - vertices[1].x), (vertices[2].y - vertices[1].y)); + + if(y_start < ClipY0) + { + int32 count = ClipY0 - y_start; + + y_start = ClipY0; + base_coord += base_step * count; + bound_coord_ul += bound_coord_us * count; + + AddIDeltas_DY(ig, idl, count); + + if(y_middle < ClipY0) + { + int32 count_ls = ClipY0 - y_middle; + + y_middle = ClipY0; + bound_coord_ll += bound_coord_ls * count_ls; + } + } + + if(y_bound > (ClipY1 + 1)) + { + y_bound = ClipY1 + 1; + + if(y_middle > y_bound) + y_middle = y_bound; + } + + if(right_facing) + { + for(int32 y = y_start; y < y_middle; y++) + { + DrawSpan(y, clut, GetPolyXFP_Int(base_coord), GetPolyXFP_Int(bound_coord_ul), vertices[0].x, ig, idl); + base_coord += base_step; + bound_coord_ul += bound_coord_us; + AddIDeltas_DY(ig, idl); + } + + for(int32 y = y_middle; y < y_bound; y++) + { + DrawSpan(y, clut, GetPolyXFP_Int(base_coord), GetPolyXFP_Int(bound_coord_ll), vertices[0].x, ig, idl); + base_coord += base_step; + bound_coord_ll += bound_coord_ls; + AddIDeltas_DY(ig, idl); + } + } + else + { + for(int32 y = y_start; y < y_middle; y++) + { + DrawSpan(y, clut, GetPolyXFP_Int(bound_coord_ul), GetPolyXFP_Int(base_coord), vertices[0].x, ig, idl); + base_coord += base_step; + bound_coord_ul += bound_coord_us; + AddIDeltas_DY(ig, idl); + } + + for(int32 y = y_middle; y < y_bound; y++) + { + DrawSpan(y, clut, GetPolyXFP_Int(bound_coord_ll), GetPolyXFP_Int(base_coord), vertices[0].x, ig, idl); + base_coord += base_step; + bound_coord_ll += bound_coord_ls; + AddIDeltas_DY(ig, idl); + } + } + +#if 0 + printf("[GPU] Vertices: %d:%d(r=%d, g=%d, b=%d) -> %d:%d(r=%d, g=%d, b=%d) -> %d:%d(r=%d, g=%d, b=%d)\n\n\n", vertices[0].x, vertices[0].y, + vertices[0].r, vertices[0].g, vertices[0].b, + vertices[1].x, vertices[1].y, + vertices[1].r, vertices[1].g, vertices[1].b, + vertices[2].x, vertices[2].y, + vertices[2].r, vertices[2].g, vertices[2].b); +#endif +} + +template +void PS_GPU::Command_DrawPolygon(const uint32 *cb) +{ + const unsigned cb0 = cb[0]; + tri_vertex vertices[3]; + uint32 clut = 0; + unsigned sv = 0; + //uint32 tpage = 0; + + // Base timing is approximate, and could be improved. + if(numvertices == 4 && InCmd == INCMD_QUAD) + DrawTimeAvail -= (28 + 18); + else + DrawTimeAvail -= (64 + 18); + + if(goraud && textured) + DrawTimeAvail -= 150 * 3; + else if(goraud) + DrawTimeAvail -= 96 * 3; + else if(textured) + DrawTimeAvail -= 60 * 3; + + if(numvertices == 4) + { + if(InCmd == INCMD_QUAD) + { + memcpy(&vertices[0], &InQuad_F3Vertices[1], 2 * sizeof(tri_vertex)); + clut = InQuad_clut; + sv = 2; + } + } + //else + // memset(vertices, 0, sizeof(vertices)); + + for(unsigned v = sv; v < 3; v++) + { + if(v == 0 || goraud) + { + uint32 raw_color = (*cb & 0xFFFFFF); + + vertices[v].r = raw_color & 0xFF; + vertices[v].g = (raw_color >> 8) & 0xFF; + vertices[v].b = (raw_color >> 16) & 0xFF; + + cb++; + } + else + { + vertices[v].r = vertices[0].r; + vertices[v].g = vertices[0].g; + vertices[v].b = vertices[0].b; + } + + vertices[v].x = sign_x_to_s32(11, ((int16)(*cb & 0xFFFF))) + OffsX; + vertices[v].y = sign_x_to_s32(11, ((int16)(*cb >> 16))) + OffsY; + cb++; + + if(textured) + { + vertices[v].u = (*cb & 0xFF); + vertices[v].v = (*cb >> 8) & 0xFF; + + if(v == 0) + { + clut = ((*cb >> 16) & 0xFFFF) << 4; + } + + cb++; + } + } + + if(numvertices == 4) + { + if(InCmd == INCMD_QUAD) + { + InCmd = INCMD_NONE; + } + else + { + InCmd = INCMD_QUAD; + InCmd_CC = cb0 >> 24; + memcpy(&InQuad_F3Vertices[0], &vertices[0], sizeof(tri_vertex) * 3); + InQuad_clut = clut; + } + } + + DrawTriangle(vertices, clut); +} + diff --git a/mednafen/psx-0925/gpu_sprite.inc b/mednafen/psx-0925/gpu_sprite.inc new file mode 100644 index 00000000..19c6b0d4 --- /dev/null +++ b/mednafen/psx-0925/gpu_sprite.inc @@ -0,0 +1,232 @@ +template +void PS_GPU::DrawSprite(int32 x_arg, int32 y_arg, int32 w, int32 h, uint8 u_arg, uint8 v_arg, uint32 color, uint32 clut_offset) +{ + const int32 r = color & 0xFF; + const int32 g = (color >> 8) & 0xFF; + const int32 b = (color >> 16) & 0xFF; + const uint16 fill_color = 0x8000 | ((r >> 3) << 0) | ((g >> 3) << 5) | ((b >> 3) << 10); + + int32 x_start, x_bound; + int32 y_start, y_bound; + uint8 u, v; + int v_inc = 1, u_inc = 1; + + //printf("[GPU] Sprite: x=%d, y=%d, w=%d, h=%d\n", x_arg, y_arg, w, h); + + x_start = x_arg; + x_bound = x_arg + w; + + y_start = y_arg; + y_bound = y_arg + h; + + if(textured) + { + u = u_arg; + v = v_arg; + + if(FlipX) + { + u_inc = -1; + u |= 1; + } + // FIXME: Something weird happens when lower bit of u is set and we're not doing horizontal flip, but I'm not sure what it is exactly(needs testing) + // It may only happen to the first pixel, so look for that case too during testing. + //else + // u = (u + 1) & ~1; + + if(FlipY) + { + v_inc = -1; + } + } + + if(x_start < ClipX0) + { + if(textured) + u += (ClipX0 - x_start) * u_inc; + + x_start = ClipX0; + } + + if(y_start < ClipY0) + { + if(textured) + v += (ClipY0 - y_start) * v_inc; + + y_start = ClipY0; + } + + if(x_bound > (ClipX1 + 1)) + x_bound = ClipX1 + 1; + + if(y_bound > (ClipY1 + 1)) + y_bound = ClipY1 + 1; + + if(y_bound > y_start && x_bound > x_start) + { + // + // Note(TODO): From tests on a PS1, even a 0-width sprite takes up time to "draw" proportional to its height. + // + int32 suck_time = (x_bound - x_start) * (y_bound - y_start); + + // Disabled until we can get it to take into account texture windowing, which can cause large sprites to be drawn entirely from cache(and not suffer from a texturing + // penalty); and disabled until we find a game that needs more accurate sprite draw timing. :b +#if 0 + if(textured) + { + // Empirically-observed approximations of time(66MHz cycles) taken to draw large textured sprites in the various texture depths, when the texture data and CLUT data + // was zero(non-zero takes longer to draw, TODO test that more): + // 4bpp - area * 2 + // 8bpp - area * 3 + // 15/16bpp - area * 5 + // (other factors come into more importance for smaller sprites) + static const int cw[4] = { 64, 32, 32, 32 }; + static const int ch[4] = { 64, 64, 32, 32 }; + static const int mm[4] = { 2 - 1, 3 - 1, 5 - 1, 5 - 1 }; + + // Parts of the first few(up to texture cache height) horizontal lines can be in cache, so assume they are. + suck_time += mm[TexMode_TA] * std::max(0, (x_bound - x_start) - cw[TexMode_TA]) * std::min(ch[TexMode_TA], y_bound - y_start); + + // The rest of the horizontal lines should not possibly have parts in the cache now. + suck_time += mm[TexMode_TA] * (x_bound - x_start) * std::max(0, (y_bound - y_start) - ch[TexMode_TA]); + } + else +#endif + + if((BlendMode >= 0) || MaskEval_TA) + { + suck_time += ((((x_bound + 1) & ~1) - (x_start & ~1)) * (y_bound - y_start)) >> 1; + } + + DrawTimeAvail -= suck_time; + } + + + //HeightMode && !dfe && ((y & 1) == ((DisplayFB_YStart + !field_atvs) & 1)) && !DisplayOff + //printf("%d:%d, %d, %d ---- heightmode=%d displayfb_ystart=%d field_atvs=%d displayoff=%d\n", w, h, scanline, dfe, HeightMode, DisplayFB_YStart, field_atvs, DisplayOff); + + for(int32 y = y_start; y < y_bound; y++) + { + uint8 u_r; + + if(textured) + u_r = u; + + if(!LineSkipTest(y)) + { + for(int32 x = x_start; x < x_bound; x++) + { + if(textured) + { + uint16 fbw = GetTexel(clut_offset, u_r, v); + + if(fbw) + { + if(TexMult) + { + fbw = ModTexel(fbw, r, g, b, 3, 2); + } + PlotPixel(x, y, fbw); + } + } + else + PlotPixel(x, y, fill_color); + + if(textured) + u_r += u_inc; + } + } + if(textured) + v += v_inc; + } +} + +template +void PS_GPU::Command_DrawSprite(const uint32 *cb) +{ + int32 x, y; + int32 w, h; + uint8 u = 0, v = 0; + uint32 color = 0; + uint32 clut = 0; + + DrawTimeAvail -= 16; // FIXME, correct time. + + color = *cb & 0x00FFFFFF; + cb++; + + x = sign_x_to_s32(11, (*cb & 0xFFFF)); + y = sign_x_to_s32(11, (*cb >> 16)); + cb++; + + if(textured) + { + u = *cb & 0xFF; + v = (*cb >> 8) & 0xFF; + clut = ((*cb >> 16) & 0xFFFF) << 4; + cb++; + } + + switch(raw_size) + { + default: + case 0: + w = (*cb & 0x3FF); + h = (*cb >> 16) & 0x1FF; + cb++; + break; + + case 1: + w = 1; + h = 1; + break; + + case 2: + w = 8; + h = 8; + break; + + case 3: + w = 16; + h = 16; + break; + } + + //printf("SPRITE: %d %d %d -- %d %d\n", raw_size, x, y, w, h); + + x = sign_x_to_s32(11, x + OffsX); + y = sign_x_to_s32(11, y + OffsY); + + switch(SpriteFlip & 0x3000) + { + case 0x0000: + if(!TexMult || color == 0x808080) + DrawSprite(x, y, w, h, u, v, color, clut); + else + DrawSprite(x, y, w, h, u, v, color, clut); + break; + + case 0x1000: + if(!TexMult || color == 0x808080) + DrawSprite(x, y, w, h, u, v, color, clut); + else + DrawSprite(x, y, w, h, u, v, color, clut); + break; + + case 0x2000: + if(!TexMult || color == 0x808080) + DrawSprite(x, y, w, h, u, v, color, clut); + else + DrawSprite(x, y, w, h, u, v, color, clut); + break; + + case 0x3000: + if(!TexMult || color == 0x808080) + DrawSprite(x, y, w, h, u, v, color, clut); + else + DrawSprite(x, y, w, h, u, v, color, clut); + break; + } +} + + diff --git a/mednafen/psx-0925/gte.cpp b/mednafen/psx-0925/gte.cpp new file mode 100644 index 00000000..b78b60df --- /dev/null +++ b/mednafen/psx-0925/gte.cpp @@ -0,0 +1,1739 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PSXDEV_GTE_TESTING +#include "psx.h" +#include "gte.h" +#endif + +static uint32 ReciprocalTable[0x8000] = +{ + #include "gte_divrecip.inc" +}; + +/* Notes: + + AVSZ3/AVSZ4: + OTZ is MAC0 >> 12 + OTZ overflow/underflow flag is set in an overflow condition even if MAC0 == 0. + sf field bit has no effect? + + FLAG register: + Bits present mask: 0xfffff000 + + Checksum bit can't be directly set, it's apparently calculated like (bool)(FLAGS & 0x7f87e000) + + Instructions effectively clear it 0 at start. (todo: test "invalid" instructions) + + X/Y FIFO [3] register write pushes a copy down to [2] + +*/ + +#ifndef PSXDEV_GTE_TESTING +namespace MDFN_IEN_PSX +{ +#endif + +typedef struct +{ + int16 MX[3][3]; + int16 dummy; +} __attribute__((__packed__)) gtematrix; + +typedef struct +{ + union + { + struct + { + uint8 R; + uint8 G; + uint8 B; + uint8 CD; + }; + uint8 Raw8[4]; + }; +} gtergb; + +typedef struct +{ + int16 X; + int16 Y; +} gtexy; + +int16 Lm_B(unsigned int which, int32 value, int lm); +uint8 Lm_C(unsigned int which, int32 value); + + + +int32 Lm_G(unsigned int which, int32 value); +int32 Lm_H(int32 value); + +void MAC_to_RGB_FIFO(void); +void MAC_to_IR(int lm); + +void MultiplyMatrixByVector(const gtematrix *matrix, const int16 *v, const int32 *crv, uint32 sf, int lm); + +static uint32 CR[32]; +static uint32 FLAGS; // Temporary for instruction execution, copied into CR[31] at end of instruction execution. + +typedef union +{ + gtematrix All[4]; + int32 Raw[4][5]; // Don't read from this(Raw[][]), only write(and when writing, if running on a big-endian platform, swap the upper 16-bits with the lower 16-bits) + int16 Raw16[4][10]; + + struct + { + gtematrix Rot; + gtematrix Light; + gtematrix Color; + gtematrix AbbyNormal; + }; +} Matrices_t; + +static Matrices_t Matrices; + +static union +{ + int32 All[4][4]; // Really only [4][3], but [4] to ease address calculation. + + struct + { + int32 T[4]; + int32 B[4]; + int32 FC[4]; + int32 Null[4]; + }; +} CRVectors; + +static int32 OFX; +static int32 OFY; +static uint16 H; +static int16 DQA; +static int32 DQB; + +static int16 ZSF3; +static int16 ZSF4; + + +// Begin DR +static int16 Vectors[3][4]; +static gtergb RGB; +static uint16 OTZ; + +static int16 IR[4]; + +#define IR0 IR[0] +#define IR1 IR[1] +#define IR2 IR[2] +#define IR3 IR[3] + +static gtexy XY_FIFO[4]; +static uint16 Z_FIFO[4]; +static gtergb RGB_FIFO[3]; +static int32 MAC[4]; +static uint32 LZCS; +static uint32 LZCR; + +static uint32 Reg23; +// end DR + +int32 RTPS(uint32 instr); +int32 RTPT(uint32 instr); + +int32 NCLIP(uint32 instr); + +void NormColor(uint32 sf, int lm, uint32 v); +int32 NCS(uint32 instr); +int32 NCT(uint32 instr); + + +void NormColorColor(uint32 v, uint32 sf, int lm); +int32 NCCS(uint32 instr); +int32 NCCT(uint32 instr); + +void NormColorDepthCue(uint32 v, uint32 sf, int lm); +int32 NCDS(uint32 instr); +int32 NCDT(uint32 instr); + +int32 AVSZ3(uint32 instr); +int32 AVSZ4(uint32 instr); + +int32 OP(uint32 instr); + +int32 GPF(uint32 instr); +int32 GPL(uint32 instr); + +void DepthCue(int mult_IR123, int RGB_from_FIFO, uint32 sf, int lm); +int32 DCPL(uint32 instr); +int32 DPCS(uint32 instr); +int32 DPCT(uint32 instr); +int32 INTPL(uint32 instr); + +int32 SQR(uint32 instr); +int32 MVMVA(uint32 instr); + +static INLINE uint8 Sat5(int16 cc) +{ + if(cc < 0) + cc = 0; + if(cc > 0x1F) + cc = 0x1F; + return(cc); +} + + + +void GTE_Power(void) +{ + memset(CR, 0, sizeof(CR)); + //memset(DR, 0, sizeof(DR)); + + memset(Matrices.All, 0, sizeof(Matrices.All)); + memset(CRVectors.All, 0, sizeof(CRVectors.All)); + OFX = 0; + OFY = 0; + H = 0; + DQA = 0; + DQB = 0; + ZSF3 = 0; + ZSF4 = 0; + + + memset(Vectors, 0, sizeof(Vectors)); + memset(&RGB, 0, sizeof(RGB)); + OTZ = 0; + IR0 = 0; + IR1 = 0; + IR2 = 0; + IR3 = 0; + + memset(XY_FIFO, 0, sizeof(XY_FIFO)); + memset(Z_FIFO, 0, sizeof(Z_FIFO)); + memset(RGB_FIFO, 0, sizeof(RGB_FIFO)); + memset(MAC, 0, sizeof(MAC)); + LZCS = 0; + LZCR = 0; + + Reg23 = 0; +} + +// TODO: Don't save redundant state, regarding CR cache variables +int GTE_StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { + SFARRAY32(CR, 32), + SFVAR(FLAGS), + + SFARRAY16(&Matrices.Raw16[0][0], 4 * 10), + + SFARRAY32(&CRVectors.All[0][0], 4 * 4), + + SFVAR(OFX), + SFVAR(OFY), + SFVAR(H), + SFVAR(DQA), + SFVAR(DQB), + + SFVAR(ZSF3), + SFVAR(ZSF4), + SFARRAY16(&Vectors[0][0], 3 * 4), + + SFARRAY(RGB.Raw8, 4), + SFVAR(OTZ), + SFARRAY16(IR, 4), + + SFVAR(XY_FIFO[0].X), + SFVAR(XY_FIFO[0].Y), + SFVAR(XY_FIFO[1].X), + SFVAR(XY_FIFO[1].Y), + SFVAR(XY_FIFO[2].X), + SFVAR(XY_FIFO[2].Y), + SFVAR(XY_FIFO[3].X), + SFVAR(XY_FIFO[3].Y), + + SFARRAY16(Z_FIFO, 4), + + SFARRAY(RGB_FIFO[0].Raw8, 4), + SFARRAY(RGB_FIFO[1].Raw8, 4), + SFARRAY(RGB_FIFO[2].Raw8, 4), + SFARRAY(RGB_FIFO[3].Raw8, 4), + + SFARRAY32(MAC, 4), + + SFVAR(LZCS), + SFVAR(LZCR), + SFVAR(Reg23), + + SFEND + }; + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "GTE"); + + if(load) + { + + } + + return(ret); +} + + +void GTE_WriteCR(unsigned int which, uint32 value) +{ + static const uint32 mask_table[32] = { + /* 0x00 */ + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + + /* 0x08 */ + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + + /* 0x10 */ + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + + /* 0x18 */ + 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0x0000FFFF, 0xFFFFFFFF, 0x0000FFFF, 0x0000FFFF, 0xFFFFFFFF + }; + + //PSX_WARNING("[GTE] Write CR %d, 0x%08x", which, value); + + value &= mask_table[which]; + + CR[which] = value | (CR[which] & ~mask_table[which]); + + if(which < 24) + { + int we = which >> 3; + which &= 0x7; + + if(which >= 5) + CRVectors.All[we][which - 5] = value; + else + { + #ifdef MSB_FIRST + Matrices.Raw[we][which] = (value << 16) | (value >> 16); + #else + Matrices.Raw[we][which] = value; + #endif + } + return; + } + + switch(which) + { + case 24: + OFX = value; + break; + + case 25: + OFY = value; + break; + + case 26: + H = value; + break; + + case 27: + DQA = value; + break; + + case 28: + DQB = value; + break; + + case 29: + ZSF3 = value; + break; + + case 30: + ZSF4 = value; + break; + + case 31: + CR[31] = (value & 0x7ffff000) | ((value & 0x7f87e000) ? (1 << 31) : 0); + break; + } +} + +uint32 GTE_ReadCR(unsigned int which) +{ + uint32 ret = 0; + + switch(which) + { + default: + ret = CR[which]; + if(which == 4 || which == 12 || which == 20) + ret = (int16)ret; + break; + + case 24: + ret = OFX; + break; + + case 25: + ret = OFY; + break; + + case 26: + ret = (int16)H; + break; + + case 27: + ret = (int16)DQA; + break; + + case 28: + ret = DQB; + break; + + case 29: + ret = (int16)ZSF3; + break; + + case 30: + ret = (int16)ZSF4; + break; + + case 31: + ret = CR[31]; + break; + } + + return(ret); +} + +void GTE_WriteDR(unsigned int which, uint32 value) +{ + switch(which & 0x1F) + { + case 0: + Vectors[0][0] = value; + Vectors[0][1] = value >> 16; + break; + + case 1: + Vectors[0][2] = value; + break; + + case 2: + Vectors[1][0] = value; + Vectors[1][1] = value >> 16; + break; + + case 3: + Vectors[1][2] = value; + break; + + case 4: + Vectors[2][0] = value; + Vectors[2][1] = value >> 16; + break; + + case 5: + Vectors[2][2] = value; + break; + + case 6: + RGB.R = value >> 0; + RGB.G = value >> 8; + RGB.B = value >> 16; + RGB.CD = value >> 24; + break; + + case 7: + OTZ = value; + break; + + case 8: + IR0 = value; + break; + + case 9: + IR1 = value; + break; + + case 10: + IR2 = value; + break; + + case 11: + IR3 = value; + break; + + case 12: + XY_FIFO[0].X = value; + XY_FIFO[0].Y = value >> 16; + break; + + case 13: + XY_FIFO[1].X = value; + XY_FIFO[1].Y = value >> 16; + break; + + case 14: + XY_FIFO[2].X = value; + XY_FIFO[2].Y = value >> 16; + XY_FIFO[3].X = value; + XY_FIFO[3].Y = value >> 16; + break; + + case 15: + XY_FIFO[3].X = value; + XY_FIFO[3].Y = value >> 16; + + XY_FIFO[0] = XY_FIFO[1]; + XY_FIFO[1] = XY_FIFO[2]; + XY_FIFO[2] = XY_FIFO[3]; + break; + + case 16: + Z_FIFO[0] = value; + break; + + case 17: + Z_FIFO[1] = value; + break; + + case 18: + Z_FIFO[2] = value; + break; + + case 19: + Z_FIFO[3] = value; + break; + + case 20: + RGB_FIFO[0].R = value; + RGB_FIFO[0].G = value >> 8; + RGB_FIFO[0].B = value >> 16; + RGB_FIFO[0].CD = value >> 24; + break; + + case 21: + RGB_FIFO[1].R = value; + RGB_FIFO[1].G = value >> 8; + RGB_FIFO[1].B = value >> 16; + RGB_FIFO[1].CD = value >> 24; + break; + + case 22: + RGB_FIFO[2].R = value; + RGB_FIFO[2].G = value >> 8; + RGB_FIFO[2].B = value >> 16; + RGB_FIFO[2].CD = value >> 24; + break; + + case 23: + Reg23 = value; + break; + + case 24: + MAC[0] = value; + break; + + case 25: + MAC[1] = value; + break; + + case 26: + MAC[2] = value; + break; + + case 27: + MAC[3] = value; + break; + + case 28: + IR1 = ((value >> 0) & 0x1F) << 7; + IR2 = ((value >> 5) & 0x1F) << 7; + IR3 = ((value >> 10) & 0x1F) << 7; + break; + + case 29: // Read-only + break; + + case 30: + LZCS = value; + { + uint32 test = value & 0x80000000; + LZCR = 0; + + while((value & 0x80000000) == test && LZCR < 32) + { + LZCR++; + value <<= 1; + } + } + break; + + case 31: // Read-only + break; + } +} + +uint32 GTE_ReadDR(unsigned int which) +{ + uint32 ret = 0; + + switch(which & 0x1F) + { + case 0: + ret = (uint16)Vectors[0][0] | ((uint16)Vectors[0][1] << 16); + break; + + case 1: + ret = (int16)Vectors[0][2]; + break; + + case 2: + ret = (uint16)Vectors[1][0] | ((uint16)Vectors[1][1] << 16); + break; + + case 3: + ret = (int16)Vectors[1][2]; + break; + + case 4: + ret = (uint16)Vectors[2][0] | ((uint16)Vectors[2][1] << 16); + break; + + case 5: + ret = (int16)Vectors[2][2]; + break; + + case 6: + ret = RGB.R | (RGB.G << 8) | (RGB.B << 16) | (RGB.CD << 24); + break; + + case 7: + ret = (uint16)OTZ; + break; + + case 8: + ret = (int16)IR0; + break; + + case 9: + ret = (int16)IR1; + break; + + case 10: + ret = (int16)IR2; + break; + + case 11: + ret = (int16)IR3; + break; + + case 12: + ret = (uint16)XY_FIFO[0].X | ((uint16)XY_FIFO[0].Y << 16); + break; + + case 13: + ret = (uint16)XY_FIFO[1].X | ((uint16)XY_FIFO[1].Y << 16); + break; + + case 14: + ret = (uint16)XY_FIFO[2].X | ((uint16)XY_FIFO[2].Y << 16); + break; + + case 15: + ret = (uint16)XY_FIFO[3].X | ((uint16)XY_FIFO[3].Y << 16); + break; + + case 16: + ret = (uint16)Z_FIFO[0]; + break; + + case 17: + ret = (uint16)Z_FIFO[1]; + break; + + case 18: + ret = (uint16)Z_FIFO[2]; + break; + + case 19: + ret = (uint16)Z_FIFO[3]; + break; + + case 20: + ret = RGB_FIFO[0].R | (RGB_FIFO[0].G << 8) | (RGB_FIFO[0].B << 16) | (RGB_FIFO[0].CD << 24); + break; + + case 21: + ret = RGB_FIFO[1].R | (RGB_FIFO[1].G << 8) | (RGB_FIFO[1].B << 16) | (RGB_FIFO[1].CD << 24); + break; + + case 22: + ret = RGB_FIFO[2].R | (RGB_FIFO[2].G << 8) | (RGB_FIFO[2].B << 16) | (RGB_FIFO[2].CD << 24); + break; + + case 23: + ret = Reg23; + break; + + case 24: + ret = MAC[0]; + break; + + case 25: + ret = MAC[1]; + break; + + case 26: + ret = MAC[2]; + break; + + case 27: + ret = MAC[3]; + break; + + case 28: + case 29: + ret = Sat5(IR1 >> 7) | (Sat5(IR2 >> 7) << 5) | (Sat5(IR3 >> 7) << 10); + break; + + case 30: + ret = LZCS; + break; + + case 31: + ret = LZCR; + break; + } + return(ret); +} + +#define sign_x_to_s64(_bits, _value) (((int64)((uint64)(_value) << (64 - _bits))) >> (64 - _bits)) +INLINE int64 A_MV(unsigned which, int64 value) +{ + if(value >= (1LL << 43)) + FLAGS |= 1 << (30 - which); + + if(value < -(1LL << 43)) + FLAGS |= 1 << (27 - which); + + return sign_x_to_s64(44, value); +} + +INLINE int64 F(int64 value) +{ + if(value < -2147483648LL) + { + // flag set here + FLAGS |= 1 << 15; + } + + if(value > 2147483647LL) + { + // flag set here + FLAGS |= 1 << 16; + } + return(value); +} + + +INLINE int16 Lm_B(unsigned int which, int32 value, int lm) +{ + int32 tmp = lm << 15; + + if(value < (-32768 + tmp)) + { + // set flag here + FLAGS |= 1 << (24 - which); + value = -32768 + tmp; + } + + if(value > 32767) + { + // Set flag here + FLAGS |= 1 << (24 - which); + value = 32767; + } + + return(value); +} + + +INLINE int16 Lm_B_PTZ(unsigned int which, int32 value, int32 ftv_value, int lm) +{ + int32 tmp = lm << 15; + + if(ftv_value < -32768) + { + FLAGS |= 1 << (24 - which); + } + + if(ftv_value > 32767) + { + FLAGS |= 1 << (24 - which); + } + + if(value < (-32768 + tmp)) + { + value = -32768 + tmp; + } + + if(value > 32767) + { + value = 32767; + } + + return(value); +} + +INLINE uint8 Lm_C(unsigned int which, int32 value) +{ + if(value & ~0xFF) + { + // Set flag here + FLAGS |= 1 << (21 - which); // Tested with GPF + + if(value < 0) + value = 0; + + if(value > 255) + value = 255; + } + + return(value); +} + +INLINE int32 Lm_D(int32 value, int unchained) +{ + // Not sure if we should have it as int64, or just chain on to and special case when the F flags are set. + if(!unchained) + { + if(FLAGS & (1 << 15)) + { + FLAGS |= 1 << 18; + return(0); + } + + if(FLAGS & (1 << 16)) + { + FLAGS |= 1 << 18; + return(0xFFFF); + } + } + + if(value < 0) + { + // Set flag here + value = 0; + FLAGS |= 1 << 18; // Tested with AVSZ3 + } + else if(value > 65535) + { + // Set flag here. + value = 65535; + FLAGS |= 1 << 18; // Tested with AVSZ3 + } + + return(value); +} + +INLINE int32 Lm_G(unsigned int which, int32 value) +{ + if(value < -1024) + { + // Set flag here + value = -1024; + FLAGS |= 1 << (14 - which); + } + + if(value > 1023) + { + // Set flag here. + value = 1023; + FLAGS |= 1 << (14 - which); + } + + return(value); +} + +// limit to 4096, not 4095 +INLINE int32 Lm_H(int32 value) +{ +#if 0 + if(FLAGS & (1 << 15)) + { + value = 0; + FLAGS |= 1 << 12; + return value; + } + + if(FLAGS & (1 << 16)) + { + value = 4096; + FLAGS |= 1 << 12; + return value; + } +#endif + + if(value < 0) + { + value = 0; + FLAGS |= 1 << 12; + } + + if(value > 4096) + { + value = 4096; + FLAGS |= 1 << 12; + } + + return(value); +} + +INLINE void MAC_to_RGB_FIFO(void) +{ + RGB_FIFO[0] = RGB_FIFO[1]; + RGB_FIFO[1] = RGB_FIFO[2]; + RGB_FIFO[2].R = Lm_C(0, MAC[1] >> 4); + RGB_FIFO[2].G = Lm_C(1, MAC[2] >> 4); + RGB_FIFO[2].B = Lm_C(2, MAC[3] >> 4); + RGB_FIFO[2].CD = RGB.CD; +} + + +INLINE void MAC_to_IR(int lm) +{ + IR1 = Lm_B(0, MAC[1], lm); + IR2 = Lm_B(1, MAC[2], lm); + IR3 = Lm_B(2, MAC[3], lm); +} + +INLINE void MultiplyMatrixByVector(const gtematrix *matrix, const int16 *v, const int32 *crv, uint32 sf, int lm) +{ + unsigned i; + + for(i = 0; i < 3; i++) + { + int64 tmp; + int32 mulr[3]; + + tmp = (int64)crv[i] << 12; + + if(matrix == &Matrices.AbbyNormal) + { + if(i == 0) + { + mulr[0] = -((RGB.R << 4) * v[0]); + mulr[1] = (RGB.R << 4) * v[1]; + mulr[2] = IR0 * v[2]; + } + else + { + mulr[0] = (int16)CR[i] * v[0]; + mulr[1] = (int16)CR[i] * v[1]; + mulr[2] = (int16)CR[i] * v[2]; + } + } + else + { + mulr[0] = matrix->MX[i][0] * v[0]; + mulr[1] = matrix->MX[i][1] * v[1]; + mulr[2] = matrix->MX[i][2] * v[2]; + } + + tmp = A_MV(i, tmp + mulr[0]); + if(crv == CRVectors.FC) + { + Lm_B(i, tmp >> sf, FALSE); + tmp = 0; + } + + tmp = A_MV(i, tmp + mulr[1]); + tmp = A_MV(i, tmp + mulr[2]); + + MAC[1 + i] = tmp >> sf; + } + + + MAC_to_IR(lm); +} + + +INLINE void MultiplyMatrixByVector_PT(const gtematrix *matrix, const int16 *v, const int32 *crv, uint32 sf, int lm) +{ + int64 tmp[3]; + unsigned i; + + for(i = 0; i < 3; i++) + { + int32 mulr[3]; + + tmp[i] = (int64)crv[i] << 12; + + mulr[0] = matrix->MX[i][0] * v[0]; + mulr[1] = matrix->MX[i][1] * v[1]; + mulr[2] = matrix->MX[i][2] * v[2]; + + tmp[i] = A_MV(i, tmp[i] + mulr[0]); + tmp[i] = A_MV(i, tmp[i] + mulr[1]); + tmp[i] = A_MV(i, tmp[i] + mulr[2]); + + MAC[1 + i] = tmp[i] >> sf; + } + + IR1 = Lm_B(0, MAC[1], lm); + IR2 = Lm_B(1, MAC[2], lm); + //printf("FTV: %08x %08x\n", crv[2], (uint32)(tmp[2] >> 12)); + IR3 = Lm_B_PTZ(2, MAC[3], tmp[2] >> 12, lm); + + Z_FIFO[0] = Z_FIFO[1]; + Z_FIFO[1] = Z_FIFO[2]; + Z_FIFO[2] = Z_FIFO[3]; + Z_FIFO[3] = Lm_D(tmp[2] >> 12, TRUE); +} + + +#define VAR_UNUSED __attribute__((unused)) + +#define DECODE_FIELDS \ + const uint32 sf VAR_UNUSED = (instr & (1 << 19)) ? 12 : 0; \ + const uint32 mx VAR_UNUSED = (instr >> 17) & 0x3; \ + const uint32 v_i = (instr >> 15) & 0x3; \ + const int32* cv VAR_UNUSED = CRVectors.All[(instr >> 13) & 0x3]; \ + const int lm VAR_UNUSED = (instr >> 10) & 1; \ + int16 v[3]; \ + if(v_i == 3) \ + { \ + v[0] = IR1; \ + v[1] = IR2; \ + v[2] = IR3; \ + } \ + else \ + { \ + v[0] = Vectors[v_i][0]; \ + v[1] = Vectors[v_i][1]; \ + v[2] = Vectors[v_i][2]; \ + } + + +int32 SQR(uint32 instr) +{ + DECODE_FIELDS; + + MAC[1] = ((IR1 * IR1) >> sf); + MAC[2] = ((IR2 * IR2) >> sf); + MAC[3] = ((IR3 * IR3) >> sf); + + MAC_to_IR(lm); + + return(5); +} + + +int32 MVMVA(uint32 instr) +{ + DECODE_FIELDS; + + MultiplyMatrixByVector(&Matrices.All[mx], v, cv, sf, lm); + + return(8); +} + +static INLINE unsigned CountLeadingZeroU16(uint16 val) +{ + unsigned ret = 0; + + while(!(val & 0x8000) && ret < 16) + { + val <<= 1; + ret++; + } + + return ret; +} + +static INLINE uint32 Divide(uint32 dividend, uint32 divisor) +{ + //if((Z_FIFO[3] * 2) > H) + if((divisor * 2) > dividend) + { + unsigned shift_bias = CountLeadingZeroU16(divisor); + + dividend <<= shift_bias; + divisor <<= shift_bias; + + return ((int64)dividend * ReciprocalTable[divisor & 0x7FFF] + 32768) >> 16; + } + else + { + FLAGS |= 1 << 17; + return 0x1FFFF; + } +} + +static INLINE void TransformXY(int64 h_div_sz) +{ + MAC[0] = F((int64)OFX + IR1 * h_div_sz) >> 16; + XY_FIFO[3].X = Lm_G(0, MAC[0]); + + MAC[0] = F((int64)OFY + IR2 * h_div_sz) >> 16; + XY_FIFO[3].Y = Lm_G(1, MAC[0]); + + XY_FIFO[0] = XY_FIFO[1]; + XY_FIFO[1] = XY_FIFO[2]; + XY_FIFO[2] = XY_FIFO[3]; +} + +static INLINE void TransformDQ(int64 h_div_sz) +{ + MAC[0] = F((int64)DQB + DQA * h_div_sz); + IR0 = Lm_H(((int64)DQB + DQA * h_div_sz) >> 12); +} + +int32 RTPS(uint32 instr) +{ + DECODE_FIELDS; + int64 h_div_sz; + + MultiplyMatrixByVector_PT(&Matrices.Rot, Vectors[0], CRVectors.T, sf, lm); + h_div_sz = Divide(H, Z_FIFO[3]); + + TransformXY(h_div_sz); + TransformDQ(h_div_sz); + + return(15); +} + +int32 RTPT(uint32 instr) +{ + DECODE_FIELDS; + int i; + + for(i = 0; i < 3; i++) + { + int64 h_div_sz; + + MultiplyMatrixByVector_PT(&Matrices.Rot, Vectors[i], CRVectors.T, sf, lm); + h_div_sz = Divide(H, Z_FIFO[3]); + + TransformXY(h_div_sz); + + if(i == 2) + TransformDQ(h_div_sz); + } + + return(23); +} + +INLINE void NormColor(uint32 sf, int lm, uint32 v) +{ + int16 tmp_vector[3]; + + MultiplyMatrixByVector(&Matrices.Light, Vectors[v], CRVectors.Null, sf, lm); + + tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3; + MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm); + + MAC_to_RGB_FIFO(); +} + +int32 NCS(uint32 instr) +{ + DECODE_FIELDS; + + NormColor(sf, lm, 0); + + return(14); +} + +int32 NCT(uint32 instr) +{ + DECODE_FIELDS; + int i; + + for(i = 0; i < 3; i++) + NormColor(sf, lm, i); + + return(30); +} + +INLINE void NormColorColor(uint32 v, uint32 sf, int lm) +{ + int16 tmp_vector[3]; + + MultiplyMatrixByVector(&Matrices.Light, Vectors[v], CRVectors.Null, sf, lm); + + tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3; + MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm); + + MAC[1] = ((RGB.R << 4) * IR1) >> sf; + MAC[2] = ((RGB.G << 4) * IR2) >> sf; + MAC[3] = ((RGB.B << 4) * IR3) >> sf; + + MAC_to_IR(lm); + + MAC_to_RGB_FIFO(); +} + +int32 NCCS(uint32 instr) +{ + DECODE_FIELDS; + + NormColorColor(0, sf, lm); + return(17); +} + + +int32 NCCT(uint32 instr) +{ + int i; + DECODE_FIELDS; + + for(i = 0; i < 3; i++) + NormColorColor(i, sf, lm); + + return(39); +} + +INLINE void DepthCue(int mult_IR123, int RGB_from_FIFO, uint32 sf, int lm) +{ + int32 RGB_temp[3]; + int32 IR_temp[3] = { IR1, IR2, IR3 }; + int i; + + //assert(sf); + + if(RGB_from_FIFO) + { + RGB_temp[0] = RGB_FIFO[0].R << 4; + RGB_temp[1] = RGB_FIFO[0].G << 4; + RGB_temp[2] = RGB_FIFO[0].B << 4; + } + else + { + RGB_temp[0] = RGB.R << 4; + RGB_temp[1] = RGB.G << 4; + RGB_temp[2] = RGB.B << 4; + } + + if(mult_IR123) + { + for(i = 0; i < 3; i++) + { + MAC[1 + i] = A_MV(i, (((int64)CRVectors.FC[i] << 12) - RGB_temp[i] * IR_temp[i])) >> sf; + MAC[1 + i] = A_MV(i, (RGB_temp[i] * IR_temp[i] + IR0 * Lm_B(i, MAC[1 + i], FALSE))) >> sf; + } + } + else + { + for(i = 0; i < 3; i++) + { + MAC[1 + i] = A_MV(i, (((int64)CRVectors.FC[i] << 12) - (RGB_temp[i] << 12))) >> sf; + MAC[1 + i] = A_MV(i, (((int64)RGB_temp[i] << 12) + IR0 * Lm_B(i, MAC[1 + i], FALSE))) >> sf; + } + } + + MAC_to_IR(lm); + + MAC_to_RGB_FIFO(); +} + + +int32 DCPL(uint32 instr) +{ + DECODE_FIELDS; + + DepthCue(TRUE, FALSE, sf, lm); + + return(8); +} + + +int32 DPCS(uint32 instr) +{ + DECODE_FIELDS; + + DepthCue(FALSE, FALSE, sf, lm); + + return(8); +} + +int32 DPCT(uint32 instr) +{ + int i; + DECODE_FIELDS; + + for(i = 0; i < 3; i++) + { + DepthCue(FALSE, TRUE, sf, lm); + } + + return(17); +} + +int32 INTPL(uint32 instr) +{ + DECODE_FIELDS; + + MAC[1] = A_MV(0, (((int64)CRVectors.FC[0] << 12) - (IR1 << 12))) >> sf; + MAC[2] = A_MV(1, (((int64)CRVectors.FC[1] << 12) - (IR2 << 12))) >> sf; + MAC[3] = A_MV(2, (((int64)CRVectors.FC[2] << 12) - (IR3 << 12))) >> sf; + + MAC[1] = A_MV(0, (((int64)IR1 << 12) + IR0 * Lm_B(0, MAC[1], FALSE)) >> sf); + MAC[2] = A_MV(1, (((int64)IR2 << 12) + IR0 * Lm_B(1, MAC[2], FALSE)) >> sf); + MAC[3] = A_MV(2, (((int64)IR3 << 12) + IR0 * Lm_B(2, MAC[3], FALSE)) >> sf); + + MAC_to_IR(lm); + + MAC_to_RGB_FIFO(); + + return(8); +} + + +INLINE void NormColorDepthCue(uint32 v, uint32 sf, int lm) +{ + int16 tmp_vector[3]; + + MultiplyMatrixByVector(&Matrices.Light, Vectors[v], CRVectors.Null, sf, lm); + + tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3; + MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm); + + DepthCue(TRUE, FALSE, sf, lm); +} + +int32 NCDS(uint32 instr) +{ + DECODE_FIELDS; + + NormColorDepthCue(0, sf, lm); + + return(19); +} + +int32 NCDT(uint32 instr) +{ + int i; + DECODE_FIELDS; + + for(i = 0; i < 3; i++) + { + NormColorDepthCue(i, sf, lm); + } + + return(44); +} + +int32 CC(uint32 instr) +{ + DECODE_FIELDS; + int16 tmp_vector[3]; + + tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3; + MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm); + + MAC[1] = ((RGB.R << 4) * IR1) >> sf; + MAC[2] = ((RGB.G << 4) * IR2) >> sf; + MAC[3] = ((RGB.B << 4) * IR3) >> sf; + + MAC_to_IR(lm); + + MAC_to_RGB_FIFO(); + + return(11); +} + +int32 CDP(uint32 instr) +{ + DECODE_FIELDS; + int16 tmp_vector[3]; + + tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3; + MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm); + + DepthCue(TRUE, FALSE, sf, lm); + + return(13); +} + +int32 NCLIP(uint32 instr) +{ + DECODE_FIELDS; + + MAC[0] = F( (int64)(XY_FIFO[0].X * (XY_FIFO[1].Y - XY_FIFO[2].Y)) + (XY_FIFO[1].X * (XY_FIFO[2].Y - XY_FIFO[0].Y)) + (XY_FIFO[2].X * (XY_FIFO[0].Y - XY_FIFO[1].Y)) + ); + + return(8); +} + +int32 AVSZ3(uint32 instr) +{ + DECODE_FIELDS; + + MAC[0] = F(((int64)ZSF3 * (Z_FIFO[1] + Z_FIFO[2] + Z_FIFO[3]))); + + OTZ = Lm_D(MAC[0] >> 12, FALSE); + + return(5); +} + +int32 AVSZ4(uint32 instr) +{ + DECODE_FIELDS; + + MAC[0] = F(((int64)ZSF4 * (Z_FIFO[0] + Z_FIFO[1] + Z_FIFO[2] + Z_FIFO[3]))); + + OTZ = Lm_D(MAC[0] >> 12, FALSE); + + return(5); +} + + +// -32768 * -32768 - 32767 * -32768 = 2147450880 +// (2 ^ 31) - 1 = 2147483647 +int32 OP(uint32 instr) +{ + DECODE_FIELDS; + + MAC[1] = ((Matrices.Rot.MX[1][1] * IR3) - (Matrices.Rot.MX[2][2] * IR2)) >> sf; + MAC[2] = ((Matrices.Rot.MX[2][2] * IR1) - (Matrices.Rot.MX[0][0] * IR3)) >> sf; + MAC[3] = ((Matrices.Rot.MX[0][0] * IR2) - (Matrices.Rot.MX[1][1] * IR1)) >> sf; + + MAC_to_IR(lm); + + return(6); +} + +int32 GPF(uint32 instr) +{ + DECODE_FIELDS; + + MAC[1] = (IR0 * IR1) >> sf; + MAC[2] = (IR0 * IR2) >> sf; + MAC[3] = (IR0 * IR3) >> sf; + + MAC_to_IR(lm); + + MAC_to_RGB_FIFO(); + + return(5); +} + +int32 GPL(uint32 instr) +{ + DECODE_FIELDS; + + MAC[1] = A_MV(0, ((int64)MAC[1] << sf) + (IR0 * IR1)) >> sf; + MAC[2] = A_MV(1, ((int64)MAC[2] << sf) + (IR0 * IR2)) >> sf; + MAC[3] = A_MV(2, ((int64)MAC[3] << sf) + (IR0 * IR3)) >> sf; + + MAC_to_IR(lm); + + MAC_to_RGB_FIFO(); + + return(5); +} + +/* + +--------------------------------------------------------------------------------------------- +| 24 23 22 21 20 | 19 | 18 17 | 16 15 | 14 13 | 12 11 | 10 | 9 8 7 6 | 5 4 3 2 1 0 | +|-------------------------------------------------------------------------------------------| +| (unused) | sf | mx | v | cv |(unused)| lm | (unused) | opcode | +--------------------------------------------------------------------------------------------- + (unused) = unused, ignored + + sf = shift 12 + + mx = matrix selection + + v = source vector + + cv = add vector(translation/back/far color(bugged)/none) + + (unused) = unused, ignored + + lm = limit negative results to 0 + + (unused) = unused, ignored + + opcode = operation code +*/ + +int32 GTE_Instruction(uint32 instr) +{ + const unsigned code = instr & 0x3F; + int32 ret = 1; + + FLAGS = 0; + + switch(code) + { + default: +#ifndef PSXDEV_GTE_TESTING + PSX_WARNING("[GTE] Unknown instruction code: 0x%02x", code); +#endif + break; + + case 0x00: // alternate? + case 0x01: + ret = RTPS(instr); + break; + +/* + case 0x02: // UNSTABLE? + break; + + case 0x03: // UNSTABLE? + break; + + case 0x04: // Probably simple with v,cv,sf,mx,lm ignored. Same calculation as 0x3B? + break; + + case 0x05: // UNSTABLE? + break; +*/ + + case 0x06: + ret = NCLIP(instr); + break; + +/* + case 0x07: // UNSTABLE? + break; + + case 0x08: // UNSTABLE? + break; + + case 0x09: // UNSTABLE? + break; + + case 0x0A: // UNSTABLE? + break; + + case 0x0B: // UNSTABLE? + break; + +*/ + + case 0x0C: + ret = OP(instr); + break; + +/* + case 0x0D: // UNSTABLE? + break; + + case 0x0E: // UNSTABLE? + break; + + case 0x0F: // UNSTABLE? + break; +*/ + + case 0x10: + ret = DPCS(instr); + break; + + case 0x11: + ret = INTPL(instr); + break; + + case 0x12: + ret = MVMVA(instr); + break; + + case 0x13: + ret = NCDS(instr); + break; + + case 0x14: + ret = CDP(instr); + break; + + +/* + case 0x15: // does one push on RGB FIFO, what else... + break; +*/ + + case 0x16: + ret = NCDT(instr); + break; + +/* + case 0x17: // PARTIALLY UNSTABLE(depending on sf or v or cv or mx or lm???), similar behavior under some conditions to 0x16? + break; + + case 0x18: + break; + + case 0x19: + break; +*/ + + case 0x1A: // Alternate for 0x29? + ret = DCPL(instr); + break; + + case 0x1B: + ret = NCCS(instr); + break; + + case 0x1C: + ret = CC(instr); + break; + +/* + case 0x1D: + break; +*/ + + case 0x1E: + ret = NCS(instr); + break; + +/* + case 0x1F: + break; +*/ + + case 0x20: + ret = NCT(instr); + break; +/* + case 0x21: + break; + + case 0x22: // UNSTABLE? + break; + + case 0x23: + break; + + case 0x24: + break; + + case 0x25: + break; + + case 0x26: + break; + + case 0x27: + break; +*/ + + case 0x28: + ret = SQR(instr); + break; + + case 0x29: + ret = DCPL(instr); + break; + + case 0x2A: + ret = DPCT(instr); + break; + +/* + case 0x2B: + break; + + case 0x2C: + break; +*/ + + case 0x2D: + ret = AVSZ3(instr); + break; + + case 0x2E: + ret = AVSZ4(instr); + break; + +/* + case 0x2F: // UNSTABLE? + break; +*/ + + case 0x30: + ret = RTPT(instr); + break; + +/* + case 0x31: // UNSTABLE? + break; + + case 0x32: // UNSTABLE? + break; + + case 0x33: // UNSTABLE? + break; + + case 0x34: // UNSTABLE? + break; + + case 0x35: // UNSTABLE? + break; + + case 0x36: // UNSTABLE? + break; + + case 0x37: // UNSTABLE? + break; + + case 0x38: + break; + + case 0x39: // Probably simple with v,cv,sf,mx,lm ignored. + break; + + case 0x3A: // Probably simple with v,cv,sf,mx,lm ignored. + break; + + case 0x3B: // Probably simple with v,cv,sf,mx,lm ignored. Same calculation as 0x04? + break; + + case 0x3C: // UNSTABLE? + break; +*/ + + case 0x3D: + ret = GPF(instr); + break; + + case 0x3E: + ret = GPL(instr); + break; + + case 0x3F: + ret = NCCT(instr); + break; + } + + if(FLAGS & 0x7f87e000) + FLAGS |= 1 << 31; + + CR[31] = FLAGS; + + return(ret - 1); +} + +#ifndef PSXDEV_GTE_TESTING +} +#endif diff --git a/mednafen/psx-0925/gte.h b/mednafen/psx-0925/gte.h new file mode 100644 index 00000000..fdac4a1e --- /dev/null +++ b/mednafen/psx-0925/gte.h @@ -0,0 +1,21 @@ +#ifndef __MDFN_PSX_GTE_H +#define __MDFN_PSX_GTE_H + +namespace MDFN_IEN_PSX +{ + +void GTE_Power(void); +int GTE_StateAction(StateMem *sm, int load, int data_only); + +int32 GTE_Instruction(uint32 instr); + +void GTE_WriteCR(unsigned int which, uint32 value); +void GTE_WriteDR(unsigned int which, uint32 value); + +uint32 GTE_ReadCR(unsigned int which); +uint32 GTE_ReadDR(unsigned int which); + + +} + +#endif diff --git a/mednafen/psx-0925/gte_divrecip.inc b/mednafen/psx-0925/gte_divrecip.inc new file mode 100644 index 00000000..25e7b1e7 --- /dev/null +++ b/mednafen/psx-0925/gte_divrecip.inc @@ -0,0 +1,32768 @@ +0x00020000, +0x0001fffc, +0x0001fff8, +0x0001fff4, +0x0001fff0, +0x0001ffec, +0x0001ffe8, +0x0001ffe4, +0x0001ffe0, +0x0001ffdc, +0x0001ffd8, +0x0001ffd4, +0x0001ffd0, +0x0001ffcc, +0x0001ffc8, +0x0001ffc4, +0x0001ffc0, +0x0001ffbc, +0x0001ffb8, +0x0001ffb4, +0x0001ffb0, +0x0001ffac, +0x0001ffa8, +0x0001ffa4, +0x0001ffa0, +0x0001ff9c, +0x0001ff98, +0x0001ff94, +0x0001ff90, +0x0001ff8c, +0x0001ff88, +0x0001ff84, +0x0001ff80, +0x0001ff7c, +0x0001ff78, +0x0001ff74, +0x0001ff70, +0x0001ff6c, +0x0001ff68, +0x0001ff64, +0x0001ff60, +0x0001ff5c, +0x0001ff58, +0x0001ff54, +0x0001ff50, +0x0001ff4c, +0x0001ff48, +0x0001ff44, +0x0001ff40, +0x0001ff3c, +0x0001ff38, +0x0001ff34, +0x0001ff30, +0x0001ff2c, +0x0001ff28, +0x0001ff24, +0x0001ff20, +0x0001ff1c, +0x0001ff18, +0x0001ff14, +0x0001ff10, +0x0001ff0c, +0x0001ff08, +0x0001ff04, +0x0001ff01, +0x0001fefd, +0x0001fef9, +0x0001fef5, +0x0001fef1, +0x0001feed, +0x0001fee9, +0x0001fee5, +0x0001fee1, +0x0001fedd, +0x0001fed9, +0x0001fed5, +0x0001fed1, +0x0001fecd, +0x0001fec9, +0x0001fec5, +0x0001fec1, +0x0001febd, +0x0001feb9, +0x0001feb5, +0x0001feb1, +0x0001fead, +0x0001fea9, +0x0001fea5, +0x0001fea1, +0x0001fe9d, +0x0001fe99, +0x0001fe95, +0x0001fe91, +0x0001fe8d, +0x0001fe89, +0x0001fe85, +0x0001fe81, +0x0001fe7e, +0x0001fe7a, +0x0001fe76, +0x0001fe72, +0x0001fe6e, +0x0001fe6a, +0x0001fe66, +0x0001fe62, +0x0001fe5e, +0x0001fe5a, +0x0001fe56, +0x0001fe52, +0x0001fe4e, +0x0001fe4a, +0x0001fe46, +0x0001fe42, +0x0001fe3e, +0x0001fe3a, +0x0001fe36, +0x0001fe32, +0x0001fe2e, +0x0001fe2a, +0x0001fe26, +0x0001fe22, +0x0001fe1e, +0x0001fe1a, +0x0001fe16, +0x0001fe12, +0x0001fe0e, +0x0001fe0a, +0x0001fe06, +0x0001fe02, +0x0001fdfe, +0x0001fdfa, +0x0001fdf6, +0x0001fdf2, +0x0001fdee, +0x0001fdea, +0x0001fde6, +0x0001fde2, +0x0001fdde, +0x0001fdda, +0x0001fdd6, +0x0001fdd2, +0x0001fdce, +0x0001fdca, +0x0001fdc6, +0x0001fdc2, +0x0001fdbe, +0x0001fdba, +0x0001fdb6, +0x0001fdb2, +0x0001fdae, +0x0001fdaa, +0x0001fda6, +0x0001fda2, +0x0001fd9e, +0x0001fd9a, +0x0001fd96, +0x0001fd92, +0x0001fd8e, +0x0001fd8a, +0x0001fd86, +0x0001fd82, +0x0001fd7f, +0x0001fd7b, +0x0001fd77, +0x0001fd73, +0x0001fd6f, +0x0001fd6b, +0x0001fd67, +0x0001fd63, +0x0001fd5f, +0x0001fd5b, +0x0001fd57, +0x0001fd53, +0x0001fd4f, +0x0001fd4b, +0x0001fd47, +0x0001fd43, +0x0001fd3f, +0x0001fd3b, +0x0001fd37, +0x0001fd33, +0x0001fd2f, +0x0001fd2b, +0x0001fd27, +0x0001fd23, +0x0001fd1f, +0x0001fd1b, +0x0001fd17, +0x0001fd13, +0x0001fd0f, +0x0001fd0b, +0x0001fd07, +0x0001fd04, +0x0001fd00, +0x0001fcfc, +0x0001fcf8, +0x0001fcf4, +0x0001fcf0, +0x0001fcec, +0x0001fce8, +0x0001fce4, +0x0001fce0, +0x0001fcdc, +0x0001fcd8, +0x0001fcd4, +0x0001fcd0, +0x0001fccc, +0x0001fcc8, +0x0001fcc4, +0x0001fcc0, +0x0001fcbd, +0x0001fcb9, +0x0001fcb5, +0x0001fcb1, +0x0001fcad, +0x0001fca9, +0x0001fca5, +0x0001fca1, +0x0001fc9d, +0x0001fc99, +0x0001fc95, +0x0001fc91, +0x0001fc8d, +0x0001fc89, +0x0001fc87, +0x0001fc83, +0x0001fc7f, +0x0001fc7b, +0x0001fc77, +0x0001fc73, +0x0001fc6f, +0x0001fc6b, +0x0001fc67, +0x0001fc63, +0x0001fc5f, +0x0001fc5b, +0x0001fc57, +0x0001fc53, +0x0001fc4f, +0x0001fc4b, +0x0001fc47, +0x0001fc43, +0x0001fc40, +0x0001fc3c, +0x0001fc38, +0x0001fc34, +0x0001fc30, +0x0001fc2c, +0x0001fc28, +0x0001fc24, +0x0001fc20, +0x0001fc1c, +0x0001fc18, +0x0001fc14, +0x0001fc10, +0x0001fc0c, +0x0001fc08, +0x0001fc04, +0x0001fc00, +0x0001fbfc, +0x0001fbf8, +0x0001fbf4, +0x0001fbf0, +0x0001fbec, +0x0001fbe8, +0x0001fbe4, +0x0001fbe0, +0x0001fbdc, +0x0001fbd8, +0x0001fbd4, +0x0001fbd0, +0x0001fbcc, +0x0001fbc8, +0x0001fbc4, +0x0001fbc1, +0x0001fbbd, +0x0001fbb9, +0x0001fbb5, +0x0001fbb1, +0x0001fbad, +0x0001fba9, +0x0001fba5, +0x0001fba1, +0x0001fb9d, +0x0001fb99, +0x0001fb95, +0x0001fb91, +0x0001fb8d, +0x0001fb8b, +0x0001fb87, +0x0001fb83, +0x0001fb7f, +0x0001fb7b, +0x0001fb77, +0x0001fb73, +0x0001fb6f, +0x0001fb6b, +0x0001fb67, +0x0001fb63, +0x0001fb5f, +0x0001fb5b, +0x0001fb57, +0x0001fb53, +0x0001fb4f, +0x0001fb4b, +0x0001fb47, +0x0001fb43, +0x0001fb40, +0x0001fb3c, +0x0001fb38, +0x0001fb34, +0x0001fb30, +0x0001fb2c, +0x0001fb28, +0x0001fb24, +0x0001fb20, +0x0001fb1c, +0x0001fb18, +0x0001fb14, +0x0001fb10, +0x0001fb0d, +0x0001fb09, +0x0001fb05, +0x0001fb01, +0x0001fafd, +0x0001faf9, +0x0001faf5, +0x0001faf1, +0x0001faed, +0x0001fae9, +0x0001fae5, +0x0001fae1, +0x0001fadd, +0x0001fad9, +0x0001fad5, +0x0001fad2, +0x0001face, +0x0001faca, +0x0001fac6, +0x0001fac2, +0x0001fabe, +0x0001faba, +0x0001fab6, +0x0001fab2, +0x0001faae, +0x0001faaa, +0x0001faa6, +0x0001faa2, +0x0001fa9e, +0x0001fa9a, +0x0001fa96, +0x0001fa92, +0x0001fa8e, +0x0001fa8a, +0x0001fa86, +0x0001fa82, +0x0001fa7f, +0x0001fa7b, +0x0001fa77, +0x0001fa73, +0x0001fa6f, +0x0001fa6b, +0x0001fa67, +0x0001fa65, +0x0001fa61, +0x0001fa5d, +0x0001fa59, +0x0001fa55, +0x0001fa51, +0x0001fa4d, +0x0001fa49, +0x0001fa45, +0x0001fa41, +0x0001fa3d, +0x0001fa39, +0x0001fa35, +0x0001fa31, +0x0001fa2d, +0x0001fa2a, +0x0001fa26, +0x0001fa22, +0x0001fa1e, +0x0001fa1a, +0x0001fa16, +0x0001fa12, +0x0001fa0e, +0x0001fa0a, +0x0001fa06, +0x0001fa02, +0x0001f9fe, +0x0001f9fa, +0x0001f9f6, +0x0001f9f2, +0x0001f9ee, +0x0001f9ea, +0x0001f9e6, +0x0001f9e2, +0x0001f9de, +0x0001f9da, +0x0001f9d6, +0x0001f9d3, +0x0001f9cf, +0x0001f9cb, +0x0001f9c7, +0x0001f9c3, +0x0001f9bf, +0x0001f9bd, +0x0001f9b9, +0x0001f9b5, +0x0001f9b1, +0x0001f9ad, +0x0001f9a9, +0x0001f9a5, +0x0001f9a1, +0x0001f99d, +0x0001f999, +0x0001f995, +0x0001f991, +0x0001f98d, +0x0001f989, +0x0001f985, +0x0001f982, +0x0001f97e, +0x0001f97a, +0x0001f976, +0x0001f972, +0x0001f96e, +0x0001f96a, +0x0001f966, +0x0001f962, +0x0001f95e, +0x0001f95a, +0x0001f956, +0x0001f952, +0x0001f94e, +0x0001f94a, +0x0001f946, +0x0001f942, +0x0001f93e, +0x0001f93a, +0x0001f936, +0x0001f932, +0x0001f92e, +0x0001f92b, +0x0001f927, +0x0001f923, +0x0001f91f, +0x0001f91b, +0x0001f918, +0x0001f914, +0x0001f910, +0x0001f90c, +0x0001f908, +0x0001f904, +0x0001f900, +0x0001f8fc, +0x0001f8f8, +0x0001f8f4, +0x0001f8f0, +0x0001f8ec, +0x0001f8e8, +0x0001f8e4, +0x0001f8e0, +0x0001f8dd, +0x0001f8db, +0x0001f8d7, +0x0001f8d3, +0x0001f8cf, +0x0001f8cb, +0x0001f8c7, +0x0001f8c3, +0x0001f8bf, +0x0001f8bb, +0x0001f8b7, +0x0001f8b3, +0x0001f8af, +0x0001f8ab, +0x0001f8a7, +0x0001f8a3, +0x0001f89f, +0x0001f89c, +0x0001f898, +0x0001f894, +0x0001f890, +0x0001f88c, +0x0001f888, +0x0001f884, +0x0001f880, +0x0001f87c, +0x0001f878, +0x0001f874, +0x0001f870, +0x0001f86c, +0x0001f868, +0x0001f864, +0x0001f860, +0x0001f85f, +0x0001f85b, +0x0001f857, +0x0001f853, +0x0001f84f, +0x0001f84b, +0x0001f847, +0x0001f843, +0x0001f83f, +0x0001f83b, +0x0001f837, +0x0001f833, +0x0001f82f, +0x0001f82b, +0x0001f827, +0x0001f823, +0x0001f820, +0x0001f81c, +0x0001f818, +0x0001f814, +0x0001f810, +0x0001f80c, +0x0001f808, +0x0001f804, +0x0001f800, +0x0001f7fc, +0x0001f7f8, +0x0001f7f4, +0x0001f7f0, +0x0001f7ec, +0x0001f7e8, +0x0001f7e4, +0x0001f7e2, +0x0001f7df, +0x0001f7db, +0x0001f7d7, +0x0001f7d3, +0x0001f7cf, +0x0001f7cb, +0x0001f7c7, +0x0001f7c3, +0x0001f7bf, +0x0001f7bb, +0x0001f7b7, +0x0001f7b3, +0x0001f7af, +0x0001f7ab, +0x0001f7a7, +0x0001f7a3, +0x0001f7a0, +0x0001f79c, +0x0001f798, +0x0001f794, +0x0001f790, +0x0001f78c, +0x0001f788, +0x0001f784, +0x0001f780, +0x0001f77c, +0x0001f778, +0x0001f774, +0x0001f770, +0x0001f76c, +0x0001f768, +0x0001f766, +0x0001f763, +0x0001f75f, +0x0001f75b, +0x0001f757, +0x0001f753, +0x0001f74f, +0x0001f74b, +0x0001f747, +0x0001f743, +0x0001f73f, +0x0001f73b, +0x0001f737, +0x0001f733, +0x0001f72f, +0x0001f72b, +0x0001f728, +0x0001f724, +0x0001f720, +0x0001f71c, +0x0001f718, +0x0001f714, +0x0001f711, +0x0001f70d, +0x0001f709, +0x0001f705, +0x0001f701, +0x0001f6fd, +0x0001f6f9, +0x0001f6f5, +0x0001f6f1, +0x0001f6ed, +0x0001f6e9, +0x0001f6e5, +0x0001f6e2, +0x0001f6de, +0x0001f6da, +0x0001f6d6, +0x0001f6d2, +0x0001f6ce, +0x0001f6ca, +0x0001f6c6, +0x0001f6c4, +0x0001f6c0, +0x0001f6bc, +0x0001f6b8, +0x0001f6b4, +0x0001f6b0, +0x0001f6ad, +0x0001f6a9, +0x0001f6a5, +0x0001f6a1, +0x0001f69d, +0x0001f699, +0x0001f695, +0x0001f691, +0x0001f68d, +0x0001f689, +0x0001f685, +0x0001f681, +0x0001f67e, +0x0001f67a, +0x0001f676, +0x0001f672, +0x0001f66e, +0x0001f66a, +0x0001f666, +0x0001f662, +0x0001f660, +0x0001f65c, +0x0001f658, +0x0001f654, +0x0001f650, +0x0001f64c, +0x0001f649, +0x0001f645, +0x0001f641, +0x0001f63d, +0x0001f639, +0x0001f635, +0x0001f631, +0x0001f62d, +0x0001f629, +0x0001f625, +0x0001f621, +0x0001f61d, +0x0001f619, +0x0001f616, +0x0001f612, +0x0001f60e, +0x0001f60a, +0x0001f606, +0x0001f602, +0x0001f600, +0x0001f5fc, +0x0001f5f8, +0x0001f5f4, +0x0001f5f0, +0x0001f5ec, +0x0001f5e8, +0x0001f5e5, +0x0001f5e1, +0x0001f5dd, +0x0001f5d9, +0x0001f5d5, +0x0001f5d1, +0x0001f5cd, +0x0001f5c9, +0x0001f5c5, +0x0001f5c1, +0x0001f5bd, +0x0001f5b9, +0x0001f5b5, +0x0001f5b2, +0x0001f5ae, +0x0001f5aa, +0x0001f5a6, +0x0001f5a2, +0x0001f59e, +0x0001f59c, +0x0001f598, +0x0001f594, +0x0001f590, +0x0001f58c, +0x0001f588, +0x0001f584, +0x0001f581, +0x0001f57d, +0x0001f579, +0x0001f575, +0x0001f571, +0x0001f56d, +0x0001f569, +0x0001f565, +0x0001f561, +0x0001f55d, +0x0001f559, +0x0001f555, +0x0001f551, +0x0001f54e, +0x0001f54a, +0x0001f546, +0x0001f542, +0x0001f53e, +0x0001f53a, +0x0001f537, +0x0001f533, +0x0001f52f, +0x0001f52b, +0x0001f527, +0x0001f523, +0x0001f51f, +0x0001f51b, +0x0001f517, +0x0001f513, +0x0001f511, +0x0001f50e, +0x0001f50a, +0x0001f506, +0x0001f502, +0x0001f4fe, +0x0001f4fa, +0x0001f4f6, +0x0001f4f2, +0x0001f4ee, +0x0001f4ea, +0x0001f4e6, +0x0001f4e3, +0x0001f4df, +0x0001f4db, +0x0001f4d7, +0x0001f4d3, +0x0001f4cf, +0x0001f4cb, +0x0001f4c7, +0x0001f4c3, +0x0001f4c1, +0x0001f4bd, +0x0001f4ba, +0x0001f4b6, +0x0001f4b2, +0x0001f4ae, +0x0001f4aa, +0x0001f4a6, +0x0001f4a2, +0x0001f49e, +0x0001f49a, +0x0001f496, +0x0001f492, +0x0001f48f, +0x0001f48b, +0x0001f487, +0x0001f483, +0x0001f47f, +0x0001f47b, +0x0001f477, +0x0001f473, +0x0001f46f, +0x0001f46d, +0x0001f469, +0x0001f466, +0x0001f462, +0x0001f45e, +0x0001f45a, +0x0001f456, +0x0001f452, +0x0001f44e, +0x0001f44a, +0x0001f446, +0x0001f442, +0x0001f43f, +0x0001f43b, +0x0001f437, +0x0001f433, +0x0001f42f, +0x0001f42b, +0x0001f427, +0x0001f423, +0x0001f41f, +0x0001f41d, +0x0001f419, +0x0001f415, +0x0001f412, +0x0001f40e, +0x0001f40a, +0x0001f406, +0x0001f402, +0x0001f3fe, +0x0001f3fa, +0x0001f3f6, +0x0001f3f2, +0x0001f3ee, +0x0001f3eb, +0x0001f3e7, +0x0001f3e3, +0x0001f3df, +0x0001f3db, +0x0001f3d7, +0x0001f3d3, +0x0001f3cf, +0x0001f3cd, +0x0001f3c9, +0x0001f3c5, +0x0001f3c2, +0x0001f3be, +0x0001f3ba, +0x0001f3b6, +0x0001f3b2, +0x0001f3ae, +0x0001f3aa, +0x0001f3a6, +0x0001f3a2, +0x0001f39e, +0x0001f39a, +0x0001f397, +0x0001f393, +0x0001f38f, +0x0001f38b, +0x0001f387, +0x0001f383, +0x0001f37f, +0x0001f37b, +0x0001f379, +0x0001f375, +0x0001f371, +0x0001f36e, +0x0001f36a, +0x0001f366, +0x0001f362, +0x0001f35e, +0x0001f35a, +0x0001f356, +0x0001f352, +0x0001f34f, +0x0001f34b, +0x0001f347, +0x0001f343, +0x0001f33f, +0x0001f33b, +0x0001f337, +0x0001f333, +0x0001f32f, +0x0001f32c, +0x0001f328, +0x0001f324, +0x0001f320, +0x0001f31c, +0x0001f318, +0x0001f314, +0x0001f310, +0x0001f30c, +0x0001f30b, +0x0001f307, +0x0001f303, +0x0001f2ff, +0x0001f2fb, +0x0001f2f7, +0x0001f2f3, +0x0001f2ef, +0x0001f2eb, +0x0001f2e7, +0x0001f2e4, +0x0001f2e0, +0x0001f2dc, +0x0001f2d8, +0x0001f2d4, +0x0001f2d0, +0x0001f2cc, +0x0001f2c8, +0x0001f2c6, +0x0001f2c3, +0x0001f2bf, +0x0001f2bb, +0x0001f2b7, +0x0001f2b3, +0x0001f2af, +0x0001f2ab, +0x0001f2a7, +0x0001f2a3, +0x0001f2a0, +0x0001f29c, +0x0001f298, +0x0001f294, +0x0001f290, +0x0001f28c, +0x0001f288, +0x0001f284, +0x0001f282, +0x0001f27e, +0x0001f27b, +0x0001f277, +0x0001f273, +0x0001f26f, +0x0001f26b, +0x0001f267, +0x0001f263, +0x0001f25f, +0x0001f25b, +0x0001f258, +0x0001f254, +0x0001f250, +0x0001f24c, +0x0001f248, +0x0001f244, +0x0001f240, +0x0001f23c, +0x0001f23a, +0x0001f236, +0x0001f233, +0x0001f22f, +0x0001f22b, +0x0001f227, +0x0001f223, +0x0001f21f, +0x0001f21b, +0x0001f217, +0x0001f213, +0x0001f210, +0x0001f20c, +0x0001f208, +0x0001f204, +0x0001f200, +0x0001f1fc, +0x0001f1f8, +0x0001f1f6, +0x0001f1f2, +0x0001f1ee, +0x0001f1eb, +0x0001f1e7, +0x0001f1e3, +0x0001f1df, +0x0001f1db, +0x0001f1d7, +0x0001f1d3, +0x0001f1cf, +0x0001f1cb, +0x0001f1c8, +0x0001f1c4, +0x0001f1c0, +0x0001f1bc, +0x0001f1b8, +0x0001f1b4, +0x0001f1b2, +0x0001f1ae, +0x0001f1aa, +0x0001f1a7, +0x0001f1a3, +0x0001f19f, +0x0001f19b, +0x0001f197, +0x0001f193, +0x0001f18f, +0x0001f18b, +0x0001f187, +0x0001f184, +0x0001f180, +0x0001f17c, +0x0001f178, +0x0001f174, +0x0001f170, +0x0001f16c, +0x0001f168, +0x0001f165, +0x0001f161, +0x0001f15d, +0x0001f159, +0x0001f155, +0x0001f151, +0x0001f14f, +0x0001f14b, +0x0001f147, +0x0001f144, +0x0001f140, +0x0001f13c, +0x0001f138, +0x0001f134, +0x0001f130, +0x0001f12c, +0x0001f128, +0x0001f125, +0x0001f121, +0x0001f11d, +0x0001f119, +0x0001f115, +0x0001f113, +0x0001f10f, +0x0001f10b, +0x0001f108, +0x0001f104, +0x0001f100, +0x0001f0fc, +0x0001f0f8, +0x0001f0f4, +0x0001f0f0, +0x0001f0ec, +0x0001f0e9, +0x0001f0e5, +0x0001f0e1, +0x0001f0dd, +0x0001f0d9, +0x0001f0d7, +0x0001f0d3, +0x0001f0cf, +0x0001f0cb, +0x0001f0c8, +0x0001f0c4, +0x0001f0c0, +0x0001f0bc, +0x0001f0b8, +0x0001f0b4, +0x0001f0b0, +0x0001f0ac, +0x0001f0a9, +0x0001f0a5, +0x0001f0a1, +0x0001f09d, +0x0001f09b, +0x0001f097, +0x0001f093, +0x0001f08f, +0x0001f08c, +0x0001f088, +0x0001f084, +0x0001f080, +0x0001f07c, +0x0001f078, +0x0001f074, +0x0001f070, +0x0001f06d, +0x0001f069, +0x0001f065, +0x0001f061, +0x0001f05f, +0x0001f05b, +0x0001f057, +0x0001f053, +0x0001f04f, +0x0001f04c, +0x0001f048, +0x0001f044, +0x0001f040, +0x0001f03c, +0x0001f038, +0x0001f034, +0x0001f030, +0x0001f02d, +0x0001f029, +0x0001f025, +0x0001f023, +0x0001f01f, +0x0001f01b, +0x0001f017, +0x0001f013, +0x0001f010, +0x0001f00c, +0x0001f008, +0x0001f004, +0x0001f000, +0x0001effc, +0x0001eff8, +0x0001eff4, +0x0001eff1, +0x0001efed, +0x0001efe9, +0x0001efe7, +0x0001efe3, +0x0001efdf, +0x0001efdb, +0x0001efd7, +0x0001efd3, +0x0001efd0, +0x0001efcc, +0x0001efc8, +0x0001efc4, +0x0001efc0, +0x0001efbc, +0x0001efb8, +0x0001efb4, +0x0001efb1, +0x0001efad, +0x0001efab, +0x0001efa7, +0x0001efa3, +0x0001ef9f, +0x0001ef9b, +0x0001ef97, +0x0001ef94, +0x0001ef90, +0x0001ef8b, +0x0001ef87, +0x0001ef83, +0x0001ef80, +0x0001ef7e, +0x0001ef7a, +0x0001ef76, +0x0001ef72, +0x0001ef6e, +0x0001ef6a, +0x0001ef66, +0x0001ef63, +0x0001ef5f, +0x0001ef5b, +0x0001ef57, +0x0001ef53, +0x0001ef4f, +0x0001ef4b, +0x0001ef48, +0x0001ef46, +0x0001ef42, +0x0001ef3e, +0x0001ef3a, +0x0001ef36, +0x0001ef32, +0x0001ef2e, +0x0001ef2b, +0x0001ef27, +0x0001ef23, +0x0001ef1f, +0x0001ef1b, +0x0001ef17, +0x0001ef13, +0x0001ef0f, +0x0001ef0e, +0x0001ef0a, +0x0001ef06, +0x0001ef02, +0x0001eefe, +0x0001eefa, +0x0001eef6, +0x0001eef2, +0x0001eeef, +0x0001eeeb, +0x0001eee7, +0x0001eee3, +0x0001eedf, +0x0001eedb, +0x0001eed7, +0x0001eed5, +0x0001eed2, +0x0001eece, +0x0001eeca, +0x0001eec6, +0x0001eec2, +0x0001eebe, +0x0001eeba, +0x0001eeb7, +0x0001eeb3, +0x0001eeaf, +0x0001eeab, +0x0001eea7, +0x0001eea3, +0x0001ee9f, +0x0001ee9d, +0x0001ee9a, +0x0001ee96, +0x0001ee92, +0x0001ee8e, +0x0001ee8a, +0x0001ee86, +0x0001ee82, +0x0001ee7e, +0x0001ee7b, +0x0001ee77, +0x0001ee73, +0x0001ee6f, +0x0001ee6b, +0x0001ee67, +0x0001ee63, +0x0001ee61, +0x0001ee5e, +0x0001ee5a, +0x0001ee56, +0x0001ee52, +0x0001ee4e, +0x0001ee4a, +0x0001ee46, +0x0001ee43, +0x0001ee3f, +0x0001ee3b, +0x0001ee37, +0x0001ee33, +0x0001ee2f, +0x0001ee2b, +0x0001ee29, +0x0001ee26, +0x0001ee22, +0x0001ee1e, +0x0001ee1a, +0x0001ee16, +0x0001ee12, +0x0001ee0e, +0x0001ee0a, +0x0001ee07, +0x0001ee03, +0x0001edff, +0x0001edfb, +0x0001edf7, +0x0001edf3, +0x0001edf1, +0x0001eded, +0x0001edea, +0x0001ede6, +0x0001ede2, +0x0001edde, +0x0001edda, +0x0001edd6, +0x0001edd2, +0x0001edce, +0x0001edcb, +0x0001edc7, +0x0001edc3, +0x0001edbf, +0x0001edbb, +0x0001edb9, +0x0001edb5, +0x0001edb1, +0x0001edad, +0x0001eda9, +0x0001eda6, +0x0001eda2, +0x0001eda0, +0x0001ed9c, +0x0001ed98, +0x0001ed94, +0x0001ed90, +0x0001ed8d, +0x0001ed89, +0x0001ed85, +0x0001ed81, +0x0001ed7d, +0x0001ed79, +0x0001ed75, +0x0001ed72, +0x0001ed70, +0x0001ed6c, +0x0001ed68, +0x0001ed64, +0x0001ed60, +0x0001ed5c, +0x0001ed59, +0x0001ed55, +0x0001ed51, +0x0001ed4d, +0x0001ed49, +0x0001ed45, +0x0001ed41, +0x0001ed3e, +0x0001ed3c, +0x0001ed38, +0x0001ed34, +0x0001ed30, +0x0001ed2c, +0x0001ed28, +0x0001ed25, +0x0001ed21, +0x0001ed1d, +0x0001ed19, +0x0001ed15, +0x0001ed11, +0x0001ed0d, +0x0001ed0c, +0x0001ed08, +0x0001ed04, +0x0001ed00, +0x0001ecfc, +0x0001ecf8, +0x0001ecf4, +0x0001ecf1, +0x0001eced, +0x0001ece9, +0x0001ece5, +0x0001ece1, +0x0001ecdd, +0x0001ecd9, +0x0001ecd8, +0x0001ecd4, +0x0001ecd0, +0x0001eccc, +0x0001ecc8, +0x0001ecc4, +0x0001ecc0, +0x0001ecbd, +0x0001ecb9, +0x0001ecb5, +0x0001ecb1, +0x0001ecad, +0x0001eca9, +0x0001eca7, +0x0001eca4, +0x0001eca0, +0x0001ec9c, +0x0001ec98, +0x0001ec94, +0x0001ec90, +0x0001ec8c, +0x0001ec89, +0x0001ec85, +0x0001ec81, +0x0001ec7d, +0x0001ec79, +0x0001ec75, +0x0001ec73, +0x0001ec70, +0x0001ec6c, +0x0001ec68, +0x0001ec64, +0x0001ec60, +0x0001ec5c, +0x0001ec58, +0x0001ec55, +0x0001ec51, +0x0001ec4d, +0x0001ec49, +0x0001ec45, +0x0001ec43, +0x0001ec3f, +0x0001ec3c, +0x0001ec38, +0x0001ec34, +0x0001ec30, +0x0001ec2c, +0x0001ec28, +0x0001ec24, +0x0001ec21, +0x0001ec1d, +0x0001ec19, +0x0001ec15, +0x0001ec11, +0x0001ec0f, +0x0001ec0b, +0x0001ec08, +0x0001ec04, +0x0001ec00, +0x0001ebfc, +0x0001ebf8, +0x0001ebf4, +0x0001ebf0, +0x0001ebed, +0x0001ebe9, +0x0001ebe5, +0x0001ebe1, +0x0001ebdf, +0x0001ebdb, +0x0001ebd7, +0x0001ebd3, +0x0001ebcf, +0x0001ebcb, +0x0001ebc7, +0x0001ebc6, +0x0001ebc2, +0x0001ebbe, +0x0001ebba, +0x0001ebb6, +0x0001ebb2, +0x0001ebaf, +0x0001ebab, +0x0001eba7, +0x0001eba3, +0x0001eb9f, +0x0001eb9b, +0x0001eb99, +0x0001eb96, +0x0001eb92, +0x0001eb8e, +0x0001eb8a, +0x0001eb86, +0x0001eb82, +0x0001eb7f, +0x0001eb7b, +0x0001eb77, +0x0001eb73, +0x0001eb6f, +0x0001eb6d, +0x0001eb69, +0x0001eb66, +0x0001eb62, +0x0001eb5e, +0x0001eb5a, +0x0001eb56, +0x0001eb52, +0x0001eb4f, +0x0001eb4b, +0x0001eb47, +0x0001eb43, +0x0001eb41, +0x0001eb3d, +0x0001eb3a, +0x0001eb36, +0x0001eb32, +0x0001eb2e, +0x0001eb2a, +0x0001eb26, +0x0001eb23, +0x0001eb1f, +0x0001eb1b, +0x0001eb17, +0x0001eb15, +0x0001eb11, +0x0001eb0d, +0x0001eb0a, +0x0001eb06, +0x0001eb02, +0x0001eafe, +0x0001eafa, +0x0001eaf6, +0x0001eaf3, +0x0001eaef, +0x0001eaeb, +0x0001eae9, +0x0001eae5, +0x0001eae1, +0x0001eadd, +0x0001eada, +0x0001ead6, +0x0001ead2, +0x0001eace, +0x0001eaca, +0x0001eac6, +0x0001eac3, +0x0001eabf, +0x0001eabb, +0x0001eab9, +0x0001eab5, +0x0001eab1, +0x0001eaae, +0x0001eaaa, +0x0001eaa6, +0x0001eaa2, +0x0001ea9e, +0x0001ea9a, +0x0001ea97, +0x0001ea93, +0x0001ea8f, +0x0001ea8d, +0x0001ea89, +0x0001ea85, +0x0001ea81, +0x0001ea7e, +0x0001ea7a, +0x0001ea76, +0x0001ea72, +0x0001ea6e, +0x0001ea6a, +0x0001ea67, +0x0001ea63, +0x0001ea61, +0x0001ea5d, +0x0001ea59, +0x0001ea55, +0x0001ea51, +0x0001ea4e, +0x0001ea4a, +0x0001ea46, +0x0001ea42, +0x0001ea3e, +0x0001ea3a, +0x0001ea37, +0x0001ea35, +0x0001ea31, +0x0001ea2d, +0x0001ea29, +0x0001ea25, +0x0001ea22, +0x0001ea1e, +0x0001ea1a, +0x0001ea16, +0x0001ea12, +0x0001ea0e, +0x0001ea0b, +0x0001ea09, +0x0001ea05, +0x0001ea01, +0x0001e9fc, +0x0001e9f8, +0x0001e9f5, +0x0001e9f3, +0x0001e9ef, +0x0001e9eb, +0x0001e9e7, +0x0001e9e3, +0x0001e9df, +0x0001e9dc, +0x0001e9d8, +0x0001e9d4, +0x0001e9d0, +0x0001e9cc, +0x0001e9ca, +0x0001e9c7, +0x0001e9c3, +0x0001e9bf, +0x0001e9bb, +0x0001e9b7, +0x0001e9b4, +0x0001e9b0, +0x0001e9ac, +0x0001e9a8, +0x0001e9a4, +0x0001e9a0, +0x0001e99f, +0x0001e99b, +0x0001e997, +0x0001e993, +0x0001e98f, +0x0001e98b, +0x0001e988, +0x0001e984, +0x0001e980, +0x0001e97c, +0x0001e978, +0x0001e976, +0x0001e973, +0x0001e96f, +0x0001e96b, +0x0001e967, +0x0001e963, +0x0001e960, +0x0001e95c, +0x0001e958, +0x0001e954, +0x0001e950, +0x0001e94e, +0x0001e94a, +0x0001e947, +0x0001e943, +0x0001e93f, +0x0001e93b, +0x0001e937, +0x0001e934, +0x0001e930, +0x0001e92c, +0x0001e928, +0x0001e926, +0x0001e922, +0x0001e91f, +0x0001e91b, +0x0001e917, +0x0001e913, +0x0001e90f, +0x0001e90b, +0x0001e908, +0x0001e904, +0x0001e900, +0x0001e8fe, +0x0001e8fa, +0x0001e8f6, +0x0001e8f3, +0x0001e8ef, +0x0001e8eb, +0x0001e8e7, +0x0001e8e3, +0x0001e8e0, +0x0001e8dc, +0x0001e8d8, +0x0001e8d6, +0x0001e8d2, +0x0001e8ce, +0x0001e8cb, +0x0001e8c7, +0x0001e8c3, +0x0001e8bf, +0x0001e8bb, +0x0001e8b7, +0x0001e8b4, +0x0001e8b0, +0x0001e8ae, +0x0001e8aa, +0x0001e8a6, +0x0001e8a2, +0x0001e89f, +0x0001e89b, +0x0001e897, +0x0001e893, +0x0001e88f, +0x0001e88b, +0x0001e888, +0x0001e886, +0x0001e882, +0x0001e87e, +0x0001e87a, +0x0001e876, +0x0001e873, +0x0001e86f, +0x0001e86b, +0x0001e867, +0x0001e863, +0x0001e860, +0x0001e85c, +0x0001e85a, +0x0001e856, +0x0001e852, +0x0001e84e, +0x0001e84b, +0x0001e847, +0x0001e843, +0x0001e83f, +0x0001e83b, +0x0001e837, +0x0001e834, +0x0001e832, +0x0001e82e, +0x0001e829, +0x0001e825, +0x0001e821, +0x0001e81f, +0x0001e81b, +0x0001e818, +0x0001e814, +0x0001e810, +0x0001e80c, +0x0001e808, +0x0001e805, +0x0001e801, +0x0001e7fd, +0x0001e7fb, +0x0001e7f7, +0x0001e7f4, +0x0001e7f0, +0x0001e7ec, +0x0001e7e8, +0x0001e7e4, +0x0001e7e0, +0x0001e7dd, +0x0001e7d9, +0x0001e7d5, +0x0001e7d3, +0x0001e7cf, +0x0001e7cc, +0x0001e7c8, +0x0001e7c4, +0x0001e7c0, +0x0001e7bc, +0x0001e7b9, +0x0001e7b5, +0x0001e7b1, +0x0001e7af, +0x0001e7ab, +0x0001e7a7, +0x0001e7a4, +0x0001e7a0, +0x0001e79c, +0x0001e798, +0x0001e794, +0x0001e791, +0x0001e78d, +0x0001e78b, +0x0001e787, +0x0001e783, +0x0001e77f, +0x0001e77c, +0x0001e778, +0x0001e774, +0x0001e770, +0x0001e76c, +0x0001e769, +0x0001e767, +0x0001e763, +0x0001e75f, +0x0001e75b, +0x0001e758, +0x0001e754, +0x0001e750, +0x0001e74c, +0x0001e748, +0x0001e744, +0x0001e743, +0x0001e73f, +0x0001e73b, +0x0001e737, +0x0001e733, +0x0001e730, +0x0001e72c, +0x0001e728, +0x0001e724, +0x0001e720, +0x0001e71d, +0x0001e71b, +0x0001e717, +0x0001e713, +0x0001e70f, +0x0001e70b, +0x0001e708, +0x0001e704, +0x0001e700, +0x0001e6fc, +0x0001e6f8, +0x0001e6f6, +0x0001e6f3, +0x0001e6ef, +0x0001e6eb, +0x0001e6e7, +0x0001e6e3, +0x0001e6e0, +0x0001e6dc, +0x0001e6d8, +0x0001e6d4, +0x0001e6d2, +0x0001e6cf, +0x0001e6cb, +0x0001e6c7, +0x0001e6c3, +0x0001e6bf, +0x0001e6bc, +0x0001e6b8, +0x0001e6b4, +0x0001e6b0, +0x0001e6ae, +0x0001e6aa, +0x0001e6a7, +0x0001e6a3, +0x0001e69f, +0x0001e69b, +0x0001e697, +0x0001e694, +0x0001e690, +0x0001e68c, +0x0001e688, +0x0001e686, +0x0001e682, +0x0001e67f, +0x0001e67b, +0x0001e677, +0x0001e673, +0x0001e66f, +0x0001e66c, +0x0001e668, +0x0001e664, +0x0001e662, +0x0001e65e, +0x0001e659, +0x0001e655, +0x0001e651, +0x0001e64f, +0x0001e64c, +0x0001e648, +0x0001e644, +0x0001e640, +0x0001e63c, +0x0001e639, +0x0001e635, +0x0001e631, +0x0001e62f, +0x0001e62b, +0x0001e628, +0x0001e624, +0x0001e620, +0x0001e61c, +0x0001e618, +0x0001e615, +0x0001e611, +0x0001e60d, +0x0001e60b, +0x0001e607, +0x0001e604, +0x0001e600, +0x0001e5fc, +0x0001e5f8, +0x0001e5f4, +0x0001e5f1, +0x0001e5ed, +0x0001e5eb, +0x0001e5e7, +0x0001e5e3, +0x0001e5e0, +0x0001e5dc, +0x0001e5d8, +0x0001e5d4, +0x0001e5d0, +0x0001e5cd, +0x0001e5c9, +0x0001e5c7, +0x0001e5c3, +0x0001e5bf, +0x0001e5bc, +0x0001e5b8, +0x0001e5b4, +0x0001e5b0, +0x0001e5ac, +0x0001e5a9, +0x0001e5a7, +0x0001e5a3, +0x0001e59f, +0x0001e59b, +0x0001e598, +0x0001e594, +0x0001e590, +0x0001e58c, +0x0001e588, +0x0001e585, +0x0001e583, +0x0001e57f, +0x0001e57b, +0x0001e577, +0x0001e574, +0x0001e570, +0x0001e56c, +0x0001e568, +0x0001e564, +0x0001e563, +0x0001e55f, +0x0001e55b, +0x0001e557, +0x0001e553, +0x0001e550, +0x0001e54c, +0x0001e548, +0x0001e544, +0x0001e540, +0x0001e53f, +0x0001e53b, +0x0001e537, +0x0001e533, +0x0001e52f, +0x0001e52c, +0x0001e528, +0x0001e524, +0x0001e520, +0x0001e51e, +0x0001e51b, +0x0001e517, +0x0001e513, +0x0001e50f, +0x0001e50b, +0x0001e508, +0x0001e504, +0x0001e500, +0x0001e4fc, +0x0001e4fa, +0x0001e4f7, +0x0001e4f3, +0x0001e4ef, +0x0001e4eb, +0x0001e4e7, +0x0001e4e4, +0x0001e4e0, +0x0001e4dc, +0x0001e4da, +0x0001e4d6, +0x0001e4d3, +0x0001e4cf, +0x0001e4cb, +0x0001e4c7, +0x0001e4c3, +0x0001e4c0, +0x0001e4bc, +0x0001e4b8, +0x0001e4b6, +0x0001e4b2, +0x0001e4af, +0x0001e4ab, +0x0001e4a7, +0x0001e4a3, +0x0001e49f, +0x0001e49c, +0x0001e498, +0x0001e496, +0x0001e492, +0x0001e48e, +0x0001e48a, +0x0001e486, +0x0001e482, +0x0001e47f, +0x0001e47d, +0x0001e479, +0x0001e475, +0x0001e471, +0x0001e46e, +0x0001e46a, +0x0001e466, +0x0001e462, +0x0001e45f, +0x0001e45d, +0x0001e459, +0x0001e455, +0x0001e451, +0x0001e44e, +0x0001e44a, +0x0001e446, +0x0001e442, +0x0001e43e, +0x0001e43d, +0x0001e439, +0x0001e435, +0x0001e431, +0x0001e42d, +0x0001e42a, +0x0001e426, +0x0001e422, +0x0001e41e, +0x0001e41c, +0x0001e419, +0x0001e415, +0x0001e411, +0x0001e40d, +0x0001e409, +0x0001e406, +0x0001e402, +0x0001e3fe, +0x0001e3fa, +0x0001e3f8, +0x0001e3f5, +0x0001e3f1, +0x0001e3ed, +0x0001e3e9, +0x0001e3e6, +0x0001e3e2, +0x0001e3de, +0x0001e3da, +0x0001e3d8, +0x0001e3d5, +0x0001e3d1, +0x0001e3cd, +0x0001e3c9, +0x0001e3c5, +0x0001e3c2, +0x0001e3be, +0x0001e3ba, +0x0001e3b8, +0x0001e3b4, +0x0001e3b1, +0x0001e3ad, +0x0001e3a9, +0x0001e3a5, +0x0001e3a1, +0x0001e39e, +0x0001e39a, +0x0001e398, +0x0001e394, +0x0001e390, +0x0001e38d, +0x0001e389, +0x0001e385, +0x0001e381, +0x0001e37e, +0x0001e37a, +0x0001e378, +0x0001e374, +0x0001e370, +0x0001e36d, +0x0001e369, +0x0001e365, +0x0001e361, +0x0001e35d, +0x0001e35a, +0x0001e358, +0x0001e354, +0x0001e350, +0x0001e34c, +0x0001e349, +0x0001e345, +0x0001e341, +0x0001e33d, +0x0001e339, +0x0001e338, +0x0001e334, +0x0001e330, +0x0001e32c, +0x0001e328, +0x0001e325, +0x0001e321, +0x0001e31d, +0x0001e319, +0x0001e316, +0x0001e314, +0x0001e310, +0x0001e30c, +0x0001e308, +0x0001e305, +0x0001e301, +0x0001e2fd, +0x0001e2f9, +0x0001e2f5, +0x0001e2f4, +0x0001e2f0, +0x0001e2ec, +0x0001e2e8, +0x0001e2e4, +0x0001e2e1, +0x0001e2dd, +0x0001e2d9, +0x0001e2d5, +0x0001e2d3, +0x0001e2d0, +0x0001e2cc, +0x0001e2c8, +0x0001e2c6, +0x0001e2c2, +0x0001e2be, +0x0001e2ba, +0x0001e2b7, +0x0001e2b3, +0x0001e2af, +0x0001e2ab, +0x0001e2a8, +0x0001e2a6, +0x0001e2a2, +0x0001e29e, +0x0001e29a, +0x0001e297, +0x0001e293, +0x0001e28f, +0x0001e28b, +0x0001e288, +0x0001e286, +0x0001e282, +0x0001e27e, +0x0001e27a, +0x0001e277, +0x0001e273, +0x0001e26f, +0x0001e26b, +0x0001e269, +0x0001e266, +0x0001e262, +0x0001e25e, +0x0001e25a, +0x0001e257, +0x0001e253, +0x0001e24f, +0x0001e24b, +0x0001e249, +0x0001e246, +0x0001e242, +0x0001e23e, +0x0001e23a, +0x0001e237, +0x0001e233, +0x0001e22f, +0x0001e22d, +0x0001e229, +0x0001e226, +0x0001e222, +0x0001e21e, +0x0001e21a, +0x0001e217, +0x0001e213, +0x0001e20f, +0x0001e20d, +0x0001e209, +0x0001e206, +0x0001e202, +0x0001e1fe, +0x0001e1fa, +0x0001e1f7, +0x0001e1f3, +0x0001e1f1, +0x0001e1ed, +0x0001e1e9, +0x0001e1e6, +0x0001e1e2, +0x0001e1de, +0x0001e1da, +0x0001e1d7, +0x0001e1d3, +0x0001e1d1, +0x0001e1cd, +0x0001e1c9, +0x0001e1c6, +0x0001e1c2, +0x0001e1be, +0x0001e1ba, +0x0001e1b7, +0x0001e1b5, +0x0001e1b1, +0x0001e1ad, +0x0001e1a9, +0x0001e1a6, +0x0001e1a2, +0x0001e19e, +0x0001e19a, +0x0001e197, +0x0001e195, +0x0001e191, +0x0001e18d, +0x0001e189, +0x0001e186, +0x0001e182, +0x0001e17e, +0x0001e17a, +0x0001e178, +0x0001e175, +0x0001e171, +0x0001e16d, +0x0001e169, +0x0001e166, +0x0001e162, +0x0001e15e, +0x0001e15a, +0x0001e158, +0x0001e155, +0x0001e151, +0x0001e14d, +0x0001e149, +0x0001e146, +0x0001e142, +0x0001e13e, +0x0001e13c, +0x0001e138, +0x0001e135, +0x0001e131, +0x0001e12d, +0x0001e129, +0x0001e126, +0x0001e122, +0x0001e11e, +0x0001e11c, +0x0001e118, +0x0001e115, +0x0001e111, +0x0001e10d, +0x0001e109, +0x0001e106, +0x0001e102, +0x0001e0ff, +0x0001e0fb, +0x0001e0f8, +0x0001e0f4, +0x0001e0f2, +0x0001e0ee, +0x0001e0ea, +0x0001e0e7, +0x0001e0e3, +0x0001e0df, +0x0001e0db, +0x0001e0d8, +0x0001e0d6, +0x0001e0d2, +0x0001e0ce, +0x0001e0cb, +0x0001e0c7, +0x0001e0c3, +0x0001e0bf, +0x0001e0bc, +0x0001e0ba, +0x0001e0b6, +0x0001e0b2, +0x0001e0ae, +0x0001e0ab, +0x0001e0a7, +0x0001e0a3, +0x0001e09f, +0x0001e09e, +0x0001e09a, +0x0001e096, +0x0001e092, +0x0001e08f, +0x0001e08b, +0x0001e087, +0x0001e083, +0x0001e081, +0x0001e07e, +0x0001e07a, +0x0001e076, +0x0001e072, +0x0001e06f, +0x0001e06b, +0x0001e067, +0x0001e065, +0x0001e062, +0x0001e05e, +0x0001e05a, +0x0001e056, +0x0001e053, +0x0001e04f, +0x0001e04b, +0x0001e049, +0x0001e045, +0x0001e042, +0x0001e03e, +0x0001e03a, +0x0001e036, +0x0001e033, +0x0001e02f, +0x0001e02d, +0x0001e029, +0x0001e026, +0x0001e022, +0x0001e01e, +0x0001e01a, +0x0001e017, +0x0001e013, +0x0001e011, +0x0001e00d, +0x0001e009, +0x0001e006, +0x0001e002, +0x0001dffe, +0x0001dffa, +0x0001dff7, +0x0001dff5, +0x0001dff1, +0x0001dfed, +0x0001dfea, +0x0001dfe6, +0x0001dfe2, +0x0001dfde, +0x0001dfdb, +0x0001dfd9, +0x0001dfd5, +0x0001dfd1, +0x0001dfcd, +0x0001dfca, +0x0001dfc6, +0x0001dfc2, +0x0001dfbe, +0x0001dfbd, +0x0001dfb9, +0x0001dfb5, +0x0001dfb1, +0x0001dfae, +0x0001dfaa, +0x0001dfa6, +0x0001dfa2, +0x0001dfa0, +0x0001df9d, +0x0001df99, +0x0001df95, +0x0001df91, +0x0001df8e, +0x0001df8a, +0x0001df86, +0x0001df84, +0x0001df81, +0x0001df7d, +0x0001df79, +0x0001df75, +0x0001df72, +0x0001df6e, +0x0001df6a, +0x0001df68, +0x0001df64, +0x0001df61, +0x0001df5d, +0x0001df59, +0x0001df55, +0x0001df52, +0x0001df4e, +0x0001df4c, +0x0001df48, +0x0001df45, +0x0001df41, +0x0001df3d, +0x0001df3a, +0x0001df36, +0x0001df32, +0x0001df2e, +0x0001df2b, +0x0001df27, +0x0001df23, +0x0001df21, +0x0001df1e, +0x0001df1a, +0x0001df16, +0x0001df12, +0x0001df0f, +0x0001df0b, +0x0001df07, +0x0001df05, +0x0001df02, +0x0001defe, +0x0001defa, +0x0001def6, +0x0001def3, +0x0001deef, +0x0001deed, +0x0001dee9, +0x0001dee6, +0x0001dee2, +0x0001dede, +0x0001deda, +0x0001ded7, +0x0001ded3, +0x0001ded1, +0x0001decd, +0x0001deca, +0x0001dec6, +0x0001dec2, +0x0001debe, +0x0001debb, +0x0001deb9, +0x0001deb5, +0x0001deb1, +0x0001deae, +0x0001deaa, +0x0001dea6, +0x0001dea2, +0x0001de9f, +0x0001de9d, +0x0001de99, +0x0001de95, +0x0001de92, +0x0001de8e, +0x0001de8a, +0x0001de86, +0x0001de85, +0x0001de81, +0x0001de7d, +0x0001de79, +0x0001de76, +0x0001de72, +0x0001de6e, +0x0001de6a, +0x0001de69, +0x0001de65, +0x0001de61, +0x0001de5d, +0x0001de5a, +0x0001de56, +0x0001de52, +0x0001de50, +0x0001de4d, +0x0001de49, +0x0001de45, +0x0001de41, +0x0001de3e, +0x0001de3a, +0x0001de36, +0x0001de34, +0x0001de31, +0x0001de2d, +0x0001de29, +0x0001de25, +0x0001de22, +0x0001de1e, +0x0001de1c, +0x0001de18, +0x0001de15, +0x0001de11, +0x0001de0d, +0x0001de09, +0x0001de06, +0x0001de02, +0x0001de00, +0x0001ddfc, +0x0001ddf9, +0x0001ddf5, +0x0001ddf1, +0x0001dded, +0x0001ddea, +0x0001dde8, +0x0001dde4, +0x0001dde0, +0x0001dddd, +0x0001ddd9, +0x0001ddd5, +0x0001ddd1, +0x0001ddce, +0x0001ddcc, +0x0001ddc8, +0x0001ddc4, +0x0001ddc1, +0x0001ddbd, +0x0001ddb9, +0x0001ddb5, +0x0001ddb3, +0x0001ddb0, +0x0001ddac, +0x0001dda8, +0x0001dda5, +0x0001dda1, +0x0001dd9d, +0x0001dd99, +0x0001dd97, +0x0001dd94, +0x0001dd90, +0x0001dd8c, +0x0001dd89, +0x0001dd85, +0x0001dd81, +0x0001dd7f, +0x0001dd7b, +0x0001dd77, +0x0001dd74, +0x0001dd70, +0x0001dd6c, +0x0001dd6a, +0x0001dd66, +0x0001dd63, +0x0001dd5f, +0x0001dd5b, +0x0001dd58, +0x0001dd54, +0x0001dd52, +0x0001dd4e, +0x0001dd4b, +0x0001dd47, +0x0001dd43, +0x0001dd3f, +0x0001dd3c, +0x0001dd38, +0x0001dd36, +0x0001dd32, +0x0001dd2f, +0x0001dd2b, +0x0001dd27, +0x0001dd23, +0x0001dd20, +0x0001dd1e, +0x0001dd1a, +0x0001dd16, +0x0001dd13, +0x0001dd0f, +0x0001dd0b, +0x0001dd07, +0x0001dd06, +0x0001dd02, +0x0001dcfe, +0x0001dcfa, +0x0001dcf7, +0x0001dcf3, +0x0001dcef, +0x0001dcec, +0x0001dcea, +0x0001dce6, +0x0001dce2, +0x0001dcde, +0x0001dcdb, +0x0001dcd7, +0x0001dcd3, +0x0001dcd1, +0x0001dcce, +0x0001dcca, +0x0001dcc6, +0x0001dcc3, +0x0001dcbf, +0x0001dcbb, +0x0001dcb9, +0x0001dcb5, +0x0001dcb2, +0x0001dcae, +0x0001dcaa, +0x0001dca7, +0x0001dca3, +0x0001dca1, +0x0001dc9d, +0x0001dc9a, +0x0001dc96, +0x0001dc92, +0x0001dc8e, +0x0001dc8b, +0x0001dc87, +0x0001dc85, +0x0001dc81, +0x0001dc7e, +0x0001dc7a, +0x0001dc76, +0x0001dc72, +0x0001dc6f, +0x0001dc6d, +0x0001dc69, +0x0001dc65, +0x0001dc62, +0x0001dc5e, +0x0001dc5a, +0x0001dc56, +0x0001dc55, +0x0001dc51, +0x0001dc4d, +0x0001dc49, +0x0001dc46, +0x0001dc42, +0x0001dc3e, +0x0001dc3a, +0x0001dc39, +0x0001dc35, +0x0001dc31, +0x0001dc2d, +0x0001dc2a, +0x0001dc26, +0x0001dc22, +0x0001dc20, +0x0001dc1d, +0x0001dc19, +0x0001dc15, +0x0001dc12, +0x0001dc0e, +0x0001dc0a, +0x0001dc08, +0x0001dc04, +0x0001dc01, +0x0001dbfd, +0x0001dbf9, +0x0001dbf6, +0x0001dbf2, +0x0001dbee, +0x0001dbec, +0x0001dbe9, +0x0001dbe5, +0x0001dbe1, +0x0001dbdd, +0x0001dbda, +0x0001dbd6, +0x0001dbd4, +0x0001dbd0, +0x0001dbcd, +0x0001dbc9, +0x0001dbc5, +0x0001dbc3, +0x0001dbbf, +0x0001dbbb, +0x0001dbb8, +0x0001dbb4, +0x0001dbb0, +0x0001dbae, +0x0001dbab, +0x0001dba7, +0x0001dba3, +0x0001dba0, +0x0001db9c, +0x0001db98, +0x0001db96, +0x0001db93, +0x0001db8f, +0x0001db8b, +0x0001db87, +0x0001db84, +0x0001db80, +0x0001db7e, +0x0001db7a, +0x0001db77, +0x0001db73, +0x0001db6f, +0x0001db6c, +0x0001db6a, +0x0001db66, +0x0001db62, +0x0001db5f, +0x0001db5b, +0x0001db57, +0x0001db53, +0x0001db52, +0x0001db4e, +0x0001db4a, +0x0001db47, +0x0001db43, +0x0001db3f, +0x0001db3b, +0x0001db3a, +0x0001db36, +0x0001db32, +0x0001db2e, +0x0001db2b, +0x0001db27, +0x0001db23, +0x0001db21, +0x0001db1e, +0x0001db1a, +0x0001db16, +0x0001db13, +0x0001db0f, +0x0001db0b, +0x0001db09, +0x0001db06, +0x0001db02, +0x0001dafe, +0x0001dafa, +0x0001daf7, +0x0001daf3, +0x0001daf1, +0x0001daed, +0x0001daea, +0x0001dae6, +0x0001dae2, +0x0001dadf, +0x0001dadb, +0x0001dad9, +0x0001dad5, +0x0001dad2, +0x0001dace, +0x0001daca, +0x0001dac6, +0x0001dac3, +0x0001dac1, +0x0001dabd, +0x0001dab9, +0x0001dab6, +0x0001dab2, +0x0001daae, +0x0001daab, +0x0001daa9, +0x0001daa5, +0x0001daa1, +0x0001da9e, +0x0001da9a, +0x0001da96, +0x0001da93, +0x0001da91, +0x0001da8d, +0x0001da89, +0x0001da86, +0x0001da82, +0x0001da7e, +0x0001da7a, +0x0001da79, +0x0001da75, +0x0001da71, +0x0001da6d, +0x0001da6a, +0x0001da66, +0x0001da62, +0x0001da60, +0x0001da5d, +0x0001da59, +0x0001da55, +0x0001da52, +0x0001da4e, +0x0001da4c, +0x0001da48, +0x0001da45, +0x0001da41, +0x0001da3d, +0x0001da39, +0x0001da36, +0x0001da34, +0x0001da30, +0x0001da2c, +0x0001da29, +0x0001da25, +0x0001da21, +0x0001da1e, +0x0001da1c, +0x0001da18, +0x0001da14, +0x0001da11, +0x0001da0d, +0x0001da0a, +0x0001da06, +0x0001da03, +0x0001d9ff, +0x0001d9fb, +0x0001d9f9, +0x0001d9f6, +0x0001d9f2, +0x0001d9ee, +0x0001d9eb, +0x0001d9e7, +0x0001d9e3, +0x0001d9e1, +0x0001d9de, +0x0001d9da, +0x0001d9d6, +0x0001d9d3, +0x0001d9cf, +0x0001d9cb, +0x0001d9c9, +0x0001d9c6, +0x0001d9c2, +0x0001d9be, +0x0001d9bb, +0x0001d9b7, +0x0001d9b5, +0x0001d9b1, +0x0001d9ae, +0x0001d9aa, +0x0001d9a6, +0x0001d9a3, +0x0001d99f, +0x0001d99d, +0x0001d999, +0x0001d996, +0x0001d992, +0x0001d98e, +0x0001d98b, +0x0001d989, +0x0001d985, +0x0001d981, +0x0001d97e, +0x0001d97a, +0x0001d976, +0x0001d973, +0x0001d971, +0x0001d96d, +0x0001d969, +0x0001d966, +0x0001d962, +0x0001d95e, +0x0001d95c, +0x0001d959, +0x0001d955, +0x0001d951, +0x0001d94e, +0x0001d94a, +0x0001d946, +0x0001d944, +0x0001d941, +0x0001d93d, +0x0001d939, +0x0001d936, +0x0001d932, +0x0001d930, +0x0001d92c, +0x0001d929, +0x0001d925, +0x0001d921, +0x0001d91e, +0x0001d91a, +0x0001d918, +0x0001d914, +0x0001d911, +0x0001d90d, +0x0001d909, +0x0001d906, +0x0001d902, +0x0001d900, +0x0001d8fc, +0x0001d8f9, +0x0001d8f5, +0x0001d8f1, +0x0001d8ee, +0x0001d8ec, +0x0001d8e8, +0x0001d8e4, +0x0001d8e1, +0x0001d8dd, +0x0001d8d9, +0x0001d8d6, +0x0001d8d4, +0x0001d8d0, +0x0001d8cc, +0x0001d8c9, +0x0001d8c5, +0x0001d8c1, +0x0001d8bf, +0x0001d8bc, +0x0001d8b8, +0x0001d8b4, +0x0001d8b1, +0x0001d8ad, +0x0001d8a9, +0x0001d8a7, +0x0001d8a4, +0x0001d8a0, +0x0001d89c, +0x0001d899, +0x0001d895, +0x0001d893, +0x0001d88f, +0x0001d88c, +0x0001d888, +0x0001d884, +0x0001d881, +0x0001d87d, +0x0001d87b, +0x0001d877, +0x0001d874, +0x0001d870, +0x0001d86c, +0x0001d868, +0x0001d865, +0x0001d863, +0x0001d85f, +0x0001d85c, +0x0001d858, +0x0001d854, +0x0001d851, +0x0001d84d, +0x0001d849, +0x0001d846, +0x0001d844, +0x0001d840, +0x0001d83c, +0x0001d839, +0x0001d835, +0x0001d831, +0x0001d830, +0x0001d82c, +0x0001d828, +0x0001d825, +0x0001d821, +0x0001d81d, +0x0001d819, +0x0001d818, +0x0001d814, +0x0001d810, +0x0001d80d, +0x0001d809, +0x0001d805, +0x0001d803, +0x0001d800, +0x0001d7fc, +0x0001d7f8, +0x0001d7f5, +0x0001d7f1, +0x0001d7ef, +0x0001d7ec, +0x0001d7e8, +0x0001d7e4, +0x0001d7e0, +0x0001d7dd, +0x0001d7db, +0x0001d7d7, +0x0001d7d4, +0x0001d7d0, +0x0001d7cc, +0x0001d7c9, +0x0001d7c5, +0x0001d7c3, +0x0001d7bf, +0x0001d7bc, +0x0001d7b8, +0x0001d7b4, +0x0001d7b1, +0x0001d7af, +0x0001d7ab, +0x0001d7a7, +0x0001d7a4, +0x0001d7a0, +0x0001d79c, +0x0001d79b, +0x0001d797, +0x0001d793, +0x0001d790, +0x0001d78c, +0x0001d788, +0x0001d786, +0x0001d783, +0x0001d77f, +0x0001d77b, +0x0001d778, +0x0001d774, +0x0001d770, +0x0001d76e, +0x0001d76b, +0x0001d767, +0x0001d763, +0x0001d760, +0x0001d75c, +0x0001d75a, +0x0001d756, +0x0001d753, +0x0001d74f, +0x0001d74b, +0x0001d748, +0x0001d746, +0x0001d742, +0x0001d73f, +0x0001d73b, +0x0001d737, +0x0001d734, +0x0001d732, +0x0001d72e, +0x0001d72a, +0x0001d727, +0x0001d723, +0x0001d71f, +0x0001d71c, +0x0001d71a, +0x0001d716, +0x0001d712, +0x0001d70f, +0x0001d70b, +0x0001d707, +0x0001d706, +0x0001d702, +0x0001d6fe, +0x0001d6fa, +0x0001d6f7, +0x0001d6f3, +0x0001d6f1, +0x0001d6ee, +0x0001d6ea, +0x0001d6e6, +0x0001d6e3, +0x0001d6df, +0x0001d6dd, +0x0001d6d9, +0x0001d6d6, +0x0001d6d2, +0x0001d6ce, +0x0001d6cb, +0x0001d6c7, +0x0001d6c5, +0x0001d6c1, +0x0001d6be, +0x0001d6ba, +0x0001d6b6, +0x0001d6b3, +0x0001d6b1, +0x0001d6ad, +0x0001d6aa, +0x0001d6a6, +0x0001d6a3, +0x0001d6a0, +0x0001d69c, +0x0001d698, +0x0001d695, +0x0001d691, +0x0001d68d, +0x0001d68c, +0x0001d688, +0x0001d684, +0x0001d681, +0x0001d67d, +0x0001d679, +0x0001d677, +0x0001d674, +0x0001d670, +0x0001d66c, +0x0001d669, +0x0001d665, +0x0001d663, +0x0001d65f, +0x0001d65c, +0x0001d658, +0x0001d654, +0x0001d651, +0x0001d64f, +0x0001d64b, +0x0001d648, +0x0001d644, +0x0001d640, +0x0001d63d, +0x0001d63b, +0x0001d637, +0x0001d633, +0x0001d630, +0x0001d62c, +0x0001d628, +0x0001d627, +0x0001d623, +0x0001d61f, +0x0001d61c, +0x0001d618, +0x0001d614, +0x0001d612, +0x0001d60f, +0x0001d60b, +0x0001d607, +0x0001d604, +0x0001d600, +0x0001d5fe, +0x0001d5fa, +0x0001d5f7, +0x0001d5f3, +0x0001d5ef, +0x0001d5ec, +0x0001d5ea, +0x0001d5e6, +0x0001d5e3, +0x0001d5df, +0x0001d5db, +0x0001d5d8, +0x0001d5d6, +0x0001d5d2, +0x0001d5ce, +0x0001d5cb, +0x0001d5c7, +0x0001d5c3, +0x0001d5c0, +0x0001d5be, +0x0001d5ba, +0x0001d5b7, +0x0001d5b3, +0x0001d5af, +0x0001d5ac, +0x0001d5aa, +0x0001d5a6, +0x0001d5a2, +0x0001d59f, +0x0001d59b, +0x0001d597, +0x0001d596, +0x0001d592, +0x0001d58e, +0x0001d58b, +0x0001d587, +0x0001d583, +0x0001d581, +0x0001d57e, +0x0001d57a, +0x0001d576, +0x0001d573, +0x0001d56f, +0x0001d56d, +0x0001d569, +0x0001d566, +0x0001d562, +0x0001d55e, +0x0001d55b, +0x0001d559, +0x0001d555, +0x0001d552, +0x0001d54e, +0x0001d54a, +0x0001d547, +0x0001d545, +0x0001d541, +0x0001d53d, +0x0001d53a, +0x0001d536, +0x0001d532, +0x0001d531, +0x0001d52d, +0x0001d529, +0x0001d526, +0x0001d522, +0x0001d51e, +0x0001d51c, +0x0001d519, +0x0001d515, +0x0001d511, +0x0001d50e, +0x0001d50a, +0x0001d508, +0x0001d504, +0x0001d501, +0x0001d4fd, +0x0001d4f9, +0x0001d4f6, +0x0001d4f3, +0x0001d4ef, +0x0001d4ec, +0x0001d4ea, +0x0001d4e6, +0x0001d4e3, +0x0001d4df, +0x0001d4db, +0x0001d4d8, +0x0001d4d6, +0x0001d4d2, +0x0001d4cf, +0x0001d4cb, +0x0001d4c7, +0x0001d4c4, +0x0001d4c2, +0x0001d4be, +0x0001d4ba, +0x0001d4b7, +0x0001d4b3, +0x0001d4b0, +0x0001d4ae, +0x0001d4aa, +0x0001d4a6, +0x0001d4a3, +0x0001d49f, +0x0001d49b, +0x0001d49a, +0x0001d496, +0x0001d492, +0x0001d48f, +0x0001d48b, +0x0001d489, +0x0001d485, +0x0001d482, +0x0001d47e, +0x0001d47a, +0x0001d477, +0x0001d475, +0x0001d471, +0x0001d46e, +0x0001d46a, +0x0001d466, +0x0001d463, +0x0001d461, +0x0001d45d, +0x0001d45a, +0x0001d456, +0x0001d452, +0x0001d44f, +0x0001d44d, +0x0001d449, +0x0001d445, +0x0001d442, +0x0001d43e, +0x0001d43b, +0x0001d439, +0x0001d435, +0x0001d431, +0x0001d42e, +0x0001d42a, +0x0001d426, +0x0001d425, +0x0001d421, +0x0001d41d, +0x0001d41a, +0x0001d416, +0x0001d414, +0x0001d410, +0x0001d40d, +0x0001d409, +0x0001d405, +0x0001d402, +0x0001d400, +0x0001d3fc, +0x0001d3f9, +0x0001d3f5, +0x0001d3f1, +0x0001d3ee, +0x0001d3ec, +0x0001d3e8, +0x0001d3e5, +0x0001d3e1, +0x0001d3dd, +0x0001d3da, +0x0001d3d8, +0x0001d3d4, +0x0001d3d0, +0x0001d3cd, +0x0001d3c9, +0x0001d3c6, +0x0001d3c4, +0x0001d3c0, +0x0001d3bc, +0x0001d3b9, +0x0001d3b5, +0x0001d3b3, +0x0001d3b0, +0x0001d3ac, +0x0001d3a8, +0x0001d3a5, +0x0001d3a1, +0x0001d39f, +0x0001d39b, +0x0001d398, +0x0001d394, +0x0001d390, +0x0001d38d, +0x0001d38b, +0x0001d387, +0x0001d384, +0x0001d380, +0x0001d37c, +0x0001d379, +0x0001d377, +0x0001d373, +0x0001d370, +0x0001d36c, +0x0001d368, +0x0001d365, +0x0001d363, +0x0001d35f, +0x0001d35b, +0x0001d358, +0x0001d354, +0x0001d351, +0x0001d34f, +0x0001d34b, +0x0001d348, +0x0001d344, +0x0001d340, +0x0001d33d, +0x0001d339, +0x0001d335, +0x0001d334, +0x0001d330, +0x0001d32c, +0x0001d329, +0x0001d325, +0x0001d321, +0x0001d320, +0x0001d31c, +0x0001d318, +0x0001d315, +0x0001d311, +0x0001d30f, +0x0001d30c, +0x0001d308, +0x0001d304, +0x0001d301, +0x0001d2fd, +0x0001d2fb, +0x0001d2f8, +0x0001d2f4, +0x0001d2f0, +0x0001d2ed, +0x0001d2eb, +0x0001d2e7, +0x0001d2e4, +0x0001d2e0, +0x0001d2dc, +0x0001d2d9, +0x0001d2d7, +0x0001d2d3, +0x0001d2d0, +0x0001d2cc, +0x0001d2c8, +0x0001d2c6, +0x0001d2c3, +0x0001d2bf, +0x0001d2bb, +0x0001d2b8, +0x0001d2b4, +0x0001d2b2, +0x0001d2af, +0x0001d2ab, +0x0001d2a7, +0x0001d2a4, +0x0001d2a0, +0x0001d29e, +0x0001d29b, +0x0001d297, +0x0001d293, +0x0001d290, +0x0001d28e, +0x0001d28a, +0x0001d287, +0x0001d283, +0x0001d27f, +0x0001d27c, +0x0001d27a, +0x0001d276, +0x0001d273, +0x0001d26f, +0x0001d26b, +0x0001d26a, +0x0001d266, +0x0001d262, +0x0001d25f, +0x0001d25b, +0x0001d257, +0x0001d256, +0x0001d252, +0x0001d24e, +0x0001d24b, +0x0001d247, +0x0001d245, +0x0001d242, +0x0001d23e, +0x0001d23a, +0x0001d237, +0x0001d233, +0x0001d231, +0x0001d22e, +0x0001d22a, +0x0001d226, +0x0001d223, +0x0001d21f, +0x0001d21d, +0x0001d219, +0x0001d216, +0x0001d212, +0x0001d20f, +0x0001d20d, +0x0001d209, +0x0001d205, +0x0001d202, +0x0001d1fe, +0x0001d1fb, +0x0001d1f9, +0x0001d1f5, +0x0001d1f1, +0x0001d1ee, +0x0001d1ea, +0x0001d1e8, +0x0001d1e5, +0x0001d1e1, +0x0001d1dd, +0x0001d1da, +0x0001d1d6, +0x0001d1d4, +0x0001d1d1, +0x0001d1cd, +0x0001d1c9, +0x0001d1c6, +0x0001d1c4, +0x0001d1c0, +0x0001d1bd, +0x0001d1b9, +0x0001d1b5, +0x0001d1b2, +0x0001d1b0, +0x0001d1ac, +0x0001d1a9, +0x0001d1a5, +0x0001d1a1, +0x0001d19e, +0x0001d19a, +0x0001d199, +0x0001d195, +0x0001d191, +0x0001d18e, +0x0001d18a, +0x0001d188, +0x0001d185, +0x0001d181, +0x0001d17d, +0x0001d17a, +0x0001d176, +0x0001d174, +0x0001d171, +0x0001d16d, +0x0001d169, +0x0001d166, +0x0001d164, +0x0001d160, +0x0001d15d, +0x0001d159, +0x0001d155, +0x0001d152, +0x0001d150, +0x0001d14c, +0x0001d149, +0x0001d145, +0x0001d141, +0x0001d140, +0x0001d13c, +0x0001d138, +0x0001d135, +0x0001d131, +0x0001d12d, +0x0001d12c, +0x0001d128, +0x0001d124, +0x0001d121, +0x0001d11d, +0x0001d11b, +0x0001d118, +0x0001d114, +0x0001d110, +0x0001d10d, +0x0001d10b, +0x0001d107, +0x0001d104, +0x0001d100, +0x0001d0fc, +0x0001d0f9, +0x0001d0f7, +0x0001d0f3, +0x0001d0f0, +0x0001d0ec, +0x0001d0e8, +0x0001d0e7, +0x0001d0e3, +0x0001d0df, +0x0001d0dc, +0x0001d0d8, +0x0001d0d4, +0x0001d0d3, +0x0001d0cf, +0x0001d0cb, +0x0001d0c8, +0x0001d0c4, +0x0001d0c2, +0x0001d0bf, +0x0001d0bb, +0x0001d0b7, +0x0001d0b4, +0x0001d0b0, +0x0001d0ae, +0x0001d0ab, +0x0001d0a7, +0x0001d0a3, +0x0001d0a0, +0x0001d09e, +0x0001d09a, +0x0001d097, +0x0001d093, +0x0001d08f, +0x0001d08c, +0x0001d08a, +0x0001d086, +0x0001d083, +0x0001d07f, +0x0001d07b, +0x0001d07a, +0x0001d076, +0x0001d072, +0x0001d06f, +0x0001d06b, +0x0001d069, +0x0001d066, +0x0001d062, +0x0001d05e, +0x0001d05b, +0x0001d057, +0x0001d055, +0x0001d052, +0x0001d04e, +0x0001d04a, +0x0001d047, +0x0001d045, +0x0001d041, +0x0001d03e, +0x0001d03a, +0x0001d036, +0x0001d033, +0x0001d031, +0x0001d02d, +0x0001d02a, +0x0001d026, +0x0001d022, +0x0001d021, +0x0001d01d, +0x0001d019, +0x0001d016, +0x0001d012, +0x0001d00e, +0x0001d00d, +0x0001d009, +0x0001d005, +0x0001d002, +0x0001cffe, +0x0001cffc, +0x0001cff8, +0x0001cff4, +0x0001cff2, +0x0001cfef, +0x0001cfeb, +0x0001cfe8, +0x0001cfe4, +0x0001cfe2, +0x0001cfde, +0x0001cfdb, +0x0001cfd7, +0x0001cfd4, +0x0001cfd2, +0x0001cfce, +0x0001cfcb, +0x0001cfc7, +0x0001cfc3, +0x0001cfc2, +0x0001cfbe, +0x0001cfba, +0x0001cfb7, +0x0001cfb3, +0x0001cfaf, +0x0001cfae, +0x0001cfaa, +0x0001cfa6, +0x0001cfa3, +0x0001cf9f, +0x0001cf9d, +0x0001cf9a, +0x0001cf96, +0x0001cf92, +0x0001cf8f, +0x0001cf8d, +0x0001cf89, +0x0001cf86, +0x0001cf82, +0x0001cf7f, +0x0001cf7d, +0x0001cf79, +0x0001cf76, +0x0001cf72, +0x0001cf6e, +0x0001cf6b, +0x0001cf69, +0x0001cf65, +0x0001cf62, +0x0001cf5e, +0x0001cf5a, +0x0001cf59, +0x0001cf55, +0x0001cf51, +0x0001cf4e, +0x0001cf4a, +0x0001cf48, +0x0001cf45, +0x0001cf41, +0x0001cf3d, +0x0001cf3a, +0x0001cf38, +0x0001cf34, +0x0001cf31, +0x0001cf2d, +0x0001cf2a, +0x0001cf28, +0x0001cf24, +0x0001cf21, +0x0001cf1d, +0x0001cf19, +0x0001cf16, +0x0001cf14, +0x0001cf10, +0x0001cf0d, +0x0001cf09, +0x0001cf05, +0x0001cf04, +0x0001cf00, +0x0001cefc, +0x0001cef9, +0x0001cef5, +0x0001cef3, +0x0001cef0, +0x0001ceec, +0x0001cee8, +0x0001cee5, +0x0001cee3, +0x0001cedf, +0x0001cedc, +0x0001ced8, +0x0001ced5, +0x0001ced1, +0x0001cecf, +0x0001cecc, +0x0001cec8, +0x0001cec4, +0x0001cec1, +0x0001cebf, +0x0001cebb, +0x0001ceb8, +0x0001ceb4, +0x0001ceb0, +0x0001ceaf, +0x0001ceab, +0x0001cea7, +0x0001cea4, +0x0001cea0, +0x0001ce9e, +0x0001ce9b, +0x0001ce97, +0x0001ce93, +0x0001ce90, +0x0001ce8c, +0x0001ce8a, +0x0001ce87, +0x0001ce83, +0x0001ce80, +0x0001ce7c, +0x0001ce7a, +0x0001ce77, +0x0001ce73, +0x0001ce6f, +0x0001ce6c, +0x0001ce6a, +0x0001ce66, +0x0001ce63, +0x0001ce5f, +0x0001ce5b, +0x0001ce5a, +0x0001ce57, +0x0001ce53, +0x0001ce4f, +0x0001ce4c, +0x0001ce48, +0x0001ce45, +0x0001ce43, +0x0001ce3f, +0x0001ce3c, +0x0001ce38, +0x0001ce34, +0x0001ce33, +0x0001ce2f, +0x0001ce2b, +0x0001ce28, +0x0001ce24, +0x0001ce22, +0x0001ce1f, +0x0001ce1b, +0x0001ce17, +0x0001ce14, +0x0001ce12, +0x0001ce0e, +0x0001ce0b, +0x0001ce07, +0x0001ce04, +0x0001ce02, +0x0001cdfe, +0x0001cdfb, +0x0001cdf7, +0x0001cdf3, +0x0001cdf2, +0x0001cdee, +0x0001cdea, +0x0001cde7, +0x0001cde3, +0x0001cde1, +0x0001cdde, +0x0001cdda, +0x0001cdd6, +0x0001cdd3, +0x0001cdd1, +0x0001cdcd, +0x0001cdca, +0x0001cdc6, +0x0001cdc3, +0x0001cdbf, +0x0001cdbd, +0x0001cdba, +0x0001cdb6, +0x0001cdb2, +0x0001cdaf, +0x0001cdad, +0x0001cda9, +0x0001cda6, +0x0001cda2, +0x0001cd9f, +0x0001cd9d, +0x0001cd99, +0x0001cd96, +0x0001cd92, +0x0001cd8e, +0x0001cd8d, +0x0001cd89, +0x0001cd85, +0x0001cd82, +0x0001cd7e, +0x0001cd7c, +0x0001cd79, +0x0001cd75, +0x0001cd71, +0x0001cd6e, +0x0001cd6c, +0x0001cd68, +0x0001cd65, +0x0001cd61, +0x0001cd5e, +0x0001cd5c, +0x0001cd58, +0x0001cd55, +0x0001cd51, +0x0001cd4d, +0x0001cd4c, +0x0001cd48, +0x0001cd44, +0x0001cd41, +0x0001cd3d, +0x0001cd39, +0x0001cd38, +0x0001cd34, +0x0001cd30, +0x0001cd2d, +0x0001cd29, +0x0001cd27, +0x0001cd24, +0x0001cd20, +0x0001cd1d, +0x0001cd19, +0x0001cd17, +0x0001cd14, +0x0001cd10, +0x0001cd0c, +0x0001cd09, +0x0001cd07, +0x0001cd03, +0x0001cd00, +0x0001ccfc, +0x0001ccf9, +0x0001ccf7, +0x0001ccf3, +0x0001ccef, +0x0001ccec, +0x0001cce8, +0x0001cce6, +0x0001cce3, +0x0001ccdf, +0x0001ccdc, +0x0001ccd8, +0x0001ccd6, +0x0001ccd3, +0x0001cccf, +0x0001cccb, +0x0001ccc8, +0x0001ccc6, +0x0001ccc2, +0x0001ccbf, +0x0001ccbb, +0x0001ccb8, +0x0001ccb5, +0x0001ccb2, +0x0001ccae, +0x0001ccad, +0x0001cca9, +0x0001cca5, +0x0001cca2, +0x0001cc9e, +0x0001cc9c, +0x0001cc99, +0x0001cc95, +0x0001cc92, +0x0001cc8e, +0x0001cc8c, +0x0001cc89, +0x0001cc85, +0x0001cc81, +0x0001cc7e, +0x0001cc7c, +0x0001cc78, +0x0001cc75, +0x0001cc71, +0x0001cc6e, +0x0001cc6c, +0x0001cc68, +0x0001cc65, +0x0001cc61, +0x0001cc5d, +0x0001cc5c, +0x0001cc58, +0x0001cc54, +0x0001cc51, +0x0001cc4f, +0x0001cc4b, +0x0001cc48, +0x0001cc44, +0x0001cc41, +0x0001cc3f, +0x0001cc3b, +0x0001cc38, +0x0001cc34, +0x0001cc31, +0x0001cc2f, +0x0001cc2b, +0x0001cc28, +0x0001cc24, +0x0001cc20, +0x0001cc1f, +0x0001cc1b, +0x0001cc17, +0x0001cc14, +0x0001cc10, +0x0001cc0e, +0x0001cc0b, +0x0001cc07, +0x0001cc04, +0x0001cc00, +0x0001cbfe, +0x0001cbfb, +0x0001cbf7, +0x0001cbf3, +0x0001cbf0, +0x0001cbee, +0x0001cbea, +0x0001cbe7, +0x0001cbe3, +0x0001cbe0, +0x0001cbde, +0x0001cbda, +0x0001cbd7, +0x0001cbd3, +0x0001cbcf, +0x0001cbce, +0x0001cbca, +0x0001cbc7, +0x0001cbc3, +0x0001cbbf, +0x0001cbbe, +0x0001cbba, +0x0001cbb6, +0x0001cbb3, +0x0001cbaf, +0x0001cbad, +0x0001cbaa, +0x0001cba6, +0x0001cba3, +0x0001cb9f, +0x0001cb9d, +0x0001cb9a, +0x0001cb96, +0x0001cb92, +0x0001cb8f, +0x0001cb8d, +0x0001cb89, +0x0001cb86, +0x0001cb82, +0x0001cb80, +0x0001cb7d, +0x0001cb79, +0x0001cb76, +0x0001cb72, +0x0001cb70, +0x0001cb6d, +0x0001cb69, +0x0001cb65, +0x0001cb62, +0x0001cb60, +0x0001cb5c, +0x0001cb59, +0x0001cb55, +0x0001cb52, +0x0001cb50, +0x0001cb4c, +0x0001cb49, +0x0001cb45, +0x0001cb42, +0x0001cb40, +0x0001cb3c, +0x0001cb39, +0x0001cb35, +0x0001cb31, +0x0001cb30, +0x0001cb2c, +0x0001cb28, +0x0001cb25, +0x0001cb21, +0x0001cb1f, +0x0001cb1c, +0x0001cb19, +0x0001cb15, +0x0001cb12, +0x0001cb0e, +0x0001cb0b, +0x0001cb09, +0x0001cb05, +0x0001cb02, +0x0001cafe, +0x0001cafa, +0x0001caf9, +0x0001caf5, +0x0001caf2, +0x0001caee, +0x0001caea, +0x0001cae9, +0x0001cae5, +0x0001cae1, +0x0001cade, +0x0001cadc, +0x0001cad8, +0x0001cad5, +0x0001cad1, +0x0001cace, +0x0001cacc, +0x0001cac8, +0x0001cac5, +0x0001cac1, +0x0001cabe, +0x0001cabc, +0x0001cab8, +0x0001cab5, +0x0001cab1, +0x0001caae, +0x0001caac, +0x0001caa8, +0x0001caa5, +0x0001caa1, +0x0001ca9f, +0x0001ca9c, +0x0001ca98, +0x0001ca94, +0x0001ca91, +0x0001ca8f, +0x0001ca8c, +0x0001ca88, +0x0001ca84, +0x0001ca81, +0x0001ca7f, +0x0001ca7b, +0x0001ca78, +0x0001ca74, +0x0001ca71, +0x0001ca6f, +0x0001ca6b, +0x0001ca68, +0x0001ca64, +0x0001ca62, +0x0001ca5f, +0x0001ca5b, +0x0001ca58, +0x0001ca54, +0x0001ca52, +0x0001ca4f, +0x0001ca4b, +0x0001ca48, +0x0001ca44, +0x0001ca42, +0x0001ca3f, +0x0001ca3b, +0x0001ca37, +0x0001ca34, +0x0001ca32, +0x0001ca2f, +0x0001ca2b, +0x0001ca27, +0x0001ca26, +0x0001ca22, +0x0001ca1e, +0x0001ca1b, +0x0001ca17, +0x0001ca15, +0x0001ca12, +0x0001ca0e, +0x0001ca0b, +0x0001ca07, +0x0001ca05, +0x0001ca02, +0x0001c9fe, +0x0001c9fb, +0x0001c9f7, +0x0001c9f5, +0x0001c9f2, +0x0001c9ee, +0x0001c9eb, +0x0001c9e9, +0x0001c9e5, +0x0001c9e2, +0x0001c9de, +0x0001c9da, +0x0001c9d9, +0x0001c9d5, +0x0001c9d1, +0x0001c9ce, +0x0001c9ca, +0x0001c9c9, +0x0001c9c5, +0x0001c9c1, +0x0001c9be, +0x0001c9ba, +0x0001c9b8, +0x0001c9b5, +0x0001c9b1, +0x0001c9ae, +0x0001c9ac, +0x0001c9a8, +0x0001c9a5, +0x0001c9a1, +0x0001c99e, +0x0001c99c, +0x0001c998, +0x0001c995, +0x0001c991, +0x0001c98e, +0x0001c98c, +0x0001c988, +0x0001c985, +0x0001c981, +0x0001c97f, +0x0001c97b, +0x0001c978, +0x0001c974, +0x0001c972, +0x0001c96f, +0x0001c96b, +0x0001c968, +0x0001c964, +0x0001c962, +0x0001c95f, +0x0001c95b, +0x0001c957, +0x0001c956, +0x0001c952, +0x0001c94f, +0x0001c94b, +0x0001c947, +0x0001c946, +0x0001c942, +0x0001c93e, +0x0001c93b, +0x0001c937, +0x0001c936, +0x0001c932, +0x0001c92e, +0x0001c92b, +0x0001c929, +0x0001c925, +0x0001c922, +0x0001c91e, +0x0001c91b, +0x0001c919, +0x0001c915, +0x0001c912, +0x0001c90e, +0x0001c90b, +0x0001c909, +0x0001c905, +0x0001c902, +0x0001c8fe, +0x0001c8fc, +0x0001c8f9, +0x0001c8f5, +0x0001c8f2, +0x0001c8ee, +0x0001c8ec, +0x0001c8e9, +0x0001c8e5, +0x0001c8e2, +0x0001c8de, +0x0001c8dc, +0x0001c8d9, +0x0001c8d5, +0x0001c8d2, +0x0001c8d0, +0x0001c8cc, +0x0001c8c9, +0x0001c8c5, +0x0001c8c2, +0x0001c8c0, +0x0001c8bc, +0x0001c8b9, +0x0001c8b5, +0x0001c8b3, +0x0001c8b0, +0x0001c8ac, +0x0001c8a9, +0x0001c8a5, +0x0001c8a3, +0x0001c8a0, +0x0001c89c, +0x0001c898, +0x0001c895, +0x0001c893, +0x0001c890, +0x0001c88c, +0x0001c888, +0x0001c887, +0x0001c883, +0x0001c87f, +0x0001c87c, +0x0001c878, +0x0001c877, +0x0001c873, +0x0001c86f, +0x0001c86c, +0x0001c868, +0x0001c866, +0x0001c863, +0x0001c85f, +0x0001c85c, +0x0001c85a, +0x0001c856, +0x0001c853, +0x0001c84f, +0x0001c84c, +0x0001c84a, +0x0001c846, +0x0001c843, +0x0001c83f, +0x0001c83c, +0x0001c83a, +0x0001c836, +0x0001c833, +0x0001c82f, +0x0001c82d, +0x0001c82a, +0x0001c826, +0x0001c823, +0x0001c81f, +0x0001c81d, +0x0001c81a, +0x0001c816, +0x0001c813, +0x0001c80f, +0x0001c80d, +0x0001c80a, +0x0001c806, +0x0001c803, +0x0001c801, +0x0001c7fd, +0x0001c7fa, +0x0001c7f6, +0x0001c7f2, +0x0001c7f1, +0x0001c7ed, +0x0001c7ea, +0x0001c7e7, +0x0001c7e4, +0x0001c7e0, +0x0001c7dc, +0x0001c7db, +0x0001c7d7, +0x0001c7d4, +0x0001c7d0, +0x0001c7ce, +0x0001c7cb, +0x0001c7c7, +0x0001c7c4, +0x0001c7c0, +0x0001c7be, +0x0001c7bb, +0x0001c7b7, +0x0001c7b4, +0x0001c7b2, +0x0001c7ae, +0x0001c7ab, +0x0001c7a7, +0x0001c7a4, +0x0001c7a2, +0x0001c79e, +0x0001c79b, +0x0001c797, +0x0001c795, +0x0001c792, +0x0001c78e, +0x0001c78b, +0x0001c787, +0x0001c785, +0x0001c782, +0x0001c77e, +0x0001c77b, +0x0001c779, +0x0001c775, +0x0001c772, +0x0001c76e, +0x0001c76b, +0x0001c769, +0x0001c765, +0x0001c762, +0x0001c75e, +0x0001c75c, +0x0001c759, +0x0001c755, +0x0001c752, +0x0001c74e, +0x0001c74c, +0x0001c749, +0x0001c745, +0x0001c742, +0x0001c740, +0x0001c73c, +0x0001c739, +0x0001c735, +0x0001c732, +0x0001c730, +0x0001c72c, +0x0001c729, +0x0001c725, +0x0001c724, +0x0001c720, +0x0001c71c, +0x0001c719, +0x0001c715, +0x0001c714, +0x0001c710, +0x0001c70c, +0x0001c709, +0x0001c707, +0x0001c704, +0x0001c700, +0x0001c6fc, +0x0001c6f9, +0x0001c6f7, +0x0001c6f4, +0x0001c6f0, +0x0001c6ec, +0x0001c6eb, +0x0001c6e7, +0x0001c6e4, +0x0001c6e0, +0x0001c6dc, +0x0001c6db, +0x0001c6d7, +0x0001c6d4, +0x0001c6d0, +0x0001c6ce, +0x0001c6cb, +0x0001c6c7, +0x0001c6c4, +0x0001c6c0, +0x0001c6be, +0x0001c6bb, +0x0001c6b7, +0x0001c6b4, +0x0001c6b2, +0x0001c6ae, +0x0001c6ab, +0x0001c6a7, +0x0001c6a4, +0x0001c6a2, +0x0001c69e, +0x0001c69b, +0x0001c697, +0x0001c695, +0x0001c692, +0x0001c68e, +0x0001c68b, +0x0001c687, +0x0001c685, +0x0001c682, +0x0001c67e, +0x0001c67b, +0x0001c679, +0x0001c675, +0x0001c672, +0x0001c66e, +0x0001c66b, +0x0001c669, +0x0001c665, +0x0001c662, +0x0001c65e, +0x0001c65c, +0x0001c659, +0x0001c655, +0x0001c653, +0x0001c650, +0x0001c64c, +0x0001c649, +0x0001c645, +0x0001c643, +0x0001c640, +0x0001c63c, +0x0001c639, +0x0001c637, +0x0001c633, +0x0001c630, +0x0001c62c, +0x0001c629, +0x0001c627, +0x0001c623, +0x0001c620, +0x0001c61c, +0x0001c61b, +0x0001c617, +0x0001c614, +0x0001c610, +0x0001c60c, +0x0001c60b, +0x0001c607, +0x0001c604, +0x0001c600, +0x0001c5fe, +0x0001c5fb, +0x0001c5f7, +0x0001c5f4, +0x0001c5f2, +0x0001c5ee, +0x0001c5eb, +0x0001c5e7, +0x0001c5e4, +0x0001c5e2, +0x0001c5de, +0x0001c5db, +0x0001c5d7, +0x0001c5d5, +0x0001c5d2, +0x0001c5ce, +0x0001c5cb, +0x0001c5c7, +0x0001c5c5, +0x0001c5c2, +0x0001c5be, +0x0001c5bb, +0x0001c5b9, +0x0001c5b6, +0x0001c5b2, +0x0001c5ae, +0x0001c5ad, +0x0001c5a9, +0x0001c5a6, +0x0001c5a2, +0x0001c59e, +0x0001c59d, +0x0001c599, +0x0001c596, +0x0001c592, +0x0001c590, +0x0001c58d, +0x0001c589, +0x0001c586, +0x0001c582, +0x0001c580, +0x0001c57d, +0x0001c579, +0x0001c576, +0x0001c574, +0x0001c570, +0x0001c56d, +0x0001c569, +0x0001c566, +0x0001c564, +0x0001c560, +0x0001c55d, +0x0001c559, +0x0001c558, +0x0001c554, +0x0001c550, +0x0001c54d, +0x0001c54b, +0x0001c548, +0x0001c544, +0x0001c540, +0x0001c53d, +0x0001c53b, +0x0001c538, +0x0001c534, +0x0001c531, +0x0001c52f, +0x0001c52b, +0x0001c528, +0x0001c524, +0x0001c521, +0x0001c51f, +0x0001c51b, +0x0001c518, +0x0001c514, +0x0001c512, +0x0001c50f, +0x0001c50b, +0x0001c508, +0x0001c506, +0x0001c502, +0x0001c4ff, +0x0001c4fb, +0x0001c4f8, +0x0001c4f6, +0x0001c4f2, +0x0001c4ef, +0x0001c4eb, +0x0001c4ea, +0x0001c4e6, +0x0001c4e2, +0x0001c4df, +0x0001c4db, +0x0001c4da, +0x0001c4d6, +0x0001c4d3, +0x0001c4cf, +0x0001c4cd, +0x0001c4ca, +0x0001c4c6, +0x0001c4c3, +0x0001c4c0, +0x0001c4bd, +0x0001c4b9, +0x0001c4b8, +0x0001c4b4, +0x0001c4b1, +0x0001c4ad, +0x0001c4ab, +0x0001c4a8, +0x0001c4a4, +0x0001c4a1, +0x0001c49f, +0x0001c49b, +0x0001c498, +0x0001c494, +0x0001c493, +0x0001c48f, +0x0001c48b, +0x0001c488, +0x0001c484, +0x0001c483, +0x0001c47f, +0x0001c47c, +0x0001c478, +0x0001c476, +0x0001c473, +0x0001c46f, +0x0001c46c, +0x0001c46a, +0x0001c466, +0x0001c463, +0x0001c45f, +0x0001c45e, +0x0001c45a, +0x0001c457, +0x0001c453, +0x0001c44f, +0x0001c44e, +0x0001c44a, +0x0001c447, +0x0001c443, +0x0001c441, +0x0001c43e, +0x0001c43a, +0x0001c437, +0x0001c435, +0x0001c431, +0x0001c42e, +0x0001c42a, +0x0001c427, +0x0001c425, +0x0001c422, +0x0001c41e, +0x0001c41a, +0x0001c419, +0x0001c415, +0x0001c412, +0x0001c40e, +0x0001c40c, +0x0001c409, +0x0001c405, +0x0001c402, +0x0001c400, +0x0001c3fc, +0x0001c3f9, +0x0001c3f5, +0x0001c3f2, +0x0001c3f0, +0x0001c3ed, +0x0001c3e9, +0x0001c3e6, +0x0001c3e4, +0x0001c3e0, +0x0001c3dd, +0x0001c3d9, +0x0001c3d7, +0x0001c3d4, +0x0001c3d0, +0x0001c3cd, +0x0001c3cb, +0x0001c3c8, +0x0001c3c4, +0x0001c3c0, +0x0001c3bd, +0x0001c3bb, +0x0001c3b8, +0x0001c3b4, +0x0001c3b1, +0x0001c3af, +0x0001c3ab, +0x0001c3a8, +0x0001c3a4, +0x0001c3a2, +0x0001c39f, +0x0001c39b, +0x0001c398, +0x0001c396, +0x0001c393, +0x0001c38f, +0x0001c38b, +0x0001c388, +0x0001c386, +0x0001c383, +0x0001c37f, +0x0001c37c, +0x0001c37a, +0x0001c376, +0x0001c373, +0x0001c36f, +0x0001c36d, +0x0001c36a, +0x0001c366, +0x0001c363, +0x0001c35f, +0x0001c35e, +0x0001c35a, +0x0001c357, +0x0001c353, +0x0001c351, +0x0001c34e, +0x0001c34a, +0x0001c347, +0x0001c345, +0x0001c341, +0x0001c33e, +0x0001c33a, +0x0001c338, +0x0001c335, +0x0001c332, +0x0001c32e, +0x0001c32b, +0x0001c327, +0x0001c324, +0x0001c322, +0x0001c31f, +0x0001c31b, +0x0001c317, +0x0001c316, +0x0001c312, +0x0001c30f, +0x0001c30b, +0x0001c309, +0x0001c306, +0x0001c302, +0x0001c2ff, +0x0001c2fd, +0x0001c2fa, +0x0001c2f6, +0x0001c2f3, +0x0001c2f1, +0x0001c2ed, +0x0001c2ea, +0x0001c2e6, +0x0001c2e5, +0x0001c2e1, +0x0001c2dd, +0x0001c2da, +0x0001c2d8, +0x0001c2d5, +0x0001c2d1, +0x0001c2ce, +0x0001c2ca, +0x0001c2c8, +0x0001c2c5, +0x0001c2c1, +0x0001c2be, +0x0001c2bc, +0x0001c2b9, +0x0001c2b5, +0x0001c2b2, +0x0001c2b0, +0x0001c2ac, +0x0001c2a9, +0x0001c2a5, +0x0001c2a3, +0x0001c2a0, +0x0001c29c, +0x0001c299, +0x0001c297, +0x0001c294, +0x0001c290, +0x0001c28d, +0x0001c28b, +0x0001c287, +0x0001c284, +0x0001c280, +0x0001c27f, +0x0001c27b, +0x0001c278, +0x0001c274, +0x0001c272, +0x0001c26f, +0x0001c26b, +0x0001c268, +0x0001c264, +0x0001c262, +0x0001c25f, +0x0001c25b, +0x0001c258, +0x0001c256, +0x0001c253, +0x0001c24f, +0x0001c24c, +0x0001c24a, +0x0001c246, +0x0001c243, +0x0001c23f, +0x0001c23e, +0x0001c23a, +0x0001c236, +0x0001c233, +0x0001c231, +0x0001c22e, +0x0001c22a, +0x0001c227, +0x0001c225, +0x0001c221, +0x0001c21e, +0x0001c21a, +0x0001c219, +0x0001c215, +0x0001c212, +0x0001c20e, +0x0001c20c, +0x0001c209, +0x0001c205, +0x0001c202, +0x0001c1fe, +0x0001c1fc, +0x0001c1f9, +0x0001c1f5, +0x0001c1f2, +0x0001c1f0, +0x0001c1ed, +0x0001c1e9, +0x0001c1e6, +0x0001c1e4, +0x0001c1e0, +0x0001c1dd, +0x0001c1d9, +0x0001c1d8, +0x0001c1d4, +0x0001c1d1, +0x0001c1cd, +0x0001c1cb, +0x0001c1c8, +0x0001c1c4, +0x0001c1c1, +0x0001c1bf, +0x0001c1bb, +0x0001c1b8, +0x0001c1b4, +0x0001c1b3, +0x0001c1af, +0x0001c1ac, +0x0001c1a8, +0x0001c1a5, +0x0001c1a1, +0x0001c1a0, +0x0001c19c, +0x0001c199, +0x0001c195, +0x0001c193, +0x0001c190, +0x0001c18c, +0x0001c189, +0x0001c187, +0x0001c184, +0x0001c180, +0x0001c17d, +0x0001c17b, +0x0001c177, +0x0001c174, +0x0001c170, +0x0001c16e, +0x0001c16b, +0x0001c167, +0x0001c164, +0x0001c162, +0x0001c15f, +0x0001c15b, +0x0001c158, +0x0001c156, +0x0001c152, +0x0001c14f, +0x0001c14b, +0x0001c14a, +0x0001c146, +0x0001c143, +0x0001c13f, +0x0001c13d, +0x0001c13a, +0x0001c136, +0x0001c133, +0x0001c131, +0x0001c12e, +0x0001c12a, +0x0001c127, +0x0001c125, +0x0001c121, +0x0001c11e, +0x0001c11a, +0x0001c119, +0x0001c115, +0x0001c112, +0x0001c10e, +0x0001c10c, +0x0001c109, +0x0001c105, +0x0001c102, +0x0001c100, +0x0001c0fc, +0x0001c0f9, +0x0001c0f5, +0x0001c0f4, +0x0001c0f0, +0x0001c0ed, +0x0001c0e9, +0x0001c0e7, +0x0001c0e4, +0x0001c0e0, +0x0001c0dd, +0x0001c0d9, +0x0001c0d8, +0x0001c0d4, +0x0001c0d1, +0x0001c0cd, +0x0001c0cb, +0x0001c0c8, +0x0001c0c4, +0x0001c0c1, +0x0001c0bf, +0x0001c0bc, +0x0001c0b8, +0x0001c0b5, +0x0001c0b3, +0x0001c0af, +0x0001c0ac, +0x0001c0a8, +0x0001c0a7, +0x0001c0a3, +0x0001c0a0, +0x0001c09c, +0x0001c09a, +0x0001c097, +0x0001c093, +0x0001c090, +0x0001c08e, +0x0001c08a, +0x0001c087, +0x0001c083, +0x0001c082, +0x0001c07e, +0x0001c07b, +0x0001c077, +0x0001c075, +0x0001c072, +0x0001c06e, +0x0001c06b, +0x0001c069, +0x0001c066, +0x0001c062, +0x0001c05f, +0x0001c05d, +0x0001c059, +0x0001c056, +0x0001c052, +0x0001c051, +0x0001c04d, +0x0001c04a, +0x0001c046, +0x0001c044, +0x0001c041, +0x0001c03d, +0x0001c03a, +0x0001c038, +0x0001c035, +0x0001c031, +0x0001c02e, +0x0001c02c, +0x0001c028, +0x0001c025, +0x0001c021, +0x0001c020, +0x0001c01b, +0x0001c019, +0x0001c016, +0x0001c012, +0x0001c00f, +0x0001c00d, +0x0001c009, +0x0001c006, +0x0001c002, +0x0001c001, +0x0001bffd, +0x0001bffa, +0x0001bff6, +0x0001bff4, +0x0001bff1, +0x0001bfed, +0x0001bfea, +0x0001bfe8, +0x0001bfe5, +0x0001bfe1, +0x0001bfde, +0x0001bfdc, +0x0001bfd9, +0x0001bfd5, +0x0001bfd2, +0x0001bfd0, +0x0001bfcc, +0x0001bfc9, +0x0001bfc5, +0x0001bfc4, +0x0001bfc0, +0x0001bfbd, +0x0001bfb9, +0x0001bfb7, +0x0001bfb4, +0x0001bfb0, +0x0001bfad, +0x0001bfab, +0x0001bfa8, +0x0001bfa4, +0x0001bfa1, +0x0001bf9f, +0x0001bf9b, +0x0001bf98, +0x0001bf94, +0x0001bf93, +0x0001bf8f, +0x0001bf8c, +0x0001bf88, +0x0001bf86, +0x0001bf83, +0x0001bf7f, +0x0001bf7c, +0x0001bf7a, +0x0001bf77, +0x0001bf73, +0x0001bf70, +0x0001bf6e, +0x0001bf6b, +0x0001bf67, +0x0001bf64, +0x0001bf62, +0x0001bf5e, +0x0001bf5b, +0x0001bf59, +0x0001bf56, +0x0001bf52, +0x0001bf4f, +0x0001bf4d, +0x0001bf49, +0x0001bf46, +0x0001bf42, +0x0001bf41, +0x0001bf3d, +0x0001bf3a, +0x0001bf36, +0x0001bf34, +0x0001bf31, +0x0001bf2d, +0x0001bf2a, +0x0001bf28, +0x0001bf25, +0x0001bf21, +0x0001bf1e, +0x0001bf1c, +0x0001bf18, +0x0001bf15, +0x0001bf11, +0x0001bf10, +0x0001bf0c, +0x0001bf09, +0x0001bf05, +0x0001bf03, +0x0001bf00, +0x0001befd, +0x0001bef9, +0x0001bef7, +0x0001bef4, +0x0001bef0, +0x0001beed, +0x0001beeb, +0x0001bee8, +0x0001bee4, +0x0001bee1, +0x0001bedf, +0x0001bedb, +0x0001bed8, +0x0001bed4, +0x0001bed3, +0x0001becf, +0x0001becc, +0x0001bec8, +0x0001bec6, +0x0001bec3, +0x0001bebf, +0x0001bebc, +0x0001beba, +0x0001beb7, +0x0001beb3, +0x0001beb0, +0x0001beae, +0x0001beaa, +0x0001bea7, +0x0001bea3, +0x0001bea2, +0x0001be9e, +0x0001be9b, +0x0001be97, +0x0001be96, +0x0001be92, +0x0001be8f, +0x0001be8b, +0x0001be8a, +0x0001be86, +0x0001be83, +0x0001be7f, +0x0001be7d, +0x0001be7a, +0x0001be76, +0x0001be73, +0x0001be71, +0x0001be6e, +0x0001be6a, +0x0001be67, +0x0001be65, +0x0001be62, +0x0001be5e, +0x0001be5b, +0x0001be59, +0x0001be55, +0x0001be52, +0x0001be4e, +0x0001be4d, +0x0001be49, +0x0001be46, +0x0001be42, +0x0001be40, +0x0001be3d, +0x0001be39, +0x0001be36, +0x0001be34, +0x0001be31, +0x0001be2d, +0x0001be2c, +0x0001be28, +0x0001be25, +0x0001be21, +0x0001be1f, +0x0001be1c, +0x0001be18, +0x0001be15, +0x0001be13, +0x0001be10, +0x0001be0c, +0x0001be09, +0x0001be07, +0x0001be03, +0x0001be00, +0x0001bdfd, +0x0001bdfb, +0x0001bdf7, +0x0001bdf4, +0x0001bdf0, +0x0001bdef, +0x0001bdeb, +0x0001bde8, +0x0001bde4, +0x0001bde2, +0x0001bddf, +0x0001bddb, +0x0001bdd8, +0x0001bdd6, +0x0001bdd3, +0x0001bdcf, +0x0001bdcd, +0x0001bdca, +0x0001bdc7, +0x0001bdc3, +0x0001bdc1, +0x0001bdbe, +0x0001bdba, +0x0001bdb7, +0x0001bdb5, +0x0001bdb2, +0x0001bdae, +0x0001bdab, +0x0001bda9, +0x0001bda5, +0x0001bda2, +0x0001bd9e, +0x0001bd9d, +0x0001bd99, +0x0001bd96, +0x0001bd92, +0x0001bd91, +0x0001bd8d, +0x0001bd8a, +0x0001bd86, +0x0001bd84, +0x0001bd81, +0x0001bd7d, +0x0001bd7a, +0x0001bd78, +0x0001bd75, +0x0001bd71, +0x0001bd6f, +0x0001bd6c, +0x0001bd68, +0x0001bd65, +0x0001bd63, +0x0001bd60, +0x0001bd5c, +0x0001bd59, +0x0001bd57, +0x0001bd54, +0x0001bd50, +0x0001bd4d, +0x0001bd4b, +0x0001bd47, +0x0001bd44, +0x0001bd40, +0x0001bd3f, +0x0001bd3b, +0x0001bd38, +0x0001bd34, +0x0001bd32, +0x0001bd2f, +0x0001bd2b, +0x0001bd28, +0x0001bd26, +0x0001bd23, +0x0001bd1f, +0x0001bd1c, +0x0001bd1a, +0x0001bd17, +0x0001bd13, +0x0001bd10, +0x0001bd0d, +0x0001bd0b, +0x0001bd08, +0x0001bd04, +0x0001bd01, +0x0001bcff, +0x0001bcfb, +0x0001bcf8, +0x0001bcf5, +0x0001bcf3, +0x0001bcef, +0x0001bcec, +0x0001bce8, +0x0001bce7, +0x0001bce3, +0x0001bce0, +0x0001bcde, +0x0001bcdb, +0x0001bcd7, +0x0001bcd4, +0x0001bcd2, +0x0001bcce, +0x0001bccb, +0x0001bcc7, +0x0001bcc6, +0x0001bcc2, +0x0001bcbf, +0x0001bcbb, +0x0001bcba, +0x0001bcb6, +0x0001bcb3, +0x0001bcb1, +0x0001bcad, +0x0001bcaa, +0x0001bca7, +0x0001bca5, +0x0001bca1, +0x0001bc9e, +0x0001bc9a, +0x0001bc99, +0x0001bc95, +0x0001bc92, +0x0001bc8e, +0x0001bc8c, +0x0001bc89, +0x0001bc86, +0x0001bc82, +0x0001bc80, +0x0001bc7d, +0x0001bc79, +0x0001bc78, +0x0001bc74, +0x0001bc71, +0x0001bc6d, +0x0001bc6c, +0x0001bc68, +0x0001bc65, +0x0001bc61, +0x0001bc5f, +0x0001bc5c, +0x0001bc58, +0x0001bc55, +0x0001bc53, +0x0001bc50, +0x0001bc4c, +0x0001bc4b, +0x0001bc47, +0x0001bc44, +0x0001bc40, +0x0001bc3e, +0x0001bc3b, +0x0001bc38, +0x0001bc34, +0x0001bc32, +0x0001bc2f, +0x0001bc2b, +0x0001bc28, +0x0001bc26, +0x0001bc23, +0x0001bc1f, +0x0001bc1d, +0x0001bc1a, +0x0001bc17, +0x0001bc13, +0x0001bc11, +0x0001bc0e, +0x0001bc0a, +0x0001bc07, +0x0001bc05, +0x0001bc02, +0x0001bbfe, +0x0001bbfb, +0x0001bbf9, +0x0001bbf6, +0x0001bbf2, +0x0001bbf0, +0x0001bbed, +0x0001bbe9, +0x0001bbe6, +0x0001bbe4, +0x0001bbe1, +0x0001bbdd, +0x0001bbda, +0x0001bbd8, +0x0001bbd5, +0x0001bbd1, +0x0001bbce, +0x0001bbcc, +0x0001bbc9, +0x0001bbc5, +0x0001bbc2, +0x0001bbc0, +0x0001bbbc, +0x0001bbb9, +0x0001bbb7, +0x0001bbb4, +0x0001bbb0, +0x0001bbad, +0x0001bbab, +0x0001bba8, +0x0001bba4, +0x0001bba1, +0x0001bb9f, +0x0001bb9b, +0x0001bb98, +0x0001bb94, +0x0001bb93, +0x0001bb90, +0x0001bb8c, +0x0001bb89, +0x0001bb87, +0x0001bb84, +0x0001bb80, +0x0001bb7d, +0x0001bb7b, +0x0001bb77, +0x0001bb74, +0x0001bb70, +0x0001bb6f, +0x0001bb6b, +0x0001bb68, +0x0001bb66, +0x0001bb63, +0x0001bb5f, +0x0001bb5c, +0x0001bb5a, +0x0001bb57, +0x0001bb53, +0x0001bb50, +0x0001bb4e, +0x0001bb4a, +0x0001bb47, +0x0001bb43, +0x0001bb42, +0x0001bb3e, +0x0001bb3b, +0x0001bb39, +0x0001bb36, +0x0001bb32, +0x0001bb2f, +0x0001bb2d, +0x0001bb2a, +0x0001bb26, +0x0001bb23, +0x0001bb21, +0x0001bb1d, +0x0001bb1a, +0x0001bb18, +0x0001bb15, +0x0001bb11, +0x0001bb0e, +0x0001bb0c, +0x0001bb09, +0x0001bb05, +0x0001bb02, +0x0001bb00, +0x0001bafd, +0x0001baf9, +0x0001baf6, +0x0001baf4, +0x0001baf0, +0x0001baed, +0x0001baeb, +0x0001bae8, +0x0001bae4, +0x0001bae1, +0x0001badf, +0x0001badc, +0x0001bad8, +0x0001bad5, +0x0001bad3, +0x0001bad0, +0x0001bacc, +0x0001baca, +0x0001bac7, +0x0001bac3, +0x0001bac0, +0x0001babe, +0x0001babb, +0x0001bab7, +0x0001bab4, +0x0001bab2, +0x0001baaf, +0x0001baab, +0x0001baa9, +0x0001baa6, +0x0001baa3, +0x0001ba9f, +0x0001ba9d, +0x0001ba9a, +0x0001ba96, +0x0001ba93, +0x0001ba91, +0x0001ba8e, +0x0001ba8a, +0x0001ba87, +0x0001ba85, +0x0001ba82, +0x0001ba7e, +0x0001ba7c, +0x0001ba79, +0x0001ba76, +0x0001ba72, +0x0001ba70, +0x0001ba6d, +0x0001ba69, +0x0001ba66, +0x0001ba64, +0x0001ba61, +0x0001ba5d, +0x0001ba5c, +0x0001ba58, +0x0001ba55, +0x0001ba51, +0x0001ba4f, +0x0001ba4c, +0x0001ba49, +0x0001ba45, +0x0001ba43, +0x0001ba40, +0x0001ba3c, +0x0001ba39, +0x0001ba37, +0x0001ba34, +0x0001ba30, +0x0001ba2f, +0x0001ba2b, +0x0001ba28, +0x0001ba24, +0x0001ba23, +0x0001ba1f, +0x0001ba1c, +0x0001ba18, +0x0001ba16, +0x0001ba13, +0x0001ba10, +0x0001ba0d, +0x0001ba09, +0x0001ba08, +0x0001ba04, +0x0001ba01, +0x0001b9fd, +0x0001b9fc, +0x0001b9f8, +0x0001b9f5, +0x0001b9f3, +0x0001b9ef, +0x0001b9ec, +0x0001b9e9, +0x0001b9e7, +0x0001b9e3, +0x0001b9e0, +0x0001b9dd, +0x0001b9db, +0x0001b9d7, +0x0001b9d4, +0x0001b9d2, +0x0001b9cf, +0x0001b9cb, +0x0001b9c8, +0x0001b9c6, +0x0001b9c3, +0x0001b9bf, +0x0001b9bd, +0x0001b9ba, +0x0001b9b7, +0x0001b9b3, +0x0001b9b1, +0x0001b9ae, +0x0001b9ab, +0x0001b9a7, +0x0001b9a5, +0x0001b9a2, +0x0001b99e, +0x0001b99d, +0x0001b999, +0x0001b996, +0x0001b992, +0x0001b991, +0x0001b98d, +0x0001b98a, +0x0001b988, +0x0001b985, +0x0001b981, +0x0001b97e, +0x0001b97c, +0x0001b979, +0x0001b975, +0x0001b972, +0x0001b970, +0x0001b96d, +0x0001b969, +0x0001b967, +0x0001b964, +0x0001b960, +0x0001b95d, +0x0001b95b, +0x0001b958, +0x0001b954, +0x0001b953, +0x0001b94f, +0x0001b94c, +0x0001b948, +0x0001b947, +0x0001b943, +0x0001b940, +0x0001b93c, +0x0001b93b, +0x0001b937, +0x0001b934, +0x0001b932, +0x0001b92f, +0x0001b92b, +0x0001b928, +0x0001b926, +0x0001b922, +0x0001b91f, +0x0001b91c, +0x0001b91a, +0x0001b916, +0x0001b913, +0x0001b911, +0x0001b90e, +0x0001b90a, +0x0001b907, +0x0001b905, +0x0001b902, +0x0001b8fe, +0x0001b8fd, +0x0001b8f9, +0x0001b8f6, +0x0001b8f2, +0x0001b8f0, +0x0001b8ed, +0x0001b8ea, +0x0001b8e6, +0x0001b8e4, +0x0001b8e1, +0x0001b8de, +0x0001b8dc, +0x0001b8d8, +0x0001b8d5, +0x0001b8d1, +0x0001b8d0, +0x0001b8cc, +0x0001b8c9, +0x0001b8c7, +0x0001b8c4, +0x0001b8c0, +0x0001b8bd, +0x0001b8bb, +0x0001b8b8, +0x0001b8b4, +0x0001b8b1, +0x0001b8af, +0x0001b8ac, +0x0001b8a8, +0x0001b8a6, +0x0001b8a3, +0x0001b8a0, +0x0001b89c, +0x0001b89a, +0x0001b897, +0x0001b894, +0x0001b890, +0x0001b88f, +0x0001b88b, +0x0001b888, +0x0001b884, +0x0001b883, +0x0001b87f, +0x0001b87c, +0x0001b87a, +0x0001b877, +0x0001b873, +0x0001b870, +0x0001b86e, +0x0001b86b, +0x0001b867, +0x0001b865, +0x0001b862, +0x0001b85f, +0x0001b85b, +0x0001b859, +0x0001b856, +0x0001b853, +0x0001b84f, +0x0001b84d, +0x0001b84a, +0x0001b846, +0x0001b845, +0x0001b841, +0x0001b83e, +0x0001b83a, +0x0001b839, +0x0001b835, +0x0001b832, +0x0001b830, +0x0001b82d, +0x0001b829, +0x0001b826, +0x0001b824, +0x0001b821, +0x0001b81d, +0x0001b81c, +0x0001b818, +0x0001b815, +0x0001b811, +0x0001b80f, +0x0001b80c, +0x0001b809, +0x0001b807, +0x0001b803, +0x0001b800, +0x0001b7fd, +0x0001b7fb, +0x0001b7f7, +0x0001b7f4, +0x0001b7f1, +0x0001b7ef, +0x0001b7eb, +0x0001b7e8, +0x0001b7e6, +0x0001b7e3, +0x0001b7df, +0x0001b7dc, +0x0001b7da, +0x0001b7d7, +0x0001b7d3, +0x0001b7d2, +0x0001b7ce, +0x0001b7cb, +0x0001b7c7, +0x0001b7c6, +0x0001b7c2, +0x0001b7bf, +0x0001b7bd, +0x0001b7ba, +0x0001b7b6, +0x0001b7b3, +0x0001b7b1, +0x0001b7ae, +0x0001b7aa, +0x0001b7a8, +0x0001b7a5, +0x0001b7a1, +0x0001b79e, +0x0001b79c, +0x0001b799, +0x0001b795, +0x0001b792, +0x0001b790, +0x0001b78d, +0x0001b789, +0x0001b788, +0x0001b784, +0x0001b781, +0x0001b77d, +0x0001b77c, +0x0001b778, +0x0001b775, +0x0001b773, +0x0001b770, +0x0001b76c, +0x0001b769, +0x0001b767, +0x0001b764, +0x0001b760, +0x0001b75e, +0x0001b75b, +0x0001b758, +0x0001b754, +0x0001b752, +0x0001b74f, +0x0001b74c, +0x0001b74a, +0x0001b746, +0x0001b743, +0x0001b740, +0x0001b73e, +0x0001b73a, +0x0001b737, +0x0001b733, +0x0001b732, +0x0001b72e, +0x0001b72b, +0x0001b729, +0x0001b726, +0x0001b722, +0x0001b71f, +0x0001b71d, +0x0001b71a, +0x0001b717, +0x0001b713, +0x0001b710, +0x0001b70e, +0x0001b70b, +0x0001b707, +0x0001b706, +0x0001b702, +0x0001b6ff, +0x0001b6fc, +0x0001b6fa, +0x0001b6f6, +0x0001b6f3, +0x0001b6f1, +0x0001b6ee, +0x0001b6ea, +0x0001b6e7, +0x0001b6e5, +0x0001b6e2, +0x0001b6de, +0x0001b6dd, +0x0001b6d9, +0x0001b6d6, +0x0001b6d2, +0x0001b6d1, +0x0001b6cd, +0x0001b6ca, +0x0001b6c8, +0x0001b6c5, +0x0001b6c1, +0x0001b6be, +0x0001b6bc, +0x0001b6b9, +0x0001b6b5, +0x0001b6b4, +0x0001b6b0, +0x0001b6ad, +0x0001b6a9, +0x0001b6a8, +0x0001b6a4, +0x0001b6a1, +0x0001b69f, +0x0001b69c, +0x0001b698, +0x0001b697, +0x0001b693, +0x0001b690, +0x0001b68c, +0x0001b68b, +0x0001b687, +0x0001b684, +0x0001b682, +0x0001b67f, +0x0001b67b, +0x0001b678, +0x0001b676, +0x0001b673, +0x0001b66f, +0x0001b66e, +0x0001b66a, +0x0001b667, +0x0001b663, +0x0001b662, +0x0001b65e, +0x0001b65b, +0x0001b659, +0x0001b656, +0x0001b652, +0x0001b64f, +0x0001b64d, +0x0001b64a, +0x0001b646, +0x0001b644, +0x0001b641, +0x0001b63e, +0x0001b63a, +0x0001b638, +0x0001b635, +0x0001b632, +0x0001b630, +0x0001b62c, +0x0001b629, +0x0001b626, +0x0001b624, +0x0001b621, +0x0001b61d, +0x0001b61b, +0x0001b618, +0x0001b615, +0x0001b613, +0x0001b60f, +0x0001b60c, +0x0001b609, +0x0001b607, +0x0001b603, +0x0001b600, +0x0001b5fe, +0x0001b5fb, +0x0001b5f7, +0x0001b5f4, +0x0001b5f2, +0x0001b5ef, +0x0001b5eb, +0x0001b5ea, +0x0001b5e6, +0x0001b5e3, +0x0001b5df, +0x0001b5de, +0x0001b5da, +0x0001b5d7, +0x0001b5d5, +0x0001b5d2, +0x0001b5ce, +0x0001b5cb, +0x0001b5c9, +0x0001b5c6, +0x0001b5c2, +0x0001b5c1, +0x0001b5bd, +0x0001b5ba, +0x0001b5b6, +0x0001b5b5, +0x0001b5b1, +0x0001b5ae, +0x0001b5ac, +0x0001b5a9, +0x0001b5a5, +0x0001b5a2, +0x0001b5a0, +0x0001b59d, +0x0001b59a, +0x0001b596, +0x0001b595, +0x0001b591, +0x0001b58e, +0x0001b58c, +0x0001b589, +0x0001b585, +0x0001b582, +0x0001b580, +0x0001b57d, +0x0001b579, +0x0001b577, +0x0001b574, +0x0001b571, +0x0001b56f, +0x0001b56c, +0x0001b568, +0x0001b565, +0x0001b563, +0x0001b560, +0x0001b55c, +0x0001b55a, +0x0001b557, +0x0001b554, +0x0001b550, +0x0001b54f, +0x0001b54b, +0x0001b548, +0x0001b546, +0x0001b543, +0x0001b53f, +0x0001b53d, +0x0001b53a, +0x0001b537, +0x0001b533, +0x0001b532, +0x0001b52e, +0x0001b52b, +0x0001b529, +0x0001b526, +0x0001b522, +0x0001b51f, +0x0001b51d, +0x0001b51a, +0x0001b516, +0x0001b514, +0x0001b511, +0x0001b50e, +0x0001b50a, +0x0001b509, +0x0001b505, +0x0001b502, +0x0001b500, +0x0001b4fd, +0x0001b4f9, +0x0001b4f7, +0x0001b4f4, +0x0001b4f1, +0x0001b4ed, +0x0001b4ec, +0x0001b4e8, +0x0001b4e5, +0x0001b4e3, +0x0001b4e0, +0x0001b4dc, +0x0001b4d9, +0x0001b4d7, +0x0001b4d4, +0x0001b4d0, +0x0001b4ce, +0x0001b4cb, +0x0001b4c8, +0x0001b4c6, +0x0001b4c3, +0x0001b4bf, +0x0001b4bc, +0x0001b4ba, +0x0001b4b7, +0x0001b4b3, +0x0001b4b1, +0x0001b4ae, +0x0001b4ab, +0x0001b4a7, +0x0001b4a6, +0x0001b4a2, +0x0001b49f, +0x0001b49d, +0x0001b49a, +0x0001b496, +0x0001b493, +0x0001b491, +0x0001b48e, +0x0001b48a, +0x0001b489, +0x0001b485, +0x0001b482, +0x0001b480, +0x0001b47d, +0x0001b479, +0x0001b476, +0x0001b474, +0x0001b471, +0x0001b46d, +0x0001b46b, +0x0001b468, +0x0001b465, +0x0001b461, +0x0001b460, +0x0001b45c, +0x0001b459, +0x0001b457, +0x0001b454, +0x0001b450, +0x0001b44e, +0x0001b44b, +0x0001b448, +0x0001b444, +0x0001b443, +0x0001b43f, +0x0001b43c, +0x0001b43a, +0x0001b437, +0x0001b433, +0x0001b430, +0x0001b42d, +0x0001b42b, +0x0001b428, +0x0001b424, +0x0001b421, +0x0001b41f, +0x0001b41c, +0x0001b418, +0x0001b417, +0x0001b413, +0x0001b410, +0x0001b40e, +0x0001b40b, +0x0001b407, +0x0001b404, +0x0001b402, +0x0001b3ff, +0x0001b3fb, +0x0001b3fa, +0x0001b3f6, +0x0001b3f3, +0x0001b3f1, +0x0001b3ee, +0x0001b3ea, +0x0001b3e7, +0x0001b3e5, +0x0001b3e2, +0x0001b3df, +0x0001b3dd, +0x0001b3da, +0x0001b3d6, +0x0001b3d4, +0x0001b3d1, +0x0001b3ce, +0x0001b3ca, +0x0001b3c9, +0x0001b3c5, +0x0001b3c2, +0x0001b3c0, +0x0001b3bd, +0x0001b3b9, +0x0001b3b8, +0x0001b3b4, +0x0001b3b1, +0x0001b3ad, +0x0001b3ac, +0x0001b3a8, +0x0001b3a5, +0x0001b3a3, +0x0001b3a0, +0x0001b39c, +0x0001b39b, +0x0001b397, +0x0001b394, +0x0001b390, +0x0001b38f, +0x0001b38b, +0x0001b388, +0x0001b386, +0x0001b383, +0x0001b37f, +0x0001b37e, +0x0001b37a, +0x0001b377, +0x0001b375, +0x0001b372, +0x0001b36e, +0x0001b36b, +0x0001b369, +0x0001b366, +0x0001b363, +0x0001b361, +0x0001b35d, +0x0001b35a, +0x0001b358, +0x0001b355, +0x0001b352, +0x0001b34e, +0x0001b34c, +0x0001b349, +0x0001b346, +0x0001b344, +0x0001b341, +0x0001b33d, +0x0001b33b, +0x0001b338, +0x0001b335, +0x0001b331, +0x0001b330, +0x0001b32c, +0x0001b329, +0x0001b327, +0x0001b324, +0x0001b320, +0x0001b31f, +0x0001b31b, +0x0001b318, +0x0001b314, +0x0001b313, +0x0001b30f, +0x0001b30c, +0x0001b30a, +0x0001b307, +0x0001b303, +0x0001b302, +0x0001b2fe, +0x0001b2fb, +0x0001b2f8, +0x0001b2f6, +0x0001b2f2, +0x0001b2ef, +0x0001b2ed, +0x0001b2ea, +0x0001b2e7, +0x0001b2e5, +0x0001b2e1, +0x0001b2de, +0x0001b2db, +0x0001b2d9, +0x0001b2d6, +0x0001b2d2, +0x0001b2d0, +0x0001b2cd, +0x0001b2ca, +0x0001b2c8, +0x0001b2c5, +0x0001b2c1, +0x0001b2be, +0x0001b2bc, +0x0001b2b9, +0x0001b2b5, +0x0001b2b2, +0x0001b2b0, +0x0001b2ad, +0x0001b2aa, +0x0001b2a8, +0x0001b2a4, +0x0001b2a1, +0x0001b29f, +0x0001b29c, +0x0001b299, +0x0001b295, +0x0001b293, +0x0001b290, +0x0001b28d, +0x0001b28b, +0x0001b288, +0x0001b284, +0x0001b283, +0x0001b27f, +0x0001b27c, +0x0001b27a, +0x0001b277, +0x0001b273, +0x0001b270, +0x0001b26e, +0x0001b26b, +0x0001b267, +0x0001b266, +0x0001b262, +0x0001b25f, +0x0001b25d, +0x0001b25a, +0x0001b256, +0x0001b253, +0x0001b251, +0x0001b24e, +0x0001b24b, +0x0001b249, +0x0001b246, +0x0001b242, +0x0001b240, +0x0001b23d, +0x0001b23a, +0x0001b238, +0x0001b235, +0x0001b231, +0x0001b22e, +0x0001b22c, +0x0001b229, +0x0001b225, +0x0001b224, +0x0001b220, +0x0001b21d, +0x0001b21b, +0x0001b218, +0x0001b214, +0x0001b211, +0x0001b20f, +0x0001b20c, +0x0001b208, +0x0001b207, +0x0001b203, +0x0001b200, +0x0001b1fe, +0x0001b1fb, +0x0001b1f8, +0x0001b1f6, +0x0001b1f2, +0x0001b1ef, +0x0001b1ec, +0x0001b1ea, +0x0001b1e7, +0x0001b1e3, +0x0001b1e1, +0x0001b1de, +0x0001b1db, +0x0001b1d9, +0x0001b1d6, +0x0001b1d2, +0x0001b1cf, +0x0001b1cd, +0x0001b1ca, +0x0001b1c6, +0x0001b1c5, +0x0001b1c1, +0x0001b1be, +0x0001b1bc, +0x0001b1b9, +0x0001b1b5, +0x0001b1b4, +0x0001b1b0, +0x0001b1ad, +0x0001b1aa, +0x0001b1a8, +0x0001b1a4, +0x0001b1a1, +0x0001b19f, +0x0001b19c, +0x0001b199, +0x0001b197, +0x0001b194, +0x0001b190, +0x0001b18d, +0x0001b18b, +0x0001b188, +0x0001b184, +0x0001b183, +0x0001b17f, +0x0001b17c, +0x0001b17a, +0x0001b177, +0x0001b173, +0x0001b172, +0x0001b16e, +0x0001b16b, +0x0001b167, +0x0001b166, +0x0001b162, +0x0001b15f, +0x0001b15d, +0x0001b15a, +0x0001b156, +0x0001b155, +0x0001b151, +0x0001b14e, +0x0001b14c, +0x0001b149, +0x0001b145, +0x0001b144, +0x0001b140, +0x0001b13d, +0x0001b13b, +0x0001b138, +0x0001b134, +0x0001b133, +0x0001b12f, +0x0001b12c, +0x0001b129, +0x0001b127, +0x0001b124, +0x0001b120, +0x0001b11e, +0x0001b11b, +0x0001b118, +0x0001b116, +0x0001b113, +0x0001b10f, +0x0001b10e, +0x0001b10a, +0x0001b107, +0x0001b103, +0x0001b102, +0x0001b0fe, +0x0001b0fb, +0x0001b0f9, +0x0001b0f6, +0x0001b0f2, +0x0001b0f1, +0x0001b0ed, +0x0001b0ea, +0x0001b0e8, +0x0001b0e5, +0x0001b0e2, +0x0001b0de, +0x0001b0dc, +0x0001b0d9, +0x0001b0d6, +0x0001b0d4, +0x0001b0d1, +0x0001b0cd, +0x0001b0cc, +0x0001b0c8, +0x0001b0c5, +0x0001b0c3, +0x0001b0c0, +0x0001b0bc, +0x0001b0b9, +0x0001b0b7, +0x0001b0b4, +0x0001b0b1, +0x0001b0af, +0x0001b0ab, +0x0001b0a8, +0x0001b0a6, +0x0001b0a3, +0x0001b0a0, +0x0001b09e, +0x0001b09b, +0x0001b097, +0x0001b095, +0x0001b092, +0x0001b08f, +0x0001b08b, +0x0001b08a, +0x0001b086, +0x0001b083, +0x0001b081, +0x0001b07e, +0x0001b07a, +0x0001b079, +0x0001b075, +0x0001b072, +0x0001b070, +0x0001b06d, +0x0001b069, +0x0001b066, +0x0001b064, +0x0001b061, +0x0001b05e, +0x0001b05c, +0x0001b059, +0x0001b055, +0x0001b053, +0x0001b050, +0x0001b04d, +0x0001b04b, +0x0001b048, +0x0001b044, +0x0001b041, +0x0001b03f, +0x0001b03c, +0x0001b038, +0x0001b037, +0x0001b033, +0x0001b030, +0x0001b02e, +0x0001b02b, +0x0001b028, +0x0001b026, +0x0001b022, +0x0001b01f, +0x0001b01c, +0x0001b01a, +0x0001b017, +0x0001b013, +0x0001b012, +0x0001b00e, +0x0001b00b, +0x0001b009, +0x0001b006, +0x0001b002, +0x0001b001, +0x0001affd, +0x0001affa, +0x0001aff6, +0x0001aff5, +0x0001aff1, +0x0001afee, +0x0001afec, +0x0001afe9, +0x0001afe6, +0x0001afe4, +0x0001afe0, +0x0001afde, +0x0001afdb, +0x0001afd8, +0x0001afd6, +0x0001afd2, +0x0001afcf, +0x0001afcd, +0x0001afca, +0x0001afc7, +0x0001afc5, +0x0001afc2, +0x0001afbe, +0x0001afbd, +0x0001afb9, +0x0001afb6, +0x0001afb2, +0x0001afb1, +0x0001afad, +0x0001afaa, +0x0001afa8, +0x0001afa5, +0x0001afa2, +0x0001afa0, +0x0001af9d, +0x0001af99, +0x0001af98, +0x0001af94, +0x0001af91, +0x0001af8f, +0x0001af8c, +0x0001af88, +0x0001af87, +0x0001af83, +0x0001af80, +0x0001af7e, +0x0001af7b, +0x0001af78, +0x0001af74, +0x0001af72, +0x0001af6f, +0x0001af6c, +0x0001af6a, +0x0001af67, +0x0001af63, +0x0001af62, +0x0001af5e, +0x0001af5b, +0x0001af59, +0x0001af56, +0x0001af52, +0x0001af51, +0x0001af4d, +0x0001af4a, +0x0001af48, +0x0001af45, +0x0001af42, +0x0001af3e, +0x0001af3d, +0x0001af39, +0x0001af36, +0x0001af34, +0x0001af31, +0x0001af2d, +0x0001af2c, +0x0001af28, +0x0001af25, +0x0001af23, +0x0001af20, +0x0001af1d, +0x0001af1b, +0x0001af18, +0x0001af14, +0x0001af13, +0x0001af0f, +0x0001af0c, +0x0001af08, +0x0001af07, +0x0001af03, +0x0001af00, +0x0001aefe, +0x0001aefb, +0x0001aef8, +0x0001aef6, +0x0001aef3, +0x0001aeef, +0x0001aeed, +0x0001aeea, +0x0001aee7, +0x0001aee5, +0x0001aee2, +0x0001aede, +0x0001aedd, +0x0001aed9, +0x0001aed6, +0x0001aed3, +0x0001aed1, +0x0001aecd, +0x0001aeca, +0x0001aec8, +0x0001aec5, +0x0001aec2, +0x0001aec0, +0x0001aebd, +0x0001aeb9, +0x0001aeb8, +0x0001aeb4, +0x0001aeb1, +0x0001aeaf, +0x0001aeac, +0x0001aea8, +0x0001aea7, +0x0001aea3, +0x0001aea0, +0x0001ae9e, +0x0001ae9b, +0x0001ae98, +0x0001ae94, +0x0001ae93, +0x0001ae8f, +0x0001ae8c, +0x0001ae8a, +0x0001ae87, +0x0001ae83, +0x0001ae82, +0x0001ae7e, +0x0001ae7b, +0x0001ae79, +0x0001ae76, +0x0001ae74, +0x0001ae71, +0x0001ae6d, +0x0001ae6a, +0x0001ae68, +0x0001ae65, +0x0001ae61, +0x0001ae60, +0x0001ae5c, +0x0001ae59, +0x0001ae57, +0x0001ae54, +0x0001ae51, +0x0001ae4f, +0x0001ae4c, +0x0001ae48, +0x0001ae47, +0x0001ae43, +0x0001ae40, +0x0001ae3e, +0x0001ae3b, +0x0001ae37, +0x0001ae36, +0x0001ae32, +0x0001ae2f, +0x0001ae2d, +0x0001ae2a, +0x0001ae27, +0x0001ae23, +0x0001ae22, +0x0001ae1e, +0x0001ae1b, +0x0001ae19, +0x0001ae16, +0x0001ae12, +0x0001ae11, +0x0001ae0d, +0x0001ae0a, +0x0001ae08, +0x0001ae05, +0x0001ae02, +0x0001ae00, +0x0001adfd, +0x0001adf9, +0x0001adf8, +0x0001adf4, +0x0001adf1, +0x0001adef, +0x0001adec, +0x0001ade8, +0x0001ade7, +0x0001ade3, +0x0001ade0, +0x0001addd, +0x0001addb, +0x0001add8, +0x0001add4, +0x0001add3, +0x0001adcf, +0x0001adcc, +0x0001adca, +0x0001adc7, +0x0001adc4, +0x0001adc2, +0x0001adbe, +0x0001adbb, +0x0001adb9, +0x0001adb6, +0x0001adb3, +0x0001adb1, +0x0001adae, +0x0001adaa, +0x0001ada9, +0x0001ada5, +0x0001ada2, +0x0001ada0, +0x0001ad9d, +0x0001ad9a, +0x0001ad96, +0x0001ad95, +0x0001ad91, +0x0001ad8e, +0x0001ad8c, +0x0001ad89, +0x0001ad85, +0x0001ad84, +0x0001ad80, +0x0001ad7d, +0x0001ad7b, +0x0001ad78, +0x0001ad75, +0x0001ad73, +0x0001ad70, +0x0001ad6c, +0x0001ad6b, +0x0001ad67, +0x0001ad64, +0x0001ad62, +0x0001ad5f, +0x0001ad5b, +0x0001ad5a, +0x0001ad56, +0x0001ad53, +0x0001ad50, +0x0001ad4e, +0x0001ad4b, +0x0001ad47, +0x0001ad46, +0x0001ad42, +0x0001ad3f, +0x0001ad3d, +0x0001ad3a, +0x0001ad36, +0x0001ad35, +0x0001ad31, +0x0001ad2e, +0x0001ad2c, +0x0001ad29, +0x0001ad26, +0x0001ad24, +0x0001ad21, +0x0001ad1d, +0x0001ad1c, +0x0001ad18, +0x0001ad15, +0x0001ad13, +0x0001ad10, +0x0001ad0c, +0x0001ad0a, +0x0001ad06, +0x0001ad05, +0x0001ad01, +0x0001acfe, +0x0001acfc, +0x0001acf9, +0x0001acf6, +0x0001acf4, +0x0001acf1, +0x0001aced, +0x0001acec, +0x0001ace8, +0x0001ace5, +0x0001ace3, +0x0001ace0, +0x0001acdd, +0x0001acdb, +0x0001acd8, +0x0001acd4, +0x0001acd3, +0x0001accf, +0x0001accc, +0x0001acca, +0x0001acc7, +0x0001acc4, +0x0001acc2, +0x0001acbf, +0x0001acbb, +0x0001acba, +0x0001acb6, +0x0001acb3, +0x0001acb1, +0x0001acae, +0x0001acab, +0x0001aca7, +0x0001aca6, +0x0001aca2, +0x0001ac9f, +0x0001ac9d, +0x0001ac9a, +0x0001ac96, +0x0001ac95, +0x0001ac91, +0x0001ac8e, +0x0001ac8c, +0x0001ac89, +0x0001ac86, +0x0001ac84, +0x0001ac81, +0x0001ac7d, +0x0001ac7c, +0x0001ac78, +0x0001ac75, +0x0001ac73, +0x0001ac70, +0x0001ac6d, +0x0001ac6b, +0x0001ac68, +0x0001ac64, +0x0001ac63, +0x0001ac5f, +0x0001ac5c, +0x0001ac5a, +0x0001ac57, +0x0001ac54, +0x0001ac52, +0x0001ac4f, +0x0001ac4b, +0x0001ac4a, +0x0001ac46, +0x0001ac43, +0x0001ac41, +0x0001ac3e, +0x0001ac3b, +0x0001ac39, +0x0001ac36, +0x0001ac32, +0x0001ac30, +0x0001ac2d, +0x0001ac2a, +0x0001ac28, +0x0001ac25, +0x0001ac21, +0x0001ac20, +0x0001ac1c, +0x0001ac19, +0x0001ac17, +0x0001ac14, +0x0001ac11, +0x0001ac0f, +0x0001ac0c, +0x0001ac08, +0x0001ac07, +0x0001ac03, +0x0001ac00, +0x0001abfe, +0x0001abfb, +0x0001abf8, +0x0001abf4, +0x0001abf3, +0x0001abef, +0x0001abec, +0x0001abea, +0x0001abe7, +0x0001abe4, +0x0001abe2, +0x0001abdf, +0x0001abdb, +0x0001abda, +0x0001abd6, +0x0001abd3, +0x0001abd1, +0x0001abce, +0x0001abcb, +0x0001abc9, +0x0001abc5, +0x0001abc2, +0x0001abc0, +0x0001abbd, +0x0001abba, +0x0001abb8, +0x0001abb5, +0x0001abb1, +0x0001abb0, +0x0001abac, +0x0001aba9, +0x0001aba7, +0x0001aba3, +0x0001aba2, +0x0001ab9e, +0x0001ab9b, +0x0001ab99, +0x0001ab96, +0x0001ab93, +0x0001ab91, +0x0001ab8e, +0x0001ab8a, +0x0001ab89, +0x0001ab85, +0x0001ab82, +0x0001ab80, +0x0001ab7d, +0x0001ab7a, +0x0001ab78, +0x0001ab75, +0x0001ab71, +0x0001ab70, +0x0001ab6c, +0x0001ab69, +0x0001ab67, +0x0001ab64, +0x0001ab61, +0x0001ab5f, +0x0001ab5c, +0x0001ab58, +0x0001ab57, +0x0001ab53, +0x0001ab50, +0x0001ab4e, +0x0001ab4b, +0x0001ab48, +0x0001ab46, +0x0001ab43, +0x0001ab3f, +0x0001ab3e, +0x0001ab3a, +0x0001ab37, +0x0001ab35, +0x0001ab32, +0x0001ab2f, +0x0001ab2d, +0x0001ab2a, +0x0001ab26, +0x0001ab25, +0x0001ab21, +0x0001ab1e, +0x0001ab1c, +0x0001ab19, +0x0001ab16, +0x0001ab14, +0x0001ab11, +0x0001ab0d, +0x0001ab0c, +0x0001ab08, +0x0001ab05, +0x0001ab03, +0x0001ab00, +0x0001aafd, +0x0001aafb, +0x0001aaf8, +0x0001aaf4, +0x0001aaf3, +0x0001aaef, +0x0001aaec, +0x0001aae9, +0x0001aae7, +0x0001aae4, +0x0001aae0, +0x0001aadf, +0x0001aadb, +0x0001aad8, +0x0001aad6, +0x0001aad3, +0x0001aad0, +0x0001aace, +0x0001aacb, +0x0001aac7, +0x0001aac6, +0x0001aac2, +0x0001aabf, +0x0001aabd, +0x0001aaba, +0x0001aab7, +0x0001aab5, +0x0001aab2, +0x0001aaae, +0x0001aaad, +0x0001aaa9, +0x0001aaa6, +0x0001aaa4, +0x0001aaa1, +0x0001aa9e, +0x0001aa9c, +0x0001aa99, +0x0001aa95, +0x0001aa94, +0x0001aa90, +0x0001aa8d, +0x0001aa8b, +0x0001aa88, +0x0001aa85, +0x0001aa83, +0x0001aa80, +0x0001aa7c, +0x0001aa7b, +0x0001aa77, +0x0001aa74, +0x0001aa72, +0x0001aa6f, +0x0001aa6c, +0x0001aa6a, +0x0001aa67, +0x0001aa63, +0x0001aa62, +0x0001aa5e, +0x0001aa5b, +0x0001aa59, +0x0001aa56, +0x0001aa53, +0x0001aa51, +0x0001aa4e, +0x0001aa4a, +0x0001aa49, +0x0001aa45, +0x0001aa42, +0x0001aa41, +0x0001aa3e, +0x0001aa3a, +0x0001aa39, +0x0001aa35, +0x0001aa32, +0x0001aa30, +0x0001aa2d, +0x0001aa2a, +0x0001aa28, +0x0001aa25, +0x0001aa21, +0x0001aa20, +0x0001aa1c, +0x0001aa19, +0x0001aa17, +0x0001aa14, +0x0001aa11, +0x0001aa0f, +0x0001aa0c, +0x0001aa08, +0x0001aa07, +0x0001aa03, +0x0001aa00, +0x0001a9fe, +0x0001a9fb, +0x0001a9f8, +0x0001a9f6, +0x0001a9f3, +0x0001a9ef, +0x0001a9ee, +0x0001a9ea, +0x0001a9e7, +0x0001a9e5, +0x0001a9e2, +0x0001a9df, +0x0001a9dd, +0x0001a9da, +0x0001a9d6, +0x0001a9d5, +0x0001a9d1, +0x0001a9ce, +0x0001a9cc, +0x0001a9c9, +0x0001a9c6, +0x0001a9c4, +0x0001a9c1, +0x0001a9bd, +0x0001a9bc, +0x0001a9b8, +0x0001a9b5, +0x0001a9b3, +0x0001a9b0, +0x0001a9ad, +0x0001a9ab, +0x0001a9a8, +0x0001a9a4, +0x0001a9a3, +0x0001a99f, +0x0001a99c, +0x0001a99a, +0x0001a997, +0x0001a994, +0x0001a992, +0x0001a98f, +0x0001a98c, +0x0001a98a, +0x0001a987, +0x0001a983, +0x0001a982, +0x0001a97e, +0x0001a97b, +0x0001a979, +0x0001a976, +0x0001a973, +0x0001a971, +0x0001a96e, +0x0001a96a, +0x0001a969, +0x0001a965, +0x0001a962, +0x0001a960, +0x0001a95d, +0x0001a95a, +0x0001a958, +0x0001a955, +0x0001a951, +0x0001a950, +0x0001a94c, +0x0001a949, +0x0001a947, +0x0001a944, +0x0001a941, +0x0001a93f, +0x0001a93c, +0x0001a938, +0x0001a937, +0x0001a933, +0x0001a930, +0x0001a92e, +0x0001a92b, +0x0001a928, +0x0001a926, +0x0001a923, +0x0001a91f, +0x0001a91e, +0x0001a91a, +0x0001a917, +0x0001a915, +0x0001a912, +0x0001a90f, +0x0001a90d, +0x0001a90a, +0x0001a906, +0x0001a905, +0x0001a901, +0x0001a8fe, +0x0001a8fc, +0x0001a8f9, +0x0001a8f6, +0x0001a8f4, +0x0001a8f1, +0x0001a8ed, +0x0001a8ec, +0x0001a8e8, +0x0001a8e5, +0x0001a8e3, +0x0001a8e0, +0x0001a8de, +0x0001a8db, +0x0001a8d9, +0x0001a8d6, +0x0001a8d2, +0x0001a8d1, +0x0001a8cd, +0x0001a8ca, +0x0001a8c8, +0x0001a8c5, +0x0001a8c2, +0x0001a8c0, +0x0001a8bd, +0x0001a8ba, +0x0001a8b8, +0x0001a8b5, +0x0001a8b3, +0x0001a8b0, +0x0001a8ac, +0x0001a8ab, +0x0001a8a7, +0x0001a8a4, +0x0001a8a2, +0x0001a89f, +0x0001a89c, +0x0001a89a, +0x0001a897, +0x0001a893, +0x0001a892, +0x0001a88e, +0x0001a88b, +0x0001a889, +0x0001a886, +0x0001a883, +0x0001a881, +0x0001a87e, +0x0001a87b, +0x0001a879, +0x0001a876, +0x0001a872, +0x0001a871, +0x0001a86d, +0x0001a86a, +0x0001a868, +0x0001a865, +0x0001a862, +0x0001a860, +0x0001a85d, +0x0001a85b, +0x0001a858, +0x0001a854, +0x0001a853, +0x0001a850, +0x0001a84c, +0x0001a84b, +0x0001a847, +0x0001a844, +0x0001a842, +0x0001a83f, +0x0001a83c, +0x0001a83a, +0x0001a837, +0x0001a833, +0x0001a832, +0x0001a82e, +0x0001a82b, +0x0001a829, +0x0001a826, +0x0001a823, +0x0001a821, +0x0001a81e, +0x0001a81b, +0x0001a819, +0x0001a816, +0x0001a812, +0x0001a811, +0x0001a80d, +0x0001a80a, +0x0001a808, +0x0001a805, +0x0001a803, +0x0001a800, +0x0001a7fd, +0x0001a7fb, +0x0001a7f8, +0x0001a7f4, +0x0001a7f3, +0x0001a7ef, +0x0001a7ec, +0x0001a7ea, +0x0001a7e7, +0x0001a7e4, +0x0001a7e2, +0x0001a7df, +0x0001a7dc, +0x0001a7da, +0x0001a7d7, +0x0001a7d3, +0x0001a7d2, +0x0001a7ce, +0x0001a7cb, +0x0001a7c9, +0x0001a7c6, +0x0001a7c3, +0x0001a7c1, +0x0001a7be, +0x0001a7ba, +0x0001a7b9, +0x0001a7b5, +0x0001a7b2, +0x0001a7b1, +0x0001a7ad, +0x0001a7ac, +0x0001a7a8, +0x0001a7a5, +0x0001a7a3, +0x0001a7a0, +0x0001a79d, +0x0001a79b, +0x0001a798, +0x0001a794, +0x0001a793, +0x0001a78f, +0x0001a78c, +0x0001a78a, +0x0001a787, +0x0001a784, +0x0001a782, +0x0001a77f, +0x0001a77c, +0x0001a779, +0x0001a777, +0x0001a774, +0x0001a770, +0x0001a76f, +0x0001a76b, +0x0001a76a, +0x0001a766, +0x0001a763, +0x0001a761, +0x0001a75e, +0x0001a75b, +0x0001a759, +0x0001a756, +0x0001a753, +0x0001a751, +0x0001a74e, +0x0001a74a, +0x0001a749, +0x0001a745, +0x0001a742, +0x0001a740, +0x0001a73d, +0x0001a73a, +0x0001a738, +0x0001a735, +0x0001a732, +0x0001a730, +0x0001a72d, +0x0001a72b, +0x0001a728, +0x0001a724, +0x0001a723, +0x0001a71f, +0x0001a71c, +0x0001a71a, +0x0001a717, +0x0001a714, +0x0001a712, +0x0001a70f, +0x0001a70c, +0x0001a70a, +0x0001a707, +0x0001a703, +0x0001a702, +0x0001a6fe, +0x0001a6fb, +0x0001a6f9, +0x0001a6f6, +0x0001a6f3, +0x0001a6f1, +0x0001a6ee, +0x0001a6ec, +0x0001a6e9, +0x0001a6e6, +0x0001a6e4, +0x0001a6e1, +0x0001a6dd, +0x0001a6dc, +0x0001a6d8, +0x0001a6d5, +0x0001a6d3, +0x0001a6d0, +0x0001a6cd, +0x0001a6cb, +0x0001a6c8, +0x0001a6c5, +0x0001a6c3, +0x0001a6c0, +0x0001a6bc, +0x0001a6bb, +0x0001a6b7, +0x0001a6b4, +0x0001a6b2, +0x0001a6af, +0x0001a6ad, +0x0001a6aa, +0x0001a6a7, +0x0001a6a5, +0x0001a6a2, +0x0001a69f, +0x0001a69d, +0x0001a69a, +0x0001a696, +0x0001a695, +0x0001a691, +0x0001a68e, +0x0001a68c, +0x0001a689, +0x0001a686, +0x0001a684, +0x0001a681, +0x0001a67d, +0x0001a67c, +0x0001a679, +0x0001a675, +0x0001a674, +0x0001a670, +0x0001a66f, +0x0001a66b, +0x0001a668, +0x0001a666, +0x0001a663, +0x0001a660, +0x0001a65e, +0x0001a65b, +0x0001a657, +0x0001a656, +0x0001a653, +0x0001a64f, +0x0001a64e, +0x0001a64a, +0x0001a647, +0x0001a645, +0x0001a642, +0x0001a63f, +0x0001a63d, +0x0001a63a, +0x0001a636, +0x0001a635, +0x0001a631, +0x0001a630, +0x0001a62d, +0x0001a629, +0x0001a628, +0x0001a624, +0x0001a621, +0x0001a61e, +0x0001a61b, +0x0001a619, +0x0001a616, +0x0001a614, +0x0001a611, +0x0001a60e, +0x0001a60c, +0x0001a609, +0x0001a605, +0x0001a604, +0x0001a601, +0x0001a5fd, +0x0001a5fc, +0x0001a5f8, +0x0001a5f5, +0x0001a5f3, +0x0001a5f0, +0x0001a5ee, +0x0001a5eb, +0x0001a5e8, +0x0001a5e6, +0x0001a5e3, +0x0001a5e0, +0x0001a5de, +0x0001a5db, +0x0001a5d7, +0x0001a5d6, +0x0001a5d3, +0x0001a5cf, +0x0001a5ce, +0x0001a5ca, +0x0001a5c7, +0x0001a5c5, +0x0001a5c2, +0x0001a5c0, +0x0001a5bd, +0x0001a5ba, +0x0001a5b8, +0x0001a5b5, +0x0001a5b2, +0x0001a5b0, +0x0001a5ad, +0x0001a5a9, +0x0001a5a8, +0x0001a5a4, +0x0001a5a1, +0x0001a5a0, +0x0001a59c, +0x0001a59b, +0x0001a597, +0x0001a594, +0x0001a592, +0x0001a58f, +0x0001a58c, +0x0001a58a, +0x0001a587, +0x0001a584, +0x0001a582, +0x0001a57f, +0x0001a57b, +0x0001a57a, +0x0001a576, +0x0001a575, +0x0001a571, +0x0001a56e, +0x0001a56d, +0x0001a569, +0x0001a566, +0x0001a564, +0x0001a561, +0x0001a55e, +0x0001a55c, +0x0001a559, +0x0001a556, +0x0001a554, +0x0001a551, +0x0001a54d, +0x0001a54c, +0x0001a548, +0x0001a547, +0x0001a543, +0x0001a540, +0x0001a53e, +0x0001a53b, +0x0001a538, +0x0001a536, +0x0001a533, +0x0001a530, +0x0001a52e, +0x0001a52b, +0x0001a527, +0x0001a526, +0x0001a523, +0x0001a521, +0x0001a51e, +0x0001a51a, +0x0001a519, +0x0001a515, +0x0001a512, +0x0001a510, +0x0001a50d, +0x0001a50a, +0x0001a508, +0x0001a505, +0x0001a502, +0x0001a500, +0x0001a4fd, +0x0001a4f9, +0x0001a4f8, +0x0001a4f4, +0x0001a4f3, +0x0001a4f0, +0x0001a4ec, +0x0001a4eb, +0x0001a4e7, +0x0001a4e4, +0x0001a4e2, +0x0001a4df, +0x0001a4dc, +0x0001a4da, +0x0001a4d7, +0x0001a4d4, +0x0001a4d2, +0x0001a4cf, +0x0001a4cd, +0x0001a4ca, +0x0001a4c7, +0x0001a4c3, +0x0001a4c2, +0x0001a4be, +0x0001a4bb, +0x0001a4b9, +0x0001a4b6, +0x0001a4b4, +0x0001a4b1, +0x0001a4ae, +0x0001a4ac, +0x0001a4a9, +0x0001a4a6, +0x0001a4a4, +0x0001a4a1, +0x0001a49e, +0x0001a49c, +0x0001a499, +0x0001a495, +0x0001a494, +0x0001a490, +0x0001a48f, +0x0001a48b, +0x0001a488, +0x0001a487, +0x0001a483, +0x0001a480, +0x0001a47e, +0x0001a47b, +0x0001a478, +0x0001a476, +0x0001a473, +0x0001a471, +0x0001a46e, +0x0001a46b, +0x0001a469, +0x0001a466, +0x0001a462, +0x0001a461, +0x0001a45e, +0x0001a45a, +0x0001a459, +0x0001a455, +0x0001a452, +0x0001a450, +0x0001a44d, +0x0001a44b, +0x0001a448, +0x0001a445, +0x0001a443, +0x0001a440, +0x0001a43d, +0x0001a43b, +0x0001a438, +0x0001a435, +0x0001a433, +0x0001a430, +0x0001a42c, +0x0001a42b, +0x0001a427, +0x0001a426, +0x0001a422, +0x0001a41f, +0x0001a41e, +0x0001a41a, +0x0001a417, +0x0001a415, +0x0001a412, +0x0001a40f, +0x0001a40d, +0x0001a40a, +0x0001a408, +0x0001a405, +0x0001a402, +0x0001a400, +0x0001a3fd, +0x0001a3f9, +0x0001a3f8, +0x0001a3f5, +0x0001a3f1, +0x0001a3f0, +0x0001a3ec, +0x0001a3e9, +0x0001a3e7, +0x0001a3e4, +0x0001a3e2, +0x0001a3df, +0x0001a3dc, +0x0001a3da, +0x0001a3d7, +0x0001a3d4, +0x0001a3d2, +0x0001a3cf, +0x0001a3cc, +0x0001a3ca, +0x0001a3c7, +0x0001a3c5, +0x0001a3c2, +0x0001a3be, +0x0001a3bd, +0x0001a3b9, +0x0001a3b6, +0x0001a3b5, +0x0001a3b1, +0x0001a3ae, +0x0001a3ac, +0x0001a3a9, +0x0001a3a6, +0x0001a3a4, +0x0001a3a1, +0x0001a39f, +0x0001a39c, +0x0001a399, +0x0001a397, +0x0001a394, +0x0001a390, +0x0001a38f, +0x0001a38c, +0x0001a388, +0x0001a387, +0x0001a383, +0x0001a380, +0x0001a37e, +0x0001a37b, +0x0001a379, +0x0001a376, +0x0001a373, +0x0001a371, +0x0001a36e, +0x0001a36c, +0x0001a369, +0x0001a365, +0x0001a364, +0x0001a361, +0x0001a35d, +0x0001a35c, +0x0001a358, +0x0001a357, +0x0001a353, +0x0001a350, +0x0001a34f, +0x0001a34b, +0x0001a348, +0x0001a346, +0x0001a343, +0x0001a340, +0x0001a33e, +0x0001a33b, +0x0001a339, +0x0001a336, +0x0001a333, +0x0001a331, +0x0001a32e, +0x0001a32b, +0x0001a329, +0x0001a326, +0x0001a322, +0x0001a321, +0x0001a31d, +0x0001a31c, +0x0001a319, +0x0001a315, +0x0001a314, +0x0001a310, +0x0001a30d, +0x0001a30b, +0x0001a308, +0x0001a305, +0x0001a303, +0x0001a300, +0x0001a2fe, +0x0001a2fb, +0x0001a2f8, +0x0001a2f6, +0x0001a2f3, +0x0001a2f0, +0x0001a2ee, +0x0001a2eb, +0x0001a2e7, +0x0001a2e6, +0x0001a2e3, +0x0001a2e1, +0x0001a2de, +0x0001a2da, +0x0001a2d9, +0x0001a2d5, +0x0001a2d2, +0x0001a2d1, +0x0001a2cd, +0x0001a2ca, +0x0001a2c8, +0x0001a2c5, +0x0001a2c3, +0x0001a2c0, +0x0001a2bd, +0x0001a2bb, +0x0001a2b8, +0x0001a2b5, +0x0001a2b3, +0x0001a2b0, +0x0001a2ad, +0x0001a2ab, +0x0001a2a8, +0x0001a2a4, +0x0001a2a3, +0x0001a29f, +0x0001a29e, +0x0001a29b, +0x0001a297, +0x0001a296, +0x0001a292, +0x0001a28f, +0x0001a28d, +0x0001a28a, +0x0001a287, +0x0001a285, +0x0001a282, +0x0001a280, +0x0001a27d, +0x0001a27a, +0x0001a278, +0x0001a275, +0x0001a272, +0x0001a270, +0x0001a26d, +0x0001a269, +0x0001a268, +0x0001a265, +0x0001a263, +0x0001a260, +0x0001a25c, +0x0001a25b, +0x0001a257, +0x0001a254, +0x0001a253, +0x0001a24f, +0x0001a24c, +0x0001a24a, +0x0001a247, +0x0001a245, +0x0001a242, +0x0001a23f, +0x0001a23d, +0x0001a23a, +0x0001a237, +0x0001a235, +0x0001a232, +0x0001a22f, +0x0001a22d, +0x0001a22a, +0x0001a228, +0x0001a225, +0x0001a221, +0x0001a220, +0x0001a21c, +0x0001a219, +0x0001a217, +0x0001a215, +0x0001a212, +0x0001a20e, +0x0001a20d, +0x0001a20a, +0x0001a206, +0x0001a205, +0x0001a201, +0x0001a200, +0x0001a1fc, +0x0001a1f9, +0x0001a1f8, +0x0001a1f4, +0x0001a1f1, +0x0001a1ef, +0x0001a1ec, +0x0001a1eb, +0x0001a1e7, +0x0001a1e4, +0x0001a1e2, +0x0001a1df, +0x0001a1dc, +0x0001a1da, +0x0001a1d7, +0x0001a1d5, +0x0001a1d2, +0x0001a1cf, +0x0001a1cd, +0x0001a1ca, +0x0001a1c7, +0x0001a1c5, +0x0001a1c2, +0x0001a1bf, +0x0001a1bd, +0x0001a1ba, +0x0001a1b8, +0x0001a1b5, +0x0001a1b2, +0x0001a1b0, +0x0001a1ad, +0x0001a1a9, +0x0001a1a8, +0x0001a1a5, +0x0001a1a3, +0x0001a1a0, +0x0001a19c, +0x0001a19b, +0x0001a197, +0x0001a194, +0x0001a193, +0x0001a18f, +0x0001a18e, +0x0001a18a, +0x0001a187, +0x0001a186, +0x0001a182, +0x0001a17f, +0x0001a17d, +0x0001a17a, +0x0001a179, +0x0001a175, +0x0001a172, +0x0001a170, +0x0001a16d, +0x0001a16a, +0x0001a168, +0x0001a165, +0x0001a162, +0x0001a160, +0x0001a15d, +0x0001a15b, +0x0001a158, +0x0001a155, +0x0001a153, +0x0001a150, +0x0001a14d, +0x0001a14b, +0x0001a148, +0x0001a146, +0x0001a143, +0x0001a140, +0x0001a13e, +0x0001a13b, +0x0001a137, +0x0001a136, +0x0001a132, +0x0001a131, +0x0001a12e, +0x0001a12a, +0x0001a129, +0x0001a125, +0x0001a122, +0x0001a121, +0x0001a11d, +0x0001a11c, +0x0001a118, +0x0001a115, +0x0001a114, +0x0001a110, +0x0001a10d, +0x0001a10b, +0x0001a108, +0x0001a105, +0x0001a103, +0x0001a100, +0x0001a0fe, +0x0001a0fb, +0x0001a0f8, +0x0001a0f6, +0x0001a0f3, +0x0001a0f0, +0x0001a0ee, +0x0001a0eb, +0x0001a0e9, +0x0001a0e6, +0x0001a0e3, +0x0001a0e1, +0x0001a0de, +0x0001a0db, +0x0001a0d9, +0x0001a0d6, +0x0001a0d4, +0x0001a0d1, +0x0001a0ce, +0x0001a0cc, +0x0001a0c9, +0x0001a0c5, +0x0001a0c3, +0x0001a0c0, +0x0001a0be, +0x0001a0bb, +0x0001a0b9, +0x0001a0b6, +0x0001a0b3, +0x0001a0b1, +0x0001a0ae, +0x0001a0ab, +0x0001a0a9, +0x0001a0a6, +0x0001a0a4, +0x0001a0a1, +0x0001a09e, +0x0001a09c, +0x0001a099, +0x0001a096, +0x0001a094, +0x0001a091, +0x0001a08f, +0x0001a08c, +0x0001a089, +0x0001a087, +0x0001a084, +0x0001a080, +0x0001a07f, +0x0001a07c, +0x0001a07a, +0x0001a077, +0x0001a073, +0x0001a072, +0x0001a06f, +0x0001a06b, +0x0001a06a, +0x0001a066, +0x0001a065, +0x0001a062, +0x0001a05e, +0x0001a05d, +0x0001a059, +0x0001a056, +0x0001a055, +0x0001a051, +0x0001a050, +0x0001a04c, +0x0001a049, +0x0001a048, +0x0001a044, +0x0001a041, +0x0001a03f, +0x0001a03c, +0x0001a03b, +0x0001a037, +0x0001a034, +0x0001a032, +0x0001a02f, +0x0001a02c, +0x0001a02a, +0x0001a027, +0x0001a025, +0x0001a022, +0x0001a01f, +0x0001a01d, +0x0001a01a, +0x0001a017, +0x0001a015, +0x0001a012, +0x0001a010, +0x0001a00d, +0x0001a00a, +0x0001a008, +0x0001a005, +0x0001a002, +0x0001a000, +0x00019ffd, +0x00019ffb, +0x00019ff8, +0x00019ff5, +0x00019ff3, +0x00019ff0, +0x00019fed, +0x00019feb, +0x00019fe8, +0x00019fe6, +0x00019fe3, +0x00019fe0, +0x00019fde, +0x00019fdb, +0x00019fd7, +0x00019fd6, +0x00019fd3, +0x00019fd1, +0x00019fce, +0x00019fca, +0x00019fc9, +0x00019fc6, +0x00019fc2, +0x00019fc1, +0x00019fbd, +0x00019fbc, +0x00019fb9, +0x00019fb5, +0x00019fb4, +0x00019fb0, +0x00019fad, +0x00019fac, +0x00019fa8, +0x00019fa7, +0x00019fa3, +0x00019fa0, +0x00019f9f, +0x00019f9b, +0x00019f98, +0x00019f96, +0x00019f93, +0x00019f92, +0x00019f8e, +0x00019f8b, +0x00019f89, +0x00019f86, +0x00019f83, +0x00019f81, +0x00019f7e, +0x00019f7c, +0x00019f79, +0x00019f76, +0x00019f74, +0x00019f71, +0x00019f6e, +0x00019f6d, +0x00019f69, +0x00019f66, +0x00019f65, +0x00019f61, +0x00019f5e, +0x00019f5c, +0x00019f59, +0x00019f58, +0x00019f54, +0x00019f51, +0x00019f4f, +0x00019f4c, +0x00019f49, +0x00019f47, +0x00019f44, +0x00019f42, +0x00019f3f, +0x00019f3c, +0x00019f3a, +0x00019f37, +0x00019f34, +0x00019f32, +0x00019f2f, +0x00019f2d, +0x00019f2a, +0x00019f27, +0x00019f25, +0x00019f22, +0x00019f1f, +0x00019f1d, +0x00019f1a, +0x00019f18, +0x00019f15, +0x00019f12, +0x00019f10, +0x00019f0d, +0x00019f0b, +0x00019f08, +0x00019f05, +0x00019f03, +0x00019f00, +0x00019efd, +0x00019efb, +0x00019ef8, +0x00019ef6, +0x00019ef3, +0x00019ef0, +0x00019eee, +0x00019eeb, +0x00019ee8, +0x00019ee6, +0x00019ee3, +0x00019ee1, +0x00019ede, +0x00019edb, +0x00019ed9, +0x00019ed6, +0x00019ed3, +0x00019ed1, +0x00019ece, +0x00019ecc, +0x00019ec9, +0x00019ec6, +0x00019ec4, +0x00019ec1, +0x00019ebf, +0x00019ebc, +0x00019eb9, +0x00019eb7, +0x00019eb4, +0x00019eb1, +0x00019eaf, +0x00019eac, +0x00019eaa, +0x00019ea7, +0x00019ea4, +0x00019ea2, +0x00019e9f, +0x00019e9b, +0x00019e9a, +0x00019e97, +0x00019e95, +0x00019e92, +0x00019e8f, +0x00019e8d, +0x00019e8a, +0x00019e86, +0x00019e85, +0x00019e82, +0x00019e80, +0x00019e7d, +0x00019e79, +0x00019e78, +0x00019e75, +0x00019e73, +0x00019e70, +0x00019e6c, +0x00019e6b, +0x00019e68, +0x00019e64, +0x00019e63, +0x00019e60, +0x00019e5e, +0x00019e5b, +0x00019e57, +0x00019e56, +0x00019e53, +0x00019e4f, +0x00019e4e, +0x00019e4a, +0x00019e49, +0x00019e46, +0x00019e42, +0x00019e41, +0x00019e3d, +0x00019e3a, +0x00019e39, +0x00019e35, +0x00019e34, +0x00019e31, +0x00019e2d, +0x00019e2c, +0x00019e28, +0x00019e25, +0x00019e24, +0x00019e21, +0x00019e1e, +0x00019e1c, +0x00019e19, +0x00019e15, +0x00019e14, +0x00019e11, +0x00019e0d, +0x00019e0c, +0x00019e09, +0x00019e07, +0x00019e04, +0x00019e01, +0x00019dff, +0x00019dfc, +0x00019dfa, +0x00019df7, +0x00019df4, +0x00019df2, +0x00019def, +0x00019dec, +0x00019dea, +0x00019de7, +0x00019de5, +0x00019de2, +0x00019ddf, +0x00019ddd, +0x00019dda, +0x00019dd8, +0x00019dd5, +0x00019dd2, +0x00019dd0, +0x00019dcd, +0x00019dcb, +0x00019dc8, +0x00019dc5, +0x00019dc3, +0x00019dc0, +0x00019dbd, +0x00019dbb, +0x00019db8, +0x00019db6, +0x00019db3, +0x00019db0, +0x00019dae, +0x00019dab, +0x00019da9, +0x00019da6, +0x00019da3, +0x00019da1, +0x00019d9e, +0x00019d9b, +0x00019d99, +0x00019d96, +0x00019d94, +0x00019d91, +0x00019d8e, +0x00019d8c, +0x00019d89, +0x00019d88, +0x00019d84, +0x00019d81, +0x00019d7f, +0x00019d7c, +0x00019d7b, +0x00019d77, +0x00019d74, +0x00019d73, +0x00019d6f, +0x00019d6c, +0x00019d6a, +0x00019d67, +0x00019d66, +0x00019d62, +0x00019d5f, +0x00019d5e, +0x00019d5a, +0x00019d59, +0x00019d56, +0x00019d52, +0x00019d51, +0x00019d4d, +0x00019d4a, +0x00019d49, +0x00019d45, +0x00019d44, +0x00019d41, +0x00019d3d, +0x00019d3c, +0x00019d38, +0x00019d37, +0x00019d34, +0x00019d30, +0x00019d2f, +0x00019d2c, +0x00019d28, +0x00019d27, +0x00019d23, +0x00019d22, +0x00019d1f, +0x00019d1b, +0x00019d1a, +0x00019d17, +0x00019d15, +0x00019d12, +0x00019d0f, +0x00019d0d, +0x00019d0a, +0x00019d08, +0x00019d05, +0x00019d02, +0x00019d00, +0x00019cfd, +0x00019cfa, +0x00019cf8, +0x00019cf5, +0x00019cf3, +0x00019cf0, +0x00019ced, +0x00019ceb, +0x00019ce8, +0x00019ce6, +0x00019ce3, +0x00019ce0, +0x00019cde, +0x00019cdb, +0x00019cd8, +0x00019cd6, +0x00019cd3, +0x00019cd0, +0x00019cce, +0x00019ccb, +0x00019cc9, +0x00019cc6, +0x00019cc3, +0x00019cc1, +0x00019cbe, +0x00019cbc, +0x00019cb9, +0x00019cb6, +0x00019cb4, +0x00019cb1, +0x00019cae, +0x00019cac, +0x00019ca9, +0x00019ca7, +0x00019ca4, +0x00019ca1, +0x00019c9f, +0x00019c9c, +0x00019c9b, +0x00019c97, +0x00019c94, +0x00019c92, +0x00019c8f, +0x00019c8e, +0x00019c8a, +0x00019c87, +0x00019c86, +0x00019c82, +0x00019c81, +0x00019c7e, +0x00019c7a, +0x00019c79, +0x00019c75, +0x00019c72, +0x00019c71, +0x00019c6d, +0x00019c6c, +0x00019c69, +0x00019c65, +0x00019c64, +0x00019c61, +0x00019c5f, +0x00019c5c, +0x00019c59, +0x00019c57, +0x00019c54, +0x00019c52, +0x00019c4f, +0x00019c4c, +0x00019c4a, +0x00019c47, +0x00019c44, +0x00019c42, +0x00019c3f, +0x00019c3d, +0x00019c3a, +0x00019c37, +0x00019c35, +0x00019c32, +0x00019c30, +0x00019c2d, +0x00019c2a, +0x00019c28, +0x00019c25, +0x00019c23, +0x00019c20, +0x00019c1d, +0x00019c1b, +0x00019c18, +0x00019c17, +0x00019c13, +0x00019c10, +0x00019c0e, +0x00019c0b, +0x00019c08, +0x00019c06, +0x00019c03, +0x00019c02, +0x00019bfe, +0x00019bfb, +0x00019bfa, +0x00019bf6, +0x00019bf5, +0x00019bf2, +0x00019bee, +0x00019bed, +0x00019be9, +0x00019be8, +0x00019be5, +0x00019be1, +0x00019be0, +0x00019bdd, +0x00019bdb, +0x00019bd8, +0x00019bd5, +0x00019bd3, +0x00019bd0, +0x00019bcd, +0x00019bcb, +0x00019bc8, +0x00019bc6, +0x00019bc3, +0x00019bc0, +0x00019bbe, +0x00019bbb, +0x00019bb9, +0x00019bb6, +0x00019bb3, +0x00019bb1, +0x00019bae, +0x00019bac, +0x00019ba9, +0x00019ba6, +0x00019ba4, +0x00019ba1, +0x00019b9e, +0x00019b9c, +0x00019b99, +0x00019b97, +0x00019b94, +0x00019b91, +0x00019b8f, +0x00019b8c, +0x00019b8b, +0x00019b87, +0x00019b85, +0x00019b82, +0x00019b7f, +0x00019b7d, +0x00019b7a, +0x00019b78, +0x00019b75, +0x00019b72, +0x00019b70, +0x00019b6d, +0x00019b6c, +0x00019b68, +0x00019b65, +0x00019b64, +0x00019b60, +0x00019b5f, +0x00019b5c, +0x00019b58, +0x00019b57, +0x00019b53, +0x00019b52, +0x00019b4f, +0x00019b4b, +0x00019b4a, +0x00019b47, +0x00019b45, +0x00019b42, +0x00019b3f, +0x00019b3d, +0x00019b3a, +0x00019b37, +0x00019b35, +0x00019b32, +0x00019b30, +0x00019b2d, +0x00019b2a, +0x00019b28, +0x00019b25, +0x00019b23, +0x00019b20, +0x00019b1d, +0x00019b1b, +0x00019b18, +0x00019b16, +0x00019b13, +0x00019b10, +0x00019b0e, +0x00019b0b, +0x00019b0a, +0x00019b06, +0x00019b03, +0x00019b02, +0x00019afe, +0x00019afd, +0x00019afa, +0x00019af6, +0x00019af5, +0x00019af2, +0x00019af0, +0x00019aed, +0x00019aea, +0x00019ae8, +0x00019ae5, +0x00019ae3, +0x00019ae0, +0x00019add, +0x00019adb, +0x00019ad8, +0x00019ad5, +0x00019ad3, +0x00019ad0, +0x00019ace, +0x00019acb, +0x00019ac8, +0x00019ac6, +0x00019ac3, +0x00019ac1, +0x00019abe, +0x00019abb, +0x00019ab9, +0x00019ab6, +0x00019ab5, +0x00019ab1, +0x00019aae, +0x00019aad, +0x00019aa9, +0x00019aa8, +0x00019aa4, +0x00019aa1, +0x00019aa0, +0x00019a9c, +0x00019a9b, +0x00019a98, +0x00019a94, +0x00019a93, +0x00019a90, +0x00019a8e, +0x00019a8b, +0x00019a88, +0x00019a86, +0x00019a83, +0x00019a80, +0x00019a7e, +0x00019a7b, +0x00019a79, +0x00019a76, +0x00019a73, +0x00019a71, +0x00019a6e, +0x00019a6c, +0x00019a69, +0x00019a66, +0x00019a64, +0x00019a61, +0x00019a5f, +0x00019a5c, +0x00019a59, +0x00019a57, +0x00019a54, +0x00019a53, +0x00019a4f, +0x00019a4c, +0x00019a4b, +0x00019a47, +0x00019a46, +0x00019a43, +0x00019a3f, +0x00019a3e, +0x00019a3b, +0x00019a38, +0x00019a36, +0x00019a33, +0x00019a30, +0x00019a2e, +0x00019a2b, +0x00019a2a, +0x00019a26, +0x00019a23, +0x00019a22, +0x00019a1e, +0x00019a1d, +0x00019a1a, +0x00019a16, +0x00019a15, +0x00019a12, +0x00019a10, +0x00019a0d, +0x00019a0a, +0x00019a08, +0x00019a05, +0x00019a03, +0x00019a00, +0x000199fd, +0x000199fb, +0x000199f8, +0x000199f6, +0x000199f3, +0x000199f0, +0x000199ee, +0x000199eb, +0x000199ea, +0x000199e6, +0x000199e3, +0x000199e2, +0x000199de, +0x000199dd, +0x000199da, +0x000199d6, +0x000199d5, +0x000199d2, +0x000199d0, +0x000199cd, +0x000199ca, +0x000199c8, +0x000199c5, +0x000199c3, +0x000199c0, +0x000199bd, +0x000199bb, +0x000199b8, +0x000199b6, +0x000199b3, +0x000199b0, +0x000199ae, +0x000199ab, +0x000199aa, +0x000199a6, +0x000199a3, +0x000199a2, +0x0001999e, +0x0001999d, +0x0001999a, +0x00019996, +0x00019995, +0x00019991, +0x00019990, +0x0001998d, +0x00019989, +0x00019988, +0x00019985, +0x00019983, +0x00019980, +0x0001997d, +0x0001997b, +0x00019978, +0x00019976, +0x00019973, +0x00019970, +0x0001996e, +0x0001996b, +0x00019969, +0x00019966, +0x00019963, +0x00019961, +0x0001995e, +0x0001995d, +0x00019959, +0x00019956, +0x00019955, +0x00019951, +0x00019950, +0x0001994d, +0x00019949, +0x00019948, +0x00019945, +0x00019943, +0x00019940, +0x0001993d, +0x0001993b, +0x00019938, +0x00019936, +0x00019933, +0x00019930, +0x0001992e, +0x0001992b, +0x00019929, +0x00019926, +0x00019923, +0x00019921, +0x0001991e, +0x0001991d, +0x00019919, +0x00019916, +0x00019915, +0x00019911, +0x00019910, +0x0001990d, +0x00019909, +0x00019908, +0x00019905, +0x00019903, +0x00019900, +0x000198fd, +0x000198fb, +0x000198f8, +0x000198f5, +0x000198f2, +0x000198f1, +0x000198ed, +0x000198ec, +0x000198e9, +0x000198e6, +0x000198e4, +0x000198e1, +0x000198df, +0x000198dc, +0x000198d9, +0x000198d7, +0x000198d4, +0x000198d2, +0x000198cf, +0x000198ce, +0x000198ca, +0x000198c7, +0x000198c6, +0x000198c2, +0x000198c1, +0x000198be, +0x000198ba, +0x000198b9, +0x000198b6, +0x000198b4, +0x000198b1, +0x000198ae, +0x000198ac, +0x000198a9, +0x000198a7, +0x000198a4, +0x000198a1, +0x0001989f, +0x0001989c, +0x0001989b, +0x00019897, +0x00019894, +0x00019893, +0x0001988f, +0x0001988e, +0x0001988b, +0x00019887, +0x00019886, +0x00019883, +0x00019881, +0x0001987e, +0x0001987c, +0x00019879, +0x00019876, +0x00019874, +0x00019871, +0x00019870, +0x0001986c, +0x00019869, +0x00019868, +0x00019864, +0x00019863, +0x00019860, +0x0001985c, +0x0001985b, +0x00019858, +0x00019856, +0x00019853, +0x00019850, +0x0001984e, +0x0001984b, +0x00019849, +0x00019846, +0x00019843, +0x00019841, +0x0001983e, +0x0001983d, +0x00019839, +0x00019836, +0x00019835, +0x00019831, +0x00019830, +0x0001982d, +0x0001982b, +0x00019828, +0x00019825, +0x00019823, +0x00019820, +0x0001981e, +0x0001981b, +0x00019818, +0x00019816, +0x00019813, +0x00019812, +0x0001980e, +0x0001980b, +0x0001980a, +0x00019806, +0x00019805, +0x00019802, +0x000197fe, +0x000197fd, +0x000197fa, +0x000197f8, +0x000197f5, +0x000197f2, +0x000197f0, +0x000197ed, +0x000197eb, +0x000197e8, +0x000197e5, +0x000197e3, +0x000197e0, +0x000197df, +0x000197db, +0x000197da, +0x000197d7, +0x000197d3, +0x000197d2, +0x000197cf, +0x000197cd, +0x000197ca, +0x000197c7, +0x000197c5, +0x000197c2, +0x000197c0, +0x000197bd, +0x000197ba, +0x000197b8, +0x000197b5, +0x000197b4, +0x000197b0, +0x000197ad, +0x000197ac, +0x000197a9, +0x000197a5, +0x000197a4, +0x000197a1, +0x0001979f, +0x0001979c, +0x00019799, +0x00019797, +0x00019794, +0x00019792, +0x0001978f, +0x0001978c, +0x0001978a, +0x00019787, +0x00019786, +0x00019782, +0x00019781, +0x0001977e, +0x0001977a, +0x00019779, +0x00019776, +0x00019774, +0x00019771, +0x0001976e, +0x0001976c, +0x00019769, +0x00019767, +0x00019764, +0x00019761, +0x0001975f, +0x0001975c, +0x0001975b, +0x00019757, +0x00019756, +0x00019753, +0x0001974f, +0x0001974e, +0x0001974b, +0x00019749, +0x00019746, +0x00019743, +0x00019741, +0x0001973e, +0x0001973c, +0x00019739, +0x00019736, +0x00019734, +0x00019731, +0x00019730, +0x0001972d, +0x00019729, +0x00019728, +0x00019725, +0x00019723, +0x00019720, +0x0001971e, +0x0001971b, +0x00019718, +0x00019716, +0x00019713, +0x00019711, +0x0001970e, +0x0001970b, +0x0001970a, +0x00019706, +0x00019705, +0x00019702, +0x000196fe, +0x000196fd, +0x000196fa, +0x000196f8, +0x000196f5, +0x000196f3, +0x000196f0, +0x000196ed, +0x000196eb, +0x000196e8, +0x000196e7, +0x000196e3, +0x000196e0, +0x000196df, +0x000196db, +0x000196da, +0x000196d7, +0x000196d3, +0x000196d2, +0x000196cf, +0x000196cd, +0x000196ca, +0x000196c7, +0x000196c5, +0x000196c2, +0x000196c0, +0x000196bd, +0x000196bc, +0x000196b8, +0x000196b5, +0x000196b4, +0x000196b1, +0x000196af, +0x000196ac, +0x000196a9, +0x000196a7, +0x000196a4, +0x000196a2, +0x0001969f, +0x0001969c, +0x0001969a, +0x00019697, +0x00019695, +0x00019692, +0x00019691, +0x0001968e, +0x0001968a, +0x00019689, +0x00019686, +0x00019684, +0x00019681, +0x0001967e, +0x0001967c, +0x00019679, +0x00019677, +0x00019674, +0x00019671, +0x0001966f, +0x0001966d, +0x0001966a, +0x00019667, +0x00019666, +0x00019662, +0x00019661, +0x0001965e, +0x0001965a, +0x00019659, +0x00019656, +0x00019654, +0x00019651, +0x0001964e, +0x0001964c, +0x00019649, +0x00019647, +0x00019644, +0x00019643, +0x0001963f, +0x0001963c, +0x0001963b, +0x00019638, +0x00019636, +0x00019633, +0x00019630, +0x0001962e, +0x0001962b, +0x00019629, +0x00019626, +0x00019624, +0x00019621, +0x0001961e, +0x0001961d, +0x00019619, +0x00019618, +0x00019615, +0x00019611, +0x00019610, +0x0001960d, +0x0001960b, +0x00019608, +0x00019605, +0x00019603, +0x00019600, +0x000195fe, +0x000195fb, +0x000195fa, +0x000195f6, +0x000195f3, +0x000195f2, +0x000195ef, +0x000195ed, +0x000195ea, +0x000195e7, +0x000195e5, +0x000195e2, +0x000195e0, +0x000195dd, +0x000195dc, +0x000195d8, +0x000195d5, +0x000195d4, +0x000195d0, +0x000195cf, +0x000195cc, +0x000195c8, +0x000195c7, +0x000195c4, +0x000195c2, +0x000195bf, +0x000195bc, +0x000195ba, +0x000195b7, +0x000195b5, +0x000195b2, +0x000195b1, +0x000195ae, +0x000195aa, +0x000195a9, +0x000195a6, +0x000195a4, +0x000195a1, +0x0001959e, +0x0001959c, +0x00019599, +0x00019597, +0x00019594, +0x00019593, +0x0001958f, +0x0001958c, +0x0001958b, +0x00019587, +0x00019586, +0x00019583, +0x00019580, +0x0001957e, +0x0001957b, +0x00019579, +0x00019576, +0x00019573, +0x00019571, +0x0001956e, +0x0001956d, +0x00019569, +0x00019568, +0x00019565, +0x00019561, +0x00019560, +0x0001955d, +0x0001955b, +0x00019558, +0x00019555, +0x00019553, +0x00019550, +0x0001954e, +0x0001954b, +0x0001954a, +0x00019546, +0x00019543, +0x00019542, +0x0001953f, +0x0001953d, +0x0001953a, +0x00019537, +0x00019535, +0x00019532, +0x00019530, +0x0001952d, +0x0001952b, +0x00019529, +0x00019526, +0x00019524, +0x00019521, +0x0001951e, +0x0001951c, +0x00019519, +0x00019518, +0x00019515, +0x00019511, +0x00019510, +0x0001950d, +0x0001950b, +0x00019508, +0x00019506, +0x00019503, +0x00019500, +0x000194fe, +0x000194fb, +0x000194fa, +0x000194f7, +0x000194f3, +0x000194f2, +0x000194ef, +0x000194ed, +0x000194ea, +0x000194e8, +0x000194e5, +0x000194e2, +0x000194e0, +0x000194dd, +0x000194dc, +0x000194d8, +0x000194d5, +0x000194d4, +0x000194d1, +0x000194cf, +0x000194cc, +0x000194ca, +0x000194c7, +0x000194c4, +0x000194c2, +0x000194bf, +0x000194be, +0x000194ba, +0x000194b7, +0x000194b6, +0x000194b2, +0x000194b1, +0x000194ae, +0x000194ac, +0x000194a9, +0x000194a6, +0x000194a4, +0x000194a1, +0x0001949f, +0x0001949c, +0x00019499, +0x00019498, +0x00019494, +0x00019493, +0x00019490, +0x0001948e, +0x0001948b, +0x00019488, +0x00019486, +0x00019483, +0x00019481, +0x0001947e, +0x0001947d, +0x0001947a, +0x00019476, +0x00019475, +0x00019472, +0x00019470, +0x0001946d, +0x0001946a, +0x00019468, +0x00019465, +0x00019463, +0x00019460, +0x0001945f, +0x0001945b, +0x00019458, +0x00019457, +0x00019454, +0x00019452, +0x0001944f, +0x0001944c, +0x0001944a, +0x00019447, +0x00019445, +0x00019442, +0x00019441, +0x0001943d, +0x0001943a, +0x00019439, +0x00019436, +0x00019434, +0x00019431, +0x0001942e, +0x0001942c, +0x00019429, +0x00019427, +0x00019424, +0x00019423, +0x0001941f, +0x0001941c, +0x0001941b, +0x00019417, +0x00019416, +0x00019413, +0x00019410, +0x0001940e, +0x0001940b, +0x00019409, +0x00019406, +0x00019404, +0x00019401, +0x000193fe, +0x000193fd, +0x000193f9, +0x000193f8, +0x000193f5, +0x000193f1, +0x000193f0, +0x000193ed, +0x000193eb, +0x000193e9, +0x000193e6, +0x000193e4, +0x000193e1, +0x000193de, +0x000193dc, +0x000193d9, +0x000193d8, +0x000193d5, +0x000193d3, +0x000193d0, +0x000193cd, +0x000193cb, +0x000193c8, +0x000193c6, +0x000193c3, +0x000193c0, +0x000193be, +0x000193bb, +0x000193ba, +0x000193b7, +0x000193b5, +0x000193b2, +0x000193af, +0x000193ad, +0x000193aa, +0x000193a8, +0x000193a5, +0x000193a4, +0x000193a1, +0x0001939d, +0x0001939c, +0x00019399, +0x00019397, +0x00019394, +0x00019392, +0x0001938f, +0x0001938c, +0x0001938b, +0x00019387, +0x00019386, +0x00019383, +0x00019381, +0x0001937e, +0x0001937b, +0x00019379, +0x00019376, +0x00019374, +0x00019371, +0x00019370, +0x0001936d, +0x00019369, +0x00019368, +0x00019365, +0x00019363, +0x00019360, +0x0001935e, +0x0001935b, +0x00019358, +0x00019357, +0x00019353, +0x00019352, +0x0001934f, +0x0001934d, +0x0001934a, +0x00019347, +0x00019345, +0x00019342, +0x00019341, +0x0001933d, +0x0001933a, +0x00019339, +0x00019336, +0x00019334, +0x00019331, +0x0001932f, +0x0001932c, +0x00019329, +0x00019327, +0x00019324, +0x00019323, +0x0001931f, +0x0001931e, +0x0001931b, +0x00019318, +0x00019316, +0x00019313, +0x00019311, +0x0001930e, +0x0001930d, +0x00019309, +0x00019306, +0x00019305, +0x00019302, +0x00019300, +0x000192fd, +0x000192fb, +0x000192f8, +0x000192f5, +0x000192f3, +0x000192f0, +0x000192ef, +0x000192ec, +0x000192ea, +0x000192e7, +0x000192e4, +0x000192e2, +0x000192df, +0x000192dd, +0x000192da, +0x000192d9, +0x000192d5, +0x000192d2, +0x000192d1, +0x000192ce, +0x000192cc, +0x000192c9, +0x000192c6, +0x000192c4, +0x000192c1, +0x000192bf, +0x000192bc, +0x000192bb, +0x000192b8, +0x000192b4, +0x000192b3, +0x000192b0, +0x000192ae, +0x000192ab, +0x000192a8, +0x000192a6, +0x000192a3, +0x000192a2, +0x0001929f, +0x0001929d, +0x0001929a, +0x00019297, +0x00019295, +0x00019292, +0x00019290, +0x0001928d, +0x0001928c, +0x00019289, +0x00019285, +0x00019284, +0x00019281, +0x0001927f, +0x0001927c, +0x0001927a, +0x00019277, +0x00019274, +0x00019273, +0x0001926f, +0x0001926e, +0x0001926b, +0x00019269, +0x00019266, +0x00019263, +0x00019261, +0x0001925e, +0x0001925d, +0x0001925a, +0x00019258, +0x00019255, +0x00019252, +0x00019250, +0x0001924d, +0x0001924b, +0x00019248, +0x00019247, +0x00019244, +0x00019240, +0x0001923f, +0x0001923c, +0x0001923a, +0x00019237, +0x00019235, +0x00019232, +0x0001922f, +0x0001922e, +0x0001922a, +0x00019229, +0x00019226, +0x00019224, +0x00019221, +0x0001921e, +0x0001921c, +0x00019219, +0x00019218, +0x00019214, +0x00019213, +0x00019210, +0x0001920d, +0x0001920b, +0x00019208, +0x00019206, +0x00019203, +0x00019202, +0x000191fe, +0x000191fb, +0x000191fa, +0x000191f7, +0x000191f5, +0x000191f2, +0x000191f0, +0x000191ed, +0x000191ea, +0x000191e8, +0x000191e5, +0x000191e4, +0x000191e1, +0x000191df, +0x000191dc, +0x000191d9, +0x000191d7, +0x000191d4, +0x000191d2, +0x000191cf, +0x000191ce, +0x000191cb, +0x000191c7, +0x000191c6, +0x000191c3, +0x000191c1, +0x000191be, +0x000191bc, +0x000191b9, +0x000191b6, +0x000191b5, +0x000191b1, +0x000191b0, +0x000191ad, +0x000191ab, +0x000191a8, +0x000191a5, +0x000191a3, +0x000191a0, +0x0001919f, +0x0001919c, +0x0001919a, +0x00019197, +0x00019194, +0x00019192, +0x0001918f, +0x0001918d, +0x0001918a, +0x00019189, +0x00019186, +0x00019182, +0x00019181, +0x0001917e, +0x0001917c, +0x00019179, +0x00019177, +0x00019174, +0x00019172, +0x0001916f, +0x0001916e, +0x0001916b, +0x00019167, +0x00019166, +0x00019163, +0x00019161, +0x0001915e, +0x0001915c, +0x00019159, +0x00019158, +0x00019155, +0x00019151, +0x00019150, +0x0001914d, +0x0001914b, +0x00019148, +0x00019146, +0x00019143, +0x00019140, +0x0001913f, +0x0001913c, +0x0001913a, +0x00019137, +0x00019135, +0x00019132, +0x0001912f, +0x0001912d, +0x0001912a, +0x00019129, +0x00019126, +0x00019124, +0x00019121, +0x0001911e, +0x0001911c, +0x00019119, +0x00019117, +0x00019114, +0x00019113, +0x00019110, +0x0001910e, +0x0001910b, +0x00019108, +0x00019106, +0x00019103, +0x00019102, +0x000190fe, +0x000190fd, +0x000190fa, +0x000190f7, +0x000190f5, +0x000190f2, +0x000190f0, +0x000190ed, +0x000190ec, +0x000190e9, +0x000190e5, +0x000190e4, +0x000190e1, +0x000190df, +0x000190dc, +0x000190da, +0x000190d7, +0x000190d6, +0x000190d3, +0x000190cf, +0x000190ce, +0x000190cb, +0x000190c9, +0x000190c6, +0x000190c4, +0x000190c1, +0x000190be, +0x000190bd, +0x000190ba, +0x000190b8, +0x000190b5, +0x000190b3, +0x000190b0, +0x000190ad, +0x000190ab, +0x000190a8, +0x000190a7, +0x000190a4, +0x000190a2, +0x0001909f, +0x0001909c, +0x0001909a, +0x00019097, +0x00019095, +0x00019092, +0x00019091, +0x0001908e, +0x0001908c, +0x00019089, +0x00019086, +0x00019084, +0x00019081, +0x00019080, +0x0001907c, +0x0001907b, +0x00019078, +0x00019075, +0x00019073, +0x00019070, +0x0001906e, +0x0001906b, +0x0001906a, +0x00019066, +0x00019063, +0x00019062, +0x0001905f, +0x0001905d, +0x0001905a, +0x00019058, +0x00019055, +0x00019052, +0x00019051, +0x0001904d, +0x0001904c, +0x00019049, +0x00019047, +0x00019044, +0x00019042, +0x0001903f, +0x0001903c, +0x0001903b, +0x00019038, +0x00019035, +0x00019034, +0x00019030, +0x0001902f, +0x0001902c, +0x0001902a, +0x00019027, +0x00019026, +0x00019022, +0x0001901f, +0x0001901e, +0x0001901b, +0x00019019, +0x00019016, +0x00019014, +0x00019011, +0x0001900e, +0x0001900d, +0x00019009, +0x00019008, +0x00019005, +0x00019003, +0x00019000, +0x00018ffe, +0x00018ffb, +0x00018ff8, +0x00018ff7, +0x00018ff4, +0x00018ff2, +0x00018fef, +0x00018fed, +0x00018fea, +0x00018fe7, +0x00018fe5, +0x00018fe2, +0x00018fe1, +0x00018fde, +0x00018fdc, +0x00018fd9, +0x00018fd7, +0x00018fd4, +0x00018fd1, +0x00018fd0, +0x00018fcc, +0x00018fcb, +0x00018fc8, +0x00018fc6, +0x00018fc3, +0x00018fc0, +0x00018fbe, +0x00018fbb, +0x00018fba, +0x00018fb7, +0x00018fb5, +0x00018fb2, +0x00018fb0, +0x00018fad, +0x00018faa, +0x00018fa9, +0x00018fa5, +0x00018fa4, +0x00018fa1, +0x00018f9f, +0x00018f9c, +0x00018f99, +0x00018f97, +0x00018f94, +0x00018f93, +0x00018f90, +0x00018f8e, +0x00018f8b, +0x00018f89, +0x00018f86, +0x00018f83, +0x00018f81, +0x00018f7e, +0x00018f7d, +0x00018f7a, +0x00018f78, +0x00018f75, +0x00018f72, +0x00018f70, +0x00018f6d, +0x00018f6c, +0x00018f68, +0x00018f67, +0x00018f64, +0x00018f62, +0x00018f5f, +0x00018f5c, +0x00018f5a, +0x00018f57, +0x00018f56, +0x00018f53, +0x00018f51, +0x00018f4e, +0x00018f4b, +0x00018f49, +0x00018f46, +0x00018f45, +0x00018f41, +0x00018f40, +0x00018f3d, +0x00018f3b, +0x00018f38, +0x00018f35, +0x00018f33, +0x00018f30, +0x00018f2f, +0x00018f2c, +0x00018f2a, +0x00018f27, +0x00018f24, +0x00018f22, +0x00018f1f, +0x00018f1d, +0x00018f1a, +0x00018f19, +0x00018f16, +0x00018f14, +0x00018f11, +0x00018f0e, +0x00018f0c, +0x00018f09, +0x00018f08, +0x00018f04, +0x00018f03, +0x00018f01, +0x00018efd, +0x00018efa, +0x00018ef9, +0x00018ef6, +0x00018ef4, +0x00018ef1, +0x00018eef, +0x00018eec, +0x00018eeb, +0x00018ee8, +0x00018ee5, +0x00018ee3, +0x00018ee0, +0x00018ede, +0x00018edb, +0x00018eda, +0x00018ed7, +0x00018ed5, +0x00018ed2, +0x00018ecf, +0x00018ecd, +0x00018eca, +0x00018ec9, +0x00018ec5, +0x00018ec4, +0x00018ec1, +0x00018ebf, +0x00018ebc, +0x00018eb9, +0x00018eb7, +0x00018eb4, +0x00018eb3, +0x00018eb0, +0x00018eae, +0x00018eab, +0x00018ea9, +0x00018ea6, +0x00018ea3, +0x00018ea2, +0x00018e9f, +0x00018e9d, +0x00018e9a, +0x00018e98, +0x00018e95, +0x00018e94, +0x00018e91, +0x00018e8d, +0x00018e8c, +0x00018e89, +0x00018e87, +0x00018e84, +0x00018e83, +0x00018e7f, +0x00018e7e, +0x00018e7b, +0x00018e78, +0x00018e76, +0x00018e73, +0x00018e71, +0x00018e6e, +0x00018e6d, +0x00018e6a, +0x00018e68, +0x00018e65, +0x00018e62, +0x00018e60, +0x00018e5d, +0x00018e5c, +0x00018e59, +0x00018e57, +0x00018e54, +0x00018e52, +0x00018e4f, +0x00018e4c, +0x00018e4b, +0x00018e48, +0x00018e46, +0x00018e43, +0x00018e41, +0x00018e3e, +0x00018e3d, +0x00018e3a, +0x00018e36, +0x00018e35, +0x00018e32, +0x00018e30, +0x00018e2d, +0x00018e2c, +0x00018e28, +0x00018e27, +0x00018e24, +0x00018e21, +0x00018e1f, +0x00018e1c, +0x00018e1a, +0x00018e17, +0x00018e16, +0x00018e13, +0x00018e11, +0x00018e0e, +0x00018e0b, +0x00018e09, +0x00018e06, +0x00018e05, +0x00018e02, +0x00018e00, +0x00018dfd, +0x00018dfb, +0x00018df8, +0x00018df5, +0x00018df4, +0x00018df0, +0x00018def, +0x00018dec, +0x00018dea, +0x00018de7, +0x00018de6, +0x00018de2, +0x00018ddf, +0x00018dde, +0x00018ddb, +0x00018dd9, +0x00018dd6, +0x00018dd4, +0x00018dd1, +0x00018dd0, +0x00018dcd, +0x00018dca, +0x00018dc8, +0x00018dc5, +0x00018dc3, +0x00018dc0, +0x00018dbd, +0x00018dbc, +0x00018db9, +0x00018db7, +0x00018db4, +0x00018db2, +0x00018daf, +0x00018dae, +0x00018dab, +0x00018da9, +0x00018da6, +0x00018da3, +0x00018da1, +0x00018d9e, +0x00018d9d, +0x00018d9a, +0x00018d98, +0x00018d95, +0x00018d93, +0x00018d90, +0x00018d8d, +0x00018d8c, +0x00018d88, +0x00018d87, +0x00018d84, +0x00018d82, +0x00018d7f, +0x00018d7e, +0x00018d7b, +0x00018d79, +0x00018d76, +0x00018d73, +0x00018d71, +0x00018d6e, +0x00018d6d, +0x00018d69, +0x00018d68, +0x00018d65, +0x00018d63, +0x00018d60, +0x00018d5d, +0x00018d5b, +0x00018d58, +0x00018d57, +0x00018d54, +0x00018d52, +0x00018d4f, +0x00018d4e, +0x00018d4a, +0x00018d49, +0x00018d46, +0x00018d43, +0x00018d41, +0x00018d3e, +0x00018d3c, +0x00018d39, +0x00018d38, +0x00018d35, +0x00018d33, +0x00018d30, +0x00018d2d, +0x00018d2b, +0x00018d28, +0x00018d27, +0x00018d24, +0x00018d22, +0x00018d1f, +0x00018d1d, +0x00018d1a, +0x00018d17, +0x00018d16, +0x00018d13, +0x00018d11, +0x00018d0e, +0x00018d0c, +0x00018d09, +0x00018d08, +0x00018d05, +0x00018d03, +0x00018d00, +0x00018cfd, +0x00018cfb, +0x00018cf8, +0x00018cf7, +0x00018cf4, +0x00018cf2, +0x00018cef, +0x00018ced, +0x00018cea, +0x00018ce7, +0x00018ce6, +0x00018ce3, +0x00018ce1, +0x00018cde, +0x00018cdc, +0x00018cd9, +0x00018cd8, +0x00018cd5, +0x00018cd3, +0x00018cd0, +0x00018ccd, +0x00018ccb, +0x00018cc8, +0x00018cc7, +0x00018cc4, +0x00018cc2, +0x00018cbf, +0x00018cbd, +0x00018cba, +0x00018cb7, +0x00018cb6, +0x00018cb2, +0x00018cb1, +0x00018cae, +0x00018cac, +0x00018ca9, +0x00018ca8, +0x00018ca5, +0x00018ca3, +0x00018ca0, +0x00018c9d, +0x00018c9b, +0x00018c98, +0x00018c96, +0x00018c93, +0x00018c91, +0x00018c8e, +0x00018c8d, +0x00018c8a, +0x00018c88, +0x00018c85, +0x00018c83, +0x00018c80, +0x00018c7f, +0x00018c7c, +0x00018c79, +0x00018c77, +0x00018c74, +0x00018c72, +0x00018c6f, +0x00018c6e, +0x00018c6b, +0x00018c69, +0x00018c66, +0x00018c65, +0x00018c61, +0x00018c5e, +0x00018c5d, +0x00018c5a, +0x00018c58, +0x00018c55, +0x00018c54, +0x00018c50, +0x00018c4f, +0x00018c4c, +0x00018c4a, +0x00018c47, +0x00018c44, +0x00018c43, +0x00018c3f, +0x00018c3e, +0x00018c3b, +0x00018c39, +0x00018c36, +0x00018c35, +0x00018c32, +0x00018c2e, +0x00018c2d, +0x00018c2a, +0x00018c28, +0x00018c25, +0x00018c24, +0x00018c20, +0x00018c1f, +0x00018c1c, +0x00018c1a, +0x00018c17, +0x00018c14, +0x00018c13, +0x00018c0f, +0x00018c0e, +0x00018c0b, +0x00018c09, +0x00018c06, +0x00018c05, +0x00018c02, +0x00018c00, +0x00018bfd, +0x00018bfa, +0x00018bf8, +0x00018bf5, +0x00018bf4, +0x00018bf1, +0x00018bef, +0x00018bec, +0x00018bea, +0x00018be7, +0x00018be6, +0x00018be3, +0x00018be0, +0x00018bde, +0x00018bdb, +0x00018bd9, +0x00018bd6, +0x00018bd5, +0x00018bd2, +0x00018bd0, +0x00018bcd, +0x00018bcb, +0x00018bc8, +0x00018bc5, +0x00018bc4, +0x00018bc1, +0x00018bbf, +0x00018bbc, +0x00018bba, +0x00018bb7, +0x00018bb6, +0x00018bb3, +0x00018bb1, +0x00018bae, +0x00018bab, +0x00018ba9, +0x00018ba6, +0x00018ba5, +0x00018ba2, +0x00018ba0, +0x00018b9d, +0x00018b9b, +0x00018b98, +0x00018b95, +0x00018b94, +0x00018b91, +0x00018b8f, +0x00018b8c, +0x00018b8a, +0x00018b87, +0x00018b86, +0x00018b83, +0x00018b81, +0x00018b7e, +0x00018b7b, +0x00018b79, +0x00018b76, +0x00018b75, +0x00018b72, +0x00018b70, +0x00018b6d, +0x00018b6c, +0x00018b68, +0x00018b67, +0x00018b64, +0x00018b61, +0x00018b60, +0x00018b5d, +0x00018b5b, +0x00018b58, +0x00018b55, +0x00018b53, +0x00018b50, +0x00018b4f, +0x00018b4c, +0x00018b4a, +0x00018b47, +0x00018b45, +0x00018b42, +0x00018b41, +0x00018b3e, +0x00018b3c, +0x00018b39, +0x00018b36, +0x00018b34, +0x00018b31, +0x00018b30, +0x00018b2d, +0x00018b2b, +0x00018b28, +0x00018b27, +0x00018b23, +0x00018b22, +0x00018b1f, +0x00018b1c, +0x00018b1a, +0x00018b17, +0x00018b16, +0x00018b13, +0x00018b11, +0x00018b0e, +0x00018b0c, +0x00018b09, +0x00018b08, +0x00018b05, +0x00018b02, +0x00018b00, +0x00018afd, +0x00018afb, +0x00018af8, +0x00018af7, +0x00018af4, +0x00018af2, +0x00018aef, +0x00018aed, +0x00018aea, +0x00018ae9, +0x00018ae6, +0x00018ae3, +0x00018ae1, +0x00018ade, +0x00018add, +0x00018ad9, +0x00018ad8, +0x00018ad5, +0x00018ad3, +0x00018ad0, +0x00018acf, +0x00018acc, +0x00018ac8, +0x00018ac7, +0x00018ac4, +0x00018ac2, +0x00018abf, +0x00018abe, +0x00018abb, +0x00018ab9, +0x00018ab6, +0x00018ab4, +0x00018ab1, +0x00018aae, +0x00018aad, +0x00018aaa, +0x00018aa8, +0x00018aa5, +0x00018aa3, +0x00018aa0, +0x00018a9f, +0x00018a9c, +0x00018a9a, +0x00018a97, +0x00018a96, +0x00018a92, +0x00018a8f, +0x00018a8e, +0x00018a8b, +0x00018a89, +0x00018a86, +0x00018a85, +0x00018a81, +0x00018a80, +0x00018a7d, +0x00018a7b, +0x00018a78, +0x00018a75, +0x00018a74, +0x00018a71, +0x00018a6f, +0x00018a6c, +0x00018a6a, +0x00018a67, +0x00018a66, +0x00018a63, +0x00018a61, +0x00018a5e, +0x00018a5b, +0x00018a59, +0x00018a56, +0x00018a55, +0x00018a52, +0x00018a50, +0x00018a4d, +0x00018a4b, +0x00018a48, +0x00018a47, +0x00018a44, +0x00018a42, +0x00018a3f, +0x00018a3c, +0x00018a3b, +0x00018a37, +0x00018a36, +0x00018a34, +0x00018a31, +0x00018a2e, +0x00018a2d, +0x00018a2a, +0x00018a28, +0x00018a25, +0x00018a23, +0x00018a20, +0x00018a1f, +0x00018a1c, +0x00018a1a, +0x00018a17, +0x00018a14, +0x00018a12, +0x00018a0f, +0x00018a0e, +0x00018a0b, +0x00018a09, +0x00018a06, +0x00018a05, +0x00018a02, +0x00018a00, +0x000189fd, +0x000189fb, +0x000189f8, +0x000189f5, +0x000189f4, +0x000189f1, +0x000189ef, +0x000189ec, +0x000189ea, +0x000189e7, +0x000189e6, +0x000189e3, +0x000189e1, +0x000189de, +0x000189dd, +0x000189da, +0x000189d6, +0x000189d5, +0x000189d2, +0x000189d0, +0x000189cd, +0x000189cc, +0x000189c9, +0x000189c7, +0x000189c4, +0x000189c2, +0x000189bf, +0x000189be, +0x000189bb, +0x000189b8, +0x000189b6, +0x000189b3, +0x000189b2, +0x000189ae, +0x000189ad, +0x000189aa, +0x000189a8, +0x000189a5, +0x000189a4, +0x000189a1, +0x0001899f, +0x0001899c, +0x00018999, +0x00018997, +0x00018994, +0x00018993, +0x00018990, +0x0001898e, +0x0001898b, +0x00018989, +0x00018986, +0x00018985, +0x00018982, +0x00018980, +0x0001897d, +0x0001897a, +0x00018979, +0x00018975, +0x00018974, +0x00018971, +0x0001896f, +0x0001896c, +0x0001896b, +0x00018968, +0x00018966, +0x00018963, +0x00018961, +0x0001895e, +0x0001895b, +0x0001895a, +0x00018957, +0x00018955, +0x00018952, +0x00018951, +0x0001894d, +0x0001894c, +0x00018949, +0x00018947, +0x00018944, +0x00018943, +0x00018940, +0x0001893d, +0x0001893b, +0x00018938, +0x00018936, +0x00018933, +0x00018932, +0x0001892f, +0x0001892d, +0x0001892a, +0x00018929, +0x00018925, +0x00018924, +0x00018921, +0x0001891e, +0x0001891c, +0x00018919, +0x00018918, +0x00018915, +0x00018913, +0x00018910, +0x0001890e, +0x0001890b, +0x0001890a, +0x00018907, +0x00018904, +0x00018901, +0x00018900, +0x000188fd, +0x000188fb, +0x000188f8, +0x000188f7, +0x000188f3, +0x000188f2, +0x000188ef, +0x000188ed, +0x000188ea, +0x000188e9, +0x000188e6, +0x000188e4, +0x000188e1, +0x000188e0, +0x000188dd, +0x000188d9, +0x000188d8, +0x000188d5, +0x000188d3, +0x000188d0, +0x000188cf, +0x000188cc, +0x000188ca, +0x000188c7, +0x000188c6, +0x000188c2, +0x000188c1, +0x000188be, +0x000188bc, +0x000188b9, +0x000188b6, +0x000188b5, +0x000188b2, +0x000188b0, +0x000188ad, +0x000188ac, +0x000188a8, +0x000188a7, +0x000188a4, +0x000188a2, +0x0001889f, +0x0001889e, +0x0001889b, +0x00018899, +0x00018896, +0x00018895, +0x00018891, +0x0001888e, +0x0001888d, +0x0001888a, +0x00018888, +0x00018885, +0x00018884, +0x00018881, +0x0001887f, +0x0001887c, +0x0001887b, +0x00018877, +0x00018876, +0x00018873, +0x00018871, +0x0001886e, +0x0001886b, +0x0001886a, +0x00018867, +0x00018865, +0x00018862, +0x00018860, +0x0001885d, +0x0001885c, +0x00018859, +0x00018857, +0x00018854, +0x00018853, +0x00018850, +0x0001884e, +0x0001884b, +0x0001884a, +0x00018846, +0x00018843, +0x00018842, +0x0001883f, +0x0001883d, +0x0001883a, +0x00018839, +0x00018836, +0x00018834, +0x00018831, +0x0001882f, +0x0001882c, +0x0001882b, +0x00018828, +0x00018826, +0x00018823, +0x00018820, +0x0001881f, +0x0001881c, +0x0001881a, +0x00018817, +0x00018815, +0x00018812, +0x00018811, +0x0001880e, +0x0001880c, +0x00018809, +0x00018808, +0x00018805, +0x00018803, +0x00018800, +0x000187fe, +0x000187fb, +0x000187f8, +0x000187f7, +0x000187f4, +0x000187f2, +0x000187ef, +0x000187ee, +0x000187eb, +0x000187e9, +0x000187e6, +0x000187e4, +0x000187e1, +0x000187e0, +0x000187dd, +0x000187db, +0x000187d7, +0x000187d6, +0x000187d3, +0x000187d1, +0x000187ce, +0x000187cd, +0x000187ca, +0x000187c8, +0x000187c5, +0x000187c4, +0x000187c0, +0x000187bd, +0x000187bc, +0x000187b9, +0x000187b7, +0x000187b4, +0x000187b3, +0x000187b0, +0x000187ae, +0x000187ab, +0x000187aa, +0x000187a6, +0x000187a5, +0x000187a2, +0x000187a0, +0x0001879d, +0x0001879c, +0x00018799, +0x00018796, +0x00018794, +0x00018791, +0x00018790, +0x0001878d, +0x0001878b, +0x00018788, +0x00018786, +0x00018783, +0x00018782, +0x0001877f, +0x0001877d, +0x0001877a, +0x00018779, +0x00018776, +0x00018774, +0x00018771, +0x0001876f, +0x0001876c, +0x00018769, +0x00018768, +0x00018765, +0x00018763, +0x00018760, +0x0001875f, +0x0001875c, +0x0001875a, +0x00018757, +0x00018756, +0x00018752, +0x00018751, +0x0001874e, +0x0001874c, +0x00018749, +0x00018748, +0x00018745, +0x00018743, +0x00018740, +0x0001873d, +0x0001873c, +0x00018739, +0x00018737, +0x00018734, +0x00018732, +0x0001872f, +0x0001872e, +0x0001872b, +0x00018729, +0x00018726, +0x00018725, +0x00018722, +0x00018720, +0x0001871d, +0x0001871b, +0x00018718, +0x00018715, +0x00018714, +0x00018711, +0x0001870f, +0x0001870c, +0x0001870b, +0x00018708, +0x00018706, +0x00018703, +0x00018702, +0x000186fe, +0x000186fd, +0x000186fa, +0x000186f8, +0x000186f5, +0x000186f4, +0x000186f1, +0x000186ef, +0x000186ec, +0x000186e9, +0x000186e8, +0x000186e5, +0x000186e3, +0x000186e0, +0x000186de, +0x000186db, +0x000186da, +0x000186d7, +0x000186d5, +0x000186d2, +0x000186d1, +0x000186ce, +0x000186cc, +0x000186c9, +0x000186c7, +0x000186c4, +0x000186c1, +0x000186c0, +0x000186bd, +0x000186bb, +0x000186b8, +0x000186b7, +0x000186b4, +0x000186b2, +0x000186af, +0x000186ae, +0x000186ab, +0x000186a8, +0x000186a6, +0x000186a3, +0x000186a1, +0x0001869e, +0x0001869d, +0x0001869a, +0x00018698, +0x00018695, +0x00018694, +0x00018691, +0x0001868f, +0x0001868c, +0x0001868b, +0x00018688, +0x00018686, +0x00018683, +0x00018681, +0x0001867e, +0x0001867d, +0x0001867a, +0x00018677, +0x00018675, +0x00018672, +0x00018671, +0x0001866e, +0x0001866c, +0x00018669, +0x00018668, +0x00018665, +0x00018663, +0x00018660, +0x0001865e, +0x0001865b, +0x0001865a, +0x00018657, +0x00018655, +0x00018652, +0x00018651, +0x0001864e, +0x0001864c, +0x00018649, +0x00018646, +0x00018645, +0x00018642, +0x00018640, +0x0001863d, +0x0001863b, +0x00018638, +0x00018637, +0x00018634, +0x00018632, +0x0001862f, +0x0001862e, +0x0001862b, +0x00018629, +0x00018626, +0x00018625, +0x00018622, +0x00018620, +0x0001861d, +0x0001861b, +0x00018618, +0x00018615, +0x00018614, +0x00018611, +0x0001860f, +0x0001860c, +0x0001860b, +0x00018608, +0x00018606, +0x00018603, +0x00018602, +0x000185fe, +0x000185fd, +0x000185fa, +0x000185f8, +0x000185f5, +0x000185f4, +0x000185f1, +0x000185ef, +0x000185ec, +0x000185eb, +0x000185e8, +0x000185e5, +0x000185e3, +0x000185e0, +0x000185de, +0x000185db, +0x000185da, +0x000185d7, +0x000185d5, +0x000185d2, +0x000185d1, +0x000185ce, +0x000185cc, +0x000185c9, +0x000185c8, +0x000185c5, +0x000185c3, +0x000185c0, +0x000185be, +0x000185bb, +0x000185ba, +0x000185b7, +0x000185b4, +0x000185b2, +0x000185af, +0x000185ae, +0x000185ab, +0x000185a9, +0x000185a6, +0x000185a5, +0x000185a2, +0x000185a0, +0x0001859d, +0x0001859b, +0x00018598, +0x00018597, +0x00018594, +0x00018592, +0x0001858f, +0x0001858e, +0x0001858b, +0x00018589, +0x00018586, +0x00018584, +0x00018581, +0x00018580, +0x0001857d, +0x0001857b, +0x00018578, +0x00018577, +0x00018573, +0x00018572, +0x0001856f, +0x0001856d, +0x0001856a, +0x00018569, +0x00018566, +0x00018563, +0x00018561, +0x0001855e, +0x0001855d, +0x0001855a, +0x00018558, +0x00018555, +0x00018554, +0x00018551, +0x0001854f, +0x0001854c, +0x0001854a, +0x00018547, +0x00018546, +0x00018543, +0x00018541, +0x0001853e, +0x0001853d, +0x0001853a, +0x00018538, +0x00018535, +0x00018534, +0x00018531, +0x0001852f, +0x0001852c, +0x00018529, +0x00018528, +0x00018524, +0x00018523, +0x00018520, +0x0001851e, +0x0001851b, +0x0001851a, +0x00018517, +0x00018515, +0x00018512, +0x00018511, +0x0001850e, +0x0001850c, +0x00018509, +0x00018508, +0x00018505, +0x00018503, +0x00018500, +0x000184fe, +0x000184fb, +0x000184fa, +0x000184f7, +0x000184f5, +0x000184f2, +0x000184f1, +0x000184ee, +0x000184eb, +0x000184e9, +0x000184e6, +0x000184e5, +0x000184e2, +0x000184e0, +0x000184dd, +0x000184dc, +0x000184d8, +0x000184d7, +0x000184d4, +0x000184d2, +0x000184cf, +0x000184ce, +0x000184cb, +0x000184c9, +0x000184c6, +0x000184c5, +0x000184c2, +0x000184c0, +0x000184bd, +0x000184bc, +0x000184b9, +0x000184b7, +0x000184b4, +0x000184b1, +0x000184af, +0x000184ac, +0x000184ab, +0x000184a8, +0x000184a6, +0x000184a3, +0x000184a2, +0x0001849f, +0x0001849d, +0x0001849a, +0x00018499, +0x00018496, +0x00018494, +0x00018491, +0x00018490, +0x0001848d, +0x0001848b, +0x00018488, +0x00018486, +0x00018483, +0x00018482, +0x0001847f, +0x0001847d, +0x0001847a, +0x00018477, +0x00018476, +0x00018473, +0x00018471, +0x0001846e, +0x0001846d, +0x0001846a, +0x00018468, +0x00018465, +0x00018463, +0x00018460, +0x0001845f, +0x0001845c, +0x00018459, +0x00018458, +0x00018455, +0x00018453, +0x00018450, +0x0001844f, +0x0001844c, +0x0001844a, +0x00018447, +0x00018446, +0x00018443, +0x00018441, +0x0001843e, +0x0001843d, +0x0001843a, +0x00018438, +0x00018435, +0x00018434, +0x00018431, +0x0001842f, +0x0001842c, +0x0001842a, +0x00018427, +0x00018426, +0x00018423, +0x00018421, +0x0001841e, +0x0001841d, +0x0001841a, +0x00018418, +0x00018415, +0x00018414, +0x00018411, +0x0001840e, +0x0001840c, +0x00018409, +0x00018408, +0x00018405, +0x00018403, +0x00018400, +0x000183fe, +0x000183fb, +0x000183fa, +0x000183f7, +0x000183f5, +0x000183f2, +0x000183f1, +0x000183ee, +0x000183ec, +0x000183e9, +0x000183e8, +0x000183e5, +0x000183e3, +0x000183e0, +0x000183df, +0x000183dc, +0x000183da, +0x000183d7, +0x000183d6, +0x000183d3, +0x000183d1, +0x000183ce, +0x000183cc, +0x000183c9, +0x000183c6, +0x000183c5, +0x000183c2, +0x000183c0, +0x000183bd, +0x000183bc, +0x000183b9, +0x000183b7, +0x000183b4, +0x000183b3, +0x000183b0, +0x000183ae, +0x000183ab, +0x000183aa, +0x000183a7, +0x000183a5, +0x000183a2, +0x000183a1, +0x0001839d, +0x0001839c, +0x00018399, +0x00018397, +0x00018394, +0x00018393, +0x00018390, +0x0001838e, +0x0001838b, +0x0001838a, +0x00018387, +0x00018385, +0x00018382, +0x00018381, +0x0001837e, +0x0001837b, +0x00018379, +0x00018376, +0x00018375, +0x00018372, +0x00018370, +0x0001836d, +0x0001836b, +0x00018368, +0x00018367, +0x00018364, +0x00018362, +0x0001835f, +0x0001835e, +0x0001835b, +0x00018359, +0x00018356, +0x00018355, +0x00018352, +0x00018350, +0x0001834d, +0x0001834c, +0x00018349, +0x00018347, +0x00018344, +0x00018343, +0x00018340, +0x0001833e, +0x0001833b, +0x00018339, +0x00018336, +0x00018335, +0x00018332, +0x00018330, +0x0001832d, +0x0001832c, +0x00018329, +0x00018327, +0x00018324, +0x00018323, +0x00018320, +0x0001831e, +0x0001831b, +0x0001831a, +0x00018317, +0x00018315, +0x00018312, +0x00018311, +0x0001830e, +0x0001830c, +0x00018309, +0x00018308, +0x00018305, +0x00018302, +0x00018300, +0x000182fd, +0x000182fb, +0x000182f8, +0x000182f7, +0x000182f4, +0x000182f2, +0x000182ef, +0x000182ee, +0x000182eb, +0x000182e9, +0x000182e6, +0x000182e5, +0x000182e2, +0x000182e0, +0x000182dd, +0x000182dc, +0x000182d9, +0x000182d7, +0x000182d4, +0x000182d3, +0x000182d0, +0x000182ce, +0x000182cb, +0x000182ca, +0x000182c7, +0x000182c5, +0x000182c2, +0x000182c1, +0x000182bd, +0x000182bc, +0x000182b9, +0x000182b7, +0x000182b4, +0x000182b3, +0x000182b0, +0x000182ae, +0x000182ab, +0x000182aa, +0x000182a7, +0x000182a5, +0x000182a2, +0x0001829f, +0x0001829e, +0x0001829b, +0x00018299, +0x00018296, +0x00018295, +0x00018292, +0x00018290, +0x0001828d, +0x0001828c, +0x00018289, +0x00018287, +0x00018284, +0x00018283, +0x00018280, +0x0001827e, +0x0001827b, +0x00018279, +0x00018276, +0x00018275, +0x00018272, +0x00018270, +0x0001826d, +0x0001826c, +0x00018269, +0x00018267, +0x00018264, +0x00018263, +0x00018260, +0x0001825e, +0x0001825b, +0x0001825a, +0x00018257, +0x00018255, +0x00018252, +0x00018251, +0x0001824e, +0x0001824c, +0x00018249, +0x00018248, +0x00018245, +0x00018242, +0x00018240, +0x0001823d, +0x0001823b, +0x00018238, +0x00018237, +0x00018234, +0x00018232, +0x0001822f, +0x0001822e, +0x0001822b, +0x00018229, +0x00018226, +0x00018225, +0x00018222, +0x00018220, +0x0001821d, +0x0001821c, +0x00018219, +0x00018217, +0x00018214, +0x00018214, +0x00018211, +0x0001820e, +0x0001820c, +0x00018209, +0x00018208, +0x00018205, +0x00018203, +0x00018200, +0x000181fe, +0x000181fb, +0x000181fa, +0x000181f7, +0x000181f5, +0x000181f2, +0x000181f1, +0x000181ee, +0x000181ec, +0x000181e9, +0x000181e8, +0x000181e5, +0x000181e3, +0x000181e0, +0x000181df, +0x000181dc, +0x000181da, +0x000181d7, +0x000181d6, +0x000181d3, +0x000181d1, +0x000181ce, +0x000181cd, +0x000181ca, +0x000181c8, +0x000181c5, +0x000181c4, +0x000181c1, +0x000181bf, +0x000181bc, +0x000181bb, +0x000181b8, +0x000181b6, +0x000181b3, +0x000181b2, +0x000181af, +0x000181ad, +0x000181aa, +0x000181a9, +0x000181a6, +0x000181a4, +0x000181a1, +0x000181a0, +0x0001819c, +0x0001819b, +0x00018198, +0x00018196, +0x00018193, +0x00018192, +0x0001818f, +0x0001818d, +0x0001818a, +0x00018189, +0x00018186, +0x00018184, +0x00018181, +0x0001817e, +0x0001817d, +0x0001817a, +0x00018178, +0x00018175, +0x00018174, +0x00018171, +0x0001816f, +0x0001816c, +0x0001816b, +0x00018168, +0x00018166, +0x00018163, +0x00018162, +0x0001815f, +0x0001815d, +0x0001815a, +0x00018159, +0x00018156, +0x00018154, +0x00018151, +0x00018150, +0x0001814d, +0x0001814b, +0x00018148, +0x00018147, +0x00018144, +0x00018142, +0x0001813f, +0x0001813d, +0x0001813a, +0x00018139, +0x00018136, +0x00018134, +0x00018131, +0x00018130, +0x0001812d, +0x0001812b, +0x00018128, +0x00018127, +0x00018124, +0x00018122, +0x0001811f, +0x0001811e, +0x0001811b, +0x00018119, +0x00018116, +0x00018115, +0x00018112, +0x00018110, +0x0001810d, +0x0001810c, +0x00018109, +0x00018107, +0x00018104, +0x00018103, +0x00018100, +0x000180fe, +0x000180fb, +0x000180fa, +0x000180f7, +0x000180f5, +0x000180f2, +0x000180f0, +0x000180ef, +0x000180ec, +0x000180ea, +0x000180e7, +0x000180e6, +0x000180e3, +0x000180e1, +0x000180de, +0x000180dd, +0x000180da, +0x000180d8, +0x000180d5, +0x000180d4, +0x000180d1, +0x000180cf, +0x000180cc, +0x000180cb, +0x000180c8, +0x000180c6, +0x000180c3, +0x000180c2, +0x000180bf, +0x000180bd, +0x000180ba, +0x000180b9, +0x000180b6, +0x000180b4, +0x000180b1, +0x000180b0, +0x000180ad, +0x000180ab, +0x000180a8, +0x000180a7, +0x000180a4, +0x000180a2, +0x0001809f, +0x0001809e, +0x0001809b, +0x00018099, +0x00018096, +0x00018095, +0x00018092, +0x00018090, +0x0001808d, +0x0001808c, +0x00018089, +0x00018087, +0x00018084, +0x00018083, +0x00018080, +0x0001807e, +0x0001807b, +0x0001807a, +0x00018077, +0x00018075, +0x00018072, +0x00018071, +0x0001806e, +0x0001806c, +0x00018069, +0x00018068, +0x00018065, +0x00018063, +0x00018060, +0x0001805f, +0x0001805c, +0x0001805a, +0x00018057, +0x00018056, +0x00018053, +0x00018051, +0x0001804e, +0x0001804d, +0x0001804a, +0x00018048, +0x00018045, +0x00018044, +0x00018041, +0x0001803f, +0x0001803c, +0x0001803b, +0x00018038, +0x00018036, +0x00018033, +0x00018032, +0x0001802f, +0x0001802d, +0x0001802a, +0x00018029, +0x00018026, +0x00018024, +0x00018021, +0x00018020, +0x0001801d, +0x0001801b, +0x00018018, +0x00018017, +0x00018014, +0x00018012, +0x0001800f, +0x0001800e, +0x0001800b, +0x00018009, +0x00018006, +0x00018005, +0x00018002, +0x00018000, +0x00017ffd, +0x00017ffc, +0x00017ff9, +0x00017ff7, +0x00017ff4, +0x00017ff3, +0x00017ff0, +0x00017fee, +0x00017feb, +0x00017fea, +0x00017fe7, +0x00017fe5, +0x00017fe2, +0x00017fe1, +0x00017fde, +0x00017fdc, +0x00017fd9, +0x00017fd8, +0x00017fd5, +0x00017fd3, +0x00017fd0, +0x00017fcd, +0x00017fcb, +0x00017fc8, +0x00017fc7, +0x00017fc4, +0x00017fc2, +0x00017fc0, +0x00017fbe, +0x00017fbb, +0x00017fba, +0x00017fb7, +0x00017fb5, +0x00017fb2, +0x00017fb1, +0x00017fae, +0x00017fac, +0x00017fa9, +0x00017fa8, +0x00017fa5, +0x00017fa3, +0x00017fa0, +0x00017f9f, +0x00017f9c, +0x00017f9a, +0x00017f97, +0x00017f96, +0x00017f93, +0x00017f91, +0x00017f8e, +0x00017f8d, +0x00017f8a, +0x00017f88, +0x00017f85, +0x00017f84, +0x00017f81, +0x00017f7f, +0x00017f7c, +0x00017f7b, +0x00017f78, +0x00017f76, +0x00017f73, +0x00017f72, +0x00017f6f, +0x00017f6d, +0x00017f6a, +0x00017f69, +0x00017f66, +0x00017f64, +0x00017f61, +0x00017f60, +0x00017f5d, +0x00017f5b, +0x00017f58, +0x00017f57, +0x00017f54, +0x00017f52, +0x00017f4f, +0x00017f4e, +0x00017f4b, +0x00017f49, +0x00017f46, +0x00017f45, +0x00017f42, +0x00017f40, +0x00017f3f, +0x00017f3c, +0x00017f3a, +0x00017f37, +0x00017f36, +0x00017f33, +0x00017f31, +0x00017f2e, +0x00017f2d, +0x00017f2a, +0x00017f28, +0x00017f25, +0x00017f24, +0x00017f21, +0x00017f1f, +0x00017f1c, +0x00017f1b, +0x00017f18, +0x00017f16, +0x00017f13, +0x00017f12, +0x00017f0f, +0x00017f0d, +0x00017f0a, +0x00017f09, +0x00017f06, +0x00017f04, +0x00017f01, +0x00017f00, +0x00017efd, +0x00017efc, +0x00017ef9, +0x00017ef7, +0x00017ef4, +0x00017ef3, +0x00017ef0, +0x00017eee, +0x00017eeb, +0x00017eea, +0x00017ee7, +0x00017ee5, +0x00017ee2, +0x00017ee1, +0x00017ede, +0x00017edc, +0x00017ed9, +0x00017ed8, +0x00017ed5, +0x00017ed3, +0x00017ed0, +0x00017ecf, +0x00017ecc, +0x00017eca, +0x00017ec7, +0x00017ec6, +0x00017ec3, +0x00017ec1, +0x00017ebe, +0x00017ebd, +0x00017eba, +0x00017eb8, +0x00017eb5, +0x00017eb4, +0x00017eb2, +0x00017eaf, +0x00017ead, +0x00017eaa, +0x00017ea9, +0x00017ea6, +0x00017ea4, +0x00017ea1, +0x00017ea0, +0x00017e9d, +0x00017e9b, +0x00017e98, +0x00017e97, +0x00017e94, +0x00017e92, +0x00017e8f, +0x00017e8e, +0x00017e8b, +0x00017e89, +0x00017e86, +0x00017e85, +0x00017e82, +0x00017e80, +0x00017e7d, +0x00017e7c, +0x00017e79, +0x00017e77, +0x00017e74, +0x00017e73, +0x00017e70, +0x00017e6e, +0x00017e6b, +0x00017e6a, +0x00017e67, +0x00017e65, +0x00017e62, +0x00017e61, +0x00017e5e, +0x00017e5d, +0x00017e5a, +0x00017e58, +0x00017e55, +0x00017e54, +0x00017e51, +0x00017e4f, +0x00017e4c, +0x00017e4b, +0x00017e48, +0x00017e46, +0x00017e43, +0x00017e42, +0x00017e3f, +0x00017e3d, +0x00017e3a, +0x00017e39, +0x00017e36, +0x00017e34, +0x00017e31, +0x00017e30, +0x00017e2d, +0x00017e2b, +0x00017e28, +0x00017e27, +0x00017e24, +0x00017e22, +0x00017e21, +0x00017e1e, +0x00017e1c, +0x00017e19, +0x00017e18, +0x00017e15, +0x00017e13, +0x00017e10, +0x00017e0f, +0x00017e0c, +0x00017e0a, +0x00017e07, +0x00017e06, +0x00017e03, +0x00017e01, +0x00017dff, +0x00017dfd, +0x00017dfa, +0x00017df9, +0x00017df6, +0x00017df4, +0x00017df1, +0x00017df0, +0x00017ded, +0x00017deb, +0x00017de8, +0x00017de7, +0x00017de4, +0x00017de2, +0x00017ddf, +0x00017dde, +0x00017ddb, +0x00017dd9, +0x00017dd6, +0x00017dd5, +0x00017dd2, +0x00017dd0, +0x00017dcd, +0x00017dcc, +0x00017dc9, +0x00017dc7, +0x00017dc4, +0x00017dc3, +0x00017dc0, +0x00017dbe, +0x00017dbb, +0x00017dba, +0x00017db7, +0x00017db5, +0x00017db2, +0x00017db1, +0x00017dae, +0x00017dac, +0x00017da9, +0x00017da8, +0x00017da5, +0x00017da3, +0x00017da1, +0x00017d9f, +0x00017d9c, +0x00017d9b, +0x00017d98, +0x00017d96, +0x00017d93, +0x00017d92, +0x00017d8f, +0x00017d8d, +0x00017d8a, +0x00017d89, +0x00017d86, +0x00017d84, +0x00017d81, +0x00017d80, +0x00017d7d, +0x00017d7c, +0x00017d79, +0x00017d77, +0x00017d74, +0x00017d73, +0x00017d70, +0x00017d6e, +0x00017d6b, +0x00017d6a, +0x00017d67, +0x00017d65, +0x00017d64, +0x00017d61, +0x00017d5f, +0x00017d5c, +0x00017d5b, +0x00017d58, +0x00017d56, +0x00017d53, +0x00017d52, +0x00017d4f, +0x00017d4d, +0x00017d4a, +0x00017d49, +0x00017d46, +0x00017d44, +0x00017d41, +0x00017d40, +0x00017d3d, +0x00017d3c, +0x00017d39, +0x00017d37, +0x00017d34, +0x00017d33, +0x00017d30, +0x00017d2e, +0x00017d2b, +0x00017d2a, +0x00017d27, +0x00017d25, +0x00017d22, +0x00017d21, +0x00017d1e, +0x00017d1c, +0x00017d19, +0x00017d18, +0x00017d15, +0x00017d13, +0x00017d10, +0x00017d0f, +0x00017d0c, +0x00017d0a, +0x00017d07, +0x00017d06, +0x00017d04, +0x00017d01, +0x00017d00, +0x00017cfd, +0x00017cfc, +0x00017cf9, +0x00017cf7, +0x00017cf4, +0x00017cf3, +0x00017cf0, +0x00017cee, +0x00017ceb, +0x00017cea, +0x00017ce7, +0x00017ce5, +0x00017ce2, +0x00017ce1, +0x00017cde, +0x00017cdc, +0x00017cd9, +0x00017cd8, +0x00017cd5, +0x00017cd3, +0x00017cd0, +0x00017ccf, +0x00017ccc, +0x00017cca, +0x00017cc7, +0x00017cc6, +0x00017cc3, +0x00017cc1, +0x00017cbf, +0x00017cbd, +0x00017cba, +0x00017cb9, +0x00017cb6, +0x00017cb4, +0x00017cb1, +0x00017cb0, +0x00017cad, +0x00017cab, +0x00017ca8, +0x00017ca7, +0x00017ca5, +0x00017ca2, +0x00017ca1, +0x00017c9e, +0x00017c9c, +0x00017c99, +0x00017c98, +0x00017c95, +0x00017c93, +0x00017c90, +0x00017c8f, +0x00017c8c, +0x00017c8a, +0x00017c87, +0x00017c86, +0x00017c83, +0x00017c81, +0x00017c7f, +0x00017c7d, +0x00017c7a, +0x00017c78, +0x00017c77, +0x00017c74, +0x00017c72, +0x00017c6f, +0x00017c6e, +0x00017c6b, +0x00017c69, +0x00017c66, +0x00017c65, +0x00017c62, +0x00017c60, +0x00017c5e, +0x00017c5c, +0x00017c59, +0x00017c58, +0x00017c55, +0x00017c53, +0x00017c50, +0x00017c4f, +0x00017c4c, +0x00017c4a, +0x00017c47, +0x00017c46, +0x00017c43, +0x00017c41, +0x00017c3e, +0x00017c3d, +0x00017c3a, +0x00017c38, +0x00017c35, +0x00017c34, +0x00017c32, +0x00017c30, +0x00017c2e, +0x00017c2b, +0x00017c2a, +0x00017c27, +0x00017c25, +0x00017c22, +0x00017c21, +0x00017c1e, +0x00017c1c, +0x00017c19, +0x00017c18, +0x00017c15, +0x00017c13, +0x00017c10, +0x00017c0f, +0x00017c0c, +0x00017c0a, +0x00017c07, +0x00017c06, +0x00017c03, +0x00017c01, +0x00017bff, +0x00017bfd, +0x00017bfa, +0x00017bf9, +0x00017bf6, +0x00017bf4, +0x00017bf1, +0x00017bf0, +0x00017bed, +0x00017beb, +0x00017bea, +0x00017be7, +0x00017be5, +0x00017be2, +0x00017be1, +0x00017bde, +0x00017bdc, +0x00017bd9, +0x00017bd8, +0x00017bd5, +0x00017bd3, +0x00017bd1, +0x00017bcf, +0x00017bcc, +0x00017bcb, +0x00017bc8, +0x00017bc6, +0x00017bc3, +0x00017bc2, +0x00017bbf, +0x00017bbd, +0x00017bba, +0x00017bb9, +0x00017bb6, +0x00017bb4, +0x00017bb1, +0x00017bb0, +0x00017bad, +0x00017bab, +0x00017ba8, +0x00017ba7, +0x00017ba5, +0x00017ba2, +0x00017ba1, +0x00017b9e, +0x00017b9d, +0x00017b9a, +0x00017b98, +0x00017b95, +0x00017b94, +0x00017b91, +0x00017b8f, +0x00017b8c, +0x00017b8b, +0x00017b88, +0x00017b86, +0x00017b83, +0x00017b82, +0x00017b7f, +0x00017b7d, +0x00017b7a, +0x00017b79, +0x00017b76, +0x00017b74, +0x00017b72, +0x00017b70, +0x00017b6d, +0x00017b6c, +0x00017b69, +0x00017b67, +0x00017b64, +0x00017b63, +0x00017b60, +0x00017b5f, +0x00017b5c, +0x00017b5a, +0x00017b57, +0x00017b56, +0x00017b53, +0x00017b51, +0x00017b4e, +0x00017b4d, +0x00017b4a, +0x00017b49, +0x00017b46, +0x00017b44, +0x00017b43, +0x00017b40, +0x00017b3e, +0x00017b3b, +0x00017b3a, +0x00017b37, +0x00017b35, +0x00017b32, +0x00017b31, +0x00017b2e, +0x00017b2c, +0x00017b29, +0x00017b28, +0x00017b25, +0x00017b24, +0x00017b21, +0x00017b1f, +0x00017b1c, +0x00017b1b, +0x00017b18, +0x00017b16, +0x00017b13, +0x00017b12, +0x00017b0f, +0x00017b0d, +0x00017b0a, +0x00017b09, +0x00017b07, +0x00017b04, +0x00017b03, +0x00017b00, +0x00017aff, +0x00017afc, +0x00017afa, +0x00017af7, +0x00017af6, +0x00017af3, +0x00017af1, +0x00017aee, +0x00017aed, +0x00017aea, +0x00017ae8, +0x00017ae5, +0x00017ae4, +0x00017ae1, +0x00017adf, +0x00017adc, +0x00017adb, +0x00017ad8, +0x00017ad7, +0x00017ad4, +0x00017ad2, +0x00017ad1, +0x00017ace, +0x00017acc, +0x00017ac9, +0x00017ac8, +0x00017ac5, +0x00017ac3, +0x00017ac0, +0x00017abf, +0x00017abc, +0x00017aba, +0x00017ab7, +0x00017ab6, +0x00017ab3, +0x00017ab2, +0x00017aaf, +0x00017aad, +0x00017aaa, +0x00017aa9, +0x00017aa6, +0x00017aa4, +0x00017aa1, +0x00017aa0, +0x00017a9d, +0x00017a9b, +0x00017a9a, +0x00017a97, +0x00017a95, +0x00017a92, +0x00017a91, +0x00017a8e, +0x00017a8d, +0x00017a8a, +0x00017a88, +0x00017a85, +0x00017a84, +0x00017a81, +0x00017a7f, +0x00017a7c, +0x00017a7b, +0x00017a78, +0x00017a76, +0x00017a73, +0x00017a72, +0x00017a6f, +0x00017a6d, +0x00017a6a, +0x00017a69, +0x00017a66, +0x00017a65, +0x00017a62, +0x00017a60, +0x00017a5f, +0x00017a5c, +0x00017a5a, +0x00017a57, +0x00017a56, +0x00017a53, +0x00017a51, +0x00017a4e, +0x00017a4d, +0x00017a4a, +0x00017a48, +0x00017a47, +0x00017a44, +0x00017a42, +0x00017a3f, +0x00017a3e, +0x00017a3b, +0x00017a3a, +0x00017a37, +0x00017a35, +0x00017a32, +0x00017a31, +0x00017a2e, +0x00017a2c, +0x00017a29, +0x00017a28, +0x00017a25, +0x00017a23, +0x00017a20, +0x00017a1f, +0x00017a1c, +0x00017a1b, +0x00017a18, +0x00017a16, +0x00017a15, +0x00017a12, +0x00017a10, +0x00017a0d, +0x00017a0c, +0x00017a09, +0x00017a07, +0x00017a04, +0x00017a03, +0x00017a00, +0x000179ff, +0x000179fc, +0x000179fa, +0x000179f7, +0x000179f6, +0x000179f3, +0x000179f1, +0x000179ee, +0x000179ed, +0x000179ea, +0x000179e8, +0x000179e7, +0x000179e4, +0x000179e2, +0x000179e0, +0x000179de, +0x000179db, +0x000179da, +0x000179d7, +0x000179d5, +0x000179d2, +0x000179d1, +0x000179ce, +0x000179cc, +0x000179c9, +0x000179c8, +0x000179c5, +0x000179c3, +0x000179c1, +0x000179bf, +0x000179bc, +0x000179bb, +0x000179b9, +0x000179b6, +0x000179b5, +0x000179b2, +0x000179b0, +0x000179ad, +0x000179ac, +0x000179a9, +0x000179a7, +0x000179a4, +0x000179a3, +0x000179a0, +0x0001799f, +0x0001799c, +0x0001799a, +0x00017997, +0x00017996, +0x00017993, +0x00017991, +0x0001798e, +0x0001798d, +0x0001798b, +0x00017988, +0x00017987, +0x00017984, +0x00017982, +0x00017980, +0x0001797e, +0x0001797b, +0x0001797a, +0x00017977, +0x00017975, +0x00017972, +0x00017971, +0x0001796e, +0x0001796c, +0x00017969, +0x00017968, +0x00017965, +0x00017963, +0x00017961, +0x0001795f, +0x0001795e, +0x0001795b, +0x00017959, +0x00017956, +0x00017955, +0x00017952, +0x00017950, +0x0001794d, +0x0001794c, +0x00017949, +0x00017947, +0x00017944, +0x00017943, +0x00017940, +0x0001793f, +0x0001793c, +0x0001793a, +0x00017937, +0x00017936, +0x00017933, +0x00017931, +0x0001792f, +0x0001792e, +0x0001792b, +0x00017929, +0x00017926, +0x00017925, +0x00017922, +0x00017920, +0x0001791d, +0x0001791c, +0x0001791b, +0x00017918, +0x00017916, +0x00017913, +0x00017912, +0x0001790f, +0x0001790d, +0x0001790a, +0x00017909, +0x00017906, +0x00017904, +0x00017901, +0x00017900, +0x000178fd, +0x000178fc, +0x000178f9, +0x000178f7, +0x000178f4, +0x000178f3, +0x000178f1, +0x000178ee, +0x000178ed, +0x000178ea, +0x000178e8, +0x000178e5, +0x000178e4, +0x000178e1, +0x000178e0, +0x000178dd, +0x000178db, +0x000178d8, +0x000178d7, +0x000178d4, +0x000178d2, +0x000178cf, +0x000178ce, +0x000178cc, +0x000178ca, +0x000178c8, +0x000178c5, +0x000178c4, +0x000178c1, +0x000178bf, +0x000178bc, +0x000178bb, +0x000178b8, +0x000178b6, +0x000178b3, +0x000178b2, +0x000178af, +0x000178ae, +0x000178ab, +0x000178a9, +0x000178a6, +0x000178a5, +0x000178a3, +0x000178a0, +0x0001789f, +0x0001789c, +0x0001789a, +0x00017897, +0x00017896, +0x00017893, +0x00017892, +0x0001788f, +0x0001788d, +0x0001788a, +0x00017889, +0x00017886, +0x00017884, +0x00017881, +0x00017880, +0x0001787d, +0x0001787b, +0x0001787a, +0x00017877, +0x00017876, +0x00017873, +0x00017871, +0x0001786e, +0x0001786d, +0x0001786a, +0x00017868, +0x00017865, +0x00017864, +0x00017861, +0x0001785f, +0x0001785d, +0x0001785b, +0x00017858, +0x00017857, +0x00017855, +0x00017852, +0x00017851, +0x0001784e, +0x0001784c, +0x00017849, +0x00017848, +0x00017845, +0x00017844, +0x00017841, +0x0001783f, +0x0001783c, +0x0001783b, +0x00017838, +0x00017836, +0x00017833, +0x00017832, +0x0001782f, +0x0001782d, +0x0001782c, +0x00017829, +0x00017828, +0x00017825, +0x00017823, +0x00017820, +0x0001781f, +0x0001781c, +0x0001781a, +0x00017819, +0x00017816, +0x00017815, +0x00017812, +0x00017810, +0x0001780d, +0x0001780c, +0x00017809, +0x00017807, +0x00017804, +0x00017803, +0x00017800, +0x000177ff, +0x000177fc, +0x000177fa, +0x000177f9, +0x000177f6, +0x000177f4, +0x000177f1, +0x000177f0, +0x000177ed, +0x000177eb, +0x000177e9, +0x000177e7, +0x000177e4, +0x000177e3, +0x000177e0, +0x000177de, +0x000177db, +0x000177da, +0x000177d7, +0x000177d5, +0x000177d4, +0x000177d1, +0x000177d0, +0x000177cd, +0x000177cb, +0x000177c8, +0x000177c7, +0x000177c4, +0x000177c2, +0x000177bf, +0x000177be, +0x000177bb, +0x000177ba, +0x000177b7, +0x000177b5, +0x000177b4, +0x000177b1, +0x000177af, +0x000177ac, +0x000177ab, +0x000177a8, +0x000177a6, +0x000177a3, +0x000177a2, +0x0001779f, +0x0001779e, +0x0001779b, +0x00017799, +0x00017796, +0x00017795, +0x00017792, +0x00017790, +0x0001778f, +0x0001778c, +0x0001778b, +0x00017788, +0x00017786, +0x00017783, +0x00017782, +0x0001777f, +0x0001777d, +0x0001777a, +0x00017779, +0x00017776, +0x00017774, +0x00017772, +0x00017770, +0x0001776f, +0x0001776c, +0x0001776a, +0x00017767, +0x00017766, +0x00017763, +0x00017761, +0x0001775e, +0x0001775d, +0x0001775a, +0x00017759, +0x00017756, +0x00017754, +0x00017751, +0x00017750, +0x0001774d, +0x0001774b, +0x0001774a, +0x00017747, +0x00017745, +0x00017743, +0x00017741, +0x0001773e, +0x0001773d, +0x0001773a, +0x00017738, +0x00017735, +0x00017734, +0x00017731, +0x0001772f, +0x0001772d, +0x0001772b, +0x0001772a, +0x00017727, +0x00017725, +0x00017722, +0x00017721, +0x0001771e, +0x0001771c, +0x00017719, +0x00017718, +0x00017715, +0x00017714, +0x00017711, +0x0001770f, +0x0001770c, +0x0001770b, +0x00017708, +0x00017707, +0x00017704, +0x00017703, +0x00017700, +0x000176fe, +0x000176fb, +0x000176fa, +0x000176f7, +0x000176f5, +0x000176f3, +0x000176f1, +0x000176ee, +0x000176ed, +0x000176eb, +0x000176e8, +0x000176e7, +0x000176e4, +0x000176e2, +0x000176e0, +0x000176de, +0x000176db, +0x000176da, +0x000176d7, +0x000176d5, +0x000176d2, +0x000176d1, +0x000176cf, +0x000176cd, +0x000176cb, +0x000176c8, +0x000176c7, +0x000176c4, +0x000176c2, +0x000176bf, +0x000176be, +0x000176bb, +0x000176ba, +0x000176b7, +0x000176b5, +0x000176b4, +0x000176b1, +0x000176af, +0x000176ac, +0x000176ab, +0x000176a8, +0x000176a7, +0x000176a4, +0x000176a2, +0x0001769f, +0x0001769e, +0x0001769b, +0x00017699, +0x00017698, +0x00017695, +0x00017694, +0x00017691, +0x0001768f, +0x0001768c, +0x0001768b, +0x00017688, +0x00017686, +0x00017683, +0x00017682, +0x0001767f, +0x0001767e, +0x0001767c, +0x00017679, +0x00017678, +0x00017675, +0x00017673, +0x00017670, +0x0001766f, +0x0001766c, +0x0001766b, +0x00017668, +0x00017666, +0x00017663, +0x00017662, +0x00017660, +0x0001765e, +0x0001765c, +0x00017659, +0x00017658, +0x00017655, +0x00017653, +0x00017650, +0x0001764f, +0x0001764c, +0x0001764b, +0x00017648, +0x00017646, +0x00017645, +0x00017642, +0x00017640, +0x0001763d, +0x0001763c, +0x00017639, +0x00017638, +0x00017635, +0x00017633, +0x00017630, +0x0001762f, +0x0001762c, +0x0001762a, +0x00017629, +0x00017626, +0x00017625, +0x00017622, +0x00017620, +0x0001761d, +0x0001761c, +0x00017619, +0x00017617, +0x00017614, +0x00017613, +0x00017610, +0x0001760f, +0x0001760d, +0x0001760a, +0x00017609, +0x00017606, +0x00017604, +0x00017601, +0x00017600, +0x000175fd, +0x000175fc, +0x000175f9, +0x000175f7, +0x000175f5, +0x000175f2, +0x000175f0, +0x000175ed, +0x000175ec, +0x000175e9, +0x000175e8, +0x000175e6, +0x000175e3, +0x000175e2, +0x000175df, +0x000175dd, +0x000175db, +0x000175d9, +0x000175d6, +0x000175d5, +0x000175d2, +0x000175d0, +0x000175cf, +0x000175cc, +0x000175cb, +0x000175c8, +0x000175c6, +0x000175c3, +0x000175c2, +0x000175bf, +0x000175bd, +0x000175bb, +0x000175b9, +0x000175b6, +0x000175b5, +0x000175b3, +0x000175b0, +0x000175af, +0x000175ac, +0x000175aa, +0x000175a8, +0x000175a6, +0x000175a3, +0x000175a2, +0x0001759f, +0x0001759d, +0x0001759c, +0x00017599, +0x00017598, +0x00017595, +0x00017593, +0x00017590, +0x0001758f, +0x0001758c, +0x0001758a, +0x00017588, +0x00017586, +0x00017585, +0x00017582, +0x00017580, +0x0001757d, +0x0001757c, +0x00017579, +0x00017577, +0x00017575, +0x00017573, +0x00017570, +0x0001756f, +0x0001756d, +0x0001756a, +0x00017569, +0x00017566, +0x00017565, +0x00017562, +0x00017560, +0x0001755d, +0x0001755c, +0x00017559, +0x00017557, +0x00017555, +0x00017553, +0x00017552, +0x0001754f, +0x0001754d, +0x0001754a, +0x00017549, +0x00017546, +0x00017544, +0x00017542, +0x00017540, +0x0001753d, +0x0001753c, +0x0001753a, +0x00017537, +0x00017536, +0x00017533, +0x00017532, +0x0001752f, +0x0001752d, +0x0001752a, +0x00017529, +0x00017526, +0x00017524, +0x00017523, +0x00017520, +0x0001751f, +0x0001751c, +0x0001751a, +0x00017517, +0x00017516, +0x00017513, +0x00017511, +0x0001750f, +0x0001750d, +0x0001750a, +0x00017509, +0x00017507, +0x00017504, +0x00017503, +0x00017500, +0x000174ff, +0x000174fc, +0x000174fa, +0x000174f7, +0x000174f6, +0x000174f3, +0x000174f1, +0x000174f0, +0x000174ed, +0x000174ec, +0x000174e9, +0x000174e7, +0x000174e4, +0x000174e3, +0x000174e0, +0x000174de, +0x000174db, +0x000174da, +0x000174d7, +0x000174d6, +0x000174d3, +0x000174d1, +0x000174ce, +0x000174cd, +0x000174cb, +0x000174c9, +0x000174c7, +0x000174c4, +0x000174c3, +0x000174c0, +0x000174be, +0x000174bb, +0x000174ba, +0x000174b7, +0x000174b6, +0x000174b4, +0x000174b1, +0x000174b0, +0x000174ad, +0x000174ab, +0x000174a9, +0x000174a7, +0x000174a4, +0x000174a3, +0x000174a1, +0x0001749e, +0x0001749d, +0x0001749a, +0x00017499, +0x00017496, +0x00017494, +0x00017491, +0x00017490, +0x0001748d, +0x0001748c, +0x0001748a, +0x00017487, +0x00017486, +0x00017483, +0x00017481, +0x0001747e, +0x0001747d, +0x0001747a, +0x00017479, +0x00017476, +0x00017474, +0x00017473, +0x00017470, +0x0001746e, +0x0001746c, +0x0001746a, +0x00017467, +0x00017466, +0x00017463, +0x00017461, +0x0001745e, +0x0001745d, +0x0001745c, +0x00017459, +0x00017457, +0x00017454, +0x00017453, +0x00017450, +0x0001744e, +0x0001744c, +0x0001744a, +0x00017447, +0x00017446, +0x00017444, +0x00017441, +0x00017440, +0x0001743d, +0x0001743c, +0x00017439, +0x00017437, +0x00017434, +0x00017433, +0x00017430, +0x0001742f, +0x0001742d, +0x0001742a, +0x00017429, +0x00017426, +0x00017424, +0x00017421, +0x00017420, +0x0001741d, +0x0001741c, +0x0001741a, +0x00017417, +0x00017416, +0x00017413, +0x00017411, +0x0001740f, +0x0001740d, +0x0001740a, +0x00017409, +0x00017406, +0x00017404, +0x00017403, +0x00017400, +0x000173ff, +0x000173fc, +0x000173fa, +0x000173f7, +0x000173f6, +0x000173f3, +0x000173f1, +0x000173ef, +0x000173ed, +0x000173ec, +0x000173e9, +0x000173e7, +0x000173e4, +0x000173e3, +0x000173e0, +0x000173df, +0x000173dc, +0x000173da, +0x000173d7, +0x000173d5, +0x000173d4, +0x000173d1, +0x000173cf, +0x000173cc, +0x000173cb, +0x000173c9, +0x000173c7, +0x000173c5, +0x000173c2, +0x000173c1, +0x000173be, +0x000173bc, +0x000173ba, +0x000173b8, +0x000173b7, +0x000173b4, +0x000173b2, +0x000173af, +0x000173ae, +0x000173ab, +0x000173aa, +0x000173a7, +0x000173a5, +0x000173a2, +0x000173a1, +0x0001739f, +0x0001739d, +0x0001739b, +0x00017398, +0x00017397, +0x00017394, +0x00017392, +0x0001738f, +0x0001738e, +0x0001738d, +0x0001738a, +0x00017388, +0x00017385, +0x00017384, +0x00017381, +0x00017380, +0x0001737d, +0x0001737b, +0x00017378, +0x00017377, +0x00017375, +0x00017372, +0x00017371, +0x0001736e, +0x0001736d, +0x0001736a, +0x00017368, +0x00017365, +0x00017364, +0x00017363, +0x00017360, +0x0001735e, +0x0001735b, +0x0001735a, +0x00017357, +0x00017356, +0x00017353, +0x00017351, +0x00017350, +0x0001734d, +0x0001734b, +0x00017348, +0x00017347, +0x00017344, +0x00017343, +0x00017340, +0x0001733e, +0x0001733b, +0x0001733a, +0x00017339, +0x00017336, +0x00017334, +0x00017331, +0x00017330, +0x0001732d, +0x0001732b, +0x00017329, +0x00017327, +0x00017326, +0x00017323, +0x00017321, +0x0001731e, +0x0001731d, +0x0001731a, +0x00017319, +0x00017316, +0x00017314, +0x00017311, +0x00017310, +0x0001730e, +0x0001730c, +0x0001730a, +0x00017307, +0x00017306, +0x00017303, +0x00017301, +0x000172ff, +0x000172fd, +0x000172fc, +0x000172f9, +0x000172f7, +0x000172f4, +0x000172f3, +0x000172f0, +0x000172ef, +0x000172ec, +0x000172ea, +0x000172e7, +0x000172e6, +0x000172e4, +0x000172e2, +0x000172e0, +0x000172dd, +0x000172dc, +0x000172d9, +0x000172d7, +0x000172d5, +0x000172d3, +0x000172d2, +0x000172cf, +0x000172cd, +0x000172ca, +0x000172c9, +0x000172c6, +0x000172c5, +0x000172c2, +0x000172c0, +0x000172bd, +0x000172bc, +0x000172b9, +0x000172b8, +0x000172b5, +0x000172b3, +0x000172b2, +0x000172af, +0x000172ad, +0x000172ab, +0x000172a9, +0x000172a6, +0x000172a5, +0x000172a2, +0x000172a0, +0x0001729f, +0x0001729c, +0x0001729b, +0x00017298, +0x00017296, +0x00017293, +0x00017292, +0x0001728f, +0x0001728e, +0x0001728c, +0x00017289, +0x00017288, +0x00017285, +0x00017284, +0x00017281, +0x0001727f, +0x0001727c, +0x0001727b, +0x00017279, +0x00017277, +0x00017275, +0x00017272, +0x00017271, +0x0001726e, +0x0001726c, +0x0001726a, +0x00017268, +0x00017267, +0x00017264, +0x00017262, +0x0001725f, +0x0001725e, +0x0001725b, +0x0001725a, +0x00017257, +0x00017255, +0x00017254, +0x00017251, +0x0001724f, +0x0001724d, +0x0001724b, +0x00017248, +0x00017247, +0x00017244, +0x00017242, +0x00017241, +0x0001723e, +0x0001723d, +0x0001723a, +0x00017238, +0x00017235, +0x00017234, +0x00017231, +0x00017230, +0x0001722e, +0x0001722b, +0x0001722a, +0x00017227, +0x00017226, +0x00017223, +0x00017221, +0x0001721e, +0x0001721d, +0x0001721b, +0x00017219, +0x00017217, +0x00017214, +0x00017213, +0x00017210, +0x0001720e, +0x0001720c, +0x0001720a, +0x00017209, +0x00017206, +0x00017204, +0x00017201, +0x00017200, +0x000171fd, +0x000171fc, +0x000171f9, +0x000171f7, +0x000171f6, +0x000171f3, +0x000171f2, +0x000171ef, +0x000171ed, +0x000171ea, +0x000171e9, +0x000171e6, +0x000171e5, +0x000171e3, +0x000171e0, +0x000171df, +0x000171dc, +0x000171da, +0x000171d8, +0x000171d6, +0x000171d3, +0x000171d2, +0x000171d0, +0x000171cd, +0x000171cc, +0x000171c9, +0x000171c8, +0x000171c5, +0x000171c3, +0x000171c0, +0x000171bf, +0x000171bd, +0x000171ba, +0x000171b9, +0x000171b6, +0x000171b4, +0x000171b3, +0x000171b0, +0x000171ae, +0x000171ac, +0x000171aa, +0x000171a7, +0x000171a6, +0x000171a3, +0x000171a1, +0x000171a0, +0x0001719d, +0x0001719c, +0x00017199, +0x00017197, +0x00017194, +0x00017193, +0x00017190, +0x0001718f, +0x0001718d, +0x0001718a, +0x00017189, +0x00017186, +0x00017185, +0x00017182, +0x00017180, +0x0001717f, +0x0001717c, +0x0001717b, +0x00017178, +0x00017176, +0x00017173, +0x00017172, +0x0001716f, +0x0001716e, +0x0001716c, +0x00017169, +0x00017168, +0x00017165, +0x00017163, +0x00017161, +0x0001715f, +0x0001715c, +0x0001715b, +0x00017159, +0x00017156, +0x00017155, +0x00017152, +0x00017151, +0x0001714e, +0x0001714c, +0x0001714a, +0x00017148, +0x00017147, +0x00017144, +0x00017142, +0x0001713f, +0x0001713e, +0x0001713b, +0x0001713a, +0x00017138, +0x00017135, +0x00017134, +0x00017131, +0x00017130, +0x0001712d, +0x0001712b, +0x00017128, +0x00017127, +0x00017125, +0x00017123, +0x00017121, +0x0001711e, +0x0001711d, +0x0001711a, +0x00017119, +0x00017116, +0x00017114, +0x00017113, +0x00017110, +0x0001710e, +0x0001710c, +0x0001710a, +0x00017107, +0x00017106, +0x00017103, +0x00017101, +0x00017100, +0x000170fd, +0x000170fc, +0x000170f9, +0x000170f7, +0x000170f4, +0x000170f3, +0x000170f0, +0x000170ef, +0x000170ed, +0x000170ea, +0x000170e9, +0x000170e6, +0x000170e5, +0x000170e2, +0x000170e0, +0x000170df, +0x000170dc, +0x000170db, +0x000170d8, +0x000170d6, +0x000170d3, +0x000170d2, +0x000170cf, +0x000170ce, +0x000170cc, +0x000170c9, +0x000170c8, +0x000170c5, +0x000170c3, +0x000170c1, +0x000170bf, +0x000170bc, +0x000170bb, +0x000170b9, +0x000170b6, +0x000170b5, +0x000170b2, +0x000170b1, +0x000170ae, +0x000170ad, +0x000170aa, +0x000170a8, +0x000170a5, +0x000170a4, +0x000170a2, +0x000170a0, +0x0001709e, +0x0001709b, +0x0001709a, +0x00017097, +0x00017096, +0x00017093, +0x00017091, +0x00017090, +0x0001708d, +0x0001708b, +0x00017089, +0x00017087, +0x00017084, +0x00017083, +0x00017081, +0x0001707f, +0x0001707d, +0x0001707a, +0x00017079, +0x00017076, +0x00017074, +0x00017072, +0x00017070, +0x0001706f, +0x0001706c, +0x0001706a, +0x00017068, +0x00017066, +0x00017063, +0x00017062, +0x00017060, +0x0001705d, +0x0001705c, +0x00017059, +0x00017058, +0x00017055, +0x00017053, +0x00017051, +0x0001704f, +0x0001704e, +0x0001704b, +0x00017049, +0x00017046, +0x00017045, +0x00017042, +0x00017041, +0x0001703f, +0x0001703c, +0x0001703b, +0x00017038, +0x00017037, +0x00017034, +0x00017032, +0x0001702f, +0x0001702e, +0x0001702d, +0x0001702a, +0x00017028, +0x00017025, +0x00017024, +0x00017021, +0x00017020, +0x0001701e, +0x0001701b, +0x0001701a, +0x00017017, +0x00017016, +0x00017013, +0x00017011, +0x0001700e, +0x0001700d, +0x0001700c, +0x00017009, +0x00017007, +0x00017004, +0x00017003, +0x00017000, +0x00016fff, +0x00016ffd, +0x00016ffa, +0x00016ff9, +0x00016ff6, +0x00016ff5, +0x00016ff2, +0x00016ff0, +0x00016fed, +0x00016fec, +0x00016fea, +0x00016fe8, +0x00016fe6, +0x00016fe3, +0x00016fe2, +0x00016fdf, +0x00016fde, +0x00016fdc, +0x00016fd9, +0x00016fd8, +0x00016fd5, +0x00016fd3, +0x00016fd1, +0x00016fcf, +0x00016fcc, +0x00016fcb, +0x00016fc9, +0x00016fc7, +0x00016fc5, +0x00016fc2, +0x00016fc1, +0x00016fbe, +0x00016fbc, +0x00016fbb, +0x00016fb8, +0x00016fb7, +0x00016fb4, +0x00016fb2, +0x00016fb0, +0x00016fae, +0x00016fab, +0x00016fa9, +0x00016fa8, +0x00016fa5, +0x00016fa3, +0x00016fa2, +0x00016f9f, +0x00016f9e, +0x00016f9b, +0x00016f99, +0x00016f97, +0x00016f95, +0x00016f92, +0x00016f91, +0x00016f8f, +0x00016f8c, +0x00016f8b, +0x00016f88, +0x00016f87, +0x00016f84, +0x00016f82, +0x00016f81, +0x00016f7e, +0x00016f7d, +0x00016f7a, +0x00016f78, +0x00016f76, +0x00016f74, +0x00016f73, +0x00016f70, +0x00016f6e, +0x00016f6c, +0x00016f6a, +0x00016f67, +0x00016f66, +0x00016f64, +0x00016f61, +0x00016f60, +0x00016f5d, +0x00016f5c, +0x00016f59, +0x00016f57, +0x00016f55, +0x00016f53, +0x00016f52, +0x00016f4f, +0x00016f4d, +0x00016f4b, +0x00016f49, +0x00016f46, +0x00016f45, +0x00016f43, +0x00016f41, +0x00016f3f, +0x00016f3c, +0x00016f3b, +0x00016f38, +0x00016f36, +0x00016f35, +0x00016f32, +0x00016f31, +0x00016f2e, +0x00016f2c, +0x00016f2a, +0x00016f28, +0x00016f27, +0x00016f24, +0x00016f22, +0x00016f20, +0x00016f1e, +0x00016f1b, +0x00016f1a, +0x00016f17, +0x00016f16, +0x00016f14, +0x00016f11, +0x00016f10, +0x00016f0d, +0x00016f0b, +0x00016f09, +0x00016f07, +0x00016f06, +0x00016f03, +0x00016f01, +0x00016eff, +0x00016efd, +0x00016efa, +0x00016ef9, +0x00016ef7, +0x00016ef5, +0x00016ef3, +0x00016ef0, +0x00016eef, +0x00016eec, +0x00016eea, +0x00016ee8, +0x00016ee6, +0x00016ee5, +0x00016ee2, +0x00016ee0, +0x00016ede, +0x00016edc, +0x00016ed9, +0x00016ed8, +0x00016ed6, +0x00016ed4, +0x00016ed2, +0x00016ecf, +0x00016ece, +0x00016ecb, +0x00016eca, +0x00016ec8, +0x00016ec5, +0x00016ec4, +0x00016ec1, +0x00016ebf, +0x00016ebd, +0x00016ebb, +0x00016eba, +0x00016eb7, +0x00016eb5, +0x00016eb3, +0x00016eb1, +0x00016eae, +0x00016ead, +0x00016eaa, +0x00016ea9, +0x00016ea7, +0x00016ea4, +0x00016ea3, +0x00016ea0, +0x00016e9f, +0x00016e9c, +0x00016e9a, +0x00016e98, +0x00016e96, +0x00016e93, +0x00016e92, +0x00016e90, +0x00016e8e, +0x00016e8c, +0x00016e89, +0x00016e88, +0x00016e85, +0x00016e84, +0x00016e82, +0x00016e7f, +0x00016e7e, +0x00016e7b, +0x00016e7a, +0x00016e77, +0x00016e75, +0x00016e74, +0x00016e71, +0x00016e70, +0x00016e6d, +0x00016e6b, +0x00016e68, +0x00016e67, +0x00016e66, +0x00016e63, +0x00016e61, +0x00016e5e, +0x00016e5d, +0x00016e5a, +0x00016e59, +0x00016e57, +0x00016e54, +0x00016e53, +0x00016e50, +0x00016e4f, +0x00016e4c, +0x00016e4a, +0x00016e49, +0x00016e46, +0x00016e45, +0x00016e42, +0x00016e40, +0x00016e3d, +0x00016e3c, +0x00016e3b, +0x00016e38, +0x00016e36, +0x00016e33, +0x00016e32, +0x00016e2f, +0x00016e2e, +0x00016e2c, +0x00016e29, +0x00016e28, +0x00016e25, +0x00016e24, +0x00016e21, +0x00016e1f, +0x00016e1e, +0x00016e1b, +0x00016e1a, +0x00016e17, +0x00016e15, +0x00016e13, +0x00016e11, +0x00016e10, +0x00016e0d, +0x00016e0b, +0x00016e09, +0x00016e07, +0x00016e04, +0x00016e03, +0x00016e01, +0x00016dff, +0x00016dfd, +0x00016dfa, +0x00016df9, +0x00016df6, +0x00016df5, +0x00016df3, +0x00016df0, +0x00016def, +0x00016dec, +0x00016deb, +0x00016de8, +0x00016de6, +0x00016de5, +0x00016de2, +0x00016de1, +0x00016dde, +0x00016ddc, +0x00016dd9, +0x00016dd8, +0x00016dd7, +0x00016dd4, +0x00016dd2, +0x00016dcf, +0x00016dce, +0x00016dcb, +0x00016dca, +0x00016dc8, +0x00016dc5, +0x00016dc4, +0x00016dc1, +0x00016dc0, +0x00016dbd, +0x00016dbb, +0x00016dba, +0x00016db7, +0x00016db6, +0x00016db3, +0x00016db1, +0x00016daf, +0x00016dad, +0x00016dac, +0x00016da9, +0x00016da7, +0x00016da5, +0x00016da3, +0x00016da0, +0x00016d9f, +0x00016d9d, +0x00016d9a, +0x00016d99, +0x00016d96, +0x00016d94, +0x00016d93, +0x00016d90, +0x00016d8f, +0x00016d8c, +0x00016d8a, +0x00016d87, +0x00016d86, +0x00016d85, +0x00016d82, +0x00016d80, +0x00016d7d, +0x00016d7c, +0x00016d7b, +0x00016d78, +0x00016d76, +0x00016d73, +0x00016d72, +0x00016d6f, +0x00016d6e, +0x00016d6c, +0x00016d6a, +0x00016d68, +0x00016d65, +0x00016d64, +0x00016d61, +0x00016d60, +0x00016d5e, +0x00016d5b, +0x00016d5a, +0x00016d57, +0x00016d56, +0x00016d53, +0x00016d51, +0x00016d50, +0x00016d4d, +0x00016d4c, +0x00016d49, +0x00016d47, +0x00016d44, +0x00016d43, +0x00016d42, +0x00016d3f, +0x00016d3d, +0x00016d3a, +0x00016d39, +0x00016d36, +0x00016d35, +0x00016d33, +0x00016d30, +0x00016d2f, +0x00016d2c, +0x00016d2b, +0x00016d28, +0x00016d26, +0x00016d25, +0x00016d22, +0x00016d21, +0x00016d1e, +0x00016d1d, +0x00016d1b, +0x00016d18, +0x00016d17, +0x00016d14, +0x00016d13, +0x00016d10, +0x00016d0e, +0x00016d0d, +0x00016d0a, +0x00016d09, +0x00016d06, +0x00016d04, +0x00016d01, +0x00016d00, +0x00016cff, +0x00016cfc, +0x00016cfa, +0x00016cf7, +0x00016cf6, +0x00016cf3, +0x00016cf2, +0x00016cf0, +0x00016ced, +0x00016cec, +0x00016ce9, +0x00016ce8, +0x00016ce5, +0x00016ce3, +0x00016ce2, +0x00016cdf, +0x00016cde, +0x00016cdb, +0x00016cda, +0x00016cd7, +0x00016cd5, +0x00016cd4, +0x00016cd1, +0x00016cd0, +0x00016ccd, +0x00016ccb, +0x00016cc8, +0x00016cc7, +0x00016cc6, +0x00016cc3, +0x00016cc1, +0x00016cbe, +0x00016cbd, +0x00016cba, +0x00016cb9, +0x00016cb7, +0x00016cb4, +0x00016cb3, +0x00016cb0, +0x00016caf, +0x00016cad, +0x00016caa, +0x00016ca9, +0x00016ca6, +0x00016ca5, +0x00016ca2, +0x00016ca0, +0x00016c9f, +0x00016c9c, +0x00016c9b, +0x00016c98, +0x00016c97, +0x00016c94, +0x00016c92, +0x00016c90, +0x00016c8e, +0x00016c8b, +0x00016c8a, +0x00016c89, +0x00016c86, +0x00016c84, +0x00016c81, +0x00016c80, +0x00016c7f, +0x00016c7c, +0x00016c7a, +0x00016c77, +0x00016c76, +0x00016c73, +0x00016c72, +0x00016c70, +0x00016c6d, +0x00016c6c, +0x00016c69, +0x00016c68, +0x00016c65, +0x00016c64, +0x00016c62, +0x00016c5f, +0x00016c5e, +0x00016c5b, +0x00016c5a, +0x00016c58, +0x00016c55, +0x00016c54, +0x00016c51, +0x00016c50, +0x00016c4d, +0x00016c4b, +0x00016c4a, +0x00016c47, +0x00016c46, +0x00016c43, +0x00016c41, +0x00016c3f, +0x00016c3d, +0x00016c3c, +0x00016c39, +0x00016c37, +0x00016c35, +0x00016c33, +0x00016c30, +0x00016c2f, +0x00016c2e, +0x00016c2b, +0x00016c29, +0x00016c26, +0x00016c25, +0x00016c24, +0x00016c21, +0x00016c1f, +0x00016c1c, +0x00016c1b, +0x00016c18, +0x00016c17, +0x00016c15, +0x00016c12, +0x00016c11, +0x00016c0e, +0x00016c0d, +0x00016c0a, +0x00016c09, +0x00016c07, +0x00016c04, +0x00016c03, +0x00016c00, +0x00016bff, +0x00016bfd, +0x00016bfa, +0x00016bf9, +0x00016bf6, +0x00016bf5, +0x00016bf2, +0x00016bf0, +0x00016bef, +0x00016bec, +0x00016beb, +0x00016be8, +0x00016be6, +0x00016be4, +0x00016be2, +0x00016be1, +0x00016bde, +0x00016bdc, +0x00016bda, +0x00016bd8, +0x00016bd7, +0x00016bd4, +0x00016bd3, +0x00016bd0, +0x00016bce, +0x00016bcb, +0x00016bca, +0x00016bc9, +0x00016bc6, +0x00016bc4, +0x00016bc1, +0x00016bc0, +0x00016bbd, +0x00016bbc, +0x00016bba, +0x00016bb7, +0x00016bb6, +0x00016bb3, +0x00016bb2, +0x00016baf, +0x00016bae, +0x00016bac, +0x00016ba9, +0x00016ba8, +0x00016ba5, +0x00016ba4, +0x00016ba2, +0x00016b9f, +0x00016b9e, +0x00016b9b, +0x00016b9a, +0x00016b97, +0x00016b95, +0x00016b93, +0x00016b91, +0x00016b8f, +0x00016b8e, +0x00016b8b, +0x00016b8a, +0x00016b87, +0x00016b85, +0x00016b82, +0x00016b81, +0x00016b80, +0x00016b7d, +0x00016b7b, +0x00016b79, +0x00016b77, +0x00016b76, +0x00016b73, +0x00016b71, +0x00016b6f, +0x00016b6d, +0x00016b6a, +0x00016b69, +0x00016b68, +0x00016b65, +0x00016b63, +0x00016b60, +0x00016b5f, +0x00016b5e, +0x00016b5b, +0x00016b59, +0x00016b56, +0x00016b55, +0x00016b52, +0x00016b51, +0x00016b4f, +0x00016b4d, +0x00016b4b, +0x00016b48, +0x00016b47, +0x00016b45, +0x00016b43, +0x00016b41, +0x00016b3e, +0x00016b3d, +0x00016b3a, +0x00016b39, +0x00016b37, +0x00016b34, +0x00016b33, +0x00016b30, +0x00016b2f, +0x00016b2d, +0x00016b2b, +0x00016b29, +0x00016b26, +0x00016b25, +0x00016b22, +0x00016b21, +0x00016b1f, +0x00016b1c, +0x00016b1b, +0x00016b18, +0x00016b17, +0x00016b15, +0x00016b12, +0x00016b11, +0x00016b0e, +0x00016b0d, +0x00016b0a, +0x00016b09, +0x00016b07, +0x00016b04, +0x00016b03, +0x00016b00, +0x00016aff, +0x00016afc, +0x00016afa, +0x00016af9, +0x00016af6, +0x00016af5, +0x00016af2, +0x00016af0, +0x00016aef, +0x00016aec, +0x00016aeb, +0x00016ae8, +0x00016ae6, +0x00016ae4, +0x00016ae2, +0x00016ae1, +0x00016ade, +0x00016add, +0x00016ada, +0x00016ad8, +0x00016ad7, +0x00016ad4, +0x00016ad3, +0x00016ad0, +0x00016ace, +0x00016acc, +0x00016aca, +0x00016ac9, +0x00016ac6, +0x00016ac4, +0x00016ac2, +0x00016ac0, +0x00016abf, +0x00016abc, +0x00016abb, +0x00016ab8, +0x00016ab6, +0x00016ab3, +0x00016ab2, +0x00016ab1, +0x00016aae, +0x00016aac, +0x00016aaa, +0x00016aa8, +0x00016aa7, +0x00016aa4, +0x00016aa2, +0x00016aa0, +0x00016a9e, +0x00016a9b, +0x00016a9a, +0x00016a98, +0x00016a96, +0x00016a94, +0x00016a92, +0x00016a90, +0x00016a8d, +0x00016a8c, +0x00016a89, +0x00016a88, +0x00016a86, +0x00016a84, +0x00016a82, +0x00016a7f, +0x00016a7e, +0x00016a7c, +0x00016a7a, +0x00016a78, +0x00016a75, +0x00016a74, +0x00016a71, +0x00016a70, +0x00016a6e, +0x00016a6b, +0x00016a6a, +0x00016a67, +0x00016a66, +0x00016a64, +0x00016a62, +0x00016a60, +0x00016a5d, +0x00016a5c, +0x00016a59, +0x00016a58, +0x00016a56, +0x00016a53, +0x00016a52, +0x00016a4f, +0x00016a4e, +0x00016a4c, +0x00016a4a, +0x00016a48, +0x00016a45, +0x00016a44, +0x00016a42, +0x00016a40, +0x00016a3e, +0x00016a3b, +0x00016a3a, +0x00016a37, +0x00016a36, +0x00016a34, +0x00016a31, +0x00016a30, +0x00016a2d, +0x00016a2c, +0x00016a2a, +0x00016a28, +0x00016a26, +0x00016a23, +0x00016a22, +0x00016a1f, +0x00016a1e, +0x00016a1c, +0x00016a19, +0x00016a18, +0x00016a15, +0x00016a14, +0x00016a12, +0x00016a10, +0x00016a0e, +0x00016a0b, +0x00016a0a, +0x00016a08, +0x00016a06, +0x00016a04, +0x00016a01, +0x00016a00, +0x000169fd, +0x000169fc, +0x000169fa, +0x000169f8, +0x000169f6, +0x000169f3, +0x000169f2, +0x000169f0, +0x000169ee, +0x000169ec, +0x000169e9, +0x000169e8, +0x000169e5, +0x000169e4, +0x000169e2, +0x000169df, +0x000169de, +0x000169db, +0x000169da, +0x000169d8, +0x000169d6, +0x000169d4, +0x000169d1, +0x000169d0, +0x000169cf, +0x000169cc, +0x000169ca, +0x000169c7, +0x000169c6, +0x000169c3, +0x000169c2, +0x000169c0, +0x000169be, +0x000169bc, +0x000169b9, +0x000169b8, +0x000169b6, +0x000169b4, +0x000169b2, +0x000169af, +0x000169ae, +0x000169ab, +0x000169aa, +0x000169a8, +0x000169a6, +0x000169a4, +0x000169a1, +0x000169a0, +0x0001699e, +0x0001699c, +0x0001699a, +0x00016997, +0x00016996, +0x00016994, +0x00016991, +0x00016990, +0x0001698e, +0x0001698c, +0x0001698a, +0x00016987, +0x00016986, +0x00016983, +0x00016982, +0x00016980, +0x0001697e, +0x0001697c, +0x00016979, +0x00016978, +0x00016976, +0x00016974, +0x00016972, +0x0001696f, +0x0001696e, +0x0001696d, +0x0001696a, +0x00016968, +0x00016966, +0x00016964, +0x00016961, +0x00016960, +0x0001695e, +0x0001695c, +0x0001695a, +0x00016957, +0x00016956, +0x00016955, +0x00016952, +0x00016950, +0x0001694e, +0x0001694c, +0x0001694b, +0x00016948, +0x00016947, +0x00016944, +0x00016942, +0x00016941, +0x0001693e, +0x0001693d, +0x0001693a, +0x00016938, +0x00016936, +0x00016934, +0x00016933, +0x00016930, +0x0001692f, +0x0001692c, +0x0001692a, +0x00016929, +0x00016926, +0x00016925, +0x00016922, +0x00016920, +0x0001691f, +0x0001691c, +0x0001691b, +0x00016918, +0x00016917, +0x00016915, +0x00016912, +0x00016911, +0x0001690e, +0x0001690d, +0x0001690a, +0x00016908, +0x00016907, +0x00016904, +0x00016903, +0x00016900, +0x000168ff, +0x000168fd, +0x000168fa, +0x000168f9, +0x000168f6, +0x000168f5, +0x000168f3, +0x000168f0, +0x000168ef, +0x000168ec, +0x000168eb, +0x000168e8, +0x000168e7, +0x000168e5, +0x000168e2, +0x000168e1, +0x000168de, +0x000168dd, +0x000168db, +0x000168d9, +0x000168d7, +0x000168d4, +0x000168d3, +0x000168d1, +0x000168cf, +0x000168cd, +0x000168ca, +0x000168c9, +0x000168c8, +0x000168c5, +0x000168c3, +0x000168c1, +0x000168bf, +0x000168bc, +0x000168bb, +0x000168b9, +0x000168b7, +0x000168b5, +0x000168b2, +0x000168b1, +0x000168b0, +0x000168ad, +0x000168ab, +0x000168a9, +0x000168a7, +0x000168a6, +0x000168a3, +0x000168a2, +0x0001689f, +0x0001689d, +0x0001689a, +0x00016899, +0x00016898, +0x00016895, +0x00016894, +0x00016891, +0x0001688f, +0x0001688d, +0x0001688b, +0x0001688a, +0x00016887, +0x00016886, +0x00016883, +0x00016881, +0x00016880, +0x0001687d, +0x0001687c, +0x00016879, +0x00016878, +0x00016876, +0x00016873, +0x00016872, +0x0001686f, +0x0001686e, +0x0001686b, +0x00016869, +0x00016868, +0x00016865, +0x00016864, +0x00016861, +0x00016860, +0x0001685e, +0x0001685b, +0x0001685a, +0x00016857, +0x00016856, +0x00016854, +0x00016852, +0x00016850, +0x0001684d, +0x0001684c, +0x0001684b, +0x00016848, +0x00016846, +0x00016844, +0x00016842, +0x00016841, +0x0001683e, +0x0001683c, +0x0001683a, +0x00016838, +0x00016837, +0x00016834, +0x00016833, +0x00016830, +0x0001682e, +0x0001682c, +0x0001682a, +0x00016829, +0x00016826, +0x00016825, +0x00016822, +0x00016820, +0x0001681f, +0x0001681c, +0x0001681b, +0x00016818, +0x00016817, +0x00016815, +0x00016812, +0x00016811, +0x0001680e, +0x0001680d, +0x0001680b, +0x00016808, +0x00016807, +0x00016804, +0x00016803, +0x00016801, +0x000167ff, +0x000167fd, +0x000167fa, +0x000167f9, +0x000167f8, +0x000167f5, +0x000167f3, +0x000167f1, +0x000167ef, +0x000167ec, +0x000167eb, +0x000167ea, +0x000167e7, +0x000167e5, +0x000167e2, +0x000167e1, +0x000167e0, +0x000167dd, +0x000167db, +0x000167d9, +0x000167d7, +0x000167d6, +0x000167d3, +0x000167d2, +0x000167cf, +0x000167cd, +0x000167cc, +0x000167c9, +0x000167c8, +0x000167c5, +0x000167c4, +0x000167c2, +0x000167bf, +0x000167be, +0x000167bb, +0x000167ba, +0x000167b8, +0x000167b5, +0x000167b4, +0x000167b1, +0x000167b0, +0x000167ad, +0x000167ac, +0x000167aa, +0x000167a7, +0x000167a6, +0x000167a3, +0x000167a2, +0x000167a0, +0x0001679e, +0x0001679c, +0x00016799, +0x00016797, +0x00016796, +0x00016793, +0x00016792, +0x00016790, +0x0001678e, +0x0001678c, +0x00016789, +0x00016788, +0x00016787, +0x00016784, +0x00016782, +0x00016780, +0x0001677e, +0x0001677d, +0x0001677a, +0x00016779, +0x00016776, +0x00016774, +0x00016773, +0x00016770, +0x0001676f, +0x0001676c, +0x0001676b, +0x00016769, +0x00016766, +0x00016765, +0x00016762, +0x00016761, +0x0001675f, +0x0001675d, +0x0001675b, +0x00016758, +0x00016757, +0x00016756, +0x00016753, +0x00016751, +0x0001674f, +0x0001674d, +0x0001674c, +0x00016749, +0x00016748, +0x00016745, +0x00016743, +0x00016742, +0x0001673f, +0x0001673e, +0x0001673b, +0x00016739, +0x00016738, +0x00016735, +0x00016734, +0x00016731, +0x00016730, +0x0001672e, +0x0001672b, +0x0001672a, +0x00016727, +0x00016726, +0x00016724, +0x00016722, +0x00016720, +0x0001671d, +0x0001671c, +0x0001671b, +0x00016718, +0x00016716, +0x00016714, +0x00016712, +0x0001670f, +0x0001670e, +0x0001670d, +0x0001670a, +0x00016708, +0x00016706, +0x00016704, +0x00016703, +0x00016700, +0x000166ff, +0x000166fc, +0x000166fa, +0x000166f9, +0x000166f6, +0x000166f5, +0x000166f2, +0x000166f1, +0x000166ef, +0x000166ec, +0x000166eb, +0x000166e8, +0x000166e7, +0x000166e5, +0x000166e3, +0x000166e1, +0x000166de, +0x000166dd, +0x000166dc, +0x000166d9, +0x000166d7, +0x000166d5, +0x000166d3, +0x000166d2, +0x000166cf, +0x000166ce, +0x000166cb, +0x000166c9, +0x000166c8, +0x000166c5, +0x000166c4, +0x000166c1, +0x000166bf, +0x000166be, +0x000166bb, +0x000166ba, +0x000166b7, +0x000166b6, +0x000166b4, +0x000166b1, +0x000166b0, +0x000166ad, +0x000166ac, +0x000166aa, +0x000166a8, +0x000166a6, +0x000166a3, +0x000166a2, +0x000166a1, +0x0001669e, +0x0001669d, +0x0001669a, +0x00016698, +0x00016696, +0x00016694, +0x00016693, +0x00016690, +0x0001668f, +0x0001668c, +0x0001668a, +0x00016689, +0x00016686, +0x00016685, +0x00016682, +0x00016681, +0x0001667f, +0x0001667c, +0x0001667b, +0x00016678, +0x00016677, +0x00016675, +0x00016673, +0x00016671, +0x0001666e, +0x0001666d, +0x0001666c, +0x00016669, +0x00016667, +0x00016665, +0x00016663, +0x00016662, +0x0001665f, +0x0001665e, +0x0001665b, +0x0001665a, +0x00016658, +0x00016655, +0x00016654, +0x00016651, +0x00016650, +0x0001664e, +0x0001664c, +0x0001664a, +0x00016647, +0x00016646, +0x00016645, +0x00016642, +0x00016640, +0x0001663e, +0x0001663c, +0x0001663b, +0x00016638, +0x00016637, +0x00016634, +0x00016632, +0x00016631, +0x0001662e, +0x0001662d, +0x0001662a, +0x00016629, +0x00016627, +0x00016624, +0x00016623, +0x00016620, +0x0001661f, +0x0001661d, +0x0001661b, +0x00016619, +0x00016616, +0x00016615, +0x00016614, +0x00016611, +0x0001660f, +0x0001660d, +0x0001660b, +0x0001660a, +0x00016607, +0x00016606, +0x00016603, +0x00016601, +0x00016600, +0x000165fd, +0x000165fc, +0x000165f9, +0x000165f8, +0x000165f6, +0x000165f3, +0x000165f2, +0x000165ef, +0x000165ee, +0x000165ec, +0x000165ea, +0x000165e8, +0x000165e5, +0x000165e4, +0x000165e3, +0x000165e0, +0x000165de, +0x000165dc, +0x000165da, +0x000165d9, +0x000165d6, +0x000165d5, +0x000165d2, +0x000165d0, +0x000165cf, +0x000165cc, +0x000165cb, +0x000165c8, +0x000165c7, +0x000165c5, +0x000165c2, +0x000165c1, +0x000165be, +0x000165bd, +0x000165bb, +0x000165b9, +0x000165b7, +0x000165b4, +0x000165b3, +0x000165b2, +0x000165af, +0x000165ad, +0x000165ab, +0x000165a9, +0x000165a8, +0x000165a5, +0x000165a4, +0x000165a2, +0x0001659f, +0x0001659e, +0x0001659c, +0x00016599, +0x00016598, +0x00016595, +0x00016594, +0x00016592, +0x00016590, +0x0001658e, +0x0001658b, +0x0001658a, +0x00016589, +0x00016586, +0x00016584, +0x00016582, +0x00016580, +0x0001657f, +0x0001657c, +0x0001657b, +0x00016578, +0x00016577, +0x00016575, +0x00016572, +0x00016571, +0x0001656e, +0x0001656d, +0x0001656b, +0x00016569, +0x00016567, +0x00016566, +0x00016563, +0x00016562, +0x0001655f, +0x0001655d, +0x0001655c, +0x00016559, +0x00016558, +0x00016555, +0x00016554, +0x00016552, +0x0001654f, +0x0001654e, +0x0001654b, +0x0001654a, +0x00016549, +0x00016546, +0x00016544, +0x00016542, +0x00016540, +0x0001653f, +0x0001653c, +0x0001653b, +0x00016538, +0x00016536, +0x00016535, +0x00016532, +0x00016531, +0x0001652e, +0x0001652d, +0x0001652b, +0x00016528, +0x00016527, +0x00016526, +0x00016523, +0x00016521, +0x0001651f, +0x0001651d, +0x0001651c, +0x00016519, +0x00016518, +0x00016515, +0x00016514, +0x00016512, +0x0001650f, +0x0001650e, +0x0001650b, +0x0001650a, +0x00016508, +0x00016506, +0x00016504, +0x00016501, +0x00016500, +0x000164ff, +0x000164fc, +0x000164fa, +0x000164f8, +0x000164f6, +0x000164f5, +0x000164f2, +0x000164f1, +0x000164ee, +0x000164ec, +0x000164eb, +0x000164e8, +0x000164e7, +0x000164e4, +0x000164e3, +0x000164e1, +0x000164df, +0x000164dd, +0x000164dc, +0x000164d9, +0x000164d8, +0x000164d5, +0x000164d3, +0x000164d2, +0x000164cf, +0x000164ce, +0x000164cb, +0x000164ca, +0x000164c8, +0x000164c5, +0x000164c4, +0x000164c1, +0x000164c0, +0x000164be, +0x000164bc, +0x000164ba, +0x000164b7, +0x000164b6, +0x000164b5, +0x000164b2, +0x000164b1, +0x000164ae, +0x000164ac, +0x000164ab, +0x000164a8, +0x000164a7, +0x000164a4, +0x000164a3, +0x000164a0, +0x0001649f, +0x0001649d, +0x0001649a, +0x00016499, +0x00016496, +0x00016495, +0x00016493, +0x00016491, +0x0001648f, +0x0001648e, +0x0001648b, +0x0001648a, +0x00016487, +0x00016486, +0x00016484, +0x00016481, +0x00016480, +0x0001647d, +0x0001647c, +0x0001647a, +0x00016478, +0x00016476, +0x00016473, +0x00016472, +0x00016471, +0x0001646e, +0x0001646c, +0x0001646b, +0x00016468, +0x00016467, +0x00016464, +0x00016463, +0x00016461, +0x0001645f, +0x0001645d, +0x0001645a, +0x00016459, +0x00016458, +0x00016455, +0x00016453, +0x00016451, +0x0001644f, +0x0001644e, +0x0001644b, +0x0001644a, +0x00016447, +0x00016446, +0x00016444, +0x00016441, +0x00016440, +0x0001643f, +0x0001643c, +0x0001643a, +0x00016438, +0x00016436, +0x00016435, +0x00016432, +0x00016431, +0x0001642e, +0x0001642d, +0x0001642b, +0x00016428, +0x00016427, +0x00016424, +0x00016423, +0x00016421, +0x0001641f, +0x0001641d, +0x0001641a, +0x00016419, +0x00016418, +0x00016415, +0x00016413, +0x00016412, +0x0001640f, +0x0001640e, +0x0001640b, +0x0001640a, +0x00016408, +0x00016406, +0x00016404, +0x00016401, +0x00016400, +0x000163ff, +0x000163fc, +0x000163fa, +0x000163f8, +0x000163f6, +0x000163f5, +0x000163f2, +0x000163f1, +0x000163ef, +0x000163ed, +0x000163eb, +0x000163e8, +0x000163e7, +0x000163e6, +0x000163e3, +0x000163e1, +0x000163df, +0x000163dd, +0x000163dc, +0x000163d9, +0x000163d8, +0x000163d5, +0x000163d4, +0x000163d2, +0x000163cf, +0x000163ce, +0x000163cb, +0x000163ca, +0x000163c8, +0x000163c6, +0x000163c4, +0x000163c3, +0x000163c0, +0x000163bf, +0x000163bc, +0x000163ba, +0x000163b9, +0x000163b6, +0x000163b5, +0x000163b2, +0x000163b0, +0x000163af, +0x000163ac, +0x000163ab, +0x000163a9, +0x000163a6, +0x000163a5, +0x000163a4, +0x000163a1, +0x0001639f, +0x0001639d, +0x0001639b, +0x0001639a, +0x00016397, +0x00016396, +0x00016393, +0x00016392, +0x00016390, +0x0001638d, +0x0001638c, +0x0001638b, +0x00016388, +0x00016387, +0x00016384, +0x00016382, +0x00016381, +0x0001637e, +0x0001637d, +0x0001637a, +0x00016379, +0x00016377, +0x00016374, +0x00016373, +0x00016370, +0x0001636f, +0x0001636e, +0x0001636b, +0x00016369, +0x00016368, +0x00016365, +0x00016364, +0x00016361, +0x00016360, +0x0001635e, +0x0001635c, +0x0001635a, +0x00016357, +0x00016356, +0x00016355, +0x00016352, +0x00016350, +0x0001634f, +0x0001634c, +0x0001634b, +0x00016348, +0x00016347, +0x00016345, +0x00016343, +0x00016341, +0x0001633e, +0x0001633d, +0x0001633c, +0x00016339, +0x00016337, +0x00016336, +0x00016333, +0x00016332, +0x0001632f, +0x0001632e, +0x0001632c, +0x0001632a, +0x00016328, +0x00016325, +0x00016324, +0x00016323, +0x00016320, +0x0001631f, +0x0001631c, +0x0001631a, +0x00016319, +0x00016316, +0x00016315, +0x00016313, +0x00016311, +0x0001630f, +0x0001630c, +0x0001630b, +0x0001630a, +0x00016307, +0x00016306, +0x00016303, +0x00016301, +0x00016300, +0x000162fd, +0x000162fc, +0x000162fa, +0x000162f8, +0x000162f6, +0x000162f4, +0x000162f2, +0x000162f1, +0x000162ee, +0x000162ed, +0x000162ea, +0x000162e8, +0x000162e7, +0x000162e4, +0x000162e3, +0x000162e0, +0x000162df, +0x000162dd, +0x000162db, +0x000162d9, +0x000162d8, +0x000162d5, +0x000162d4, +0x000162d1, +0x000162cf, +0x000162ce, +0x000162cb, +0x000162ca, +0x000162c7, +0x000162c6, +0x000162c4, +0x000162c2, +0x000162c0, +0x000162bf, +0x000162bc, +0x000162bb, +0x000162b8, +0x000162b7, +0x000162b4, +0x000162b2, +0x000162b1, +0x000162ae, +0x000162ad, +0x000162aa, +0x000162a9, +0x000162a7, +0x000162a5, +0x000162a3, +0x000162a2, +0x0001629f, +0x0001629e, +0x0001629b, +0x00016299, +0x00016298, +0x00016295, +0x00016294, +0x00016291, +0x00016290, +0x0001628e, +0x0001628c, +0x0001628a, +0x00016289, +0x00016286, +0x00016285, +0x00016282, +0x00016281, +0x0001627f, +0x0001627c, +0x0001627b, +0x00016278, +0x00016277, +0x00016276, +0x00016273, +0x00016271, +0x00016270, +0x0001626d, +0x0001626c, +0x00016269, +0x00016268, +0x00016266, +0x00016264, +0x00016262, +0x00016261, +0x0001625e, +0x0001625d, +0x0001625a, +0x00016259, +0x00016257, +0x00016254, +0x00016253, +0x00016250, +0x0001624f, +0x0001624d, +0x0001624b, +0x00016249, +0x00016248, +0x00016245, +0x00016244, +0x00016241, +0x00016240, +0x0001623e, +0x0001623b, +0x0001623a, +0x00016237, +0x00016236, +0x00016235, +0x00016232, +0x00016230, +0x0001622f, +0x0001622c, +0x0001622b, +0x00016228, +0x00016227, +0x00016225, +0x00016223, +0x00016221, +0x0001621e, +0x0001621d, +0x0001621c, +0x00016219, +0x00016218, +0x00016216, +0x00016213, +0x00016212, +0x0001620f, +0x0001620e, +0x0001620c, +0x0001620a, +0x00016208, +0x00016207, +0x00016204, +0x00016203, +0x00016200, +0x000161ff, +0x000161fd, +0x000161fa, +0x000161f9, +0x000161f6, +0x000161f5, +0x000161f4, +0x000161f1, +0x000161ef, +0x000161ee, +0x000161eb, +0x000161ea, +0x000161e7, +0x000161e6, +0x000161e4, +0x000161e2, +0x000161e0, +0x000161dd, +0x000161dc, +0x000161db, +0x000161d8, +0x000161d7, +0x000161d5, +0x000161d2, +0x000161d1, +0x000161ce, +0x000161cd, +0x000161cb, +0x000161c9, +0x000161c7, +0x000161c5, +0x000161c2, +0x000161c1, +0x000161c0, +0x000161bd, +0x000161bc, +0x000161b9, +0x000161b7, +0x000161b6, +0x000161b3, +0x000161b2, +0x000161b1, +0x000161ae, +0x000161ac, +0x000161aa, +0x000161a8, +0x000161a7, +0x000161a4, +0x000161a3, +0x000161a1, +0x0001619f, +0x0001619d, +0x0001619a, +0x00016199, +0x00016198, +0x00016195, +0x00016194, +0x00016192, +0x0001618f, +0x0001618e, +0x0001618b, +0x0001618a, +0x00016189, +0x00016186, +0x00016184, +0x00016182, +0x00016180, +0x0001617f, +0x0001617c, +0x0001617b, +0x00016179, +0x00016177, +0x00016175, +0x00016172, +0x00016171, +0x00016170, +0x0001616d, +0x0001616c, +0x0001616a, +0x00016167, +0x00016166, +0x00016163, +0x00016162, +0x00016161, +0x0001615e, +0x0001615c, +0x0001615b, +0x00016158, +0x00016157, +0x00016154, +0x00016153, +0x00016151, +0x0001614f, +0x0001614d, +0x0001614c, +0x00016149, +0x00016148, +0x00016145, +0x00016144, +0x00016142, +0x0001613f, +0x0001613e, +0x0001613b, +0x0001613a, +0x00016139, +0x00016136, +0x00016134, +0x00016133, +0x00016130, +0x0001612f, +0x0001612c, +0x0001612b, +0x00016129, +0x00016127, +0x00016125, +0x00016124, +0x00016121, +0x00016120, +0x0001611d, +0x0001611c, +0x0001611a, +0x00016117, +0x00016116, +0x00016115, +0x00016112, +0x00016111, +0x0001610e, +0x0001610c, +0x0001610b, +0x00016108, +0x00016107, +0x00016104, +0x00016103, +0x00016101, +0x000160ff, +0x000160fd, +0x000160fc, +0x000160f9, +0x000160f8, +0x000160f5, +0x000160f4, +0x000160f2, +0x000160ef, +0x000160ee, +0x000160ed, +0x000160ea, +0x000160e9, +0x000160e6, +0x000160e4, +0x000160e3, +0x000160e0, +0x000160df, +0x000160de, +0x000160db, +0x000160d9, +0x000160d7, +0x000160d5, +0x000160d4, +0x000160d1, +0x000160d0, +0x000160cd, +0x000160cc, +0x000160ca, +0x000160c7, +0x000160c6, +0x000160c3, +0x000160c2, +0x000160c1, +0x000160be, +0x000160bc, +0x000160bb, +0x000160b8, +0x000160b7, +0x000160b4, +0x000160b3, +0x000160b1, +0x000160af, +0x000160ad, +0x000160ac, +0x000160a9, +0x000160a8, +0x000160a5, +0x000160a4, +0x000160a2, +0x000160a0, +0x0001609e, +0x0001609d, +0x0001609a, +0x00016099, +0x00016096, +0x00016095, +0x00016093, +0x00016090, +0x0001608f, +0x0001608e, +0x0001608b, +0x0001608a, +0x00016087, +0x00016085, +0x00016084, +0x00016081, +0x00016080, +0x0001607f, +0x0001607c, +0x0001607a, +0x00016078, +0x00016076, +0x00016075, +0x00016072, +0x00016071, +0x0001606f, +0x0001606d, +0x0001606b, +0x00016069, +0x00016067, +0x00016066, +0x00016063, +0x00016062, +0x00016060, +0x0001605e, +0x0001605c, +0x00016059, +0x00016058, +0x00016057, +0x00016054, +0x00016053, +0x00016051, +0x0001604e, +0x0001604d, +0x0001604a, +0x00016049, +0x00016048, +0x00016045, +0x00016043, +0x00016042, +0x0001603f, +0x0001603e, +0x0001603b, +0x0001603a, +0x00016038, +0x00016036, +0x00016034, +0x00016033, +0x00016030, +0x0001602f, +0x0001602c, +0x0001602b, +0x00016029, +0x00016027, +0x00016025, +0x00016024, +0x00016021, +0x00016020, +0x0001601d, +0x0001601c, +0x0001601a, +0x00016017, +0x00016016, +0x00016015, +0x00016012, +0x00016011, +0x0001600e, +0x0001600c, +0x0001600b, +0x00016008, +0x00016007, +0x00016006, +0x00016003, +0x00016001, +0x00015fff, +0x00015ffd, +0x00015ffc, +0x00015ff9, +0x00015ff8, +0x00015ff6, +0x00015ff4, +0x00015ff2, +0x00015ff0, +0x00015fee, +0x00015fed, +0x00015fea, +0x00015fe9, +0x00015fe7, +0x00015fe5, +0x00015fe3, +0x00015fe0, +0x00015fde, +0x00015fdd, +0x00015fdb, +0x00015fd9, +0x00015fd7, +0x00015fd5, +0x00015fd3, +0x00015fd2, +0x00015fcf, +0x00015fce, +0x00015fcc, +0x00015fca, +0x00015fc8, +0x00015fc5, +0x00015fc4, +0x00015fc3, +0x00015fc0, +0x00015fbf, +0x00015fbd, +0x00015fba, +0x00015fb9, +0x00015fb6, +0x00015fb5, +0x00015fb4, +0x00015fb1, +0x00015fb0, +0x00015fae, +0x00015fab, +0x00015faa, +0x00015fa7, +0x00015fa6, +0x00015fa5, +0x00015fa2, +0x00015fa0, +0x00015f9f, +0x00015f9c, +0x00015f9b, +0x00015f9a, +0x00015f97, +0x00015f95, +0x00015f93, +0x00015f91, +0x00015f90, +0x00015f8d, +0x00015f8c, +0x00015f8a, +0x00015f88, +0x00015f86, +0x00015f84, +0x00015f82, +0x00015f81, +0x00015f7e, +0x00015f7d, +0x00015f7b, +0x00015f79, +0x00015f77, +0x00015f75, +0x00015f73, +0x00015f72, +0x00015f6f, +0x00015f6e, +0x00015f6c, +0x00015f6a, +0x00015f68, +0x00015f67, +0x00015f64, +0x00015f63, +0x00015f60, +0x00015f5f, +0x00015f5d, +0x00015f5a, +0x00015f59, +0x00015f58, +0x00015f55, +0x00015f54, +0x00015f51, +0x00015f50, +0x00015f4e, +0x00015f4b, +0x00015f4a, +0x00015f49, +0x00015f46, +0x00015f45, +0x00015f42, +0x00015f40, +0x00015f3f, +0x00015f3c, +0x00015f3b, +0x00015f3a, +0x00015f37, +0x00015f35, +0x00015f33, +0x00015f31, +0x00015f30, +0x00015f2d, +0x00015f2c, +0x00015f2b, +0x00015f28, +0x00015f26, +0x00015f25, +0x00015f22, +0x00015f21, +0x00015f1e, +0x00015f1d, +0x00015f1b, +0x00015f19, +0x00015f17, +0x00015f16, +0x00015f13, +0x00015f12, +0x00015f0f, +0x00015f0e, +0x00015f0c, +0x00015f0a, +0x00015f08, +0x00015f07, +0x00015f04, +0x00015f03, +0x00015f00, +0x00015eff, +0x00015efd, +0x00015efb, +0x00015ef9, +0x00015ef8, +0x00015ef5, +0x00015ef4, +0x00015ef1, +0x00015ef0, +0x00015eee, +0x00015eeb, +0x00015eea, +0x00015ee7, +0x00015ee6, +0x00015ee4, +0x00015ee2, +0x00015ee0, +0x00015edf, +0x00015edc, +0x00015edb, +0x00015ed8, +0x00015ed7, +0x00015ed5, +0x00015ed3, +0x00015ed1, +0x00015ed0, +0x00015ecd, +0x00015ecc, +0x00015eca, +0x00015ec8, +0x00015ec6, +0x00015ec4, +0x00015ec2, +0x00015ec1, +0x00015ebe, +0x00015ebd, +0x00015ebb, +0x00015eb9, +0x00015eb7, +0x00015eb4, +0x00015eb3, +0x00015eb2, +0x00015eaf, +0x00015eae, +0x00015eac, +0x00015eaa, +0x00015ea8, +0x00015ea7, +0x00015ea4, +0x00015ea3, +0x00015ea0, +0x00015e9f, +0x00015e9d, +0x00015e9a, +0x00015e99, +0x00015e98, +0x00015e95, +0x00015e94, +0x00015e92, +0x00015e90, +0x00015e8e, +0x00015e8b, +0x00015e8a, +0x00015e89, +0x00015e86, +0x00015e85, +0x00015e83, +0x00015e81, +0x00015e7f, +0x00015e7c, +0x00015e7b, +0x00015e7a, +0x00015e77, +0x00015e76, +0x00015e74, +0x00015e71, +0x00015e70, +0x00015e6f, +0x00015e6c, +0x00015e6b, +0x00015e68, +0x00015e67, +0x00015e65, +0x00015e62, +0x00015e61, +0x00015e60, +0x00015e5d, +0x00015e5c, +0x00015e59, +0x00015e58, +0x00015e56, +0x00015e53, +0x00015e52, +0x00015e51, +0x00015e4e, +0x00015e4d, +0x00015e4b, +0x00015e48, +0x00015e47, +0x00015e44, +0x00015e43, +0x00015e42, +0x00015e3f, +0x00015e3e, +0x00015e3c, +0x00015e39, +0x00015e38, +0x00015e37, +0x00015e34, +0x00015e33, +0x00015e30, +0x00015e2e, +0x00015e2d, +0x00015e2a, +0x00015e29, +0x00015e28, +0x00015e25, +0x00015e24, +0x00015e21, +0x00015e1f, +0x00015e1e, +0x00015e1b, +0x00015e1a, +0x00015e19, +0x00015e16, +0x00015e15, +0x00015e13, +0x00015e10, +0x00015e0f, +0x00015e0c, +0x00015e0b, +0x00015e0a, +0x00015e07, +0x00015e05, +0x00015e04, +0x00015e01, +0x00015e00, +0x00015dff, +0x00015dfc, +0x00015dfb, +0x00015df8, +0x00015df6, +0x00015df5, +0x00015df2, +0x00015df1, +0x00015df0, +0x00015ded, +0x00015deb, +0x00015de9, +0x00015de7, +0x00015de6, +0x00015de3, +0x00015de2, +0x00015de1, +0x00015dde, +0x00015ddc, +0x00015ddb, +0x00015dd8, +0x00015dd7, +0x00015dd4, +0x00015dd3, +0x00015dd2, +0x00015dcf, +0x00015dcd, +0x00015dcc, +0x00015dc9, +0x00015dc8, +0x00015dc5, +0x00015dc4, +0x00015dc2, +0x00015dc0, +0x00015dbe, +0x00015dbd, +0x00015dba, +0x00015db9, +0x00015db8, +0x00015db5, +0x00015db3, +0x00015db1, +0x00015daf, +0x00015dae, +0x00015dab, +0x00015daa, +0x00015da9, +0x00015da6, +0x00015da4, +0x00015da3, +0x00015da0, +0x00015d9f, +0x00015d9c, +0x00015d9b, +0x00015d99, +0x00015d97, +0x00015d95, +0x00015d94, +0x00015d91, +0x00015d90, +0x00015d8d, +0x00015d8c, +0x00015d8a, +0x00015d88, +0x00015d86, +0x00015d85, +0x00015d82, +0x00015d81, +0x00015d7f, +0x00015d7d, +0x00015d7b, +0x00015d79, +0x00015d77, +0x00015d76, +0x00015d73, +0x00015d72, +0x00015d70, +0x00015d6e, +0x00015d6c, +0x00015d6a, +0x00015d68, +0x00015d67, +0x00015d64, +0x00015d63, +0x00015d61, +0x00015d5f, +0x00015d5d, +0x00015d5c, +0x00015d59, +0x00015d58, +0x00015d55, +0x00015d54, +0x00015d52, +0x00015d50, +0x00015d4e, +0x00015d4d, +0x00015d4a, +0x00015d49, +0x00015d47, +0x00015d45, +0x00015d43, +0x00015d41, +0x00015d3f, +0x00015d3e, +0x00015d3b, +0x00015d3a, +0x00015d38, +0x00015d36, +0x00015d34, +0x00015d32, +0x00015d30, +0x00015d2f, +0x00015d2c, +0x00015d2b, +0x00015d29, +0x00015d27, +0x00015d25, +0x00015d24, +0x00015d21, +0x00015d20, +0x00015d1d, +0x00015d1c, +0x00015d1a, +0x00015d18, +0x00015d16, +0x00015d15, +0x00015d12, +0x00015d11, +0x00015d0f, +0x00015d0e, +0x00015d0c, +0x00015d0a, +0x00015d08, +0x00015d05, +0x00015d04, +0x00015d03, +0x00015d00, +0x00015cff, +0x00015cfd, +0x00015cfb, +0x00015cf9, +0x00015cf8, +0x00015cf5, +0x00015cf4, +0x00015cf1, +0x00015cf0, +0x00015cee, +0x00015cec, +0x00015cea, +0x00015ce9, +0x00015ce6, +0x00015ce5, +0x00015ce3, +0x00015ce1, +0x00015cdf, +0x00015cdd, +0x00015cdb, +0x00015cda, +0x00015cd7, +0x00015cd6, +0x00015cd4, +0x00015cd2, +0x00015cd0, +0x00015ccf, +0x00015ccc, +0x00015ccb, +0x00015cc8, +0x00015cc7, +0x00015cc5, +0x00015cc3, +0x00015cc1, +0x00015cc0, +0x00015cbd, +0x00015cbc, +0x00015cba, +0x00015cb8, +0x00015cb6, +0x00015cb4, +0x00015cb2, +0x00015cb1, +0x00015cae, +0x00015cad, +0x00015cab, +0x00015ca9, +0x00015ca7, +0x00015ca6, +0x00015ca3, +0x00015ca2, +0x00015c9f, +0x00015c9e, +0x00015c9c, +0x00015c9a, +0x00015c98, +0x00015c97, +0x00015c94, +0x00015c93, +0x00015c92, +0x00015c8f, +0x00015c8d, +0x00015c8b, +0x00015c89, +0x00015c88, +0x00015c85, +0x00015c84, +0x00015c83, +0x00015c80, +0x00015c7e, +0x00015c7d, +0x00015c7a, +0x00015c79, +0x00015c76, +0x00015c75, +0x00015c74, +0x00015c71, +0x00015c6f, +0x00015c6e, +0x00015c6b, +0x00015c6a, +0x00015c69, +0x00015c66, +0x00015c65, +0x00015c62, +0x00015c60, +0x00015c5f, +0x00015c5c, +0x00015c5b, +0x00015c5a, +0x00015c57, +0x00015c56, +0x00015c54, +0x00015c52, +0x00015c50, +0x00015c4d, +0x00015c4c, +0x00015c4b, +0x00015c48, +0x00015c47, +0x00015c45, +0x00015c43, +0x00015c41, +0x00015c40, +0x00015c3d, +0x00015c3c, +0x00015c39, +0x00015c38, +0x00015c36, +0x00015c34, +0x00015c32, +0x00015c31, +0x00015c2e, +0x00015c2d, +0x00015c2b, +0x00015c29, +0x00015c27, +0x00015c25, +0x00015c23, +0x00015c22, +0x00015c21, +0x00015c1e, +0x00015c1d, +0x00015c1b, +0x00015c18, +0x00015c17, +0x00015c14, +0x00015c13, +0x00015c12, +0x00015c0f, +0x00015c0e, +0x00015c0c, +0x00015c0a, +0x00015c08, +0x00015c07, +0x00015c04, +0x00015c03, +0x00015c01, +0x00015bff, +0x00015bfd, +0x00015bfb, +0x00015bf9, +0x00015bf8, +0x00015bf5, +0x00015bf4, +0x00015bf2, +0x00015bf0, +0x00015bee, +0x00015bed, +0x00015bea, +0x00015be9, +0x00015be8, +0x00015be5, +0x00015be3, +0x00015be1, +0x00015bdf, +0x00015bde, +0x00015bdb, +0x00015bda, +0x00015bd9, +0x00015bd6, +0x00015bd5, +0x00015bd3, +0x00015bd0, +0x00015bcf, +0x00015bcc, +0x00015bcb, +0x00015bca, +0x00015bc7, +0x00015bc6, +0x00015bc4, +0x00015bc1, +0x00015bc0, +0x00015bbf, +0x00015bbc, +0x00015bbb, +0x00015bb9, +0x00015bb7, +0x00015bb5, +0x00015bb3, +0x00015bb1, +0x00015bb0, +0x00015bad, +0x00015bac, +0x00015baa, +0x00015ba8, +0x00015ba6, +0x00015ba5, +0x00015ba2, +0x00015ba1, +0x00015b9e, +0x00015b9d, +0x00015b9b, +0x00015b99, +0x00015b97, +0x00015b96, +0x00015b93, +0x00015b92, +0x00015b91, +0x00015b8e, +0x00015b8c, +0x00015b8b, +0x00015b88, +0x00015b87, +0x00015b84, +0x00015b83, +0x00015b82, +0x00015b7f, +0x00015b7e, +0x00015b7c, +0x00015b79, +0x00015b78, +0x00015b77, +0x00015b74, +0x00015b73, +0x00015b71, +0x00015b6f, +0x00015b6d, +0x00015b6a, +0x00015b69, +0x00015b68, +0x00015b65, +0x00015b64, +0x00015b62, +0x00015b60, +0x00015b5e, +0x00015b5d, +0x00015b5a, +0x00015b59, +0x00015b56, +0x00015b55, +0x00015b53, +0x00015b51, +0x00015b4f, +0x00015b4e, +0x00015b4b, +0x00015b4a, +0x00015b48, +0x00015b46, +0x00015b44, +0x00015b43, +0x00015b40, +0x00015b3f, +0x00015b3c, +0x00015b3b, +0x00015b3a, +0x00015b37, +0x00015b36, +0x00015b34, +0x00015b32, +0x00015b31, +0x00015b2e, +0x00015b2d, +0x00015b2b, +0x00015b29, +0x00015b27, +0x00015b26, +0x00015b23, +0x00015b22, +0x00015b1f, +0x00015b1e, +0x00015b1c, +0x00015b1a, +0x00015b18, +0x00015b17, +0x00015b14, +0x00015b13, +0x00015b12, +0x00015b0f, +0x00015b0e, +0x00015b0c, +0x00015b09, +0x00015b08, +0x00015b07, +0x00015b04, +0x00015b03, +0x00015b00, +0x00015aff, +0x00015afd, +0x00015afb, +0x00015af9, +0x00015af8, +0x00015af5, +0x00015af4, +0x00015af2, +0x00015af0, +0x00015aee, +0x00015aed, +0x00015aea, +0x00015ae9, +0x00015ae6, +0x00015ae5, +0x00015ae4, +0x00015ae1, +0x00015adf, +0x00015ade, +0x00015adb, +0x00015ada, +0x00015ad9, +0x00015ad6, +0x00015ad5, +0x00015ad3, +0x00015ad1, +0x00015acf, +0x00015acc, +0x00015acb, +0x00015aca, +0x00015ac7, +0x00015ac6, +0x00015ac4, +0x00015ac2, +0x00015ac0, +0x00015abf, +0x00015abc, +0x00015abb, +0x00015aba, +0x00015ab7, +0x00015ab5, +0x00015ab4, +0x00015ab1, +0x00015ab0, +0x00015aad, +0x00015aac, +0x00015aab, +0x00015aa8, +0x00015aa7, +0x00015aa5, +0x00015aa2, +0x00015aa1, +0x00015aa0, +0x00015a9d, +0x00015a9c, +0x00015a9a, +0x00015a98, +0x00015a96, +0x00015a94, +0x00015a92, +0x00015a91, +0x00015a8e, +0x00015a8d, +0x00015a8b, +0x00015a89, +0x00015a87, +0x00015a86, +0x00015a83, +0x00015a82, +0x00015a81, +0x00015a7e, +0x00015a7d, +0x00015a7a, +0x00015a78, +0x00015a77, +0x00015a74, +0x00015a73, +0x00015a72, +0x00015a6f, +0x00015a6e, +0x00015a6c, +0x00015a6a, +0x00015a68, +0x00015a67, +0x00015a64, +0x00015a63, +0x00015a61, +0x00015a5f, +0x00015a5d, +0x00015a5b, +0x00015a59, +0x00015a58, +0x00015a55, +0x00015a54, +0x00015a53, +0x00015a50, +0x00015a4e, +0x00015a4d, +0x00015a4c, +0x00015a49, +0x00015a48, +0x00015a45, +0x00015a44, +0x00015a42, +0x00015a40, +0x00015a3e, +0x00015a3d, +0x00015a3a, +0x00015a39, +0x00015a37, +0x00015a35, +0x00015a33, +0x00015a32, +0x00015a2f, +0x00015a2e, +0x00015a2d, +0x00015a2a, +0x00015a29, +0x00015a26, +0x00015a24, +0x00015a23, +0x00015a20, +0x00015a1f, +0x00015a1e, +0x00015a1b, +0x00015a1a, +0x00015a18, +0x00015a16, +0x00015a14, +0x00015a13, +0x00015a10, +0x00015a0f, +0x00015a0e, +0x00015a0b, +0x00015a09, +0x00015a07, +0x00015a05, +0x00015a04, +0x00015a01, +0x00015a00, +0x000159ff, +0x000159fc, +0x000159fb, +0x000159f9, +0x000159f7, +0x000159f5, +0x000159f4, +0x000159f1, +0x000159f0, +0x000159ee, +0x000159ec, +0x000159ea, +0x000159e9, +0x000159e6, +0x000159e5, +0x000159e2, +0x000159e1, +0x000159e0, +0x000159dd, +0x000159dc, +0x000159da, +0x000159d7, +0x000159d6, +0x000159d5, +0x000159d2, +0x000159d1, +0x000159cf, +0x000159cd, +0x000159cb, +0x000159ca, +0x000159c7, +0x000159c6, +0x000159c3, +0x000159c2, +0x000159c0, +0x000159be, +0x000159bc, +0x000159bb, +0x000159b8, +0x000159b7, +0x000159b6, +0x000159b3, +0x000159b2, +0x000159b0, +0x000159ae, +0x000159ac, +0x000159ab, +0x000159a8, +0x000159a7, +0x000159a5, +0x000159a3, +0x000159a1, +0x0001599f, +0x0001599d, +0x0001599c, +0x00015999, +0x00015998, +0x00015997, +0x00015994, +0x00015993, +0x00015991, +0x0001598e, +0x0001598d, +0x0001598c, +0x00015989, +0x00015988, +0x00015986, +0x00015984, +0x00015982, +0x00015980, +0x0001597e, +0x0001597d, +0x0001597a, +0x00015979, +0x00015977, +0x00015975, +0x00015973, +0x00015972, +0x0001596f, +0x0001596e, +0x0001596d, +0x0001596a, +0x00015969, +0x00015967, +0x00015965, +0x00015963, +0x00015961, +0x00015960, +0x0001595e, +0x0001595c, +0x0001595a, +0x00015959, +0x00015956, +0x00015955, +0x00015952, +0x00015951, +0x00015950, +0x0001594d, +0x0001594b, +0x0001594a, +0x00015947, +0x00015946, +0x00015945, +0x00015942, +0x00015941, +0x0001593f, +0x0001593d, +0x0001593b, +0x0001593a, +0x00015937, +0x00015936, +0x00015935, +0x00015932, +0x00015931, +0x0001592f, +0x0001592c, +0x0001592b, +0x00015928, +0x00015927, +0x00015926, +0x00015923, +0x00015922, +0x00015920, +0x0001591e, +0x0001591c, +0x0001591b, +0x00015918, +0x00015917, +0x00015916, +0x00015913, +0x00015912, +0x00015910, +0x0001590d, +0x0001590c, +0x0001590b, +0x00015908, +0x00015907, +0x00015905, +0x00015903, +0x00015901, +0x000158ff, +0x000158fd, +0x000158fc, +0x000158f9, +0x000158f8, +0x000158f7, +0x000158f4, +0x000158f3, +0x000158f1, +0x000158ee, +0x000158ed, +0x000158ec, +0x000158e9, +0x000158e8, +0x000158e6, +0x000158e4, +0x000158e2, +0x000158e1, +0x000158de, +0x000158dd, +0x000158dc, +0x000158d9, +0x000158d8, +0x000158d5, +0x000158d4, +0x000158d2, +0x000158cf, +0x000158ce, +0x000158cd, +0x000158ca, +0x000158c9, +0x000158c7, +0x000158c5, +0x000158c3, +0x000158c2, +0x000158bf, +0x000158be, +0x000158bd, +0x000158ba, +0x000158b9, +0x000158b7, +0x000158b5, +0x000158b3, +0x000158b2, +0x000158af, +0x000158ae, +0x000158ab, +0x000158aa, +0x000158a8, +0x000158a6, +0x000158a4, +0x000158a3, +0x000158a0, +0x0001589f, +0x0001589e, +0x0001589b, +0x0001589a, +0x00015898, +0x00015896, +0x00015894, +0x00015893, +0x00015890, +0x0001588f, +0x0001588d, +0x0001588b, +0x00015889, +0x00015888, +0x00015885, +0x00015884, +0x00015881, +0x00015880, +0x0001587f, +0x0001587c, +0x0001587b, +0x00015879, +0x00015878, +0x00015875, +0x00015874, +0x00015872, +0x00015870, +0x0001586e, +0x0001586d, +0x0001586a, +0x00015869, +0x00015867, +0x00015865, +0x00015863, +0x00015862, +0x0001585f, +0x0001585e, +0x0001585d, +0x0001585a, +0x00015859, +0x00015856, +0x00015855, +0x00015853, +0x00015851, +0x0001584f, +0x0001584e, +0x0001584b, +0x0001584a, +0x00015849, +0x00015846, +0x00015845, +0x00015843, +0x00015841, +0x0001583f, +0x0001583e, +0x0001583b, +0x0001583a, +0x00015838, +0x00015836, +0x00015834, +0x00015833, +0x00015830, +0x0001582f, +0x0001582e, +0x0001582b, +0x0001582a, +0x00015828, +0x00015826, +0x00015824, +0x00015823, +0x00015820, +0x0001581f, +0x0001581c, +0x0001581b, +0x0001581a, +0x00015817, +0x00015816, +0x00015814, +0x00015811, +0x00015810, +0x0001580f, +0x0001580c, +0x0001580b, +0x00015809, +0x00015807, +0x00015805, +0x00015804, +0x00015801, +0x00015800, +0x000157ff, +0x000157fc, +0x000157fb, +0x000157f9, +0x000157f7, +0x000157f5, +0x000157f4, +0x000157f1, +0x000157f0, +0x000157ef, +0x000157ec, +0x000157eb, +0x000157e9, +0x000157e6, +0x000157e5, +0x000157e2, +0x000157e1, +0x000157e0, +0x000157dd, +0x000157dc, +0x000157da, +0x000157d8, +0x000157d6, +0x000157d5, +0x000157d2, +0x000157d1, +0x000157d0, +0x000157cd, +0x000157cc, +0x000157ca, +0x000157c8, +0x000157c6, +0x000157c5, +0x000157c2, +0x000157c1, +0x000157c0, +0x000157bd, +0x000157bb, +0x000157ba, +0x000157b7, +0x000157b6, +0x000157b5, +0x000157b2, +0x000157b1, +0x000157af, +0x000157ad, +0x000157ab, +0x000157a9, +0x000157a7, +0x000157a6, +0x000157a3, +0x000157a2, +0x000157a1, +0x0001579e, +0x0001579d, +0x0001579b, +0x00015799, +0x00015797, +0x00015796, +0x00015793, +0x00015792, +0x0001578f, +0x0001578e, +0x0001578d, +0x0001578a, +0x00015789, +0x00015787, +0x00015785, +0x00015783, +0x00015782, +0x0001577f, +0x0001577e, +0x0001577d, +0x0001577a, +0x00015779, +0x00015777, +0x00015775, +0x00015773, +0x00015772, +0x0001576f, +0x0001576e, +0x0001576d, +0x0001576a, +0x00015769, +0x00015767, +0x00015764, +0x00015763, +0x00015762, +0x0001575f, +0x0001575e, +0x0001575c, +0x0001575a, +0x00015758, +0x00015757, +0x00015754, +0x00015753, +0x00015752, +0x0001574f, +0x0001574e, +0x0001574b, +0x0001574a, +0x00015748, +0x00015746, +0x00015744, +0x00015743, +0x00015740, +0x0001573f, +0x0001573e, +0x0001573b, +0x0001573a, +0x00015738, +0x00015736, +0x00015734, +0x00015733, +0x00015730, +0x0001572f, +0x0001572e, +0x0001572b, +0x0001572a, +0x00015728, +0x00015726, +0x00015724, +0x00015723, +0x00015720, +0x0001571f, +0x0001571d, +0x0001571b, +0x00015719, +0x00015718, +0x00015715, +0x00015714, +0x00015713, +0x00015710, +0x0001570f, +0x0001570d, +0x0001570b, +0x00015709, +0x00015708, +0x00015705, +0x00015704, +0x00015703, +0x00015700, +0x000156ff, +0x000156fd, +0x000156fb, +0x000156f9, +0x000156f8, +0x000156f5, +0x000156f4, +0x000156f3, +0x000156f0, +0x000156ef, +0x000156ec, +0x000156eb, +0x000156e9, +0x000156e7, +0x000156e5, +0x000156e4, +0x000156e1, +0x000156e0, +0x000156df, +0x000156dc, +0x000156da, +0x000156d9, +0x000156d6, +0x000156d5, +0x000156d4, +0x000156d1, +0x000156d0, +0x000156ce, +0x000156cc, +0x000156ca, +0x000156c9, +0x000156c6, +0x000156c5, +0x000156c4, +0x000156c1, +0x000156c0, +0x000156be, +0x000156bc, +0x000156ba, +0x000156b9, +0x000156b6, +0x000156b5, +0x000156b4, +0x000156b1, +0x000156b0, +0x000156ae, +0x000156ac, +0x000156aa, +0x000156a8, +0x000156a6, +0x000156a4, +0x000156a3, +0x000156a0, +0x0001569f, +0x0001569e, +0x0001569b, +0x0001569a, +0x00015698, +0x00015696, +0x00015694, +0x00015693, +0x00015690, +0x0001568f, +0x0001568e, +0x0001568b, +0x0001568a, +0x00015688, +0x00015686, +0x00015684, +0x00015683, +0x00015680, +0x0001567f, +0x0001567e, +0x0001567b, +0x0001567a, +0x00015678, +0x00015676, +0x00015674, +0x00015673, +0x00015670, +0x0001566f, +0x0001566e, +0x0001566b, +0x0001566a, +0x00015668, +0x00015666, +0x00015664, +0x00015663, +0x00015660, +0x0001565f, +0x0001565e, +0x0001565b, +0x0001565a, +0x00015658, +0x00015656, +0x00015654, +0x00015653, +0x00015650, +0x0001564f, +0x0001564d, +0x0001564b, +0x00015649, +0x00015648, +0x00015645, +0x00015644, +0x00015643, +0x00015640, +0x0001563f, +0x0001563d, +0x0001563b, +0x00015639, +0x00015638, +0x00015635, +0x00015634, +0x00015633, +0x00015630, +0x0001562f, +0x0001562d, +0x0001562b, +0x00015629, +0x00015628, +0x00015625, +0x00015624, +0x00015623, +0x00015620, +0x0001561f, +0x0001561d, +0x0001561b, +0x00015619, +0x00015618, +0x00015615, +0x00015614, +0x00015613, +0x00015610, +0x0001560f, +0x0001560d, +0x0001560b, +0x00015609, +0x00015608, +0x00015605, +0x00015604, +0x00015603, +0x00015600, +0x000155ff, +0x000155fd, +0x000155fb, +0x000155f9, +0x000155f8, +0x000155f5, +0x000155f4, +0x000155f3, +0x000155f0, +0x000155ef, +0x000155ed, +0x000155eb, +0x000155e9, +0x000155e8, +0x000155e5, +0x000155e4, +0x000155e3, +0x000155e0, +0x000155df, +0x000155dd, +0x000155db, +0x000155d9, +0x000155d8, +0x000155d5, +0x000155d4, +0x000155d3, +0x000155d0, +0x000155cf, +0x000155cd, +0x000155cb, +0x000155c9, +0x000155c6, +0x000155c5, +0x000155c4, +0x000155c1, +0x000155c0, +0x000155be, +0x000155bc, +0x000155ba, +0x000155b9, +0x000155b6, +0x000155b5, +0x000155b4, +0x000155b1, +0x000155b0, +0x000155ae, +0x000155ac, +0x000155ab, +0x000155a9, +0x000155a7, +0x000155a5, +0x000155a4, +0x000155a1, +0x000155a0, +0x0001559f, +0x0001559c, +0x0001559b, +0x00015599, +0x00015597, +0x00015595, +0x00015594, +0x00015591, +0x00015590, +0x0001558f, +0x0001558c, +0x0001558b, +0x00015589, +0x00015587, +0x00015585, +0x00015584, +0x00015581, +0x00015580, +0x0001557f, +0x0001557c, +0x0001557b, +0x00015579, +0x00015577, +0x00015575, +0x00015574, +0x00015571, +0x00015570, +0x0001556f, +0x0001556c, +0x0001556b, +0x00015569, +0x00015567, +0x00015565, +0x00015564, +0x00015561, +0x00015560, +0x0001555f, +0x0001555c, +0x0001555b, +0x00015559, +0x00015557, +0x00015555, +0x00015554, +0x00015551, +0x00015550, +0x0001554f, +0x0001554c, +0x0001554b, +0x00015549, +0x00015547, +0x00015545, +0x00015544, +0x00015541, +0x00015540, +0x0001553f, +0x0001553c, +0x0001553b, +0x00015539, +0x00015537, +0x00015535, +0x00015534, +0x00015531, +0x00015530, +0x0001552f, +0x0001552c, +0x0001552b, +0x00015529, +0x00015527, +0x00015525, +0x00015524, +0x00015521, +0x00015520, +0x0001551f, +0x0001551c, +0x0001551b, +0x00015519, +0x00015517, +0x00015515, +0x00015514, +0x00015511, +0x00015510, +0x0001550f, +0x0001550c, +0x0001550b, +0x00015509, +0x00015507, +0x00015505, +0x00015504, +0x00015501, +0x00015500, +0x000154ff, +0x000154fc, +0x000154fb, +0x000154f9, +0x000154f7, +0x000154f5, +0x000154f4, +0x000154f1, +0x000154f0, +0x000154ef, +0x000154ec, +0x000154eb, +0x000154e9, +0x000154e7, +0x000154e5, +0x000154e3, +0x000154e2, +0x000154df, +0x000154de, +0x000154dc, +0x000154da, +0x000154d8, +0x000154d7, +0x000154d5, +0x000154d3, +0x000154d2, +0x000154cf, +0x000154ce, +0x000154cd, +0x000154ca, +0x000154c9, +0x000154c7, +0x000154c5, +0x000154c3, +0x000154c2, +0x000154bf, +0x000154be, +0x000154bd, +0x000154ba, +0x000154b9, +0x000154b7, +0x000154b5, +0x000154b3, +0x000154b2, +0x000154af, +0x000154ae, +0x000154ad, +0x000154ab, +0x000154a9, +0x000154a7, +0x000154a6, +0x000154a3, +0x000154a2, +0x000154a1, +0x0001549e, +0x0001549d, +0x0001549b, +0x00015499, +0x00015497, +0x00015496, +0x00015493, +0x00015492, +0x00015491, +0x0001548e, +0x0001548d, +0x0001548b, +0x00015489, +0x00015487, +0x00015486, +0x00015483, +0x00015482, +0x00015481, +0x0001547e, +0x0001547d, +0x0001547c, +0x00015479, +0x00015478, +0x00015476, +0x00015474, +0x00015472, +0x00015471, +0x0001546e, +0x0001546d, +0x0001546c, +0x00015469, +0x00015468, +0x00015466, +0x00015464, +0x00015462, +0x00015461, +0x0001545e, +0x0001545d, +0x0001545c, +0x00015459, +0x00015458, +0x00015456, +0x00015454, +0x00015452, +0x00015451, +0x0001544e, +0x0001544d, +0x0001544c, +0x00015449, +0x00015448, +0x00015446, +0x00015444, +0x00015442, +0x00015441, +0x0001543e, +0x0001543d, +0x0001543c, +0x0001543a, +0x00015438, +0x00015436, +0x00015435, +0x00015432, +0x00015431, +0x00015430, +0x0001542d, +0x0001542c, +0x0001542b, +0x00015428, +0x00015427, +0x00015425, +0x00015423, +0x00015421, +0x00015420, +0x0001541d, +0x0001541c, +0x0001541b, +0x00015418, +0x00015417, +0x00015415, +0x00015413, +0x00015411, +0x00015410, +0x0001540d, +0x0001540c, +0x0001540b, +0x00015408, +0x00015407, +0x00015405, +0x00015403, +0x00015401, +0x00015400, +0x000153fd, +0x000153fc, +0x000153fb, +0x000153f8, +0x000153f7, +0x000153f5, +0x000153f3, +0x000153f1, +0x000153f0, +0x000153ed, +0x000153ec, +0x000153eb, +0x000153e8, +0x000153e7, +0x000153e5, +0x000153e3, +0x000153e1, +0x000153e0, +0x000153dd, +0x000153dc, +0x000153db, +0x000153d8, +0x000153d7, +0x000153d6, +0x000153d3, +0x000153d2, +0x000153d0, +0x000153ce, +0x000153cc, +0x000153cb, +0x000153ca, +0x000153c7, +0x000153c6, +0x000153c4, +0x000153c2, +0x000153c0, +0x000153bf, +0x000153bc, +0x000153bb, +0x000153ba, +0x000153b7, +0x000153b6, +0x000153b4, +0x000153b2, +0x000153b0, +0x000153af, +0x000153ac, +0x000153ab, +0x000153aa, +0x000153a7, +0x000153a6, +0x000153a4, +0x000153a2, +0x000153a0, +0x0001539f, +0x0001539c, +0x0001539b, +0x0001539a, +0x00015397, +0x00015396, +0x00015394, +0x00015392, +0x00015390, +0x0001538f, +0x0001538c, +0x0001538b, +0x0001538a, +0x00015387, +0x00015386, +0x00015384, +0x00015382, +0x00015381, +0x0001537f, +0x0001537d, +0x0001537b, +0x0001537a, +0x00015377, +0x00015376, +0x00015375, +0x00015372, +0x00015371, +0x0001536f, +0x0001536d, +0x0001536b, +0x0001536a, +0x00015367, +0x00015366, +0x00015365, +0x00015362, +0x00015361, +0x0001535f, +0x0001535d, +0x0001535b, +0x0001535a, +0x00015359, +0x00015356, +0x00015355, +0x00015353, +0x00015351, +0x0001534f, +0x0001534e, +0x0001534b, +0x0001534a, +0x00015349, +0x00015346, +0x00015345, +0x00015343, +0x00015341, +0x0001533f, +0x0001533e, +0x0001533b, +0x0001533a, +0x00015339, +0x00015336, +0x00015335, +0x00015333, +0x00015331, +0x0001532f, +0x0001532e, +0x0001532c, +0x0001532a, +0x00015329, +0x00015326, +0x00015325, +0x00015324, +0x00015321, +0x00015320, +0x0001531e, +0x0001531d, +0x0001531a, +0x00015319, +0x00015318, +0x00015315, +0x00015314, +0x00015313, +0x00015310, +0x0001530f, +0x0001530d, +0x0001530b, +0x00015309, +0x00015308, +0x00015305, +0x00015304, +0x00015303, +0x00015300, +0x000152ff, +0x000152fd, +0x000152fb, +0x000152f9, +0x000152f8, +0x000152f5, +0x000152f4, +0x000152f3, +0x000152f0, +0x000152ef, +0x000152ed, +0x000152ec, +0x000152e9, +0x000152e8, +0x000152e7, +0x000152e4, +0x000152e3, +0x000152e2, +0x000152df, +0x000152de, +0x000152dc, +0x000152da, +0x000152d8, +0x000152d7, +0x000152d4, +0x000152d3, +0x000152d2, +0x000152cf, +0x000152ce, +0x000152cc, +0x000152ca, +0x000152c8, +0x000152c7, +0x000152c4, +0x000152c3, +0x000152c2, +0x000152bf, +0x000152be, +0x000152bc, +0x000152ba, +0x000152b8, +0x000152b7, +0x000152b5, +0x000152b3, +0x000152b2, +0x000152b1, +0x000152ae, +0x000152ad, +0x000152ab, +0x000152a9, +0x000152a7, +0x000152a6, +0x000152a3, +0x000152a2, +0x000152a1, +0x0001529e, +0x0001529d, +0x0001529b, +0x00015299, +0x00015297, +0x00015296, +0x00015293, +0x00015292, +0x00015291, +0x0001528e, +0x0001528d, +0x0001528b, +0x00015289, +0x00015287, +0x00015286, +0x00015284, +0x00015282, +0x00015281, +0x0001527e, +0x0001527d, +0x0001527c, +0x00015279, +0x00015278, +0x00015276, +0x00015274, +0x00015272, +0x00015271, +0x00015270, +0x0001526d, +0x0001526c, +0x0001526a, +0x00015268, +0x00015266, +0x00015265, +0x00015262, +0x00015261, +0x00015260, +0x0001525d, +0x0001525c, +0x0001525a, +0x00015258, +0x00015257, +0x00015255, +0x00015253, +0x00015251, +0x00015250, +0x0001524d, +0x0001524c, +0x0001524b, +0x00015248, +0x00015247, +0x00015245, +0x00015243, +0x00015241, +0x00015241, +0x0001523e, +0x0001523d, +0x0001523b, +0x00015239, +0x00015237, +0x00015236, +0x00015233, +0x00015232, +0x00015231, +0x0001522e, +0x0001522d, +0x0001522c, +0x00015229, +0x00015228, +0x00015226, +0x00015224, +0x00015222, +0x00015221, +0x0001521e, +0x0001521d, +0x0001521c, +0x00015219, +0x00015218, +0x00015216, +0x00015214, +0x00015212, +0x00015211, +0x00015210, +0x0001520d, +0x0001520c, +0x0001520b, +0x00015208, +0x00015207, +0x00015205, +0x00015203, +0x00015201, +0x00015200, +0x000151fd, +0x000151fc, +0x000151fb, +0x000151f8, +0x000151f7, +0x000151f5, +0x000151f3, +0x000151f1, +0x000151f0, +0x000151ee, +0x000151ec, +0x000151eb, +0x000151e8, +0x000151e7, +0x000151e6, +0x000151e4, +0x000151e2, +0x000151e0, +0x000151df, +0x000151dc, +0x000151db, +0x000151da, +0x000151d7, +0x000151d6, +0x000151d4, +0x000151d2, +0x000151d0, +0x000151cf, +0x000151cd, +0x000151cb, +0x000151ca, +0x000151c7, +0x000151c6, +0x000151c5, +0x000151c2, +0x000151c1, +0x000151bf, +0x000151bd, +0x000151bb, +0x000151ba, +0x000151b9, +0x000151b6, +0x000151b5, +0x000151b3, +0x000151b1, +0x000151af, +0x000151ae, +0x000151ac, +0x000151aa, +0x000151a9, +0x000151a6, +0x000151a5, +0x000151a4, +0x000151a1, +0x000151a0, +0x0001519e, +0x0001519c, +0x0001519a, +0x00015199, +0x00015196, +0x00015195, +0x00015194, +0x00015191, +0x00015190, +0x0001518e, +0x0001518d, +0x0001518a, +0x00015189, +0x00015188, +0x00015185, +0x00015184, +0x00015183, +0x00015180, +0x0001517f, +0x0001517d, +0x0001517b, +0x00015179, +0x00015178, +0x00015175, +0x00015174, +0x00015173, +0x00015170, +0x0001516f, +0x0001516d, +0x0001516b, +0x00015169, +0x00015168, +0x00015166, +0x00015164, +0x00015163, +0x00015161, +0x0001515f, +0x0001515d, +0x0001515c, +0x0001515a, +0x00015158, +0x00015157, +0x00015156, +0x00015153, +0x00015152, +0x00015150, +0x0001514e, +0x0001514c, +0x0001514b, +0x00015148, +0x00015147, +0x00015146, +0x00015143, +0x00015142, +0x00015141, +0x0001513e, +0x0001513d, +0x0001513b, +0x00015139, +0x00015137, +0x00015136, +0x00015135, +0x00015132, +0x00015131, +0x0001512f, +0x0001512d, +0x0001512b, +0x0001512a, +0x00015127, +0x00015126, +0x00015125, +0x00015122, +0x00015121, +0x00015120, +0x0001511d, +0x0001511c, +0x0001511a, +0x00015118, +0x00015116, +0x00015115, +0x00015114, +0x00015111, +0x00015110, +0x0001510e, +0x0001510c, +0x0001510b, +0x00015109, +0x00015107, +0x00015105, +0x00015104, +0x00015101, +0x00015100, +0x000150ff, +0x000150fc, +0x000150fb, +0x000150f9, +0x000150f7, +0x000150f5, +0x000150f4, +0x000150f3, +0x000150f0, +0x000150ef, +0x000150ee, +0x000150eb, +0x000150ea, +0x000150e8, +0x000150e6, +0x000150e4, +0x000150e3, +0x000150e0, +0x000150df, +0x000150de, +0x000150db, +0x000150da, +0x000150d9, +0x000150d6, +0x000150d5, +0x000150d3, +0x000150d1, +0x000150cf, +0x000150ce, +0x000150cd, +0x000150ca, +0x000150c9, +0x000150c7, +0x000150c5, +0x000150c3, +0x000150c2, +0x000150bf, +0x000150be, +0x000150bd, +0x000150ba, +0x000150b9, +0x000150b8, +0x000150b5, +0x000150b4, +0x000150b2, +0x000150b0, +0x000150ae, +0x000150ad, +0x000150ac, +0x000150a9, +0x000150a8, +0x000150a6, +0x000150a4, +0x000150a3, +0x000150a1, +0x0001509f, +0x0001509d, +0x0001509c, +0x00015099, +0x00015098, +0x00015097, +0x00015094, +0x00015093, +0x00015091, +0x0001508f, +0x0001508d, +0x0001508c, +0x0001508b, +0x00015088, +0x00015087, +0x00015086, +0x00015083, +0x00015082, +0x0001507f, +0x0001507e, +0x0001507d, +0x0001507a, +0x00015079, +0x00015077, +0x00015076, +0x00015074, +0x00015072, +0x00015071, +0x0001506e, +0x0001506d, +0x0001506c, +0x00015069, +0x00015068, +0x00015066, +0x00015064, +0x00015062, +0x00015061, +0x0001505f, +0x0001505d, +0x0001505c, +0x0001505b, +0x00015058, +0x00015057, +0x00015055, +0x00015053, +0x00015051, +0x00015050, +0x0001504d, +0x0001504c, +0x0001504b, +0x00015048, +0x00015047, +0x00015046, +0x00015043, +0x00015042, +0x00015040, +0x0001503f, +0x0001503c, +0x0001503b, +0x0001503a, +0x00015037, +0x00015036, +0x00015035, +0x00015032, +0x00015031, +0x0001502f, +0x0001502d, +0x0001502b, +0x0001502a, +0x00015027, +0x00015026, +0x00015025, +0x00015023, +0x00015021, +0x00015020, +0x0001501e, +0x0001501c, +0x0001501a, +0x00015019, +0x00015016, +0x00015015, +0x00015014, +0x00015011, +0x00015010, +0x0001500e, +0x0001500c, +0x0001500b, +0x00015009, +0x00015008, +0x00015005, +0x00015004, +0x00015003, +0x00015000, +0x00014fff, +0x00014ffd, +0x00014ffb, +0x00014ff9, +0x00014ff8, +0x00014ff6, +0x00014ff4, +0x00014ff3, +0x00014ff0, +0x00014fef, +0x00014fee, +0x00014fec, +0x00014fea, +0x00014fe8, +0x00014fe7, +0x00014fe4, +0x00014fe3, +0x00014fe2, +0x00014fdf, +0x00014fde, +0x00014fdd, +0x00014fda, +0x00014fd9, +0x00014fd7, +0x00014fd5, +0x00014fd3, +0x00014fd2, +0x00014fd1, +0x00014fce, +0x00014fcd, +0x00014fcc, +0x00014fc9, +0x00014fc8, +0x00014fc6, +0x00014fc4, +0x00014fc2, +0x00014fc1, +0x00014fbe, +0x00014fbd, +0x00014fbc, +0x00014fb9, +0x00014fb8, +0x00014fb7, +0x00014fb5, +0x00014fb3, +0x00014fb1, +0x00014fb0, +0x00014fad, +0x00014fac, +0x00014fab, +0x00014fa8, +0x00014fa6, +0x00014fa5, +0x00014fa4, +0x00014fa1, +0x00014fa0, +0x00014f9e, +0x00014f9c, +0x00014f9a, +0x00014f99, +0x00014f96, +0x00014f95, +0x00014f94, +0x00014f93, +0x00014f90, +0x00014f8f, +0x00014f8d, +0x00014f8b, +0x00014f89, +0x00014f88, +0x00014f85, +0x00014f84, +0x00014f83, +0x00014f80, +0x00014f7f, +0x00014f7e, +0x00014f7c, +0x00014f7a, +0x00014f78, +0x00014f77, +0x00014f74, +0x00014f73, +0x00014f72, +0x00014f6f, +0x00014f6e, +0x00014f6d, +0x00014f6a, +0x00014f69, +0x00014f67, +0x00014f66, +0x00014f63, +0x00014f62, +0x00014f61, +0x00014f5e, +0x00014f5d, +0x00014f5c, +0x00014f59, +0x00014f58, +0x00014f56, +0x00014f54, +0x00014f52, +0x00014f51, +0x00014f50, +0x00014f4d, +0x00014f4c, +0x00014f4b, +0x00014f48, +0x00014f47, +0x00014f45, +0x00014f43, +0x00014f41, +0x00014f40, +0x00014f3e, +0x00014f3c, +0x00014f3b, +0x00014f3a, +0x00014f37, +0x00014f36, +0x00014f34, +0x00014f32, +0x00014f30, +0x00014f2f, +0x00014f2c, +0x00014f2b, +0x00014f2a, +0x00014f27, +0x00014f26, +0x00014f25, +0x00014f22, +0x00014f21, +0x00014f1f, +0x00014f1e, +0x00014f1b, +0x00014f1a, +0x00014f19, +0x00014f16, +0x00014f15, +0x00014f14, +0x00014f11, +0x00014f10, +0x00014f0e, +0x00014f0c, +0x00014f0a, +0x00014f09, +0x00014f08, +0x00014f05, +0x00014f04, +0x00014f03, +0x00014f00, +0x00014eff, +0x00014efd, +0x00014efb, +0x00014ef9, +0x00014ef8, +0x00014ef6, +0x00014ef4, +0x00014ef3, +0x00014ef2, +0x00014eef, +0x00014eee, +0x00014eec, +0x00014eea, +0x00014ee8, +0x00014ee7, +0x00014ee5, +0x00014ee3, +0x00014ee2, +0x00014edf, +0x00014ede, +0x00014edd, +0x00014edb, +0x00014ed9, +0x00014ed7, +0x00014ed6, +0x00014ed4, +0x00014ed2, +0x00014ed1, +0x00014ece, +0x00014ecd, +0x00014ecc, +0x00014ec9, +0x00014ec8, +0x00014ec6, +0x00014ec4, +0x00014ec2, +0x00014ec1, +0x00014ebe, +0x00014ebd, +0x00014ebc, +0x00014eb9, +0x00014eb8, +0x00014eb7, +0x00014eb5, +0x00014eb3, +0x00014eb1, +0x00014eb0, +0x00014eae, +0x00014eac, +0x00014eab, +0x00014ea8, +0x00014ea7, +0x00014ea6, +0x00014ea3, +0x00014ea2, +0x00014ea0, +0x00014e9f, +0x00014e9d, +0x00014e9b, +0x00014e9a, +0x00014e97, +0x00014e96, +0x00014e95, +0x00014e92, +0x00014e91, +0x00014e90, +0x00014e8e, +0x00014e8c, +0x00014e8a, +0x00014e89, +0x00014e86, +0x00014e85, +0x00014e84, +0x00014e81, +0x00014e80, +0x00014e7f, +0x00014e7c, +0x00014e7b, +0x00014e79, +0x00014e78, +0x00014e75, +0x00014e74, +0x00014e73, +0x00014e70, +0x00014e6f, +0x00014e6e, +0x00014e6b, +0x00014e6a, +0x00014e68, +0x00014e67, +0x00014e64, +0x00014e63, +0x00014e62, +0x00014e5f, +0x00014e5e, +0x00014e5d, +0x00014e5a, +0x00014e59, +0x00014e57, +0x00014e55, +0x00014e54, +0x00014e52, +0x00014e51, +0x00014e4e, +0x00014e4d, +0x00014e4c, +0x00014e49, +0x00014e48, +0x00014e46, +0x00014e44, +0x00014e43, +0x00014e41, +0x00014e40, +0x00014e3d, +0x00014e3c, +0x00014e3b, +0x00014e38, +0x00014e37, +0x00014e35, +0x00014e33, +0x00014e32, +0x00014e30, +0x00014e2e, +0x00014e2c, +0x00014e2b, +0x00014e2a, +0x00014e27, +0x00014e26, +0x00014e25, +0x00014e22, +0x00014e21, +0x00014e1f, +0x00014e1d, +0x00014e1b, +0x00014e1a, +0x00014e19, +0x00014e16, +0x00014e15, +0x00014e14, +0x00014e11, +0x00014e10, +0x00014e0e, +0x00014e0c, +0x00014e0a, +0x00014e09, +0x00014e07, +0x00014e05, +0x00014e04, +0x00014e03, +0x00014e00, +0x00014dff, +0x00014dfd, +0x00014dfb, +0x00014df9, +0x00014df8, +0x00014df6, +0x00014df4, +0x00014df3, +0x00014df2, +0x00014def, +0x00014dee, +0x00014dec, +0x00014dea, +0x00014de9, +0x00014de7, +0x00014de5, +0x00014de3, +0x00014de2, +0x00014ddf, +0x00014dde, +0x00014ddd, +0x00014ddb, +0x00014dd9, +0x00014dd8, +0x00014dd6, +0x00014dd4, +0x00014dd2, +0x00014dd1, +0x00014dce, +0x00014dcd, +0x00014dcc, +0x00014dc9, +0x00014dc8, +0x00014dc7, +0x00014dc5, +0x00014dc3, +0x00014dc1, +0x00014dc0, +0x00014dbd, +0x00014dbc, +0x00014dbb, +0x00014db8, +0x00014db7, +0x00014db6, +0x00014db4, +0x00014db2, +0x00014db0, +0x00014daf, +0x00014dad, +0x00014dab, +0x00014daa, +0x00014da7, +0x00014da6, +0x00014da5, +0x00014da2, +0x00014da1, +0x00014d9f, +0x00014d9e, +0x00014d9c, +0x00014d9a, +0x00014d99, +0x00014d96, +0x00014d95, +0x00014d94, +0x00014d91, +0x00014d90, +0x00014d8e, +0x00014d8d, +0x00014d8b, +0x00014d89, +0x00014d88, +0x00014d85, +0x00014d84, +0x00014d83, +0x00014d80, +0x00014d7f, +0x00014d7e, +0x00014d7b, +0x00014d7a, +0x00014d78, +0x00014d77, +0x00014d74, +0x00014d73, +0x00014d72, +0x00014d6f, +0x00014d6e, +0x00014d6d, +0x00014d6a, +0x00014d69, +0x00014d67, +0x00014d66, +0x00014d63, +0x00014d62, +0x00014d61, +0x00014d5e, +0x00014d5d, +0x00014d5c, +0x00014d59, +0x00014d58, +0x00014d56, +0x00014d54, +0x00014d52, +0x00014d51, +0x00014d50, +0x00014d4d, +0x00014d4c, +0x00014d4b, +0x00014d48, +0x00014d47, +0x00014d45, +0x00014d43, +0x00014d42, +0x00014d40, +0x00014d3f, +0x00014d3c, +0x00014d3b, +0x00014d3a, +0x00014d37, +0x00014d36, +0x00014d34, +0x00014d32, +0x00014d31, +0x00014d2f, +0x00014d2d, +0x00014d2b, +0x00014d2a, +0x00014d29, +0x00014d26, +0x00014d25, +0x00014d24, +0x00014d21, +0x00014d20, +0x00014d1e, +0x00014d1c, +0x00014d1a, +0x00014d19, +0x00014d17, +0x00014d16, +0x00014d15, +0x00014d12, +0x00014d11, +0x00014d10, +0x00014d0d, +0x00014d0c, +0x00014d0a, +0x00014d09, +0x00014d07, +0x00014d05, +0x00014d04, +0x00014d01, +0x00014d00, +0x00014cff, +0x00014cfc, +0x00014cfb, +0x00014cf9, +0x00014cf8, +0x00014cf6, +0x00014cf4, +0x00014cf3, +0x00014cf0, +0x00014cef, +0x00014cee, +0x00014ceb, +0x00014cea, +0x00014ce9, +0x00014ce7, +0x00014ce5, +0x00014ce3, +0x00014ce2, +0x00014cdf, +0x00014cde, +0x00014cdd, +0x00014cda, +0x00014cd9, +0x00014cd8, +0x00014cd6, +0x00014cd4, +0x00014cd2, +0x00014cd1, +0x00014ccf, +0x00014ccd, +0x00014ccc, +0x00014cc9, +0x00014cc8, +0x00014cc7, +0x00014cc5, +0x00014cc3, +0x00014cc2, +0x00014cc0, +0x00014cbe, +0x00014cbc, +0x00014cbb, +0x00014cb8, +0x00014cb7, +0x00014cb6, +0x00014cb5, +0x00014cb2, +0x00014cb1, +0x00014caf, +0x00014cad, +0x00014cab, +0x00014caa, +0x00014ca8, +0x00014ca6, +0x00014ca5, +0x00014ca2, +0x00014ca1, +0x00014ca0, +0x00014c9e, +0x00014c9c, +0x00014c9b, +0x00014c99, +0x00014c97, +0x00014c95, +0x00014c94, +0x00014c91, +0x00014c90, +0x00014c8f, +0x00014c8e, +0x00014c8b, +0x00014c8a, +0x00014c88, +0x00014c86, +0x00014c84, +0x00014c83, +0x00014c81, +0x00014c7f, +0x00014c7e, +0x00014c7d, +0x00014c7a, +0x00014c79, +0x00014c77, +0x00014c75, +0x00014c74, +0x00014c72, +0x00014c70, +0x00014c6e, +0x00014c6d, +0x00014c6c, +0x00014c69, +0x00014c68, +0x00014c67, +0x00014c64, +0x00014c63, +0x00014c61, +0x00014c5f, +0x00014c5d, +0x00014c5c, +0x00014c5b, +0x00014c58, +0x00014c57, +0x00014c56, +0x00014c53, +0x00014c52, +0x00014c50, +0x00014c4e, +0x00014c4c, +0x00014c4b, +0x00014c4a, +0x00014c47, +0x00014c46, +0x00014c45, +0x00014c42, +0x00014c41, +0x00014c40, +0x00014c3e, +0x00014c3c, +0x00014c3a, +0x00014c39, +0x00014c38, +0x00014c35, +0x00014c34, +0x00014c33, +0x00014c30, +0x00014c2f, +0x00014c2d, +0x00014c2b, +0x00014c2a, +0x00014c28, +0x00014c27, +0x00014c24, +0x00014c23, +0x00014c22, +0x00014c1f, +0x00014c1e, +0x00014c1d, +0x00014c1a, +0x00014c19, +0x00014c17, +0x00014c16, +0x00014c13, +0x00014c12, +0x00014c11, +0x00014c0e, +0x00014c0d, +0x00014c0c, +0x00014c0a, +0x00014c08, +0x00014c06, +0x00014c05, +0x00014c03, +0x00014c01, +0x00014c00, +0x00014bfd, +0x00014bfc, +0x00014bfb, +0x00014bfa, +0x00014bf7, +0x00014bf6, +0x00014bf4, +0x00014bf2, +0x00014bf0, +0x00014bef, +0x00014bed, +0x00014beb, +0x00014bea, +0x00014be9, +0x00014be6, +0x00014be5, +0x00014be3, +0x00014be1, +0x00014be0, +0x00014bde, +0x00014bdc, +0x00014bda, +0x00014bd9, +0x00014bd8, +0x00014bd5, +0x00014bd4, +0x00014bd3, +0x00014bd0, +0x00014bcf, +0x00014bcd, +0x00014bcc, +0x00014bca, +0x00014bc8, +0x00014bc7, +0x00014bc4, +0x00014bc3, +0x00014bc2, +0x00014bbf, +0x00014bbe, +0x00014bbd, +0x00014bbb, +0x00014bb9, +0x00014bb7, +0x00014bb6, +0x00014bb3, +0x00014bb2, +0x00014bb1, +0x00014bae, +0x00014bad, +0x00014bac, +0x00014baa, +0x00014ba8, +0x00014ba7, +0x00014ba5, +0x00014ba3, +0x00014ba1, +0x00014ba0, +0x00014b9f, +0x00014b9c, +0x00014b9b, +0x00014b9a, +0x00014b97, +0x00014b96, +0x00014b94, +0x00014b92, +0x00014b90, +0x00014b8f, +0x00014b8e, +0x00014b8b, +0x00014b8a, +0x00014b89, +0x00014b86, +0x00014b85, +0x00014b84, +0x00014b81, +0x00014b80, +0x00014b7e, +0x00014b7d, +0x00014b7a, +0x00014b79, +0x00014b78, +0x00014b75, +0x00014b74, +0x00014b73, +0x00014b70, +0x00014b6f, +0x00014b6d, +0x00014b6c, +0x00014b6a, +0x00014b69, +0x00014b66, +0x00014b65, +0x00014b64, +0x00014b62, +0x00014b60, +0x00014b5e, +0x00014b5d, +0x00014b5b, +0x00014b59, +0x00014b58, +0x00014b57, +0x00014b54, +0x00014b53, +0x00014b51, +0x00014b4f, +0x00014b4e, +0x00014b4c, +0x00014b4a, +0x00014b48, +0x00014b47, +0x00014b46, +0x00014b43, +0x00014b42, +0x00014b41, +0x00014b3e, +0x00014b3d, +0x00014b3b, +0x00014b3a, +0x00014b38, +0x00014b36, +0x00014b35, +0x00014b32, +0x00014b31, +0x00014b30, +0x00014b2d, +0x00014b2c, +0x00014b2b, +0x00014b29, +0x00014b27, +0x00014b25, +0x00014b24, +0x00014b22, +0x00014b20, +0x00014b1f, +0x00014b1e, +0x00014b1b, +0x00014b1a, +0x00014b19, +0x00014b16, +0x00014b15, +0x00014b13, +0x00014b12, +0x00014b10, +0x00014b0e, +0x00014b0d, +0x00014b0a, +0x00014b09, +0x00014b08, +0x00014b05, +0x00014b04, +0x00014b03, +0x00014b01, +0x00014aff, +0x00014afd, +0x00014afc, +0x00014afa, +0x00014af8, +0x00014af7, +0x00014af6, +0x00014af3, +0x00014af2, +0x00014af0, +0x00014aee, +0x00014aed, +0x00014aeb, +0x00014ae9, +0x00014ae7, +0x00014ae6, +0x00014ae5, +0x00014ae2, +0x00014ae1, +0x00014ae0, +0x00014add, +0x00014adc, +0x00014adb, +0x00014ad9, +0x00014ad7, +0x00014ad5, +0x00014ad4, +0x00014ad1, +0x00014ad0, +0x00014acf, +0x00014ace, +0x00014acb, +0x00014aca, +0x00014ac8, +0x00014ac6, +0x00014ac5, +0x00014ac3, +0x00014ac1, +0x00014abf, +0x00014abe, +0x00014abd, +0x00014aba, +0x00014ab9, +0x00014ab8, +0x00014ab5, +0x00014ab4, +0x00014ab2, +0x00014ab1, +0x00014aaf, +0x00014aad, +0x00014aac, +0x00014aa9, +0x00014aa8, +0x00014aa7, +0x00014aa4, +0x00014aa3, +0x00014aa2, +0x00014aa0, +0x00014a9e, +0x00014a9c, +0x00014a9b, +0x00014a99, +0x00014a97, +0x00014a96, +0x00014a95, +0x00014a93, +0x00014a90, +0x00014a8f, +0x00014a8e, +0x00014a8b, +0x00014a8a, +0x00014a89, +0x00014a86, +0x00014a85, +0x00014a83, +0x00014a82, +0x00014a80, +0x00014a7e, +0x00014a7d, +0x00014a7a, +0x00014a79, +0x00014a78, +0x00014a77, +0x00014a74, +0x00014a73, +0x00014a71, +0x00014a6f, +0x00014a6e, +0x00014a6c, +0x00014a6b, +0x00014a68, +0x00014a67, +0x00014a66, +0x00014a63, +0x00014a62, +0x00014a61, +0x00014a5f, +0x00014a5d, +0x00014a5c, +0x00014a5a, +0x00014a58, +0x00014a56, +0x00014a55, +0x00014a54, +0x00014a51, +0x00014a50, +0x00014a4f, +0x00014a4c, +0x00014a4b, +0x00014a49, +0x00014a47, +0x00014a46, +0x00014a44, +0x00014a43, +0x00014a40, +0x00014a3f, +0x00014a3e, +0x00014a3b, +0x00014a3a, +0x00014a39, +0x00014a37, +0x00014a35, +0x00014a34, +0x00014a32, +0x00014a30, +0x00014a2e, +0x00014a2d, +0x00014a2c, +0x00014a29, +0x00014a28, +0x00014a27, +0x00014a24, +0x00014a23, +0x00014a22, +0x00014a20, +0x00014a1e, +0x00014a1c, +0x00014a1b, +0x00014a18, +0x00014a17, +0x00014a16, +0x00014a15, +0x00014a12, +0x00014a11, +0x00014a0f, +0x00014a0d, +0x00014a0c, +0x00014a0a, +0x00014a09, +0x00014a06, +0x00014a05, +0x00014a04, +0x00014a01, +0x00014a00, +0x000149ff, +0x000149fc, +0x000149fb, +0x000149fa, +0x000149f8, +0x000149f6, +0x000149f4, +0x000149f3, +0x000149f1, +0x000149ef, +0x000149ee, +0x000149ed, +0x000149ea, +0x000149e9, +0x000149e8, +0x000149e5, +0x000149e4, +0x000149e2, +0x000149e1, +0x000149de, +0x000149dd, +0x000149dc, +0x000149d9, +0x000149d8, +0x000149d7, +0x000149d5, +0x000149d3, +0x000149d2, +0x000149d0, +0x000149ce, +0x000149cc, +0x000149cb, +0x000149ca, +0x000149c7, +0x000149c6, +0x000149c5, +0x000149c2, +0x000149c1, +0x000149c0, +0x000149bd, +0x000149bc, +0x000149ba, +0x000149b8, +0x000149b6, +0x000149b5, +0x000149b4, +0x000149b1, +0x000149b0, +0x000149af, +0x000149ac, +0x000149ab, +0x000149aa, +0x000149a8, +0x000149a6, +0x000149a5, +0x000149a3, +0x000149a1, +0x0001499f, +0x0001499e, +0x0001499d, +0x0001499a, +0x00014999, +0x00014998, +0x00014995, +0x00014994, +0x00014993, +0x00014991, +0x0001498f, +0x0001498d, +0x0001498c, +0x0001498a, +0x00014988, +0x00014987, +0x00014986, +0x00014983, +0x00014982, +0x00014981, +0x0001497e, +0x0001497d, +0x0001497b, +0x0001497a, +0x00014978, +0x00014976, +0x00014975, +0x00014972, +0x00014971, +0x00014970, +0x0001496f, +0x0001496c, +0x0001496b, +0x00014969, +0x00014967, +0x00014966, +0x00014964, +0x00014963, +0x00014960, +0x0001495f, +0x0001495e, +0x0001495b, +0x0001495a, +0x00014959, +0x00014957, +0x00014955, +0x00014954, +0x00014952, +0x00014950, +0x0001494e, +0x0001494d, +0x0001494c, +0x00014949, +0x00014948, +0x00014947, +0x00014944, +0x00014943, +0x00014942, +0x00014940, +0x0001493e, +0x0001493c, +0x0001493b, +0x00014939, +0x00014937, +0x00014936, +0x00014935, +0x00014932, +0x00014931, +0x00014930, +0x0001492d, +0x0001492c, +0x0001492a, +0x00014929, +0x00014927, +0x00014925, +0x00014924, +0x00014921, +0x00014920, +0x0001491f, +0x0001491e, +0x0001491b, +0x0001491a, +0x00014918, +0x00014916, +0x00014915, +0x00014913, +0x00014912, +0x0001490f, +0x0001490e, +0x0001490d, +0x0001490a, +0x00014909, +0x00014908, +0x00014906, +0x00014904, +0x00014903, +0x00014901, +0x000148ff, +0x000148fd, +0x000148fc, +0x000148fb, +0x000148f8, +0x000148f7, +0x000148f6, +0x000148f3, +0x000148f2, +0x000148f1, +0x000148ef, +0x000148ed, +0x000148eb, +0x000148ea, +0x000148e8, +0x000148e6, +0x000148e5, +0x000148e4, +0x000148e1, +0x000148e0, +0x000148df, +0x000148dc, +0x000148db, +0x000148d9, +0x000148d8, +0x000148d6, +0x000148d4, +0x000148d3, +0x000148d0, +0x000148cf, +0x000148ce, +0x000148cd, +0x000148ca, +0x000148c9, +0x000148c7, +0x000148c5, +0x000148c4, +0x000148c2, +0x000148c1, +0x000148be, +0x000148bd, +0x000148bc, +0x000148b9, +0x000148b8, +0x000148b7, +0x000148b5, +0x000148b3, +0x000148b2, +0x000148b0, +0x000148ae, +0x000148ac, +0x000148ab, +0x000148aa, +0x000148a7, +0x000148a6, +0x000148a5, +0x000148a2, +0x000148a1, +0x000148a0, +0x0001489e, +0x0001489c, +0x0001489a, +0x00014899, +0x00014897, +0x00014895, +0x00014894, +0x00014893, +0x00014890, +0x0001488f, +0x0001488e, +0x0001488b, +0x0001488a, +0x00014888, +0x00014887, +0x00014885, +0x00014883, +0x00014882, +0x00014881, +0x0001487e, +0x0001487d, +0x0001487c, +0x00014879, +0x00014878, +0x00014876, +0x00014875, +0x00014873, +0x00014871, +0x00014870, +0x0001486d, +0x0001486c, +0x0001486b, +0x0001486a, +0x00014867, +0x00014866, +0x00014864, +0x00014862, +0x00014861, +0x0001485f, +0x0001485e, +0x0001485c, +0x0001485a, +0x00014859, +0x00014856, +0x00014855, +0x00014854, +0x00014853, +0x00014850, +0x0001484f, +0x0001484d, +0x0001484b, +0x0001484a, +0x00014848, +0x00014847, +0x00014844, +0x00014843, +0x00014842, +0x0001483f, +0x0001483e, +0x0001483d, +0x0001483b, +0x00014839, +0x00014838, +0x00014836, +0x00014834, +0x00014832, +0x00014831, +0x00014830, +0x0001482d, +0x0001482c, +0x0001482b, +0x00014828, +0x00014827, +0x00014826, +0x00014824, +0x00014822, +0x00014820, +0x0001481f, +0x0001481d, +0x0001481b, +0x0001481a, +0x00014819, +0x00014817, +0x00014816, +0x00014813, +0x00014812, +0x00014811, +0x0001480f, +0x0001480d, +0x0001480c, +0x0001480a, +0x00014808, +0x00014806, +0x00014805, +0x00014804, +0x00014801, +0x00014800, +0x000147ff, +0x000147fd, +0x000147fb, +0x000147fa, +0x000147f8, +0x000147f6, +0x000147f4, +0x000147f3, +0x000147f2, +0x000147ef, +0x000147ee, +0x000147ed, +0x000147ea, +0x000147e9, +0x000147e8, +0x000147e6, +0x000147e4, +0x000147e3, +0x000147e1, +0x000147df, +0x000147dd, +0x000147dc, +0x000147db, +0x000147d8, +0x000147d7, +0x000147d6, +0x000147d3, +0x000147d2, +0x000147d1, +0x000147cf, +0x000147cd, +0x000147cb, +0x000147ca, +0x000147c9, +0x000147c6, +0x000147c5, +0x000147c4, +0x000147c1, +0x000147c0, +0x000147bf, +0x000147bd, +0x000147bb, +0x000147ba, +0x000147b8, +0x000147b6, +0x000147b4, +0x000147b3, +0x000147b2, +0x000147af, +0x000147ae, +0x000147ad, +0x000147aa, +0x000147a9, +0x000147a8, +0x000147a6, +0x000147a4, +0x000147a2, +0x000147a1, +0x0001479f, +0x0001479d, +0x0001479c, +0x0001479b, +0x00014798, +0x00014797, +0x00014796, +0x00014794, +0x00014792, +0x00014791, +0x0001478f, +0x0001478d, +0x0001478b, +0x0001478a, +0x00014789, +0x00014786, +0x00014785, +0x00014784, +0x00014781, +0x00014780, +0x0001477f, +0x0001477d, +0x0001477b, +0x00014779, +0x00014778, +0x00014776, +0x00014774, +0x00014773, +0x00014772, +0x0001476f, +0x0001476e, +0x0001476d, +0x0001476a, +0x00014769, +0x00014768, +0x00014766, +0x00014764, +0x00014762, +0x00014761, +0x00014760, +0x0001475d, +0x0001475c, +0x0001475b, +0x00014758, +0x00014757, +0x00014756, +0x00014754, +0x00014752, +0x00014750, +0x0001474f, +0x0001474d, +0x0001474b, +0x0001474a, +0x00014749, +0x00014746, +0x00014745, +0x00014744, +0x00014742, +0x00014740, +0x0001473f, +0x0001473d, +0x0001473c, +0x00014739, +0x00014738, +0x00014737, +0x00014734, +0x00014733, +0x00014732, +0x00014731, +0x0001472e, +0x0001472d, +0x0001472b, +0x0001472a, +0x00014728, +0x00014726, +0x00014725, +0x00014722, +0x00014721, +0x00014720, +0x0001471f, +0x0001471c, +0x0001471b, +0x0001471a, +0x00014717, +0x00014716, +0x00014714, +0x00014713, +0x00014711, +0x0001470f, +0x0001470e, +0x0001470d, +0x0001470a, +0x00014709, +0x00014708, +0x00014705, +0x00014704, +0x00014703, +0x00014701, +0x000146ff, +0x000146fd, +0x000146fc, +0x000146fa, +0x000146f8, +0x000146f7, +0x000146f6, +0x000146f3, +0x000146f2, +0x000146f1, +0x000146ef, +0x000146ed, +0x000146ec, +0x000146ea, +0x000146e8, +0x000146e6, +0x000146e5, +0x000146e4, +0x000146e1, +0x000146e0, +0x000146df, +0x000146de, +0x000146db, +0x000146da, +0x000146d8, +0x000146d6, +0x000146d5, +0x000146d3, +0x000146d2, +0x000146cf, +0x000146ce, +0x000146cd, +0x000146ca, +0x000146c9, +0x000146c8, +0x000146c7, +0x000146c4, +0x000146c3, +0x000146c1, +0x000146c0, +0x000146be, +0x000146bc, +0x000146bb, +0x000146b8, +0x000146b7, +0x000146b6, +0x000146b5, +0x000146b2, +0x000146b1, +0x000146b0, +0x000146ad, +0x000146ac, +0x000146aa, +0x000146a9, +0x000146a7, +0x000146a5, +0x000146a4, +0x000146a3, +0x000146a0, +0x0001469f, +0x0001469e, +0x0001469b, +0x0001469a, +0x00014699, +0x00014697, +0x00014695, +0x00014693, +0x00014692, +0x00014690, +0x0001468e, +0x0001468d, +0x0001468c, +0x00014689, +0x00014688, +0x00014687, +0x00014685, +0x00014683, +0x00014682, +0x00014680, +0x0001467e, +0x0001467c, +0x0001467b, +0x0001467a, +0x00014677, +0x00014676, +0x00014675, +0x00014673, +0x00014671, +0x00014670, +0x0001466e, +0x0001466c, +0x0001466b, +0x0001466a, +0x00014667, +0x00014666, +0x00014665, +0x00014662, +0x00014661, +0x00014660, +0x0001465e, +0x0001465c, +0x0001465a, +0x00014659, +0x00014658, +0x00014655, +0x00014654, +0x00014653, +0x00014650, +0x0001464f, +0x0001464e, +0x0001464c, +0x0001464a, +0x00014649, +0x00014647, +0x00014646, +0x00014643, +0x00014642, +0x00014641, +0x0001463e, +0x0001463d, +0x0001463c, +0x0001463b, +0x00014638, +0x00014637, +0x00014635, +0x00014634, +0x00014632, +0x00014630, +0x0001462f, +0x0001462d, +0x0001462b, +0x0001462a, +0x00014629, +0x00014626, +0x00014625, +0x00014624, +0x00014622, +0x00014620, +0x0001461f, +0x0001461d, +0x0001461b, +0x00014619, +0x00014618, +0x00014617, +0x00014614, +0x00014613, +0x00014612, +0x00014611, +0x0001460e, +0x0001460d, +0x0001460b, +0x00014609, +0x00014608, +0x00014606, +0x00014605, +0x00014603, +0x00014601, +0x00014600, +0x000145ff, +0x000145fc, +0x000145fb, +0x000145fa, +0x000145f7, +0x000145f6, +0x000145f5, +0x000145f3, +0x000145f1, +0x000145ef, +0x000145ee, +0x000145ed, +0x000145ea, +0x000145e9, +0x000145e8, +0x000145e5, +0x000145e4, +0x000145e3, +0x000145e1, +0x000145df, +0x000145de, +0x000145dc, +0x000145db, +0x000145d9, +0x000145d7, +0x000145d6, +0x000145d3, +0x000145d2, +0x000145d1, +0x000145d0, +0x000145cd, +0x000145cc, +0x000145cb, +0x000145c9, +0x000145c7, +0x000145c5, +0x000145c4, +0x000145c2, +0x000145c0, +0x000145bf, +0x000145be, +0x000145bb, +0x000145ba, +0x000145b9, +0x000145b7, +0x000145b5, +0x000145b4, +0x000145b2, +0x000145b0, +0x000145af, +0x000145ad, +0x000145ac, +0x000145a9, +0x000145a8, +0x000145a7, +0x000145a5, +0x000145a3, +0x000145a1, +0x000145a0, +0x0001459f, +0x0001459c, +0x0001459b, +0x0001459a, +0x00014598, +0x00014596, +0x00014595, +0x00014593, +0x00014592, +0x0001458f, +0x0001458e, +0x0001458d, +0x0001458a, +0x00014589, +0x00014588, +0x00014587, +0x00014584, +0x00014583, +0x00014581, +0x00014580, +0x0001457e, +0x0001457c, +0x0001457b, +0x00014579, +0x00014577, +0x00014576, +0x00014575, +0x00014572, +0x00014571, +0x00014570, +0x0001456e, +0x0001456c, +0x0001456b, +0x00014569, +0x00014568, +0x00014566, +0x00014564, +0x00014563, +0x00014560, +0x0001455f, +0x0001455e, +0x0001455d, +0x0001455a, +0x00014559, +0x00014558, +0x00014556, +0x00014554, +0x00014553, +0x00014551, +0x0001454f, +0x0001454d, +0x0001454c, +0x0001454b, +0x00014548, +0x00014547, +0x00014546, +0x00014545, +0x00014542, +0x00014541, +0x0001453f, +0x0001453e, +0x0001453c, +0x0001453a, +0x00014539, +0x00014537, +0x00014535, +0x00014534, +0x00014533, +0x00014530, +0x0001452f, +0x0001452e, +0x0001452c, +0x0001452a, +0x00014529, +0x00014527, +0x00014525, +0x00014524, +0x00014522, +0x00014521, +0x0001451e, +0x0001451d, +0x0001451c, +0x0001451b, +0x00014518, +0x00014517, +0x00014516, +0x00014513, +0x00014512, +0x00014511, +0x0001450f, +0x0001450d, +0x0001450b, +0x0001450a, +0x00014509, +0x00014506, +0x00014505, +0x00014504, +0x00014503, +0x00014500, +0x000144ff, +0x000144fd, +0x000144fb, +0x000144fa, +0x000144f8, +0x000144f7, +0x000144f5, +0x000144f3, +0x000144f2, +0x000144f1, +0x000144ee, +0x000144ed, +0x000144ec, +0x000144e9, +0x000144e8, +0x000144e7, +0x000144e5, +0x000144e3, +0x000144e2, +0x000144e0, +0x000144df, +0x000144dc, +0x000144db, +0x000144da, +0x000144d9, +0x000144d6, +0x000144d5, +0x000144d2, +0x000144d1, +0x000144d0, +0x000144ce, +0x000144cc, +0x000144cb, +0x000144c9, +0x000144c8, +0x000144c5, +0x000144c4, +0x000144c3, +0x000144c2, +0x000144bf, +0x000144be, +0x000144bd, +0x000144ba, +0x000144b9, +0x000144b8, +0x000144b6, +0x000144b4, +0x000144b2, +0x000144b1, +0x000144b0, +0x000144ad, +0x000144ac, +0x000144ab, +0x000144aa, +0x000144a7, +0x000144a6, +0x000144a5, +0x000144a3, +0x000144a1, +0x0001449f, +0x0001449e, +0x0001449c, +0x0001449a, +0x00014499, +0x00014498, +0x00014495, +0x00014494, +0x00014493, +0x00014492, +0x0001448f, +0x0001448e, +0x0001448c, +0x0001448b, +0x00014489, +0x00014487, +0x00014486, +0x00014484, +0x00014482, +0x00014481, +0x00014480, +0x0001447d, +0x0001447c, +0x0001447b, +0x0001447a, +0x00014477, +0x00014476, +0x00014474, +0x00014473, +0x00014471, +0x0001446f, +0x0001446e, +0x0001446c, +0x0001446a, +0x00014469, +0x00014468, +0x00014465, +0x00014464, +0x00014463, +0x00014461, +0x0001445f, +0x0001445e, +0x0001445c, +0x0001445b, +0x00014459, +0x00014457, +0x00014456, +0x00014454, +0x00014452, +0x00014451, +0x00014450, +0x0001444d, +0x0001444c, +0x0001444b, +0x00014449, +0x00014447, +0x00014446, +0x00014444, +0x00014443, +0x00014441, +0x0001443f, +0x0001443e, +0x0001443d, +0x0001443a, +0x00014439, +0x00014438, +0x00014435, +0x00014434, +0x00014433, +0x00014431, +0x0001442f, +0x0001442e, +0x0001442c, +0x0001442b, +0x00014429, +0x00014427, +0x00014426, +0x00014425, +0x00014422, +0x00014421, +0x00014420, +0x0001441d, +0x0001441c, +0x0001441b, +0x00014419, +0x00014417, +0x00014416, +0x00014414, +0x00014413, +0x00014410, +0x0001440f, +0x0001440e, +0x0001440d, +0x0001440a, +0x00014409, +0x00014408, +0x00014405, +0x00014404, +0x00014403, +0x00014401, +0x000143ff, +0x000143fd, +0x000143fc, +0x000143fb, +0x000143f8, +0x000143f7, +0x000143f6, +0x000143f5, +0x000143f2, +0x000143f1, +0x000143f0, +0x000143ed, +0x000143ec, +0x000143ea, +0x000143e9, +0x000143e7, +0x000143e5, +0x000143e4, +0x000143e3, +0x000143e0, +0x000143df, +0x000143de, +0x000143dd, +0x000143da, +0x000143d9, +0x000143d8, +0x000143d6, +0x000143d4, +0x000143d2, +0x000143d1, +0x000143cf, +0x000143cd, +0x000143cc, +0x000143cb, +0x000143c8, +0x000143c7, +0x000143c6, +0x000143c5, +0x000143c2, +0x000143c1, +0x000143bf, +0x000143be, +0x000143bc, +0x000143ba, +0x000143b9, +0x000143b7, +0x000143b5, +0x000143b4, +0x000143b3, +0x000143b0, +0x000143af, +0x000143ae, +0x000143ac, +0x000143aa, +0x000143a9, +0x000143a7, +0x000143a6, +0x000143a4, +0x000143a2, +0x000143a1, +0x0001439f, +0x0001439d, +0x0001439c, +0x0001439b, +0x00014398, +0x00014397, +0x00014396, +0x00014394, +0x00014392, +0x00014391, +0x0001438f, +0x0001438e, +0x0001438c, +0x0001438a, +0x00014389, +0x00014387, +0x00014385, +0x00014384, +0x00014383, +0x00014380, +0x0001437f, +0x0001437e, +0x0001437c, +0x0001437a, +0x00014379, +0x00014377, +0x00014376, +0x00014374, +0x00014372, +0x00014371, +0x00014370, +0x0001436d, +0x0001436c, +0x0001436b, +0x00014368, +0x00014367, +0x00014366, +0x00014364, +0x00014362, +0x00014361, +0x0001435f, +0x0001435e, +0x0001435b, +0x0001435a, +0x00014359, +0x00014358, +0x00014355, +0x00014354, +0x00014353, +0x00014350, +0x0001434f, +0x0001434e, +0x0001434c, +0x0001434a, +0x00014348, +0x00014347, +0x00014346, +0x00014343, +0x00014342, +0x00014341, +0x00014340, +0x0001433d, +0x0001433d, +0x0001433a, +0x00014339, +0x00014338, +0x00014336, +0x00014334, +0x00014332, +0x00014331, +0x00014330, +0x0001432d, +0x0001432c, +0x0001432b, +0x0001432a, +0x00014327, +0x00014326, +0x00014325, +0x00014323, +0x00014321, +0x00014320, +0x0001431e, +0x0001431d, +0x0001431a, +0x00014319, +0x00014318, +0x00014315, +0x00014314, +0x00014313, +0x00014312, +0x0001430f, +0x0001430e, +0x0001430d, +0x0001430b, +0x00014309, +0x00014308, +0x00014306, +0x00014305, +0x00014303, +0x00014301, +0x00014300, +0x000142ff, +0x000142fc, +0x000142fb, +0x000142fa, +0x000142f7, +0x000142f6, +0x000142f5, +0x000142f3, +0x000142f1, +0x000142f0, +0x000142ee, +0x000142ed, +0x000142eb, +0x000142e9, +0x000142e8, +0x000142e7, +0x000142e4, +0x000142e3, +0x000142e2, +0x000142e0, +0x000142de, +0x000142dd, +0x000142db, +0x000142da, +0x000142d8, +0x000142d6, +0x000142d5, +0x000142d3, +0x000142d1, +0x000142d0, +0x000142cf, +0x000142cc, +0x000142cb, +0x000142ca, +0x000142c8, +0x000142c6, +0x000142c5, +0x000142c3, +0x000142c2, +0x000142c0, +0x000142be, +0x000142bd, +0x000142bc, +0x000142b9, +0x000142b8, +0x000142b7, +0x000142b6, +0x000142b3, +0x000142b2, +0x000142b1, +0x000142ae, +0x000142ad, +0x000142ab, +0x000142aa, +0x000142a8, +0x000142a6, +0x000142a5, +0x000142a4, +0x000142a1, +0x000142a0, +0x0001429f, +0x0001429e, +0x0001429b, +0x0001429a, +0x00014299, +0x00014297, +0x00014295, +0x00014293, +0x00014292, +0x00014290, +0x0001428e, +0x0001428d, +0x0001428c, +0x00014289, +0x00014288, +0x00014287, +0x00014286, +0x00014283, +0x00014282, +0x00014281, +0x0001427f, +0x0001427d, +0x0001427c, +0x0001427a, +0x00014279, +0x00014276, +0x00014275, +0x00014274, +0x00014273, +0x00014271, +0x0001426f, +0x0001426d, +0x0001426c, +0x0001426a, +0x00014268, +0x00014267, +0x00014266, +0x00014263, +0x00014262, +0x00014261, +0x00014260, +0x0001425d, +0x0001425c, +0x0001425b, +0x00014259, +0x00014257, +0x00014256, +0x00014254, +0x00014253, +0x00014251, +0x0001424f, +0x0001424e, +0x0001424d, +0x0001424a, +0x00014249, +0x00014248, +0x00014246, +0x00014244, +0x00014243, +0x00014241, +0x00014240, +0x0001423e, +0x0001423c, +0x0001423b, +0x00014239, +0x00014237, +0x00014236, +0x00014235, +0x00014232, +0x00014231, +0x00014230, +0x0001422f, +0x0001422c, +0x0001422b, +0x0001422a, +0x00014228, +0x00014226, +0x00014224, +0x00014223, +0x00014222, +0x0001421f, +0x0001421e, +0x0001421d, +0x0001421c, +0x00014219, +0x00014218, +0x00014217, +0x00014215, +0x00014213, +0x00014212, +0x00014210, +0x0001420f, +0x0001420d, +0x0001420b, +0x0001420a, +0x00014208, +0x00014206, +0x00014205, +0x00014204, +0x00014201, +0x00014200, +0x000141ff, +0x000141fd, +0x000141fb, +0x000141fa, +0x000141f8, +0x000141f7, +0x000141f5, +0x000141f3, +0x000141f2, +0x000141f1, +0x000141ee, +0x000141ed, +0x000141ec, +0x000141eb, +0x000141e8, +0x000141e7, +0x000141e6, +0x000141e4, +0x000141e2, +0x000141e1, +0x000141df, +0x000141de, +0x000141dc, +0x000141da, +0x000141d9, +0x000141d6, +0x000141d5, +0x000141d4, +0x000141d3, +0x000141d0, +0x000141cf, +0x000141ce, +0x000141cc, +0x000141ca, +0x000141c9, +0x000141c7, +0x000141c6, +0x000141c4, +0x000141c2, +0x000141c1, +0x000141c0, +0x000141bd, +0x000141bc, +0x000141bb, +0x000141ba, +0x000141b7, +0x000141b6, +0x000141b5, +0x000141b3, +0x000141b1, +0x000141b0, +0x000141ae, +0x000141ad, +0x000141aa, +0x000141a9, +0x000141a8, +0x000141a6, +0x000141a4, +0x000141a3, +0x000141a1, +0x0001419f, +0x0001419e, +0x0001419d, +0x0001419a, +0x00014199, +0x00014198, +0x00014196, +0x00014194, +0x00014193, +0x00014191, +0x00014190, +0x0001418e, +0x0001418c, +0x0001418b, +0x0001418a, +0x00014187, +0x00014186, +0x00014185, +0x00014184, +0x00014181, +0x00014180, +0x0001417f, +0x0001417d, +0x0001417b, +0x0001417a, +0x00014178, +0x00014177, +0x00014175, +0x00014173, +0x00014172, +0x00014171, +0x0001416e, +0x0001416d, +0x0001416c, +0x0001416b, +0x00014168, +0x00014167, +0x00014166, +0x00014164, +0x00014162, +0x00014161, +0x0001415f, +0x0001415e, +0x0001415c, +0x0001415a, +0x00014159, +0x00014158, +0x00014155, +0x00014154, +0x00014153, +0x00014152, +0x0001414f, +0x0001414e, +0x0001414c, +0x0001414b, +0x00014149, +0x00014147, +0x00014146, +0x00014145, +0x00014142, +0x00014141, +0x00014140, +0x0001413d, +0x0001413c, +0x0001413b, +0x0001413a, +0x00014137, +0x00014136, +0x00014135, +0x00014133, +0x00014131, +0x00014130, +0x0001412e, +0x0001412d, +0x0001412b, +0x00014129, +0x00014128, +0x00014127, +0x00014124, +0x00014123, +0x00014122, +0x00014121, +0x0001411e, +0x0001411d, +0x0001411c, +0x0001411a, +0x00014118, +0x00014117, +0x00014115, +0x00014114, +0x00014112, +0x00014110, +0x0001410f, +0x0001410e, +0x0001410b, +0x0001410a, +0x00014109, +0x00014108, +0x00014105, +0x00014104, +0x00014103, +0x00014101, +0x000140ff, +0x000140fd, +0x000140fc, +0x000140fb, +0x000140f8, +0x000140f7, +0x000140f6, +0x000140f5, +0x000140f2, +0x000140f1, +0x000140f0, +0x000140ee, +0x000140ec, +0x000140eb, +0x000140e9, +0x000140e8, +0x000140e6, +0x000140e4, +0x000140e3, +0x000140e2, +0x000140df, +0x000140de, +0x000140dc, +0x000140db, +0x000140da, +0x000140d7, +0x000140d6, +0x000140d5, +0x000140d3, +0x000140d1, +0x000140d0, +0x000140ce, +0x000140cd, +0x000140cb, +0x000140c9, +0x000140c8, +0x000140c7, +0x000140c4, +0x000140c3, +0x000140c2, +0x000140c1, +0x000140be, +0x000140bd, +0x000140bc, +0x000140ba, +0x000140b8, +0x000140b7, +0x000140b5, +0x000140b4, +0x000140b2, +0x000140b0, +0x000140af, +0x000140ae, +0x000140ab, +0x000140aa, +0x000140a9, +0x000140a8, +0x000140a5, +0x000140a4, +0x000140a3, +0x000140a1, +0x0001409f, +0x0001409e, +0x0001409c, +0x0001409b, +0x00014099, +0x00014097, +0x00014096, +0x00014095, +0x00014092, +0x00014091, +0x00014090, +0x0001408f, +0x0001408c, +0x0001408b, +0x0001408a, +0x00014088, +0x00014086, +0x00014085, +0x00014083, +0x00014082, +0x00014080, +0x0001407e, +0x0001407d, +0x0001407c, +0x00014079, +0x00014078, +0x00014077, +0x00014076, +0x00014073, +0x00014072, +0x00014071, +0x0001406f, +0x0001406d, +0x0001406c, +0x0001406a, +0x00014069, +0x00014067, +0x00014065, +0x00014064, +0x00014063, +0x00014060, +0x0001405f, +0x0001405e, +0x0001405d, +0x0001405a, +0x00014059, +0x00014058, +0x00014056, +0x00014054, +0x00014053, +0x00014051, +0x00014050, +0x0001404e, +0x0001404c, +0x0001404b, +0x0001404a, +0x00014047, +0x00014046, +0x00014045, +0x00014044, +0x00014041, +0x00014040, +0x0001403f, +0x0001403d, +0x0001403b, +0x0001403a, +0x00014038, +0x00014037, +0x00014035, +0x00014033, +0x00014032, +0x00014031, +0x0001402e, +0x0001402d, +0x0001402c, +0x0001402b, +0x00014028, +0x00014027, +0x00014026, +0x00014024, +0x00014022, +0x00014021, +0x0001401f, +0x0001401e, +0x0001401c, +0x0001401a, +0x00014019, +0x00014018, +0x00014015, +0x00014014, +0x00014013, +0x00014012, +0x0001400f, +0x0001400e, +0x0001400d, +0x0001400b, +0x00014009, +0x00014008, +0x00014006, +0x00014005, +0x00014003, +0x00014001, +0x00014000, +0x00013fff, +0x00013ffc, +0x00013ffb, +0x00013ffa, +0x00013ff9, +0x00013ff6, +0x00013ff5, +0x00013ff4, +0x00013ff2, +0x00013ff0, +0x00013fef, +0x00013fed, +0x00013fec, +0x00013fea, +0x00013fe8, +0x00013fe7, +0x00013fe6, +0x00013fe3, +0x00013fe2, +0x00013fe1, +0x00013fe0, +0x00013fdd, +0x00013fdc, +0x00013fdb, +0x00013fd9, +0x00013fd7, +0x00013fd6, +0x00013fd4, +0x00013fd3, +0x00013fd1, +0x00013fcf, +0x00013fce, +0x00013fcd, +0x00013fca, +0x00013fc9, +0x00013fc8, +0x00013fc7, +0x00013fc4, +0x00013fc3, +0x00013fc2, +0x00013fc0, +0x00013fbe, +0x00013fbd, +0x00013fbb, +0x00013fba, +0x00013fb8, +0x00013fb6, +0x00013fb5, +0x00013fb4, +0x00013fb1, +0x00013fb0, +0x00013faf, +0x00013fae, +0x00013fab, +0x00013faa, +0x00013fa9, +0x00013fa7, +0x00013fa5, +0x00013fa4, +0x00013fa2, +0x00013fa1, +0x00013f9f, +0x00013f9d, +0x00013f9c, +0x00013f9b, +0x00013f98, +0x00013f97, +0x00013f96, +0x00013f95, +0x00013f92, +0x00013f91, +0x00013f90, +0x00013f8e, +0x00013f8c, +0x00013f8b, +0x00013f89, +0x00013f88, +0x00013f86, +0x00013f84, +0x00013f83, +0x00013f82, +0x00013f7f, +0x00013f7e, +0x00013f7d, +0x00013f7c, +0x00013f79, +0x00013f78, +0x00013f77, +0x00013f75, +0x00013f73, +0x00013f72, +0x00013f70, +0x00013f6f, +0x00013f6d, +0x00013f6b, +0x00013f6a, +0x00013f69, +0x00013f66, +0x00013f65, +0x00013f64, +0x00013f63, +0x00013f60, +0x00013f5f, +0x00013f5e, +0x00013f5c, +0x00013f5a, +0x00013f59, +0x00013f57, +0x00013f56, +0x00013f54, +0x00013f52, +0x00013f51, +0x00013f50, +0x00013f4d, +0x00013f4c, +0x00013f4b, +0x00013f4a, +0x00013f48, +0x00013f46, +0x00013f45, +0x00013f43, +0x00013f42, +0x00013f40, +0x00013f3e, +0x00013f3d, +0x00013f3c, +0x00013f39, +0x00013f38, +0x00013f37, +0x00013f36, +0x00013f33, +0x00013f32, +0x00013f31, +0x00013f2f, +0x00013f2d, +0x00013f2c, +0x00013f2a, +0x00013f29, +0x00013f27, +0x00013f25, +0x00013f24, +0x00013f23, +0x00013f20, +0x00013f1f, +0x00013f1e, +0x00013f1d, +0x00013f1a, +0x00013f19, +0x00013f18, +0x00013f16, +0x00013f14, +0x00013f13, +0x00013f11, +0x00013f10, +0x00013f0e, +0x00013f0c, +0x00013f0b, +0x00013f0a, +0x00013f07, +0x00013f06, +0x00013f05, +0x00013f04, +0x00013f01, +0x00013f00, +0x00013eff, +0x00013efe, +0x00013efb, +0x00013efa, +0x00013ef9, +0x00013ef7, +0x00013ef5, +0x00013ef4, +0x00013ef2, +0x00013ef1, +0x00013eef, +0x00013eed, +0x00013eec, +0x00013eeb, +0x00013eea, +0x00013ee7, +0x00013ee6, +0x00013ee5, +0x00013ee3, +0x00013ee1, +0x00013ee0, +0x00013ede, +0x00013edd, +0x00013edb, +0x00013ed9, +0x00013ed8, +0x00013ed7, +0x00013ed4, +0x00013ed3, +0x00013ed2, +0x00013ed1, +0x00013ece, +0x00013ecd, +0x00013ecc, +0x00013eca, +0x00013ec8, +0x00013ec7, +0x00013ec5, +0x00013ec4, +0x00013ec2, +0x00013ec0, +0x00013ebf, +0x00013ebe, +0x00013ebb, +0x00013eba, +0x00013eb9, +0x00013eb8, +0x00013eb5, +0x00013eb4, +0x00013eb3, +0x00013eb1, +0x00013eaf, +0x00013eae, +0x00013ead, +0x00013eab, +0x00013ea9, +0x00013ea8, +0x00013ea6, +0x00013ea5, +0x00013ea3, +0x00013ea1, +0x00013ea0, +0x00013e9f, +0x00013e9c, +0x00013e9b, +0x00013e9a, +0x00013e99, +0x00013e96, +0x00013e95, +0x00013e94, +0x00013e92, +0x00013e90, +0x00013e8f, +0x00013e8d, +0x00013e8c, +0x00013e8a, +0x00013e88, +0x00013e87, +0x00013e86, +0x00013e84, +0x00013e82, +0x00013e81, +0x00013e80, +0x00013e7d, +0x00013e7c, +0x00013e7b, +0x00013e7a, +0x00013e77, +0x00013e76, +0x00013e75, +0x00013e74, +0x00013e71, +0x00013e70, +0x00013e6f, +0x00013e6d, +0x00013e6b, +0x00013e6a, +0x00013e68, +0x00013e67, +0x00013e65, +0x00013e63, +0x00013e62, +0x00013e61, +0x00013e5e, +0x00013e5d, +0x00013e5c, +0x00013e5b, +0x00013e58, +0x00013e57, +0x00013e56, +0x00013e54, +0x00013e53, +0x00013e51, +0x00013e50, +0x00013e4e, +0x00013e4d, +0x00013e4b, +0x00013e49, +0x00013e48, +0x00013e47, +0x00013e44, +0x00013e43, +0x00013e42, +0x00013e41, +0x00013e3e, +0x00013e3d, +0x00013e3c, +0x00013e3a, +0x00013e38, +0x00013e37, +0x00013e35, +0x00013e34, +0x00013e32, +0x00013e30, +0x00013e2f, +0x00013e2e, +0x00013e2b, +0x00013e2a, +0x00013e29, +0x00013e28, +0x00013e25, +0x00013e24, +0x00013e23, +0x00013e22, +0x00013e20, +0x00013e1e, +0x00013e1d, +0x00013e1b, +0x00013e1a, +0x00013e18, +0x00013e16, +0x00013e15, +0x00013e14, +0x00013e11, +0x00013e10, +0x00013e0f, +0x00013e0e, +0x00013e0b, +0x00013e0a, +0x00013e09, +0x00013e07, +0x00013e05, +0x00013e04, +0x00013e02, +0x00013e01, +0x00013dff, +0x00013dfe, +0x00013dfc, +0x00013dfb, +0x00013df9, +0x00013df7, +0x00013df6, +0x00013df5, +0x00013df2, +0x00013df1, +0x00013df0, +0x00013def, +0x00013ded, +0x00013deb, +0x00013dea, +0x00013de8, +0x00013de7, +0x00013de5, +0x00013de3, +0x00013de2, +0x00013de1, +0x00013dde, +0x00013ddd, +0x00013ddc, +0x00013ddb, +0x00013dd8, +0x00013dd7, +0x00013dd6, +0x00013dd5, +0x00013dd2, +0x00013dd1, +0x00013dd0, +0x00013dce, +0x00013dcc, +0x00013dcb, +0x00013dc9, +0x00013dc8, +0x00013dc6, +0x00013dc4, +0x00013dc3, +0x00013dc2, +0x00013dc0, +0x00013dbf, +0x00013dbc, +0x00013dbb, +0x00013dba, +0x00013db9, +0x00013db6, +0x00013db5, +0x00013db4, +0x00013db2, +0x00013db0, +0x00013daf, +0x00013dad, +0x00013dac, +0x00013daa, +0x00013da8, +0x00013da7, +0x00013da6, +0x00013da3, +0x00013da2, +0x00013da1, +0x00013da0, +0x00013d9f, +0x00013d9c, +0x00013d9b, +0x00013d9a, +0x00013d98, +0x00013d96, +0x00013d95, +0x00013d93, +0x00013d92, +0x00013d90, +0x00013d8e, +0x00013d8d, +0x00013d8c, +0x00013d89, +0x00013d88, +0x00013d87, +0x00013d86, +0x00013d83, +0x00013d82, +0x00013d81, +0x00013d80, +0x00013d7e, +0x00013d7c, +0x00013d7b, +0x00013d79, +0x00013d78, +0x00013d76, +0x00013d74, +0x00013d73, +0x00013d72, +0x00013d6f, +0x00013d6e, +0x00013d6d, +0x00013d6c, +0x00013d69, +0x00013d68, +0x00013d67, +0x00013d66, +0x00013d63, +0x00013d62, +0x00013d61, +0x00013d5f, +0x00013d5e, +0x00013d5c, +0x00013d5a, +0x00013d59, +0x00013d58, +0x00013d55, +0x00013d54, +0x00013d53, +0x00013d52, +0x00013d4f, +0x00013d4e, +0x00013d4d, +0x00013d4c, +0x00013d49, +0x00013d48, +0x00013d47, +0x00013d45, +0x00013d43, +0x00013d42, +0x00013d40, +0x00013d3f, +0x00013d3d, +0x00013d3b, +0x00013d3a, +0x00013d39, +0x00013d38, +0x00013d35, +0x00013d34, +0x00013d33, +0x00013d32, +0x00013d2f, +0x00013d2e, +0x00013d2d, +0x00013d2b, +0x00013d29, +0x00013d28, +0x00013d26, +0x00013d25, +0x00013d23, +0x00013d21, +0x00013d20, +0x00013d1f, +0x00013d1c, +0x00013d1b, +0x00013d1a, +0x00013d19, +0x00013d18, +0x00013d15, +0x00013d14, +0x00013d13, +0x00013d11, +0x00013d0f, +0x00013d0e, +0x00013d0c, +0x00013d0b, +0x00013d09, +0x00013d07, +0x00013d06, +0x00013d05, +0x00013d02, +0x00013d01, +0x00013d00, +0x00013cff, +0x00013cfc, +0x00013cfb, +0x00013cfa, +0x00013cf9, +0x00013cf7, +0x00013cf5, +0x00013cf4, +0x00013cf2, +0x00013cf1, +0x00013cef, +0x00013ced, +0x00013cec, +0x00013ceb, +0x00013ce8, +0x00013ce7, +0x00013ce6, +0x00013ce5, +0x00013ce2, +0x00013ce1, +0x00013ce0, +0x00013cdf, +0x00013cdc, +0x00013cdb, +0x00013cda, +0x00013cd8, +0x00013cd7, +0x00013cd5, +0x00013cd3, +0x00013cd2, +0x00013cd1, +0x00013cce, +0x00013ccd, +0x00013ccc, +0x00013ccb, +0x00013cc8, +0x00013cc7, +0x00013cc6, +0x00013cc5, +0x00013cc2, +0x00013cc1, +0x00013cc0, +0x00013cbe, +0x00013cbc, +0x00013cbb, +0x00013cb9, +0x00013cb8, +0x00013cb7, +0x00013cb4, +0x00013cb3, +0x00013cb2, +0x00013cb1, +0x00013cae, +0x00013cad, +0x00013cac, +0x00013cab, +0x00013ca8, +0x00013ca7, +0x00013ca6, +0x00013ca4, +0x00013ca2, +0x00013ca1, +0x00013c9f, +0x00013c9e, +0x00013c9c, +0x00013c9a, +0x00013c99, +0x00013c98, +0x00013c97, +0x00013c94, +0x00013c93, +0x00013c92, +0x00013c91, +0x00013c8e, +0x00013c8d, +0x00013c8c, +0x00013c8a, +0x00013c88, +0x00013c87, +0x00013c85, +0x00013c84, +0x00013c82, +0x00013c80, +0x00013c7f, +0x00013c7e, +0x00013c7c, +0x00013c7a, +0x00013c79, +0x00013c78, +0x00013c77, +0x00013c74, +0x00013c73, +0x00013c72, +0x00013c70, +0x00013c6e, +0x00013c6d, +0x00013c6b, +0x00013c6a, +0x00013c68, +0x00013c66, +0x00013c65, +0x00013c64, +0x00013c62, +0x00013c60, +0x00013c5f, +0x00013c5e, +0x00013c5b, +0x00013c5a, +0x00013c59, +0x00013c58, +0x00013c56, +0x00013c54, +0x00013c53, +0x00013c51, +0x00013c50, +0x00013c4e, +0x00013c4c, +0x00013c4b, +0x00013c4a, +0x00013c47, +0x00013c46, +0x00013c45, +0x00013c44, +0x00013c41, +0x00013c40, +0x00013c3f, +0x00013c3e, +0x00013c3b, +0x00013c3a, +0x00013c39, +0x00013c38, +0x00013c36, +0x00013c35, +0x00013c33, +0x00013c31, +0x00013c30, +0x00013c2f, +0x00013c2c, +0x00013c2b, +0x00013c2a, +0x00013c29, +0x00013c26, +0x00013c25, +0x00013c24, +0x00013c23, +0x00013c20, +0x00013c1f, +0x00013c1e, +0x00013c1c, +0x00013c1b, +0x00013c19, +0x00013c17, +0x00013c16, +0x00013c15, +0x00013c13, +0x00013c11, +0x00013c10, +0x00013c0f, +0x00013c0c, +0x00013c0b, +0x00013c0a, +0x00013c09, +0x00013c07, +0x00013c05, +0x00013c04, +0x00013c02, +0x00013c01, +0x00013bff, +0x00013bfe, +0x00013bfc, +0x00013bfb, +0x00013bf9, +0x00013bf7, +0x00013bf6, +0x00013bf5, +0x00013bf2, +0x00013bf1, +0x00013bf0, +0x00013bef, +0x00013bed, +0x00013beb, +0x00013bea, +0x00013be9, +0x00013be7, +0x00013be5, +0x00013be4, +0x00013be2, +0x00013be1, +0x00013bdf, +0x00013bdd, +0x00013bdc, +0x00013bdb, +0x00013bd9, +0x00013bd7, +0x00013bd6, +0x00013bd5, +0x00013bd4, +0x00013bd1, +0x00013bd0, +0x00013bcf, +0x00013bcd, +0x00013bcb, +0x00013bca, +0x00013bc8, +0x00013bc7, +0x00013bc5, +0x00013bc4, +0x00013bc2, +0x00013bc1, +0x00013bbf, +0x00013bbd, +0x00013bbc, +0x00013bbb, +0x00013bba, +0x00013bb7, +0x00013bb6, +0x00013bb5, +0x00013bb3, +0x00013bb1, +0x00013bb0, +0x00013baf, +0x00013bad, +0x00013bab, +0x00013baa, +0x00013ba8, +0x00013ba7, +0x00013ba6, +0x00013ba3, +0x00013ba2, +0x00013ba1, +0x00013ba0, +0x00013b9d, +0x00013b9c, +0x00013b9b, +0x00013b9a, +0x00013b97, +0x00013b96, +0x00013b95, +0x00013b93, +0x00013b91, +0x00013b90, +0x00013b8e, +0x00013b8d, +0x00013b8c, +0x00013b8a, +0x00013b88, +0x00013b87, +0x00013b86, +0x00013b83, +0x00013b82, +0x00013b81, +0x00013b80, +0x00013b7d, +0x00013b7c, +0x00013b7b, +0x00013b79, +0x00013b77, +0x00013b76, +0x00013b75, +0x00013b74, +0x00013b71, +0x00013b70, +0x00013b6f, +0x00013b6e, +0x00013b6b, +0x00013b6a, +0x00013b69, +0x00013b67, +0x00013b65, +0x00013b64, +0x00013b62, +0x00013b61, +0x00013b60, +0x00013b5e, +0x00013b5c, +0x00013b5b, +0x00013b5a, +0x00013b57, +0x00013b56, +0x00013b55, +0x00013b54, +0x00013b51, +0x00013b50, +0x00013b4f, +0x00013b4e, +0x00013b4c, +0x00013b4a, +0x00013b49, +0x00013b47, +0x00013b46, +0x00013b44, +0x00013b42, +0x00013b41, +0x00013b40, +0x00013b3e, +0x00013b3c, +0x00013b3b, +0x00013b3a, +0x00013b39, +0x00013b36, +0x00013b35, +0x00013b34, +0x00013b32, +0x00013b30, +0x00013b2f, +0x00013b2e, +0x00013b2c, +0x00013b2a, +0x00013b29, +0x00013b27, +0x00013b26, +0x00013b25, +0x00013b22, +0x00013b21, +0x00013b20, +0x00013b1f, +0x00013b1c, +0x00013b1b, +0x00013b1a, +0x00013b19, +0x00013b16, +0x00013b15, +0x00013b14, +0x00013b12, +0x00013b11, +0x00013b0f, +0x00013b0e, +0x00013b0c, +0x00013b0b, +0x00013b09, +0x00013b07, +0x00013b06, +0x00013b05, +0x00013b02, +0x00013b01, +0x00013b00, +0x00013aff, +0x00013afe, +0x00013afb, +0x00013afa, +0x00013af9, +0x00013af7, +0x00013af5, +0x00013af4, +0x00013af2, +0x00013af1, +0x00013aef, +0x00013aee, +0x00013aec, +0x00013aeb, +0x00013aea, +0x00013ae7, +0x00013ae6, +0x00013ae5, +0x00013ae4, +0x00013ae1, +0x00013ae0, +0x00013adf, +0x00013ade, +0x00013adb, +0x00013ada, +0x00013ad9, +0x00013ad7, +0x00013ad6, +0x00013ad4, +0x00013ad2, +0x00013ad1, +0x00013ad0, +0x00013ace, +0x00013acc, +0x00013acb, +0x00013aca, +0x00013ac7, +0x00013ac6, +0x00013ac5, +0x00013ac4, +0x00013ac2, +0x00013ac0, +0x00013abf, +0x00013abe, +0x00013abc, +0x00013aba, +0x00013ab9, +0x00013ab7, +0x00013ab6, +0x00013ab4, +0x00013ab3, +0x00013ab1, +0x00013aaf, +0x00013aae, +0x00013aad, +0x00013aaa, +0x00013aa9, +0x00013aa8, +0x00013aa7, +0x00013aa4, +0x00013aa3, +0x00013aa2, +0x00013aa1, +0x00013a9f, +0x00013a9d, +0x00013a9c, +0x00013a9b, +0x00013a99, +0x00013a97, +0x00013a96, +0x00013a94, +0x00013a93, +0x00013a92, +0x00013a90, +0x00013a8e, +0x00013a8d, +0x00013a8c, +0x00013a89, +0x00013a88, +0x00013a87, +0x00013a86, +0x00013a83, +0x00013a82, +0x00013a81, +0x00013a80, +0x00013a7e, +0x00013a7c, +0x00013a7b, +0x00013a79, +0x00013a78, +0x00013a76, +0x00013a75, +0x00013a73, +0x00013a72, +0x00013a71, +0x00013a6e, +0x00013a6d, +0x00013a6c, +0x00013a6b, +0x00013a68, +0x00013a67, +0x00013a66, +0x00013a65, +0x00013a62, +0x00013a61, +0x00013a60, +0x00013a5e, +0x00013a5d, +0x00013a5b, +0x00013a5a, +0x00013a58, +0x00013a57, +0x00013a55, +0x00013a53, +0x00013a52, +0x00013a51, +0x00013a50, +0x00013a4d, +0x00013a4c, +0x00013a4b, +0x00013a4a, +0x00013a47, +0x00013a46, +0x00013a45, +0x00013a43, +0x00013a42, +0x00013a40, +0x00013a3f, +0x00013a3d, +0x00013a3c, +0x00013a3a, +0x00013a38, +0x00013a37, +0x00013a36, +0x00013a34, +0x00013a32, +0x00013a31, +0x00013a30, +0x00013a2f, +0x00013a2c, +0x00013a2b, +0x00013a2a, +0x00013a28, +0x00013a26, +0x00013a25, +0x00013a24, +0x00013a22, +0x00013a21, +0x00013a1f, +0x00013a1d, +0x00013a1c, +0x00013a1b, +0x00013a19, +0x00013a17, +0x00013a16, +0x00013a15, +0x00013a12, +0x00013a11, +0x00013a10, +0x00013a0f, +0x00013a0d, +0x00013a0b, +0x00013a0a, +0x00013a09, +0x00013a07, +0x00013a05, +0x00013a04, +0x00013a02, +0x00013a01, +0x00013a00, +0x000139fe, +0x000139fc, +0x000139fb, +0x000139fa, +0x000139f7, +0x000139f6, +0x000139f5, +0x000139f4, +0x000139f3, +0x000139f0, +0x000139ef, +0x000139ee, +0x000139ec, +0x000139ea, +0x000139e9, +0x000139e7, +0x000139e6, +0x000139e4, +0x000139e3, +0x000139e1, +0x000139e0, +0x000139df, +0x000139dc, +0x000139db, +0x000139da, +0x000139d9, +0x000139d6, +0x000139d5, +0x000139d4, +0x000139d3, +0x000139d1, +0x000139cf, +0x000139ce, +0x000139cc, +0x000139cb, +0x000139c9, +0x000139c8, +0x000139c6, +0x000139c5, +0x000139c3, +0x000139c1, +0x000139c0, +0x000139bf, +0x000139be, +0x000139bb, +0x000139ba, +0x000139b9, +0x000139b8, +0x000139b5, +0x000139b4, +0x000139b3, +0x000139b2, +0x000139b0, +0x000139ae, +0x000139ad, +0x000139ab, +0x000139aa, +0x000139a8, +0x000139a6, +0x000139a5, +0x000139a4, +0x000139a2, +0x000139a0, +0x0001399f, +0x0001399e, +0x0001399d, +0x0001399a, +0x00013999, +0x00013998, +0x00013997, +0x00013994, +0x00013993, +0x00013992, +0x00013990, +0x0001398f, +0x0001398d, +0x0001398b, +0x0001398a, +0x00013989, +0x00013987, +0x00013985, +0x00013984, +0x00013983, +0x00013982, +0x0001397f, +0x0001397e, +0x0001397d, +0x0001397c, +0x00013979, +0x00013978, +0x00013977, +0x00013975, +0x00013973, +0x00013972, +0x00013970, +0x0001396f, +0x0001396e, +0x0001396c, +0x0001396a, +0x00013969, +0x00013968, +0x00013965, +0x00013964, +0x00013963, +0x00013962, +0x00013961, +0x0001395e, +0x0001395d, +0x0001395c, +0x0001395a, +0x00013958, +0x00013957, +0x00013956, +0x00013954, +0x00013952, +0x00013951, +0x0001394f, +0x0001394e, +0x0001394d, +0x0001394a, +0x00013949, +0x00013948, +0x00013947, +0x00013944, +0x00013943, +0x00013942, +0x00013941, +0x0001393f, +0x0001393d, +0x0001393c, +0x0001393b, +0x00013939, +0x00013937, +0x00013936, +0x00013934, +0x00013933, +0x00013932, +0x00013931, +0x0001392e, +0x0001392d, +0x0001392c, +0x0001392b, +0x00013928, +0x00013927, +0x00013926, +0x00013925, +0x00013923, +0x00013921, +0x00013920, +0x0001391f, +0x0001391d, +0x0001391b, +0x0001391a, +0x00013918, +0x00013917, +0x00013916, +0x00013914, +0x00013912, +0x00013911, +0x00013910, +0x0001390d, +0x0001390c, +0x0001390b, +0x0001390a, +0x00013909, +0x00013906, +0x00013905, +0x00013904, +0x00013902, +0x00013900, +0x000138ff, +0x000138fe, +0x000138fc, +0x000138fb, +0x000138f9, +0x000138f7, +0x000138f6, +0x000138f5, +0x000138f3, +0x000138f1, +0x000138f0, +0x000138ef, +0x000138ee, +0x000138eb, +0x000138ea, +0x000138e9, +0x000138e8, +0x000138e5, +0x000138e4, +0x000138e3, +0x000138e1, +0x000138e0, +0x000138de, +0x000138dd, +0x000138db, +0x000138da, +0x000138d8, +0x000138d6, +0x000138d5, +0x000138d4, +0x000138d3, +0x000138d0, +0x000138cf, +0x000138ce, +0x000138cd, +0x000138ca, +0x000138c9, +0x000138c8, +0x000138c7, +0x000138c4, +0x000138c3, +0x000138c2, +0x000138c0, +0x000138bf, +0x000138bd, +0x000138bc, +0x000138ba, +0x000138b9, +0x000138b7, +0x000138b5, +0x000138b4, +0x000138b3, +0x000138b2, +0x000138af, +0x000138ae, +0x000138ad, +0x000138ac, +0x000138a9, +0x000138a8, +0x000138a7, +0x000138a6, +0x000138a4, +0x000138a2, +0x000138a1, +0x0001389f, +0x0001389e, +0x0001389c, +0x0001389b, +0x00013899, +0x00013898, +0x00013897, +0x00013894, +0x00013893, +0x00013892, +0x00013891, +0x0001388e, +0x0001388d, +0x0001388c, +0x0001388b, +0x00013889, +0x00013887, +0x00013886, +0x00013885, +0x00013883, +0x00013881, +0x00013880, +0x0001387e, +0x0001387d, +0x0001387c, +0x0001387a, +0x00013878, +0x00013877, +0x00013876, +0x00013873, +0x00013873, +0x00013871, +0x00013870, +0x0001386e, +0x0001386c, +0x0001386b, +0x0001386a, +0x00013868, +0x00013866, +0x00013865, +0x00013864, +0x00013863, +0x00013860, +0x0001385f, +0x0001385e, +0x0001385d, +0x0001385b, +0x00013859, +0x00013858, +0x00013857, +0x00013855, +0x00013853, +0x00013852, +0x00013850, +0x0001384f, +0x0001384e, +0x0001384c, +0x0001384a, +0x00013849, +0x00013848, +0x00013845, +0x00013844, +0x00013843, +0x00013842, +0x00013841, +0x0001383e, +0x0001383d, +0x0001383c, +0x0001383b, +0x00013838, +0x00013837, +0x00013836, +0x00013834, +0x00013833, +0x00013831, +0x00013830, +0x0001382e, +0x0001382d, +0x0001382c, +0x00013829, +0x00013828, +0x00013827, +0x00013826, +0x00013823, +0x00013822, +0x00013821, +0x00013820, +0x0001381e, +0x0001381c, +0x0001381b, +0x0001381a, +0x00013818, +0x00013816, +0x00013815, +0x00013814, +0x00013812, +0x00013811, +0x0001380f, +0x0001380d, +0x0001380c, +0x0001380b, +0x00013809, +0x00013807, +0x00013806, +0x00013805, +0x00013804, +0x00013801, +0x00013800, +0x000137ff, +0x000137fe, +0x000137fc, +0x000137fa, +0x000137f9, +0x000137f7, +0x000137f6, +0x000137f4, +0x000137f3, +0x000137f1, +0x000137f0, +0x000137ef, +0x000137ed, +0x000137eb, +0x000137ea, +0x000137e9, +0x000137e6, +0x000137e5, +0x000137e4, +0x000137e3, +0x000137e2, +0x000137df, +0x000137de, +0x000137dd, +0x000137db, +0x000137d9, +0x000137d8, +0x000137d7, +0x000137d5, +0x000137d4, +0x000137d2, +0x000137d0, +0x000137cf, +0x000137ce, +0x000137cd, +0x000137ca, +0x000137c9, +0x000137c8, +0x000137c7, +0x000137c4, +0x000137c3, +0x000137c2, +0x000137c1, +0x000137bf, +0x000137bd, +0x000137bc, +0x000137bb, +0x000137b9, +0x000137b7, +0x000137b6, +0x000137b4, +0x000137b3, +0x000137b1, +0x000137b0, +0x000137ae, +0x000137ad, +0x000137ab, +0x000137aa, +0x000137a9, +0x000137a6, +0x000137a5, +0x000137a4, +0x000137a3, +0x000137a0, +0x0001379f, +0x0001379e, +0x0001379d, +0x0001379c, +0x00013799, +0x00013798, +0x00013797, +0x00013795, +0x00013794, +0x00013792, +0x00013791, +0x0001378f, +0x0001378e, +0x0001378c, +0x0001378a, +0x00013789, +0x00013788, +0x00013787, +0x00013784, +0x00013783, +0x00013782, +0x00013781, +0x00013780, +0x0001377d, +0x0001377c, +0x0001377b, +0x00013779, +0x00013777, +0x00013776, +0x00013775, +0x00013773, +0x00013772, +0x00013770, +0x0001376f, +0x0001376d, +0x0001376c, +0x0001376b, +0x00013768, +0x00013767, +0x00013766, +0x00013765, +0x00013762, +0x00013761, +0x00013760, +0x0001375f, +0x0001375e, +0x0001375b, +0x0001375a, +0x00013759, +0x00013757, +0x00013756, +0x00013754, +0x00013753, +0x00013751, +0x00013750, +0x0001374e, +0x0001374d, +0x0001374b, +0x0001374a, +0x00013749, +0x00013746, +0x00013745, +0x00013744, +0x00013743, +0x00013740, +0x0001373f, +0x0001373e, +0x0001373d, +0x0001373c, +0x00013739, +0x00013738, +0x00013737, +0x00013735, +0x00013734, +0x00013732, +0x00013731, +0x0001372f, +0x0001372e, +0x0001372c, +0x0001372b, +0x00013729, +0x00013728, +0x00013727, +0x00013724, +0x00013723, +0x00013722, +0x00013721, +0x00013720, +0x0001371d, +0x0001371c, +0x0001371b, +0x0001371a, +0x00013717, +0x00013716, +0x00013715, +0x00013713, +0x00013712, +0x00013710, +0x0001370f, +0x0001370d, +0x0001370c, +0x0001370b, +0x00013709, +0x00013707, +0x00013706, +0x00013705, +0x00013702, +0x00013701, +0x00013700, +0x000136ff, +0x000136fe, +0x000136fb, +0x000136fa, +0x000136f9, +0x000136f7, +0x000136f6, +0x000136f4, +0x000136f3, +0x000136f1, +0x000136f0, +0x000136ee, +0x000136ed, +0x000136eb, +0x000136ea, +0x000136e9, +0x000136e6, +0x000136e5, +0x000136e4, +0x000136e3, +0x000136e2, +0x000136df, +0x000136de, +0x000136dd, +0x000136dc, +0x000136d9, +0x000136d8, +0x000136d7, +0x000136d5, +0x000136d4, +0x000136d2, +0x000136d1, +0x000136cf, +0x000136ce, +0x000136cd, +0x000136cb, +0x000136c9, +0x000136c8, +0x000136c7, +0x000136c4, +0x000136c3, +0x000136c2, +0x000136c1, +0x000136c0, +0x000136bd, +0x000136bc, +0x000136bb, +0x000136ba, +0x000136b8, +0x000136b6, +0x000136b5, +0x000136b3, +0x000136b2, +0x000136b0, +0x000136af, +0x000136ad, +0x000136ac, +0x000136ab, +0x000136a9, +0x000136a7, +0x000136a6, +0x000136a5, +0x000136a4, +0x000136a1, +0x000136a0, +0x0001369f, +0x0001369e, +0x0001369b, +0x0001369a, +0x00013699, +0x00013698, +0x00013696, +0x00013694, +0x00013693, +0x00013691, +0x00013690, +0x0001368e, +0x0001368d, +0x0001368b, +0x0001368a, +0x00013689, +0x00013687, +0x00013685, +0x00013684, +0x00013683, +0x00013682, +0x0001367f, +0x0001367e, +0x0001367d, +0x0001367c, +0x00013679, +0x00013678, +0x00013677, +0x00013676, +0x00013674, +0x00013672, +0x00013671, +0x0001366f, +0x0001366e, +0x0001366d, +0x0001366b, +0x00013669, +0x00013668, +0x00013667, +0x00013665, +0x00013663, +0x00013662, +0x00013661, +0x00013660, +0x0001365d, +0x0001365c, +0x0001365b, +0x0001365a, +0x00013658, +0x00013656, +0x00013655, +0x00013653, +0x00013652, +0x00013650, +0x0001364f, +0x0001364d, +0x0001364c, +0x0001364b, +0x00013649, +0x00013647, +0x00013646, +0x00013645, +0x00013644, +0x00013641, +0x00013640, +0x0001363f, +0x0001363e, +0x0001363b, +0x0001363b, +0x00013639, +0x00013638, +0x00013636, +0x00013635, +0x00013633, +0x00013632, +0x00013630, +0x0001362f, +0x0001362e, +0x0001362c, +0x0001362a, +0x00013629, +0x00013628, +0x00013627, +0x00013624, +0x00013623, +0x00013622, +0x00013621, +0x0001361e, +0x0001361d, +0x0001361c, +0x0001361b, +0x00013619, +0x00013617, +0x00013616, +0x00013615, +0x00013613, +0x00013612, +0x00013610, +0x0001360f, +0x0001360d, +0x0001360c, +0x0001360b, +0x00013608, +0x00013607, +0x00013606, +0x00013605, +0x00013602, +0x00013601, +0x00013600, +0x000135ff, +0x000135fe, +0x000135fb, +0x000135fa, +0x000135f9, +0x000135f8, +0x000135f6, +0x000135f4, +0x000135f3, +0x000135f1, +0x000135f0, +0x000135ef, +0x000135ed, +0x000135eb, +0x000135ea, +0x000135e9, +0x000135e7, +0x000135e5, +0x000135e4, +0x000135e3, +0x000135e2, +0x000135df, +0x000135de, +0x000135dd, +0x000135dc, +0x000135da, +0x000135d8, +0x000135d7, +0x000135d6, +0x000135d4, +0x000135d3, +0x000135d1, +0x000135d0, +0x000135ce, +0x000135cd, +0x000135cb, +0x000135ca, +0x000135c8, +0x000135c7, +0x000135c6, +0x000135c3, +0x000135c2, +0x000135c1, +0x000135c0, +0x000135bf, +0x000135bc, +0x000135bb, +0x000135ba, +0x000135b9, +0x000135b7, +0x000135b5, +0x000135b4, +0x000135b3, +0x000135b1, +0x000135af, +0x000135ae, +0x000135ac, +0x000135ab, +0x000135aa, +0x000135a8, +0x000135a6, +0x000135a5, +0x000135a4, +0x000135a3, +0x000135a0, +0x0001359f, +0x0001359e, +0x0001359d, +0x0001359b, +0x00013599, +0x00013598, +0x00013597, +0x00013595, +0x00013593, +0x00013592, +0x00013591, +0x0001358f, +0x0001358e, +0x0001358c, +0x0001358b, +0x00013589, +0x00013588, +0x00013587, +0x00013584, +0x00013583, +0x00013582, +0x00013581, +0x0001357f, +0x0001357e, +0x0001357c, +0x0001357b, +0x00013579, +0x00013577, +0x00013576, +0x00013575, +0x00013574, +0x00013571, +0x00013570, +0x0001356f, +0x0001356e, +0x0001356d, +0x0001356a, +0x00013569, +0x00013568, +0x00013567, +0x00013565, +0x00013563, +0x00013562, +0x00013561, +0x0001355f, +0x0001355d, +0x0001355c, +0x0001355b, +0x00013559, +0x00013558, +0x00013556, +0x00013554, +0x00013553, +0x00013552, +0x00013551, +0x0001354e, +0x0001354d, +0x0001354c, +0x0001354b, +0x0001354a, +0x00013547, +0x00013546, +0x00013545, +0x00013544, +0x00013542, +0x00013540, +0x0001353f, +0x0001353e, +0x0001353c, +0x0001353b, +0x00013539, +0x00013538, +0x00013536, +0x00013535, +0x00013533, +0x00013531, +0x00013530, +0x0001352f, +0x0001352e, +0x0001352b, +0x0001352a, +0x00013529, +0x00013528, +0x00013527, +0x00013524, +0x00013523, +0x00013522, +0x00013521, +0x0001351f, +0x0001351d, +0x0001351c, +0x0001351b, +0x00013519, +0x00013518, +0x00013516, +0x00013515, +0x00013513, +0x00013512, +0x00013511, +0x0001350e, +0x0001350d, +0x0001350c, +0x0001350b, +0x00013508, +0x00013507, +0x00013506, +0x00013505, +0x00013504, +0x00013501, +0x00013500, +0x000134ff, +0x000134fe, +0x000134fc, +0x000134fa, +0x000134f9, +0x000134f8, +0x000134f6, +0x000134f5, +0x000134f3, +0x000134f2, +0x000134f0, +0x000134ef, +0x000134ee, +0x000134eb, +0x000134ea, +0x000134e9, +0x000134e8, +0x000134e7, +0x000134e4, +0x000134e3, +0x000134e2, +0x000134e1, +0x000134de, +0x000134dd, +0x000134dc, +0x000134db, +0x000134d9, +0x000134d7, +0x000134d6, +0x000134d5, +0x000134d3, +0x000134d2, +0x000134d0, +0x000134cf, +0x000134cd, +0x000134cc, +0x000134cb, +0x000134c8, +0x000134c7, +0x000134c6, +0x000134c4, +0x000134c3, +0x000134c2, +0x000134bf, +0x000134be, +0x000134bd, +0x000134bc, +0x000134ba, +0x000134b8, +0x000134b7, +0x000134b6, +0x000134b4, +0x000134b3, +0x000134b1, +0x000134b0, +0x000134ae, +0x000134ad, +0x000134ac, +0x000134aa, +0x000134a8, +0x000134a7, +0x000134a6, +0x000134a5, +0x000134a2, +0x000134a1, +0x000134a0, +0x0001349f, +0x0001349e, +0x0001349b, +0x0001349a, +0x00013499, +0x00013498, +0x00013496, +0x00013494, +0x00013493, +0x00013492, +0x00013490, +0x0001348e, +0x0001348d, +0x0001348c, +0x0001348a, +0x00013489, +0x00013487, +0x00013486, +0x00013484, +0x00013483, +0x00013482, +0x00013480, +0x0001347e, +0x0001347d, +0x0001347c, +0x0001347b, +0x00013478, +0x00013477, +0x00013476, +0x00013475, +0x00013474, +0x00013471, +0x00013470, +0x0001346f, +0x0001346d, +0x0001346c, +0x0001346a, +0x00013469, +0x00013467, +0x00013466, +0x00013465, +0x00013463, +0x00013461, +0x00013460, +0x0001345f, +0x0001345e, +0x0001345b, +0x0001345a, +0x00013459, +0x00013458, +0x00013457, +0x00013454, +0x00013453, +0x00013452, +0x00013451, +0x0001344f, +0x0001344d, +0x0001344c, +0x0001344b, +0x00013449, +0x00013448, +0x00013446, +0x00013445, +0x00013443, +0x00013442, +0x00013441, +0x0001343f, +0x0001343d, +0x0001343c, +0x0001343b, +0x0001343a, +0x00013437, +0x00013436, +0x00013435, +0x00013434, +0x00013431, +0x00013430, +0x0001342f, +0x0001342e, +0x0001342d, +0x0001342a, +0x00013429, +0x00013428, +0x00013427, +0x00013425, +0x00013423, +0x00013422, +0x00013420, +0x0001341f, +0x0001341e, +0x0001341c, +0x0001341a, +0x00013419, +0x00013418, +0x00013417, +0x00013414, +0x00013413, +0x00013412, +0x00013411, +0x00013410, +0x0001340d, +0x0001340c, +0x0001340b, +0x0001340a, +0x00013408, +0x00013406, +0x00013405, +0x00013404, +0x00013402, +0x00013401, +0x000133ff, +0x000133fe, +0x000133fc, +0x000133fb, +0x000133fa, +0x000133f8, +0x000133f6, +0x000133f5, +0x000133f4, +0x000133f3, +0x000133f0, +0x000133ef, +0x000133ee, +0x000133ed, +0x000133ec, +0x000133e9, +0x000133e8, +0x000133e7, +0x000133e6, +0x000133e4, +0x000133e2, +0x000133e1, +0x000133e0, +0x000133de, +0x000133dd, +0x000133db, +0x000133da, +0x000133d8, +0x000133d7, +0x000133d5, +0x000133d3, +0x000133d2, +0x000133d1, +0x000133d0, +0x000133cd, +0x000133cc, +0x000133cb, +0x000133ca, +0x000133c9, +0x000133c6, +0x000133c5, +0x000133c4, +0x000133c3, +0x000133c1, +0x000133bf, +0x000133be, +0x000133bd, +0x000133bb, +0x000133ba, +0x000133b8, +0x000133b7, +0x000133b5, +0x000133b4, +0x000133b3, +0x000133b1, +0x000133af, +0x000133ae, +0x000133ad, +0x000133ac, +0x000133a9, +0x000133a8, +0x000133a7, +0x000133a6, +0x000133a5, +0x000133a2, +0x000133a1, +0x000133a0, +0x0001339f, +0x0001339d, +0x0001339b, +0x0001339a, +0x00013399, +0x00013397, +0x00013396, +0x00013394, +0x00013393, +0x00013391, +0x00013390, +0x0001338f, +0x0001338d, +0x0001338b, +0x0001338a, +0x00013389, +0x00013388, +0x00013385, +0x00013384, +0x00013383, +0x00013382, +0x00013380, +0x0001337e, +0x0001337d, +0x0001337c, +0x0001337a, +0x00013378, +0x00013377, +0x00013376, +0x00013374, +0x00013373, +0x00013371, +0x00013370, +0x0001336e, +0x0001336d, +0x0001336c, +0x0001336a, +0x00013368, +0x00013367, +0x00013366, +0x00013365, +0x00013362, +0x00013361, +0x00013360, +0x0001335f, +0x0001335e, +0x0001335b, +0x0001335a, +0x00013359, +0x00013358, +0x00013356, +0x00013354, +0x00013353, +0x00013352, +0x00013350, +0x0001334f, +0x0001334e, +0x0001334c, +0x0001334a, +0x00013349, +0x00013348, +0x00013347, +0x00013344, +0x00013343, +0x00013342, +0x00013341, +0x00013340, +0x0001333d, +0x0001333c, +0x0001333b, +0x0001333a, +0x00013338, +0x00013336, +0x00013335, +0x00013334, +0x00013332, +0x00013331, +0x0001332f, +0x0001332e, +0x0001332c, +0x0001332b, +0x0001332a, +0x00013328, +0x00013326, +0x00013325, +0x00013324, +0x00013323, +0x00013320, +0x0001331f, +0x0001331e, +0x0001331d, +0x0001331c, +0x00013319, +0x00013318, +0x00013317, +0x00013316, +0x00013314, +0x00013312, +0x00013311, +0x00013310, +0x0001330e, +0x0001330d, +0x0001330b, +0x0001330a, +0x00013308, +0x00013307, +0x00013306, +0x00013304, +0x00013302, +0x00013301, +0x00013300, +0x000132ff, +0x000132fc, +0x000132fb, +0x000132fa, +0x000132f9, +0x000132f8, +0x000132f6, +0x000132f4, +0x000132f3, +0x000132f2, +0x000132f0, +0x000132ef, +0x000132ed, +0x000132ec, +0x000132ea, +0x000132e9, +0x000132e8, +0x000132e6, +0x000132e4, +0x000132e3, +0x000132e2, +0x000132e1, +0x000132de, +0x000132dd, +0x000132dc, +0x000132db, +0x000132da, +0x000132d7, +0x000132d6, +0x000132d5, +0x000132d4, +0x000132d2, +0x000132d0, +0x000132cf, +0x000132ce, +0x000132cc, +0x000132cb, +0x000132c9, +0x000132c8, +0x000132c6, +0x000132c5, +0x000132c4, +0x000132c2, +0x000132c0, +0x000132bf, +0x000132be, +0x000132bd, +0x000132ba, +0x000132b9, +0x000132b8, +0x000132b7, +0x000132b6, +0x000132b3, +0x000132b2, +0x000132b1, +0x000132b0, +0x000132ae, +0x000132ac, +0x000132ab, +0x000132aa, +0x000132a8, +0x000132a7, +0x000132a5, +0x000132a4, +0x000132a2, +0x000132a1, +0x000132a0, +0x0001329e, +0x0001329c, +0x0001329b, +0x0001329a, +0x00013298, +0x00013297, +0x00013295, +0x00013294, +0x00013293, +0x00013291, +0x0001328f, +0x0001328e, +0x0001328d, +0x0001328c, +0x00013289, +0x00013288, +0x00013287, +0x00013286, +0x00013285, +0x00013282, +0x00013281, +0x00013280, +0x0001327f, +0x0001327e, +0x0001327b, +0x0001327a, +0x00013279, +0x00013278, +0x00013276, +0x00013274, +0x00013273, +0x00013272, +0x00013270, +0x0001326f, +0x0001326d, +0x0001326c, +0x0001326a, +0x00013269, +0x00013268, +0x00013266, +0x00013264, +0x00013263, +0x00013262, +0x00013261, +0x0001325e, +0x0001325d, +0x0001325c, +0x0001325b, +0x0001325a, +0x00013258, +0x00013256, +0x00013255, +0x00013254, +0x00013252, +0x00013251, +0x0001324f, +0x0001324e, +0x0001324d, +0x0001324b, +0x0001324a, +0x00013248, +0x00013247, +0x00013245, +0x00013244, +0x00013243, +0x00013241, +0x0001323f, +0x0001323e, +0x0001323d, +0x0001323c, +0x00013239, +0x00013238, +0x00013237, +0x00013236, +0x00013235, +0x00013232, +0x00013231, +0x00013230, +0x0001322f, +0x0001322d, +0x0001322b, +0x0001322a, +0x00013229, +0x00013227, +0x00013226, +0x00013224, +0x00013223, +0x00013221, +0x00013220, +0x0001321f, +0x0001321e, +0x0001321b, +0x0001321a, +0x00013219, +0x00013218, +0x00013217, +0x00013214, +0x00013213, +0x00013212, +0x00013211, +0x00013210, +0x0001320d, +0x0001320c, +0x0001320b, +0x0001320a, +0x00013208, +0x00013206, +0x00013205, +0x00013204, +0x00013202, +0x00013201, +0x000131ff, +0x000131fe, +0x000131fc, +0x000131fb, +0x000131fa, +0x000131f8, +0x000131f6, +0x000131f5, +0x000131f4, +0x000131f3, +0x000131f0, +0x000131ef, +0x000131ee, +0x000131ed, +0x000131ec, +0x000131e9, +0x000131e8, +0x000131e7, +0x000131e6, +0x000131e5, +0x000131e3, +0x000131e1, +0x000131e0, +0x000131df, +0x000131dd, +0x000131dc, +0x000131da, +0x000131d9, +0x000131d7, +0x000131d6, +0x000131d5, +0x000131d3, +0x000131d1, +0x000131d0, +0x000131cf, +0x000131ce, +0x000131cb, +0x000131ca, +0x000131c9, +0x000131c8, +0x000131c7, +0x000131c4, +0x000131c3, +0x000131c2, +0x000131c1, +0x000131bf, +0x000131bd, +0x000131bc, +0x000131bb, +0x000131b9, +0x000131b8, +0x000131b6, +0x000131b5, +0x000131b4, +0x000131b2, +0x000131b1, +0x000131af, +0x000131ae, +0x000131ac, +0x000131ab, +0x000131aa, +0x000131a8, +0x000131a6, +0x000131a5, +0x000131a4, +0x000131a3, +0x000131a2, +0x0001319f, +0x0001319e, +0x0001319d, +0x0001319c, +0x0001319a, +0x00013198, +0x00013197, +0x00013196, +0x00013194, +0x00013193, +0x00013191, +0x00013190, +0x0001318e, +0x0001318d, +0x0001318c, +0x0001318a, +0x00013188, +0x00013187, +0x00013186, +0x00013185, +0x00013182, +0x00013181, +0x00013180, +0x0001317f, +0x0001317e, +0x0001317b, +0x0001317a, +0x00013179, +0x00013178, +0x00013177, +0x00013174, +0x00013173, +0x00013172, +0x00013171, +0x0001316f, +0x0001316d, +0x0001316c, +0x0001316b, +0x00013169, +0x00013168, +0x00013167, +0x00013165, +0x00013163, +0x00013162, +0x00013161, +0x00013160, +0x0001315d, +0x0001315c, +0x0001315b, +0x0001315a, +0x00013159, +0x00013156, +0x00013155, +0x00013154, +0x00013153, +0x00013151, +0x0001314f, +0x0001314e, +0x0001314d, +0x0001314c, +0x0001314a, +0x00013148, +0x00013147, +0x00013146, +0x00013144, +0x00013143, +0x00013141, +0x00013140, +0x0001313e, +0x0001313d, +0x0001313c, +0x0001313a, +0x00013138, +0x00013137, +0x00013136, +0x00013135, +0x00013132, +0x00013131, +0x00013130, +0x0001312f, +0x0001312e, +0x0001312c, +0x0001312b, +0x0001312a, +0x00013129, +0x00013126, +0x00013125, +0x00013124, +0x00013123, +0x00013121, +0x00013120, +0x0001311e, +0x0001311d, +0x0001311b, +0x0001311a, +0x00013119, +0x00013117, +0x00013115, +0x00013114, +0x00013113, +0x00013112, +0x0001310f, +0x0001310e, +0x0001310d, +0x0001310c, +0x0001310b, +0x00013108, +0x00013107, +0x00013106, +0x00013105, +0x00013104, +0x00013102, +0x00013100, +0x000130ff, +0x000130fe, +0x000130fc, +0x000130fb, +0x000130f9, +0x000130f8, +0x000130f6, +0x000130f5, +0x000130f4, +0x000130f2, +0x000130f1, +0x000130ef, +0x000130ee, +0x000130ed, +0x000130eb, +0x000130e9, +0x000130e8, +0x000130e7, +0x000130e6, +0x000130e3, +0x000130e2, +0x000130e1, +0x000130e0, +0x000130df, +0x000130dd, +0x000130db, +0x000130da, +0x000130d9, +0x000130d7, +0x000130d6, +0x000130d4, +0x000130d3, +0x000130d2, +0x000130d0, +0x000130cf, +0x000130cd, +0x000130cc, +0x000130ca, +0x000130c9, +0x000130c8, +0x000130c6, +0x000130c4, +0x000130c3, +0x000130c2, +0x000130c1, +0x000130c0, +0x000130bd, +0x000130bc, +0x000130bb, +0x000130ba, +0x000130b9, +0x000130b6, +0x000130b5, +0x000130b4, +0x000130b3, +0x000130b1, +0x000130af, +0x000130ae, +0x000130ad, +0x000130ab, +0x000130aa, +0x000130a8, +0x000130a7, +0x000130a5, +0x000130a4, +0x000130a3, +0x000130a1, +0x0001309f, +0x0001309e, +0x0001309d, +0x0001309c, +0x0001309b, +0x00013098, +0x00013097, +0x00013096, +0x00013095, +0x00013094, +0x00013091, +0x00013090, +0x0001308f, +0x0001308e, +0x0001308c, +0x0001308a, +0x00013089, +0x00013088, +0x00013086, +0x00013085, +0x00013083, +0x00013082, +0x00013081, +0x0001307f, +0x0001307e, +0x0001307d, +0x0001307b, +0x00013079, +0x00013078, +0x00013077, +0x00013076, +0x00013074, +0x00013072, +0x00013071, +0x00013070, +0x0001306e, +0x0001306d, +0x0001306c, +0x0001306a, +0x00013069, +0x00013067, +0x00013066, +0x00013065, +0x00013063, +0x00013061, +0x00013060, +0x0001305f, +0x0001305e, +0x0001305b, +0x0001305a, +0x00013059, +0x00013058, +0x00013057, +0x00013056, +0x00013053, +0x00013052, +0x00013051, +0x00013050, +0x0001304e, +0x0001304c, +0x0001304b, +0x0001304a, +0x00013048, +0x00013047, +0x00013045, +0x00013044, +0x00013043, +0x00013041, +0x00013040, +0x0001303f, +0x0001303d, +0x0001303b, +0x0001303a, +0x00013039, +0x00013038, +0x00013035, +0x00013034, +0x00013033, +0x00013032, +0x00013031, +0x0001302e, +0x0001302d, +0x0001302c, +0x0001302b, +0x0001302a, +0x00013028, +0x00013026, +0x00013025, +0x00013024, +0x00013022, +0x00013021, +0x0001301f, +0x0001301e, +0x0001301d, +0x0001301b, +0x0001301a, +0x00013018, +0x00013017, +0x00013015, +0x00013014, +0x00013013, +0x00013012, +0x0001300f, +0x0001300e, +0x0001300d, +0x0001300c, +0x0001300b, +0x00013008, +0x00013007, +0x00013006, +0x00013005, +0x00013004, +0x00013001, +0x00013000, +0x00012fff, +0x00012ffe, +0x00012ffc, +0x00012ffb, +0x00012ff9, +0x00012ff8, +0x00012ff7, +0x00012ff5, +0x00012ff4, +0x00012ff2, +0x00012ff1, +0x00012fef, +0x00012fee, +0x00012fed, +0x00012feb, +0x00012fe9, +0x00012fe8, +0x00012fe7, +0x00012fe6, +0x00012fe5, +0x00012fe2, +0x00012fe1, +0x00012fe0, +0x00012fdf, +0x00012fde, +0x00012fdb, +0x00012fda, +0x00012fd9, +0x00012fd8, +0x00012fd6, +0x00012fd4, +0x00012fd3, +0x00012fd2, +0x00012fd1, +0x00012fcf, +0x00012fce, +0x00012fcc, +0x00012fcb, +0x00012fc9, +0x00012fc8, +0x00012fc7, +0x00012fc5, +0x00012fc3, +0x00012fc2, +0x00012fc1, +0x00012fbf, +0x00012fbd, +0x00012fbc, +0x00012fbb, +0x00012fba, +0x00012fb7, +0x00012fb6, +0x00012fb5, +0x00012fb4, +0x00012fb3, +0x00012fb2, +0x00012faf, +0x00012fae, +0x00012fad, +0x00012fac, +0x00012faa, +0x00012fa8, +0x00012fa7, +0x00012fa6, +0x00012fa5, +0x00012fa3, +0x00012fa2, +0x00012fa0, +0x00012f9f, +0x00012f9d, +0x00012f9c, +0x00012f9b, +0x00012f99, +0x00012f98, +0x00012f96, +0x00012f95, +0x00012f94, +0x00012f93, +0x00012f90, +0x00012f8f, +0x00012f8e, +0x00012f8d, +0x00012f8c, +0x00012f89, +0x00012f88, +0x00012f87, +0x00012f86, +0x00012f85, +0x00012f82, +0x00012f81, +0x00012f80, +0x00012f7f, +0x00012f7d, +0x00012f7c, +0x00012f7a, +0x00012f79, +0x00012f78, +0x00012f76, +0x00012f75, +0x00012f73, +0x00012f72, +0x00012f70, +0x00012f6f, +0x00012f6e, +0x00012f6d, +0x00012f6b, +0x00012f69, +0x00012f68, +0x00012f67, +0x00012f66, +0x00012f63, +0x00012f62, +0x00012f61, +0x00012f60, +0x00012f5f, +0x00012f5e, +0x00012f5b, +0x00012f5a, +0x00012f59, +0x00012f58, +0x00012f56, +0x00012f54, +0x00012f53, +0x00012f52, +0x00012f50, +0x00012f4f, +0x00012f4e, +0x00012f4c, +0x00012f4b, +0x00012f49, +0x00012f48, +0x00012f47, +0x00012f45, +0x00012f43, +0x00012f42, +0x00012f41, +0x00012f40, +0x00012f3e, +0x00012f3c, +0x00012f3b, +0x00012f3a, +0x00012f39, +0x00012f38, +0x00012f35, +0x00012f34, +0x00012f33, +0x00012f32, +0x00012f31, +0x00012f2e, +0x00012f2d, +0x00012f2c, +0x00012f2b, +0x00012f29, +0x00012f28, +0x00012f26, +0x00012f25, +0x00012f24, +0x00012f22, +0x00012f21, +0x00012f1f, +0x00012f1e, +0x00012f1c, +0x00012f1b, +0x00012f1a, +0x00012f19, +0x00012f16, +0x00012f15, +0x00012f14, +0x00012f13, +0x00012f12, +0x00012f0f, +0x00012f0e, +0x00012f0d, +0x00012f0c, +0x00012f0b, +0x00012f09, +0x00012f07, +0x00012f06, +0x00012f05, +0x00012f04, +0x00012f02, +0x00012f00, +0x00012eff, +0x00012efe, +0x00012efc, +0x00012efb, +0x00012ef9, +0x00012ef8, +0x00012ef7, +0x00012ef5, +0x00012ef4, +0x00012ef3, +0x00012ef1, +0x00012eef, +0x00012eee, +0x00012eed, +0x00012eec, +0x00012eea, +0x00012ee8, +0x00012ee7, +0x00012ee6, +0x00012ee5, +0x00012ee4, +0x00012ee1, +0x00012ee0, +0x00012edf, +0x00012ede, +0x00012edc, +0x00012eda, +0x00012ed9, +0x00012ed8, +0x00012ed7, +0x00012ed5, +0x00012ed4, +0x00012ed2, +0x00012ed1, +0x00012ecf, +0x00012ece, +0x00012ecd, +0x00012ecb, +0x00012eca, +0x00012ec8, +0x00012ec7, +0x00012ec6, +0x00012ec5, +0x00012ec2, +0x00012ec1, +0x00012ec0, +0x00012ebf, +0x00012ebe, +0x00012ebb, +0x00012eba, +0x00012eb9, +0x00012eb8, +0x00012eb7, +0x00012eb5, +0x00012eb3, +0x00012eb2, +0x00012eb1, +0x00012eb0, +0x00012eae, +0x00012eac, +0x00012eab, +0x00012eaa, +0x00012ea8, +0x00012ea7, +0x00012ea5, +0x00012ea4, +0x00012ea2, +0x00012ea1, +0x00012ea0, +0x00012e9f, +0x00012e9d, +0x00012e9b, +0x00012e9a, +0x00012e99, +0x00012e98, +0x00012e95, +0x00012e94, +0x00012e93, +0x00012e92, +0x00012e91, +0x00012e90, +0x00012e8d, +0x00012e8c, +0x00012e8b, +0x00012e8a, +0x00012e88, +0x00012e86, +0x00012e85, +0x00012e84, +0x00012e83, +0x00012e81, +0x00012e80, +0x00012e7e, +0x00012e7d, +0x00012e7b, +0x00012e7a, +0x00012e79, +0x00012e77, +0x00012e76, +0x00012e74, +0x00012e73, +0x00012e72, +0x00012e71, +0x00012e6e, +0x00012e6d, +0x00012e6c, +0x00012e6b, +0x00012e6a, +0x00012e67, +0x00012e66, +0x00012e65, +0x00012e64, +0x00012e63, +0x00012e60, +0x00012e5f, +0x00012e5e, +0x00012e5d, +0x00012e5c, +0x00012e5a, +0x00012e58, +0x00012e57, +0x00012e56, +0x00012e55, +0x00012e53, +0x00012e51, +0x00012e50, +0x00012e4f, +0x00012e4e, +0x00012e4d, +0x00012e4a, +0x00012e49, +0x00012e48, +0x00012e47, +0x00012e46, +0x00012e43, +0x00012e42, +0x00012e41, +0x00012e40, +0x00012e3f, +0x00012e3d, +0x00012e3b, +0x00012e3a, +0x00012e39, +0x00012e37, +0x00012e36, +0x00012e34, +0x00012e33, +0x00012e32, +0x00012e30, +0x00012e2f, +0x00012e2e, +0x00012e2c, +0x00012e2a, +0x00012e29, +0x00012e28, +0x00012e27, +0x00012e25, +0x00012e23, +0x00012e22, +0x00012e21, +0x00012e20, +0x00012e1f, +0x00012e1c, +0x00012e1b, +0x00012e1a, +0x00012e19, +0x00012e18, +0x00012e16, +0x00012e14, +0x00012e13, +0x00012e12, +0x00012e11, +0x00012e0f, +0x00012e0d, +0x00012e0c, +0x00012e0b, +0x00012e09, +0x00012e08, +0x00012e07, +0x00012e05, +0x00012e04, +0x00012e02, +0x00012e01, +0x00012e00, +0x00012dfe, +0x00012dfc, +0x00012dfb, +0x00012dfa, +0x00012df9, +0x00012df8, +0x00012df5, +0x00012df4, +0x00012df3, +0x00012df2, +0x00012df1, +0x00012dee, +0x00012ded, +0x00012dec, +0x00012deb, +0x00012dea, +0x00012de8, +0x00012de6, +0x00012de5, +0x00012de4, +0x00012de3, +0x00012de1, +0x00012de0, +0x00012dde, +0x00012ddd, +0x00012ddb, +0x00012dda, +0x00012dd9, +0x00012dd7, +0x00012dd6, +0x00012dd4, +0x00012dd3, +0x00012dd2, +0x00012dd1, +0x00012dce, +0x00012dcd, +0x00012dcc, +0x00012dcb, +0x00012dca, +0x00012dc7, +0x00012dc6, +0x00012dc5, +0x00012dc4, +0x00012dc3, +0x00012dc1, +0x00012dbf, +0x00012dbe, +0x00012dbd, +0x00012dbc, +0x00012dba, +0x00012db8, +0x00012db7, +0x00012db6, +0x00012db5, +0x00012db3, +0x00012db2, +0x00012db0, +0x00012daf, +0x00012dad, +0x00012dac, +0x00012dab, +0x00012da9, +0x00012da8, +0x00012da6, +0x00012da5, +0x00012da3, +0x00012da2, +0x00012da1, +0x00012da0, +0x00012d9e, +0x00012d9c, +0x00012d9b, +0x00012d9a, +0x00012d99, +0x00012d97, +0x00012d95, +0x00012d94, +0x00012d93, +0x00012d92, +0x00012d91, +0x00012d8e, +0x00012d8d, +0x00012d8c, +0x00012d8b, +0x00012d8a, +0x00012d88, +0x00012d86, +0x00012d85, +0x00012d84, +0x00012d83, +0x00012d81, +0x00012d7f, +0x00012d7e, +0x00012d7d, +0x00012d7b, +0x00012d7a, +0x00012d79, +0x00012d77, +0x00012d76, +0x00012d74, +0x00012d73, +0x00012d72, +0x00012d71, +0x00012d6f, +0x00012d6d, +0x00012d6c, +0x00012d6b, +0x00012d6a, +0x00012d67, +0x00012d66, +0x00012d65, +0x00012d64, +0x00012d63, +0x00012d62, +0x00012d5f, +0x00012d5e, +0x00012d5d, +0x00012d5c, +0x00012d5b, +0x00012d59, +0x00012d57, +0x00012d56, +0x00012d55, +0x00012d53, +0x00012d52, +0x00012d51, +0x00012d4f, +0x00012d4e, +0x00012d4c, +0x00012d4b, +0x00012d4a, +0x00012d48, +0x00012d47, +0x00012d45, +0x00012d44, +0x00012d43, +0x00012d42, +0x00012d3f, +0x00012d3e, +0x00012d3d, +0x00012d3c, +0x00012d3b, +0x00012d3a, +0x00012d37, +0x00012d36, +0x00012d35, +0x00012d34, +0x00012d33, +0x00012d30, +0x00012d2f, +0x00012d2e, +0x00012d2d, +0x00012d2c, +0x00012d2a, +0x00012d28, +0x00012d27, +0x00012d26, +0x00012d24, +0x00012d23, +0x00012d22, +0x00012d20, +0x00012d1f, +0x00012d1d, +0x00012d1c, +0x00012d1b, +0x00012d19, +0x00012d18, +0x00012d16, +0x00012d15, +0x00012d14, +0x00012d13, +0x00012d10, +0x00012d0f, +0x00012d0e, +0x00012d0d, +0x00012d0c, +0x00012d0b, +0x00012d08, +0x00012d07, +0x00012d06, +0x00012d05, +0x00012d04, +0x00012d01, +0x00012d00, +0x00012cff, +0x00012cfe, +0x00012cfc, +0x00012cfb, +0x00012cf9, +0x00012cf8, +0x00012cf7, +0x00012cf5, +0x00012cf4, +0x00012cf3, +0x00012cf1, +0x00012cf0, +0x00012cee, +0x00012ced, +0x00012cec, +0x00012cea, +0x00012ce8, +0x00012ce7, +0x00012ce6, +0x00012ce5, +0x00012ce4, +0x00012ce1, +0x00012ce0, +0x00012cdf, +0x00012cde, +0x00012cdd, +0x00012cdc, +0x00012cd9, +0x00012cd8, +0x00012cd7, +0x00012cd6, +0x00012cd4, +0x00012cd3, +0x00012cd1, +0x00012cd0, +0x00012ccf, +0x00012ccd, +0x00012ccc, +0x00012cca, +0x00012cc9, +0x00012cc8, +0x00012cc6, +0x00012cc5, +0x00012cc4, +0x00012cc2, +0x00012cc1, +0x00012cbf, +0x00012cbe, +0x00012cbd, +0x00012cbc, +0x00012cb9, +0x00012cb8, +0x00012cb7, +0x00012cb6, +0x00012cb5, +0x00012cb2, +0x00012cb1, +0x00012cb0, +0x00012caf, +0x00012cae, +0x00012cad, +0x00012caa, +0x00012ca9, +0x00012ca8, +0x00012ca7, +0x00012ca5, +0x00012ca4, +0x00012ca2, +0x00012ca1, +0x00012ca0, +0x00012c9e, +0x00012c9d, +0x00012c9b, +0x00012c9a, +0x00012c99, +0x00012c97, +0x00012c96, +0x00012c95, +0x00012c93, +0x00012c91, +0x00012c90, +0x00012c8f, +0x00012c8e, +0x00012c8d, +0x00012c8a, +0x00012c89, +0x00012c88, +0x00012c87, +0x00012c86, +0x00012c83, +0x00012c82, +0x00012c81, +0x00012c80, +0x00012c7f, +0x00012c7d, +0x00012c7b, +0x00012c7a, +0x00012c79, +0x00012c78, +0x00012c76, +0x00012c75, +0x00012c73, +0x00012c72, +0x00012c71, +0x00012c6f, +0x00012c6e, +0x00012c6c, +0x00012c6b, +0x00012c6a, +0x00012c68, +0x00012c67, +0x00012c66, +0x00012c64, +0x00012c62, +0x00012c61, +0x00012c60, +0x00012c5f, +0x00012c5e, +0x00012c5b, +0x00012c5a, +0x00012c59, +0x00012c58, +0x00012c57, +0x00012c56, +0x00012c53, +0x00012c52, +0x00012c51, +0x00012c50, +0x00012c4e, +0x00012c4c, +0x00012c4b, +0x00012c4a, +0x00012c49, +0x00012c47, +0x00012c46, +0x00012c45, +0x00012c43, +0x00012c42, +0x00012c40, +0x00012c3f, +0x00012c3e, +0x00012c3d, +0x00012c3b, +0x00012c39, +0x00012c38, +0x00012c37, +0x00012c36, +0x00012c35, +0x00012c32, +0x00012c31, +0x00012c30, +0x00012c2f, +0x00012c2e, +0x00012c2d, +0x00012c2a, +0x00012c29, +0x00012c28, +0x00012c27, +0x00012c26, +0x00012c24, +0x00012c22, +0x00012c21, +0x00012c20, +0x00012c1e, +0x00012c1d, +0x00012c1c, +0x00012c1a, +0x00012c19, +0x00012c17, +0x00012c16, +0x00012c15, +0x00012c13, +0x00012c12, +0x00012c10, +0x00012c0f, +0x00012c0e, +0x00012c0d, +0x00012c0b, +0x00012c09, +0x00012c08, +0x00012c07, +0x00012c06, +0x00012c05, +0x00012c02, +0x00012c01, +0x00012c00, +0x00012bff, +0x00012bfe, +0x00012bfc, +0x00012bfa, +0x00012bf9, +0x00012bf8, +0x00012bf7, +0x00012bf5, +0x00012bf4, +0x00012bf2, +0x00012bf1, +0x00012bf0, +0x00012bee, +0x00012bed, +0x00012beb, +0x00012bea, +0x00012be9, +0x00012be7, +0x00012be6, +0x00012be5, +0x00012be3, +0x00012be2, +0x00012be0, +0x00012bdf, +0x00012bde, +0x00012bdd, +0x00012bdb, +0x00012bd9, +0x00012bd8, +0x00012bd7, +0x00012bd6, +0x00012bd5, +0x00012bd2, +0x00012bd1, +0x00012bd0, +0x00012bcf, +0x00012bce, +0x00012bcc, +0x00012bca, +0x00012bc9, +0x00012bc8, +0x00012bc7, +0x00012bc5, +0x00012bc4, +0x00012bc2, +0x00012bc1, +0x00012bc0, +0x00012bbe, +0x00012bbd, +0x00012bbb, +0x00012bba, +0x00012bb9, +0x00012bb7, +0x00012bb6, +0x00012bb5, +0x00012bb3, +0x00012bb1, +0x00012bb0, +0x00012baf, +0x00012bae, +0x00012bad, +0x00012baa, +0x00012ba9, +0x00012ba8, +0x00012ba7, +0x00012ba6, +0x00012ba5, +0x00012ba2, +0x00012ba1, +0x00012ba0, +0x00012b9f, +0x00012b9e, +0x00012b9c, +0x00012b9a, +0x00012b99, +0x00012b98, +0x00012b97, +0x00012b94, +0x00012b93, +0x00012b92, +0x00012b91, +0x00012b90, +0x00012b8e, +0x00012b8c, +0x00012b8b, +0x00012b8a, +0x00012b89, +0x00012b87, +0x00012b86, +0x00012b84, +0x00012b83, +0x00012b82, +0x00012b80, +0x00012b7f, +0x00012b7e, +0x00012b7c, +0x00012b7b, +0x00012b79, +0x00012b78, +0x00012b77, +0x00012b76, +0x00012b74, +0x00012b72, +0x00012b71, +0x00012b70, +0x00012b6f, +0x00012b6e, +0x00012b6b, +0x00012b6a, +0x00012b69, +0x00012b68, +0x00012b67, +0x00012b66, +0x00012b63, +0x00012b62, +0x00012b61, +0x00012b60, +0x00012b5f, +0x00012b5d, +0x00012b5b, +0x00012b5a, +0x00012b59, +0x00012b58, +0x00012b56, +0x00012b55, +0x00012b53, +0x00012b52, +0x00012b51, +0x00012b4f, +0x00012b4e, +0x00012b4d, +0x00012b4b, +0x00012b4a, +0x00012b48, +0x00012b47, +0x00012b46, +0x00012b45, +0x00012b43, +0x00012b41, +0x00012b40, +0x00012b3f, +0x00012b3e, +0x00012b3c, +0x00012b3a, +0x00012b39, +0x00012b38, +0x00012b37, +0x00012b36, +0x00012b33, +0x00012b32, +0x00012b31, +0x00012b30, +0x00012b2f, +0x00012b2e, +0x00012b2b, +0x00012b2a, +0x00012b29, +0x00012b28, +0x00012b27, +0x00012b25, +0x00012b23, +0x00012b22, +0x00012b21, +0x00012b20, +0x00012b1e, +0x00012b1d, +0x00012b1b, +0x00012b1a, +0x00012b19, +0x00012b17, +0x00012b16, +0x00012b15, +0x00012b13, +0x00012b12, +0x00012b10, +0x00012b0f, +0x00012b0e, +0x00012b0d, +0x00012b0b, +0x00012b09, +0x00012b08, +0x00012b07, +0x00012b06, +0x00012b05, +0x00012b02, +0x00012b01, +0x00012b00, +0x00012aff, +0x00012afe, +0x00012afc, +0x00012afa, +0x00012af9, +0x00012af8, +0x00012af7, +0x00012af5, +0x00012af4, +0x00012af2, +0x00012af1, +0x00012af0, +0x00012aee, +0x00012aed, +0x00012aec, +0x00012aea, +0x00012ae9, +0x00012ae7, +0x00012ae6, +0x00012ae5, +0x00012ae4, +0x00012ae2, +0x00012ae0, +0x00012adf, +0x00012ade, +0x00012add, +0x00012adc, +0x00012ad9, +0x00012ad8, +0x00012ad7, +0x00012ad6, +0x00012ad5, +0x00012ad4, +0x00012ad1, +0x00012ad0, +0x00012acf, +0x00012ace, +0x00012acd, +0x00012acb, +0x00012ac9, +0x00012ac8, +0x00012ac7, +0x00012ac6, +0x00012ac4, +0x00012ac3, +0x00012ac1, +0x00012ac0, +0x00012abf, +0x00012abd, +0x00012abc, +0x00012abb, +0x00012ab9, +0x00012ab8, +0x00012ab6, +0x00012ab5, +0x00012ab4, +0x00012ab3, +0x00012ab1, +0x00012aaf, +0x00012aae, +0x00012aad, +0x00012aac, +0x00012aab, +0x00012aa8, +0x00012aa7, +0x00012aa6, +0x00012aa5, +0x00012aa4, +0x00012aa3, +0x00012aa0, +0x00012a9f, +0x00012a9e, +0x00012a9d, +0x00012a9c, +0x00012a9a, +0x00012a98, +0x00012a97, +0x00012a96, +0x00012a95, +0x00012a93, +0x00012a92, +0x00012a90, +0x00012a8f, +0x00012a8e, +0x00012a8c, +0x00012a8b, +0x00012a89, +0x00012a88, +0x00012a87, +0x00012a85, +0x00012a84, +0x00012a83, +0x00012a81, +0x00012a80, +0x00012a7e, +0x00012a7d, +0x00012a7c, +0x00012a7b, +0x00012a79, +0x00012a77, +0x00012a76, +0x00012a75, +0x00012a74, +0x00012a73, +0x00012a70, +0x00012a6f, +0x00012a6e, +0x00012a6d, +0x00012a6c, +0x00012a6b, +0x00012a68, +0x00012a67, +0x00012a66, +0x00012a65, +0x00012a63, +0x00012a62, +0x00012a60, +0x00012a5f, +0x00012a5e, +0x00012a5c, +0x00012a5b, +0x00012a5a, +0x00012a58, +0x00012a57, +0x00012a55, +0x00012a54, +0x00012a53, +0x00012a52, +0x00012a50, +0x00012a4e, +0x00012a4d, +0x00012a4c, +0x00012a4b, +0x00012a4a, +0x00012a47, +0x00012a46, +0x00012a45, +0x00012a44, +0x00012a43, +0x00012a42, +0x00012a3f, +0x00012a3e, +0x00012a3d, +0x00012a3c, +0x00012a3b, +0x00012a39, +0x00012a38, +0x00012a37, +0x00012a36, +0x00012a34, +0x00012a33, +0x00012a31, +0x00012a30, +0x00012a2f, +0x00012a2d, +0x00012a2c, +0x00012a2b, +0x00012a29, +0x00012a28, +0x00012a26, +0x00012a25, +0x00012a24, +0x00012a23, +0x00012a21, +0x00012a1f, +0x00012a1e, +0x00012a1d, +0x00012a1c, +0x00012a1b, +0x00012a18, +0x00012a17, +0x00012a16, +0x00012a15, +0x00012a14, +0x00012a13, +0x00012a10, +0x00012a0f, +0x00012a0e, +0x00012a0d, +0x00012a0c, +0x00012a0a, +0x00012a08, +0x00012a07, +0x00012a06, +0x00012a05, +0x00012a03, +0x00012a02, +0x00012a00, +0x000129ff, +0x000129fe, +0x000129fd, +0x000129fb, +0x000129fa, +0x000129f8, +0x000129f7, +0x000129f6, +0x000129f4, +0x000129f3, +0x000129f2, +0x000129f0, +0x000129ef, +0x000129ed, +0x000129ec, +0x000129eb, +0x000129ea, +0x000129e8, +0x000129e6, +0x000129e5, +0x000129e4, +0x000129e3, +0x000129e2, +0x000129e1, +0x000129de, +0x000129dd, +0x000129dc, +0x000129db, +0x000129da, +0x000129d8, +0x000129d6, +0x000129d5, +0x000129d4, +0x000129d3, +0x000129d1, +0x000129d0, +0x000129ce, +0x000129cd, +0x000129cc, +0x000129ca, +0x000129c9, +0x000129c8, +0x000129c6, +0x000129c5, +0x000129c3, +0x000129c2, +0x000129c1, +0x000129c0, +0x000129be, +0x000129bc, +0x000129bb, +0x000129ba, +0x000129b9, +0x000129b8, +0x000129b6, +0x000129b4, +0x000129b3, +0x000129b2, +0x000129b1, +0x000129b0, +0x000129ad, +0x000129ac, +0x000129ab, +0x000129aa, +0x000129a9, +0x000129a8, +0x000129a5, +0x000129a4, +0x000129a3, +0x000129a2, +0x000129a1, +0x0001299f, +0x0001299d, +0x0001299c, +0x0001299b, +0x0001299a, +0x00012998, +0x00012997, +0x00012995, +0x00012994, +0x00012993, +0x00012991, +0x00012990, +0x0001298f, +0x0001298e, +0x0001298c, +0x0001298a, +0x00012989, +0x00012988, +0x00012987, +0x00012985, +0x00012984, +0x00012982, +0x00012981, +0x00012980, +0x0001297e, +0x0001297d, +0x0001297c, +0x0001297b, +0x00012979, +0x00012977, +0x00012976, +0x00012975, +0x00012974, +0x00012973, +0x00012971, +0x0001296f, +0x0001296e, +0x0001296d, +0x0001296c, +0x0001296b, +0x00012968, +0x00012967, +0x00012966, +0x00012965, +0x00012964, +0x00012963, +0x00012960, +0x0001295f, +0x0001295e, +0x0001295d, +0x0001295c, +0x0001295a, +0x00012959, +0x00012957, +0x00012956, +0x00012955, +0x00012954, +0x00012952, +0x00012951, +0x0001294f, +0x0001294e, +0x0001294d, +0x0001294b, +0x0001294a, +0x00012949, +0x00012947, +0x00012946, +0x00012944, +0x00012943, +0x00012942, +0x00012941, +0x0001293f, +0x0001293d, +0x0001293c, +0x0001293b, +0x0001293a, +0x00012939, +0x00012938, +0x00012935, +0x00012934, +0x00012933, +0x00012932, +0x00012931, +0x00012930, +0x0001292d, +0x0001292c, +0x0001292b, +0x0001292a, +0x00012929, +0x00012927, +0x00012925, +0x00012924, +0x00012923, +0x00012922, +0x00012920, +0x0001291f, +0x0001291d, +0x0001291c, +0x0001291b, +0x0001291a, +0x00012918, +0x00012917, +0x00012915, +0x00012914, +0x00012913, +0x00012911, +0x00012910, +0x0001290f, +0x0001290e, +0x0001290c, +0x0001290a, +0x00012909, +0x00012908, +0x00012907, +0x00012906, +0x00012903, +0x00012902, +0x00012901, +0x00012900, +0x000128ff, +0x000128fe, +0x000128fb, +0x000128fa, +0x000128f9, +0x000128f8, +0x000128f7, +0x000128f6, +0x000128f3, +0x000128f2, +0x000128f1, +0x000128f0, +0x000128ef, +0x000128ed, +0x000128ec, +0x000128ea, +0x000128e9, +0x000128e8, +0x000128e6, +0x000128e5, +0x000128e4, +0x000128e2, +0x000128e1, +0x000128e0, +0x000128de, +0x000128dd, +0x000128dc, +0x000128da, +0x000128d9, +0x000128d7, +0x000128d6, +0x000128d5, +0x000128d4, +0x000128d2, +0x000128d0, +0x000128cf, +0x000128ce, +0x000128cd, +0x000128cc, +0x000128cb, +0x000128c8, +0x000128c7, +0x000128c6, +0x000128c5, +0x000128c4, +0x000128c3, +0x000128c0, +0x000128bf, +0x000128be, +0x000128bd, +0x000128bc, +0x000128ba, +0x000128b8, +0x000128b7, +0x000128b6, +0x000128b5, +0x000128b3, +0x000128b2, +0x000128b0, +0x000128af, +0x000128ae, +0x000128ac, +0x000128ab, +0x000128aa, +0x000128a9, +0x000128a7, +0x000128a6, +0x000128a4, +0x000128a3, +0x000128a2, +0x000128a1, +0x0001289f, +0x0001289d, +0x0001289c, +0x0001289b, +0x0001289a, +0x00012899, +0x00012896, +0x00012895, +0x00012894, +0x00012893, +0x00012892, +0x00012891, +0x0001288e, +0x0001288d, +0x0001288c, +0x0001288b, +0x0001288a, +0x00012889, +0x00012887, +0x00012885, +0x00012884, +0x00012883, +0x00012882, +0x00012880, +0x0001287f, +0x0001287d, +0x0001287c, +0x0001287b, +0x00012879, +0x00012878, +0x00012877, +0x00012875, +0x00012874, +0x00012872, +0x00012871, +0x00012870, +0x0001286f, +0x0001286d, +0x0001286c, +0x0001286a, +0x00012869, +0x00012868, +0x00012867, +0x00012866, +0x00012863, +0x00012862, +0x00012861, +0x00012860, +0x0001285f, +0x0001285e, +0x0001285b, +0x0001285a, +0x00012859, +0x00012858, +0x00012857, +0x00012855, +0x00012853, +0x00012852, +0x00012851, +0x00012850, +0x0001284e, +0x0001284d, +0x0001284b, +0x0001284a, +0x00012849, +0x00012848, +0x00012846, +0x00012845, +0x00012844, +0x00012842, +0x00012841, +0x0001283f, +0x0001283e, +0x0001283d, +0x0001283c, +0x0001283a, +0x00012838, +0x00012837, +0x00012836, +0x00012835, +0x00012834, +0x00012833, +0x00012832, +0x0001282f, +0x0001282e, +0x0001282d, +0x0001282c, +0x0001282b, +0x0001282a, +0x00012827, +0x00012826, +0x00012825, +0x00012824, +0x00012823, +0x00012822, +0x00012820, +0x0001281e, +0x0001281d, +0x0001281c, +0x0001281b, +0x00012819, +0x00012818, +0x00012816, +0x00012815, +0x00012814, +0x00012813, +0x00012811, +0x00012810, +0x0001280e, +0x0001280d, +0x0001280c, +0x0001280a, +0x00012809, +0x00012808, +0x00012807, +0x00012805, +0x00012803, +0x00012802, +0x00012801, +0x00012800, +0x000127ff, +0x000127fd, +0x000127fb, +0x000127fa, +0x000127f9, +0x000127f8, +0x000127f7, +0x000127f6, +0x000127f3, +0x000127f2, +0x000127f1, +0x000127f0, +0x000127ef, +0x000127ee, +0x000127eb, +0x000127ea, +0x000127e9, +0x000127e8, +0x000127e7, +0x000127e5, +0x000127e3, +0x000127e2, +0x000127e1, +0x000127e0, +0x000127de, +0x000127dd, +0x000127dc, +0x000127da, +0x000127d9, +0x000127d8, +0x000127d6, +0x000127d5, +0x000127d4, +0x000127d2, +0x000127d1, +0x000127cf, +0x000127ce, +0x000127cd, +0x000127cc, +0x000127cb, +0x000127c9, +0x000127c7, +0x000127c6, +0x000127c5, +0x000127c4, +0x000127c3, +0x000127c0, +0x000127bf, +0x000127be, +0x000127bd, +0x000127bc, +0x000127bb, +0x000127b8, +0x000127b7, +0x000127b6, +0x000127b5, +0x000127b4, +0x000127b3, +0x000127b1, +0x000127af, +0x000127ae, +0x000127ad, +0x000127ac, +0x000127aa, +0x000127a9, +0x000127a7, +0x000127a6, +0x000127a5, +0x000127a4, +0x000127a2, +0x000127a1, +0x000127a0, +0x0001279e, +0x0001279d, +0x0001279b, +0x0001279a, +0x00012799, +0x00012798, +0x00012796, +0x00012794, +0x00012793, +0x00012792, +0x00012791, +0x00012790, +0x0001278e, +0x0001278c, +0x0001278b, +0x0001278a, +0x00012789, +0x00012787, +0x00012786, +0x00012785, +0x00012783, +0x00012782, +0x00012781, +0x00012780, +0x0001277e, +0x0001277c, +0x0001277b, +0x0001277a, +0x00012779, +0x00012778, +0x00012776, +0x00012774, +0x00012773, +0x00012772, +0x00012771, +0x00012770, +0x0001276f, +0x0001276c, +0x0001276b, +0x0001276a, +0x00012769, +0x00012768, +0x00012767, +0x00012764, +0x00012763, +0x00012762, +0x00012761, +0x00012760, +0x0001275e, +0x0001275d, +0x0001275b, +0x0001275a, +0x00012759, +0x00012758, +0x00012756, +0x00012755, +0x00012754, +0x00012752, +0x00012751, +0x00012750, +0x0001274e, +0x0001274d, +0x0001274c, +0x0001274a, +0x00012749, +0x00012747, +0x00012746, +0x00012745, +0x00012744, +0x00012743, +0x00012741, +0x0001273f, +0x0001273e, +0x0001273d, +0x0001273c, +0x0001273b, +0x00012738, +0x00012737, +0x00012736, +0x00012735, +0x00012734, +0x00012733, +0x00012732, +0x0001272f, +0x0001272e, +0x0001272d, +0x0001272c, +0x0001272b, +0x00012729, +0x00012727, +0x00012726, +0x00012725, +0x00012724, +0x00012723, +0x00012721, +0x00012720, +0x0001271e, +0x0001271d, +0x0001271c, +0x0001271b, +0x00012719, +0x00012718, +0x00012716, +0x00012715, +0x00012714, +0x00012712, +0x00012711, +0x00012710, +0x0001270f, +0x0001270d, +0x0001270c, +0x0001270a, +0x00012709, +0x00012708, +0x00012707, +0x00012706, +0x00012703, +0x00012702, +0x00012701, +0x00012700, +0x000126ff, +0x000126fe, +0x000126fb, +0x000126fa, +0x000126f9, +0x000126f8, +0x000126f7, +0x000126f6, +0x000126f4, +0x000126f2, +0x000126f1, +0x000126f0, +0x000126ef, +0x000126ee, +0x000126ec, +0x000126ea, +0x000126e9, +0x000126e8, +0x000126e7, +0x000126e5, +0x000126e4, +0x000126e3, +0x000126e1, +0x000126e0, +0x000126df, +0x000126dd, +0x000126dc, +0x000126db, +0x000126d9, +0x000126d8, +0x000126d7, +0x000126d5, +0x000126d4, +0x000126d3, +0x000126d2, +0x000126d0, +0x000126ce, +0x000126cd, +0x000126cc, +0x000126cb, +0x000126ca, +0x000126c9, +0x000126c6, +0x000126c5, +0x000126c4, +0x000126c3, +0x000126c2, +0x000126c1, +0x000126be, +0x000126bd, +0x000126bc, +0x000126bb, +0x000126ba, +0x000126b9, +0x000126b7, +0x000126b5, +0x000126b4, +0x000126b3, +0x000126b2, +0x000126b0, +0x000126af, +0x000126ad, +0x000126ac, +0x000126ab, +0x000126aa, +0x000126a8, +0x000126a7, +0x000126a6, +0x000126a4, +0x000126a3, +0x000126a2, +0x000126a0, +0x0001269f, +0x0001269e, +0x0001269c, +0x0001269b, +0x00012699, +0x00012698, +0x00012697, +0x00012696, +0x00012695, +0x00012693, +0x00012691, +0x00012690, +0x0001268f, +0x0001268e, +0x0001268d, +0x0001268c, +0x00012689, +0x00012688, +0x00012687, +0x00012686, +0x00012685, +0x00012684, +0x00012681, +0x00012680, +0x0001267f, +0x0001267e, +0x0001267d, +0x0001267b, +0x0001267a, +0x00012678, +0x00012677, +0x00012676, +0x00012675, +0x00012673, +0x00012672, +0x00012670, +0x0001266f, +0x0001266e, +0x0001266d, +0x0001266b, +0x0001266a, +0x00012669, +0x00012667, +0x00012666, +0x00012664, +0x00012663, +0x00012662, +0x00012661, +0x0001265f, +0x0001265e, +0x0001265c, +0x0001265b, +0x0001265a, +0x00012659, +0x00012658, +0x00012655, +0x00012654, +0x00012653, +0x00012652, +0x00012651, +0x00012650, +0x0001264d, +0x0001264c, +0x0001264b, +0x0001264a, +0x00012649, +0x00012648, +0x00012646, +0x00012644, +0x00012643, +0x00012642, +0x00012641, +0x00012640, +0x0001263e, +0x0001263d, +0x0001263b, +0x0001263a, +0x00012639, +0x00012637, +0x00012637, +0x00012635, +0x00012634, +0x00012633, +0x00012631, +0x00012630, +0x0001262f, +0x0001262d, +0x0001262c, +0x0001262a, +0x00012629, +0x00012628, +0x00012627, +0x00012626, +0x00012624, +0x00012622, +0x00012621, +0x00012620, +0x0001261f, +0x0001261e, +0x0001261d, +0x0001261a, +0x00012619, +0x00012618, +0x00012617, +0x00012616, +0x00012615, +0x00012612, +0x00012611, +0x00012610, +0x0001260f, +0x0001260e, +0x0001260d, +0x0001260b, +0x00012609, +0x00012608, +0x00012607, +0x00012606, +0x00012605, +0x00012603, +0x00012602, +0x00012600, +0x000125ff, +0x000125fe, +0x000125fd, +0x000125fb, +0x000125fa, +0x000125f9, +0x000125f7, +0x000125f6, +0x000125f5, +0x000125f3, +0x000125f2, +0x000125f1, +0x000125ef, +0x000125ee, +0x000125ec, +0x000125eb, +0x000125ea, +0x000125e9, +0x000125e8, +0x000125e6, +0x000125e4, +0x000125e3, +0x000125e2, +0x000125e1, +0x000125e0, +0x000125df, +0x000125dc, +0x000125db, +0x000125da, +0x000125d9, +0x000125d8, +0x000125d7, +0x000125d6, +0x000125d3, +0x000125d2, +0x000125d1, +0x000125d0, +0x000125cf, +0x000125cd, +0x000125cb, +0x000125ca, +0x000125c9, +0x000125c8, +0x000125c7, +0x000125c5, +0x000125c4, +0x000125c2, +0x000125c1, +0x000125c0, +0x000125bf, +0x000125bd, +0x000125bc, +0x000125bb, +0x000125b9, +0x000125b8, +0x000125b7, +0x000125b5, +0x000125b4, +0x000125b3, +0x000125b2, +0x000125b0, +0x000125ae, +0x000125ad, +0x000125ac, +0x000125ab, +0x000125aa, +0x000125a8, +0x000125a6, +0x000125a5, +0x000125a4, +0x000125a3, +0x000125a2, +0x000125a1, +0x0001259e, +0x0001259d, +0x0001259c, +0x0001259b, +0x0001259a, +0x00012599, +0x00012597, +0x00012595, +0x00012594, +0x00012593, +0x00012592, +0x00012591, +0x0001258f, +0x0001258e, +0x0001258d, +0x0001258a, +0x00012589, +0x00012588, +0x00012587, +0x00012586, +0x00012585, +0x00012584, +0x00012581, +0x00012580, +0x0001257f, +0x0001257e, +0x0001257d, +0x0001257c, +0x0001257a, +0x00012578, +0x00012577, +0x00012576, +0x00012575, +0x00012574, +0x00012572, +0x00012571, +0x0001256f, +0x0001256e, +0x0001256d, +0x0001256c, +0x0001256a, +0x00012569, +0x00012568, +0x00012566, +0x00012565, +0x00012564, +0x00012562, +0x00012561, +0x00012560, +0x0001255f, +0x0001255d, +0x0001255c, +0x0001255a, +0x00012559, +0x00012558, +0x00012557, +0x00012556, +0x00012554, +0x00012552, +0x00012551, +0x00012550, +0x0001254f, +0x0001254e, +0x0001254d, +0x0001254a, +0x00012549, +0x00012548, +0x00012547, +0x00012546, +0x00012545, +0x00012544, +0x00012541, +0x00012540, +0x0001253f, +0x0001253e, +0x0001253d, +0x0001253c, +0x0001253a, +0x00012538, +0x00012537, +0x00012536, +0x00012535, +0x00012534, +0x00012532, +0x00012530, +0x0001252f, +0x0001252e, +0x0001252d, +0x0001252b, +0x0001252a, +0x00012529, +0x00012527, +0x00012526, +0x00012525, +0x00012523, +0x00012522, +0x00012521, +0x00012520, +0x0001251e, +0x0001251d, +0x0001251b, +0x0001251a, +0x00012519, +0x00012518, +0x00012517, +0x00012515, +0x00012513, +0x00012512, +0x00012511, +0x00012510, +0x0001250f, +0x0001250e, +0x0001250b, +0x0001250a, +0x00012509, +0x00012508, +0x00012507, +0x00012506, +0x00012505, +0x00012502, +0x00012501, +0x00012500, +0x000124ff, +0x000124fe, +0x000124fd, +0x000124fb, +0x000124f9, +0x000124f8, +0x000124f7, +0x000124f6, +0x000124f5, +0x000124f3, +0x000124f2, +0x000124f0, +0x000124ef, +0x000124ee, +0x000124ed, +0x000124eb, +0x000124ea, +0x000124e9, +0x000124e7, +0x000124e6, +0x000124e5, +0x000124e3, +0x000124e2, +0x000124e1, +0x000124e0, +0x000124de, +0x000124dd, +0x000124db, +0x000124da, +0x000124d9, +0x000124d8, +0x000124d7, +0x000124d5, +0x000124d3, +0x000124d2, +0x000124d1, +0x000124d0, +0x000124cf, +0x000124ce, +0x000124cb, +0x000124ca, +0x000124c9, +0x000124c8, +0x000124c7, +0x000124c6, +0x000124c3, +0x000124c2, +0x000124c1, +0x000124c0, +0x000124bf, +0x000124be, +0x000124bc, +0x000124ba, +0x000124b9, +0x000124b8, +0x000124b7, +0x000124b6, +0x000124b4, +0x000124b3, +0x000124b1, +0x000124b0, +0x000124af, +0x000124ae, +0x000124ac, +0x000124ab, +0x000124aa, +0x000124a8, +0x000124a7, +0x000124a6, +0x000124a4, +0x000124a3, +0x000124a2, +0x000124a1, +0x0001249f, +0x0001249e, +0x0001249c, +0x0001249b, +0x0001249a, +0x00012499, +0x00012498, +0x00012496, +0x00012494, +0x00012493, +0x00012492, +0x00012491, +0x00012490, +0x0001248f, +0x0001248c, +0x0001248b, +0x0001248a, +0x00012489, +0x00012488, +0x00012487, +0x00012486, +0x00012483, +0x00012482, +0x00012481, +0x00012480, +0x0001247f, +0x0001247e, +0x0001247c, +0x0001247a, +0x00012479, +0x00012478, +0x00012477, +0x00012476, +0x00012474, +0x00012473, +0x00012471, +0x00012470, +0x0001246f, +0x0001246e, +0x0001246c, +0x0001246b, +0x0001246a, +0x00012468, +0x00012467, +0x00012465, +0x00012464, +0x00012463, +0x00012462, +0x00012461, +0x0001245f, +0x0001245d, +0x0001245c, +0x0001245b, +0x0001245a, +0x00012459, +0x00012457, +0x00012455, +0x00012454, +0x00012453, +0x00012452, +0x00012451, +0x00012450, +0x0001244d, +0x0001244c, +0x0001244b, +0x0001244a, +0x00012449, +0x00012448, +0x00012447, +0x00012444, +0x00012443, +0x00012442, +0x00012441, +0x00012440, +0x0001243f, +0x0001243e, +0x0001243c, +0x0001243b, +0x00012439, +0x00012438, +0x00012437, +0x00012436, +0x00012434, +0x00012433, +0x00012432, +0x00012430, +0x0001242f, +0x0001242e, +0x0001242c, +0x0001242b, +0x0001242a, +0x00012429, +0x00012427, +0x00012426, +0x00012425, +0x00012423, +0x00012422, +0x00012421, +0x00012420, +0x0001241e, +0x0001241d, +0x0001241b, +0x0001241a, +0x00012419, +0x00012418, +0x00012417, +0x00012416, +0x00012413, +0x00012412, +0x00012411, +0x00012410, +0x0001240f, +0x0001240e, +0x0001240d, +0x0001240a, +0x00012409, +0x00012408, +0x00012407, +0x00012406, +0x00012405, +0x00012403, +0x00012401, +0x00012400, +0x000123ff, +0x000123fe, +0x000123fd, +0x000123fb, +0x000123fa, +0x000123f8, +0x000123f7, +0x000123f6, +0x000123f5, +0x000123f3, +0x000123f2, +0x000123f1, +0x000123ef, +0x000123ee, +0x000123ed, +0x000123eb, +0x000123ea, +0x000123e9, +0x000123e8, +0x000123e6, +0x000123e5, +0x000123e3, +0x000123e2, +0x000123e1, +0x000123e0, +0x000123df, +0x000123dd, +0x000123dc, +0x000123da, +0x000123d9, +0x000123d8, +0x000123d7, +0x000123d6, +0x000123d4, +0x000123d2, +0x000123d1, +0x000123d0, +0x000123cf, +0x000123ce, +0x000123cd, +0x000123ca, +0x000123c9, +0x000123c8, +0x000123c7, +0x000123c6, +0x000123c5, +0x000123c4, +0x000123c2, +0x000123c0, +0x000123bf, +0x000123be, +0x000123bd, +0x000123bc, +0x000123ba, +0x000123b9, +0x000123b7, +0x000123b6, +0x000123b5, +0x000123b4, +0x000123b2, +0x000123b1, +0x000123b0, +0x000123ae, +0x000123ad, +0x000123ac, +0x000123aa, +0x000123a9, +0x000123a8, +0x000123a7, +0x000123a5, +0x000123a4, +0x000123a2, +0x000123a1, +0x000123a0, +0x0001239f, +0x0001239e, +0x0001239c, +0x0001239a, +0x00012399, +0x00012398, +0x00012397, +0x00012395, +0x00012394, +0x00012393, +0x00012392, +0x00012390, +0x0001238f, +0x0001238e, +0x0001238d, +0x0001238b, +0x0001238a, +0x00012388, +0x00012387, +0x00012386, +0x00012385, +0x00012384, +0x00012382, +0x00012380, +0x0001237f, +0x0001237e, +0x0001237d, +0x0001237c, +0x0001237b, +0x00012378, +0x00012377, +0x00012376, +0x00012375, +0x00012374, +0x00012373, +0x00012372, +0x00012371, +0x0001236e, +0x0001236d, +0x0001236c, +0x0001236b, +0x0001236a, +0x00012369, +0x00012367, +0x00012365, +0x00012364, +0x00012363, +0x00012362, +0x00012361, +0x0001235f, +0x0001235e, +0x0001235c, +0x0001235b, +0x0001235a, +0x00012359, +0x00012358, +0x00012356, +0x00012355, +0x00012354, +0x00012352, +0x00012351, +0x00012350, +0x0001234e, +0x0001234d, +0x0001234c, +0x0001234b, +0x00012349, +0x00012348, +0x00012346, +0x00012345, +0x00012344, +0x00012343, +0x00012342, +0x00012340, +0x0001233f, +0x0001233d, +0x0001233c, +0x0001233b, +0x0001233a, +0x00012339, +0x00012337, +0x00012335, +0x00012334, +0x00012333, +0x00012332, +0x00012331, +0x00012330, +0x0001232f, +0x0001232c, +0x0001232b, +0x0001232a, +0x00012329, +0x00012328, +0x00012327, +0x00012326, +0x00012323, +0x00012322, +0x00012321, +0x00012320, +0x0001231f, +0x0001231e, +0x0001231c, +0x0001231a, +0x00012319, +0x00012318, +0x00012317, +0x00012316, +0x00012314, +0x00012313, +0x00012312, +0x00012310, +0x0001230f, +0x0001230e, +0x0001230d, +0x0001230b, +0x0001230a, +0x00012309, +0x00012307, +0x00012306, +0x00012305, +0x00012303, +0x00012302, +0x00012301, +0x00012300, +0x000122fe, +0x000122fd, +0x000122fb, +0x000122fa, +0x000122f9, +0x000122f8, +0x000122f7, +0x000122f6, +0x000122f3, +0x000122f2, +0x000122f1, +0x000122f0, +0x000122ef, +0x000122ee, +0x000122ed, +0x000122ea, +0x000122e9, +0x000122e8, +0x000122e7, +0x000122e6, +0x000122e5, +0x000122e4, +0x000122e1, +0x000122e0, +0x000122df, +0x000122de, +0x000122dd, +0x000122dc, +0x000122da, +0x000122d9, +0x000122d7, +0x000122d6, +0x000122d5, +0x000122d4, +0x000122d3, +0x000122d1, +0x000122d0, +0x000122ce, +0x000122cd, +0x000122cc, +0x000122cb, +0x000122c9, +0x000122c8, +0x000122c7, +0x000122c5, +0x000122c4, +0x000122c3, +0x000122c1, +0x000122c0, +0x000122bf, +0x000122be, +0x000122bd, +0x000122bb, +0x000122ba, +0x000122b8, +0x000122b7, +0x000122b6, +0x000122b5, +0x000122b4, +0x000122b2, +0x000122b0, +0x000122af, +0x000122ae, +0x000122ad, +0x000122ac, +0x000122ab, +0x000122a8, +0x000122a7, +0x000122a6, +0x000122a5, +0x000122a4, +0x000122a3, +0x000122a2, +0x000122a1, +0x0001229e, +0x0001229d, +0x0001229c, +0x0001229b, +0x0001229a, +0x00012299, +0x00012297, +0x00012295, +0x00012294, +0x00012293, +0x00012292, +0x00012291, +0x0001228f, +0x0001228e, +0x0001228c, +0x0001228b, +0x0001228a, +0x00012289, +0x00012288, +0x00012286, +0x00012285, +0x00012283, +0x00012282, +0x00012281, +0x00012280, +0x0001227e, +0x0001227d, +0x0001227c, +0x0001227b, +0x00012279, +0x00012278, +0x00012276, +0x00012275, +0x00012274, +0x00012273, +0x00012272, +0x00012270, +0x0001226f, +0x0001226d, +0x0001226c, +0x0001226b, +0x0001226a, +0x00012269, +0x00012267, +0x00012265, +0x00012264, +0x00012263, +0x00012262, +0x00012261, +0x00012260, +0x0001225f, +0x0001225c, +0x0001225b, +0x0001225a, +0x00012259, +0x00012258, +0x00012257, +0x00012255, +0x00012253, +0x00012252, +0x00012251, +0x00012250, +0x0001224f, +0x0001224e, +0x0001224c, +0x0001224b, +0x0001224a, +0x00012249, +0x00012247, +0x00012246, +0x00012245, +0x00012243, +0x00012242, +0x00012241, +0x0001223f, +0x0001223e, +0x0001223d, +0x0001223c, +0x0001223b, +0x00012239, +0x00012238, +0x00012236, +0x00012235, +0x00012234, +0x00012233, +0x00012232, +0x00012230, +0x0001222e, +0x0001222d, +0x0001222c, +0x0001222b, +0x0001222a, +0x00012229, +0x00012228, +0x00012225, +0x00012224, +0x00012223, +0x00012222, +0x00012221, +0x00012220, +0x0001221f, +0x0001221c, +0x0001221b, +0x0001221a, +0x00012219, +0x00012218, +0x00012217, +0x00012216, +0x00012214, +0x00012212, +0x00012211, +0x00012210, +0x0001220f, +0x0001220e, +0x0001220c, +0x0001220b, +0x00012209, +0x00012208, +0x00012207, +0x00012206, +0x00012205, +0x00012203, +0x00012202, +0x00012201, +0x000121ff, +0x000121fe, +0x000121fd, +0x000121fb, +0x000121fa, +0x000121f9, +0x000121f8, +0x000121f6, +0x000121f5, +0x000121f4, +0x000121f2, +0x000121f1, +0x000121f0, +0x000121ef, +0x000121ee, +0x000121ec, +0x000121ea, +0x000121e9, +0x000121e8, +0x000121e7, +0x000121e6, +0x000121e5, +0x000121e3, +0x000121e1, +0x000121e0, +0x000121df, +0x000121de, +0x000121dd, +0x000121dc, +0x000121db, +0x000121d8, +0x000121d7, +0x000121d6, +0x000121d5, +0x000121d4, +0x000121d3, +0x000121d2, +0x000121cf, +0x000121ce, +0x000121cd, +0x000121cc, +0x000121cb, +0x000121ca, +0x000121c8, +0x000121c7, +0x000121c5, +0x000121c4, +0x000121c3, +0x000121c2, +0x000121c1, +0x000121bf, +0x000121be, +0x000121bc, +0x000121bb, +0x000121ba, +0x000121b9, +0x000121b8, +0x000121b6, +0x000121b5, +0x000121b4, +0x000121b2, +0x000121b1, +0x000121b0, +0x000121ae, +0x000121ad, +0x000121ac, +0x000121ab, +0x000121a9, +0x000121a8, +0x000121a6, +0x000121a5, +0x000121a4, +0x000121a3, +0x000121a1, +0x000121a0, +0x0001219f, +0x0001219e, +0x0001219c, +0x0001219b, +0x0001219a, +0x00012198, +0x00012197, +0x00012196, +0x00012195, +0x00012194, +0x00012192, +0x00012191, +0x0001218f, +0x0001218e, +0x0001218d, +0x0001218c, +0x0001218b, +0x0001218a, +0x00012187, +0x00012186, +0x00012185, +0x00012184, +0x00012183, +0x00012182, +0x00012181, +0x0001217e, +0x0001217d, +0x0001217c, +0x0001217b, +0x0001217a, +0x00012179, +0x00012178, +0x00012177, +0x00012174, +0x00012173, +0x00012172, +0x00012171, +0x00012170, +0x0001216f, +0x0001216e, +0x0001216c, +0x0001216a, +0x00012169, +0x00012168, +0x00012167, +0x00012166, +0x00012164, +0x00012163, +0x00012162, +0x00012160, +0x0001215f, +0x0001215e, +0x0001215d, +0x0001215b, +0x0001215a, +0x00012159, +0x00012158, +0x00012156, +0x00012155, +0x00012154, +0x00012152, +0x00012151, +0x00012150, +0x0001214f, +0x0001214d, +0x0001214c, +0x0001214b, +0x00012149, +0x00012148, +0x00012147, +0x00012146, +0x00012145, +0x00012143, +0x00012141, +0x00012140, +0x0001213f, +0x0001213e, +0x0001213d, +0x0001213c, +0x0001213b, +0x00012138, +0x00012137, +0x00012136, +0x00012135, +0x00012134, +0x00012133, +0x00012132, +0x00012131, +0x0001212e, +0x0001212d, +0x0001212c, +0x0001212b, +0x0001212a, +0x00012129, +0x00012128, +0x00012125, +0x00012124, +0x00012123, +0x00012122, +0x00012121, +0x00012120, +0x0001211e, +0x0001211d, +0x0001211b, +0x0001211a, +0x00012119, +0x00012118, +0x00012117, +0x00012115, +0x00012114, +0x00012113, +0x00012111, +0x00012110, +0x0001210f, +0x0001210e, +0x0001210c, +0x0001210b, +0x0001210a, +0x00012109, +0x00012107, +0x00012106, +0x00012105, +0x00012103, +0x00012102, +0x00012101, +0x00012100, +0x000120fe, +0x000120fd, +0x000120fb, +0x000120fa, +0x000120f9, +0x000120f8, +0x000120f7, +0x000120f6, +0x000120f4, +0x000120f2, +0x000120f1, +0x000120f0, +0x000120ef, +0x000120ee, +0x000120ed, +0x000120ec, +0x000120e9, +0x000120e8, +0x000120e7, +0x000120e6, +0x000120e5, +0x000120e4, +0x000120e3, +0x000120e2, +0x000120df, +0x000120de, +0x000120dd, +0x000120dc, +0x000120db, +0x000120da, +0x000120d8, +0x000120d6, +0x000120d5, +0x000120d4, +0x000120d3, +0x000120d2, +0x000120d1, +0x000120cf, +0x000120ce, +0x000120cc, +0x000120cb, +0x000120ca, +0x000120c9, +0x000120c8, +0x000120c6, +0x000120c5, +0x000120c4, +0x000120c2, +0x000120c1, +0x000120c0, +0x000120bf, +0x000120bd, +0x000120bc, +0x000120bb, +0x000120ba, +0x000120b8, +0x000120b7, +0x000120b5, +0x000120b4, +0x000120b3, +0x000120b2, +0x000120b1, +0x000120af, +0x000120ae, +0x000120ac, +0x000120ab, +0x000120aa, +0x000120a9, +0x000120a8, +0x000120a7, +0x000120a5, +0x000120a3, +0x000120a2, +0x000120a1, +0x000120a0, +0x0001209f, +0x0001209e, +0x0001209d, +0x0001209a, +0x00012099, +0x00012098, +0x00012097, +0x00012096, +0x00012095, +0x00012094, +0x00012092, +0x00012090, +0x0001208f, +0x0001208e, +0x0001208d, +0x0001208c, +0x0001208b, +0x00012089, +0x00012087, +0x00012086, +0x00012085, +0x00012084, +0x00012083, +0x00012082, +0x00012080, +0x0001207f, +0x0001207d, +0x0001207c, +0x0001207b, +0x0001207a, +0x00012079, +0x00012077, +0x00012076, +0x00012075, +0x00012073, +0x00012072, +0x00012071, +0x00012070, +0x0001206e, +0x0001206d, +0x0001206c, +0x0001206b, +0x00012069, +0x00012068, +0x00012066, +0x00012065, +0x00012064, +0x00012063, +0x00012062, +0x00012061, +0x00012060, +0x0001205f, +0x0001205c, +0x0001205b, +0x0001205a, +0x00012059, +0x00012058, +0x00012057, +0x00012056, +0x00012054, +0x00012052, +0x00012051, +0x00012050, +0x0001204f, +0x0001204e, +0x0001204d, +0x0001204b, +0x0001204a, +0x00012048, +0x00012047, +0x00012046, +0x00012045, +0x00012044, +0x00012042, +0x00012041, +0x00012040, +0x0001203e, +0x0001203d, +0x0001203c, +0x0001203b, +0x00012039, +0x00012038, +0x00012037, +0x00012036, +0x00012034, +0x00012033, +0x00012032, +0x00012030, +0x0001202f, +0x0001202e, +0x0001202d, +0x0001202c, +0x0001202a, +0x00012029, +0x00012027, +0x00012026, +0x00012025, +0x00012024, +0x00012023, +0x00012022, +0x00012020, +0x0001201e, +0x0001201d, +0x0001201c, +0x0001201b, +0x0001201a, +0x00012019, +0x00012018, +0x00012015, +0x00012014, +0x00012013, +0x00012012, +0x00012011, +0x00012010, +0x0001200f, +0x0001200e, +0x0001200b, +0x0001200a, +0x00012009, +0x00012008, +0x00012007, +0x00012006, +0x00012005, +0x00012003, +0x00012001, +0x00012000, +0x00011fff, +0x00011ffe, +0x00011ffd, +0x00011ffc, +0x00011ffa, +0x00011ff9, +0x00011ff7, +0x00011ff6, +0x00011ff5, +0x00011ff4, +0x00011ff3, +0x00011ff1, +0x00011ff0, +0x00011fef, +0x00011fed, +0x00011fec, +0x00011feb, +0x00011fea, +0x00011fe8, +0x00011fe7, +0x00011fe6, +0x00011fe5, +0x00011fe3, +0x00011fe2, +0x00011fe1, +0x00011fdf, +0x00011fde, +0x00011fdd, +0x00011fdc, +0x00011fdb, +0x00011fd9, +0x00011fd8, +0x00011fd6, +0x00011fd5, +0x00011fd4, +0x00011fd3, +0x00011fd2, +0x00011fd1, +0x00011fcf, +0x00011fcd, +0x00011fcc, +0x00011fcb, +0x00011fca, +0x00011fc9, +0x00011fc8, +0x00011fc7, +0x00011fc4, +0x00011fc3, +0x00011fc2, +0x00011fc1, +0x00011fc0, +0x00011fbf, +0x00011fbc, +0x00011fbb, +0x00011fba, +0x00011fb9, +0x00011fb8, +0x00011fb7, +0x00011fb6, +0x00011fb4, +0x00011fb2, +0x00011fb1, +0x00011fb0, +0x00011faf, +0x00011fae, +0x00011fad, +0x00011fac, +0x00011faa, +0x00011fa8, +0x00011fa7, +0x00011fa6, +0x00011fa5, +0x00011fa4, +0x00011fa3, +0x00011fa1, +0x00011fa0, +0x00011f9e, +0x00011f9d, +0x00011f9c, +0x00011f9b, +0x00011f9a, +0x00011f98, +0x00011f97, +0x00011f96, +0x00011f95, +0x00011f93, +0x00011f92, +0x00011f91, +0x00011f90, +0x00011f8e, +0x00011f8d, +0x00011f8c, +0x00011f8b, +0x00011f89, +0x00011f88, +0x00011f87, +0x00011f85, +0x00011f84, +0x00011f83, +0x00011f82, +0x00011f81, +0x00011f7f, +0x00011f7e, +0x00011f7c, +0x00011f7b, +0x00011f7a, +0x00011f79, +0x00011f78, +0x00011f77, +0x00011f75, +0x00011f73, +0x00011f72, +0x00011f71, +0x00011f70, +0x00011f6f, +0x00011f6e, +0x00011f6d, +0x00011f6c, +0x00011f69, +0x00011f68, +0x00011f67, +0x00011f66, +0x00011f65, +0x00011f64, +0x00011f63, +0x00011f62, +0x00011f5f, +0x00011f5e, +0x00011f5d, +0x00011f5c, +0x00011f5b, +0x00011f5a, +0x00011f59, +0x00011f57, +0x00011f55, +0x00011f54, +0x00011f53, +0x00011f52, +0x00011f51, +0x00011f50, +0x00011f4e, +0x00011f4d, +0x00011f4b, +0x00011f4a, +0x00011f49, +0x00011f48, +0x00011f47, +0x00011f46, +0x00011f44, +0x00011f43, +0x00011f42, +0x00011f40, +0x00011f3f, +0x00011f3e, +0x00011f3d, +0x00011f3b, +0x00011f3a, +0x00011f39, +0x00011f38, +0x00011f36, +0x00011f35, +0x00011f34, +0x00011f32, +0x00011f31, +0x00011f30, +0x00011f2f, +0x00011f2e, +0x00011f2c, +0x00011f2b, +0x00011f29, +0x00011f28, +0x00011f27, +0x00011f26, +0x00011f25, +0x00011f24, +0x00011f22, +0x00011f21, +0x00011f1f, +0x00011f1e, +0x00011f1d, +0x00011f1c, +0x00011f1b, +0x00011f1a, +0x00011f19, +0x00011f16, +0x00011f15, +0x00011f14, +0x00011f13, +0x00011f12, +0x00011f11, +0x00011f10, +0x00011f0f, +0x00011f0c, +0x00011f0b, +0x00011f0a, +0x00011f09, +0x00011f08, +0x00011f07, +0x00011f06, +0x00011f04, +0x00011f02, +0x00011f01, +0x00011f00, +0x00011eff, +0x00011efe, +0x00011efd, +0x00011efc, +0x00011efa, +0x00011ef8, +0x00011ef7, +0x00011ef6, +0x00011ef5, +0x00011ef4, +0x00011ef3, +0x00011ef1, +0x00011ef0, +0x00011eef, +0x00011eed, +0x00011eec, +0x00011eeb, +0x00011eea, +0x00011ee8, +0x00011ee7, +0x00011ee6, +0x00011ee5, +0x00011ee3, +0x00011ee2, +0x00011ee1, +0x00011edf, +0x00011ede, +0x00011edd, +0x00011edc, +0x00011edb, +0x00011ed9, +0x00011ed8, +0x00011ed7, +0x00011ed5, +0x00011ed4, +0x00011ed3, +0x00011ed2, +0x00011ed1, +0x00011ed0, +0x00011ece, +0x00011ecc, +0x00011ecb, +0x00011eca, +0x00011ec9, +0x00011ec8, +0x00011ec7, +0x00011ec6, +0x00011ec3, +0x00011ec2, +0x00011ec1, +0x00011ec0, +0x00011ebf, +0x00011ebe, +0x00011ebd, +0x00011ebc, +0x00011eb9, +0x00011eb8, +0x00011eb7, +0x00011eb6, +0x00011eb5, +0x00011eb4, +0x00011eb3, +0x00011eb2, +0x00011eaf, +0x00011eae, +0x00011ead, +0x00011eac, +0x00011eab, +0x00011eaa, +0x00011ea9, +0x00011ea7, +0x00011ea6, +0x00011ea4, +0x00011ea3, +0x00011ea2, +0x00011ea1, +0x00011ea0, +0x00011e9e, +0x00011e9d, +0x00011e9c, +0x00011e9a, +0x00011e99, +0x00011e98, +0x00011e97, +0x00011e95, +0x00011e94, +0x00011e93, +0x00011e92, +0x00011e90, +0x00011e8f, +0x00011e8e, +0x00011e8d, +0x00011e8b, +0x00011e8a, +0x00011e89, +0x00011e88, +0x00011e86, +0x00011e85, +0x00011e84, +0x00011e82, +0x00011e81, +0x00011e80, +0x00011e7f, +0x00011e7d, +0x00011e7c, +0x00011e7b, +0x00011e7a, +0x00011e79, +0x00011e78, +0x00011e76, +0x00011e75, +0x00011e73, +0x00011e72, +0x00011e71, +0x00011e70, +0x00011e6f, +0x00011e6d, +0x00011e6c, +0x00011e6b, +0x00011e6a, +0x00011e68, +0x00011e67, +0x00011e66, +0x00011e65, +0x00011e63, +0x00011e62, +0x00011e61, +0x00011e60, +0x00011e5e, +0x00011e5d, +0x00011e5c, +0x00011e5a, +0x00011e59, +0x00011e58, +0x00011e57, +0x00011e56, +0x00011e55, +0x00011e53, +0x00011e52, +0x00011e50, +0x00011e4f, +0x00011e4e, +0x00011e4d, +0x00011e4c, +0x00011e4b, +0x00011e49, +0x00011e48, +0x00011e46, +0x00011e45, +0x00011e44, +0x00011e43, +0x00011e42, +0x00011e41, +0x00011e40, +0x00011e3d, +0x00011e3c, +0x00011e3b, +0x00011e3a, +0x00011e39, +0x00011e38, +0x00011e37, +0x00011e36, +0x00011e33, +0x00011e32, +0x00011e31, +0x00011e30, +0x00011e2f, +0x00011e2e, +0x00011e2d, +0x00011e2c, +0x00011e2a, +0x00011e28, +0x00011e27, +0x00011e26, +0x00011e25, +0x00011e24, +0x00011e23, +0x00011e22, +0x00011e20, +0x00011e1e, +0x00011e1d, +0x00011e1c, +0x00011e1b, +0x00011e1a, +0x00011e19, +0x00011e17, +0x00011e16, +0x00011e15, +0x00011e13, +0x00011e12, +0x00011e11, +0x00011e10, +0x00011e0f, +0x00011e0d, +0x00011e0c, +0x00011e0b, +0x00011e09, +0x00011e08, +0x00011e07, +0x00011e06, +0x00011e04, +0x00011e03, +0x00011e02, +0x00011e01, +0x00011e00, +0x00011dfe, +0x00011dfd, +0x00011dfc, +0x00011dfa, +0x00011df9, +0x00011df8, +0x00011df7, +0x00011df6, +0x00011df4, +0x00011df3, +0x00011df1, +0x00011df0, +0x00011def, +0x00011dee, +0x00011ded, +0x00011dec, +0x00011deb, +0x00011de9, +0x00011de7, +0x00011de6, +0x00011de5, +0x00011de4, +0x00011de3, +0x00011de2, +0x00011de1, +0x00011de0, +0x00011ddd, +0x00011ddc, +0x00011ddb, +0x00011dda, +0x00011dd9, +0x00011dd8, +0x00011dd7, +0x00011dd6, +0x00011dd3, +0x00011dd2, +0x00011dd1, +0x00011dd0, +0x00011dcf, +0x00011dce, +0x00011dcd, +0x00011dcb, +0x00011dca, +0x00011dc8, +0x00011dc7, +0x00011dc6, +0x00011dc5, +0x00011dc4, +0x00011dc3, +0x00011dc1, +0x00011dc0, +0x00011dbe, +0x00011dbd, +0x00011dbc, +0x00011dbb, +0x00011dba, +0x00011db9, +0x00011db7, +0x00011db6, +0x00011db5, +0x00011db3, +0x00011db2, +0x00011db1, +0x00011db0, +0x00011dae, +0x00011dad, +0x00011dac, +0x00011dab, +0x00011da9, +0x00011da8, +0x00011da7, +0x00011da6, +0x00011da4, +0x00011da3, +0x00011da2, +0x00011da1, +0x00011da0, +0x00011d9e, +0x00011d9d, +0x00011d9b, +0x00011d9a, +0x00011d99, +0x00011d98, +0x00011d97, +0x00011d96, +0x00011d94, +0x00011d93, +0x00011d91, +0x00011d90, +0x00011d8f, +0x00011d8e, +0x00011d8d, +0x00011d8c, +0x00011d8b, +0x00011d88, +0x00011d87, +0x00011d86, +0x00011d85, +0x00011d84, +0x00011d83, +0x00011d82, +0x00011d81, +0x00011d7e, +0x00011d7d, +0x00011d7c, +0x00011d7b, +0x00011d7a, +0x00011d79, +0x00011d78, +0x00011d77, +0x00011d75, +0x00011d73, +0x00011d72, +0x00011d71, +0x00011d70, +0x00011d6f, +0x00011d6e, +0x00011d6d, +0x00011d6b, +0x00011d69, +0x00011d68, +0x00011d67, +0x00011d66, +0x00011d65, +0x00011d64, +0x00011d62, +0x00011d61, +0x00011d60, +0x00011d5e, +0x00011d5d, +0x00011d5c, +0x00011d5b, +0x00011d5a, +0x00011d58, +0x00011d57, +0x00011d56, +0x00011d54, +0x00011d53, +0x00011d52, +0x00011d51, +0x00011d4f, +0x00011d4e, +0x00011d4d, +0x00011d4c, +0x00011d4b, +0x00011d49, +0x00011d48, +0x00011d47, +0x00011d45, +0x00011d44, +0x00011d43, +0x00011d42, +0x00011d41, +0x00011d3f, +0x00011d3e, +0x00011d3d, +0x00011d3c, +0x00011d3b, +0x00011d3a, +0x00011d39, +0x00011d37, +0x00011d35, +0x00011d34, +0x00011d33, +0x00011d32, +0x00011d31, +0x00011d30, +0x00011d2f, +0x00011d2e, +0x00011d2b, +0x00011d2a, +0x00011d29, +0x00011d28, +0x00011d27, +0x00011d26, +0x00011d25, +0x00011d24, +0x00011d23, +0x00011d20, +0x00011d1f, +0x00011d1e, +0x00011d1d, +0x00011d1c, +0x00011d1b, +0x00011d1a, +0x00011d18, +0x00011d17, +0x00011d15, +0x00011d14, +0x00011d13, +0x00011d12, +0x00011d11, +0x00011d10, +0x00011d0e, +0x00011d0d, +0x00011d0b, +0x00011d0a, +0x00011d09, +0x00011d08, +0x00011d07, +0x00011d06, +0x00011d04, +0x00011d03, +0x00011d02, +0x00011d00, +0x00011cff, +0x00011cfe, +0x00011cfd, +0x00011cfc, +0x00011cfa, +0x00011cf9, +0x00011cf8, +0x00011cf7, +0x00011cf5, +0x00011cf4, +0x00011cf3, +0x00011cf2, +0x00011cf0, +0x00011cef, +0x00011cee, +0x00011ced, +0x00011cec, +0x00011cea, +0x00011ce9, +0x00011ce8, +0x00011ce6, +0x00011ce5, +0x00011ce4, +0x00011ce3, +0x00011ce2, +0x00011ce1, +0x00011cdf, +0x00011cdd, +0x00011cdc, +0x00011cdb, +0x00011cda, +0x00011cd9, +0x00011cd8, +0x00011cd7, +0x00011cd6, +0x00011cd3, +0x00011cd2, +0x00011cd1, +0x00011cd0, +0x00011ccf, +0x00011cce, +0x00011ccd, +0x00011ccc, +0x00011cc9, +0x00011cc8, +0x00011cc7, +0x00011cc6, +0x00011cc5, +0x00011cc4, +0x00011cc3, +0x00011cc2, +0x00011cc1, +0x00011cbe, +0x00011cbd, +0x00011cbc, +0x00011cbb, +0x00011cba, +0x00011cb9, +0x00011cb8, +0x00011cb7, +0x00011cb5, +0x00011cb3, +0x00011cb2, +0x00011cb1, +0x00011cb0, +0x00011caf, +0x00011cae, +0x00011cad, +0x00011cab, +0x00011caa, +0x00011ca8, +0x00011ca7, +0x00011ca6, +0x00011ca5, +0x00011ca4, +0x00011ca2, +0x00011ca1, +0x00011ca0, +0x00011c9f, +0x00011c9e, +0x00011c9c, +0x00011c9a, +0x00011c99, +0x00011c98, +0x00011c97, +0x00011c96, +0x00011c95, +0x00011c94, +0x00011c92, +0x00011c91, +0x00011c8f, +0x00011c8e, +0x00011c8d, +0x00011c8c, +0x00011c8b, +0x00011c8a, +0x00011c88, +0x00011c87, +0x00011c86, +0x00011c84, +0x00011c83, +0x00011c82, +0x00011c81, +0x00011c80, +0x00011c7e, +0x00011c7d, +0x00011c7c, +0x00011c7b, +0x00011c7a, +0x00011c78, +0x00011c77, +0x00011c76, +0x00011c74, +0x00011c73, +0x00011c72, +0x00011c71, +0x00011c70, +0x00011c6f, +0x00011c6d, +0x00011c6c, +0x00011c6b, +0x00011c69, +0x00011c68, +0x00011c67, +0x00011c66, +0x00011c65, +0x00011c64, +0x00011c62, +0x00011c61, +0x00011c5f, +0x00011c5e, +0x00011c5d, +0x00011c5c, +0x00011c5b, +0x00011c5a, +0x00011c59, +0x00011c57, +0x00011c55, +0x00011c54, +0x00011c53, +0x00011c52, +0x00011c51, +0x00011c50, +0x00011c4f, +0x00011c4e, +0x00011c4b, +0x00011c4a, +0x00011c49, +0x00011c48, +0x00011c47, +0x00011c46, +0x00011c45, +0x00011c44, +0x00011c43, +0x00011c40, +0x00011c3f, +0x00011c3e, +0x00011c3d, +0x00011c3c, +0x00011c3b, +0x00011c3a, +0x00011c39, +0x00011c37, +0x00011c35, +0x00011c34, +0x00011c33, +0x00011c32, +0x00011c31, +0x00011c30, +0x00011c2f, +0x00011c2d, +0x00011c2c, +0x00011c2b, +0x00011c29, +0x00011c28, +0x00011c27, +0x00011c26, +0x00011c25, +0x00011c24, +0x00011c22, +0x00011c21, +0x00011c20, +0x00011c1e, +0x00011c1d, +0x00011c1c, +0x00011c1b, +0x00011c1a, +0x00011c18, +0x00011c17, +0x00011c16, +0x00011c15, +0x00011c13, +0x00011c12, +0x00011c11, +0x00011c10, +0x00011c0e, +0x00011c0d, +0x00011c0c, +0x00011c0b, +0x00011c0a, +0x00011c08, +0x00011c07, +0x00011c06, +0x00011c04, +0x00011c03, +0x00011c02, +0x00011c01, +0x00011c00, +0x00011bff, +0x00011bfd, +0x00011bfc, +0x00011bfa, +0x00011bf9, +0x00011bf8, +0x00011bf7, +0x00011bf6, +0x00011bf5, +0x00011bf4, +0x00011bf2, +0x00011bf0, +0x00011bef, +0x00011bee, +0x00011bed, +0x00011bec, +0x00011beb, +0x00011bea, +0x00011be9, +0x00011be6, +0x00011be5, +0x00011be4, +0x00011be3, +0x00011be2, +0x00011be1, +0x00011be0, +0x00011bdf, +0x00011bde, +0x00011bdd, +0x00011bda, +0x00011bd9, +0x00011bd8, +0x00011bd7, +0x00011bd6, +0x00011bd5, +0x00011bd4, +0x00011bd3, +0x00011bd1, +0x00011bcf, +0x00011bce, +0x00011bcd, +0x00011bcc, +0x00011bcb, +0x00011bca, +0x00011bc9, +0x00011bc7, +0x00011bc6, +0x00011bc4, +0x00011bc3, +0x00011bc2, +0x00011bc1, +0x00011bc0, +0x00011bbf, +0x00011bbd, +0x00011bbc, +0x00011bbb, +0x00011bb9, +0x00011bb8, +0x00011bb7, +0x00011bb6, +0x00011bb5, +0x00011bb3, +0x00011bb2, +0x00011bb1, +0x00011bb0, +0x00011bae, +0x00011bad, +0x00011bac, +0x00011bab, +0x00011ba9, +0x00011ba8, +0x00011ba7, +0x00011ba6, +0x00011ba5, +0x00011ba3, +0x00011ba2, +0x00011ba1, +0x00011b9f, +0x00011b9e, +0x00011b9d, +0x00011b9c, +0x00011b9b, +0x00011b9a, +0x00011b98, +0x00011b97, +0x00011b96, +0x00011b94, +0x00011b93, +0x00011b92, +0x00011b91, +0x00011b90, +0x00011b8f, +0x00011b8e, +0x00011b8c, +0x00011b8a, +0x00011b89, +0x00011b88, +0x00011b87, +0x00011b86, +0x00011b85, +0x00011b84, +0x00011b83, +0x00011b80, +0x00011b7f, +0x00011b7e, +0x00011b7d, +0x00011b7c, +0x00011b7b, +0x00011b7a, +0x00011b79, +0x00011b78, +0x00011b75, +0x00011b74, +0x00011b73, +0x00011b72, +0x00011b71, +0x00011b70, +0x00011b6f, +0x00011b6e, +0x00011b6c, +0x00011b6a, +0x00011b69, +0x00011b68, +0x00011b67, +0x00011b66, +0x00011b65, +0x00011b63, +0x00011b62, +0x00011b61, +0x00011b60, +0x00011b5f, +0x00011b5e, +0x00011b5c, +0x00011b5b, +0x00011b5a, +0x00011b58, +0x00011b57, +0x00011b56, +0x00011b55, +0x00011b54, +0x00011b53, +0x00011b51, +0x00011b50, +0x00011b4e, +0x00011b4d, +0x00011b4c, +0x00011b4b, +0x00011b4a, +0x00011b49, +0x00011b48, +0x00011b47, +0x00011b45, +0x00011b43, +0x00011b42, +0x00011b41, +0x00011b40, +0x00011b3f, +0x00011b3e, +0x00011b3d, +0x00011b3c, +0x00011b39, +0x00011b38, +0x00011b37, +0x00011b36, +0x00011b35, +0x00011b34, +0x00011b33, +0x00011b32, +0x00011b31, +0x00011b30, +0x00011b2d, +0x00011b2c, +0x00011b2b, +0x00011b2a, +0x00011b29, +0x00011b28, +0x00011b27, +0x00011b26, +0x00011b24, +0x00011b22, +0x00011b21, +0x00011b20, +0x00011b1f, +0x00011b1e, +0x00011b1d, +0x00011b1c, +0x00011b1b, +0x00011b19, +0x00011b18, +0x00011b16, +0x00011b15, +0x00011b14, +0x00011b13, +0x00011b12, +0x00011b11, +0x00011b0f, +0x00011b0e, +0x00011b0d, +0x00011b0b, +0x00011b0a, +0x00011b09, +0x00011b08, +0x00011b07, +0x00011b06, +0x00011b04, +0x00011b03, +0x00011b02, +0x00011b00, +0x00011aff, +0x00011afe, +0x00011afd, +0x00011afc, +0x00011afa, +0x00011af9, +0x00011af8, +0x00011af7, +0x00011af6, +0x00011af4, +0x00011af3, +0x00011af2, +0x00011af1, +0x00011aef, +0x00011aee, +0x00011aed, +0x00011aec, +0x00011aeb, +0x00011ae9, +0x00011ae8, +0x00011ae7, +0x00011ae5, +0x00011ae4, +0x00011ae3, +0x00011ae2, +0x00011ae1, +0x00011ae0, +0x00011adf, +0x00011add, +0x00011adc, +0x00011ada, +0x00011ad9, +0x00011ad8, +0x00011ad7, +0x00011ad6, +0x00011ad5, +0x00011ad4, +0x00011ad2, +0x00011ad0, +0x00011acf, +0x00011ace, +0x00011acd, +0x00011acc, +0x00011acb, +0x00011aca, +0x00011ac7, +0x00011ac6, +0x00011ac5, +0x00011ac4, +0x00011ac3, +0x00011ac2, +0x00011ac1, +0x00011ac0, +0x00011abf, +0x00011abc, +0x00011abb, +0x00011aba, +0x00011ab9, +0x00011ab8, +0x00011ab7, +0x00011ab6, +0x00011ab5, +0x00011ab4, +0x00011ab2, +0x00011ab0, +0x00011aaf, +0x00011aae, +0x00011aad, +0x00011aac, +0x00011aab, +0x00011aaa, +0x00011aa9, +0x00011aa7, +0x00011aa6, +0x00011aa4, +0x00011aa3, +0x00011aa2, +0x00011aa1, +0x00011aa0, +0x00011a9f, +0x00011a9e, +0x00011a9c, +0x00011a9b, +0x00011a9a, +0x00011a98, +0x00011a97, +0x00011a96, +0x00011a95, +0x00011a94, +0x00011a93, +0x00011a91, +0x00011a90, +0x00011a8f, +0x00011a8e, +0x00011a8c, +0x00011a8b, +0x00011a8a, +0x00011a89, +0x00011a87, +0x00011a86, +0x00011a85, +0x00011a84, +0x00011a83, +0x00011a82, +0x00011a80, +0x00011a7f, +0x00011a7e, +0x00011a7c, +0x00011a7b, +0x00011a7a, +0x00011a79, +0x00011a78, +0x00011a77, +0x00011a75, +0x00011a74, +0x00011a73, +0x00011a71, +0x00011a70, +0x00011a6f, +0x00011a6e, +0x00011a6d, +0x00011a6c, +0x00011a6b, +0x00011a69, +0x00011a68, +0x00011a66, +0x00011a65, +0x00011a64, +0x00011a63, +0x00011a62, +0x00011a61, +0x00011a60, +0x00011a5f, +0x00011a5d, +0x00011a5b, +0x00011a5a, +0x00011a59, +0x00011a58, +0x00011a57, +0x00011a56, +0x00011a55, +0x00011a54, +0x00011a53, +0x00011a50, +0x00011a4f, +0x00011a4e, +0x00011a4d, +0x00011a4c, +0x00011a4b, +0x00011a4a, +0x00011a49, +0x00011a48, +0x00011a47, +0x00011a44, +0x00011a43, +0x00011a42, +0x00011a41, +0x00011a40, +0x00011a3f, +0x00011a3e, +0x00011a3d, +0x00011a3b, +0x00011a3a, +0x00011a38, +0x00011a37, +0x00011a36, +0x00011a35, +0x00011a34, +0x00011a33, +0x00011a32, +0x00011a30, +0x00011a2f, +0x00011a2e, +0x00011a2c, +0x00011a2b, +0x00011a2a, +0x00011a29, +0x00011a28, +0x00011a27, +0x00011a25, +0x00011a24, +0x00011a23, +0x00011a21, +0x00011a20, +0x00011a1f, +0x00011a1e, +0x00011a1d, +0x00011a1c, +0x00011a1a, +0x00011a19, +0x00011a18, +0x00011a17, +0x00011a15, +0x00011a14, +0x00011a13, +0x00011a12, +0x00011a11, +0x00011a0f, +0x00011a0e, +0x00011a0d, +0x00011a0c, +0x00011a0b, +0x00011a09, +0x00011a08, +0x00011a07, +0x00011a06, +0x00011a04, +0x00011a03, +0x00011a02, +0x00011a01, +0x00011a00, +0x000119ff, +0x000119fd, +0x000119fc, +0x000119fa, +0x000119f9, +0x000119f8, +0x000119f7, +0x000119f6, +0x000119f5, +0x000119f4, +0x000119f3, +0x000119f1, +0x000119ef, +0x000119ee, +0x000119ed, +0x000119ec, +0x000119eb, +0x000119ea, +0x000119e9, +0x000119e8, +0x000119e7, +0x000119e4, +0x000119e3, +0x000119e2, +0x000119e1, +0x000119e0, +0x000119df, +0x000119de, +0x000119dd, +0x000119dc, +0x000119d9, +0x000119d8, +0x000119d7, +0x000119d6, +0x000119d5, +0x000119d4, +0x000119d3, +0x000119d2, +0x000119d1, +0x000119d0, +0x000119cd, +0x000119cc, +0x000119cb, +0x000119ca, +0x000119c9, +0x000119c8, +0x000119c7, +0x000119c6, +0x000119c5, +0x000119c3, +0x000119c1, +0x000119c0, +0x000119bf, +0x000119be, +0x000119bd, +0x000119bc, +0x000119bb, +0x000119ba, +0x000119b8, +0x000119b7, +0x000119b5, +0x000119b4, +0x000119b3, +0x000119b2, +0x000119b1, +0x000119b0, +0x000119ae, +0x000119ad, +0x000119ac, +0x000119ab, +0x000119a9, +0x000119a8, +0x000119a7, +0x000119a6, +0x000119a5, +0x000119a3, +0x000119a2, +0x000119a1, +0x000119a0, +0x0001199f, +0x0001199d, +0x0001199c, +0x0001199b, +0x0001199a, +0x00011998, +0x00011997, +0x00011996, +0x00011995, +0x00011994, +0x00011992, +0x00011991, +0x00011990, +0x0001198f, +0x0001198e, +0x0001198d, +0x0001198b, +0x0001198a, +0x00011988, +0x00011987, +0x00011986, +0x00011985, +0x00011984, +0x00011983, +0x00011982, +0x00011980, +0x0001197f, +0x0001197e, +0x0001197c, +0x0001197b, +0x0001197a, +0x00011979, +0x00011978, +0x00011977, +0x00011975, +0x00011974, +0x00011973, +0x00011972, +0x00011971, +0x0001196f, +0x0001196e, +0x0001196d, +0x0001196c, +0x0001196a, +0x00011969, +0x00011968, +0x00011967, +0x00011966, +0x00011965, +0x00011963, +0x00011962, +0x00011961, +0x0001195f, +0x0001195e, +0x0001195d, +0x0001195c, +0x0001195b, +0x0001195a, +0x00011959, +0x00011957, +0x00011956, +0x00011955, +0x00011953, +0x00011952, +0x00011951, +0x00011950, +0x0001194f, +0x0001194e, +0x0001194d, +0x0001194b, +0x0001194a, +0x00011948, +0x00011947, +0x00011946, +0x00011945, +0x00011944, +0x00011943, +0x00011942, +0x00011941, +0x00011940, +0x0001193d, +0x0001193c, +0x0001193b, +0x0001193a, +0x00011939, +0x00011938, +0x00011937, +0x00011936, +0x00011935, +0x00011934, +0x00011931, +0x00011930, +0x0001192f, +0x0001192e, +0x0001192d, +0x0001192c, +0x0001192b, +0x0001192a, +0x00011929, +0x00011928, +0x00011925, +0x00011924, +0x00011923, +0x00011922, +0x00011921, +0x00011920, +0x0001191f, +0x0001191e, +0x0001191d, +0x0001191b, +0x00011919, +0x00011918, +0x00011917, +0x00011916, +0x00011915, +0x00011914, +0x00011913, +0x00011912, +0x00011910, +0x0001190f, +0x0001190e, +0x0001190c, +0x0001190b, +0x0001190a, +0x00011909, +0x00011908, +0x00011907, +0x00011905, +0x00011904, +0x00011903, +0x00011902, +0x00011900, +0x000118ff, +0x000118fe, +0x000118fd, +0x000118fc, +0x000118fb, +0x000118f9, +0x000118f8, +0x000118f7, +0x000118f6, +0x000118f4, +0x000118f3, +0x000118f2, +0x000118f1, +0x000118f0, +0x000118ee, +0x000118ed, +0x000118ec, +0x000118eb, +0x000118ea, +0x000118e8, +0x000118e7, +0x000118e6, +0x000118e5, +0x000118e3, +0x000118e2, +0x000118e1, +0x000118e0, +0x000118df, +0x000118de, +0x000118dd, +0x000118db, +0x000118da, +0x000118d8, +0x000118d7, +0x000118d6, +0x000118d5, +0x000118d4, +0x000118d3, +0x000118d2, +0x000118d1, +0x000118cf, +0x000118ce, +0x000118cc, +0x000118cb, +0x000118ca, +0x000118c9, +0x000118c8, +0x000118c7, +0x000118c6, +0x000118c5, +0x000118c3, +0x000118c1, +0x000118c0, +0x000118bf, +0x000118be, +0x000118bd, +0x000118bc, +0x000118bb, +0x000118ba, +0x000118b9, +0x000118b6, +0x000118b5, +0x000118b4, +0x000118b3, +0x000118b2, +0x000118b1, +0x000118b0, +0x000118af, +0x000118ae, +0x000118ad, +0x000118ab, +0x000118a9, +0x000118a8, +0x000118a7, +0x000118a6, +0x000118a5, +0x000118a4, +0x000118a3, +0x000118a2, +0x000118a1, +0x0001189f, +0x0001189d, +0x0001189c, +0x0001189b, +0x0001189a, +0x00011899, +0x00011898, +0x00011897, +0x00011896, +0x00011894, +0x00011893, +0x00011891, +0x00011890, +0x0001188f, +0x0001188e, +0x0001188d, +0x0001188c, +0x0001188b, +0x00011889, +0x00011888, +0x00011887, +0x00011885, +0x00011884, +0x00011883, +0x00011882, +0x00011881, +0x00011880, +0x0001187e, +0x0001187d, +0x0001187c, +0x0001187b, +0x00011879, +0x00011878, +0x00011877, +0x00011876, +0x00011875, +0x00011874, +0x00011872, +0x00011871, +0x00011870, +0x0001186f, +0x0001186e, +0x0001186c, +0x0001186b, +0x0001186a, +0x00011869, +0x00011867, +0x00011866, +0x00011865, +0x00011864, +0x00011863, +0x00011862, +0x00011860, +0x0001185f, +0x0001185e, +0x0001185d, +0x0001185c, +0x0001185b, +0x0001185a, +0x00011859, +0x00011856, +0x00011855, +0x00011854, +0x00011853, +0x00011852, +0x00011851, +0x00011850, +0x0001184f, +0x0001184e, +0x0001184d, +0x0001184b, +0x00011849, +0x00011848, +0x00011847, +0x00011846, +0x00011845, +0x00011844, +0x00011843, +0x00011842, +0x00011841, +0x0001183f, +0x0001183d, +0x0001183c, +0x0001183b, +0x0001183a, +0x00011839, +0x00011838, +0x00011837, +0x00011836, +0x00011835, +0x00011833, +0x00011832, +0x00011830, +0x0001182f, +0x0001182e, +0x0001182d, +0x0001182c, +0x0001182b, +0x0001182a, +0x00011828, +0x00011827, +0x00011826, +0x00011825, +0x00011823, +0x00011822, +0x00011821, +0x00011820, +0x0001181f, +0x0001181e, +0x0001181c, +0x0001181b, +0x0001181a, +0x00011819, +0x00011817, +0x00011816, +0x00011815, +0x00011814, +0x00011813, +0x00011812, +0x00011810, +0x0001180f, +0x0001180e, +0x0001180d, +0x0001180c, +0x0001180a, +0x00011809, +0x00011808, +0x00011807, +0x00011805, +0x00011804, +0x00011803, +0x00011802, +0x00011801, +0x00011800, +0x000117ff, +0x000117fd, +0x000117fc, +0x000117fb, +0x000117f9, +0x000117f8, +0x000117f7, +0x000117f6, +0x000117f5, +0x000117f4, +0x000117f3, +0x000117f1, +0x000117f0, +0x000117ef, +0x000117ed, +0x000117ec, +0x000117eb, +0x000117ea, +0x000117e9, +0x000117e8, +0x000117e7, +0x000117e6, +0x000117e4, +0x000117e2, +0x000117e1, +0x000117e0, +0x000117df, +0x000117de, +0x000117dd, +0x000117dc, +0x000117db, +0x000117da, +0x000117d9, +0x000117d6, +0x000117d5, +0x000117d4, +0x000117d3, +0x000117d2, +0x000117d1, +0x000117d0, +0x000117cf, +0x000117ce, +0x000117cd, +0x000117ca, +0x000117c9, +0x000117c8, +0x000117c7, +0x000117c6, +0x000117c4, +0x000117c3, +0x000117c2, +0x000117c1, +0x000117c0, +0x000117bf, +0x000117be, +0x000117bd, +0x000117bb, +0x000117b9, +0x000117b8, +0x000117b7, +0x000117b6, +0x000117b5, +0x000117b4, +0x000117b3, +0x000117b2, +0x000117b1, +0x000117af, +0x000117ae, +0x000117ac, +0x000117ab, +0x000117aa, +0x000117a9, +0x000117a8, +0x000117a7, +0x000117a6, +0x000117a5, +0x000117a3, +0x000117a2, +0x000117a1, +0x0001179f, +0x0001179e, +0x0001179d, +0x0001179c, +0x0001179b, +0x0001179a, +0x00011799, +0x00011797, +0x00011796, +0x00011795, +0x00011794, +0x00011792, +0x00011791, +0x00011790, +0x0001178f, +0x0001178e, +0x0001178d, +0x0001178c, +0x0001178a, +0x00011789, +0x00011788, +0x00011787, +0x00011785, +0x00011784, +0x00011783, +0x00011782, +0x00011781, +0x00011780, +0x0001177e, +0x0001177d, +0x0001177c, +0x0001177b, +0x0001177a, +0x00011779, +0x00011777, +0x00011776, +0x00011775, +0x00011774, +0x00011772, +0x00011771, +0x00011770, +0x0001176f, +0x0001176e, +0x0001176d, +0x0001176c, +0x0001176a, +0x00011769, +0x00011768, +0x00011766, +0x00011765, +0x00011764, +0x00011763, +0x00011762, +0x00011761, +0x00011760, +0x0001175f, +0x0001175d, +0x0001175c, +0x0001175a, +0x00011759, +0x00011758, +0x00011757, +0x00011756, +0x00011755, +0x00011754, +0x00011753, +0x00011752, +0x00011750, +0x0001174e, +0x0001174d, +0x0001174c, +0x0001174b, +0x0001174a, +0x00011749, +0x00011748, +0x00011747, +0x00011746, +0x00011745, +0x00011742, +0x00011741, +0x00011740, +0x0001173f, +0x0001173e, +0x0001173d, +0x0001173c, +0x0001173b, +0x0001173a, +0x00011739, +0x00011738, +0x00011735, +0x00011734, +0x00011733, +0x00011732, +0x00011731, +0x00011730, +0x0001172f, +0x0001172e, +0x0001172d, +0x0001172c, +0x0001172b, +0x00011728, +0x00011727, +0x00011726, +0x00011725, +0x00011724, +0x00011723, +0x00011722, +0x00011721, +0x00011720, +0x0001171f, +0x0001171d, +0x0001171b, +0x0001171a, +0x00011719, +0x00011718, +0x00011717, +0x00011716, +0x00011715, +0x00011714, +0x00011713, +0x00011711, +0x00011710, +0x0001170f, +0x0001170d, +0x0001170c, +0x0001170b, +0x0001170a, +0x00011709, +0x00011708, +0x00011707, +0x00011705, +0x00011704, +0x00011703, +0x00011702, +0x00011700, +0x000116ff, +0x000116fe, +0x000116fd, +0x000116fc, +0x000116fb, +0x000116f9, +0x000116f8, +0x000116f7, +0x000116f6, +0x000116f5, +0x000116f3, +0x000116f2, +0x000116f1, +0x000116f0, +0x000116ef, +0x000116ed, +0x000116ec, +0x000116eb, +0x000116ea, +0x000116e9, +0x000116e8, +0x000116e6, +0x000116e5, +0x000116e4, +0x000116e3, +0x000116e1, +0x000116e0, +0x000116df, +0x000116de, +0x000116dd, +0x000116dc, +0x000116db, +0x000116d9, +0x000116d8, +0x000116d7, +0x000116d5, +0x000116d4, +0x000116d3, +0x000116d2, +0x000116d1, +0x000116d0, +0x000116cf, +0x000116ce, +0x000116cc, +0x000116cb, +0x000116ca, +0x000116c8, +0x000116c7, +0x000116c6, +0x000116c5, +0x000116c4, +0x000116c3, +0x000116c2, +0x000116c1, +0x000116bf, +0x000116be, +0x000116bc, +0x000116bb, +0x000116ba, +0x000116b9, +0x000116b8, +0x000116b7, +0x000116b6, +0x000116b5, +0x000116b4, +0x000116b2, +0x000116b0, +0x000116af, +0x000116ae, +0x000116ad, +0x000116ac, +0x000116ab, +0x000116aa, +0x000116a9, +0x000116a8, +0x000116a7, +0x000116a6, +0x000116a3, +0x000116a2, +0x000116a1, +0x000116a0, +0x0001169f, +0x0001169e, +0x0001169d, +0x0001169c, +0x0001169b, +0x0001169a, +0x00011698, +0x00011696, +0x00011695, +0x00011695, +0x00011693, +0x00011692, +0x00011690, +0x0001168f, +0x0001168e, +0x0001168d, +0x0001168c, +0x0001168b, +0x0001168a, +0x00011689, +0x00011688, +0x00011686, +0x00011684, +0x00011683, +0x00011682, +0x00011681, +0x00011680, +0x0001167f, +0x0001167e, +0x0001167d, +0x0001167c, +0x0001167b, +0x0001167a, +0x00011677, +0x00011676, +0x00011675, +0x00011674, +0x00011673, +0x00011672, +0x00011671, +0x00011670, +0x0001166f, +0x0001166e, +0x0001166d, +0x0001166a, +0x00011669, +0x00011668, +0x00011667, +0x00011666, +0x00011665, +0x00011664, +0x00011663, +0x00011662, +0x00011661, +0x00011660, +0x0001165e, +0x0001165c, +0x0001165b, +0x0001165a, +0x00011659, +0x00011658, +0x00011657, +0x00011656, +0x00011655, +0x00011654, +0x00011653, +0x00011651, +0x00011650, +0x0001164e, +0x0001164d, +0x0001164c, +0x0001164b, +0x0001164a, +0x00011649, +0x00011648, +0x00011647, +0x00011646, +0x00011644, +0x00011643, +0x00011641, +0x00011640, +0x0001163f, +0x0001163e, +0x0001163d, +0x0001163c, +0x0001163b, +0x0001163a, +0x00011638, +0x00011637, +0x00011636, +0x00011635, +0x00011633, +0x00011632, +0x00011631, +0x00011630, +0x0001162f, +0x0001162e, +0x0001162d, +0x0001162b, +0x0001162a, +0x00011629, +0x00011628, +0x00011627, +0x00011625, +0x00011624, +0x00011623, +0x00011622, +0x00011621, +0x0001161f, +0x0001161e, +0x0001161d, +0x0001161c, +0x0001161b, +0x0001161a, +0x00011618, +0x00011617, +0x00011616, +0x00011615, +0x00011614, +0x00011612, +0x00011611, +0x00011610, +0x0001160f, +0x0001160e, +0x0001160d, +0x0001160c, +0x0001160a, +0x00011609, +0x00011608, +0x00011607, +0x00011605, +0x00011604, +0x00011603, +0x00011602, +0x00011601, +0x00011600, +0x000115ff, +0x000115fe, +0x000115fc, +0x000115fb, +0x000115f9, +0x000115f8, +0x000115f7, +0x000115f6, +0x000115f5, +0x000115f4, +0x000115f3, +0x000115f2, +0x000115f1, +0x000115ef, +0x000115ee, +0x000115ec, +0x000115eb, +0x000115ea, +0x000115e9, +0x000115e8, +0x000115e7, +0x000115e6, +0x000115e5, +0x000115e4, +0x000115e3, +0x000115e1, +0x000115df, +0x000115de, +0x000115dd, +0x000115dc, +0x000115db, +0x000115da, +0x000115d9, +0x000115d8, +0x000115d7, +0x000115d6, +0x000115d3, +0x000115d2, +0x000115d1, +0x000115d0, +0x000115cf, +0x000115ce, +0x000115cd, +0x000115cc, +0x000115cb, +0x000115ca, +0x000115c9, +0x000115c8, +0x000115c5, +0x000115c4, +0x000115c3, +0x000115c2, +0x000115c1, +0x000115c0, +0x000115bf, +0x000115be, +0x000115bd, +0x000115bc, +0x000115bb, +0x000115b9, +0x000115b7, +0x000115b6, +0x000115b5, +0x000115b4, +0x000115b3, +0x000115b2, +0x000115b1, +0x000115b0, +0x000115af, +0x000115ad, +0x000115ac, +0x000115aa, +0x000115a9, +0x000115a8, +0x000115a7, +0x000115a6, +0x000115a5, +0x000115a4, +0x000115a3, +0x000115a2, +0x000115a0, +0x0001159f, +0x0001159e, +0x0001159c, +0x0001159b, +0x0001159a, +0x00011599, +0x00011598, +0x00011597, +0x00011596, +0x00011594, +0x00011593, +0x00011592, +0x00011591, +0x00011590, +0x0001158e, +0x0001158d, +0x0001158c, +0x0001158b, +0x0001158a, +0x00011589, +0x00011587, +0x00011586, +0x00011585, +0x00011584, +0x00011583, +0x00011581, +0x00011580, +0x0001157f, +0x0001157e, +0x0001157d, +0x0001157c, +0x0001157a, +0x00011579, +0x00011578, +0x00011577, +0x00011576, +0x00011575, +0x00011573, +0x00011572, +0x00011571, +0x00011570, +0x0001156e, +0x0001156d, +0x0001156c, +0x0001156b, +0x0001156a, +0x00011569, +0x00011568, +0x00011567, +0x00011566, +0x00011565, +0x00011564, +0x00011561, +0x00011560, +0x0001155f, +0x0001155e, +0x0001155d, +0x0001155c, +0x0001155b, +0x0001155a, +0x00011559, +0x00011558, +0x00011557, +0x00011555, +0x00011553, +0x00011552, +0x00011551, +0x00011550, +0x0001154f, +0x0001154e, +0x0001154d, +0x0001154c, +0x0001154b, +0x0001154a, +0x00011548, +0x00011547, +0x00011545, +0x00011544, +0x00011543, +0x00011542, +0x00011541, +0x00011540, +0x0001153f, +0x0001153e, +0x0001153d, +0x0001153c, +0x0001153a, +0x00011539, +0x00011537, +0x00011536, +0x00011535, +0x00011534, +0x00011533, +0x00011532, +0x00011531, +0x00011530, +0x0001152f, +0x0001152d, +0x0001152c, +0x0001152b, +0x00011529, +0x00011528, +0x00011527, +0x00011526, +0x00011525, +0x00011524, +0x00011523, +0x00011522, +0x00011520, +0x0001151f, +0x0001151e, +0x0001151d, +0x0001151c, +0x0001151a, +0x00011519, +0x00011518, +0x00011517, +0x00011516, +0x00011515, +0x00011513, +0x00011512, +0x00011511, +0x00011510, +0x0001150f, +0x0001150e, +0x0001150c, +0x0001150b, +0x0001150a, +0x00011509, +0x00011508, +0x00011506, +0x00011505, +0x00011504, +0x00011503, +0x00011502, +0x00011501, +0x00011500, +0x000114fe, +0x000114fd, +0x000114fc, +0x000114fb, +0x000114fa, +0x000114f8, +0x000114f7, +0x000114f6, +0x000114f5, +0x000114f4, +0x000114f3, +0x000114f2, +0x000114f0, +0x000114ef, +0x000114ee, +0x000114ed, +0x000114eb, +0x000114ea, +0x000114e9, +0x000114e8, +0x000114e7, +0x000114e6, +0x000114e5, +0x000114e4, +0x000114e2, +0x000114e1, +0x000114e0, +0x000114de, +0x000114dd, +0x000114dc, +0x000114db, +0x000114da, +0x000114d9, +0x000114d8, +0x000114d7, +0x000114d6, +0x000114d4, +0x000114d3, +0x000114d1, +0x000114d0, +0x000114cf, +0x000114ce, +0x000114cd, +0x000114cc, +0x000114cb, +0x000114ca, +0x000114c9, +0x000114c8, +0x000114c7, +0x000114c4, +0x000114c3, +0x000114c2, +0x000114c1, +0x000114c0, +0x000114bf, +0x000114be, +0x000114bd, +0x000114bc, +0x000114bb, +0x000114ba, +0x000114b9, +0x000114b6, +0x000114b5, +0x000114b4, +0x000114b3, +0x000114b2, +0x000114b1, +0x000114b0, +0x000114af, +0x000114ae, +0x000114ad, +0x000114ac, +0x000114ab, +0x000114a8, +0x000114a7, +0x000114a6, +0x000114a5, +0x000114a4, +0x000114a3, +0x000114a2, +0x000114a1, +0x000114a0, +0x0001149f, +0x0001149e, +0x0001149c, +0x0001149a, +0x00011499, +0x00011498, +0x00011497, +0x00011496, +0x00011495, +0x00011494, +0x00011493, +0x00011492, +0x00011491, +0x0001148f, +0x0001148e, +0x0001148c, +0x0001148b, +0x0001148a, +0x00011489, +0x00011488, +0x00011487, +0x00011486, +0x00011485, +0x00011484, +0x00011482, +0x00011481, +0x00011480, +0x0001147f, +0x0001147d, +0x0001147c, +0x0001147b, +0x0001147a, +0x00011479, +0x00011478, +0x00011477, +0x00011476, +0x00011474, +0x00011473, +0x00011472, +0x00011471, +0x0001146f, +0x0001146e, +0x0001146d, +0x0001146c, +0x0001146b, +0x0001146a, +0x00011469, +0x00011467, +0x00011466, +0x00011465, +0x00011464, +0x00011463, +0x00011461, +0x00011460, +0x0001145f, +0x0001145e, +0x0001145d, +0x0001145c, +0x0001145a, +0x00011459, +0x00011458, +0x00011457, +0x00011456, +0x00011455, +0x00011453, +0x00011452, +0x00011451, +0x00011450, +0x0001144f, +0x0001144d, +0x0001144c, +0x0001144b, +0x0001144a, +0x00011449, +0x00011448, +0x00011447, +0x00011445, +0x00011444, +0x00011443, +0x00011442, +0x00011440, +0x0001143f, +0x0001143e, +0x0001143d, +0x0001143c, +0x0001143b, +0x0001143a, +0x00011439, +0x00011438, +0x00011437, +0x00011436, +0x00011435, +0x00011433, +0x00011432, +0x00011431, +0x0001142f, +0x0001142e, +0x0001142d, +0x0001142c, +0x0001142b, +0x0001142a, +0x00011429, +0x00011428, +0x00011427, +0x00011426, +0x00011424, +0x00011423, +0x00011421, +0x00011420, +0x0001141f, +0x0001141e, +0x0001141d, +0x0001141c, +0x0001141b, +0x0001141a, +0x00011419, +0x00011418, +0x00011417, +0x00011414, +0x00011413, +0x00011412, +0x00011411, +0x00011410, +0x0001140f, +0x0001140e, +0x0001140d, +0x0001140c, +0x0001140b, +0x0001140a, +0x00011409, +0x00011406, +0x00011405, +0x00011404, +0x00011403, +0x00011402, +0x00011401, +0x00011400, +0x000113ff, +0x000113fe, +0x000113fd, +0x000113fc, +0x000113fb, +0x000113fa, +0x000113f7, +0x000113f6, +0x000113f5, +0x000113f4, +0x000113f3, +0x000113f2, +0x000113f1, +0x000113f0, +0x000113ef, +0x000113ee, +0x000113ed, +0x000113ec, +0x000113ea, +0x000113e8, +0x000113e7, +0x000113e6, +0x000113e5, +0x000113e4, +0x000113e3, +0x000113e2, +0x000113e1, +0x000113e0, +0x000113df, +0x000113de, +0x000113dc, +0x000113db, +0x000113d9, +0x000113d8, +0x000113d7, +0x000113d6, +0x000113d5, +0x000113d4, +0x000113d3, +0x000113d2, +0x000113d1, +0x000113cf, +0x000113ce, +0x000113cd, +0x000113cc, +0x000113ca, +0x000113c9, +0x000113c8, +0x000113c7, +0x000113c6, +0x000113c5, +0x000113c4, +0x000113c3, +0x000113c1, +0x000113c0, +0x000113bf, +0x000113be, +0x000113bc, +0x000113bb, +0x000113ba, +0x000113b9, +0x000113b8, +0x000113b7, +0x000113b6, +0x000113b5, +0x000113b3, +0x000113b2, +0x000113b1, +0x000113b0, +0x000113af, +0x000113ad, +0x000113ac, +0x000113ab, +0x000113aa, +0x000113a9, +0x000113a8, +0x000113a7, +0x000113a5, +0x000113a4, +0x000113a3, +0x000113a1, +0x000113a0, +0x0001139f, +0x0001139e, +0x0001139d, +0x0001139c, +0x0001139b, +0x0001139a, +0x00011399, +0x00011397, +0x00011396, +0x00011395, +0x00011394, +0x00011392, +0x00011391, +0x00011390, +0x0001138f, +0x0001138e, +0x0001138d, +0x0001138c, +0x0001138b, +0x0001138a, +0x00011388, +0x00011387, +0x00011386, +0x00011385, +0x00011384, +0x00011382, +0x00011381, +0x00011380, +0x0001137f, +0x0001137e, +0x0001137d, +0x0001137c, +0x0001137a, +0x00011379, +0x00011378, +0x00011377, +0x00011376, +0x00011375, +0x00011373, +0x00011372, +0x00011371, +0x00011370, +0x0001136f, +0x0001136e, +0x0001136c, +0x0001136b, +0x0001136a, +0x00011369, +0x00011368, +0x00011367, +0x00011366, +0x00011365, +0x00011363, +0x00011362, +0x00011361, +0x00011360, +0x0001135f, +0x0001135d, +0x0001135c, +0x0001135b, +0x0001135a, +0x00011359, +0x00011358, +0x00011357, +0x00011356, +0x00011354, +0x00011353, +0x00011352, +0x00011351, +0x0001134f, +0x0001134e, +0x0001134d, +0x0001134c, +0x0001134b, +0x0001134a, +0x00011349, +0x00011348, +0x00011347, +0x00011346, +0x00011344, +0x00011343, +0x00011342, +0x00011340, +0x0001133f, +0x0001133e, +0x0001133d, +0x0001133c, +0x0001133b, +0x0001133a, +0x00011339, +0x00011338, +0x00011337, +0x00011335, +0x00011334, +0x00011332, +0x00011331, +0x00011330, +0x0001132f, +0x0001132e, +0x0001132d, +0x0001132c, +0x0001132b, +0x0001132a, +0x00011329, +0x00011328, +0x00011327, +0x00011325, +0x00011323, +0x00011322, +0x00011321, +0x00011320, +0x0001131f, +0x0001131e, +0x0001131d, +0x0001131c, +0x0001131b, +0x0001131a, +0x00011319, +0x00011318, +0x00011315, +0x00011314, +0x00011313, +0x00011312, +0x00011311, +0x00011310, +0x0001130f, +0x0001130e, +0x0001130d, +0x0001130c, +0x0001130b, +0x0001130a, +0x00011309, +0x00011308, +0x00011305, +0x00011304, +0x00011303, +0x00011302, +0x00011301, +0x00011300, +0x000112ff, +0x000112fe, +0x000112fd, +0x000112fc, +0x000112fb, +0x000112fa, +0x000112f8, +0x000112f6, +0x000112f5, +0x000112f4, +0x000112f3, +0x000112f2, +0x000112f1, +0x000112f0, +0x000112ef, +0x000112ee, +0x000112ed, +0x000112ec, +0x000112eb, +0x000112e9, +0x000112e8, +0x000112e6, +0x000112e5, +0x000112e4, +0x000112e3, +0x000112e2, +0x000112e1, +0x000112e0, +0x000112df, +0x000112de, +0x000112dd, +0x000112db, +0x000112da, +0x000112d9, +0x000112d7, +0x000112d6, +0x000112d5, +0x000112d4, +0x000112d3, +0x000112d2, +0x000112d1, +0x000112d0, +0x000112cf, +0x000112ce, +0x000112cc, +0x000112cb, +0x000112ca, +0x000112c9, +0x000112c7, +0x000112c6, +0x000112c5, +0x000112c4, +0x000112c3, +0x000112c2, +0x000112c1, +0x000112c0, +0x000112be, +0x000112bd, +0x000112bc, +0x000112bb, +0x000112ba, +0x000112b8, +0x000112b7, +0x000112b6, +0x000112b5, +0x000112b4, +0x000112b3, +0x000112b2, +0x000112b1, +0x000112af, +0x000112ae, +0x000112ad, +0x000112ac, +0x000112ab, +0x000112a9, +0x000112a8, +0x000112a7, +0x000112a6, +0x000112a5, +0x000112a4, +0x000112a3, +0x000112a1, +0x000112a0, +0x0001129f, +0x0001129e, +0x0001129d, +0x0001129c, +0x0001129b, +0x00011299, +0x00011298, +0x00011297, +0x00011296, +0x00011295, +0x00011294, +0x00011292, +0x00011291, +0x00011290, +0x0001128f, +0x0001128e, +0x0001128d, +0x0001128c, +0x0001128a, +0x00011289, +0x00011288, +0x00011287, +0x00011286, +0x00011284, +0x00011283, +0x00011282, +0x00011281, +0x00011280, +0x0001127f, +0x0001127d, +0x0001127c, +0x0001127b, +0x0001127a, +0x00011279, +0x00011278, +0x00011277, +0x00011276, +0x00011275, +0x00011274, +0x00011273, +0x00011271, +0x00011270, +0x0001126f, +0x0001126d, +0x0001126c, +0x0001126b, +0x0001126a, +0x00011269, +0x00011268, +0x00011267, +0x00011266, +0x00011265, +0x00011264, +0x00011262, +0x00011261, +0x00011260, +0x0001125f, +0x0001125d, +0x0001125c, +0x0001125b, +0x0001125a, +0x00011259, +0x00011258, +0x00011257, +0x00011256, +0x00011255, +0x00011253, +0x00011252, +0x00011251, +0x00011250, +0x0001124f, +0x0001124d, +0x0001124c, +0x0001124b, +0x0001124a, +0x00011249, +0x00011248, +0x00011247, +0x00011246, +0x00011245, +0x00011243, +0x00011242, +0x00011241, +0x00011240, +0x0001123f, +0x0001123d, +0x0001123c, +0x0001123b, +0x0001123a, +0x00011239, +0x00011238, +0x00011237, +0x00011236, +0x00011234, +0x00011233, +0x00011232, +0x00011231, +0x00011230, +0x0001122f, +0x0001122e, +0x0001122c, +0x0001122b, +0x0001122a, +0x00011229, +0x00011228, +0x00011227, +0x00011225, +0x00011224, +0x00011223, +0x00011222, +0x00011221, +0x00011220, +0x0001121f, +0x0001121e, +0x0001121c, +0x0001121b, +0x0001121a, +0x00011219, +0x00011218, +0x00011216, +0x00011215, +0x00011214, +0x00011213, +0x00011212, +0x00011211, +0x00011210, +0x0001120f, +0x0001120e, +0x0001120c, +0x0001120b, +0x0001120a, +0x00011209, +0x00011207, +0x00011206, +0x00011205, +0x00011204, +0x00011203, +0x00011202, +0x00011201, +0x00011200, +0x000111ff, +0x000111fe, +0x000111fc, +0x000111fb, +0x000111fa, +0x000111f9, +0x000111f7, +0x000111f6, +0x000111f5, +0x000111f4, +0x000111f3, +0x000111f2, +0x000111f1, +0x000111f0, +0x000111ef, +0x000111ee, +0x000111ed, +0x000111eb, +0x000111ea, +0x000111e8, +0x000111e7, +0x000111e6, +0x000111e5, +0x000111e4, +0x000111e3, +0x000111e2, +0x000111e1, +0x000111e0, +0x000111df, +0x000111de, +0x000111dd, +0x000111db, +0x000111d9, +0x000111d8, +0x000111d7, +0x000111d6, +0x000111d5, +0x000111d4, +0x000111d3, +0x000111d2, +0x000111d1, +0x000111d0, +0x000111cf, +0x000111ce, +0x000111cd, +0x000111ca, +0x000111c9, +0x000111c8, +0x000111c7, +0x000111c6, +0x000111c5, +0x000111c4, +0x000111c3, +0x000111c2, +0x000111c1, +0x000111c0, +0x000111bf, +0x000111be, +0x000111bd, +0x000111ba, +0x000111b9, +0x000111b8, +0x000111b7, +0x000111b6, +0x000111b5, +0x000111b4, +0x000111b3, +0x000111b2, +0x000111b1, +0x000111b0, +0x000111af, +0x000111ae, +0x000111ad, +0x000111aa, +0x000111a9, +0x000111a8, +0x000111a7, +0x000111a6, +0x000111a5, +0x000111a4, +0x000111a3, +0x000111a2, +0x000111a1, +0x000111a0, +0x0001119f, +0x0001119e, +0x0001119c, +0x0001119b, +0x00011199, +0x00011198, +0x00011197, +0x00011196, +0x00011195, +0x00011194, +0x00011193, +0x00011192, +0x00011191, +0x00011190, +0x0001118f, +0x0001118d, +0x0001118c, +0x0001118b, +0x00011189, +0x00011188, +0x00011187, +0x00011186, +0x00011185, +0x00011184, +0x00011183, +0x00011182, +0x00011181, +0x00011180, +0x0001117e, +0x0001117d, +0x0001117c, +0x0001117b, +0x00011179, +0x00011178, +0x00011177, +0x00011176, +0x00011175, +0x00011174, +0x00011173, +0x00011172, +0x00011171, +0x00011170, +0x0001116e, +0x0001116d, +0x0001116c, +0x0001116b, +0x00011169, +0x00011168, +0x00011167, +0x00011166, +0x00011165, +0x00011164, +0x00011163, +0x00011162, +0x00011161, +0x0001115f, +0x0001115e, +0x0001115d, +0x0001115c, +0x0001115b, +0x0001115a, +0x00011159, +0x00011157, +0x00011156, +0x00011155, +0x00011154, +0x00011153, +0x00011152, +0x00011151, +0x00011150, +0x0001114f, +0x0001114e, +0x0001114c, +0x0001114b, +0x0001114a, +0x00011149, +0x00011147, +0x00011146, +0x00011145, +0x00011144, +0x00011143, +0x00011142, +0x00011141, +0x00011140, +0x0001113f, +0x0001113e, +0x0001113d, +0x0001113b, +0x0001113a, +0x00011139, +0x00011137, +0x00011136, +0x00011135, +0x00011134, +0x00011133, +0x00011132, +0x00011131, +0x00011130, +0x0001112f, +0x0001112e, +0x0001112d, +0x0001112c, +0x0001112a, +0x00011129, +0x00011127, +0x00011126, +0x00011125, +0x00011124, +0x00011123, +0x00011122, +0x00011121, +0x00011120, +0x0001111f, +0x0001111e, +0x0001111d, +0x0001111c, +0x0001111b, +0x00011119, +0x00011117, +0x00011116, +0x00011115, +0x00011114, +0x00011113, +0x00011112, +0x00011111, +0x00011110, +0x0001110f, +0x0001110e, +0x0001110d, +0x0001110c, +0x0001110b, +0x0001110a, +0x00011107, +0x00011106, +0x00011105, +0x00011104, +0x00011103, +0x00011102, +0x00011101, +0x00011100, +0x000110ff, +0x000110fe, +0x000110fd, +0x000110fc, +0x000110fb, +0x000110fa, +0x000110f9, +0x000110f6, +0x000110f5, +0x000110f4, +0x000110f3, +0x000110f2, +0x000110f1, +0x000110f0, +0x000110ef, +0x000110ee, +0x000110ed, +0x000110ec, +0x000110eb, +0x000110ea, +0x000110e9, +0x000110e7, +0x000110e5, +0x000110e4, +0x000110e3, +0x000110e2, +0x000110e1, +0x000110e0, +0x000110df, +0x000110de, +0x000110dd, +0x000110dc, +0x000110db, +0x000110da, +0x000110d9, +0x000110d7, +0x000110d6, +0x000110d4, +0x000110d3, +0x000110d2, +0x000110d1, +0x000110d0, +0x000110cf, +0x000110ce, +0x000110cd, +0x000110cc, +0x000110cb, +0x000110ca, +0x000110c8, +0x000110c7, +0x000110c6, +0x000110c5, +0x000110c4, +0x000110c2, +0x000110c1, +0x000110c0, +0x000110bf, +0x000110bd, +0x000110bc, +0x000110bb, +0x000110ba, +0x000110b9, +0x000110b8, +0x000110b7, +0x000110b6, +0x000110b5, +0x000110b4, +0x000110b3, +0x000110b1, +0x000110b0, +0x000110af, +0x000110ae, +0x000110ad, +0x000110ab, +0x000110aa, +0x000110a9, +0x000110a8, +0x000110a7, +0x000110a6, +0x000110a5, +0x000110a4, +0x000110a3, +0x000110a2, +0x000110a0, +0x0001109f, +0x0001109e, +0x0001109d, +0x0001109c, +0x0001109b, +0x00011099, +0x00011098, +0x00011097, +0x00011096, +0x00011095, +0x00011094, +0x00011093, +0x00011092, +0x00011091, +0x0001108f, +0x0001108e, +0x0001108d, +0x0001108c, +0x0001108b, +0x0001108a, +0x00011089, +0x00011087, +0x00011086, +0x00011085, +0x00011084, +0x00011083, +0x00011082, +0x00011081, +0x00011080, +0x0001107e, +0x0001107d, +0x0001107c, +0x0001107b, +0x0001107a, +0x00011079, +0x00011078, +0x00011077, +0x00011075, +0x00011074, +0x00011073, +0x00011072, +0x00011071, +0x00011070, +0x0001106f, +0x0001106d, +0x0001106c, +0x0001106b, +0x0001106a, +0x00011069, +0x00011068, +0x00011067, +0x00011066, +0x00011065, +0x00011063, +0x00011062, +0x00011061, +0x00011060, +0x0001105f, +0x0001105e, +0x0001105c, +0x0001105b, +0x0001105a, +0x00011059, +0x00011058, +0x00011057, +0x00011056, +0x00011055, +0x00011054, +0x00011053, +0x00011051, +0x00011050, +0x0001104f, +0x0001104e, +0x0001104d, +0x0001104b, +0x0001104a, +0x00011049, +0x00011048, +0x00011047, +0x00011046, +0x00011045, +0x00011044, +0x00011043, +0x00011042, +0x00011041, +0x0001103f, +0x0001103e, +0x0001103d, +0x0001103c, +0x0001103a, +0x00011039, +0x00011038, +0x00011037, +0x00011036, +0x00011035, +0x00011034, +0x00011033, +0x00011032, +0x00011031, +0x00011030, +0x0001102f, +0x0001102d, +0x0001102c, +0x0001102b, +0x00011029, +0x00011028, +0x00011027, +0x00011026, +0x00011025, +0x00011024, +0x00011023, +0x00011022, +0x00011021, +0x00011020, +0x0001101f, +0x0001101e, +0x0001101d, +0x0001101b, +0x0001101a, +0x00011018, +0x00011017, +0x00011016, +0x00011015, +0x00011014, +0x00011013, +0x00011012, +0x00011011, +0x00011010, +0x0001100f, +0x0001100e, +0x0001100d, +0x0001100c, +0x0001100b, +0x00011009, +0x00011007, +0x00011006, +0x00011005, +0x00011004, +0x00011003, +0x00011002, +0x00011001, +0x00011000, +0x00010fff, +0x00010ffe, +0x00010ffd, +0x00010ffc, +0x00010ffb, +0x00010ffa, +0x00010ff9, +0x00010ff6, +0x00010ff5, +0x00010ff4, +0x00010ff3, +0x00010ff2, +0x00010ff1, +0x00010ff0, +0x00010fef, +0x00010fee, +0x00010fed, +0x00010fec, +0x00010feb, +0x00010fea, +0x00010fe9, +0x00010fe8, +0x00010fe7, +0x00010fe4, +0x00010fe3, +0x00010fe2, +0x00010fe1, +0x00010fe0, +0x00010fdf, +0x00010fde, +0x00010fdd, +0x00010fdc, +0x00010fdb, +0x00010fda, +0x00010fd9, +0x00010fd8, +0x00010fd7, +0x00010fd6, +0x00010fd4, +0x00010fd2, +0x00010fd1, +0x00010fd0, +0x00010fcf, +0x00010fce, +0x00010fcd, +0x00010fcc, +0x00010fcb, +0x00010fca, +0x00010fc9, +0x00010fc8, +0x00010fc7, +0x00010fc6, +0x00010fc5, +0x00010fc3, +0x00010fc2, +0x00010fc0, +0x00010fbf, +0x00010fbe, +0x00010fbd, +0x00010fbc, +0x00010fbb, +0x00010fba, +0x00010fb9, +0x00010fb8, +0x00010fb7, +0x00010fb6, +0x00010fb5, +0x00010fb4, +0x00010fb2, +0x00010fb1, +0x00010fb0, +0x00010fae, +0x00010fad, +0x00010fac, +0x00010fab, +0x00010faa, +0x00010fa9, +0x00010fa8, +0x00010fa6, +0x00010fa5, +0x00010fa4, +0x00010fa3, +0x00010fa2, +0x00010fa1, +0x00010fa0, +0x00010f9f, +0x00010f9e, +0x00010f9d, +0x00010f9c, +0x00010f9b, +0x00010f99, +0x00010f97, +0x00010f96, +0x00010f95, +0x00010f94, +0x00010f93, +0x00010f92, +0x00010f91, +0x00010f90, +0x00010f8f, +0x00010f8e, +0x00010f8d, +0x00010f8c, +0x00010f8b, +0x00010f8a, +0x00010f89, +0x00010f88, +0x00010f86, +0x00010f84, +0x00010f83, +0x00010f82, +0x00010f81, +0x00010f80, +0x00010f7f, +0x00010f7e, +0x00010f7d, +0x00010f7c, +0x00010f7b, +0x00010f7a, +0x00010f79, +0x00010f78, +0x00010f77, +0x00010f76, +0x00010f74, +0x00010f73, +0x00010f71, +0x00010f70, +0x00010f6f, +0x00010f6e, +0x00010f6d, +0x00010f6c, +0x00010f6b, +0x00010f6a, +0x00010f69, +0x00010f68, +0x00010f67, +0x00010f66, +0x00010f65, +0x00010f64, +0x00010f62, +0x00010f61, +0x00010f60, +0x00010f5f, +0x00010f5d, +0x00010f5c, +0x00010f5b, +0x00010f5a, +0x00010f59, +0x00010f58, +0x00010f57, +0x00010f56, +0x00010f55, +0x00010f54, +0x00010f53, +0x00010f52, +0x00010f50, +0x00010f4f, +0x00010f4e, +0x00010f4d, +0x00010f4c, +0x00010f4a, +0x00010f49, +0x00010f48, +0x00010f47, +0x00010f46, +0x00010f45, +0x00010f44, +0x00010f43, +0x00010f42, +0x00010f41, +0x00010f40, +0x00010f3e, +0x00010f3d, +0x00010f3c, +0x00010f3b, +0x00010f3a, +0x00010f39, +0x00010f37, +0x00010f36, +0x00010f35, +0x00010f34, +0x00010f33, +0x00010f32, +0x00010f31, +0x00010f30, +0x00010f2f, +0x00010f2e, +0x00010f2c, +0x00010f2b, +0x00010f2a, +0x00010f29, +0x00010f28, +0x00010f27, +0x00010f26, +0x00010f24, +0x00010f23, +0x00010f22, +0x00010f21, +0x00010f20, +0x00010f1f, +0x00010f1e, +0x00010f1d, +0x00010f1c, +0x00010f1a, +0x00010f19, +0x00010f18, +0x00010f17, +0x00010f16, +0x00010f15, +0x00010f14, +0x00010f13, +0x00010f11, +0x00010f10, +0x00010f0f, +0x00010f0e, +0x00010f0d, +0x00010f0c, +0x00010f0b, +0x00010f0a, +0x00010f08, +0x00010f07, +0x00010f06, +0x00010f05, +0x00010f04, +0x00010f03, +0x00010f02, +0x00010f01, +0x00010f00, +0x00010efe, +0x00010efd, +0x00010efc, +0x00010efb, +0x00010efa, +0x00010ef9, +0x00010ef8, +0x00010ef6, +0x00010ef5, +0x00010ef4, +0x00010ef3, +0x00010ef2, +0x00010ef1, +0x00010ef0, +0x00010eef, +0x00010eee, +0x00010eed, +0x00010eeb, +0x00010eea, +0x00010ee9, +0x00010ee8, +0x00010ee7, +0x00010ee6, +0x00010ee4, +0x00010ee3, +0x00010ee2, +0x00010ee1, +0x00010ee0, +0x00010edf, +0x00010ede, +0x00010edd, +0x00010edc, +0x00010edb, +0x00010eda, +0x00010ed8, +0x00010ed7, +0x00010ed6, +0x00010ed5, +0x00010ed4, +0x00010ed2, +0x00010ed1, +0x00010ed0, +0x00010ecf, +0x00010ece, +0x00010ecd, +0x00010ecc, +0x00010ecb, +0x00010eca, +0x00010ec9, +0x00010ec8, +0x00010ec7, +0x00010ec5, +0x00010ec4, +0x00010ec3, +0x00010ec2, +0x00010ec0, +0x00010ebf, +0x00010ebe, +0x00010ebd, +0x00010ebc, +0x00010ebb, +0x00010eba, +0x00010eb9, +0x00010eb8, +0x00010eb7, +0x00010eb6, +0x00010eb5, +0x00010eb4, +0x00010eb2, +0x00010eb1, +0x00010eb0, +0x00010eae, +0x00010ead, +0x00010eac, +0x00010eab, +0x00010eaa, +0x00010ea9, +0x00010ea8, +0x00010ea7, +0x00010ea6, +0x00010ea5, +0x00010ea4, +0x00010ea3, +0x00010ea2, +0x00010ea1, +0x00010e9f, +0x00010e9e, +0x00010e9c, +0x00010e9b, +0x00010e9a, +0x00010e99, +0x00010e98, +0x00010e97, +0x00010e96, +0x00010e95, +0x00010e94, +0x00010e93, +0x00010e92, +0x00010e91, +0x00010e90, +0x00010e8f, +0x00010e8e, +0x00010e8c, +0x00010e8a, +0x00010e89, +0x00010e88, +0x00010e88, +0x00010e86, +0x00010e85, +0x00010e84, +0x00010e83, +0x00010e82, +0x00010e81, +0x00010e80, +0x00010e7f, +0x00010e7e, +0x00010e7c, +0x00010e7b, +0x00010e7a, +0x00010e79, +0x00010e78, +0x00010e77, +0x00010e76, +0x00010e75, +0x00010e74, +0x00010e72, +0x00010e71, +0x00010e70, +0x00010e6f, +0x00010e6e, +0x00010e6d, +0x00010e6c, +0x00010e6b, +0x00010e69, +0x00010e68, +0x00010e67, +0x00010e66, +0x00010e65, +0x00010e64, +0x00010e63, +0x00010e62, +0x00010e61, +0x00010e60, +0x00010e5e, +0x00010e5d, +0x00010e5c, +0x00010e5b, +0x00010e5a, +0x00010e59, +0x00010e58, +0x00010e56, +0x00010e55, +0x00010e54, +0x00010e53, +0x00010e52, +0x00010e51, +0x00010e50, +0x00010e4f, +0x00010e4e, +0x00010e4d, +0x00010e4c, +0x00010e4a, +0x00010e49, +0x00010e48, +0x00010e47, +0x00010e46, +0x00010e45, +0x00010e44, +0x00010e42, +0x00010e41, +0x00010e40, +0x00010e3f, +0x00010e3e, +0x00010e3d, +0x00010e3c, +0x00010e3b, +0x00010e3a, +0x00010e39, +0x00010e38, +0x00010e37, +0x00010e35, +0x00010e34, +0x00010e33, +0x00010e32, +0x00010e31, +0x00010e2f, +0x00010e2e, +0x00010e2d, +0x00010e2c, +0x00010e2b, +0x00010e2a, +0x00010e29, +0x00010e28, +0x00010e27, +0x00010e26, +0x00010e25, +0x00010e24, +0x00010e23, +0x00010e21, +0x00010e20, +0x00010e1f, +0x00010e1e, +0x00010e1c, +0x00010e1b, +0x00010e1a, +0x00010e19, +0x00010e18, +0x00010e17, +0x00010e16, +0x00010e15, +0x00010e14, +0x00010e13, +0x00010e12, +0x00010e11, +0x00010e10, +0x00010e0f, +0x00010e0d, +0x00010e0c, +0x00010e0b, +0x00010e09, +0x00010e08, +0x00010e07, +0x00010e06, +0x00010e05, +0x00010e04, +0x00010e03, +0x00010e02, +0x00010e01, +0x00010e00, +0x00010dff, +0x00010dfe, +0x00010dfd, +0x00010dfc, +0x00010dfb, +0x00010dfa, +0x00010df8, +0x00010df7, +0x00010df5, +0x00010df4, +0x00010df3, +0x00010df2, +0x00010df1, +0x00010df0, +0x00010def, +0x00010dee, +0x00010ded, +0x00010dec, +0x00010deb, +0x00010dea, +0x00010de9, +0x00010de8, +0x00010de7, +0x00010de6, +0x00010de4, +0x00010de2, +0x00010de1, +0x00010de0, +0x00010ddf, +0x00010dde, +0x00010ddd, +0x00010ddc, +0x00010ddb, +0x00010dda, +0x00010dd9, +0x00010dd8, +0x00010dd7, +0x00010dd6, +0x00010dd5, +0x00010dd4, +0x00010dd3, +0x00010dd2, +0x00010dcf, +0x00010dce, +0x00010dcd, +0x00010dcc, +0x00010dcb, +0x00010dca, +0x00010dc9, +0x00010dc8, +0x00010dc7, +0x00010dc6, +0x00010dc5, +0x00010dc4, +0x00010dc3, +0x00010dc2, +0x00010dc1, +0x00010dc0, +0x00010dbf, +0x00010dbe, +0x00010dbb, +0x00010dba, +0x00010db9, +0x00010db8, +0x00010db7, +0x00010db6, +0x00010db5, +0x00010db4, +0x00010db3, +0x00010db2, +0x00010db1, +0x00010db0, +0x00010daf, +0x00010dae, +0x00010dad, +0x00010dac, +0x00010dab, +0x00010daa, +0x00010da8, +0x00010da6, +0x00010da5, +0x00010da4, +0x00010da3, +0x00010da2, +0x00010da1, +0x00010da0, +0x00010d9f, +0x00010d9e, +0x00010d9d, +0x00010d9c, +0x00010d9b, +0x00010d9a, +0x00010d99, +0x00010d98, +0x00010d97, +0x00010d95, +0x00010d94, +0x00010d92, +0x00010d91, +0x00010d90, +0x00010d8f, +0x00010d8e, +0x00010d8d, +0x00010d8c, +0x00010d8b, +0x00010d8a, +0x00010d89, +0x00010d88, +0x00010d87, +0x00010d86, +0x00010d85, +0x00010d84, +0x00010d82, +0x00010d81, +0x00010d80, +0x00010d7e, +0x00010d7d, +0x00010d7c, +0x00010d7b, +0x00010d7a, +0x00010d79, +0x00010d78, +0x00010d77, +0x00010d76, +0x00010d75, +0x00010d74, +0x00010d73, +0x00010d72, +0x00010d71, +0x00010d70, +0x00010d6e, +0x00010d6d, +0x00010d6c, +0x00010d6b, +0x00010d6a, +0x00010d69, +0x00010d68, +0x00010d67, +0x00010d65, +0x00010d64, +0x00010d63, +0x00010d62, +0x00010d61, +0x00010d60, +0x00010d5f, +0x00010d5e, +0x00010d5c, +0x00010d5b, +0x00010d5a, +0x00010d59, +0x00010d58, +0x00010d57, +0x00010d56, +0x00010d55, +0x00010d54, +0x00010d53, +0x00010d52, +0x00010d51, +0x00010d4f, +0x00010d4e, +0x00010d4d, +0x00010d4c, +0x00010d4b, +0x00010d4a, +0x00010d49, +0x00010d47, +0x00010d46, +0x00010d45, +0x00010d44, +0x00010d43, +0x00010d42, +0x00010d41, +0x00010d40, +0x00010d3f, +0x00010d3e, +0x00010d3d, +0x00010d3c, +0x00010d3b, +0x00010d39, +0x00010d38, +0x00010d37, +0x00010d36, +0x00010d35, +0x00010d33, +0x00010d32, +0x00010d31, +0x00010d30, +0x00010d2f, +0x00010d2e, +0x00010d2d, +0x00010d2c, +0x00010d2b, +0x00010d2a, +0x00010d29, +0x00010d28, +0x00010d27, +0x00010d26, +0x00010d25, +0x00010d23, +0x00010d22, +0x00010d21, +0x00010d20, +0x00010d1e, +0x00010d1d, +0x00010d1c, +0x00010d1b, +0x00010d1a, +0x00010d19, +0x00010d18, +0x00010d17, +0x00010d16, +0x00010d15, +0x00010d14, +0x00010d13, +0x00010d12, +0x00010d11, +0x00010d10, +0x00010d0e, +0x00010d0d, +0x00010d0c, +0x00010d0b, +0x00010d09, +0x00010d08, +0x00010d07, +0x00010d06, +0x00010d05, +0x00010d04, +0x00010d03, +0x00010d02, +0x00010d01, +0x00010d00, +0x00010cff, +0x00010cfe, +0x00010cfd, +0x00010cfc, +0x00010cfb, +0x00010cfa, +0x00010cf8, +0x00010cf7, +0x00010cf5, +0x00010cf4, +0x00010cf3, +0x00010cf2, +0x00010cf1, +0x00010cf0, +0x00010cef, +0x00010cee, +0x00010ced, +0x00010cec, +0x00010ceb, +0x00010cea, +0x00010ce9, +0x00010ce8, +0x00010ce7, +0x00010ce6, +0x00010ce5, +0x00010ce4, +0x00010ce2, +0x00010ce0, +0x00010cdf, +0x00010cde, +0x00010cdd, +0x00010cdc, +0x00010cdb, +0x00010cda, +0x00010cd9, +0x00010cd8, +0x00010cd7, +0x00010cd6, +0x00010cd5, +0x00010cd4, +0x00010cd3, +0x00010cd2, +0x00010cd1, +0x00010cd0, +0x00010ccf, +0x00010ccd, +0x00010ccb, +0x00010cca, +0x00010cc9, +0x00010cc8, +0x00010cc7, +0x00010cc6, +0x00010cc5, +0x00010cc4, +0x00010cc3, +0x00010cc2, +0x00010cc1, +0x00010cc0, +0x00010cbf, +0x00010cbe, +0x00010cbd, +0x00010cbc, +0x00010cbb, +0x00010cba, +0x00010cb9, +0x00010cb6, +0x00010cb5, +0x00010cb4, +0x00010cb3, +0x00010cb2, +0x00010cb1, +0x00010cb0, +0x00010caf, +0x00010cae, +0x00010cad, +0x00010cac, +0x00010cab, +0x00010caa, +0x00010ca9, +0x00010ca8, +0x00010ca7, +0x00010ca6, +0x00010ca5, +0x00010ca4, +0x00010ca2, +0x00010ca0, +0x00010c9f, +0x00010c9e, +0x00010c9d, +0x00010c9c, +0x00010c9b, +0x00010c9a, +0x00010c99, +0x00010c98, +0x00010c97, +0x00010c96, +0x00010c95, +0x00010c94, +0x00010c93, +0x00010c92, +0x00010c91, +0x00010c90, +0x00010c8f, +0x00010c8d, +0x00010c8b, +0x00010c8a, +0x00010c89, +0x00010c88, +0x00010c87, +0x00010c86, +0x00010c85, +0x00010c84, +0x00010c83, +0x00010c82, +0x00010c81, +0x00010c80, +0x00010c7f, +0x00010c7e, +0x00010c7d, +0x00010c7c, +0x00010c7b, +0x00010c7a, +0x00010c78, +0x00010c77, +0x00010c75, +0x00010c74, +0x00010c73, +0x00010c72, +0x00010c71, +0x00010c70, +0x00010c6f, +0x00010c6e, +0x00010c6d, +0x00010c6c, +0x00010c6b, +0x00010c6a, +0x00010c69, +0x00010c68, +0x00010c67, +0x00010c66, +0x00010c64, +0x00010c63, +0x00010c62, +0x00010c61, +0x00010c5f, +0x00010c5e, +0x00010c5d, +0x00010c5c, +0x00010c5b, +0x00010c5a, +0x00010c59, +0x00010c58, +0x00010c57, +0x00010c56, +0x00010c55, +0x00010c54, +0x00010c53, +0x00010c52, +0x00010c51, +0x00010c50, +0x00010c4f, +0x00010c4d, +0x00010c4c, +0x00010c4b, +0x00010c4a, +0x00010c49, +0x00010c48, +0x00010c47, +0x00010c46, +0x00010c44, +0x00010c43, +0x00010c42, +0x00010c41, +0x00010c40, +0x00010c3f, +0x00010c3e, +0x00010c3d, +0x00010c3c, +0x00010c3b, +0x00010c3a, +0x00010c39, +0x00010c37, +0x00010c36, +0x00010c35, +0x00010c34, +0x00010c33, +0x00010c32, +0x00010c31, +0x00010c30, +0x00010c2f, +0x00010c2e, +0x00010c2c, +0x00010c2b, +0x00010c2a, +0x00010c29, +0x00010c28, +0x00010c27, +0x00010c26, +0x00010c25, +0x00010c24, +0x00010c23, +0x00010c22, +0x00010c20, +0x00010c1f, +0x00010c1e, +0x00010c1d, +0x00010c1c, +0x00010c1b, +0x00010c1a, +0x00010c19, +0x00010c18, +0x00010c17, +0x00010c15, +0x00010c14, +0x00010c13, +0x00010c12, +0x00010c11, +0x00010c10, +0x00010c0f, +0x00010c0e, +0x00010c0d, +0x00010c0c, +0x00010c0a, +0x00010c09, +0x00010c08, +0x00010c07, +0x00010c06, +0x00010c05, +0x00010c04, +0x00010c03, +0x00010c02, +0x00010c01, +0x00010c00, +0x00010bfe, +0x00010bfd, +0x00010bfc, +0x00010bfb, +0x00010bfa, +0x00010bf9, +0x00010bf8, +0x00010bf7, +0x00010bf6, +0x00010bf4, +0x00010bf3, +0x00010bf2, +0x00010bf1, +0x00010bf0, +0x00010bef, +0x00010bee, +0x00010bed, +0x00010bec, +0x00010beb, +0x00010bea, +0x00010be9, +0x00010be8, +0x00010be6, +0x00010be5, +0x00010be4, +0x00010be3, +0x00010be2, +0x00010be1, +0x00010be0, +0x00010bdf, +0x00010bdd, +0x00010bdc, +0x00010bdb, +0x00010bda, +0x00010bd9, +0x00010bd8, +0x00010bd7, +0x00010bd6, +0x00010bd5, +0x00010bd4, +0x00010bd3, +0x00010bd2, +0x00010bd1, +0x00010bcf, +0x00010bce, +0x00010bcd, +0x00010bcc, +0x00010bcb, +0x00010bca, +0x00010bc9, +0x00010bc7, +0x00010bc6, +0x00010bc5, +0x00010bc4, +0x00010bc3, +0x00010bc2, +0x00010bc1, +0x00010bc0, +0x00010bbf, +0x00010bbd, +0x00010bbc, +0x00010bbb, +0x00010bba, +0x00010bb9, +0x00010bb8, +0x00010bb7, +0x00010bb5, +0x00010bb4, +0x00010bb3, +0x00010bb2, +0x00010bb1, +0x00010bb0, +0x00010baf, +0x00010bae, +0x00010bad, +0x00010bac, +0x00010bab, +0x00010baa, +0x00010ba9, +0x00010ba8, +0x00010ba7, +0x00010ba6, +0x00010ba5, +0x00010ba3, +0x00010ba2, +0x00010ba1, +0x00010ba0, +0x00010b9f, +0x00010b9d, +0x00010b9c, +0x00010b9b, +0x00010b9a, +0x00010b99, +0x00010b98, +0x00010b97, +0x00010b96, +0x00010b95, +0x00010b94, +0x00010b93, +0x00010b92, +0x00010b91, +0x00010b90, +0x00010b8f, +0x00010b8e, +0x00010b8d, +0x00010b8c, +0x00010b8a, +0x00010b89, +0x00010b88, +0x00010b87, +0x00010b86, +0x00010b84, +0x00010b83, +0x00010b82, +0x00010b81, +0x00010b80, +0x00010b7f, +0x00010b7e, +0x00010b7d, +0x00010b7c, +0x00010b7b, +0x00010b7a, +0x00010b79, +0x00010b78, +0x00010b77, +0x00010b76, +0x00010b75, +0x00010b74, +0x00010b73, +0x00010b71, +0x00010b70, +0x00010b6f, +0x00010b6e, +0x00010b6c, +0x00010b6b, +0x00010b6a, +0x00010b69, +0x00010b68, +0x00010b67, +0x00010b66, +0x00010b65, +0x00010b64, +0x00010b63, +0x00010b62, +0x00010b61, +0x00010b60, +0x00010b5f, +0x00010b5e, +0x00010b5d, +0x00010b5c, +0x00010b5b, +0x00010b5a, +0x00010b58, +0x00010b57, +0x00010b56, +0x00010b54, +0x00010b53, +0x00010b52, +0x00010b51, +0x00010b50, +0x00010b4f, +0x00010b4e, +0x00010b4d, +0x00010b4c, +0x00010b4b, +0x00010b4a, +0x00010b49, +0x00010b48, +0x00010b47, +0x00010b46, +0x00010b45, +0x00010b44, +0x00010b43, +0x00010b42, +0x00010b41, +0x00010b40, +0x00010b3e, +0x00010b3c, +0x00010b3b, +0x00010b3a, +0x00010b39, +0x00010b38, +0x00010b37, +0x00010b36, +0x00010b35, +0x00010b34, +0x00010b33, +0x00010b32, +0x00010b31, +0x00010b30, +0x00010b2f, +0x00010b2e, +0x00010b2d, +0x00010b2c, +0x00010b2b, +0x00010b2a, +0x00010b29, +0x00010b28, +0x00010b27, +0x00010b25, +0x00010b23, +0x00010b22, +0x00010b21, +0x00010b20, +0x00010b1f, +0x00010b1e, +0x00010b1d, +0x00010b1c, +0x00010b1b, +0x00010b1a, +0x00010b19, +0x00010b18, +0x00010b17, +0x00010b16, +0x00010b15, +0x00010b14, +0x00010b13, +0x00010b12, +0x00010b11, +0x00010b10, +0x00010b0f, +0x00010b0e, +0x00010b0b, +0x00010b0a, +0x00010b09, +0x00010b08, +0x00010b07, +0x00010b06, +0x00010b05, +0x00010b04, +0x00010b03, +0x00010b02, +0x00010b01, +0x00010b00, +0x00010aff, +0x00010afe, +0x00010afd, +0x00010afc, +0x00010afb, +0x00010afa, +0x00010af9, +0x00010af8, +0x00010af7, +0x00010af6, +0x00010af5, +0x00010af3, +0x00010af1, +0x00010af0, +0x00010aef, +0x00010aee, +0x00010aed, +0x00010aec, +0x00010aeb, +0x00010aea, +0x00010ae9, +0x00010ae8, +0x00010ae7, +0x00010ae6, +0x00010ae5, +0x00010ae4, +0x00010ae3, +0x00010ae2, +0x00010ae1, +0x00010ae0, +0x00010adf, +0x00010ade, +0x00010add, +0x00010adb, +0x00010ada, +0x00010ad8, +0x00010ad7, +0x00010ad6, +0x00010ad5, +0x00010ad4, +0x00010ad3, +0x00010ad2, +0x00010ad1, +0x00010ad0, +0x00010acf, +0x00010ace, +0x00010acd, +0x00010acc, +0x00010acb, +0x00010aca, +0x00010ac9, +0x00010ac8, +0x00010ac7, +0x00010ac6, +0x00010ac5, +0x00010ac4, +0x00010ac2, +0x00010ac1, +0x00010abf, +0x00010abe, +0x00010abd, +0x00010abc, +0x00010abb, +0x00010aba, +0x00010ab9, +0x00010ab8, +0x00010ab7, +0x00010ab6, +0x00010ab5, +0x00010ab4, +0x00010ab3, +0x00010ab2, +0x00010ab1, +0x00010ab0, +0x00010aaf, +0x00010aae, +0x00010aab, +0x00010aaa, +0x00010aa9, +0x00010aa8, +0x00010aa7, +0x00010aa6, +0x00010aa5, +0x00010aa4, +0x00010aa3, +0x00010aa2, +0x00010aa1, +0x00010aa0, +0x00010a9f, +0x00010a9e, +0x00010a9d, +0x00010a9c, +0x00010a9b, +0x00010a9a, +0x00010a99, +0x00010a98, +0x00010a97, +0x00010a96, +0x00010a95, +0x00010a94, +0x00010a93, +0x00010a90, +0x00010a8f, +0x00010a8e, +0x00010a8d, +0x00010a8c, +0x00010a8b, +0x00010a8a, +0x00010a89, +0x00010a88, +0x00010a87, +0x00010a86, +0x00010a85, +0x00010a84, +0x00010a83, +0x00010a82, +0x00010a81, +0x00010a80, +0x00010a7f, +0x00010a7e, +0x00010a7d, +0x00010a7c, +0x00010a7b, +0x00010a7a, +0x00010a79, +0x00010a77, +0x00010a76, +0x00010a74, +0x00010a73, +0x00010a72, +0x00010a71, +0x00010a70, +0x00010a6f, +0x00010a6e, +0x00010a6d, +0x00010a6c, +0x00010a6b, +0x00010a6a, +0x00010a69, +0x00010a68, +0x00010a67, +0x00010a66, +0x00010a65, +0x00010a64, +0x00010a63, +0x00010a62, +0x00010a61, +0x00010a60, +0x00010a5f, +0x00010a5e, +0x00010a5c, +0x00010a5b, +0x00010a59, +0x00010a58, +0x00010a57, +0x00010a56, +0x00010a55, +0x00010a54, +0x00010a53, +0x00010a52, +0x00010a51, +0x00010a50, +0x00010a4f, +0x00010a4e, +0x00010a4d, +0x00010a4c, +0x00010a4b, +0x00010a4a, +0x00010a49, +0x00010a48, +0x00010a47, +0x00010a46, +0x00010a45, +0x00010a44, +0x00010a43, +0x00010a41, +0x00010a40, +0x00010a3f, +0x00010a3d, +0x00010a3c, +0x00010a3b, +0x00010a3a, +0x00010a39, +0x00010a38, +0x00010a37, +0x00010a36, +0x00010a35, +0x00010a34, +0x00010a33, +0x00010a32, +0x00010a31, +0x00010a30, +0x00010a2f, +0x00010a2e, +0x00010a2d, +0x00010a2c, +0x00010a2b, +0x00010a2a, +0x00010a29, +0x00010a27, +0x00010a26, +0x00010a25, +0x00010a24, +0x00010a23, +0x00010a21, +0x00010a20, +0x00010a1f, +0x00010a1e, +0x00010a1d, +0x00010a1c, +0x00010a1b, +0x00010a1a, +0x00010a19, +0x00010a18, +0x00010a17, +0x00010a16, +0x00010a15, +0x00010a14, +0x00010a13, +0x00010a12, +0x00010a11, +0x00010a10, +0x00010a0f, +0x00010a0e, +0x00010a0c, +0x00010a0b, +0x00010a0a, +0x00010a09, +0x00010a08, +0x00010a06, +0x00010a05, +0x00010a04, +0x00010a03, +0x00010a02, +0x00010a01, +0x00010a00, +0x000109ff, +0x000109fe, +0x000109fd, +0x000109fc, +0x000109fb, +0x000109fa, +0x000109f9, +0x000109f8, +0x000109f7, +0x000109f6, +0x000109f5, +0x000109f4, +0x000109f2, +0x000109f1, +0x000109f0, +0x000109ef, +0x000109ee, +0x000109ed, +0x000109ec, +0x000109ea, +0x000109e9, +0x000109e8, +0x000109e7, +0x000109e6, +0x000109e5, +0x000109e4, +0x000109e3, +0x000109e2, +0x000109e1, +0x000109e0, +0x000109df, +0x000109de, +0x000109dd, +0x000109dc, +0x000109db, +0x000109da, +0x000109d9, +0x000109d7, +0x000109d6, +0x000109d5, +0x000109d4, +0x000109d3, +0x000109d2, +0x000109d1, +0x000109cf, +0x000109ce, +0x000109cd, +0x000109cc, +0x000109cb, +0x000109ca, +0x000109c9, +0x000109c8, +0x000109c7, +0x000109c6, +0x000109c5, +0x000109c4, +0x000109c3, +0x000109c2, +0x000109c1, +0x000109c0, +0x000109bf, +0x000109be, +0x000109bc, +0x000109bb, +0x000109ba, +0x000109b9, +0x000109b8, +0x000109b7, +0x000109b6, +0x000109b5, +0x000109b3, +0x000109b2, +0x000109b1, +0x000109b0, +0x000109af, +0x000109ae, +0x000109ad, +0x000109ac, +0x000109ab, +0x000109aa, +0x000109a9, +0x000109a8, +0x000109a7, +0x000109a6, +0x000109a5, +0x000109a4, +0x000109a2, +0x000109a1, +0x000109a0, +0x0001099f, +0x0001099e, +0x0001099d, +0x0001099c, +0x0001099b, +0x0001099a, +0x00010998, +0x00010997, +0x00010996, +0x00010995, +0x00010994, +0x00010993, +0x00010992, +0x00010991, +0x00010990, +0x0001098f, +0x0001098e, +0x0001098d, +0x0001098c, +0x0001098b, +0x0001098a, +0x00010989, +0x00010988, +0x00010987, +0x00010986, +0x00010985, +0x00010983, +0x00010982, +0x00010980, +0x0001097f, +0x0001097e, +0x0001097d, +0x0001097c, +0x0001097b, +0x0001097a, +0x00010979, +0x00010978, +0x00010977, +0x00010976, +0x00010975, +0x00010974, +0x00010973, +0x00010972, +0x00010971, +0x00010970, +0x0001096f, +0x0001096e, +0x0001096d, +0x0001096c, +0x0001096b, +0x0001096a, +0x00010969, +0x00010968, +0x00010966, +0x00010965, +0x00010964, +0x00010962, +0x00010961, +0x00010960, +0x0001095f, +0x0001095e, +0x0001095d, +0x0001095c, +0x0001095b, +0x0001095a, +0x00010959, +0x00010958, +0x00010957, +0x00010956, +0x00010955, +0x00010954, +0x00010953, +0x00010952, +0x00010951, +0x00010950, +0x0001094f, +0x0001094e, +0x0001094d, +0x0001094c, +0x0001094b, +0x00010949, +0x00010948, +0x00010947, +0x00010946, +0x00010945, +0x00010943, +0x00010942, +0x00010941, +0x00010940, +0x0001093f, +0x0001093e, +0x0001093d, +0x0001093c, +0x0001093b, +0x0001093a, +0x00010939, +0x00010938, +0x00010937, +0x00010936, +0x00010935, +0x00010934, +0x00010933, +0x00010932, +0x00010931, +0x00010930, +0x0001092f, +0x0001092e, +0x0001092d, +0x0001092b, +0x0001092a, +0x00010929, +0x00010928, +0x00010927, +0x00010925, +0x00010924, +0x00010923, +0x00010922, +0x00010921, +0x00010920, +0x0001091f, +0x0001091e, +0x0001091d, +0x0001091c, +0x0001091b, +0x0001091a, +0x00010919, +0x00010918, +0x00010917, +0x00010916, +0x00010915, +0x00010914, +0x00010913, +0x00010912, +0x00010911, +0x00010910, +0x0001090e, +0x0001090d, +0x0001090c, +0x0001090b, +0x0001090a, +0x00010909, +0x00010908, +0x00010906, +0x00010905, +0x00010904, +0x00010903, +0x00010902, +0x00010901, +0x00010900, +0x000108ff, +0x000108fe, +0x000108fd, +0x000108fc, +0x000108fb, +0x000108fa, +0x000108f9, +0x000108f8, +0x000108f7, +0x000108f6, +0x000108f5, +0x000108f4, +0x000108f3, +0x000108f2, +0x000108f0, +0x000108ef, +0x000108ee, +0x000108ed, +0x000108ec, +0x000108eb, +0x000108ea, +0x000108e8, +0x000108e7, +0x000108e6, +0x000108e5, +0x000108e4, +0x000108e3, +0x000108e2, +0x000108e1, +0x000108e0, +0x000108df, +0x000108de, +0x000108dd, +0x000108dc, +0x000108db, +0x000108da, +0x000108d9, +0x000108d8, +0x000108d7, +0x000108d6, +0x000108d5, +0x000108d3, +0x000108d2, +0x000108d1, +0x000108d0, +0x000108cf, +0x000108ce, +0x000108cd, +0x000108cc, +0x000108cb, +0x000108c9, +0x000108c8, +0x000108c7, +0x000108c6, +0x000108c5, +0x000108c4, +0x000108c3, +0x000108c2, +0x000108c1, +0x000108c0, +0x000108bf, +0x000108be, +0x000108bd, +0x000108bc, +0x000108bb, +0x000108ba, +0x000108b9, +0x000108b8, +0x000108b7, +0x000108b5, +0x000108b4, +0x000108b3, +0x000108b2, +0x000108b1, +0x000108b0, +0x000108af, +0x000108ae, +0x000108ad, +0x000108ab, +0x000108aa, +0x000108a9, +0x000108a8, +0x000108a7, +0x000108a6, +0x000108a5, +0x000108a4, +0x000108a3, +0x000108a2, +0x000108a1, +0x000108a0, +0x0001089f, +0x0001089e, +0x0001089d, +0x0001089c, +0x0001089b, +0x0001089a, +0x00010898, +0x00010897, +0x00010896, +0x00010895, +0x00010894, +0x00010893, +0x00010892, +0x00010891, +0x00010890, +0x0001088f, +0x0001088d, +0x0001088c, +0x0001088b, +0x0001088a, +0x00010889, +0x00010888, +0x00010887, +0x00010886, +0x00010885, +0x00010884, +0x00010883, +0x00010882, +0x00010881, +0x00010880, +0x0001087f, +0x0001087e, +0x0001087d, +0x0001087c, +0x0001087b, +0x0001087a, +0x00010879, +0x00010878, +0x00010877, +0x00010876, +0x00010874, +0x00010872, +0x00010871, +0x00010870, +0x0001086f, +0x0001086e, +0x0001086d, +0x0001086c, +0x0001086b, +0x0001086a, +0x00010869, +0x00010868, +0x00010867, +0x00010866, +0x00010865, +0x00010864, +0x00010863, +0x00010862, +0x00010861, +0x00010860, +0x0001085f, +0x0001085e, +0x0001085d, +0x0001085c, +0x0001085b, +0x0001085a, +0x00010859, +0x00010858, +0x00010857, +0x00010856, +0x00010855, +0x00010854, +0x00010851, +0x00010850, +0x0001084f, +0x0001084e, +0x0001084d, +0x0001084c, +0x0001084b, +0x0001084a, +0x00010849, +0x00010848, +0x00010847, +0x00010846, +0x00010845, +0x00010844, +0x00010843, +0x00010842, +0x00010841, +0x00010840, +0x0001083f, +0x0001083e, +0x0001083d, +0x0001083c, +0x0001083b, +0x0001083a, +0x00010839, +0x00010838, +0x00010837, +0x00010836, +0x00010835, +0x00010834, +0x00010833, +0x00010832, +0x0001082f, +0x0001082e, +0x0001082d, +0x0001082c, +0x0001082b, +0x0001082a, +0x00010829, +0x00010828, +0x00010827, +0x00010826, +0x00010825, +0x00010824, +0x00010823, +0x00010822, +0x00010821, +0x00010820, +0x0001081f, +0x0001081e, +0x0001081d, +0x0001081c, +0x0001081b, +0x0001081a, +0x00010819, +0x00010818, +0x00010817, +0x00010816, +0x00010815, +0x00010814, +0x00010813, +0x00010812, +0x00010811, +0x0001080f, +0x0001080d, +0x0001080c, +0x0001080b, +0x0001080a, +0x00010809, +0x00010808, +0x00010807, +0x00010806, +0x00010805, +0x00010804, +0x00010803, +0x00010802, +0x00010801, +0x00010800, +0x000107ff, +0x000107fe, +0x000107fd, +0x000107fc, +0x000107fb, +0x000107fa, +0x000107f9, +0x000107f8, +0x000107f7, +0x000107f6, +0x000107f5, +0x000107f4, +0x000107f3, +0x000107f2, +0x000107f1, +0x000107f0, +0x000107ee, +0x000107ed, +0x000107eb, +0x000107ea, +0x000107e9, +0x000107e8, +0x000107e7, +0x000107e6, +0x000107e5, +0x000107e4, +0x000107e3, +0x000107e2, +0x000107e1, +0x000107e0, +0x000107df, +0x000107de, +0x000107dd, +0x000107dc, +0x000107db, +0x000107da, +0x000107d9, +0x000107d8, +0x000107d7, +0x000107d6, +0x000107d5, +0x000107d4, +0x000107d3, +0x000107d2, +0x000107d1, +0x000107d0, +0x000107cf, +0x000107cd, +0x000107cc, +0x000107cb, +0x000107c9, +0x000107c8, +0x000107c7, +0x000107c6, +0x000107c5, +0x000107c4, +0x000107c3, +0x000107c2, +0x000107c1, +0x000107c0, +0x000107bf, +0x000107be, +0x000107bd, +0x000107bc, +0x000107bb, +0x000107ba, +0x000107b9, +0x000107b8, +0x000107b7, +0x000107b6, +0x000107b5, +0x000107b4, +0x000107b3, +0x000107b2, +0x000107b1, +0x000107b0, +0x000107af, +0x000107ae, +0x000107ac, +0x000107ab, +0x000107aa, +0x000107a9, +0x000107a7, +0x000107a6, +0x000107a5, +0x000107a4, +0x000107a3, +0x000107a2, +0x000107a1, +0x000107a0, +0x0001079f, +0x0001079e, +0x0001079d, +0x0001079c, +0x0001079b, +0x0001079a, +0x00010799, +0x00010798, +0x00010797, +0x00010796, +0x00010795, +0x00010794, +0x00010793, +0x00010792, +0x00010791, +0x00010790, +0x0001078f, +0x0001078e, +0x0001078d, +0x0001078b, +0x0001078a, +0x00010789, +0x00010788, +0x00010787, +0x00010785, +0x00010784, +0x00010783, +0x00010782, +0x00010781, +0x00010780, +0x0001077f, +0x0001077e, +0x0001077d, +0x0001077c, +0x0001077b, +0x0001077a, +0x00010779, +0x00010778, +0x00010777, +0x00010776, +0x00010775, +0x00010774, +0x00010773, +0x00010772, +0x00010771, +0x00010770, +0x0001076f, +0x0001076e, +0x0001076d, +0x0001076b, +0x0001076a, +0x00010769, +0x00010768, +0x00010767, +0x00010766, +0x00010765, +0x00010764, +0x00010763, +0x00010762, +0x00010761, +0x00010760, +0x0001075f, +0x0001075d, +0x0001075c, +0x0001075b, +0x0001075a, +0x00010759, +0x00010758, +0x00010757, +0x00010756, +0x00010755, +0x00010754, +0x00010753, +0x00010752, +0x00010751, +0x00010750, +0x0001074f, +0x0001074e, +0x0001074d, +0x0001074c, +0x0001074b, +0x0001074a, +0x00010749, +0x00010748, +0x00010747, +0x00010745, +0x00010744, +0x00010743, +0x00010742, +0x00010741, +0x00010740, +0x0001073f, +0x0001073e, +0x0001073d, +0x0001073c, +0x0001073b, +0x0001073a, +0x00010739, +0x00010737, +0x00010736, +0x00010735, +0x00010734, +0x00010733, +0x00010732, +0x00010731, +0x00010730, +0x0001072f, +0x0001072e, +0x0001072d, +0x0001072c, +0x0001072b, +0x0001072a, +0x00010729, +0x00010728, +0x00010727, +0x00010726, +0x00010725, +0x00010724, +0x00010723, +0x00010722, +0x00010721, +0x00010720, +0x0001071e, +0x0001071d, +0x0001071c, +0x0001071b, +0x0001071a, +0x00010719, +0x00010718, +0x00010717, +0x00010716, +0x00010715, +0x00010714, +0x00010712, +0x00010711, +0x00010710, +0x0001070f, +0x0001070e, +0x0001070d, +0x0001070c, +0x0001070b, +0x0001070a, +0x00010709, +0x00010708, +0x00010707, +0x00010706, +0x00010705, +0x00010704, +0x00010703, +0x00010702, +0x00010701, +0x00010700, +0x000106ff, +0x000106fe, +0x000106fd, +0x000106fc, +0x000106fb, +0x000106fa, +0x000106f8, +0x000106f7, +0x000106f6, +0x000106f5, +0x000106f4, +0x000106f3, +0x000106f2, +0x000106f1, +0x000106f0, +0x000106ef, +0x000106ee, +0x000106ec, +0x000106eb, +0x000106ea, +0x000106e9, +0x000106e8, +0x000106e7, +0x000106e6, +0x000106e5, +0x000106e4, +0x000106e3, +0x000106e2, +0x000106e1, +0x000106e0, +0x000106df, +0x000106de, +0x000106dd, +0x000106dc, +0x000106db, +0x000106da, +0x000106d9, +0x000106d8, +0x000106d7, +0x000106d6, +0x000106d5, +0x000106d4, +0x000106d3, +0x000106d1, +0x000106d0, +0x000106cf, +0x000106ce, +0x000106cd, +0x000106cc, +0x000106cb, +0x000106ca, +0x000106c9, +0x000106c7, +0x000106c6, +0x000106c5, +0x000106c4, +0x000106c3, +0x000106c2, +0x000106c1, +0x000106c0, +0x000106bf, +0x000106be, +0x000106bd, +0x000106bc, +0x000106bb, +0x000106ba, +0x000106b9, +0x000106b8, +0x000106b7, +0x000106b6, +0x000106b5, +0x000106b4, +0x000106b3, +0x000106b2, +0x000106b1, +0x000106b0, +0x000106af, +0x000106ae, +0x000106ad, +0x000106ac, +0x000106aa, +0x000106a9, +0x000106a8, +0x000106a7, +0x000106a6, +0x000106a5, +0x000106a4, +0x000106a3, +0x000106a1, +0x000106a0, +0x0001069f, +0x0001069e, +0x0001069d, +0x0001069c, +0x0001069b, +0x0001069a, +0x00010699, +0x00010698, +0x00010697, +0x00010696, +0x00010695, +0x00010694, +0x00010693, +0x00010692, +0x00010691, +0x00010690, +0x0001068f, +0x0001068e, +0x0001068d, +0x0001068c, +0x0001068b, +0x0001068a, +0x00010689, +0x00010688, +0x00010687, +0x00010686, +0x00010684, +0x00010683, +0x00010682, +0x00010681, +0x00010680, +0x0001067f, +0x0001067e, +0x0001067d, +0x0001067b, +0x0001067a, +0x00010679, +0x00010678, +0x00010677, +0x00010676, +0x00010675, +0x00010674, +0x00010673, +0x00010672, +0x00010671, +0x00010670, +0x0001066f, +0x0001066e, +0x0001066d, +0x0001066c, +0x0001066b, +0x0001066a, +0x00010669, +0x00010668, +0x00010666, +0x00010665, +0x00010664, +0x00010663, +0x00010662, +0x00010661, +0x00010660, +0x0001065f, +0x0001065e, +0x0001065d, +0x0001065c, +0x0001065b, +0x0001065a, +0x00010659, +0x00010658, +0x00010657, +0x00010656, +0x00010655, +0x00010654, +0x00010653, +0x00010652, +0x00010651, +0x00010650, +0x0001064f, +0x0001064e, +0x0001064d, +0x0001064c, +0x0001064b, +0x0001064a, +0x00010649, +0x00010648, +0x00010647, +0x00010646, +0x00010645, +0x00010644, +0x00010643, +0x00010642, +0x00010640, +0x0001063f, +0x0001063e, +0x0001063d, +0x0001063c, +0x0001063a, +0x00010639, +0x00010638, +0x00010637, +0x00010636, +0x00010635, +0x00010634, +0x00010633, +0x00010632, +0x00010631, +0x00010630, +0x0001062f, +0x0001062e, +0x0001062d, +0x0001062c, +0x0001062b, +0x0001062a, +0x00010629, +0x00010628, +0x00010627, +0x00010626, +0x00010625, +0x00010624, +0x00010623, +0x00010622, +0x00010621, +0x00010620, +0x0001061f, +0x0001061e, +0x0001061d, +0x0001061c, +0x0001061b, +0x0001061a, +0x00010619, +0x00010618, +0x00010617, +0x00010615, +0x00010614, +0x00010613, +0x00010612, +0x00010611, +0x00010610, +0x0001060f, +0x0001060d, +0x0001060c, +0x0001060b, +0x0001060a, +0x00010609, +0x00010608, +0x00010607, +0x00010606, +0x00010605, +0x00010604, +0x00010603, +0x00010602, +0x00010601, +0x00010600, +0x000105ff, +0x000105fe, +0x000105fd, +0x000105fc, +0x000105fb, +0x000105fa, +0x000105f9, +0x000105f8, +0x000105f7, +0x000105f6, +0x000105f5, +0x000105f4, +0x000105f3, +0x000105f2, +0x000105f1, +0x000105f0, +0x000105ef, +0x000105ee, +0x000105ed, +0x000105ec, +0x000105eb, +0x000105e9, +0x000105e8, +0x000105e7, +0x000105e6, +0x000105e5, +0x000105e4, +0x000105e3, +0x000105e2, +0x000105e0, +0x000105df, +0x000105de, +0x000105dd, +0x000105dc, +0x000105db, +0x000105da, +0x000105d9, +0x000105d8, +0x000105d7, +0x000105d6, +0x000105d5, +0x000105d4, +0x000105d3, +0x000105d2, +0x000105d1, +0x000105d0, +0x000105cf, +0x000105ce, +0x000105cd, +0x000105cc, +0x000105cb, +0x000105ca, +0x000105c9, +0x000105c8, +0x000105c7, +0x000105c6, +0x000105c5, +0x000105c4, +0x000105c3, +0x000105c2, +0x000105c1, +0x000105c0, +0x000105bf, +0x000105bd, +0x000105bc, +0x000105bb, +0x000105ba, +0x000105b9, +0x000105b8, +0x000105b7, +0x000105b6, +0x000105b4, +0x000105b3, +0x000105b2, +0x000105b1, +0x000105b0, +0x000105af, +0x000105ae, +0x000105ad, +0x000105ac, +0x000105ab, +0x000105aa, +0x000105a9, +0x000105a8, +0x000105a7, +0x000105a6, +0x000105a5, +0x000105a4, +0x000105a3, +0x000105a2, +0x000105a1, +0x000105a0, +0x0001059f, +0x0001059e, +0x0001059d, +0x0001059c, +0x0001059b, +0x0001059a, +0x00010599, +0x00010598, +0x00010597, +0x00010596, +0x00010595, +0x00010594, +0x00010592, +0x00010591, +0x00010590, +0x0001058f, +0x0001058e, +0x0001058d, +0x0001058c, +0x0001058b, +0x0001058a, +0x00010589, +0x00010587, +0x00010586, +0x00010585, +0x00010584, +0x00010583, +0x00010582, +0x00010581, +0x00010580, +0x0001057f, +0x0001057e, +0x0001057d, +0x0001057c, +0x0001057b, +0x0001057a, +0x00010579, +0x00010578, +0x00010577, +0x00010576, +0x00010575, +0x00010574, +0x00010573, +0x00010572, +0x00010571, +0x00010570, +0x0001056f, +0x0001056e, +0x0001056d, +0x0001056c, +0x0001056b, +0x0001056a, +0x00010569, +0x00010568, +0x00010566, +0x00010565, +0x00010564, +0x00010563, +0x00010562, +0x00010561, +0x00010560, +0x0001055f, +0x0001055e, +0x0001055d, +0x0001055c, +0x0001055b, +0x0001055a, +0x00010559, +0x00010558, +0x00010557, +0x00010556, +0x00010555, +0x00010554, +0x00010553, +0x00010552, +0x00010551, +0x00010550, +0x0001054f, +0x0001054d, +0x0001054c, +0x0001054b, +0x0001054a, +0x00010549, +0x00010548, +0x00010547, +0x00010546, +0x00010545, +0x00010544, +0x00010543, +0x00010542, +0x00010541, +0x00010540, +0x0001053f, +0x0001053e, +0x0001053d, +0x0001053c, +0x0001053b, +0x0001053a, +0x00010539, +0x00010538, +0x00010537, +0x00010536, +0x00010535, +0x00010533, +0x00010532, +0x00010531, +0x00010530, +0x0001052f, +0x0001052e, +0x0001052d, +0x0001052c, +0x0001052b, +0x0001052a, +0x00010529, +0x00010528, +0x00010527, +0x00010526, +0x00010525, +0x00010524, +0x00010523, +0x00010522, +0x00010521, +0x00010520, +0x0001051f, +0x0001051e, +0x0001051d, +0x0001051c, +0x0001051b, +0x00010519, +0x00010518, +0x00010517, +0x00010516, +0x00010515, +0x00010514, +0x00010513, +0x00010512, +0x00010511, +0x00010510, +0x0001050f, +0x0001050e, +0x0001050d, +0x0001050c, +0x0001050b, +0x0001050a, +0x00010509, +0x00010508, +0x00010507, +0x00010506, +0x00010505, +0x00010504, +0x00010503, +0x00010502, +0x00010501, +0x00010500, +0x000104fe, +0x000104fd, +0x000104fc, +0x000104fb, +0x000104fa, +0x000104f9, +0x000104f8, +0x000104f7, +0x000104f6, +0x000104f5, +0x000104f4, +0x000104f3, +0x000104f2, +0x000104f1, +0x000104f0, +0x000104ef, +0x000104ee, +0x000104ed, +0x000104ec, +0x000104eb, +0x000104ea, +0x000104e9, +0x000104e8, +0x000104e7, +0x000104e5, +0x000104e4, +0x000104e3, +0x000104e2, +0x000104e1, +0x000104e0, +0x000104df, +0x000104de, +0x000104dd, +0x000104dc, +0x000104db, +0x000104da, +0x000104d9, +0x000104d8, +0x000104d7, +0x000104d6, +0x000104d5, +0x000104d4, +0x000104d3, +0x000104d2, +0x000104d1, +0x000104d0, +0x000104cf, +0x000104ce, +0x000104cd, +0x000104cc, +0x000104cb, +0x000104c9, +0x000104c8, +0x000104c7, +0x000104c6, +0x000104c5, +0x000104c4, +0x000104c3, +0x000104c2, +0x000104c1, +0x000104c0, +0x000104bf, +0x000104be, +0x000104bd, +0x000104bc, +0x000104bb, +0x000104ba, +0x000104b9, +0x000104b8, +0x000104b7, +0x000104b6, +0x000104b5, +0x000104b4, +0x000104b3, +0x000104b1, +0x000104b0, +0x000104af, +0x000104ae, +0x000104ad, +0x000104ac, +0x000104ab, +0x000104aa, +0x000104a9, +0x000104a8, +0x000104a7, +0x000104a6, +0x000104a5, +0x000104a4, +0x000104a3, +0x000104a2, +0x000104a1, +0x000104a0, +0x0001049f, +0x0001049e, +0x0001049d, +0x0001049c, +0x0001049b, +0x0001049a, +0x00010499, +0x00010498, +0x00010497, +0x00010496, +0x00010495, +0x00010493, +0x00010492, +0x00010491, +0x00010490, +0x0001048f, +0x0001048e, +0x0001048d, +0x0001048c, +0x0001048b, +0x0001048a, +0x00010489, +0x00010488, +0x00010487, +0x00010486, +0x00010485, +0x00010484, +0x00010483, +0x00010482, +0x00010481, +0x00010480, +0x0001047f, +0x0001047e, +0x0001047c, +0x0001047b, +0x0001047a, +0x00010479, +0x00010478, +0x00010477, +0x00010476, +0x00010475, +0x00010474, +0x00010473, +0x00010472, +0x00010471, +0x00010470, +0x0001046f, +0x0001046e, +0x0001046d, +0x0001046c, +0x0001046b, +0x0001046a, +0x00010469, +0x00010468, +0x00010467, +0x00010466, +0x00010465, +0x00010464, +0x00010463, +0x00010462, +0x00010461, +0x00010460, +0x0001045e, +0x0001045d, +0x0001045c, +0x0001045b, +0x0001045a, +0x00010459, +0x00010458, +0x00010457, +0x00010456, +0x00010455, +0x00010454, +0x00010453, +0x00010452, +0x00010451, +0x00010450, +0x0001044f, +0x0001044e, +0x0001044d, +0x0001044c, +0x0001044b, +0x0001044a, +0x00010449, +0x00010448, +0x00010447, +0x00010446, +0x00010445, +0x00010444, +0x00010443, +0x00010442, +0x00010441, +0x00010440, +0x0001043f, +0x0001043e, +0x0001043d, +0x0001043c, +0x0001043b, +0x0001043a, +0x00010439, +0x00010438, +0x00010437, +0x00010436, +0x00010435, +0x00010434, +0x00010433, +0x00010432, +0x00010430, +0x0001042f, +0x0001042e, +0x0001042d, +0x0001042c, +0x0001042b, +0x0001042a, +0x00010429, +0x00010428, +0x00010427, +0x00010426, +0x00010425, +0x00010424, +0x00010423, +0x00010422, +0x00010421, +0x0001041f, +0x0001041e, +0x0001041d, +0x0001041c, +0x0001041b, +0x0001041a, +0x00010419, +0x00010418, +0x00010417, +0x00010416, +0x00010415, +0x00010414, +0x00010413, +0x00010412, +0x00010411, +0x00010410, +0x0001040f, +0x0001040e, +0x0001040d, +0x0001040c, +0x0001040b, +0x0001040a, +0x00010409, +0x00010408, +0x00010407, +0x00010406, +0x00010405, +0x00010404, +0x00010403, +0x00010402, +0x00010401, +0x00010400, +0x000103ff, +0x000103fe, +0x000103fd, +0x000103fc, +0x000103fb, +0x000103fa, +0x000103f9, +0x000103f8, +0x000103f7, +0x000103f6, +0x000103f5, +0x000103f4, +0x000103f3, +0x000103f2, +0x000103f1, +0x000103f0, +0x000103ee, +0x000103ed, +0x000103ec, +0x000103eb, +0x000103ea, +0x000103e9, +0x000103e8, +0x000103e7, +0x000103e6, +0x000103e5, +0x000103e4, +0x000103e3, +0x000103e2, +0x000103e1, +0x000103e0, +0x000103de, +0x000103dd, +0x000103dc, +0x000103db, +0x000103da, +0x000103d9, +0x000103d8, +0x000103d7, +0x000103d6, +0x000103d5, +0x000103d4, +0x000103d3, +0x000103d2, +0x000103d1, +0x000103d0, +0x000103cf, +0x000103ce, +0x000103cd, +0x000103cc, +0x000103cb, +0x000103ca, +0x000103c9, +0x000103c8, +0x000103c7, +0x000103c6, +0x000103c5, +0x000103c4, +0x000103c3, +0x000103c2, +0x000103c1, +0x000103c0, +0x000103bf, +0x000103be, +0x000103bd, +0x000103bc, +0x000103bb, +0x000103ba, +0x000103b9, +0x000103b8, +0x000103b7, +0x000103b6, +0x000103b5, +0x000103b4, +0x000103b3, +0x000103b2, +0x000103b1, +0x000103b0, +0x000103af, +0x000103ae, +0x000103ac, +0x000103ab, +0x000103aa, +0x000103a9, +0x000103a8, +0x000103a7, +0x000103a6, +0x000103a5, +0x000103a4, +0x000103a3, +0x000103a2, +0x000103a1, +0x000103a0, +0x0001039f, +0x0001039d, +0x0001039c, +0x0001039b, +0x0001039a, +0x00010399, +0x00010398, +0x00010397, +0x00010396, +0x00010395, +0x00010394, +0x00010393, +0x00010392, +0x00010391, +0x00010390, +0x0001038f, +0x0001038e, +0x0001038d, +0x0001038c, +0x0001038b, +0x0001038a, +0x00010389, +0x00010388, +0x00010387, +0x00010386, +0x00010385, +0x00010384, +0x00010383, +0x00010382, +0x00010381, +0x00010380, +0x0001037f, +0x0001037e, +0x0001037d, +0x0001037c, +0x0001037b, +0x0001037a, +0x00010379, +0x00010378, +0x00010377, +0x00010376, +0x00010375, +0x00010374, +0x00010373, +0x00010372, +0x00010371, +0x00010370, +0x0001036f, +0x0001036e, +0x0001036d, +0x0001036c, +0x0001036a, +0x00010369, +0x00010368, +0x00010367, +0x00010366, +0x00010365, +0x00010364, +0x00010363, +0x00010362, +0x00010361, +0x00010360, +0x0001035f, +0x0001035e, +0x0001035c, +0x0001035b, +0x0001035a, +0x00010359, +0x00010358, +0x00010357, +0x00010356, +0x00010355, +0x00010354, +0x00010353, +0x00010352, +0x00010351, +0x00010350, +0x0001034f, +0x0001034e, +0x0001034d, +0x0001034c, +0x0001034b, +0x0001034b, +0x0001034a, +0x00010349, +0x00010348, +0x00010347, +0x00010346, +0x00010345, +0x00010344, +0x00010343, +0x00010342, +0x00010341, +0x00010340, +0x0001033f, +0x0001033e, +0x0001033d, +0x0001033c, +0x0001033b, +0x0001033a, +0x00010339, +0x00010338, +0x00010337, +0x00010336, +0x00010334, +0x00010333, +0x00010332, +0x00010331, +0x00010330, +0x0001032f, +0x0001032e, +0x0001032d, +0x0001032c, +0x0001032a, +0x00010329, +0x00010328, +0x00010327, +0x00010326, +0x00010325, +0x00010324, +0x00010323, +0x00010322, +0x00010321, +0x00010320, +0x0001031f, +0x0001031e, +0x0001031d, +0x0001031c, +0x0001031b, +0x0001031a, +0x00010319, +0x00010318, +0x00010317, +0x00010316, +0x00010315, +0x00010314, +0x00010313, +0x00010312, +0x00010311, +0x00010310, +0x0001030f, +0x0001030e, +0x0001030d, +0x0001030c, +0x0001030b, +0x0001030a, +0x00010309, +0x00010308, +0x00010307, +0x00010306, +0x00010305, +0x00010304, +0x00010303, +0x00010302, +0x00010301, +0x00010300, +0x000102ff, +0x000102fe, +0x000102fd, +0x000102fc, +0x000102fb, +0x000102fa, +0x000102f9, +0x000102f8, +0x000102f7, +0x000102f6, +0x000102f5, +0x000102f4, +0x000102f3, +0x000102f2, +0x000102f1, +0x000102f0, +0x000102ef, +0x000102ee, +0x000102ed, +0x000102ec, +0x000102eb, +0x000102ea, +0x000102e9, +0x000102e8, +0x000102e7, +0x000102e6, +0x000102e5, +0x000102e4, +0x000102e3, +0x000102e2, +0x000102e1, +0x000102e0, +0x000102df, +0x000102dd, +0x000102dc, +0x000102db, +0x000102da, +0x000102d9, +0x000102d8, +0x000102d7, +0x000102d6, +0x000102d4, +0x000102d3, +0x000102d2, +0x000102d1, +0x000102d0, +0x000102cf, +0x000102ce, +0x000102cd, +0x000102cc, +0x000102cb, +0x000102ca, +0x000102c9, +0x000102c8, +0x000102c7, +0x000102c6, +0x000102c5, +0x000102c4, +0x000102c3, +0x000102c2, +0x000102c1, +0x000102c0, +0x000102bf, +0x000102be, +0x000102bd, +0x000102bc, +0x000102bb, +0x000102ba, +0x000102b9, +0x000102b8, +0x000102b7, +0x000102b6, +0x000102b5, +0x000102b4, +0x000102b3, +0x000102b2, +0x000102b1, +0x000102b0, +0x000102af, +0x000102ae, +0x000102ad, +0x000102ac, +0x000102ab, +0x000102aa, +0x000102a9, +0x000102a8, +0x000102a7, +0x000102a6, +0x000102a5, +0x000102a4, +0x000102a3, +0x000102a2, +0x000102a1, +0x000102a0, +0x0001029f, +0x0001029e, +0x0001029d, +0x0001029c, +0x0001029b, +0x0001029a, +0x00010299, +0x00010298, +0x00010297, +0x00010296, +0x00010295, +0x00010294, +0x00010293, +0x00010292, +0x00010291, +0x00010290, +0x0001028f, +0x0001028e, +0x0001028d, +0x0001028c, +0x0001028b, +0x0001028a, +0x00010289, +0x00010288, +0x00010287, +0x00010285, +0x00010284, +0x00010283, +0x00010282, +0x00010281, +0x00010280, +0x0001027f, +0x0001027d, +0x0001027c, +0x0001027b, +0x0001027a, +0x00010279, +0x00010278, +0x00010277, +0x00010276, +0x00010275, +0x00010274, +0x00010273, +0x00010272, +0x00010271, +0x00010270, +0x0001026f, +0x0001026e, +0x0001026d, +0x0001026c, +0x0001026b, +0x0001026a, +0x00010269, +0x00010268, +0x00010267, +0x00010266, +0x00010265, +0x00010264, +0x00010263, +0x00010262, +0x00010261, +0x00010260, +0x0001025f, +0x0001025e, +0x0001025d, +0x0001025c, +0x0001025b, +0x0001025a, +0x00010259, +0x00010258, +0x00010257, +0x00010256, +0x00010255, +0x00010254, +0x00010253, +0x00010252, +0x00010251, +0x00010250, +0x0001024f, +0x0001024e, +0x0001024d, +0x0001024c, +0x0001024b, +0x0001024a, +0x00010249, +0x00010248, +0x00010247, +0x00010246, +0x00010246, +0x00010244, +0x00010243, +0x00010242, +0x00010241, +0x0001023f, +0x0001023e, +0x0001023d, +0x0001023c, +0x0001023b, +0x0001023a, +0x00010239, +0x00010238, +0x00010237, +0x00010236, +0x00010235, +0x00010234, +0x00010233, +0x00010232, +0x00010231, +0x00010230, +0x0001022f, +0x0001022e, +0x0001022d, +0x0001022c, +0x0001022b, +0x0001022a, +0x00010229, +0x00010228, +0x00010227, +0x00010226, +0x00010225, +0x00010224, +0x00010223, +0x00010222, +0x00010221, +0x00010220, +0x0001021f, +0x0001021e, +0x0001021d, +0x0001021c, +0x0001021b, +0x0001021a, +0x00010219, +0x00010218, +0x00010217, +0x00010216, +0x00010215, +0x00010214, +0x00010213, +0x00010212, +0x00010211, +0x00010210, +0x0001020f, +0x0001020e, +0x0001020d, +0x0001020c, +0x0001020b, +0x0001020a, +0x00010209, +0x00010208, +0x00010207, +0x00010206, +0x00010205, +0x00010204, +0x00010203, +0x00010202, +0x00010201, +0x00010200, +0x000101ff, +0x000101fe, +0x000101fd, +0x000101fc, +0x000101fb, +0x000101fa, +0x000101f9, +0x000101f8, +0x000101f7, +0x000101f6, +0x000101f5, +0x000101f4, +0x000101f3, +0x000101f2, +0x000101f1, +0x000101f0, +0x000101ef, +0x000101ee, +0x000101ed, +0x000101ec, +0x000101eb, +0x000101ea, +0x000101e9, +0x000101e8, +0x000101e7, +0x000101e6, +0x000101e5, +0x000101e4, +0x000101e3, +0x000101e2, +0x000101e1, +0x000101e0, +0x000101df, +0x000101de, +0x000101dd, +0x000101dc, +0x000101db, +0x000101da, +0x000101d9, +0x000101d8, +0x000101d7, +0x000101d6, +0x000101d5, +0x000101d4, +0x000101d3, +0x000101d2, +0x000101d1, +0x000101d0, +0x000101cf, +0x000101ce, +0x000101cd, +0x000101cc, +0x000101cb, +0x000101ca, +0x000101c9, +0x000101c8, +0x000101c7, +0x000101c6, +0x000101c5, +0x000101c4, +0x000101c2, +0x000101c1, +0x000101c0, +0x000101be, +0x000101bd, +0x000101bc, +0x000101bb, +0x000101ba, +0x000101b9, +0x000101b8, +0x000101b7, +0x000101b6, +0x000101b5, +0x000101b4, +0x000101b3, +0x000101b2, +0x000101b1, +0x000101b0, +0x000101af, +0x000101ae, +0x000101ad, +0x000101ac, +0x000101ab, +0x000101aa, +0x000101a9, +0x000101a8, +0x000101a7, +0x000101a6, +0x000101a5, +0x000101a4, +0x000101a3, +0x000101a2, +0x000101a1, +0x000101a0, +0x0001019f, +0x0001019e, +0x0001019d, +0x0001019c, +0x0001019b, +0x0001019a, +0x00010199, +0x00010198, +0x00010197, +0x00010196, +0x00010195, +0x00010194, +0x00010193, +0x00010192, +0x00010191, +0x00010190, +0x0001018f, +0x0001018e, +0x0001018d, +0x0001018c, +0x0001018b, +0x0001018a, +0x00010189, +0x00010188, +0x00010187, +0x00010186, +0x00010185, +0x00010184, +0x00010183, +0x00010182, +0x00010181, +0x00010180, +0x0001017f, +0x0001017e, +0x0001017d, +0x0001017c, +0x0001017b, +0x0001017a, +0x00010179, +0x00010178, +0x00010177, +0x00010176, +0x00010175, +0x00010174, +0x00010173, +0x00010172, +0x00010171, +0x00010170, +0x0001016f, +0x0001016e, +0x0001016d, +0x0001016c, +0x0001016b, +0x0001016a, +0x00010169, +0x00010168, +0x00010167, +0x00010166, +0x00010165, +0x00010164, +0x00010163, +0x00010162, +0x00010161, +0x00010160, +0x0001015f, +0x0001015e, +0x0001015d, +0x0001015c, +0x0001015b, +0x0001015a, +0x00010159, +0x00010158, +0x00010157, +0x00010156, +0x00010155, +0x00010154, +0x00010153, +0x00010152, +0x00010151, +0x00010150, +0x0001014f, +0x0001014e, +0x0001014d, +0x0001014c, +0x0001014b, +0x0001014a, +0x00010149, +0x00010148, +0x00010147, +0x00010146, +0x00010145, +0x00010144, +0x00010143, +0x00010141, +0x00010140, +0x0001013f, +0x0001013e, +0x0001013d, +0x0001013c, +0x0001013b, +0x0001013a, +0x00010139, +0x00010138, +0x00010137, +0x00010136, +0x00010135, +0x00010134, +0x00010133, +0x00010132, +0x00010131, +0x00010130, +0x0001012f, +0x0001012e, +0x0001012d, +0x0001012c, +0x0001012b, +0x0001012a, +0x00010129, +0x00010128, +0x00010127, +0x00010126, +0x00010125, +0x00010124, +0x00010123, +0x00010122, +0x00010121, +0x00010120, +0x0001011f, +0x0001011e, +0x0001011d, +0x0001011c, +0x0001011b, +0x0001011a, +0x00010119, +0x00010118, +0x00010117, +0x00010116, +0x00010115, +0x00010114, +0x00010113, +0x00010112, +0x00010111, +0x00010110, +0x0001010f, +0x0001010e, +0x0001010d, +0x0001010c, +0x0001010b, +0x0001010a, +0x00010109, +0x00010108, +0x00010107, +0x00010106, +0x00010105, +0x00010104, +0x00010103, +0x00010102, +0x00010101, +0x00010100, +0x000100ff, +0x000100fe, +0x000100fd, +0x000100fc, +0x000100fb, +0x000100fa, +0x000100f9, +0x000100f8, +0x000100f7, +0x000100f6, +0x000100f5, +0x000100f4, +0x000100f3, +0x000100f2, +0x000100f1, +0x000100f0, +0x000100ef, +0x000100ee, +0x000100ed, +0x000100ec, +0x000100eb, +0x000100ea, +0x000100e9, +0x000100e8, +0x000100e7, +0x000100e6, +0x000100e5, +0x000100e4, +0x000100e3, +0x000100e2, +0x000100e1, +0x000100e0, +0x000100df, +0x000100de, +0x000100dd, +0x000100dc, +0x000100db, +0x000100da, +0x000100d9, +0x000100d8, +0x000100d7, +0x000100d6, +0x000100d5, +0x000100d4, +0x000100d3, +0x000100d2, +0x000100d1, +0x000100d0, +0x000100cf, +0x000100ce, +0x000100cd, +0x000100cc, +0x000100cb, +0x000100ca, +0x000100c9, +0x000100c8, +0x000100c7, +0x000100c6, +0x000100c5, +0x000100c4, +0x000100c3, +0x000100c2, +0x000100c1, +0x000100c0, +0x000100bf, +0x000100be, +0x000100bd, +0x000100bc, +0x000100bb, +0x000100ba, +0x000100b9, +0x000100b8, +0x000100b7, +0x000100b6, +0x000100b5, +0x000100b4, +0x000100b3, +0x000100b2, +0x000100b1, +0x000100b0, +0x000100af, +0x000100ae, +0x000100ad, +0x000100ac, +0x000100ab, +0x000100aa, +0x000100a9, +0x000100a8, +0x000100a7, +0x000100a6, +0x000100a5, +0x000100a4, +0x000100a3, +0x000100a2, +0x000100a1, +0x000100a0, +0x0001009f, +0x0001009e, +0x0001009d, +0x0001009c, +0x0001009b, +0x0001009a, +0x00010099, +0x00010098, +0x00010097, +0x00010096, +0x00010095, +0x00010094, +0x00010093, +0x00010092, +0x00010091, +0x00010090, +0x0001008f, +0x0001008e, +0x0001008d, +0x0001008c, +0x0001008b, +0x0001008a, +0x00010089, +0x00010088, +0x00010087, +0x00010086, +0x00010085, +0x00010084, +0x00010083, +0x00010082, +0x00010081, +0x0001007e, +0x0001007d, +0x0001007c, +0x0001007b, +0x0001007a, +0x00010079, +0x00010078, +0x00010077, +0x00010076, +0x00010075, +0x00010074, +0x00010073, +0x00010072, +0x00010071, +0x00010070, +0x0001006f, +0x0001006e, +0x0001006d, +0x0001006c, +0x0001006b, +0x0001006a, +0x00010069, +0x00010068, +0x00010067, +0x00010066, +0x00010065, +0x00010064, +0x00010063, +0x00010062, +0x00010061, +0x00010060, +0x0001005f, +0x0001005e, +0x0001005d, +0x0001005c, +0x0001005b, +0x0001005a, +0x00010059, +0x00010058, +0x00010057, +0x00010056, +0x00010055, +0x00010054, +0x00010053, +0x00010052, +0x00010051, +0x00010050, +0x0001004f, +0x0001004e, +0x0001004d, +0x0001004c, +0x0001004b, +0x0001004a, +0x00010049, +0x00010048, +0x00010047, +0x00010046, +0x00010045, +0x00010044, +0x00010043, +0x00010042, +0x00010041, +0x00010040, +0x0001003f, +0x0001003e, +0x0001003d, +0x0001003c, +0x0001003b, +0x0001003a, +0x00010039, +0x00010038, +0x00010037, +0x00010036, +0x00010035, +0x00010034, +0x00010033, +0x00010032, +0x00010031, +0x00010030, +0x0001002f, +0x0001002e, +0x0001002d, +0x0001002c, +0x0001002b, +0x0001002a, +0x00010029, +0x00010028, +0x00010027, +0x00010026, +0x00010025, +0x00010024, +0x00010023, +0x00010022, +0x00010021, +0x00010020, +0x0001001f, +0x0001001e, +0x0001001d, +0x0001001c, +0x0001001b, +0x0001001a, +0x00010019, +0x00010018, +0x00010017, +0x00010016, +0x00010015, +0x00010014, +0x00010013, +0x00010012, +0x00010011, +0x00010010, +0x0001000f, +0x0001000e, +0x0001000d, +0x0001000c, +0x0001000b, +0x0001000a, +0x00010009, +0x00010008, +0x00010007, +0x00010006, +0x00010005, +0x00010004, +0x00010003, +0x00010002, +0x00010001, +0x00010000, diff --git a/mednafen/psx-0925/input/dualanalog.cpp b/mednafen/psx-0925/input/dualanalog.cpp new file mode 100644 index 00000000..c4448b81 --- /dev/null +++ b/mednafen/psx-0925/input/dualanalog.cpp @@ -0,0 +1,285 @@ +#include "../psx.h" +#include "../frontio.h" +#include "dualanalog.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_DualAnalog : public InputDevice +{ + public: + + InputDevice_DualAnalog(bool joystick_mode_); + virtual ~InputDevice_DualAnalog(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + bool joystick_mode; + bool dtr; + + uint8 buttons[2]; + uint8 axes[2][2]; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[8]; + uint32 transmit_pos; + uint32 transmit_count; +}; + +InputDevice_DualAnalog::InputDevice_DualAnalog(bool joystick_mode_) : joystick_mode(joystick_mode_) +{ + Power(); +} + +InputDevice_DualAnalog::~InputDevice_DualAnalog() +{ + +} + +void InputDevice_DualAnalog::Power(void) +{ + dtr = 0; + + buttons[0] = buttons[1] = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; +} + +void InputDevice_DualAnalog::UpdateInput(const void *data) +{ + uint8 *d8 = (uint8 *)data; + + buttons[0] = d8[0]; + buttons[1] = d8[1]; + + for(int stick = 0; stick < 2; stick++) + { + for(int axis = 0; axis < 2; axis++) + { + int32 tmp; + + tmp = 32768 + MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 4) - ((int32)MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 8) * 32768 / 32767); + tmp >>= 8; + + axes[stick][axis] = tmp; + } + } + + //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]); + +} + + +void InputDevice_DualAnalog::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + dtr = new_dtr; +} + +bool InputDevice_DualAnalog::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_DualAnalog::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //printf("[PAD] Receive: %02x -- command_phase=%d\n", receive_buffer, command_phase); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + transmit_buffer[0] = joystick_mode ? 0x53 : 0x73; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + //if(command != 0x42) + // fprintf(stderr, "Gamepad unhandled command: 0x%02x\n", command); + + if(command == 0x42) + { + transmit_buffer[1] = 0xFF ^ buttons[0]; + transmit_buffer[2] = 0xFF ^ buttons[1]; + transmit_buffer[3] = axes[0][0]; + transmit_buffer[4] = axes[0][1]; + transmit_buffer[5] = axes[1][0]; + transmit_buffer[6] = axes[1][1]; + transmit_pos = 0; + transmit_count = 7; + } + else + { + command_phase = -1; + transmit_buffer[1] = 0; + transmit_buffer[2] = 0; + transmit_pos = 0; + transmit_count = 0; + } + break; + case 2: + //if(receive_buffer) + // printf("%d: %02x\n", 7 - transmit_count, receive_buffer); + break; + } + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 0x40; //0x100; + + return(ret); +} + +InputDevice *Device_DualAnalog_Create(bool joystick_mode) +{ + return new InputDevice_DualAnalog(joystick_mode); +} + + +InputDeviceInputInfoStruct Device_DualAnalog_IDII[24] = +{ + { "select", "SELECT", 4, IDIT_BUTTON, NULL }, + { "l3", "Left Stick, Button(L3)", 18, IDIT_BUTTON, NULL }, + { "r3", "Right stick, Button(R3)", 23, IDIT_BUTTON, NULL }, + { "start", "START", 5, IDIT_BUTTON, NULL }, + { "up", "D-Pad UP ↑", 0, IDIT_BUTTON, "down" }, + { "right", "D-Pad RIGHT →", 3, IDIT_BUTTON, "left" }, + { "down", "D-Pad DOWN ↓", 1, IDIT_BUTTON, "up" }, + { "left", "D-Pad LEFT â†", 2, IDIT_BUTTON, "right" }, + + { "l2", "L2 (rear left shoulder)", 11, IDIT_BUTTON, NULL }, + { "r2", "R2 (rear right shoulder)", 13, IDIT_BUTTON, NULL }, + { "l1", "L1 (front left shoulder)", 10, IDIT_BUTTON, NULL }, + { "r1", "R1 (front right shoulder)", 12, IDIT_BUTTON, NULL }, + + { "triangle", "â–³ (upper)", 6, IDIT_BUTTON_CAN_RAPID, NULL }, + { "circle", "â—‹ (right)", 9, IDIT_BUTTON_CAN_RAPID, NULL }, + { "cross", "x (lower)", 7, IDIT_BUTTON_CAN_RAPID, NULL }, + { "square", "â–¡ (left)", 8, IDIT_BUTTON_CAN_RAPID, NULL }, + + { "rstick_right", "Right Stick RIGHT →", 22, IDIT_BUTTON_ANALOG }, + { "rstick_left", "Right Stick LEFT â†", 21, IDIT_BUTTON_ANALOG }, + { "rstick_down", "Right Stick DOWN ↓", 20, IDIT_BUTTON_ANALOG }, + { "rstick_up", "Right Stick UP ↑", 19, IDIT_BUTTON_ANALOG }, + + { "lstick_right", "Left Stick RIGHT →", 17, IDIT_BUTTON_ANALOG }, + { "lstick_left", "Left Stick LEFT â†", 16, IDIT_BUTTON_ANALOG }, + { "lstick_down", "Left Stick DOWN ↓", 15, IDIT_BUTTON_ANALOG }, + { "lstick_up", "Left Stick UP ↑", 14, IDIT_BUTTON_ANALOG }, + +}; + +// Not sure if all these buttons are named correctly! +InputDeviceInputInfoStruct Device_AnalogJoy_IDII[24] = +{ + { "select", "SELECT", 8, IDIT_BUTTON, NULL }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { "start", "START", 9, IDIT_BUTTON, NULL }, + { "up", "Thumbstick UP ↑", 14, IDIT_BUTTON, "down" }, + { "right", "Thumbstick RIGHT →", 17, IDIT_BUTTON, "left" }, + { "down", "Thumbstick DOWN ↓", 15, IDIT_BUTTON, "up" }, + { "left", "Thumbstick LEFT â†", 16, IDIT_BUTTON, "right" }, + + { "l2", "Left stick, Trigger", 2, IDIT_BUTTON, NULL }, + { "r2", "Left stick, Pinky", 3, IDIT_BUTTON, NULL }, + { "l1", "Left stick, L-thumb", 0, IDIT_BUTTON, NULL }, + { "r1", "Left stick, R-thumb", 1, IDIT_BUTTON, NULL }, + + { "triangle", "Right stick, Pinky", 13, IDIT_BUTTON, NULL }, + { "circle", "Right stick, R-thumb", 11, IDIT_BUTTON, NULL }, + { "cross", "Right stick, L-thumb", 10, IDIT_BUTTON, NULL }, + { "square", "Right stick, Trigger", 12, IDIT_BUTTON, NULL }, + + { "rstick_right", "Right Stick, RIGHT →", 21, IDIT_BUTTON_ANALOG }, + { "rstick_left", "Right Stick, LEFT â†", 20, IDIT_BUTTON_ANALOG }, + { "rstick_down", "Right Stick, BACK ↓", 19, IDIT_BUTTON_ANALOG }, + { "rstick_up", "Right Stick, FORE ↑", 18, IDIT_BUTTON_ANALOG }, + + { "lstick_right", "Left Stick, RIGHT →", 7, IDIT_BUTTON_ANALOG }, + { "lstick_left", "Left Stick, LEFT â†", 6, IDIT_BUTTON_ANALOG }, + { "lstick_down", "Left Stick, BACK ↓", 5, IDIT_BUTTON_ANALOG }, + { "lstick_up", "Left Stick, FORE ↑", 4, IDIT_BUTTON_ANALOG }, + +}; + + +} diff --git a/mednafen/psx-0925/input/dualanalog.h b/mednafen/psx-0925/input/dualanalog.h new file mode 100644 index 00000000..71bd6e7d --- /dev/null +++ b/mednafen/psx-0925/input/dualanalog.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_DUALANALOG_H +#define __MDFN_PSX_INPUT_DUALANALOG_H + +namespace MDFN_IEN_PSX +{ + +InputDevice *Device_DualAnalog_Create(bool joystick_mode); +extern InputDeviceInputInfoStruct Device_DualAnalog_IDII[24]; +extern InputDeviceInputInfoStruct Device_AnalogJoy_IDII[24]; +} +#endif diff --git a/mednafen/psx-0925/input/dualshock.cpp b/mednafen/psx-0925/input/dualshock.cpp new file mode 100644 index 00000000..6f4ff2fc --- /dev/null +++ b/mednafen/psx-0925/input/dualshock.cpp @@ -0,0 +1,1025 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "../psx.h" +#include "../frontio.h" +#include "dualshock.h" + +/* + TODO: + If we ever call Update() more than once per video frame(IE 50/60Hz), we'll need to add debounce logic to the analog mode button evaluation code. +*/ + +/* Notes: + + Both DA and DS style rumblings work in both analog and digital modes. + + Regarding getting Dual Shock style rumble working, Sony is evil and/or mean. The owl tells me to burn Sony with boiling oil. + + To enable Dual Shock-style rumble, the game has to at least enter MAD MUNCHKINS MODE with command 0x43, and send the appropriate data(not the actual rumble type data per-se) + with command 0x4D. + + DualAnalog-style rumble support seems to be borked until power loss if MAD MUNCHKINS MODE is even entered once...investigate further. + + Command 0x44 in MAD MUNCHKINS MODE can turn on/off analog mode(and the light with it). + + Command 0x42 in MAD MUNCHKINS MODE will return the analog mode style gamepad data, even when analog mode is off. In combination with command 0x44, this could hypothetically + be used for using the light in the gamepad as some kind of game mechanic). + + Dual Analog-style rumble notes(some of which may apply to DS too): + Rumble appears to stop if you hold DTR active(TODO: for how long? instant?). (TODO: investigate if it's still stopped even if a memory card device number is sent. It may be, since rumble may + cause excessive current draw in combination with memory card access) + + Rumble will work even if you interrupt the communication process after you've sent the rumble data(via command 0x42). + Though if you interrupt it when you've only sent partial rumble data, dragons will eat you and I don't know(seems to have timing-dependent or random effects or something; + based on VERY ROUGH testing). +*/ + +namespace MDFN_IEN_PSX +{ + +class InputDevice_DualShock : public InputDevice +{ + public: + + InputDevice_DualShock(const std::string &arg_name); + virtual ~InputDevice_DualShock(); + + virtual void Power(void); + virtual void Update(const pscpu_timestamp_t timestamp); + virtual void ResetTS(void); + virtual void UpdateInput(const void *data); + + virtual void SetAMCT(bool enabled); + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + void CheckManualAnaModeChange(void); + + // + // + bool cur_ana_button_state; + bool prev_ana_button_state; + int64 combo_anatoggle_counter; + // + + bool da_rumble_compat; + + bool analog_mode; + bool analog_mode_locked; + + bool mad_munchkins; + uint8 rumble_magic[6]; + + uint8 rumble_param[2]; + + bool dtr; + + uint8 buttons[2]; + uint8 axes[2][2]; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[8]; + uint32 transmit_pos; + uint32 transmit_count; + + // + // + // + bool am_prev_info; + bool aml_prev_info; + std::string gp_name; + pscpu_timestamp_t lastts; + + // + // + bool amct_enabled; +}; + +InputDevice_DualShock::InputDevice_DualShock(const std::string &name) +{ + gp_name = name; + Power(); + am_prev_info = analog_mode; + aml_prev_info = analog_mode_locked; + amct_enabled = false; +} + +InputDevice_DualShock::~InputDevice_DualShock() +{ + +} + +void InputDevice_DualShock::Update(const pscpu_timestamp_t timestamp) +{ + lastts = timestamp; +} + +void InputDevice_DualShock::ResetTS(void) +{ + //printf("%lld\n", combo_anatoggle_counter); + if(combo_anatoggle_counter >= 0) + combo_anatoggle_counter += lastts; + lastts = 0; +} + +void InputDevice_DualShock::SetAMCT(bool enabled) +{ + amct_enabled = enabled; +} + +// +// This simulates the behavior of the actual DualShock(analog toggle button evaluation is suspended while DTR is active). +// Call in Update(), and whenever dtr goes inactive in the port access code. +void InputDevice_DualShock::CheckManualAnaModeChange(void) +{ + if(!dtr) + { + bool need_mode_toggle = false; + + if(amct_enabled) + { + if(buttons[0] == 0x09 && buttons[1] == 0x0f) + { + if(combo_anatoggle_counter == -1) + combo_anatoggle_counter = 0; + else if(combo_anatoggle_counter >= (44100 * 768)) + { + need_mode_toggle = true; + combo_anatoggle_counter = -2; + } + } + else + combo_anatoggle_counter = -1; + } + else + { + combo_anatoggle_counter = -1; + if(cur_ana_button_state && (cur_ana_button_state != prev_ana_button_state)) + { + need_mode_toggle = true; + } + } + + if(need_mode_toggle) + { + if(analog_mode_locked) + { + MDFN_DispMessage(_("%s: Analog mode is locked %s."), gp_name.c_str(), analog_mode ? _("on") : _("off")); + } + else + analog_mode = !analog_mode; + } + + prev_ana_button_state = cur_ana_button_state; // Don't move this outside of the if(!dtr) block! + } +} + +void InputDevice_DualShock::Power(void) +{ + combo_anatoggle_counter = -2; + lastts = 0; + // + // + + dtr = 0; + + buttons[0] = buttons[1] = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; + + analog_mode = false; + analog_mode_locked = false; + + mad_munchkins = false; + memset(rumble_magic, 0, sizeof(rumble_magic)); + memset(rumble_param, 0, sizeof(rumble_param)); + + da_rumble_compat = true; + + prev_ana_button_state = false; +} + +void InputDevice_DualShock::UpdateInput(const void *data) +{ + uint8 *d8 = (uint8 *)data; + + buttons[0] = d8[0]; + buttons[1] = d8[1]; + cur_ana_button_state = d8[2] & 0x01; + + for(int stick = 0; stick < 2; stick++) + { + for(int axis = 0; axis < 2; axis++) + { + int32 tmp; + + tmp = 32768 + MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 4) - ((int32)MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 8) * 32768 / 32767); + tmp >>= 8; + + axes[stick][axis] = tmp; + } + } + + if(da_rumble_compat == false) + { + uint8 sneaky_weaky = 0; + + if(rumble_param[0] == 0x01) + sneaky_weaky = 0xFF; + + MDFN_en32lsb(&d8[4 + 32 + 0], (sneaky_weaky << 0) | (rumble_param[1] << 8)); + } + else + { + uint8 sneaky_weaky = 0; + + if(((rumble_param[0] & 0xC0) == 0x40) && ((rumble_param[1] & 0x01) == 0x01)) + sneaky_weaky = 0xFF; + + MDFN_en32lsb(&d8[4 + 32 + 0], sneaky_weaky << 0); + } + + //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]); + + // + // + // + CheckManualAnaModeChange(); + + if(am_prev_info != analog_mode || aml_prev_info != analog_mode_locked) + { + MDFN_DispMessage(_("%s: Analog mode is %s(%s)."), gp_name.c_str(), analog_mode ? _("on") : _("off"), analog_mode_locked ? _("locked") : _("unlocked")); + } + am_prev_info = analog_mode; + aml_prev_info = analog_mode_locked; +} + + +void InputDevice_DualShock::SetDTR(bool new_dtr) +{ + const bool old_dtr = dtr; + dtr = new_dtr; // Set it to new state before we call CheckManualAnaModeChange(). + + if(!old_dtr && dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(old_dtr && !dtr) + { + CheckManualAnaModeChange(); + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } +} + +bool InputDevice_DualShock::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_DualShock::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //if(command == 0x44) + //if(mad_munchkins || command == 0x43) + // fprintf(stderr, "[PAD] Receive: %02x -- command=%02x, command_phase=%d, transmit_pos=%d\n", receive_buffer, command, command_phase, transmit_pos); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + if(mad_munchkins) + { + transmit_buffer[0] = 0xF3; + transmit_pos = 0; + transmit_count = 1; + command_phase = 101; + } + else + { + transmit_buffer[0] = analog_mode ? 0x73 : 0x41; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + } + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + //fprintf(stderr, "Gamepad command: 0x%02x\n", command); + //if(command != 0x42 && command != 0x43) + // fprintf(stderr, "Gamepad unhandled command: 0x%02x\n", command); + + if(command == 0x42) + { + transmit_buffer[0] = 0x5A; + transmit_pos = 0; + transmit_count = 1; + command_phase = (command << 8) | 0x00; + } + else if(command == 0x43) + { + transmit_pos = 0; + if(analog_mode) + { + transmit_buffer[1] = 0xFF ^ buttons[0]; + transmit_buffer[2] = 0xFF ^ buttons[1]; + transmit_buffer[3] = axes[0][0]; + transmit_buffer[4] = axes[0][1]; + transmit_buffer[5] = axes[1][0]; + transmit_buffer[6] = axes[1][1]; + transmit_count = 7; + } + else + { + transmit_buffer[1] = 0xFF ^ buttons[0]; + transmit_buffer[2] = 0xFF ^ buttons[1]; + transmit_count = 3; + } + } + else + { + command_phase = -1; + transmit_buffer[1] = 0; + transmit_buffer[2] = 0; + transmit_pos = 0; + transmit_count = 0; + } + break; + + case 2: + { + if(command == 0x43 && transmit_pos == 2 && (receive_buffer == 0x01)) + { + //fprintf(stderr, "Mad Munchkins mode entered!\n"); + mad_munchkins = true; + + if(da_rumble_compat) + { + rumble_param[0] = 0; + rumble_param[1] = 0; + da_rumble_compat = false; + } + command_phase = -1; + } + } + break; + + case 101: + command = receive_buffer; + + //fprintf(stderr, "Mad Munchkins DualShock command: 0x%02x\n", command); + + if(command >= 0x40 && command <= 0x4F) + { + transmit_buffer[0] = 0x5A; + transmit_pos = 0; + transmit_count = 1; + command_phase = (command << 8) | 0x00; + } + else + { + transmit_count = 0; + command_phase = -1; + } + break; + + /************************/ + /* MMMode 1, Command 0x40 */ + /************************/ + case 0x4000: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4001: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + + /************************/ + /* MMMode 1, Command 0x41 */ + /************************/ + case 0x4100: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4101: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /**************************/ + /* MMMode 0&1, Command 0x42 */ + /**************************/ + case 0x4200: + transmit_pos = 0; + if(analog_mode || mad_munchkins) + { + transmit_buffer[0] = 0xFF ^ buttons[0]; + transmit_buffer[1] = 0xFF ^ buttons[1]; + transmit_buffer[2] = axes[0][0]; + transmit_buffer[3] = axes[0][1]; + transmit_buffer[4] = axes[1][0]; + transmit_buffer[5] = axes[1][1]; + transmit_count = 6; + } + else + { + transmit_buffer[0] = 0xFF ^ buttons[0]; + transmit_buffer[1] = 0xFF ^ buttons[1]; + transmit_count = 2; + } + command_phase++; + break; + + case 0x4201: // Weak(in DS mode) + if(da_rumble_compat || (rumble_magic[0] == 0x00 && rumble_magic[2] != 0x00 && rumble_magic[3] != 0x00 && rumble_magic[4] != 0x00 && rumble_magic[5] != 0x00)) + rumble_param[0] = receive_buffer; + command_phase++; + break; + + case 0x4202: // Strong(in DS mode) + if(da_rumble_compat || rumble_magic[1] == 0x01) + rumble_param[1] = receive_buffer; + command_phase++; // Nowhere here we come! + break; + + /************************/ + /* MMMode 1, Command 0x43 */ + /************************/ + case 0x4300: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4301: + if(receive_buffer == 0x00) + { + //fprintf(stderr, "Mad Munchkins mode left!\n"); + mad_munchkins = false; + } + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x44 */ + /************************/ + case 0x4400: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4401: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase++; + + // Ignores locking state. + switch(receive_buffer) + { + case 0x00: + analog_mode = false; + //fprintf(stderr, "Analog mode disabled\n"); + break; + + case 0x01: + analog_mode = true; + //fprintf(stderr, "Analog mode enabled\n"); + break; + } + break; + + case 0x4402: + switch(receive_buffer) + { + case 0x02: + analog_mode_locked = false; + break; + + case 0x03: + analog_mode_locked = true; + break; + } + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x45 */ + /************************/ + case 0x4500: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0x01; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4501: + transmit_buffer[0] = 0x02; + transmit_buffer[1] = analog_mode ? 0x01 : 0x00; + transmit_buffer[2] = 0x02; + transmit_buffer[3] = 0x01; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + + /************************/ + /* MMMode 1, Command 0x46 */ + /************************/ + case 0x4600: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4601: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x01; + transmit_buffer[2] = 0x02; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x0A; + } + else if(receive_buffer == 0x01) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x01; + transmit_buffer[2] = 0x01; + transmit_buffer[3] = 0x01; + transmit_buffer[4] = 0x14; + } + else + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + } + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x47 */ + /************************/ + case 0x4700: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4701: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x02; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x01; + transmit_buffer[4] = 0x00; + } + else + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + } + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x48 */ + /************************/ + case 0x4800: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4801: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x01; + transmit_buffer[4] = rumble_param[0]; + } + else if(receive_buffer == 0x01) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x01; + transmit_buffer[4] = rumble_param[1]; + } + else + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + } + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x49 */ + /************************/ + case 0x4900: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4901: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x4A */ + /************************/ + case 0x4A00: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4A01: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x4B */ + /************************/ + case 0x4B00: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4B01: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x4C */ + /************************/ + case 0x4C00: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4C01: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x04; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + } + else if(receive_buffer == 0x01) + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x07; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + } + else + { + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + } + + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + /************************/ + /* MMMode 1, Command 0x4D */ + /************************/ + case 0x4D00: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = rumble_magic[0]; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4D01: + case 0x4D02: + case 0x4D03: + case 0x4D04: + case 0x4D05: + case 0x4D06: + { + unsigned index = command_phase - 0x4D01; + + if(index < 5) + { + transmit_buffer[0] = rumble_magic[1 + index]; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + else + command_phase = -1; + + rumble_magic[index] = receive_buffer; + } + break; + + /************************/ + /* MMMode 1, Command 0x4E */ + /************************/ + case 0x4E00: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4E01: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + + + /************************/ + /* MMMode 1, Command 0x4F */ + /************************/ + case 0x4F00: + if(receive_buffer == 0x00) + { + transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/ + command_phase++; + } + else + command_phase = -1; + break; + + case 0x4F01: + transmit_buffer[0] = 0x00; + transmit_buffer[1] = 0x00; + transmit_buffer[2] = 0x00; + transmit_buffer[3] = 0x00; + transmit_buffer[4] = 0x00; + transmit_pos = 0; + transmit_count = 5; + command_phase = -1; + break; + } + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 0x40; //0x100; + + return(ret); +} + +InputDevice *Device_DualShock_Create(const std::string &name) +{ + return new InputDevice_DualShock(name); +} + + +InputDeviceInputInfoStruct Device_DualShock_IDII[26] = +{ + { "select", "SELECT", 4, IDIT_BUTTON, NULL }, + { "l3", "Left Stick, Button(L3)", 18, IDIT_BUTTON, NULL }, + { "r3", "Right stick, Button(R3)", 23, IDIT_BUTTON, NULL }, + { "start", "START", 5, IDIT_BUTTON, NULL }, + { "up", "D-Pad UP ↑", 0, IDIT_BUTTON, "down" }, + { "right", "D-Pad RIGHT →", 3, IDIT_BUTTON, "left" }, + { "down", "D-Pad DOWN ↓", 1, IDIT_BUTTON, "up" }, + { "left", "D-Pad LEFT â†", 2, IDIT_BUTTON, "right" }, + + { "l2", "L2 (rear left shoulder)", 11, IDIT_BUTTON, NULL }, + { "r2", "R2 (rear right shoulder)", 13, IDIT_BUTTON, NULL }, + { "l1", "L1 (front left shoulder)", 10, IDIT_BUTTON, NULL }, + { "r1", "R1 (front right shoulder)", 12, IDIT_BUTTON, NULL }, + + { "triangle", "â–³ (upper)", 6, IDIT_BUTTON_CAN_RAPID, NULL }, + { "circle", "â—‹ (right)", 9, IDIT_BUTTON_CAN_RAPID, NULL }, + { "cross", "x (lower)", 7, IDIT_BUTTON_CAN_RAPID, NULL }, + { "square", "â–¡ (left)", 8, IDIT_BUTTON_CAN_RAPID, NULL }, + + { "analog", "Analog(mode toggle)", 24, IDIT_BUTTON, NULL }, + + { "rstick_right", "Right Stick RIGHT →", 22, IDIT_BUTTON_ANALOG }, + { "rstick_left", "Right Stick LEFT â†", 21, IDIT_BUTTON_ANALOG }, + { "rstick_down", "Right Stick DOWN ↓", 20, IDIT_BUTTON_ANALOG }, + { "rstick_up", "Right Stick UP ↑", 19, IDIT_BUTTON_ANALOG }, + + { "lstick_right", "Left Stick RIGHT →", 17, IDIT_BUTTON_ANALOG }, + { "lstick_left", "Left Stick LEFT â†", 16, IDIT_BUTTON_ANALOG }, + { "lstick_down", "Left Stick DOWN ↓", 15, IDIT_BUTTON_ANALOG }, + { "lstick_up", "Left Stick UP ↑", 14, IDIT_BUTTON_ANALOG }, + + { "rumble", "RUMBLE MONSTER RUMBA", 100, IDIT_RUMBLE }, +}; + +} diff --git a/mednafen/psx-0925/input/dualshock.h b/mednafen/psx-0925/input/dualshock.h new file mode 100644 index 00000000..758f10bf --- /dev/null +++ b/mednafen/psx-0925/input/dualshock.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_DUALSHOCK_H +#define __MDFN_PSX_INPUT_DUALSHOCK_H + +#include + +namespace MDFN_IEN_PSX +{ +InputDevice *Device_DualShock_Create(const std::string &name); +extern InputDeviceInputInfoStruct Device_DualShock_IDII[26]; +} +#endif diff --git a/mednafen/psx-0925/input/gamepad.cpp b/mednafen/psx-0925/input/gamepad.cpp new file mode 100644 index 00000000..d04bb388 --- /dev/null +++ b/mednafen/psx-0925/input/gamepad.cpp @@ -0,0 +1,216 @@ +#include "../psx.h" +#include "../frontio.h" +#include "gamepad.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_Gamepad : public InputDevice +{ + public: + + InputDevice_Gamepad(); + virtual ~InputDevice_Gamepad(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + bool dtr; + + uint8 buttons[2]; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[3]; + uint32 transmit_pos; + uint32 transmit_count; +}; + +InputDevice_Gamepad::InputDevice_Gamepad() +{ + Power(); +} + +InputDevice_Gamepad::~InputDevice_Gamepad() +{ + +} + +void InputDevice_Gamepad::Power(void) +{ + dtr = 0; + + buttons[0] = buttons[1] = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; +} + +void InputDevice_Gamepad::UpdateInput(const void *data) +{ + uint8 *d8 = (uint8 *)data; + + buttons[0] = d8[0]; + buttons[1] = d8[1]; +} + + +void InputDevice_Gamepad::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + dtr = new_dtr; +} + +bool InputDevice_Gamepad::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_Gamepad::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //printf("[PAD] Receive: %02x -- command_phase=%d\n", receive_buffer, command_phase); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + transmit_buffer[0] = 0x41; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + //if(command != 0x42) + // fprintf(stderr, "Gamepad unhandled command: 0x%02x\n", command); + //assert(command == 0x42); + if(command == 0x42) + { + transmit_buffer[1] = 0xFF ^ buttons[0]; + transmit_buffer[2] = 0xFF ^ buttons[1]; + transmit_pos = 0; + transmit_count = 3; + } + else + { + command_phase = -1; + transmit_buffer[1] = 0; + transmit_buffer[2] = 0; + transmit_pos = 0; + transmit_count = 0; + } + break; + + } + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 0x40; //0x100; + + return(ret); +} + +InputDevice *Device_Gamepad_Create(void) +{ + return new InputDevice_Gamepad(); +} + + +InputDeviceInputInfoStruct Device_Gamepad_IDII[16] = +{ + { "select", "SELECT", 4, IDIT_BUTTON, NULL }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { "start", "START", 5, IDIT_BUTTON, NULL }, + { "up", "UP ↑", 0, IDIT_BUTTON, "down" }, + { "right", "RIGHT →", 3, IDIT_BUTTON, "left" }, + { "down", "DOWN ↓", 1, IDIT_BUTTON, "up" }, + { "left", "LEFT â†", 2, IDIT_BUTTON, "right" }, + + { "l2", "L2 (rear left shoulder)", 11, IDIT_BUTTON, NULL }, + { "r2", "R2 (rear right shoulder)", 13, IDIT_BUTTON, NULL }, + { "l1", "L1 (front left shoulder)", 10, IDIT_BUTTON, NULL }, + { "r1", "R1 (front right shoulder)", 12, IDIT_BUTTON, NULL }, + + { "triangle", "â–³ (upper)", 6, IDIT_BUTTON_CAN_RAPID, NULL }, + { "circle", "â—‹ (right)", 9, IDIT_BUTTON_CAN_RAPID, NULL }, + { "cross", "x (lower)", 7, IDIT_BUTTON_CAN_RAPID, NULL }, + { "square", "â–¡ (left)", 8, IDIT_BUTTON_CAN_RAPID, NULL }, +}; + + + +} diff --git a/mednafen/psx-0925/input/gamepad.h b/mednafen/psx-0925/input/gamepad.h new file mode 100644 index 00000000..e43e6de1 --- /dev/null +++ b/mednafen/psx-0925/input/gamepad.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_GAMEPAD_H +#define __MDFN_PSX_INPUT_GAMEPAD_H + +namespace MDFN_IEN_PSX +{ + +InputDevice *Device_Gamepad_Create(void); +extern InputDeviceInputInfoStruct Device_Gamepad_IDII[16]; + +} +#endif diff --git a/mednafen/psx-0925/input/guncon.cpp b/mednafen/psx-0925/input/guncon.cpp new file mode 100644 index 00000000..41852226 --- /dev/null +++ b/mednafen/psx-0925/input/guncon.cpp @@ -0,0 +1,396 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "../psx.h" +#include "../frontio.h" +#include "guncon.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_GunCon : public InputDevice +{ + public: + + InputDevice_GunCon(void); + virtual ~InputDevice_GunCon(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + virtual void SetCrosshairsColor(uint32 color); + virtual bool RequireNoFrameskip(void); + virtual pscpu_timestamp_t GPULineHook(const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + bool dtr; + + uint8 buttons; + bool trigger_eff; + bool trigger_noclear; + uint16 hit_x, hit_y; + + int32 nom_x, nom_y; + int32 os_shot_counter; + bool prev_oss; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[16]; + uint32 transmit_pos; + uint32 transmit_count; + + // + // Video timing stuff + bool prev_vsync; + int line_counter; + + // + unsigned chair_r, chair_g, chair_b; + bool draw_chair; +}; + +InputDevice_GunCon::InputDevice_GunCon(void) : chair_r(0), chair_g(0), chair_b(0), draw_chair(false) +{ + Power(); +} + +InputDevice_GunCon::~InputDevice_GunCon() +{ + +} + +void InputDevice_GunCon::SetCrosshairsColor(uint32 color) +{ + chair_r = (color >> 16) & 0xFF; + chair_g = (color >> 8) & 0xFF; + chair_b = (color >> 0) & 0xFF; + + draw_chair = (color != (1 << 24)); +} + +void InputDevice_GunCon::Power(void) +{ + dtr = 0; + + buttons = 0; + trigger_eff = 0; + trigger_noclear = 0; + hit_x = 0; + hit_y = 0; + + nom_x = 0; + nom_y = 0; + + os_shot_counter = 0; + prev_oss = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; + + prev_vsync = 0; + line_counter = 0; +} + +void InputDevice_GunCon::UpdateInput(const void *data) +{ + uint8 *d8 = (uint8 *)data; + + nom_x = MDFN_de32lsb(&d8[0]); + nom_y = MDFN_de32lsb(&d8[4]); + + trigger_noclear = (bool)(d8[8] & 0x1); + trigger_eff |= trigger_noclear; + + buttons = d8[8] >> 1; + + if(os_shot_counter > 0) // FIXME if UpdateInput() is ever called more than once per video frame(at ~50 or ~60Hz). + os_shot_counter--; + + // Eeeeiiiiiight. + if((d8[8] & 0x8) && !prev_oss && os_shot_counter == 0) + os_shot_counter = 4; + prev_oss = d8[8] & 0x8; + + //MDFN_DispMessage("%08x %08x", nom_x, nom_y); +} + +bool InputDevice_GunCon::RequireNoFrameskip(void) +{ + return(true); +} + +pscpu_timestamp_t InputDevice_GunCon::GPULineHook(const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, + const unsigned pix_clock_offset, const unsigned pix_clock) +{ + if(vsync && !prev_vsync) + line_counter = 0; + + if(pixels && pix_clock) + { + const int avs = 22; // Not 22 for PAL, fixme. + int32 gx; + int32 gy; + + gx = ((int64)nom_x * width / MDFNGameInfo->nominal_width + 0x8000) >> 16; + gy = (nom_y + 0x8000) >> 16; + + for(int32 ix = gx; ix < (gx + (int32)(pix_clock / 762925)); ix++) + { + if(ix >= 0 && (unsigned)ix < width && line_counter >= (avs + gy) && line_counter < (avs + gy + 8)) + { + int r, g, b, a; + + format->DecodeColor(pixels[ix], r, g, b, a); + + if((r + g + b) >= 0x40) // Wrong, but not COMPLETELY ABSOLUTELY wrong, at least. ;) + { + hit_x = (int64)(ix + pix_clock_offset) * 8000000 / pix_clock; // GunCon has what appears to be an 8.00MHz ceramic resonator in it. + hit_y = line_counter; + } + } + } + + if(draw_chair) + { + if(line_counter == (avs + gy)) + { + const int ic = pix_clock / 762925; + + for(int32 x = std::max(0, gx - ic); x < std::min(width, gx + ic); x++) + { + int r, g, b, a; + int nr, ng, nb; + + format->DecodeColor(pixels[x], r, g, b, a); + + nr = (r + chair_r * 3) >> 2; + ng = (g + chair_g * 3) >> 2; + nb = (b + chair_b * 3) >> 2; + + if(abs((r * 76 + g * 150 + b * 29) - (nr * 76 + ng * 150 + nb * 29)) < 16384) + { + nr >>= 1; + ng >>= 1; + nb >>= 1; + } + + pixels[x] = format->MakeColor(nr, ng, nb, a); + } + } + else if(line_counter >= (avs + gy - 8) && line_counter <= (avs + gy + 8)) + { + int r, g, b, a; + int nr, ng, nb; + + format->DecodeColor(pixels[gx], r, g, b, a); + + nr = (r + chair_r * 3) >> 2; + ng = (g + chair_g * 3) >> 2; + nb = (b + chair_b * 3) >> 2; + + if(abs((r * 76 + g * 150 + b * 29) - (nr * 76 + ng * 150 + nb * 29)) < 16384) + { + nr >>= 1; + ng >>= 1; + nb >>= 1; + } + + pixels[gx] = format->MakeColor(nr, ng, nb, a); + } + } + } + + line_counter++; + + return(PSX_EVENT_MAXTS); +} + +void InputDevice_GunCon::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + dtr = new_dtr; +} + +bool InputDevice_GunCon::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_GunCon::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //printf("[PAD] Receive: %02x -- command_phase=%d\n", receive_buffer, command_phase); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + transmit_buffer[0] = 0x63; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + break; + + case 2: + //if(receive_buffer) + // printf("%02x\n", receive_buffer); + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + //puts("MOO"); + //if(command != 0x42) + // fprintf(stderr, "GunCon unhandled command: 0x%02x\n", command); + //assert(command == 0x42); + if(command == 0x42) + { + transmit_buffer[1] = 0xFF ^ ((buttons & 0x01) << 3); + transmit_buffer[2] = 0xFF ^ (trigger_eff << 5) ^ ((buttons & 0x02) << 5); + + if(os_shot_counter > 0) + { + hit_x = 0x01; + hit_y = 0x0A; + transmit_buffer[2] |= (1 << 5); + if(os_shot_counter == 2 || os_shot_counter == 3) + { + transmit_buffer[2] &= ~(1 << 5); + } + } + + MDFN_en16lsb(&transmit_buffer[3], hit_x); + MDFN_en16lsb(&transmit_buffer[5], hit_y); + + hit_x = 0x01; + hit_y = 0x0A; + + transmit_pos = 0; + transmit_count = 7; + + trigger_eff = trigger_noclear; + } + else + { + command_phase = -1; + transmit_buffer[1] = 0; + transmit_buffer[2] = 0; + transmit_pos = 0; + transmit_count = 0; + } + break; + + } + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 100; //0x80; //0x40; + + return(ret); +} + +InputDevice *Device_GunCon_Create(void) +{ + return new InputDevice_GunCon(); +} + + +InputDeviceInputInfoStruct Device_GunCon_IDII[6] = +{ + { "x_axis", "X Axis", -1, IDIT_X_AXIS }, + { "y_axis", "Y Axis", -1, IDIT_Y_AXIS }, + + { "trigger", "Trigger", 0, IDIT_BUTTON, NULL }, + + { "a", "A", 1, IDIT_BUTTON, NULL }, + { "b", "B", 2, IDIT_BUTTON, NULL }, + + { "offscreen_shot", "Offscreen Shot(Simulated)", 3, IDIT_BUTTON, NULL }, // Useful for "Judge Dredd", and probably not much else. +}; + + + +} diff --git a/mednafen/psx-0925/input/guncon.h b/mednafen/psx-0925/input/guncon.h new file mode 100644 index 00000000..7641cc2d --- /dev/null +++ b/mednafen/psx-0925/input/guncon.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_GUNCON_H +#define __MDFN_PSX_INPUT_GUNCON_H + +namespace MDFN_IEN_PSX +{ + +InputDevice *Device_GunCon_Create(void); +extern InputDeviceInputInfoStruct Device_GunCon_IDII[6]; + +} +#endif diff --git a/mednafen/psx-0925/input/justifier.cpp b/mednafen/psx-0925/input/justifier.cpp new file mode 100644 index 00000000..cb39d746 --- /dev/null +++ b/mednafen/psx-0925/input/justifier.cpp @@ -0,0 +1,393 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "../psx.h" +#include "../frontio.h" +#include "justifier.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_Justifier : public InputDevice +{ + public: + + InputDevice_Justifier(void); + virtual ~InputDevice_Justifier(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + virtual void SetCrosshairsColor(uint32 color); + virtual bool RequireNoFrameskip(void); + virtual pscpu_timestamp_t GPULineHook(const pscpu_timestamp_t timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + bool dtr; + + uint8 buttons; + bool trigger_eff; + bool trigger_noclear; + + bool need_hit_detect; + + int32 nom_x, nom_y; + int32 os_shot_counter; + bool prev_oss; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[16]; + uint32 transmit_pos; + uint32 transmit_count; + + // + // Video timing stuff + bool prev_vsync; + int line_counter; + + // + unsigned chair_r, chair_g, chair_b; + bool draw_chair; +}; + +InputDevice_Justifier::InputDevice_Justifier(void) : chair_r(0), chair_g(0), chair_b(0), draw_chair(false) +{ + Power(); +} + +InputDevice_Justifier::~InputDevice_Justifier() +{ + +} + +void InputDevice_Justifier::SetCrosshairsColor(uint32 color) +{ + chair_r = (color >> 16) & 0xFF; + chair_g = (color >> 8) & 0xFF; + chair_b = (color >> 0) & 0xFF; + + draw_chair = (color != (1 << 24)); +} + +void InputDevice_Justifier::Power(void) +{ + dtr = 0; + + buttons = 0; + trigger_eff = 0; + trigger_noclear = 0; + + need_hit_detect = false; + + nom_x = 0; + nom_y = 0; + + os_shot_counter = 0; + prev_oss = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; + + prev_vsync = 0; + line_counter = 0; +} + +void InputDevice_Justifier::UpdateInput(const void *data) +{ + uint8 *d8 = (uint8 *)data; + + nom_x = MDFN_de32lsb(&d8[0]); + nom_y = MDFN_de32lsb(&d8[4]); + + trigger_noclear = (bool)(d8[8] & 0x1); + trigger_eff |= trigger_noclear; + + buttons = (d8[8] >> 1) & 0x3; + + if(os_shot_counter > 0) // FIXME if UpdateInput() is ever called more than once per video frame(at ~50 or ~60Hz). + os_shot_counter--; + + if((d8[8] & 0x8) && !prev_oss && os_shot_counter == 0) + os_shot_counter = 10; + prev_oss = d8[8] & 0x8; +} + +bool InputDevice_Justifier::RequireNoFrameskip(void) +{ + return(true); +} + +pscpu_timestamp_t InputDevice_Justifier::GPULineHook(const pscpu_timestamp_t timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, + const unsigned pix_clock_offset, const unsigned pix_clock) +{ + pscpu_timestamp_t ret = PSX_EVENT_MAXTS; + + if(vsync && !prev_vsync) + line_counter = 0; + + if(pixels && pix_clock) + { + const int avs = 22; // Not 22 for PAL, fixme. + int32 gx; + int32 gy; + int32 gxa; + + gx = ((int64)nom_x * width / MDFNGameInfo->nominal_width + 0x8000) >> 16; + gy = (nom_y + 0x8000) >> 16; + gxa = gx; // - (pix_clock / 400000); + //if(gxa < 0 && gx >= 0) + // gxa = 0; + + if(!os_shot_counter && need_hit_detect && gxa >= 0 && gxa < (int)width && line_counter >= (avs + gy - 1) && line_counter <= (avs + gy + 1)) + { + int r, g, b, a; + + format->DecodeColor(pixels[gxa], r, g, b, a); + + if((r + g + b) >= 0x40) // Wrong, but not COMPLETELY ABSOLUTELY wrong, at least. ;) + { + ret = timestamp + (int64)(gxa + pix_clock_offset) * (44100 * 768) / pix_clock - 181; + } + } + + if(draw_chair) + { + if(line_counter == (avs + gy)) + { + const int ic = pix_clock / 762925; + + for(int32 x = std::max(0, gx - ic); x < std::min(width, gx + ic); x++) + { + int r, g, b, a; + int nr, ng, nb; + + format->DecodeColor(pixels[x], r, g, b, a); + + nr = (r + chair_r * 3) >> 2; + ng = (g + chair_g * 3) >> 2; + nb = (b + chair_b * 3) >> 2; + + if(abs((r * 76 + g * 150 + b * 29) - (nr * 76 + ng * 150 + nb * 29)) < 16384) + { + nr >>= 1; + ng >>= 1; + nb >>= 1; + } + + pixels[x] = format->MakeColor(nr, ng, nb, a); + } + } + else if(line_counter >= (avs + gy - 8) && line_counter <= (avs + gy + 8)) + { + int r, g, b, a; + int nr, ng, nb; + + format->DecodeColor(pixels[gx], r, g, b, a); + + nr = (r + chair_r * 3) >> 2; + ng = (g + chair_g * 3) >> 2; + nb = (b + chair_b * 3) >> 2; + + if(abs((r * 76 + g * 150 + b * 29) - (nr * 76 + ng * 150 + nb * 29)) < 16384) + { + nr >>= 1; + ng >>= 1; + nb >>= 1; + } + + pixels[gx] = format->MakeColor(nr, ng, nb, a); + } + } + } + + line_counter++; + + return(ret); +} + +void InputDevice_Justifier::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + dtr = new_dtr; +} + +bool InputDevice_Justifier::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_Justifier::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //printf("[PAD] Receive: %02x -- command_phase=%d\n", receive_buffer, command_phase); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + transmit_buffer[0] = 0x31; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + break; + + case 2: + //if(receive_buffer) + // printf("%02x\n", receive_buffer); + command_phase++; + break; + + case 3: + need_hit_detect = receive_buffer & 0x10; // TODO, see if it's (val&0x10) == 0x10, or some other mask value. + command_phase++; + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + //if(command != 0x42) + // fprintf(stderr, "Justifier unhandled command: 0x%02x\n", command); + //assert(command == 0x42); + if(command == 0x42) + { + transmit_buffer[1] = 0xFF ^ ((buttons & 2) << 2); + transmit_buffer[2] = 0xFF ^ (trigger_eff << 7) ^ ((buttons & 1) << 6); + + if(os_shot_counter > 0) + { + transmit_buffer[2] |= (1 << 7); + if(os_shot_counter == 6 || os_shot_counter == 5) + { + transmit_buffer[2] &= ~(1 << 7); + } + } + + transmit_pos = 0; + transmit_count = 3; + + trigger_eff = trigger_noclear; + } + else + { + command_phase = -1; + transmit_buffer[1] = 0; + transmit_buffer[2] = 0; + transmit_pos = 0; + transmit_count = 0; + } + break; + + } + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 200; + + return(ret); +} + +InputDevice *Device_Justifier_Create(void) +{ + return new InputDevice_Justifier(); +} + + +InputDeviceInputInfoStruct Device_Justifier_IDII[6] = +{ + { "x_axis", "X Axis", -1, IDIT_X_AXIS }, + { "y_axis", "Y Axis", -1, IDIT_Y_AXIS }, + + { "trigger", "Trigger", 0, IDIT_BUTTON, NULL }, + + { "o", "O", 1, IDIT_BUTTON, NULL }, + { "start", "Start", 2, IDIT_BUTTON, NULL }, + + { "offscreen_shot", "Offscreen Shot(Simulated)", 3, IDIT_BUTTON, NULL }, +}; + + + +} diff --git a/mednafen/psx-0925/input/justifier.h b/mednafen/psx-0925/input/justifier.h new file mode 100644 index 00000000..b9c95982 --- /dev/null +++ b/mednafen/psx-0925/input/justifier.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_JUSTIFIER_H +#define __MDFN_PSX_INPUT_JUSTIFIER_H + +namespace MDFN_IEN_PSX +{ + +InputDevice *Device_Justifier_Create(void); +extern InputDeviceInputInfoStruct Device_Justifier_IDII[6]; + +} +#endif diff --git a/mednafen/psx-0925/input/memcard.cpp b/mednafen/psx-0925/input/memcard.cpp new file mode 100644 index 00000000..8655dce0 --- /dev/null +++ b/mednafen/psx-0925/input/memcard.cpp @@ -0,0 +1,448 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// I could find no other commands than 'R', 'W', and 'S' (not sure what 'S' is for, however) + +#include "../psx.h" +#include "../frontio.h" +#include "memcard.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_Memcard : public InputDevice +{ + public: + + InputDevice_Memcard(); + virtual ~InputDevice_Memcard(); + + virtual void Power(void); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + // + // + virtual uint32 GetNVSize(void); + virtual void ReadNV(uint8 *buffer, uint32 offset, uint32 size); + virtual void WriteNV(const uint8 *buffer, uint32 offset, uint32 size); + + virtual uint64 GetNVDirtyCount(void); + virtual void ResetNVDirtyCount(void); + + private: + + bool presence_new; + + uint8 card_data[1 << 17]; + uint8 rw_buffer[128]; + uint8 write_xor; + + uint64 dirty_count; + + bool dtr; + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + uint16 addr; + uint8 calced_xor; + + uint8 transmit_buffer; + uint32 transmit_count; +}; + +InputDevice_Memcard::InputDevice_Memcard() +{ + Power(); + + dirty_count = 0; + + // Init memcard as formatted. + assert(sizeof(card_data) == (1 << 17)); + memset(card_data, 0x00, sizeof(card_data)); + + card_data[0x00] = 0x4D; + card_data[0x01] = 0x43; + card_data[0x7F] = 0x0E; + + for(unsigned int A = 0x80; A < 0x800; A += 0x80) + { + card_data[A + 0x00] = 0xA0; + card_data[A + 0x08] = 0xFF; + card_data[A + 0x09] = 0xFF; + card_data[A + 0x7F] = 0xA0; + } + + for(unsigned int A = 0x0800; A < 0x1200; A += 0x80) + { + card_data[A + 0x00] = 0xFF; + card_data[A + 0x01] = 0xFF; + card_data[A + 0x02] = 0xFF; + card_data[A + 0x03] = 0xFF; + card_data[A + 0x08] = 0xFF; + card_data[A + 0x09] = 0xFF; + } + +} + +InputDevice_Memcard::~InputDevice_Memcard() +{ + +} + +void InputDevice_Memcard::Power(void) +{ + dtr = 0; + + //buttons[0] = buttons[1] = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + transmit_buffer = 0; + + transmit_count = 0; + + addr = 0; + + presence_new = true; +} + +void InputDevice_Memcard::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + if(command_phase > 0) + PSX_WARNING("[MCR] Communication aborted???"); + } + dtr = new_dtr; +} + +bool InputDevice_Memcard::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_Memcard::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //if(command_phase > 0 || transmit_count) + // printf("[MCRDATA] Received_data=0x%02x, Sent_data=0x%02x\n", receive_buffer, transmit_buffer); + + if(transmit_count) + { + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x81) + command_phase = -1; + else + { + //printf("[MCR] Device selected\n"); + transmit_buffer = presence_new ? 0x08 : 0x00; + transmit_count = 1; + command_phase++; + } + break; + + case 1: + command = receive_buffer; + //printf("[MCR] Command received: %c\n", command); + if(command == 'R' || command == 'W') + { + command_phase++; + transmit_buffer = 0x5A; + transmit_count = 1; + } + else + { + if(command == 'S') + { + PSX_WARNING("[MCR] Memcard S command unsupported."); + } + + command_phase = -1; + transmit_buffer = 0; + transmit_count = 0; + } + break; + + case 2: + transmit_buffer = 0x5D; + transmit_count = 1; + command_phase++; + break; + + case 3: + transmit_buffer = 0x00; + transmit_count = 1; + if(command == 'R') + command_phase = 1000; + else if(command == 'W') + command_phase = 2000; + break; + + // + // Read + // + case 1000: + addr = receive_buffer << 8; + transmit_buffer = receive_buffer; + transmit_count = 1; + command_phase++; + break; + + case 1001: + addr |= receive_buffer & 0xFF; + transmit_buffer = '\\'; + transmit_count = 1; + command_phase++; + break; + + case 1002: + //printf("[MCR] READ ADDR=0x%04x\n", addr); + if(addr >= (sizeof(card_data) >> 7)) + addr = 0xFFFF; + + calced_xor = 0; + transmit_buffer = ']'; + transmit_count = 1; + command_phase++; + + // TODO: enable this code(or something like it) when CPU instruction timing is a bit better. + // + //dsr_pulse_delay = 32000; + //goto SkipDPD; + // + + break; + + case 1003: + transmit_buffer = addr >> 8; + calced_xor ^= transmit_buffer; + transmit_count = 1; + command_phase++; + break; + + case 1004: + transmit_buffer = addr & 0xFF; + calced_xor ^= transmit_buffer; + + if(addr == 0xFFFF) + { + transmit_count = 1; + command_phase = -1; + } + else + { + transmit_count = 1; + command_phase = 1024; + } + break; + + // Transmit actual 128 bytes data + case (1024 + 0) ... (1024 + 128 - 1): + transmit_buffer = card_data[(addr << 7) + (command_phase - 1024)]; + calced_xor ^= transmit_buffer; + transmit_count = 1; + command_phase++; + break; + + // XOR + case (1024 + 128): + transmit_buffer = calced_xor; + transmit_count = 1; + command_phase++; + break; + + // End flag + case (1024 + 129): + transmit_buffer = 'G'; + transmit_count = 1; + command_phase = -1; + break; + + // + // Write + // + case 2000: + calced_xor = receive_buffer; + addr = receive_buffer << 8; + transmit_buffer = receive_buffer; + transmit_count = 1; + command_phase++; + break; + + case 2001: + calced_xor ^= receive_buffer; + addr |= receive_buffer & 0xFF; + //printf("[MCR] WRITE ADDR=0x%04x\n", addr); + transmit_buffer = receive_buffer; + transmit_count = 1; + command_phase = 2048; + break; + + case (2048 + 0) ... (2048 + 128 - 1): + calced_xor ^= receive_buffer; + rw_buffer[command_phase - 2048] = receive_buffer; + + transmit_buffer = receive_buffer; + transmit_count = 1; + command_phase++; + break; + + case (2048 + 128): // XOR + write_xor = receive_buffer; + transmit_buffer = '\\'; + transmit_count = 1; + command_phase++; + break; + + case (2048 + 129): + transmit_buffer = ']'; + transmit_count = 1; + command_phase++; + break; + + case (2048 + 130): // End flag + //MDFN_DispMessage("%02x %02x", calced_xor, write_xor); + //printf("[MCR] Write End. Actual_XOR=0x%02x, CW_XOR=0x%02x\n", calced_xor, write_xor); + + if(calced_xor != write_xor) + transmit_buffer = 'N'; + else if(addr >= (sizeof(card_data) >> 7)) + transmit_buffer = 0xFF; + else + { + transmit_buffer = 'G'; + presence_new = false; + + // If the current data is different from the data to be written, increment the dirty count. + // memcpy()'ing over to card_data is also conditionalized here for a slight optimization. + if(memcmp(&card_data[addr << 7], rw_buffer, 128)) + { + memcpy(&card_data[addr << 7], rw_buffer, 128); + dirty_count++; + } + } + + transmit_count = 1; + command_phase = -1; + break; + + } + + //if(command_phase != -1 || transmit_count) + // printf("[MCR] Receive: 0x%02x, Send: 0x%02x -- %d\n", receive_buffer, transmit_buffer, command_phase); + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 0x100; + + //SkipDPD: ; + + return(ret); +} + +uint32 InputDevice_Memcard::GetNVSize(void) +{ + return(sizeof(card_data)); +} + +void InputDevice_Memcard::ReadNV(uint8 *buffer, uint32 offset, uint32 size) +{ + while(size--) + { + *buffer = card_data[offset & (sizeof(card_data) - 1)]; + buffer++; + offset++; + } +} + +void InputDevice_Memcard::WriteNV(const uint8 *buffer, uint32 offset, uint32 size) +{ + if(size) + dirty_count++; + + while(size--) + { + card_data[offset & (sizeof(card_data) - 1)] = *buffer; + buffer++; + offset++; + } +} + +uint64 InputDevice_Memcard::GetNVDirtyCount(void) +{ + return(dirty_count); +} + +void InputDevice_Memcard::ResetNVDirtyCount(void) +{ + dirty_count = 0; +} + + +InputDevice *Device_Memcard_Create(void) +{ + return new InputDevice_Memcard(); +} + +} diff --git a/mednafen/psx-0925/input/memcard.h b/mednafen/psx-0925/input/memcard.h new file mode 100644 index 00000000..05627661 --- /dev/null +++ b/mednafen/psx-0925/input/memcard.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_MEMCARD_H +#define __MDFN_PSX_INPUT_MEMCARD_H + +namespace MDFN_IEN_PSX +{ + +InputDevice *Device_Memcard_Create(void); + +} + +#endif diff --git a/mednafen/psx-0925/input/mouse.cpp b/mednafen/psx-0925/input/mouse.cpp new file mode 100644 index 00000000..dd91a031 --- /dev/null +++ b/mednafen/psx-0925/input/mouse.cpp @@ -0,0 +1,252 @@ +#include "../psx.h" +#include "../frontio.h" +#include "mouse.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_Mouse : public InputDevice +{ + public: + + InputDevice_Mouse(); + virtual ~InputDevice_Mouse(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + + virtual void Update(const pscpu_timestamp_t timestamp); + virtual void ResetTS(void); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + int32 lastts; + int32 clear_timeout; + + bool dtr; + + uint8 button; + uint8 button_post_mask; + int32 accum_xdelta; + int32 accum_ydelta; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[5]; + uint32 transmit_pos; + uint32 transmit_count; +}; + +InputDevice_Mouse::InputDevice_Mouse() +{ + Power(); +} + +InputDevice_Mouse::~InputDevice_Mouse() +{ + +} + +void InputDevice_Mouse::Update(const pscpu_timestamp_t timestamp) +{ + int32 cycles = timestamp - lastts; + + clear_timeout += cycles; + if(clear_timeout >= (33868800 / 4)) + { + //puts("Mouse timeout\n"); + clear_timeout = 0; + accum_xdelta = 0; + accum_ydelta = 0; + button &= button_post_mask; + } + + lastts = timestamp; +} + +void InputDevice_Mouse::ResetTS(void) +{ + lastts = 0; +} + +void InputDevice_Mouse::Power(void) +{ + lastts = 0; + clear_timeout = 0; + + dtr = 0; + + button = 0; + button_post_mask = 0; + accum_xdelta = 0; + accum_ydelta = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; +} + +void InputDevice_Mouse::UpdateInput(const void *data) +{ + accum_xdelta += (int32)MDFN_de32lsb((uint8*)data + 0); + accum_ydelta += (int32)MDFN_de32lsb((uint8*)data + 4); + + if(accum_xdelta > 30 * 127) accum_xdelta = 30 * 127; + if(accum_xdelta < 30 * -128) accum_xdelta = 30 * -128; + + if(accum_ydelta > 30 * 127) accum_ydelta = 30 * 127; + if(accum_ydelta < 30 * -128) accum_ydelta = 30 * -128; + + button |= *((uint8 *)data + 8); + button_post_mask = *((uint8 *)data + 8); + + //if(button) + // MDFN_DispMessage("Button\n"); + //printf("%d %d\n", accum_xdelta, accum_ydelta); +} + + +void InputDevice_Mouse::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + dtr = new_dtr; +} + +bool InputDevice_Mouse::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //printf("[PAD] Receive: %02x -- command_phase=%d\n", receive_buffer, command_phase); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + transmit_buffer[0] = 0x12; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + } + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + if(command == 0x42) + { + int32 xdelta = accum_xdelta; + int32 ydelta = accum_ydelta; + + if(xdelta < -128) xdelta = -128; + if(xdelta > 127) xdelta = 127; + + if(ydelta < -128) ydelta = -128; + if(ydelta > 127) ydelta = 127; + + transmit_buffer[1] = 0xFF; + transmit_buffer[2] = 0xFC ^ (button << 2); + transmit_buffer[3] = xdelta; + transmit_buffer[4] = ydelta; + + accum_xdelta -= xdelta; + accum_ydelta -= ydelta; + + button &= button_post_mask; + + transmit_pos = 0; + transmit_count = 5; + + clear_timeout = 0; + } + else + { + command_phase = -1; + transmit_pos = 0; + transmit_count = 0; + } + break; + + } + } + + if(!bitpos && transmit_count) + dsr_pulse_delay = 0x40; //0x100; + + return(ret); +} + +InputDevice *Device_Mouse_Create(void) +{ + return new InputDevice_Mouse(); +} + + +InputDeviceInputInfoStruct Device_Mouse_IDII[4] = +{ + { "x_axis", "X Axis", -1, IDIT_X_AXIS_REL }, + { "y_axis", "Y Axis", -1, IDIT_Y_AXIS_REL }, + { "right", "Right Button", 1, IDIT_BUTTON, NULL }, + { "left", "Left Button", 0, IDIT_BUTTON, NULL }, +}; + + + +} diff --git a/mednafen/psx-0925/input/mouse.h b/mednafen/psx-0925/input/mouse.h new file mode 100644 index 00000000..2597a75f --- /dev/null +++ b/mednafen/psx-0925/input/mouse.h @@ -0,0 +1,11 @@ +#ifndef __MDFN_PSX_INPUT_MOUSE_H +#define __MDFN_PSX_INPUT_MOUSE_H + +namespace MDFN_IEN_PSX +{ + +InputDevice *Device_Mouse_Create(void); +extern InputDeviceInputInfoStruct Device_Mouse_IDII[4]; + +} +#endif diff --git a/mednafen/psx-0925/input/multitap.cpp b/mednafen/psx-0925/input/multitap.cpp new file mode 100644 index 00000000..5f3d0aa2 --- /dev/null +++ b/mednafen/psx-0925/input/multitap.cpp @@ -0,0 +1,335 @@ +#include "../psx.h" +#include "../frontio.h" +#include "multitap.h" + +/* + Notes from tests on real thing(not necessarily emulated the same way here): + + Manual port selection read mode: + Write 0x01-0x04 instead of 0x01 as first byte, selects port(1=A,2=B,3=C,4=D) to access. + + Ports that don't exist(0x00, 0x05-0xFF) or don't have a device plugged in will not respond(no DSR pulse). + + Full read mode: + Bit0 of third byte(from-zero-index=0x02) should be set to 1 to enter full read mode, on subsequent reads. + + Appears to require a controller to be plugged into the port specified by the first byte as per manual port selection read mode, + to write the byte necessary to enter full-read mode; but once the third byte with the bit set has been written, no controller in + that port is required for doing full reads(and the manual port selection is ignored when doing a full read). + + However, if there are no controllers plugged in, or the first byte written in a full-mode communication has one or more bits in the upper + nybble set to 1, the returned data will be short: + % 0: 0xff + % 1: 0x80 + % 2: 0x5a + + Example full-read bytestream(with controllers plugged into port A, port B, and port C, with port D empty): + % 0: 0xff + % 1: 0x80 + % 2: 0x5a + + % 3: 0x73 (Port A controller data start) + % 4: 0x5a + % 5: 0xff + % 6: 0xff + % 7: 0x80 + % 8: 0x8c + % 9: 0x79 + % 10: 0x8f + + % 11: 0x53 (Port B controller data start) + % 12: 0x5a + % 13: 0xff + % 14: 0xff + % 15: 0x80 + % 16: 0x80 + % 17: 0x75 + % 18: 0x8e + + % 19: 0x41 (Port C controller data start) + % 20: 0x5a + % 21: 0xff + % 22: 0xff + % 23: 0xff + % 24: 0xff + % 25: 0xff + % 26: 0xff + + % 27: 0xff (Port D controller data start) + % 28: 0xff + % 29: 0xff + % 30: 0xff + % 31: 0xff + % 32: 0xff + % 33: 0xff + % 34: 0xff + +*/ + +namespace MDFN_IEN_PSX +{ + +InputDevice_Multitap::InputDevice_Multitap() +{ + for(int i = 0; i < 4; i++) + { + pad_devices[i] = NULL; + mc_devices[i] = NULL; + } + Power(); +} + +InputDevice_Multitap::~InputDevice_Multitap() +{ +} + +void InputDevice_Multitap::SetSubDevice(unsigned int sub_index, InputDevice *device, InputDevice *mc_device) +{ + assert(sub_index < 4); + + //printf("%d\n", sub_index); + + pad_devices[sub_index] = device; + mc_devices[sub_index] = mc_device; +} + + +void InputDevice_Multitap::Power(void) +{ + selected_device = -1; + bit_counter = 0; + receive_buffer = 0; + byte_counter = 0; + + mc_mode = false; + full_mode = false; + full_mode_setting = false; + + for(int i = 0; i < 4; i++) + { + if(pad_devices[i]) + pad_devices[i]->Power(); + + if(mc_devices[i]) + mc_devices[i]->Power(); + } +} + +void InputDevice_Multitap::SetDTR(bool new_dtr) +{ + bool old_dtr = dtr; + dtr = new_dtr; + + if(!dtr) + { + bit_counter = 0; + byte_counter = 0; + receive_buffer = 0; + selected_device = -1; + mc_mode = false; + full_mode = false; + } + + if(!old_dtr && dtr) + { + full_mode = full_mode_setting; + //if(full_mode) { + // printf("Full mode start\n"); } + } + + for(int i = 0; i < 4; i++) + { + pad_devices[i]->SetDTR(dtr); + mc_devices[i]->SetDTR(dtr); + } +} + +bool InputDevice_Multitap::GetDSR(void) +{ + return(0); +} + +bool InputDevice_Multitap::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + if(!dtr) + return(1); + + bool ret = 1; + bool mangled_txd = TxD; + int32 tmp_pulse_delay[2][4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; + + //printf("Receive bit: %d\n", TxD); + //printf("TxD %d\n", TxD); + + receive_buffer &= ~ (1 << bit_counter); + receive_buffer |= TxD << bit_counter; + + if(1) + { + uint8 sub_clock = 0; + uint8 sub_rxd_ignore = 0; + + if(full_mode) + { + if(byte_counter == 0) + { + sub_clock = 0; + sub_rxd_ignore = 0xF; + } + else if(byte_counter == 1) + { + ret = (0x80 >> bit_counter) & 1; + sub_clock = false; + sub_rxd_ignore = 0xF; + } + else if(byte_counter == 2) + { + ret = (0x5A >> bit_counter) & 1; + sub_rxd_ignore = 0xF; + + if(!mc_mode) + { + sub_clock = 0xF; + mangled_txd = (0x01 >> bit_counter) & 1; + } + } + else if(byte_counter == 0x03 || byte_counter == (0x03 + 0x08 * 1) || byte_counter == (0x03 + 0x08 * 2) || byte_counter == (0x03 + 0x08 * 3)) + { + sub_clock = 1 << selected_device; + sub_rxd_ignore = 0; + mangled_txd = (command >> bit_counter) & 1; + } + else + { + sub_clock = 1 << selected_device; + sub_rxd_ignore = 0; + // Not sure about this, would need to test with rumble-capable device on real thing? + //mangled_txd = (0x00 >> bit_counter) & 1; + } + } + else + { + if(byte_counter == 0) + { + if(bit_counter < 4) + mangled_txd = (0x01 >> bit_counter) & 1; + + sub_clock = 0xF; + sub_rxd_ignore = 0xF; + } + else if((unsigned)selected_device < 4) + { + sub_clock = 1 << selected_device; + sub_rxd_ignore = 0; + } + } + + for(int i = 0; i < 4; i++) + { + if(sub_clock & (1 << i)) + { + ret &= pad_devices[i]->Clock(mangled_txd, tmp_pulse_delay[0][i]) | ((sub_rxd_ignore >> i) & 1); + ret &= mc_devices[i]->Clock(mangled_txd, tmp_pulse_delay[1][i]) | ((sub_rxd_ignore >> i) & 1); + } + } + } + + +#if 0 + { + static uint8 sendy = 0; + + sendy &= ~(1 << bit_counter); + sendy |= ret << bit_counter; + + if(bit_counter == 7) + printf("Multitap to PSX: 0x%02x\n", sendy); + } +#endif + + + bit_counter = (bit_counter + 1) & 0x7; + if(bit_counter == 0) + { + if(byte_counter == 0) + { + mc_mode = (bool)(receive_buffer & 0xF0); + + //printf("Full mode: %d %d %d\n", full_mode, bit_counter, byte_counter); + + if(full_mode) + selected_device = 0; + else + { + //printf("Device select: %02x\n", receive_buffer); + selected_device = ((receive_buffer & 0xF) - 1) & 0xFF; + } + } + + if(byte_counter == 1) + { + command = receive_buffer; + //printf("Multitap sub-command: %02x\n", command); + } + + if((!mc_mode || full_mode) && byte_counter == 2 && command == 0x42) + { + //printf("Full mode setting: %02x\n", receive_buffer); + full_mode_setting = receive_buffer & 0x01; + } + + // Handle DSR stuff + if(full_mode) + { + if(byte_counter == 0 || byte_counter == 1) + dsr_pulse_delay = 0x40; + else if(byte_counter == 2 || byte_counter == 3) + { + //int32 td = 0; + //for(int i = 0; i < 4; i++) + //{ + // td = std::max(td, tmp_pulse_delay[0][i]); + // td = std::max(td, tmp_pulse_delay[1][i]); + //} + //dsr_pulse_delay = td; + //printf("%d %d\n", byte_counter, dsr_pulse_delay); + + // Just route the first port's DSR through here; at least one game relies on this(Formula One 2000), or else it freezes. Well, even when it doesn't + // freeze, the game crashes(as of Jan 20, 2012), but that's not the multitap emulation's fault. :b + dsr_pulse_delay = std::max(tmp_pulse_delay[0][0], tmp_pulse_delay[1][0]); + } + else if(byte_counter > 3 && byte_counter < 34) + { + dsr_pulse_delay = 0x80; + } + } + else + { + if((unsigned)selected_device < 4) + { + dsr_pulse_delay = std::max(tmp_pulse_delay[0][selected_device], tmp_pulse_delay[1][selected_device]); + } + } + + + // + // + // + + //printf("Byte Counter Increment\n"); + if(byte_counter < 255) + byte_counter++; + + if(full_mode && (byte_counter == (0x03 + 0x08 * 1) || byte_counter == (0x03 + 0x08 * 2) || byte_counter == (0x03 + 0x08 * 3))) + { + //printf("Device Select Increment\n"); + selected_device++; + } + } + + + + return(ret); +} + +} diff --git a/mednafen/psx-0925/input/multitap.h b/mednafen/psx-0925/input/multitap.h new file mode 100644 index 00000000..f295a5f7 --- /dev/null +++ b/mednafen/psx-0925/input/multitap.h @@ -0,0 +1,45 @@ +#ifndef __MDFN_PSX_INPUT_MULTITAP_H +#define __MDFN_PSX_INPUT_MULTITAP_H + +namespace MDFN_IEN_PSX +{ + +class InputDevice_Multitap : public InputDevice +{ + public: + + InputDevice_Multitap(); + virtual ~InputDevice_Multitap(); + virtual void Power(void); + + void SetSubDevice(unsigned int sub_index, InputDevice *device, InputDevice *mc_device); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + InputDevice *pad_devices[4]; + InputDevice *mc_devices[4]; + + bool dtr; + + int selected_device; + bool full_mode_setting; + + bool full_mode; + bool mc_mode; + + uint8 command; + uint8 receive_buffer; + uint8 bit_counter; + uint8 byte_counter; +}; + +} + +#endif diff --git a/mednafen/psx-0925/input/negcon.cpp b/mednafen/psx-0925/input/negcon.cpp new file mode 100644 index 00000000..939334b4 --- /dev/null +++ b/mednafen/psx-0925/input/negcon.cpp @@ -0,0 +1,259 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "../psx.h" +#include "../frontio.h" +#include "negcon.h" + +namespace MDFN_IEN_PSX +{ + +class InputDevice_neGcon : public InputDevice +{ + public: + + InputDevice_neGcon(void); + virtual ~InputDevice_neGcon(); + + virtual void Power(void); + virtual void UpdateInput(const void *data); + + // + // + // + virtual void SetDTR(bool new_dtr); + virtual bool GetDSR(void); + virtual bool Clock(bool TxD, int32 &dsr_pulse_delay); + + private: + + bool dtr; + + uint8 buttons[2]; + uint8 twist; + uint8 anabuttons[3]; + + int32 command_phase; + uint32 bitpos; + uint8 receive_buffer; + + uint8 command; + + uint8 transmit_buffer[8]; + uint32 transmit_pos; + uint32 transmit_count; +}; + +InputDevice_neGcon::InputDevice_neGcon(void) +{ + Power(); +} + +InputDevice_neGcon::~InputDevice_neGcon() +{ + +} + +void InputDevice_neGcon::Power(void) +{ + dtr = 0; + + buttons[0] = buttons[1] = 0; + twist = 0; + anabuttons[0] = 0; + anabuttons[1] = 0; + anabuttons[2] = 0; + + command_phase = 0; + + bitpos = 0; + + receive_buffer = 0; + + command = 0; + + memset(transmit_buffer, 0, sizeof(transmit_buffer)); + + transmit_pos = 0; + transmit_count = 0; +} + +void InputDevice_neGcon::UpdateInput(const void *data) +{ + uint8 *d8 = (uint8 *)data; + + buttons[0] = d8[0]; + buttons[1] = d8[1]; + + twist = ((32768 + MDFN_de32lsb((const uint8 *)data + 4) - (((int32)MDFN_de32lsb((const uint8 *)data + 8) * 32768 + 16383) / 32767)) * 255 + 32767) / 65535; + + anabuttons[0] = (MDFN_de32lsb((const uint8 *)data + 12) * 255 + 16383) / 32767; + anabuttons[1] = (MDFN_de32lsb((const uint8 *)data + 16) * 255 + 16383) / 32767; + anabuttons[2] = (MDFN_de32lsb((const uint8 *)data + 20) * 255 + 16383) / 32767; + + //printf("%02x %02x %02x %02x\n", twist, anabuttons[0], anabuttons[1], anabuttons[2]); +} + + +void InputDevice_neGcon::SetDTR(bool new_dtr) +{ + if(!dtr && new_dtr) + { + command_phase = 0; + bitpos = 0; + transmit_pos = 0; + transmit_count = 0; + } + else if(dtr && !new_dtr) + { + //if(bitpos || transmit_count) + // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + + dtr = new_dtr; +} + +bool InputDevice_neGcon::GetDSR(void) +{ + if(!dtr) + return(0); + + if(!bitpos && transmit_count) + return(1); + + return(0); +} + +bool InputDevice_neGcon::Clock(bool TxD, int32 &dsr_pulse_delay) +{ + bool ret = 1; + + dsr_pulse_delay = 0; + + if(!dtr) + return(1); + + if(transmit_count) + ret = (transmit_buffer[transmit_pos] >> bitpos) & 1; + + receive_buffer &= ~(1 << bitpos); + receive_buffer |= TxD << bitpos; + bitpos = (bitpos + 1) & 0x7; + + if(!bitpos) + { + //printf("[PAD] Receive: %02x -- command_phase=%d\n", receive_buffer, command_phase); + + if(transmit_count) + { + transmit_pos++; + transmit_count--; + } + + + switch(command_phase) + { + case 0: + if(receive_buffer != 0x01) + command_phase = -1; + else + { + transmit_buffer[0] = 0x23; + transmit_pos = 0; + transmit_count = 1; + command_phase++; + dsr_pulse_delay = 256; + } + break; + + case 1: + command = receive_buffer; + command_phase++; + + transmit_buffer[0] = 0x5A; + + //if(command != 0x42) + // fprintf(stderr, "Gamepad unhandled command: 0x%02x\n", command); + + if(command == 0x42) + { + transmit_buffer[1] = 0xFF ^ buttons[0]; + transmit_buffer[2] = 0xFF ^ buttons[1]; + transmit_buffer[3] = twist; // Twist, 0x00 through 0xFF, 0x80 center. + transmit_buffer[4] = anabuttons[0]; // Analog button I, 0x00 through 0xFF, 0x00 = no pressing, 0xFF = max. + transmit_buffer[5] = anabuttons[1]; // Analog button II, "" + transmit_buffer[6] = anabuttons[2]; // Left shoulder analog button, "" + transmit_pos = 0; + transmit_count = 7; + dsr_pulse_delay = 256; + } + else + { + command_phase = -1; + transmit_buffer[1] = 0; + transmit_buffer[2] = 0; + transmit_pos = 0; + transmit_count = 0; + } + break; + + case 2: + if(transmit_count > 0) + dsr_pulse_delay = 128; + break; + } + } + + return(ret); +} + +InputDevice *Device_neGcon_Create(void) +{ + return new InputDevice_neGcon(); +} + + +InputDeviceInputInfoStruct Device_neGcon_IDII[21] = +{ + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { "start", "START", 4, IDIT_BUTTON, NULL }, + { "up", "D-Pad UP ↑", 0, IDIT_BUTTON, "down" }, + { "right", "D-Pad RIGHT →", 3, IDIT_BUTTON, "left" }, + { "down", "D-Pad DOWN ↓", 1, IDIT_BUTTON, "up" }, + { "left", "D-Pad LEFT â†", 2, IDIT_BUTTON, "right" }, + + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { "r", "Right Shoulder", 12, IDIT_BUTTON }, + + { "b", "B", 9, IDIT_BUTTON, NULL }, + { "a", "A", 10, IDIT_BUTTON, NULL }, + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + { NULL, "empty", -1, IDIT_BUTTON, NULL }, + + { "twist_cwise", "Twist ↓|↑ (Analog, Turn Right)", 6, IDIT_BUTTON_ANALOG }, + { "twist_ccwise", "Twist ↑|↓ (Analog, Turn Left)", 5, IDIT_BUTTON_ANALOG }, + { "i", "I (Analog)", 8, IDIT_BUTTON_ANALOG }, + { "ii", "II (Analog)", 7, IDIT_BUTTON_ANALOG }, + + { "l", "Left Shoulder (Analog)", 11, IDIT_BUTTON_ANALOG }, +}; + +} diff --git a/mednafen/psx-0925/input/negcon.h b/mednafen/psx-0925/input/negcon.h new file mode 100644 index 00000000..0091fec4 --- /dev/null +++ b/mednafen/psx-0925/input/negcon.h @@ -0,0 +1,9 @@ +#ifndef __MDFN_PSX_INPUT_NEGCON_H +#define __MDFN_PSX_INPUT_NEGCON_H + +namespace MDFN_IEN_PSX +{ + InputDevice *Device_neGcon_Create(void); + extern InputDeviceInputInfoStruct Device_neGcon_IDII[21]; +} +#endif diff --git a/mednafen/psx-0925/irq.cpp b/mednafen/psx-0925/irq.cpp new file mode 100644 index 00000000..20a36c7a --- /dev/null +++ b/mednafen/psx-0925/irq.cpp @@ -0,0 +1,174 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" + +namespace MDFN_IEN_PSX +{ + +static uint16 Asserted; +static uint16 Mask; +static uint16 Status; + +static INLINE void Recalc(void) +{ + CPU->AssertIRQ(0, (bool)(Status & Mask)); +} + +void IRQ_Power(void) +{ + Asserted = 0; + Status = 0; + Mask = 0; + + Recalc(); +} + +int IRQ_StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { + SFVAR(Asserted), + SFVAR(Mask), + SFVAR(Status), + SFEND + }; + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "IRQ"); + + if(load) + { + Recalc(); + } + + return(ret); +} + + +void IRQ_Assert(int which, bool status) +{ + uint32 old_Asserted = Asserted; + //PSX_WARNING("[IRQ] Assert: %d %d", which, status); + + //if(which == IRQ_SPU && status && (Asserted & (1 << which))) + // MDFN_DispMessage("SPU IRQ glitch??"); + + Asserted &= ~(1 << which); + + if(status) + { + Asserted |= 1 << which; + //Status |= 1 << which; + Status |= (old_Asserted ^ Asserted) & Asserted; + } + + Recalc(); +} + + +void IRQ_Write(uint32 A, uint32 V) +{ + // FIXME if we ever have "accurate" bus emulation + V <<= (A & 3) * 8; + + //printf("[IRQ] Write: 0x%08x 0x%08x --- PAD TEMP\n", A, V); + + if(A & 4) + Mask = V; + else + { + Status &= V; + //Status |= Asserted; + } + + Recalc(); +} + + +uint32 IRQ_Read(uint32 A) +{ + uint32 ret = 0; + + if(A & 4) + ret = Mask; + else + ret = Status; + + // FIXME: Might want to move this out to psx.cpp eventually. + ret |= 0x1F800000; + ret >>= (A & 3) * 8; + + + //printf("[IRQ] Read: 0x%08x 0x%08x --- PAD TEMP\n", A, ret); + + return(ret); +} + + +void IRQ_Reset(void) +{ + Asserted = 0; + Status = 0; + Mask = 0; + + Recalc(); +} + + +uint32 IRQ_GetRegister(unsigned int which, char *special, const uint32 special_len) +{ + uint32 ret = 0; + + switch(which) + { + case IRQ_GSREG_ASSERTED: + ret = Asserted; + break; + + case IRQ_GSREG_STATUS: + ret = Status; + break; + + case IRQ_GSREG_MASK: + ret = Mask; + break; + } + return(ret); +} + +void IRQ_SetRegister(unsigned int which, uint32 value) +{ + switch(which) + { + case IRQ_GSREG_ASSERTED: + Asserted = value; + Recalc(); + break; + + case IRQ_GSREG_STATUS: + Status = value; + Recalc(); + break; + + case IRQ_GSREG_MASK: + Mask = value; + Recalc(); + break; + } +} + + +} diff --git a/mednafen/psx-0925/irq.h b/mednafen/psx-0925/irq.h new file mode 100644 index 00000000..43179eb8 --- /dev/null +++ b/mednafen/psx-0925/irq.h @@ -0,0 +1,43 @@ +#ifndef __MDFN_PSX_IRQ_H +#define __MDFN_PSX_IRQ_H + +namespace MDFN_IEN_PSX +{ + + +enum +{ + IRQ_VSYNC = 0, + IRQ_GPU = 1, + IRQ_CD = 2, + IRQ_DMA = 3, // Probably + IRQ_TIMER_0 = 4, + IRQ_TIMER_1 = 5, + IRQ_TIMER_2 = 6, + IRQ_SIO = 7, + IRQ_SPU = 9, + IRQ_PIO = 10, // Probably +}; + +void IRQ_Power(void); +void IRQ_Assert(int which, bool asserted); + +void IRQ_Write(uint32 A, uint32 V); +uint32 IRQ_Read(uint32 A); + + +enum +{ + IRQ_GSREG_ASSERTED = 0, + IRQ_GSREG_STATUS = 1, + IRQ_GSREG_MASK = 2 +}; + +uint32 IRQ_GetRegister(unsigned int which, char *special, const uint32 special_len); +void IRQ_SetRegister(unsigned int which, uint32 value); + +int IRQ_StateAction(StateMem *sm, int load, int data_only); +}; + + +#endif diff --git a/mednafen/psx-0925/mdec.cpp b/mednafen/psx-0925/mdec.cpp new file mode 100644 index 00000000..b726474a --- /dev/null +++ b/mednafen/psx-0925/mdec.cpp @@ -0,0 +1,543 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "mdec.h" + +#include "../cdrom/SimpleFIFO.h" +#include + +#if defined(__SSE2__) +#include +#include +#endif + +#if defined(ARCH_POWERPC_ALTIVEC) && defined(HAVE_ALTIVEC_H) + #include +#endif + +namespace MDFN_IEN_PSX +{ + + +static bool block_ready; +static int32 block_y[2][2][8][8]; +static int32 block_cb[8][8]; // [y >> 1][x >> 1] +static int32 block_cr[8][8]; // [y >> 1][x >> 1] + +static int32 run_time; +static uint32 Command; + +static uint8 QMatrix[2][64]; +static uint32 QMIndex; + +static int16 IDCTMatrix[64] MDFN_ALIGN(16); +static uint32 IDCTMIndex; + +static uint8 QScale; + +static int16 Coeff[6][64] MDFN_ALIGN(16); +static uint32 CoeffIndex; +static uint32 DecodeWB; + +static SimpleFIFO InputBuffer(65536); +static SimpleFIFO OutBuffer(384); + +static uint32 InCounter; +static bool BlockEnd; +static bool DecodeEnd; + +static const uint8 ZigZag[64] = +{ + 0x00, 0x01, 0x08, 0x10, 0x09, 0x02, 0x03, 0x0A, + 0x11, 0x18, 0x20, 0x19, 0x12, 0x0B, 0x04, 0x05, + 0x0C, 0x13, 0x1A, 0x21, 0x28, 0x30, 0x29, 0x22, + 0x1B, 0x14, 0x0D, 0x06, 0x07, 0x0E, 0x15, 0x1C, + 0x23, 0x2A, 0x31, 0x38, 0x39, 0x32, 0x2B, 0x24, + 0x1D, 0x16, 0x0F, 0x17, 0x1E, 0x25, 0x2C, 0x33, + 0x3A, 0x3B, 0x34, 0x2D, 0x26, 0x1F, 0x27, 0x2E, + 0x35, 0x3C, 0x3D, 0x36, 0x2F, 0x37, 0x3E, 0x3F +}; + +void MDEC_Power(void) +{ + run_time = 0; + block_ready = false; + + Command = 0; + memset(QMatrix, 0, sizeof(QMatrix)); + QMIndex = 0; + + memset(IDCTMatrix, 0, sizeof(IDCTMatrix)); + IDCTMIndex = 0; + + QScale = 0; + + memset(Coeff, 0, sizeof(Coeff)); + CoeffIndex = 0; + DecodeWB = 0; + + OutBuffer.Flush(); + + InCounter = 0; + BlockEnd = 0; + DecodeEnd = 0; +} + +int MDEC_StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { + SFVAR(block_ready), + + SFARRAY32(&block_y[0][0][0][0], sizeof(block_y) / sizeof(block_y[0][0][0][0])), + SFARRAY32(&block_cb[0][0], sizeof(block_cb) / sizeof(block_cb[0][0])), + SFARRAY32(&block_cr[0][0], sizeof(block_cr) / sizeof(block_cr[0][0])), + + SFVAR(run_time), + SFVAR(Command), + + SFARRAY(&QMatrix[0][0], sizeof(QMatrix) / sizeof(QMatrix[0][0])), + SFVAR(QMIndex), + + SFARRAY16(&IDCTMatrix[0], sizeof(IDCTMatrix) / sizeof(IDCTMatrix[0])), + SFVAR(IDCTMIndex), + + SFVAR(QScale), + + SFARRAY16(&Coeff[0][0], sizeof(Coeff) / sizeof(Coeff[0][0])), + SFVAR(CoeffIndex), + SFVAR(DecodeWB), + +#define SFFIFO16(fifoobj) SFARRAY16(&fifoobj.data[0], fifoobj.data.size()), \ + SFVAR(fifoobj.read_pos), \ + SFVAR(fifoobj.write_pos), \ + SFVAR(fifoobj.in_count) + + SFFIFO16(InputBuffer), + SFFIFO16(OutBuffer), +#undef SFFIFO + + SFVAR(InCounter), + SFVAR(BlockEnd), + SFVAR(DecodeEnd), + + SFEND + }; + + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "MDEC"); + + if(load) + { + + } + + return(ret); +} + + +static INLINE void WriteQTab(uint8 V) +{ + QMatrix[QMIndex >> 6][QMIndex & 0x3F] = V; + QMIndex = (QMIndex + 1) & 0x7F; +} + +static void DecodeImage(void); +static INLINE void WriteImageData(uint16 V) +{ + const uint32 qmw = (bool)(DecodeWB < 2); + + //printf("MDEC DMA SubWrite: %04x\n", V); + + if(!CoeffIndex) + { + if(DecodeWB == 0 && V == 0xFE00) + { + InputBuffer.Flush(); + return; + } + QScale = V >> 10; + Coeff[DecodeWB][ZigZag[0]] = sign_10_to_s16(V & 0x3FF) * QMatrix[qmw][0]; + CoeffIndex++; + } + else + { + if(V == 0xFE00) + { + BlockEnd = true; + while(CoeffIndex < 64) + Coeff[DecodeWB][ZigZag[CoeffIndex++]] = 0; + } + else + { + uint32 rlcount = V >> 10; + + for(uint32 i = 0; i < rlcount && CoeffIndex < 64; i++) + { + Coeff[DecodeWB][ZigZag[CoeffIndex]] = 0; + CoeffIndex++; + } + + if(CoeffIndex < 64) + { + Coeff[DecodeWB][ZigZag[CoeffIndex]] = (sign_10_to_s16(V & 0x3FF) * QScale * QMatrix[qmw][CoeffIndex]) >> 3; // Arithmetic right shift or division(negative differs)? + CoeffIndex++; + } + } + } + + if(CoeffIndex == 64 && BlockEnd) + { + BlockEnd = false; + CoeffIndex = 0; + + //printf("Block %d finished\n", DecodeWB); + + DecodeWB++; + if(DecodeWB == 6) + { + DecodeWB = 0; + + DecodeImage(); + } + } +} + +static void IDCT(int16 *in_coeff, int32 *out_coeff) +{ +#if defined(__SSE2__) + for(int i = 0; i < 8 * 8; i++) + { + __m128i sum = _mm_set1_epi32(0); + __m128i m0 = _mm_load_si128((__m128i *)&IDCTMatrix[((i & 7) * 8) + 0]); + int32 tmp[4] MDFN_ALIGN(16); + + for(int v = 0; v < 8; v++) + { + __m128i c = _mm_load_si128((__m128i *)&in_coeff[v * 8]); + __m128i m1 = _mm_set1_epi16(IDCTMatrix[(i & ~7) + v]); + __m128i m = _mm_mulhi_epi16(m0, m1); + + sum = _mm_add_epi32(sum, _mm_madd_epi16(c, m)); + } + + sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, (3 << 0) | (2 << 2) | (1 << 4) | (0 << 6))); + sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, (1 << 0) | (0 << 2))); + sum = _mm_srai_epi32(sum, 16); + + //_mm_store_ss((float *)(out_coeff + i), (__m128)sum); + _mm_store_si128((__m128i*)tmp, sum); + + out_coeff[i] = tmp[0]; //((tmp[0] + tmp[1]) + (tmp[2] + tmp[3])) >> 16; + } +#elif defined(ARCH_POWERPC_ALTIVEC) + static const uint8 snail_cake[16] MDFN_ALIGN(16) = { + 0x00, 0x01, 0x10, 0x11, + 0x04, 0x05, 0x14, 0x15, + 0x08, 0x09, 0x18, 0x19, + 0x0C, 0x0D, 0x1C, 0x1D }; + vector unsigned char snail_pizza = vec_ld(0, snail_cake); + + for(int i = 0; i < 8 * 8; i++) + { + vector signed int sum = vec_splat_s32(0); + vector signed short m0 = vec_ld((((i & 7) * 8) + 0) * sizeof(signed short), IDCTMatrix); + int32 tmp[4] MDFN_ALIGN(16); + + for(int v = 0; v < 8; v++) + { + vector signed short c = vec_ld((v * 8) * sizeof(signed short), in_coeff); + vector signed short m1 = vec_splats(IDCTMatrix[(i & ~7) + v]); + #if 0 + vector signed short m = vec_madds(m0, m1, vec_splat_s16(0)); // Has incorrect behavior for what we need. + #endif + vector signed int te = vec_mule(m0, m1); + vector signed int to = vec_mulo(m0, m1); + vector signed short m = (vector signed short)vec_perm(te, to, snail_pizza); + + sum = vec_msum(c, m, sum); + } + vec_st(sum, 0, tmp); + out_coeff[i] = ((tmp[0] + tmp[1]) + (tmp[2] + tmp[3])) >> 16; + } +#else + for(int y = 0; y < 8; y++) + { + for(int x = 0; x < 8; x++) + { + int32 sum = 0; + + for(int v = 0; v < 8; v++) + { + int16 *c = &in_coeff[v * 8]; + int16 *m0 = &IDCTMatrix[(x * 8) + 0]; + int16 *m1 = &IDCTMatrix[(y * 8) + v]; + + for(int u = 0; u < 8; u++) + { + sum += c[u] * ((m0[u] * m1[0]) >> 16); + } + } + out_coeff[y * 8 + x] = sum >> 16; + } + } +#endif +} + +static void YCbCr_to_RGB(const int32 y, const int32 cb, const int32 cr, int &r, int &g, int &b) +{ + r = (y + 128) + ((91881 * cr) >> 16); + g = (y + 128) - ((22525 * cb) >> 16) - ((46812 * cr) >> 16); + b = (y + 128) + ((116130 * cb) >> 16); + + if(r < 0) r = 0; + if(r > 255) r = 255; + + if(g < 0) g = 0; + if(g > 255) g = 255; + + if(b < 0) b = 0; + if(b > 255) b = 255; +} + +static void DecodeImage(void) +{ + //puts("DECODE"); + run_time -= 2048; //4096; //256; //1024; //2048; //8192; //1024; //4096; + + IDCT(Coeff[0], &block_cr[0][0]); + IDCT(Coeff[1], &block_cb[0][0]); + IDCT(Coeff[2], &block_y[0][0][0][0]); + IDCT(Coeff[3], &block_y[0][1][0][0]); + IDCT(Coeff[4], &block_y[1][0][0][0]); + IDCT(Coeff[5], &block_y[1][1][0][0]); + + block_ready = true; +} + +static void EncodeImage(void) +{ + //printf("ENCODE, %d\n", (Command & 0x08000000) ? 256 : 384); + + block_ready = false; + + if(!(Command & 0x08000000)) + { + uint8 output[16][16][3]; // [y][x][cc] + + for(int y = 0; y < 16; y++) + { + for(int x = 0; x < 16; x++) + { + int r, g, b; + + YCbCr_to_RGB(block_y[(y >> 3) & 1][(x >> 3) & 1][y & 7][x & 7], block_cb[y >> 1][x >> 1], block_cr[y >> 1][x >> 1], r, g, b); + + //r = y * 15; + //g = x * 15; + //b = 0; + + output[y][x][0] = r; + output[y][x][1] = g; + output[y][x][2] = b; + } + } + + for(int i = 0; i < 384; i++) + { + if(OutBuffer.CanWrite()) + OutBuffer.WriteUnit((&output[0][0][0])[i * 2 + 0] | ((&output[0][0][0])[i * 2 + 1] << 8)); + } + } + else + { + uint16 pixel_or = (Command & 0x02000000) ? 0x8000 : 0x0000; + + for(int y = 0; y < 16; y++) + { + for(int x = 0; x < 16; x++) + { + int r, g, b; + + YCbCr_to_RGB(block_y[(y >> 3) & 1][(x >> 3) & 1][y & 7][x & 7], block_cb[y >> 1][x >> 1], block_cr[y >> 1][x >> 1], r, g, b); + + if(OutBuffer.CanWrite()) + OutBuffer.WriteUnit(pixel_or | ((r >> 3) << 0) | ((g >> 3) << 5) | ((b >> 3) << 10)); + } + } + } +} + +void MDEC_DMAWrite(uint32 V) +{ + if(Command == 0x60000000) + { + for(unsigned i = 0; i < 2; i++) + { + IDCTMatrix[((IDCTMIndex & 0x7) << 3) | ((IDCTMIndex >> 3) & 0x7)] = (int16)(V & 0xFFFF); + IDCTMIndex = (IDCTMIndex + 1) & 0x3F; + + V >>= 16; + } + } + else if(Command == 0x40000001) + { + for(int i = 0; i < 4; i++) + { + WriteQTab((uint8)V); + V >>= 8; + } + } + else if((Command & 0xF5FF0000) == 0x30000000) + { + if(InCounter > 0) + { + for(int vi = 0; vi < 2; vi++) + { + if(InputBuffer.CanWrite()) + InputBuffer.WriteUnit(V); + + V >>= 16; + } + InCounter--; + } + } + else + { + printf("MYSTERY1: %08x\n", V); + } +} + +uint32 MDEC_DMARead(void) +{ + uint32 V = 0; + + if((Command & 0xF5FF0000) == 0x30000000 && OutBuffer.CanRead() >= 2) + { + V = OutBuffer.ReadUnit() | (OutBuffer.ReadUnit() << 16); + } + else + { + puts("BONUS GNOMES"); + V = rand(); + } + return(V); +} + +bool MDEC_DMACanRead(void) +{ + return(OutBuffer.CanRead() >= 2); //(OutBuffer.CanRead() >= 2) || ((Command & 0xF5FF0000) != 0x30000000); +} + +void MDEC_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + PSX_WARNING("[MDEC] Write: 0x%08x 0x%08x, %d", A, V, timestamp); + if(A & 4) + { + if(V & 0x80000000) // Reset? + { + block_ready = false; + run_time = 0; + QMIndex = 0; + IDCTMIndex = 0; + + QScale = 0; + + memset(Coeff, 0, sizeof(Coeff)); + CoeffIndex = 0; + DecodeWB = 0; + + InputBuffer.Flush(); + OutBuffer.Flush(); + + InCounter = 0; + BlockEnd = false; + } + } + else + { + Command = V; + + if((Command & 0xF5FF0000) == 0x30000000) + { + InputBuffer.Flush(); + OutBuffer.Flush(); + + block_ready = false; + BlockEnd = false; + CoeffIndex = 0; + DecodeWB = 0; + + InCounter = V & 0xFFFF; + } + else if(Command == 0x60000000) + { + IDCTMIndex = 0; + } + else if(Command == 0x40000001) + { + QMIndex = 0; + } + } +} + +uint32 MDEC_Read(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 ret = 0; + + if(A & 4) + { + ret = 0; + + if(InputBuffer.CanRead()) + ret |= 0x20000000; + } + else + { + ret = Command; + } + + //PSX_WARNING("[MDEC] Read: 0x%08x 0x%08x -- %d %d", A, ret, InputBuffer.CanRead(), InCounter); + + return(ret); +} + +void MDEC_Run(int32 clocks) +{ + run_time += clocks; + + while(run_time > 0) + { + run_time--; + + if(block_ready && !OutBuffer.CanRead()) + EncodeImage(); + + if(block_ready && OutBuffer.CanRead()) + break; + + if(!InputBuffer.CanRead()) + break; + + WriteImageData(InputBuffer.ReadUnit()); + } + + if(run_time > 0) + run_time = 0; +} + +} diff --git a/mednafen/psx-0925/mdec.h b/mednafen/psx-0925/mdec.h new file mode 100644 index 00000000..d1d6999d --- /dev/null +++ b/mednafen/psx-0925/mdec.h @@ -0,0 +1,23 @@ +#ifndef __MDFN_PSX_MDEC_H +#define __MDFN_PSX_MDEC_H + +namespace MDFN_IEN_PSX +{ + +void MDEC_DMAWrite(uint32 V); + +uint32 MDEC_DMARead(void); + +void MDEC_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); +uint32 MDEC_Read(const pscpu_timestamp_t timestamp, uint32 A); + + +void MDEC_Power(void); + +bool MDEC_DMACanRead(void); +void MDEC_Run(int32 clocks); + +int MDEC_StateAction(StateMem *sm, int load, int data_only); +} + +#endif diff --git a/mednafen/psx-0925/psx.cpp b/mednafen/psx-0925/psx.cpp new file mode 100644 index 00000000..45df1247 --- /dev/null +++ b/mednafen/psx-0925/psx.cpp @@ -0,0 +1,1878 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LIBRETRO__ +#define HAVE_PSF 1 +#endif + +#include "psx.h" +#include "mdec.h" +#include "frontio.h" +#include "timer.h" +#include "sio.h" +#include "cdc.h" +#include "spu.h" +#include "../mednafen-endian.h" +#include "../mempatcher.h" +#ifdef HAVE_PSF +#include "../PSFLoader.h" +#include "../player.h" +#endif + +#include "../cputest/cputest.h" + +extern MDFNGI EmulatedPSX; + +namespace MDFN_IEN_PSX +{ + +#ifdef HAVE_PSF +class PSF1Loader : public PSFLoader +{ + public: + + PSF1Loader(MDFNFILE *fp); + virtual ~PSF1Loader(); + + virtual void HandleEXE(const uint8 *data, uint32 len, bool ignore_pcsp = false); + + PSFTags tags; +}; +#endif + +enum +{ + REGION_JP = 0, + REGION_NA = 1, + REGION_EU = 2, +}; + +#if 0 +static uint32 PortReadCounter[0x4000] = { 0 }; // Debugging(performance) +static uint32 ReadCounter = 0; +static uint32 WriteCounter = 0; +#endif + +#ifdef HAVE_PSF +static PSF1Loader *psf_loader = NULL; +#endif + +static std::vector *cdifs = NULL; +static std::vector cdifs_scex_ids; +static bool CD_TrayOpen; +static int CD_SelectedDisc; // -1 for no disc + +static uint64 Memcard_PrevDC[8]; +static int64 Memcard_SaveDelay[8]; + +PS_CPU *CPU = NULL; +PS_SPU *SPU = NULL; +PS_GPU *GPU = NULL; +PS_CDC *CDC = NULL; +FrontIO *FIO = NULL; + +static MultiAccessSizeMem<512 * 1024, uint32, false> *BIOSROM = NULL; +static MultiAccessSizeMem<65536, uint32, false> *PIOMem = NULL; + +MultiAccessSizeMem<2048 * 1024, uint32, false> MainRAM; + +static uint32 TextMem_Start; +static std::vector TextMem; + +static MultiAccessSizeMem<1024, uint32, false> ScratchRAM; + +static const uint32 SysControl_Mask[9] = { 0x00ffffff, 0x00ffffff, 0xffffffff, 0x2f1fffff, + 0xffffffff, 0x2f1fffff, 0x2f1fffff, 0xffffffff, + 0x0003ffff }; + +static const uint32 SysControl_OR[9] = { 0x1f000000, 0x1f000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000 }; + +static struct +{ + union + { + struct + { + uint32 PIO_Base; // 0x1f801000 // BIOS Init: 0x1f000000, Writeable bits: 0x00ffffff(assumed, verify), FixedOR = 0x1f000000 + uint32 Unknown0; // 0x1f801004 // BIOS Init: 0x1f802000, Writeable bits: 0x00ffffff, FixedOR = 0x1f000000 + uint32 Unknown1; // 0x1f801008 // BIOS Init: 0x0013243f, ???? + uint32 Unknown2; // 0x1f80100c // BIOS Init: 0x00003022, Writeable bits: 0x2f1fffff, FixedOR = 0x00000000 + + uint32 BIOS_Mapping; // 0x1f801010 // BIOS Init: 0x0013243f, ???? + uint32 SPU_Delay; // 0x1f801014 // BIOS Init: 0x200931e1, Writeable bits: 0x2f1fffff, FixedOR = 0x00000000 - Affects bus timing on access to SPU + uint32 CDC_Delay; // 0x1f801018 // BIOS Init: 0x00020843, Writeable bits: 0x2f1fffff, FixedOR = 0x00000000 + uint32 Unknown4; // 0x1f80101c // BIOS Init: 0x00070777, ???? + uint32 Unknown5; // 0x1f801020 // BIOS Init: 0x00031125(but rewritten with other values often), Writeable bits: 0x0003ffff, FixedOR = 0x00000000 -- Possibly CDC related + }; + uint32 Regs[9]; + }; +} SysControl; + + +// +// Event stuff +// +// Comment out this define for extra speeeeed. +#define PSX_EVENT_SYSTEM_CHECKS 1 + +static pscpu_timestamp_t Running; // Set to -1 when not desiring exit, and 0 when we are. + +struct event_list_entry +{ + uint32 which; + pscpu_timestamp_t event_time; + event_list_entry *prev; + event_list_entry *next; +}; + +static event_list_entry events[PSX_EVENT__COUNT]; + +static void EventReset(void) +{ + for(unsigned i = 0; i < PSX_EVENT__COUNT; i++) + { + events[i].which = i; + + if(i == PSX_EVENT__SYNFIRST) + events[i].event_time = 0; + else if(i == PSX_EVENT__SYNLAST) + events[i].event_time = 0x7FFFFFFF; + else + events[i].event_time = PSX_EVENT_MAXTS; + + events[i].prev = (i > 0) ? &events[i - 1] : NULL; + events[i].next = (i < (PSX_EVENT__COUNT - 1)) ? &events[i + 1] : NULL; + } +} + +//static void RemoveEvent(event_list_entry *e) +//{ +// e->prev->next = e->next; +// e->next->prev = e->prev; +//} + +static void RebaseTS(const pscpu_timestamp_t timestamp) +{ + for(unsigned i = 0; i < PSX_EVENT__COUNT; i++) + { + if(i == PSX_EVENT__SYNFIRST || i == PSX_EVENT__SYNLAST) + continue; + + assert(events[i].event_time > timestamp); + events[i].event_time -= timestamp; + } + + CPU->SetEventNT(events[PSX_EVENT__SYNFIRST].next->event_time); +} + +void PSX_SetEventNT(const int type, const pscpu_timestamp_t next_timestamp) +{ + assert(type > PSX_EVENT__SYNFIRST && type < PSX_EVENT__SYNLAST); + event_list_entry *e = &events[type]; + + if(next_timestamp < e->event_time) + { + event_list_entry *fe = e; + + do + { + fe = fe->prev; + } + while(next_timestamp < fe->event_time); + + // Remove this event from the list, temporarily of course. + e->prev->next = e->next; + e->next->prev = e->prev; + + // Insert into the list, just after "fe". + e->prev = fe; + e->next = fe->next; + fe->next->prev = e; + fe->next = e; + + e->event_time = next_timestamp; + } + else if(next_timestamp > e->event_time) + { + event_list_entry *fe = e; + + do + { + fe = fe->next; + } while(next_timestamp > fe->event_time); + + // Remove this event from the list, temporarily of course + e->prev->next = e->next; + e->next->prev = e->prev; + + // Insert into the list, just BEFORE "fe". + e->prev = fe->prev; + e->next = fe; + fe->prev->next = e; + fe->prev = e; + + e->event_time = next_timestamp; + } + + CPU->SetEventNT(events[PSX_EVENT__SYNFIRST].next->event_time & Running); +} + +static void ForceEventUpdates(const pscpu_timestamp_t timestamp) +{ + PSX_SetEventNT(PSX_EVENT_GPU, GPU->Update(timestamp)); + PSX_SetEventNT(PSX_EVENT_CDC, CDC->Update(timestamp)); + + PSX_SetEventNT(PSX_EVENT_TIMER, TIMER_Update(timestamp)); + + PSX_SetEventNT(PSX_EVENT_DMA, DMA_Update(timestamp)); + + PSX_SetEventNT(PSX_EVENT_FIO, FIO->Update(timestamp)); + + CPU->SetEventNT(events[PSX_EVENT__SYNFIRST].next->event_time); +} + +bool MDFN_FASTCALL PSX_EventHandler(const pscpu_timestamp_t timestamp) +{ + event_list_entry *e = events[PSX_EVENT__SYNFIRST].next; +#ifdef PSX_EVENT_SYSTEM_CHECKS + pscpu_timestamp_t prev_event_time = 0; +#endif +#if 0 + { + printf("EventHandler - timestamp=%8d\n", timestamp); + event_list_entry *moo = &events[PSX_EVENT__SYNFIRST]; + while(moo) + { + printf("%u: %8d\n", moo->which, moo->event_time); + moo = moo->next; + } + } +#endif + +#ifdef PSX_EVENT_SYSTEM_CHECKS + assert(Running == 0 || timestamp >= e->event_time); // If Running == 0, our EventHandler +#endif + + while(timestamp >= e->event_time) // If Running = 0, PSX_EventHandler() may be called even if there isn't an event per-se, so while() instead of do { ... } while + { + event_list_entry *prev = e->prev; + pscpu_timestamp_t nt; + +#ifdef PSX_EVENT_SYSTEM_CHECKS + // Sanity test to make sure events are being evaluated in temporal order. + if(e->event_time < prev_event_time) + abort(); + prev_event_time = e->event_time; +#endif + + //printf("Event: %u %8d\n", e->which, e->event_time); +#ifdef PSX_EVENT_SYSTEM_CHECKS + if((timestamp - e->event_time) > 50) + printf("Late: %u %d --- %8d\n", e->which, timestamp - e->event_time, timestamp); +#endif + + switch(e->which) + { + default: abort(); + + case PSX_EVENT_GPU: + nt = GPU->Update(e->event_time); + break; + + case PSX_EVENT_CDC: + nt = CDC->Update(e->event_time); + break; + + case PSX_EVENT_TIMER: + nt = TIMER_Update(e->event_time); + break; + + case PSX_EVENT_DMA: + nt = DMA_Update(e->event_time); + break; + + case PSX_EVENT_FIO: + nt = FIO->Update(e->event_time); + break; + } +#ifdef PSX_EVENT_SYSTEM_CHECKS + assert(nt > e->event_time); +#endif + + PSX_SetEventNT(e->which, nt); + + // Order of events can change due to calling PSX_SetEventNT(), this prev business ensures we don't miss an event due to reordering. + e = prev->next; + } + +#ifdef PSX_EVENT_SYSTEM_CHECKS + for(int i = PSX_EVENT__SYNFIRST + 1; i < PSX_EVENT__SYNLAST; i++) + { + if(timestamp >= events[i].event_time) + { + printf("BUG: %u\n", i); + + event_list_entry *moo = &events[PSX_EVENT__SYNFIRST]; + + while(moo) + { + printf("%u: %8d\n", moo->which, moo->event_time); + moo = moo->next; + } + + abort(); + } + } +#endif + +//#ifdef PSX_EVENT_SYSTEM_CHECKS +// abort(); +//#endif + + return(Running); +} + + +void PSX_RequestMLExit(void) +{ + Running = 0; + CPU->SetEventNT(0); +} + + +// +// End event stuff +// + +void DMA_CheckReadDebug(uint32 A); + +template static INLINE void MemRW(const pscpu_timestamp_t timestamp, uint32 A, uint32 &V) +{ + static const uint32 mask[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x7FFFFFFF, 0x1FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + + //if(IsWrite) + // V = (T)V; + + if(!Peek) + { + #if 0 + if(IsWrite) + printf("Write%d: %08x(orig=%08x), %08x\n", (int)(sizeof(T) * 8), A & mask[A >> 29], A, V); + else + printf("Read%d: %08x(orig=%08x)\n", (int)(sizeof(T) * 8), A & mask[A >> 29], A); + #endif + } + + A &= mask[A >> 29]; + + //if(A == 0xa0 && IsWrite) + // DBG_Break(); + + if(A < 0x00800000) + //if(A <= 0x1FFFFF) + { + //DMA_CheckReadDebug(A); + //assert(A <= 0x1FFFFF); + if(Access24) + { + if(IsWrite) + MainRAM.WriteU24(A & 0x1FFFFF, V); + else + V = MainRAM.ReadU24(A & 0x1FFFFF); + } + else + { + if(IsWrite) + MainRAM.Write(A & 0x1FFFFF, V); + else + V = MainRAM.Read(A & 0x1FFFFF); + } + + return; + } + + if(A >= 0x1F800000 && A <= 0x1F8003FF) + { + if(Access24) + { + if(IsWrite) + ScratchRAM.WriteU24(A & 0x3FF, V); + else + V = ScratchRAM.ReadU24(A & 0x3FF); + } + else + { + if(IsWrite) + ScratchRAM.Write(A & 0x3FF, V); + else + V = ScratchRAM.Read(A & 0x3FF); + } + return; + } + + if(A >= 0x1FC00000 && A <= 0x1FC7FFFF) + { + if(!IsWrite) + { + if(Access24) + V = BIOSROM->ReadU24(A & 0x7FFFF); + else + V = BIOSROM->Read(A & 0x7FFFF); + } + + return; + } + + if(timestamp >= events[PSX_EVENT__SYNFIRST].next->event_time) + PSX_EventHandler(timestamp); + + if(A >= 0x1F801000 && A <= 0x1F802FFF && !Peek) // Hardware register region. (TODO: Implement proper peek suppor) + { +#if 0 + if(!IsWrite) + { + ReadCounter++; + PortReadCounter[A & 0x3FFF]++; + } + else + WriteCounter++; +#endif + + //if(IsWrite) + // printf("HW Write%d: %08x %08x\n", (unsigned int)(sizeof(T)*8), (unsigned int)A, (unsigned int)V); + //else + // printf("HW Read%d: %08x\n", (unsigned int)(sizeof(T)*8), (unsigned int)A); + + if(A >= 0x1F801C00 && A <= 0x1F801FFF) // SPU + { + if(sizeof(T) == 4 && !Access24) + { + if(IsWrite) + { + SPU->Write(timestamp, A | 0, V); + SPU->Write(timestamp, A | 2, V >> 16); + } + else + { + V = SPU->Read(timestamp, A) | (SPU->Read(timestamp, A | 2) << 16); + } + } + else + { + if(IsWrite) + SPU->Write(timestamp, A & ~1, V); + else + V = SPU->Read(timestamp, A & ~1); + } + return; + } // End SPU + + if(A >= 0x1f801800 && A <= 0x1f80180F) + { + if(IsWrite) + CDC->Write(timestamp, A & 0x3, V); + else + V = CDC->Read(timestamp, A & 0x3); + + return; + } + + if(A >= 0x1F801810 && A <= 0x1F801817) + { + if(IsWrite) + GPU->Write(timestamp, A, V); + else + V = GPU->Read(timestamp, A); + + return; + } + + if(A >= 0x1F801820 && A <= 0x1F801827) + { + if(IsWrite) + MDEC_Write(timestamp, A, V); + else + V = MDEC_Read(timestamp, A); + + return; + } + + if(A >= 0x1F801000 && A <= 0x1F801023) + { + unsigned index = (A & 0x1F) >> 2; + + //if(A == 0x1F801014 && IsWrite) + // fprintf(stderr, "%08x %08x\n",A,V); + + if(IsWrite) + { + V <<= (A & 3) * 8; + SysControl.Regs[index] = V & SysControl_Mask[index]; + } + else + { + V = SysControl.Regs[index] | SysControl_OR[index]; + V >>= (A & 3) * 8; + } + return; + } + + if(A >= 0x1F801040 && A <= 0x1F80104F) + { + if(IsWrite) + FIO->Write(timestamp, A, V); + else + V = FIO->Read(timestamp, A); + return; + } + + if(A >= 0x1F801050 && A <= 0x1F80105F) + { + if(IsWrite) + SIO_Write(timestamp, A, V); + else + V = SIO_Read(timestamp, A); + return; + } + +#if 0 + if(A >= 0x1F801060 && A <= 0x1F801063) + { + if(IsWrite) + { + + } + else + { + + } + + return; + } +#endif + + if(A >= 0x1F801070 && A <= 0x1F801077) // IRQ + { + if(IsWrite) + IRQ_Write(A, V); + else + V = IRQ_Read(A); + return; + } + + if(A >= 0x1F801080 && A <= 0x1F8010FF) // DMA + { + if(IsWrite) + DMA_Write(timestamp, A, V); + else + V = DMA_Read(timestamp, A); + + return; + } + + if(A >= 0x1F801100 && A <= 0x1F80112F) // Root counters + { + if(IsWrite) + TIMER_Write(timestamp, A, V); + else + V = TIMER_Read(timestamp, A); + + return; + } + } + + + if(A >= 0x1F000000 && A <= 0x1F7FFFFF) + { + if(!IsWrite) + { + //if((A & 0x7FFFFF) <= 0x84) + // PSX_WARNING("[PIO] Read%d from %08x at time %d", (int)(sizeof(T) * 8), A, timestamp); + + V = 0; + + if((A & 0x7FFFFF) < 65536) + { + if(Access24) + V = PIOMem->ReadU24(A & 0x7FFFFF); + else + V = PIOMem->Read(A & 0x7FFFFF); + } + else if((A & 0x7FFFFF) < (65536 + TextMem.size())) + { + if(Access24) + V = MDFN_de24lsb(&TextMem[(A & 0x7FFFFF) - 65536]); + else switch(sizeof(T)) + { + case 1: V = TextMem[(A & 0x7FFFFF) - 65536]; break; + case 2: V = MDFN_de16lsb(&TextMem[(A & 0x7FFFFF) - 65536]); break; + case 4: V = MDFN_de32lsb(&TextMem[(A & 0x7FFFFF) - 65536]); break; + } + } + } + return; + } + + if(!Peek) + { + if(IsWrite) + { + PSX_WARNING("[MEM] Unknown write%d to %08x at time %d, =%08x(%d)", (int)(sizeof(T) * 8), A, timestamp, V, V); + } + else + { + V = 0; + PSX_WARNING("[MEM] Unknown read%d from %08x at time %d", (int)(sizeof(T) * 8), A, timestamp); + } + } + else + V = 0; + +} + +void MDFN_FASTCALL PSX_MemWrite8(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + MemRW(timestamp, A, V); +} + +void MDFN_FASTCALL PSX_MemWrite16(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + MemRW(timestamp, A, V); +} + +void MDFN_FASTCALL PSX_MemWrite24(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + //assert(0); + MemRW(timestamp, A, V); +} + +void MDFN_FASTCALL PSX_MemWrite32(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + MemRW(timestamp, A, V); +} + +uint8 MDFN_FASTCALL PSX_MemRead8(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 V; + + MemRW(timestamp, A, V); + + return(V); +} + +uint16 MDFN_FASTCALL PSX_MemRead16(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 V; + + MemRW(timestamp, A, V); + + return(V); +} + +uint32 MDFN_FASTCALL PSX_MemRead24(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 V; + + //assert(0); + MemRW(timestamp, A, V); + + return(V); +} + +uint32 MDFN_FASTCALL PSX_MemRead32(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 V; + + MemRW(timestamp, A, V); + + return(V); +} + + +uint8 PSX_MemPeek8(uint32 A) +{ + uint32 V; + + MemRW(0, A, V); + + return(V); +} + +uint16 PSX_MemPeek16(uint32 A) +{ + uint32 V; + + MemRW(0, A, V); + + return(V); +} + +uint32 PSX_MemPeek32(uint32 A) +{ + uint32 V; + + MemRW(0, A, V); + + return(V); +} + +// FIXME: Add PSX_Reset() and FrontIO::Reset() so that emulated input devices don't get power-reset on reset-button reset. +static void PSX_Power(void) +{ + memset(MainRAM.data32, 0, 2048 * 1024); + memset(ScratchRAM.data32, 0, 1024); + + for(unsigned i = 0; i < 9; i++) + SysControl.Regs[i] = 0; + + CPU->Power(); + + EventReset(); + + TIMER_Power(); + + DMA_Power(); + + FIO->Power(); + SIO_Power(); + + MDEC_Power(); + CDC->Power(); + GPU->Power(); + //SPU->Power(); // Called from CDC->Power() + IRQ_Power(); + + ForceEventUpdates(0); +} + + +void PSX_GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock) +{ + FIO->GPULineHook(timestamp, line_timestamp, vsync, pixels, format, width, pix_clock_offset, pix_clock); +} + +} + +using namespace MDFN_IEN_PSX; + + +static void Emulate(EmulateSpecStruct *espec) +{ + pscpu_timestamp_t timestamp = 0; + +#ifdef __LIBRETRO__ + espec->skip = false; +#else + if(FIO->RequireNoFrameskip()) + { + //puts("MEOW"); + espec->skip = false; //TODO: Save here, and restore at end of Emulate() ? + } +#endif + + MDFNGameInfo->mouse_sensitivity = MDFN_GetSettingF("psx.input.mouse_sensitivity"); + + MDFNMP_ApplyPeriodicCheats(); + + + espec->MasterCycles = 0; + espec->SoundBufSize = 0; + + FIO->UpdateInput(); +#ifdef HAVE_PSF + GPU->StartFrame(psf_loader ? NULL : espec); +#else + GPU->StartFrame(espec); +#endif + SPU->StartFrame(espec->SoundRate, MDFN_GetSettingUI("psx.spu.resamp_quality")); + + Running = -1; +#ifdef HAVE_PSF + timestamp = CPU->Run(timestamp, psf_loader != NULL); +#else + timestamp = CPU->Run(timestamp, false); +#endif + + assert(timestamp); + + ForceEventUpdates(timestamp); + if(GPU->GetScanlineNum() < 100) + printf("[BUUUUUUUG] Frame timing end glitch; scanline=%u, st=%u\n", GPU->GetScanlineNum(), timestamp); + + //printf("scanline=%u, st=%u\n", GPU->GetScanlineNum(), timestamp); + + espec->SoundBufSize = SPU->EndFrame(espec->SoundBuf); + + CDC->ResetTS(); + TIMER_ResetTS(); + DMA_ResetTS(); + GPU->ResetTS(); + FIO->ResetTS(); + + RebaseTS(timestamp); + + espec->MasterCycles = timestamp; + +#ifdef HAVE_PSF + if(psf_loader) + { + if(!espec->skip) + { + espec->LineWidths[0].w = ~0; + Player_Draw(espec->surface, &espec->DisplayRect, 0, espec->SoundBuf, espec->SoundBufSize); + } + } +#endif + + // Save memcards if dirty. + for(int i = 0; i < 8; i++) + { + uint64 new_dc = FIO->GetMemcardDirtyCount(i); + + if(new_dc > Memcard_PrevDC[i]) + { + Memcard_PrevDC[i] = new_dc; + Memcard_SaveDelay[i] = 0; + } + + if(Memcard_SaveDelay[i] >= 0) + { + Memcard_SaveDelay[i] += timestamp; + if(Memcard_SaveDelay[i] >= (33868800 * 2)) // Wait until about 2 seconds of no new writes. + { + //fprintf(stderr, "Saving memcard %d...\n", i); + try + { + char ext[64]; + trio_snprintf(ext, sizeof(ext), "%d.mcr", i); + FIO->SaveMemcard(i, MDFN_MakeFName(MDFNMKF_SAV, 0, ext).c_str()); + Memcard_SaveDelay[i] = -1; + Memcard_PrevDC[i] = 0; + } + catch(std::exception &e) + { + MDFN_PrintError("Memcard %d save error: %s", i, e.what()); + MDFN_DispMessage("Memcard %d save error: %s", i, e.what()); + } + //MDFN_DispMessage("Memcard %d saved.", i); + } + } + } + + #if 0 + printf("read=%6d, write=%6d\n", ReadCounter, WriteCounter); + ReadCounter = 0; + WriteCounter = 0; + printf("HW Port reads for this frame:\n"); + for(unsigned i = 0; i < 0x4000; i++) + { + if(PortReadCounter[i] > 100) + printf("0x%08x: %d\n", 0x1f800000 + i, PortReadCounter[i]); + } + memset(PortReadCounter, 0, sizeof(PortReadCounter)); + printf("\n"); + #endif +} + +static bool TestMagic(const char *name, MDFNFILE *fp) +{ +#ifdef HAVE_PSF + if(PSFLoader::TestMagic(0x01, fp)) + return(true); +#endif + + if(fp->size < 0x800) + return(false); + + if(memcmp(fp->data, "PS-X EXE", 8)) + return(false); + + return(true); +} + +static bool TestMagicCD(std::vector *CDInterfaces) +{ + uint8 buf[2048]; + CDUtility::TOC toc; + int dt; + + (*CDInterfaces)[0]->ReadTOC(&toc); + + dt = toc.FindTrackByLBA(4); + if(dt > 0 && !(toc.tracks[dt].control & 0x4)) + return(false); + + if((*CDInterfaces)[0]->ReadSector(buf, 4, 1) != 0x2) + return(false); + + if(strncmp((char *)buf + 10, "Licensed by", strlen("Licensed by"))) + return(false); + + //if(strncmp((char *)buf + 32, "Sony", 4)) + // return(false); + + //for(int i = 0; i < 2048; i++) + // printf("%d, %02x %c\n", i, buf[i], buf[i]); + //exit(1); + + return(true); +} + +static const char *CalcDiscSCEx_BySYSTEMCNF(CDIF *c, unsigned *rr) +{ + const char *ret = NULL; + Stream *fp = NULL; + CDUtility::TOC toc; + + //(*CDInterfaces)[disc]->ReadTOC(&toc); + + //if(toc.first_track > 1 || toc. + + try + { + uint8 pvd[2048]; + unsigned pvd_search_count = 0; + + fp = c->MakeStream(0, ~0U); + fp->seek(0x8000, SEEK_SET); + + do + { + if((pvd_search_count++) == 32) + throw MDFN_Error(0, "PVD search count limit met."); + + fp->read(pvd, 2048); + + if(memcmp(&pvd[1], "CD001", 5)) + throw MDFN_Error(0, "Not ISO-9660"); + + if(pvd[0] == 0xFF) + throw MDFN_Error(0, "Missing Primary Volume Descriptor"); + } while(pvd[0] != 0x01); + //[156 ... 189], 34 bytes + uint32 rdel = MDFN_de32lsb(&pvd[0x9E]); + uint32 rdel_len = MDFN_de32lsb(&pvd[0xA6]); + + if(rdel_len >= (1024 * 1024 * 10)) // Arbitrary sanity check. + throw MDFN_Error(0, "Root directory table too large"); + + fp->seek((int64)rdel * 2048, SEEK_SET); + //printf("%08x, %08x\n", rdel * 2048, rdel_len); + while(fp->tell() < (((int64)rdel * 2048) + rdel_len)) + { + uint8 len_dr = fp->get_u8(); + uint8 dr[256 + 1]; + + memset(dr, 0xFF, sizeof(dr)); + + if(!len_dr) + break; + + memset(dr, 0, sizeof(dr)); + dr[0] = len_dr; + fp->read(dr + 1, len_dr - 1); + + uint8 len_fi = dr[0x20]; + + if(len_fi == 12 && !memcmp(&dr[0x21], "SYSTEM.CNF;1", 12)) + { + uint32 file_lba = MDFN_de32lsb(&dr[0x02]); + //uint32 file_len = MDFN_de32lsb(&dr[0x0A]); + uint8 fb[2048 + 1]; + char *bootpos; + + memset(fb, 0, sizeof(fb)); + fp->seek(file_lba * 2048, SEEK_SET); + fp->read(fb, 2048); + + bootpos = strstr((char*)fb, "BOOT") + 4; + while(*bootpos == ' ' || *bootpos == '\t') bootpos++; + if(*bootpos == '=') + { + bootpos++; + while(*bootpos == ' ' || *bootpos == '\t') bootpos++; + if(!strncasecmp(bootpos, "cdrom:\\", 7)) + { + bootpos += 7; + char *tmp; + + if((tmp = strchr(bootpos, '_'))) *tmp = 0; + if((tmp = strchr(bootpos, '.'))) *tmp = 0; + if((tmp = strchr(bootpos, ';'))) *tmp = 0; + //puts(bootpos); + + if(strlen(bootpos) == 4 && bootpos[0] == 'S' && (bootpos[1] == 'C' || bootpos[1] == 'L' || bootpos[1] == 'I')) + { + switch(bootpos[2]) + { + case 'E': if(rr) + *rr = REGION_EU; + ret = "SCEE"; + goto Breakout; + + case 'U': if(rr) + *rr = REGION_NA; + ret = "SCEA"; + goto Breakout; + + case 'K': // Korea? + case 'B': + case 'P': if(rr) + *rr = REGION_JP; + ret = "SCEI"; + goto Breakout; + } + } + } + } + + //puts((char*)fb); + //puts("ASOFKOASDFKO"); + } + } + } + catch(std::exception &e) + { + //puts(e.what()); + } + catch(...) + { + + } + + Breakout: + if(fp != NULL) + { + delete fp; + fp = NULL; + } + + return(ret); +} + +static unsigned CalcDiscSCEx(void) +{ + const char *prev_valid_id = NULL; + unsigned ret_region = MDFN_GetSettingI("psx.region_default"); + + cdifs_scex_ids.clear(); + +if(cdifs) + for(unsigned i = 0; i < cdifs->size(); i++) + { + const char *id = NULL; + uint8 buf[2048]; + uint8 fbuf[2048 + 1]; + unsigned ipos, opos; + + + id = CalcDiscSCEx_BySYSTEMCNF((*cdifs)[i], (i == 0) ? &ret_region : NULL); + + memset(fbuf, 0, sizeof(fbuf)); + + if(id == NULL && (*cdifs)[i]->ReadSector(buf, 4, 1) == 0x2) + { + for(ipos = 0, opos = 0; ipos < 0x48; ipos++) + { + if(buf[ipos] > 0x20 && buf[ipos] < 0x80) + { + fbuf[opos++] = tolower(buf[ipos]); + } + } + + fbuf[opos++] = 0; + + puts((char *)fbuf); + + if(strstr((char *)fbuf, "licensedby") != NULL) + { + if(strstr((char *)fbuf, "america") != NULL) + { + id = "SCEA"; + if(!i) + ret_region = REGION_NA; + } + else if(strstr((char *)fbuf, "europe") != NULL) + { + id = "SCEE"; + if(!i) + ret_region = REGION_EU; + } + else if(strstr((char *)fbuf, "japan") != NULL) + { + id = "SCEI"; // ? + if(!i) + ret_region = REGION_JP; + } + else if(strstr((char *)fbuf, "sonycomputerentertainmentinc.") != NULL) + { + id = "SCEI"; + if(!i) + ret_region = REGION_JP; + } + else // Failure case + { + if(prev_valid_id != NULL) + id = prev_valid_id; + else + { + switch(ret_region) // Less than correct, but meh, what can we do. + { + case REGION_JP: + id = "SCEI"; + break; + + case REGION_NA: + id = "SCEA"; + break; + + case REGION_EU: + id = "SCEE"; + break; + } + } + } + } + } + + if(id != NULL) + prev_valid_id = id; + + cdifs_scex_ids.push_back(id); + } + + return ret_region; +} + +static bool InitCommon(std::vector *CDInterfaces, const bool EmulateMemcards = true) +{ + unsigned region; + bool emulate_memcard[8]; + bool emulate_multitap[2]; + + for(unsigned i = 0; i < 8; i++) + { + char buf[64]; + trio_snprintf(buf, sizeof(buf), "psx.input.port%u.memcard", i + 1); + emulate_memcard[i] = EmulateMemcards && MDFN_GetSettingB(buf); + } + + for(unsigned i = 0; i < 2; i++) + { + char buf[64]; + trio_snprintf(buf, sizeof(buf), "psx.input.port%u.multitap", i + 1); + emulate_multitap[i] = MDFN_GetSettingB(buf); + } + + + cdifs = CDInterfaces; + region = CalcDiscSCEx(); + + if(!MDFN_GetSettingB("psx.region_autodetect")) + region = MDFN_GetSettingI("psx.region_default"); + + CPU = new PS_CPU(); + SPU = new PS_SPU(); + GPU = new PS_GPU(region == REGION_EU); + CDC = new PS_CDC(); + FIO = new FrontIO(emulate_memcard, emulate_multitap); + FIO->SetAMCT(MDFN_GetSettingB("psx.input.analog_mode_ct")); + for(unsigned i = 0; i < 8; i++) + { + char buf[64]; + trio_snprintf(buf, sizeof(buf), "psx.input.port%u.gun_chairs", i + 1); + FIO->SetCrosshairsColor(i, MDFN_GetSettingUI(buf)); + } + + DMA_Init(); + + if(region == REGION_EU) + { + EmulatedPSX.nominal_width = 367; // Dunno. :( + EmulatedPSX.nominal_height = 288; + + EmulatedPSX.fb_width = 768; + EmulatedPSX.fb_height = 576; + } + else + { + EmulatedPSX.lcm_width = 2720; + EmulatedPSX.lcm_height = 480; + + EmulatedPSX.nominal_width = 310; + EmulatedPSX.nominal_height = 240; + + EmulatedPSX.fb_width = 768; + EmulatedPSX.fb_height = 480; + } + + if(cdifs) + { + CD_TrayOpen = false; + CD_SelectedDisc = 0; + } + else + { + CD_TrayOpen = true; + CD_SelectedDisc = -1; + } + + CDC->SetDisc(true, NULL, NULL); + CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL, + (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL); + + + BIOSROM = new MultiAccessSizeMem<512 * 1024, uint32, false>(); + PIOMem = new MultiAccessSizeMem<65536, uint32, false>(); + + for(uint32 ma = 0x00000000; ma < 0x00800000; ma += 2048 * 1024) + { + CPU->SetFastMap(MainRAM.data32, 0x00000000 + ma, 2048 * 1024); + CPU->SetFastMap(MainRAM.data32, 0x80000000 + ma, 2048 * 1024); + CPU->SetFastMap(MainRAM.data32, 0xA0000000 + ma, 2048 * 1024); + } + + CPU->SetFastMap(BIOSROM->data32, 0x1FC00000, 512 * 1024); + CPU->SetFastMap(BIOSROM->data32, 0x9FC00000, 512 * 1024); + CPU->SetFastMap(BIOSROM->data32, 0xBFC00000, 512 * 1024); + + CPU->SetFastMap(PIOMem->data32, 0x1F000000, 65536); + CPU->SetFastMap(PIOMem->data32, 0x9F000000, 65536); + CPU->SetFastMap(PIOMem->data32, 0xBF000000, 65536); + + + MDFNMP_Init(1024, ((uint64)1 << 29) / 1024); + MDFNMP_AddRAM(2048 * 1024, 0x00000000, MainRAM.data8); + MDFNMP_AddRAM(1024, 0x1F800000, ScratchRAM.data8); + + try + { + const char *biospath_sname; + std::string biospath; + + if(region == REGION_JP) + biospath_sname = "psx.bios_jp"; + else if(region == REGION_EU) + biospath_sname = "psx.bios_eu"; + else if(region == REGION_NA) + biospath_sname = "psx.bios_na"; + else + abort(); + + biospath = MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS(biospath_sname).c_str()); + + FileWrapper BIOSFile(biospath.c_str(), FileWrapper::MODE_READ); + + BIOSFile.read(BIOSROM->data8, 512 * 1024); + + for(int i = 0; i < 8; i++) + { + char ext[64]; + trio_snprintf(ext, sizeof(ext), "%d.mcr", i); + FIO->LoadMemcard(i, MDFN_MakeFName(MDFNMKF_SAV, 0, ext).c_str()); + } + } + catch(std::exception &e) + { + MDFN_PrintError("%s", e.what()); + return(false); + } + + for(int i = 0; i < 8; i++) + { + Memcard_PrevDC[i] = FIO->GetMemcardDirtyCount(i); + Memcard_SaveDelay[i] = -1; + } + + + #ifdef WANT_DEBUGGER + DBG_Init(); + #endif + + PSX_Power(); + + return(true); +} + +static void LoadEXE(const uint8 *data, const uint32 size, bool ignore_pcsp = false) +{ + uint32 PC; + uint32 SP; + uint32 TextStart; + uint32 TextSize; + + if(size < 0x800) + throw(MDFN_Error(0, "PS-EXE is too small.")); + + PC = MDFN_de32lsb(&data[0x10]); + SP = MDFN_de32lsb(&data[0x30]); + TextStart = MDFN_de32lsb(&data[0x18]); + TextSize = MDFN_de32lsb(&data[0x1C]); + + printf("PC=0x%08x\nTextStart=0x%08x\nTextSize=0x%08x\nSP=0x%08x\n", PC, TextStart, TextSize, SP); + + TextStart &= 0x1FFFFF; + + if(TextSize > 2048 * 1024) + { + throw(MDFN_Error(0, "Text section too large")); + } + + if(TextSize > (size - 0x800)) + throw(MDFN_Error(0, "Text section recorded size is larger than data available in file. Header=0x%08x, Available=0x%08x", TextSize, size - 0x800)); + + if(TextSize < (size - 0x800)) + throw(MDFN_Error(0, "Text section recorded size is smaller than data available in file. Header=0x%08x, Available=0x%08x", TextSize, size - 0x800)); + + if(!TextMem.size()) + { + TextMem_Start = TextStart; + TextMem.resize(TextSize); + } + + if(TextStart < TextMem_Start) + { + uint32 old_size = TextMem.size(); + + printf("RESIZE: 0x%08x\n", TextMem_Start - TextStart); + + TextMem.resize(old_size + TextMem_Start - TextStart); + memmove(&TextMem[TextMem_Start - TextStart], &TextMem[0], old_size); + + TextMem_Start = TextStart; + } + + if(TextMem.size() < (TextStart - TextMem_Start + TextSize)) + TextMem.resize(TextStart - TextMem_Start + TextSize); + + memcpy(&TextMem[TextStart - TextMem_Start], data + 0x800, TextSize); + + + // + // + // + + // BIOS patch + BIOSROM->WriteU32(0x6990, (3 << 26) | ((0xBF001000 >> 2) & ((1 << 26) - 1))); +// BIOSROM->WriteU32(0x691C, (3 << 26) | ((0xBF001000 >> 2) & ((1 << 26) - 1))); + +// printf("INSN: 0x%08x\n", BIOSROM->ReadU32(0x6990)); +// exit(1); + uint8 *po; + + po = &PIOMem->data8[0x0800]; + + MDFN_en32lsb(po, (0x0 << 26) | (31 << 21) | (0x8 << 0)); // JR + po += 4; + MDFN_en32lsb(po, 0); // NOP(kinda) + po += 4; + + po = &PIOMem->data8[0x1000]; + // Load source address into r8 + uint32 sa = 0x9F000000 + 65536; + MDFN_en32lsb(po, (0xF << 26) | (0 << 21) | (1 << 16) | (sa >> 16)); // LUI + po += 4; + MDFN_en32lsb(po, (0xD << 26) | (1 << 21) | (8 << 16) | (sa & 0xFFFF)); // ORI + po += 4; + + // Load dest address into r9 + MDFN_en32lsb(po, (0xF << 26) | (0 << 21) | (1 << 16) | (TextMem_Start >> 16)); // LUI + po += 4; + MDFN_en32lsb(po, (0xD << 26) | (1 << 21) | (9 << 16) | (TextMem_Start & 0xFFFF)); // ORI + po += 4; + + // Load size into r10 + MDFN_en32lsb(po, (0xF << 26) | (0 << 21) | (1 << 16) | (TextMem.size() >> 16)); // LUI + po += 4; + MDFN_en32lsb(po, (0xD << 26) | (1 << 21) | (10 << 16) | (TextMem.size() & 0xFFFF)); // ORI + po += 4; + + // + // Loop begin + // + + MDFN_en32lsb(po, (0x24 << 26) | (8 << 21) | (1 << 16)); // LBU to r1 + po += 4; + MDFN_en32lsb(po, 0); po += 4; // NOP + + MDFN_en32lsb(po, (0x28 << 26) | (9 << 21) | (1 << 16)); // SB from r1 + po += 4; + MDFN_en32lsb(po, 0); po += 4; // NOP + + MDFN_en32lsb(po, (0x08 << 26) | (10 << 21) | (10 << 16) | 0xFFFF); // Decrement size + po += 4; + + MDFN_en32lsb(po, (0x08 << 26) | (8 << 21) | (8 << 16) | 0x0001); // Increment source addr + po += 4; + + MDFN_en32lsb(po, (0x08 << 26) | (9 << 21) | (9 << 16) | 0x0001); // Increment dest addr + po += 4; + + MDFN_en32lsb(po, (0x05 << 26) | (0 << 21) | (10 << 16) | (-8 & 0xFFFF)); + po += 4; + MDFN_en32lsb(po, 0); po += 4; // NOP + + // + // Loop end + // + + // Load SP into r29 + if(ignore_pcsp) + { + po += 16; + } + else + { + printf("MEOWPC: %08x\n", PC); + MDFN_en32lsb(po, (0xF << 26) | (0 << 21) | (1 << 16) | (SP >> 16)); // LUI + po += 4; + MDFN_en32lsb(po, (0xD << 26) | (1 << 21) | (29 << 16) | (SP & 0xFFFF)); // ORI + po += 4; + + // Load PC into r2 + MDFN_en32lsb(po, (0xF << 26) | (0 << 21) | (1 << 16) | ((PC >> 16) | 0x8000)); // LUI + po += 4; + MDFN_en32lsb(po, (0xD << 26) | (1 << 21) | (2 << 16) | (PC & 0xFFFF)); // ORI + po += 4; + } + + // Jump to r2 + MDFN_en32lsb(po, (0x0 << 26) | (2 << 21) | (0x8 << 0)); // JR + po += 4; + MDFN_en32lsb(po, 0); // NOP(kinda) + po += 4; + +} + +#ifdef HAVE_PSF +PSF1Loader::PSF1Loader(MDFNFILE *fp) +{ + tags = Load(0x01, 2033664, fp); +} + +PSF1Loader::~PSF1Loader() +{ + +} + +void PSF1Loader::HandleEXE(const uint8 *data, uint32 size, bool ignore_pcsp) +{ + LoadEXE(data, size, ignore_pcsp); +} +#endif + +static void Cleanup(void); +static int Load(const char *name, MDFNFILE *fp) +{ +#ifdef HAVE_PSF + const bool IsPSF = PSFLoader::TestMagic(0x01, fp); +#else + const bool IsPSF = false; +#endif + + if(!TestMagic(name, fp)) + { + MDFN_PrintError(_("File format is unknown to module \"%s\"."), MDFNGameInfo->shortname); + return(0); + } + +// For testing. +#if 0 + #warning "GREMLINS GREMLINS EVERYWHEREE IYEEEEEE" + #warning "Seriously, GREMLINS! Or peanut butter. Or maybe...DINOSAURS." + + static std::vector CDInterfaces; + + CDInterfaces.push_back(new CDIF_MT("/extra/games/PSX/Jumping Flash! (USA)/Jumping Flash! (USA).cue")); + //CDInterfaces.push_back(new CDIF("/extra/games/PSX/Tony Hawk's Pro Skater 2 (USA)/Tony Hawk's Pro Skater 2 (USA).cue")); + + if(!InitCommon(&CDInterfaces, !IsPSF)) + return(0); +#else + if(!InitCommon(NULL, !IsPSF)) + return(0); +#endif + + TextMem.resize(0); + + try + { +#ifdef HAVE_PSF + if(IsPSF) + { + psf_loader = new PSF1Loader(fp); + + std::vector SongNames; + + SongNames.push_back(psf_loader->tags.GetTag("title")); + + Player_Init(1, psf_loader->tags.GetTag("game"), psf_loader->tags.GetTag("artist"), psf_loader->tags.GetTag("copyright"), SongNames); + } + else +#endif + LoadEXE(fp->data, fp->size); + } + catch(std::exception &e) + { + MDFND_PrintError(e.what()); + Cleanup(); + return 0; + } + + return(1); +} + +static int LoadCD(std::vector *CDInterfaces) +{ + int ret = InitCommon(CDInterfaces); + + // TODO: fastboot setting + if(MDFN_GetSettingB("psx.fastboot")) + BIOSROM->WriteU32(0x6990, 0); + + MDFNGameInfo->GameType = GMT_CDROM; + + return(ret); +} + +static void Cleanup(void) +{ + TextMem.resize(0); + +#ifdef HAVE_PSF + if(psf_loader) + { + delete psf_loader; + psf_loader = NULL; + } +#endif + + if(CDC) + { + delete CDC; + CDC = NULL; + } + + if(SPU) + { + delete SPU; + SPU = NULL; + } + + if(GPU) + { + delete GPU; + GPU = NULL; + } + + if(CPU) + { + delete CPU; + CPU = NULL; + } + + if(FIO) + { + delete FIO; + FIO = NULL; + } + + DMA_Kill(); + + if(BIOSROM) + { + delete BIOSROM; + BIOSROM = NULL; + } + + if(PIOMem) + { + delete PIOMem; + PIOMem = NULL; + } + + cdifs = NULL; +} + +static void CloseGame(void) +{ +#ifdef HAVE_PSF + if(!psf_loader) +#endif + { + for(int i = 0; i < 8; i++) + { + // If there's an error saving one memcard, don't skip trying to save the other, since it might succeed and + // we can reduce potential data loss! + try + { + char ext[64]; + trio_snprintf(ext, sizeof(ext), "%d.mcr", i); + + FIO->SaveMemcard(i, MDFN_MakeFName(MDFNMKF_SAV, 0, ext).c_str()); + } + catch(std::exception &e) + { + MDFN_PrintError("%s", e.what()); + } + } + } + + Cleanup(); +} + + +static void SetInput(int port, const char *type, void *ptr) +{ +#ifdef HAVE_PSF + if(psf_loader) + FIO->SetInput(port, "none", NULL); + else +#endif + FIO->SetInput(port, type, ptr); +} + +static int StateAction(StateMem *sm, int load, int data_only) +{ + return(0); + SFORMAT StateRegs[] = + { + SFVAR(CD_TrayOpen), + SFVAR(CD_SelectedDisc), + SFARRAY(MainRAM.data8, 1024 * 2048), + SFARRAY(ScratchRAM.data8, 1024), + SFARRAY32(SysControl.Regs, 9), + //SFARRAY32(next_timestamps, sizeof(next_timestamps) / sizeof(next_timestamps[0])), + SFEND + }; + + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "MAIN"); + + // Call SetDisc() BEFORE we load CDC state, since SetDisc() has emulation side effects. We might want to clean this up in the future. + if(load) + { + CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL, + (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL); + } + + // TODO: Remember to increment dirty count in memory card state loading routine. + + ret &= CPU->StateAction(sm, load, data_only); + ret &= DMA_StateAction(sm, load, data_only); + ret &= TIMER_StateAction(sm, load, data_only); + ret &= CDC->StateAction(sm, load, data_only); + ret &= MDEC_StateAction(sm, load, data_only); + ret &= SPU->StateAction(sm, load, data_only); + //ret &= FIO->StateAction(sm, load, data_only); + //ret &= GPU->StateAction(sm, load, data_only); + ret &= IRQ_StateAction(sm, load, data_only); + + if(load) + { + + } + + return(ret); +} + +static void CDInsertEject(void) +{ + CD_TrayOpen = !CD_TrayOpen; + + for(unsigned disc = 0; disc < cdifs->size(); disc++) + { + if(!(*cdifs)[disc]->Eject(CD_TrayOpen)) + { + MDFN_DispMessage(_("Eject error.")); + CD_TrayOpen = !CD_TrayOpen; + } + } + + if(CD_TrayOpen) + MDFN_DispMessage(_("Virtual CD Drive Tray Open")); + else + MDFN_DispMessage(_("Virtual CD Drive Tray Closed")); + + CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL, + (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL); +} + +static void CDEject(void) +{ + if(!CD_TrayOpen) + CDInsertEject(); +} + +static void CDSelect(void) +{ + if(cdifs && CD_TrayOpen) + { + CD_SelectedDisc = (CD_SelectedDisc + 1) % (cdifs->size() + 1); + + if((unsigned)CD_SelectedDisc == cdifs->size()) + CD_SelectedDisc = -1; + + if(CD_SelectedDisc == -1) + MDFN_DispMessage(_("Disc absence selected.")); + else + MDFN_DispMessage(_("Disc %d of %d selected."), CD_SelectedDisc + 1, (int)cdifs->size()); + } +} + + +static void DoSimpleCommand(int cmd) +{ + switch(cmd) + { + case MDFN_MSC_RESET: PSX_Power(); break; + case MDFN_MSC_POWER: PSX_Power(); break; + + case MDFN_MSC_INSERT_DISK: + CDInsertEject(); + break; + + case MDFN_MSC_SELECT_DISK: + CDSelect(); + break; + + case MDFN_MSC_EJECT_DISK: + CDEject(); + break; + } +} + + +static const FileExtensionSpecStruct KnownExtensions[] = +{ +#ifdef HAVE_PSF + { ".psf", gettext_noop("PSF1 Rip") }, + { ".minipsf", gettext_noop("MiniPSF1 Rip") }, +#endif + { ".psx", gettext_noop("PS-X Executable") }, + { ".exe", gettext_noop("PS-X Executable") }, + { NULL, NULL } +}; + +static const MDFNSetting_EnumList Region_List[] = +{ + { "jp", REGION_JP, gettext_noop("Japan") }, + { "na", REGION_NA, gettext_noop("North America") }, + { "eu", REGION_EU, gettext_noop("Europe") }, + { NULL, 0 }, +}; + +static MDFNSetting PSXSettings[] = +{ + { "psx.input.mouse_sensitivity", MDFNSF_NOFLAGS, gettext_noop("Emulated mouse sensitivity."), NULL, MDFNST_FLOAT, "1.00", NULL, NULL }, + + { "psx.input.analog_mode_ct", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Enable analog mode combo-button alternate toggle."), gettext_noop("When enabled, instead of the configured Analog mode toggle button for the emulated DualShock, use a combination of buttons to toggle it instead. When Select, Start, and all four shoulder buttons are held down for about 1 second, the mode will toggle."), MDFNST_BOOL, "0", NULL, NULL }, + + { "psx.input.port1.multitap", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Enable multitap on PSX port 1."), gettext_noop("Makes ports 1B-1D available."), MDFNST_BOOL, "0", NULL, NULL }, + { "psx.input.port2.multitap", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Enable multitap on PSX port 2."), gettext_noop("Makes ports 2B-2D available."), MDFNST_BOOL, "0", NULL, NULL }, + + { "psx.input.port1.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 1/1A."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port2.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 2/2A."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port3.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 1B."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port4.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 1C."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port5.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 1D."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port6.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 2B."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port7.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 2C."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + { "psx.input.port8.memcard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulate memcard on port 2D."), NULL, MDFNST_BOOL, "1", NULL, NULL, }, + + + { "psx.input.port1.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 1/1A."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0xFF0000", "0x000000", "0x1000000" }, + { "psx.input.port2.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 2/2A."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0x00FF00", "0x000000", "0x1000000" }, + { "psx.input.port3.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 1B."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0xFF00FF", "0x000000", "0x1000000" }, + { "psx.input.port4.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 1C."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0xFF8000", "0x000000", "0x1000000" }, + { "psx.input.port5.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 1D."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0xFFFF00", "0x000000", "0x1000000" }, + { "psx.input.port6.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 2B."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0x00FFFF", "0x000000", "0x1000000" }, + { "psx.input.port7.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 2C."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0x0080FF", "0x000000", "0x1000000" }, + { "psx.input.port8.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 2D."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0x8000FF", "0x000000", "0x1000000" }, + + { "psx.fastboot", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Skip BIOS intro sequence."), gettext_noop("MAY BREAK GAMES."), MDFNST_BOOL, "0" }, + { "psx.region_autodetect", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Attempt to auto-detect region of game."), NULL, MDFNST_BOOL, "1" }, + { "psx.region_default", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Default region to use."), gettext_noop("Used if region autodetection fails or is disabled."), MDFNST_ENUM, "jp", NULL, NULL, NULL, NULL, Region_List }, + + { "psx.bios_jp", MDFNSF_EMU_STATE, gettext_noop("Path to the Japan SCPH-5500 ROM BIOS"), NULL, MDFNST_STRING, "scph5500.bin" }, + { "psx.bios_na", MDFNSF_EMU_STATE, gettext_noop("Path to the North America SCPH-5501 ROM BIOS"), gettext_noop("SHA1 0555c6fae8906f3f09baf5988f00e55f88e9f30b"), MDFNST_STRING, "scph5501.bin" }, + { "psx.bios_eu", MDFNSF_EMU_STATE, gettext_noop("Path to the Europe SCPH-5502 ROM BIOS"), NULL, MDFNST_STRING, "scph5502.bin" }, + + { "psx.spu.resamp_quality", MDFNSF_NOFLAGS, gettext_noop("SPU output resampler quality."), + gettext_noop("0 is lowest quality and CPU usage, 10 is highest quality and CPU usage. The resampler that this setting refers to is used for converting from 44.1KHz to the sampling rate of the host audio device Mednafen is using. Changing Mednafen's output rate, via the \"sound.rate\" setting, to \"44100\" will bypass the resampler, which will decrease CPU usage by Mednafen, and can increase or decrease audio quality, depending on various operating system and hardware factors."), MDFNST_UINT, "5", "0", "10" }, + { NULL }, +}; + +// Note for the future: If we ever support PSX emulation with non-8-bit RGB color components, or add a new linear RGB colorspace to MDFN_PixelFormat, we'll need +// to buffer the intermediate 24-bit non-linear RGB calculation into an array and pass that into the GPULineHook stuff, otherwise netplay could break when +// an emulated GunCon is used. This IS assuming, of course, that we ever implement save state support so that netplay actually works at all... +MDFNGI EmulatedPSX = +{ + "psx", + "Sony PlayStation", + KnownExtensions, + MODPRIO_INTERNAL_HIGH, + #ifdef WANT_DEBUGGER + &PSX_DBGInfo, + #else + NULL, + #endif + &FIO_InputInfo, + Load, + TestMagic, + LoadCD, + TestMagicCD, + CloseGame, + NULL, //ToggleLayer, + "GPU\0", //"Background Scroll\0Foreground Scroll\0Sprites\0", + NULL, + NULL, + NULL, + NULL, + NULL, + false, + StateAction, + Emulate, + SetInput, + DoSimpleCommand, + PSXSettings, + MDFN_MASTERCLOCK_FIXED(33868800), + 0, + + true, // Multires possible? + + // + // Note: Following video settings will be overwritten during game load. + // + 0, // lcm_width + 0, // lcm_height + NULL, // Dummy + + 310, // Nominal width + 240, // Nominal height + + 0, // Framebuffer width + 0, // Framebuffer height + // + // + // + + 2, // Number of output sound channels + +}; diff --git a/mednafen/psx-0925/psx.h b/mednafen/psx-0925/psx.h new file mode 100644 index 00000000..c197bd4d --- /dev/null +++ b/mednafen/psx-0925/psx.h @@ -0,0 +1,87 @@ +#ifndef __MDFN_PSX_PSX_H +#define __MDFN_PSX_PSX_H + +#include +#include +#include + +#include "../cdrom/cdromif.h" +#include "../general.h" +#include "../FileWrapper.h" + +//#define PSX_WARNING(format, ...) { printf(format "\n", ## __VA_ARGS__); } +//#define PSX_DBGINFO(format, ...) { /*printf(format "\n", ## __VA_ARGS__);*/ } +#define PSX_WARNING(format, ...) +#define PSX_DBGINFO(format, ...) + +namespace MDFN_IEN_PSX +{ + typedef int32 pscpu_timestamp_t; + + bool MDFN_FASTCALL PSX_EventHandler(const pscpu_timestamp_t timestamp); + + void MDFN_FASTCALL PSX_MemWrite8(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); + void MDFN_FASTCALL PSX_MemWrite16(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); + void MDFN_FASTCALL PSX_MemWrite24(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); + void MDFN_FASTCALL PSX_MemWrite32(const pscpu_timestamp_t timestamp, uint32 A, uint32 V); + + uint8 MDFN_FASTCALL PSX_MemRead8(const pscpu_timestamp_t timestamp, uint32 A); + uint16 MDFN_FASTCALL PSX_MemRead16(const pscpu_timestamp_t timestamp, uint32 A); + uint32 MDFN_FASTCALL PSX_MemRead24(const pscpu_timestamp_t timestamp, uint32 A); + uint32 MDFN_FASTCALL PSX_MemRead32(const pscpu_timestamp_t timestamp, uint32 A); + + uint8 PSX_MemPeek8(uint32 A); + uint16 PSX_MemPeek16(uint32 A); + uint32 PSX_MemPeek32(uint32 A); + + // Should write to WO-locations if possible + #if 0 + void PSX_MemPoke8(uint32 A, uint8 V); + void PSX_MemPoke16(uint32 A, uint16 V); + void PSX_MemPoke32(uint32 A, uint32 V); + #endif + + void PSX_RequestMLExit(void); + + enum + { + PSX_EVENT__SYNFIRST = 0, + PSX_EVENT_GPU, + PSX_EVENT_CDC, + //PSX_EVENT_SPU, + PSX_EVENT_TIMER, + PSX_EVENT_DMA, + PSX_EVENT_FIO, + PSX_EVENT__SYNLAST, + PSX_EVENT__COUNT, + }; + + #define PSX_EVENT_MAXTS 0x20000000 + void PSX_SetEventNT(const int type, const pscpu_timestamp_t next_timestamp); + + void PSX_GPULineHook(const pscpu_timestamp_t timestamp, const pscpu_timestamp_t line_timestamp, bool vsync, uint32 *pixels, const MDFN_PixelFormat* const format, const unsigned width, const unsigned pix_clock_offset, const unsigned pix_clock); +}; + + +#include "dis.h" +#include "cpu.h" +#include "irq.h" +#include "gpu.h" +#include "dma.h" +//#include "sio.h" +#include "debug.h" + +namespace MDFN_IEN_PSX +{ + class PS_CDC; + class PS_SPU; + + extern PS_CPU *CPU; + extern PS_GPU *GPU; + extern PS_CDC *CDC; + extern PS_SPU *SPU; + extern MultiAccessSizeMem<2048 * 1024, uint32, false> MainRAM; +}; + + +#endif diff --git a/mednafen/psx-0925/sio.cpp b/mednafen/psx-0925/sio.cpp new file mode 100644 index 00000000..59595ec6 --- /dev/null +++ b/mednafen/psx-0925/sio.cpp @@ -0,0 +1,106 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "sio.h" + +namespace MDFN_IEN_PSX +{ + +// Dummy implementation. + +static uint16 Status; +static uint16 Mode; +static uint16 Control; +static uint16 BaudRate; +static uint32 DataBuffer; + +void SIO_Power(void) +{ + Status = 0; + Mode = 0; + Control = 0; + BaudRate = 0; + DataBuffer = 0; +} + +uint32 SIO_Read(pscpu_timestamp_t timestamp, uint32 A) +{ + uint32 ret = 0; + + switch(A & 0xE) + { + default: + PSX_WARNING("[SIO] Unknown read: 0x%08x -- %d\n", A, timestamp); + break; + + case 0x0: + //case 0x2: + ret = DataBuffer >> ((A & 2) * 8); + break; + + case 0x4: + ret = Status; + break; + + case 0x8: + ret = Mode; + break; + + case 0xA: + ret = Control; + break; + + case 0xE: + ret = BaudRate; + break; + } + + return(ret >> ((A & 1) * 8)); +} + +void SIO_Write(pscpu_timestamp_t timestamp, uint32 A, uint32 V) +{ + V <<= (A & 1) * 8; + + switch(A & 0xE) + { + default: + PSX_WARNING("[SIO] Unknown write: 0x%08x 0x%08x -- %d\n", A, V, timestamp); + break; + + case 0x0: + //case 0x2: + V <<= (A & 2) * 8; + DataBuffer = V; + break; + + case 0x8: + Mode = V; + break; + + case 0xA: + Control = V; + break; + + case 0xE: + BaudRate = V; + break; + } +} + +} diff --git a/mednafen/psx-0925/sio.h b/mednafen/psx-0925/sio.h new file mode 100644 index 00000000..1dddecca --- /dev/null +++ b/mednafen/psx-0925/sio.h @@ -0,0 +1,13 @@ +#ifndef __MDFN_PSX_SIO_H +#define __MDFN_PSX_SIO_H + +namespace MDFN_IEN_PSX +{ + +void SIO_Write(pscpu_timestamp_t timestamp, uint32 A, uint32 V); +uint32 SIO_Read(pscpu_timestamp_t timestamp, uint32 A); +void SIO_Power(void); + +} + +#endif diff --git a/mednafen/psx-0925/spu.cpp b/mednafen/psx-0925/spu.cpp new file mode 100644 index 00000000..4eaa54fa --- /dev/null +++ b/mednafen/psx-0925/spu.cpp @@ -0,0 +1,1565 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* TODO: + Note to self: Emulating the SPU at more timing accuracy than sample, and emulating the whole SPU RAM write port FIFO thing and hypothetical periodic FIFO commit to + SPU RAM(maybe every 32 CPU cycles, with exceptions?) will likely necessitate a much more timing-accurate CPU core, and emulation of the SPU delay register(or at least the + effects of the standard value written to it), to avoid game glitches. Probably more trouble than it's worth.... + + SPU IRQ emulation isn't totally correct, behavior is kind of complex; run more tests on PS1. + + Test reverb upsampler on the real thing. + + Alter reverb algorithm to process in the pattern of L,R,L,R,L,R on each input sample, instead of doing both L and R on every 2 input samples(make + sure the real thing does it this way too, I think it at least runs the downsampler this way); and while we're at it, implement the correct buffer + offset(probably either -39 or -40, the latter is what we have now). + + Alter reverb algorithm to perform saturation more often, as occurs on the real thing. + + See if sample flag & 0x8 does anything weird, like suppressing the program-readable block end flag setting. + + Determine the actual purpose of global register 0x2C(is it REALLY an address multiplier? And if so, does it affect the reverb offsets too?) + + For ADSR and volume sweep, should the divider be reset to 0 on &0x8000 == true, or should the upper bit be cleared? + + Should shift occur on all stages of ADPCM sample decoding, or only at the end? + + On the real thing, there's some kind of weirdness with ADSR when you voice on when attack_rate(raw) = 0x7F; the envelope level register is repeatedly + reset to 0, which you can see by manual writes to the envelope level register. Normally in the attack phase when attack_rate = 0x7F, enveloping is effectively stuck/paused such that the value you write is sticky and won't be replaced or reset. Note that after you voice on, you can write a new attack_rate < 0x7F, and enveloping will work "normally" again shortly afterwards. You can even write an attack_rate of 0x7F at that point to pause enveloping clocking. I doubt any games rely on this, but it's something to keep in mind if we ever need greater insight as to how the SPU functions at a low-level in order to emulate it at cycle granularity rather than sample granularity, and it may not be a bad idea to investigate this oddity further and emulate it in the future regardless. + + Voice 1 and 3 waveform output writes to SPURAM might not be correct(noted due to problems reading this area of SPU RAM on the real thing + based on my expectations of how this should work). +*/ + +/* + Notes: + The last half of the noise freq table was confirmed on a real PSX(more or less, number of changes * 0x8000 / samples), but the first half hasn't been yet with sufficient precision. + + All addresses(for 16-bit access, at least) within the SPU address space appear to be fully read/write as if they were RAM, though + values at some addresses(like the envelope current value) will be "overwritten" by the sound processing at certain times. + + 32-bit and 8-bit reads act as if it were RAM(not tested with all addresses, but a few, assuming the rest are the same), but 8-bit writes + to odd addresses appear to be ignored, and 8-bit writes to even addresses are treated as 16-bit writes(most likely, but, need to code custom assembly to + fully test the upper 8 bits). NOTE: the preceding information doesn't necessarily cover accesses with side effects, they still need to be tested; and it + of course covers reads/writes from the point of view of software running on the CPU. + + It doesn't appear to be possible to enable FM on the first channel/voice(channel/voice 0). + + Lower bit of channel start address appears to be masked out to 0(such that ADPCM block decoding is always 8 16-bit units, 16 bytes, aligned), as far as + block-decoding and flag-set program-readable loop address go. +*/ + +/* + Update() isn't called on Read and Writes for performance reasons, it's called with sufficient granularity from the event + system, though this will obviously need to change if we ever emulate the SPU with better precision than per-sample(pair). +*/ + +#define SPUIRQ_DBG(format, ...) { printf("[SPUIRQDBG] " format " -- Voice 22 CA=0x%06x,LA=0x%06x\n", ## __VA_ARGS__, Voices[22].CurAddr, Voices[22].LoopAddr); } + +#include "psx.h" +#include "cdc.h" +#include "spu.h" + +#include "../clamp.h" + +namespace MDFN_IEN_PSX +{ + +static const int16 FIR_Table[256][4] = +{ + #include "spu_fir_table.inc" +}; + +static const uint32 NoiseFreqTable[64] = +{ + #include "spu_nft.inc" +}; + +PS_SPU::PS_SPU() +{ + last_rate = -1; + last_quality = ~0U; + + IntermediateBufferPos = 0; + memset(IntermediateBuffer, 0, sizeof(IntermediateBuffer)); +} + +PS_SPU::~PS_SPU() +{ + + +} + +void PS_SPU::Power(void) +{ + //lastts = 0; + clock_divider = 768; + + memset(SPURAM, 0, sizeof(SPURAM)); + + for(int i = 0; i < 24; i++) + { + memset(Voices[i].DecodeBuffer, 0, sizeof(Voices[i].DecodeBuffer)); + + Voices[i].DecodeWritePos = 0; + + Voices[i].DecodeFlags = 0; + + Voices[i].Sweep[0].Power(); + Voices[i].Sweep[1].Power(); + + Voices[i].Pitch = 0; + Voices[i].CurPhase = 0; + Voices[i].CurPhase_SD = 0; + + Voices[i].StartAddr = 0; + + Voices[i].CurAddr = 0; + + Voices[i].ADSRControl = 0; + + Voices[i].LoopAddr = 0; + + Voices[i].PreLRSample = 0; + + memset(&Voices[i].ADSR, 0, sizeof(SPU_ADSR)); + } + + GlobalSweep[0].Power(); + GlobalSweep[1].Power(); + + NoiseCounter = 0; + LFSR = 0; + + FM_Mode = 0; + Noise_Mode = 0; + Reverb_Mode = 0; + ReverbWA = 0; + + ReverbVol[0] = ReverbVol[1] = 0; + + CDVol[0] = CDVol[1] = 0; + + ExternVol[0] = ExternVol[1] = 0; + + IRQAddr = 0; + + RWAddr = 0; + + SPUControl = 0; + + VoiceOn = 0; + VoiceOff = 0; + + BlockEnd = 0; + + CWA = 0; + + memset(CDXA_ResampBuffer, 0, sizeof(CDXA_ResampBuffer)); + CDXA_CurPhase = 0; + + memset(Regs, 0, sizeof(Regs)); + + memset(RDSB, 0, sizeof(RDSB)); + RDSB_WP = 0; + + memset(RUSB, 0, sizeof(RUSB)); + RUSB_WP = 0; + + ReverbCur = ReverbWA; + + IRQAsserted = false; +} + +static INLINE void CalcVCDelta(const uint8 zs, uint8 speed, bool log_mode, bool dec_mode, int16 Current, int &increment, int &divinco) +{ + increment = (7 - (speed & 0x3)); + + if(dec_mode) // Decrement mode + increment = ~increment; + + divinco = 32768; + + if(speed < 0x2C) + increment <<= (0x2F - speed) >> 2; + + if(speed >= 0x30) + divinco >>= (speed - 0x2C) >> 2; + + if(log_mode) + { + if(dec_mode) // Log decrement mode + increment = (Current * increment) >> 15; + else // Log increment mode + { + if(Current >= 0x6000) + { + if(speed < 0x28) + increment >>= 2; + else if(speed >= 0x2C) + divinco >>= 2; + else // 0x28 ... 0x2B + { + increment >>= 1; + divinco >>= 1; + } + } + } + } // end if(log_mode) + + if(divinco == 0 && speed < zs) //0x7F) + divinco = 1; +} + + +INLINE void SPU_Sweep::Power(void) +{ + Control = 0; + Current = 0; + Divider = 0; +} + +INLINE void SPU_Sweep::WriteControl(uint16 value) +{ + Control = value; + Divider = 0; // Not sure about this. +} + +INLINE int16 SPU_Sweep::ReadVolume(void) +{ + return(Current); +} + +void SPU_Sweep::Clock(void) +{ + const uint16 end_value = (Control & 0x2000) ? 0x0000 : 0x7FFF; + + if(!(Control & 0x8000)) + { + Current = (Control & 0x7FFF) << 1; + return; + } + + // Invert bits + if(Control & 0x1000) + Current = ~Current; + + if((Control & 0x8000) && Current != end_value) // Sweep enabled + { + int increment; + int divinco; + + CalcVCDelta(0x7F, Control & 0x7F, Control & 0x4000, Control & 0x2000, Current, increment, divinco); + + Divider += divinco; + if(Divider & 0x8000) + { + Divider = 0; + Current += increment; + } + + if(Current & 0x8000) // Overflow or underflow + Current = end_value; + } + + // Invert bits back + if(Control & 0x1000) + Current = ~Current; +} + +INLINE void SPU_Sweep::WriteVolume(int16 value) +{ + Current = value; +} + +// output should be readable at -2 and -1 +void PS_SPU::DecodeADPCM(const uint8 *input, int16 *output, const unsigned shift, const unsigned weight) +{ + // 5 through 0xF appear to be 0 on the real thing. + static const int32 Weights[16][2] = + { + // s-1 s-2 + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 }, + }; + + for(int i = 0; i < 28; i++) + { + int32 sample; + + sample = (int16)(input[i] << 8); + sample >>= shift; + + sample += ((output[i - 1] * Weights[weight][0]) >> 6) + ((output[i - 2] * Weights[weight][1]) >> 6); + + if(sample < -32768) + sample = -32768; + + if(sample > 32767) + sample = 32767; + + output[i] = sample; + } +} + +void PS_SPU::DecodeSamples(SPU_Voice *voice) +{ + // Handle delayed flags from the previously-decoded block. + if(voice->DecodeFlags & 0x1) + { + BlockEnd |= 1 << (voice - Voices); + + if(!(voice->DecodeFlags & 0x2)) // Force enveloping to 0 if not "looping". TODO: Should we reset the ADSR divider counter too? + { + if(!(Noise_Mode & (1 << (voice - Voices)))) + { + voice->ADSR.Phase = ADSR_RELEASE; + voice->ADSR.EnvLevel = 0; + } + } + } + + // Note: Only voice->CurAddr &= 0x3FFFF at the end so IRQ address testing will work. + // 5 through 0xF appear to be 0 on the real thing. + static const int32 Weights[16][2] = + { + // s-1 s-2 + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 }, + }; + const uint32 PrevCurAddr = voice->CurAddr; + + uint16 settings; + + uint32 flags; + uint32 shift; + uint32 weight; + + uint16 coded = 0; + + + settings = SPURAM[(voice->CurAddr++) & 0x3FFFF]; + + shift = settings & 0xF; + weight = (settings >> 4) & 0xF; + flags = (settings >> 8) & 0xFF; + + for(int i = 0; i < 28; i++) + { + int32 sample; + + if(!(i & 3)) + coded = SPURAM[(voice->CurAddr++) & 0x3FFFF]; + + sample = (int16)((coded & 0xF) << 12); + sample >>= shift; + + sample += ((voice->DecodeBuffer[(voice->DecodeWritePos - 1) & 0x1F] * Weights[weight][0]) >> 6) + + ((voice->DecodeBuffer[(voice->DecodeWritePos - 2) & 0x1F] * Weights[weight][1]) >> 6); + if(sample < -32768) + sample = -32768; + + if(sample > 32767) + sample = 32767; + + voice->DecodeBuffer[voice->DecodeWritePos] = sample; + voice->DecodeWritePos = (voice->DecodeWritePos + 1) & 0x1F; + + coded >>= 4; + } + + // SPU IRQ + if(SPUControl & 0x40) + { + uint32 TestIRQAddr = IRQAddr; + + if(TestIRQAddr < PrevCurAddr) + TestIRQAddr |= 0x40000; + + if(TestIRQAddr >= PrevCurAddr && TestIRQAddr < voice->CurAddr) + { + //SPUIRQ_DBG("SPU IRQ(sample decoding) on voice %d", (int)(voice - Voices)); + IRQAsserted = true; + IRQ_Assert(IRQ_SPU, IRQAsserted); + } + } + + voice->CurAddr &= 0x3FFFF; + + if(flags & 0x4) + { + //if((int)(voice - Voices) == 22) + //{ + // SPUIRQ_DBG("[SPU] Flag loop set for voice %d, 0x%08x", (int)(voice - Voices), PrevCurAddr); + //} + voice->LoopAddr = PrevCurAddr; + } + + voice->DecodeFlags = flags; + + //printf("DEC END: %08x\n", voice->CurAddr); + + voice->DecodeBuffer[0x20] = voice->DecodeBuffer[0x00]; + voice->DecodeBuffer[0x21] = voice->DecodeBuffer[0x01]; + voice->DecodeBuffer[0x22] = voice->DecodeBuffer[0x02]; + voice->DecodeBuffer[0x23] = voice->DecodeBuffer[0x03]; +} + +void PS_SPU::CacheEnvelope(SPU_Voice *voice) +{ + uint32 raw = voice->ADSRControl; + SPU_ADSR *ADSR = &voice->ADSR; + int32 Sl, Dr, Ar, Rr, Sr; + + Sl = (raw >> 0) & 0x0F; + Dr = (raw >> 4) & 0x0F; + Ar = (raw >> 8) & 0x7F; + + Rr = (raw >> 16) & 0x1F; + Sr = (raw >> 22) & 0x7F; + + + ADSR->AttackExp = (bool)(raw & (1 << 15)); + ADSR->ReleaseExp = (bool)(raw & (1 << 21)); + ADSR->SustainExp = (bool)(raw & (1 << 31)); + ADSR->SustainDec = (bool)(raw & (1 << 30)); + + ADSR->AttackRate = Ar; + ADSR->DecayRate = Dr << 2; + ADSR->SustainRate = Sr; + ADSR->ReleaseRate = Rr << 2; + + ADSR->SustainLevel = (Sl + 1) << 11; +} + +void PS_SPU::ResetEnvelope(SPU_Voice *voice) +{ + SPU_ADSR *ADSR = &voice->ADSR; + + ADSR->EnvLevel = 0; + ADSR->Divider = 0; + ADSR->Phase = ADSR_ATTACK; +} + +void PS_SPU::ReleaseEnvelope(SPU_Voice *voice) +{ + SPU_ADSR *ADSR = &voice->ADSR; + + ADSR->Divider = 0; + ADSR->Phase = ADSR_RELEASE; +} + + +void PS_SPU::RunEnvelope(SPU_Voice *voice) +{ + SPU_ADSR *ADSR = &voice->ADSR; + int increment; + int divinco; + int16 uoflow_reset; + + if(ADSR->Phase == ADSR_ATTACK && ADSR->EnvLevel == 0x7FFF) + ADSR->Phase++; + + //static INLINE void CalcVCDelta(const uint8 zs, uint8 speed, bool log_mode, bool decrement, int16 Current, int &increment, int &divinco) + switch(ADSR->Phase) + { + default: assert(0); + break; + + case ADSR_ATTACK: + CalcVCDelta(0x7F, ADSR->AttackRate, ADSR->AttackExp, false, (int16)ADSR->EnvLevel, increment, divinco); + uoflow_reset = 0x7FFF; + break; + + case ADSR_DECAY: + CalcVCDelta(0x1F << 2, ADSR->DecayRate, true, true, (int16)ADSR->EnvLevel, increment, divinco); + uoflow_reset = 0; + break; + + case ADSR_SUSTAIN: + CalcVCDelta(0x7F, ADSR->SustainRate, ADSR->SustainExp, ADSR->SustainDec, (int16)ADSR->EnvLevel, increment, divinco); + uoflow_reset = ADSR->SustainDec ? 0 : 0x7FFF; + break; + + case ADSR_RELEASE: + CalcVCDelta(0x1F << 2, ADSR->ReleaseRate, ADSR->ReleaseExp, true, (int16)ADSR->EnvLevel, increment, divinco); + uoflow_reset = 0; + break; + } + + ADSR->Divider += divinco; + if(ADSR->Divider & 0x8000) + { + const uint16 prev_level = ADSR->EnvLevel; + + ADSR->Divider = 0; + ADSR->EnvLevel += increment; + + if(ADSR->Phase == ADSR_ATTACK) + { + // If previous the upper bit was 0, but now it's 1, handle overflow. + if(((prev_level ^ ADSR->EnvLevel) & ADSR->EnvLevel) & 0x8000) + ADSR->EnvLevel = uoflow_reset; + } + else + { + if(ADSR->EnvLevel & 0x8000) + ADSR->EnvLevel = uoflow_reset; + } + if(ADSR->Phase == ADSR_DECAY && (uint16)ADSR->EnvLevel < ADSR->SustainLevel) + ADSR->Phase++; + } +} + +INLINE void PS_SPU::CheckIRQAddr(uint32 addr) +{ + if(SPUControl & 0x40) + { + if(IRQAddr == addr) + { + //SPUIRQ_DBG("SPU IRQ (ALT): 0x%06x", addr); + IRQAsserted = true; + IRQ_Assert(IRQ_SPU, IRQAsserted); + } + } +} + +INLINE void PS_SPU::WriteSPURAM(uint32 addr, uint16 value) +{ + CheckIRQAddr(addr); + + SPURAM[addr] = value; +} + +INLINE uint16 PS_SPU::ReadSPURAM(uint32 addr) +{ + CheckIRQAddr(addr); + return(SPURAM[addr]); +} + +#include "spu_reverb.inc" + +INLINE bool PS_SPU::GetCDAudio(int32 &l, int32 &r) +{ + unsigned freq = CDC->GetCDAudioFreq(); + + if(!freq) + return false; + + if(freq == 7 || freq == 14) + { + CDC->GetCDAudio(l, r); + if(freq == 14) + CDC->GetCDAudio(l, r); + } + else + { + const int pi = CDXA_CurPhase * 37; + int32 out_tmp[2]; + + for(unsigned i = 0; i < 2; i++) + { + out_tmp[i] = ((CDXA_ResampBuffer[i][0] * FIR_Table[pi][0]) + + (CDXA_ResampBuffer[i][1] * FIR_Table[pi][1]) + + (CDXA_ResampBuffer[i][2] * FIR_Table[pi][2]) + + (CDXA_ResampBuffer[i][3] * FIR_Table[pi][3])) >> 15; + } + + l = out_tmp[0]; + r = out_tmp[1]; + + CDXA_CurPhase += freq; + + if(CDXA_CurPhase >= 7) + { + int32 raw[2]; + CDXA_CurPhase -= 7; + + CDC->GetCDAudio(raw[0], raw[1]); + + for(unsigned i = 0; i < 2; i++) + { + CDXA_ResampBuffer[i][0] = CDXA_ResampBuffer[i][1]; + CDXA_ResampBuffer[i][1] = CDXA_ResampBuffer[i][2]; + CDXA_ResampBuffer[i][2] = CDXA_ResampBuffer[i][3]; + CDXA_ResampBuffer[i][3] = raw[i]; + } + } + } + + return true; +} + +int32 PS_SPU::UpdateFromCDC(int32 clocks) +//pscpu_timestamp_t PS_SPU::Update(const pscpu_timestamp_t timestamp) +{ + //int32 clocks = timestamp - lastts; + int32 sample_clocks = 0; + //lastts = timestamp; + + clock_divider -= clocks; + + while(clock_divider <= 0) + { + clock_divider += 768; + sample_clocks++; + } + + while(sample_clocks > 0) + { + // Accumulated normal sound output. + int32 accum_l = 0; + int32 accum_r = 0; + + // Accumulated sound output for reverb input + int32 accum_fv_l = 0; + int32 accum_fv_r = 0; + + // Output of reverb processing. + int32 reverb_l = 0; + int32 reverb_r = 0; + + // Final output. + int32 output_l = 0; + int32 output_r = 0; + + const uint32 PhaseModCache = FM_Mode & ~ 1; +/* +** +** 0x1F801DAE Notes and Conjecture: +** ------------------------------------------------------------------------------------- +** | 15 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 4 3 2 1 0 | +** | ? | *13| ? | ba | *10 | wrr|rdr| df | is | c | +** ------------------------------------------------------------------------------------- +** +** c - Appears to be delayed copy of lower 6 bits from 0x1F801DAA. +** +** is - Interrupt asserted out status. (apparently not instantaneous status though...) +** +** df - Related to (c & 0x30) == 0x20 or (c & 0x30) == 0x30, at least. +** 0 = DMA busy(FIFO not empty when in DMA write mode?)? +** 1 = DMA ready? Something to do with the FIFO? +** +** rdr - Read(DMA read?) Ready? +** +** wrr - Write(DMA write?) Ready? +** +** *10 - Unknown. Some sort of (FIFO?) busy status?(BIOS tests for this bit in places) +** +** ba - Alternates between 0 and 1, even when SPUControl bit15 is 0; might be related to CD audio and voice 1 and 3 writing to SPU RAM. +** +** *13 - Unknown, was set to 1 when testing with an SPU delay system reg value of 0x200921E1(test result might not be reliable, re-run). +*/ + SPUStatus = SPUControl & 0x3F; + SPUStatus |= IRQAsserted ? 0x40 : 0x00; + + + for(int voice_num = 0; voice_num < 24; voice_num++) + { + SPU_Voice *voice = &Voices[voice_num]; + int32 voice_pvs; + + voice->PreLRSample = 0; + + //PSX_WARNING("[SPU] Voice %d CurPhase=%08x, pitch=%04x, CurAddr=%08x", voice_num, voice->CurPhase, voice->Pitch, voice->CurAddr); + + // Decode new samples if necessary. + if(voice->DecodeFlags & 0x1) + voice->CurAddr = voice->LoopAddr & ~0x7; + + if(voice->CurPhase_SD >= (24 << 12)) + { + voice->CurPhase_SD -= 28 << 12; + DecodeSamples(voice); + } + else + { + CheckIRQAddr(voice->CurAddr); + } + // + // + // + int l, r; + + if(Noise_Mode & (1 << voice_num)) + voice_pvs = (int16)LFSR; + else + { + const int si = voice->CurPhase >> 12; + const int pi = ((voice->CurPhase & 0xFFF) >> 4); + + voice_pvs = ((voice->DecodeBuffer[si + 0] * FIR_Table[pi][0]) + + (voice->DecodeBuffer[si + 1] * FIR_Table[pi][1]) + + (voice->DecodeBuffer[si + 2] * FIR_Table[pi][2]) + + (voice->DecodeBuffer[si + 3] * FIR_Table[pi][3])) >> 15; + } + + voice_pvs = (voice_pvs * (int16)voice->ADSR.EnvLevel) >> 15; + voice->PreLRSample = voice_pvs; + + if(voice_num == 1 || voice_num == 3) + { + int index = voice_num >> 1; + + WriteSPURAM(0x400 | (index * 0x200) | CWA, voice_pvs); + } + + + l = (voice_pvs * voice->Sweep[0].ReadVolume()) >> 15; + r = (voice_pvs * voice->Sweep[1].ReadVolume()) >> 15; + + accum_l += l; + accum_r += r; + + if(Reverb_Mode & (1 << voice_num)) + { + accum_fv_l += l; + accum_fv_r += r; + } + + // Run sweep + for(int lr = 0; lr < 2; lr++) + voice->Sweep[lr].Clock(); + + // Run enveloping + RunEnvelope(voice); + + // Increment stuff + { + int32 phase_inc; + + if(PhaseModCache & (1 << voice_num)) + { + // This old formula: phase_inc = (voice->Pitch * ((voice - 1)->PreLRSample + 0x8000)) >> 15; + // is incorrect, as it does not handle carrier pitches >= 0x8000 properly. + + phase_inc = voice->Pitch + (((int16)voice->Pitch * ((voice - 1)->PreLRSample)) >> 15); + if(phase_inc < 0) + { + printf("phase_inc < 0 (THIS SHOULD NOT HAPPEN)\n"); + phase_inc = 0; + } + } + else + phase_inc = voice->Pitch; + + if(phase_inc > 0x3FFF) + phase_inc = 0x3FFF; + + voice->CurPhase = (voice->CurPhase + phase_inc) & 0x1FFFF; + voice->CurPhase_SD += phase_inc; + } + + if(!(SPUControl & 0x8000) || (VoiceOff & (1 << voice_num))) + { + if(voice->ADSR.Phase != ADSR_RELEASE) + { + ReleaseEnvelope(voice); + } + } + + if((SPUControl & 0x8000) && (VoiceOn & (1 << voice_num))) + { + ResetEnvelope(voice); + + voice->DecodeFlags = 0; + voice->DecodeWritePos = 0; + + BlockEnd &= ~(1 << voice_num); + + // Weight/filter previous value initialization: + voice->DecodeBuffer[0x1E] = 0; + voice->DecodeBuffer[0x1F] = 0; + + voice->CurPhase = 0; + voice->CurPhase_SD = 28 << 12; // Trigger initial sample decode + + voice->CurAddr = voice->StartAddr & ~0x7; + } + } + + VoiceOff = 0; + VoiceOn = 0; + + // "Mute" control doesn't seem to affect CD audio(though CD audio reverb wasn't tested...) + // TODO: If we add sub-sample timing accuracy, see if it's checked for every channel at different times, or just once. + if(!(SPUControl & 0x4000)) + { + accum_l = 0; + accum_r = 0; + accum_fv_l = 0; + accum_fv_r = 0; + } + + // Get CD-DA + { + int32 cda_raw[2] = { 0 }; + + if(GetCDAudio(cda_raw[0], cda_raw[1])) + { + int32 cdav[2]; + + for(unsigned i = 0; i < 2; i++) + cdav[i] = (cda_raw[i] * CDVol[i]) >> 15; + + if(SPUControl & 0x0001) + { + accum_l += cdav[0]; + accum_r += cdav[1]; + + if(SPUControl & 0x0004) // TODO: Test this bit(and see if it is really dependent on bit0) + { + accum_fv_l += cdav[0]; + accum_fv_r += cdav[1]; + } + } + } + WriteSPURAM(CWA | 0x000, cda_raw[0]); + WriteSPURAM(CWA | 0x200, cda_raw[1]); + } + + CWA = (CWA + 1) & 0x1FF; + + NoiseCounter += NoiseFreqTable[(SPUControl >> 8) & 0x3F]; + if(NoiseCounter >= 0x8000) + { + NoiseCounter -= 0x8000; + LFSR = (LFSR << 1) | (((LFSR >> 15) ^ (LFSR >> 12) ^ (LFSR >> 11) ^ (LFSR >> 10) ^ 1) & 1); + } + + clamp(&accum_l, -32768, 32767); + clamp(&accum_r, -32768, 32767); + clamp(&accum_fv_l, -32768, 32767); + clamp(&accum_fv_r, -32768, 32767); + +#if 0 + accum_l = 0; + accum_r = 0; + //accum_fv_l = (short)(rand()); + //accum_fv_r = (short)(rand()); +#endif + + RunReverb(accum_fv_l, accum_fv_r, reverb_l, reverb_r); + + //MDFN_DispMessage("%d %d\n", MainVol[0], MainVol[1], ReverbVol[0], ReverbVol[1]); + + // FIXME: Dry volume versus everything else + output_l = (((accum_l * GlobalSweep[0].ReadVolume()) >> 16) + ((reverb_l * ReverbVol[0]) >> 15)); + output_r = (((accum_r * GlobalSweep[1].ReadVolume()) >> 16) + ((reverb_r * ReverbVol[1]) >> 15)); + + //output_l = reverb_l; + //output_r = reverb_r; + + clamp(&output_l, -32768, 32767); + clamp(&output_r, -32768, 32767); + + assert(IntermediateBufferPos < 4096); + IntermediateBuffer[IntermediateBufferPos][0] = output_l; + IntermediateBuffer[IntermediateBufferPos][1] = output_r; + IntermediateBufferPos++; + + sample_clocks--; + + // Clock global sweep + for(int lr = 0; lr < 2; lr++) + GlobalSweep[lr].Clock(); + } + + //assert(clock_divider < 768); + + return clock_divider; +} + +void PS_SPU::WriteDMA(uint32 V) +{ + //SPUIRQ_DBG("DMA Write, RWAddr after=0x%06x", RWAddr); + WriteSPURAM(RWAddr, V); + RWAddr = (RWAddr + 1) & 0x3FFFF; + + WriteSPURAM(RWAddr, V >> 16); + RWAddr = (RWAddr + 1) & 0x3FFFF; + + + CheckIRQAddr(RWAddr); +} + +uint32 PS_SPU::ReadDMA(void) +{ + uint32 ret; + + ret = (uint16)ReadSPURAM(RWAddr); + RWAddr = (RWAddr + 1) & 0x3FFFF; + + ret |= (uint32)(uint16)ReadSPURAM(RWAddr) << 16; + RWAddr = (RWAddr + 1) & 0x3FFFF; + + CheckIRQAddr(RWAddr); + + //SPUIRQ_DBG("DMA Read, RWAddr after=0x%06x", RWAddr); + + return(ret); +} + +void PS_SPU::Write(pscpu_timestamp_t timestamp, uint32 A, uint16 V) +{ + //if((A & 0x3FF) < 0x180) + // PSX_WARNING("[SPU] Write: %08x %04x", A, V); + + A &= 0x3FF; + + if(A >= 0x200) + { + //printf("Write: %08x %04x\n", A, V); + if(A < 0x260) + { + SPU_Voice *voice = &Voices[(A - 0x200) >> 2]; + voice->Sweep[(A & 2) >> 1].WriteVolume(V); + } + else if(A < 0x280) + AuxRegs[(A & 0x1F) >> 1] = V; + + return; + } + + if(A < 0x180) + { + SPU_Voice *voice = &Voices[A >> 4]; + + switch(A & 0xF) + { + case 0x00: + case 0x02: + voice->Sweep[(A & 2) >> 1].WriteControl(V); + break; + + case 0x04: voice->Pitch = V; + break; + + case 0x06: voice->StartAddr = (V << 2) & 0x3FFFF; + break; + + case 0x08: voice->ADSRControl &= 0xFFFF0000; + voice->ADSRControl |= V; + CacheEnvelope(voice); + break; + + case 0x0A: voice->ADSRControl &= 0x0000FFFF; + voice->ADSRControl |= V << 16; + CacheEnvelope(voice); + break; + + case 0x0C: voice->ADSR.EnvLevel = V; + break; + + case 0x0E: voice->LoopAddr = (V << 2) & 0x3FFFF; + //if((voice - Voices) == 22) + //{ + // SPUIRQ_DBG("Manual loop address setting for voice %d: %04x", (int)(voice - Voices), V); + //} + break; + } + } + else + { + switch(A & 0x7F) + { + case 0x00: + case 0x02: GlobalSweep[(A & 2) >> 1].WriteControl(V); + break; + + case 0x04: ReverbVol[0] = (int16)V; + break; + + case 0x06: ReverbVol[1] = (int16)V; + break; + + // Voice ON: + case 0x08: VoiceOn &= 0xFFFF0000; + VoiceOn |= V << 0; + break; + + case 0x0a: VoiceOn &= 0x0000FFFF; + VoiceOn |= (V & 0xFF) << 16; + break; + + // Voice OFF: + case 0x0c: VoiceOff &= 0xFFFF0000; + VoiceOff |= V << 0; + break; + + case 0x0e: VoiceOff &= 0x0000FFFF; + VoiceOff |= (V & 0xFF) << 16; + break; + + case 0x10: FM_Mode &= 0xFFFF0000; + FM_Mode |= V << 0; + break; + + case 0x12: FM_Mode &= 0x0000FFFF; + FM_Mode |= (V & 0xFF) << 16; + break; + + case 0x14: Noise_Mode &= 0xFFFF0000; + Noise_Mode |= V << 0; + break; + + case 0x16: Noise_Mode &= 0x0000FFFF; + Noise_Mode |= (V & 0xFF) << 16; + break; + + case 0x18: Reverb_Mode &= 0xFFFF0000; + Reverb_Mode |= V << 0; + break; + + case 0x1A: Reverb_Mode &= 0x0000FFFF; + Reverb_Mode |= (V & 0xFF) << 16; + break; + + case 0x1C: BlockEnd &= 0xFFFF0000; + BlockEnd |= V << 0; + break; + + case 0x1E: BlockEnd &= 0x0000FFFF; + BlockEnd |= V << 16; + break; + + case 0x22: ReverbWA = (V << 2) & 0x3FFFF; + ReverbCur = ReverbWA; + //PSX_WARNING("[SPU] Reverb WA set: 0x%04x", V); + break; + + case 0x24: IRQAddr = (V << 2) & 0x3FFFF; + CheckIRQAddr(RWAddr); + //SPUIRQ_DBG("Set IRQAddr=0x%06x", IRQAddr); + break; + + case 0x26: RWAddr = (V << 2) & 0x3FFFF; + CheckIRQAddr(RWAddr); + //SPUIRQ_DBG("Set RWAddr=0x%06x", RWAddr); + break; + + case 0x28: WriteSPURAM(RWAddr, V); + RWAddr = (RWAddr + 1) & 0x3FFFF; + CheckIRQAddr(RWAddr); + break; + + case 0x2A: SPUControl = V; + //SPUIRQ_DBG("Set SPUControl=0x%04x -- IRQA=%06x, RWA=%06x", V, IRQAddr, RWAddr); + //printf("SPU control write: %04x\n", V); + if(!(V & 0x40)) + { + IRQAsserted = false; + IRQ_Assert(IRQ_SPU, IRQAsserted); + } + CheckIRQAddr(RWAddr); + break; + + case 0x2C: PSX_WARNING("[SPU] Global reg 0x2c set: 0x%04x", V); + break; + + case 0x30: CDVol[0] = V; + break; + + case 0x32: CDVol[1] = V; + break; + + case 0x34: ExternVol[0] = V; + break; + + case 0x36: ExternVol[1] = V; + break; + + case 0x38: + case 0x3A: GlobalSweep[(A & 2) >> 1].WriteVolume(V); + break; + } + } + + Regs[(A & 0x1FF) >> 1] = V; +} + +uint16 PS_SPU::Read(pscpu_timestamp_t timestamp, uint32 A) +{ + A &= 0x3FF; + + PSX_DBGINFO("[SPU] Read: %08x", A); + + if(A >= 0x200) + { + if(A < 0x260) + { + SPU_Voice *voice = &Voices[(A - 0x200) >> 2]; + + //printf("Read: %08x %04x\n", A, voice->Sweep[(A & 2) >> 1].ReadVolume()); + + return voice->Sweep[(A & 2) >> 1].ReadVolume(); + } + else if(A < 0x280) + return(AuxRegs[(A & 0x1F) >> 1]); + + return(0xFFFF); + } + + + if(A < 0x180) + { + SPU_Voice *voice = &Voices[A >> 4]; + + switch(A & 0xF) + { + case 0x0C: return(voice->ADSR.EnvLevel); + case 0x0E: return(voice->LoopAddr >> 2); + } + } + else + { + switch(A & 0x7F) + { + case 0x1C: return(BlockEnd); + case 0x1E: return(BlockEnd >> 16); + + case 0x26: //PSX_WARNING("[SPU] RWADDR Read"); + break; + + case 0x28: PSX_WARNING("[SPU] SPURAM Read port(?) Read"); + + { + uint16 ret = ReadSPURAM(RWAddr); + + RWAddr = (RWAddr + 1) & 0x3FFFF; + CheckIRQAddr(RWAddr); + + return(ret); + } + + case 0x2a: + return(SPUControl); + +/* FIXME: What is this used for? */ + case 0x3C: + //PSX_WARNING("[SPU] Read Unknown: %08x", A); + return(0); + + case 0x38: + case 0x3A: return(GlobalSweep[(A & 2) >> 1].ReadVolume()); + } + } + + return(Regs[(A & 0x1FF) >> 1]); +} + + +void PS_SPU::StartFrame(double rate, uint32 quality) +{ + if((int)rate != last_rate || quality != last_quality) + { + int err = 0; + + last_rate = (int)rate; + last_quality = quality; + } + +} + +int32 PS_SPU::EndFrame(int16 *SoundBuf) +{ + //lastts = 0; + + if(last_rate == 44100) + { + int32 ret = IntermediateBufferPos; + + memcpy(SoundBuf, IntermediateBuffer, IntermediateBufferPos * 2 * sizeof(int16)); + IntermediateBufferPos = 0; + + return(ret); + } + else + { + IntermediateBufferPos = 0; + return 0; + } +} + +int PS_SPU::StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { +#define SFSWEEP(r) SFVAR((r).Control), \ + SFVAR((r).Current), \ + SFVAR((r).Divider) + +#define SFVOICE(n) SFARRAY32(&Voices[n].DecodeBuffer[0], sizeof(Voices[n].DecodeBuffer) / sizeof(Voices[n].DecodeBuffer[0])), \ + SFVAR(Voices[n].DecodeWritePos), \ + SFVAR(Voices[n].DecodeFlags), \ + \ + SFSWEEP(Voices[n].Sweep[0]), \ + SFSWEEP(Voices[n].Sweep[1]), \ + \ + SFVAR(Voices[n].Pitch), \ + SFVAR(Voices[n].CurPhase), \ + SFVAR(Voices[n].CurPhase_SD), \ + \ + SFVAR(Voices[n].StartAddr), \ + SFVAR(Voices[n].CurAddr), \ + SFVAR(Voices[n].ADSRControl), \ + SFVAR(Voices[n].LoopAddr), \ + SFVAR(Voices[n].PreLRSample), \ + \ + SFVAR(Voices[n].ADSR.EnvLevel), \ + SFVAR(Voices[n].ADSR.Divider), \ + SFVAR(Voices[n].ADSR.Phase), \ + \ + SFVAR(Voices[n].ADSR.AttackExp), \ + SFVAR(Voices[n].ADSR.SustainExp), \ + SFVAR(Voices[n].ADSR.SustainDec), \ + SFVAR(Voices[n].ADSR.ReleaseExp), \ + \ + SFVAR(Voices[n].ADSR.AttackRate), \ + SFVAR(Voices[n].ADSR.DecayRate), \ + SFVAR(Voices[n].ADSR.SustainRate), \ + SFVAR(Voices[n].ADSR.ReleaseRate), \ + \ + SFVAR(Voices[n].ADSR.SustainLevel) + + SFVOICE(0), + SFVOICE(1), + SFVOICE(2), + SFVOICE(3), + SFVOICE(4), + SFVOICE(5), + SFVOICE(6), + SFVOICE(7), + SFVOICE(8), + SFVOICE(9), + SFVOICE(10), + SFVOICE(11), + SFVOICE(12), + SFVOICE(13), + SFVOICE(14), + SFVOICE(15), + SFVOICE(16), + SFVOICE(17), + SFVOICE(18), + SFVOICE(19), + SFVOICE(20), + SFVOICE(21), + SFVOICE(22), + SFVOICE(23), +#undef SFVOICE + + SFVAR(NoiseCounter), + SFVAR(LFSR), + + SFVAR(FM_Mode), + SFVAR(Noise_Mode), + SFVAR(Reverb_Mode), + + SFVAR(ReverbWA), + + SFSWEEP(GlobalSweep[0]), + SFSWEEP(GlobalSweep[1]), + + SFARRAY32(ReverbVol, sizeof(ReverbVol) / sizeof(ReverbVol[0])), + + SFARRAY32(CDVol, sizeof(CDVol) / sizeof(CDVol[0])), + SFARRAY32(ExternVol, sizeof(ExternVol) / sizeof(ExternVol[0])), + + SFVAR(IRQAddr), + + SFVAR(RWAddr), + + SFVAR(SPUControl), + + SFVAR(VoiceOn), + SFVAR(VoiceOff), + + SFVAR(BlockEnd), + + SFVAR(CWA), + + SFARRAY32(&CDXA_ResampBuffer[0][0], sizeof(CDXA_ResampBuffer) / sizeof(CDXA_ResampBuffer[0][0])), + SFVAR(CDXA_CurPhase), + + SFARRAY16(Regs, sizeof(Regs) / sizeof(Regs[0])), + SFARRAY16(AuxRegs, sizeof(AuxRegs) / sizeof(AuxRegs[0])), + + SFARRAY16(&RDSB[0][0], sizeof(RDSB) / sizeof(RDSB[0][0])), + SFVAR(RDSB_WP), + + SFARRAY16(&RUSB[0][0], sizeof(RUSB) / sizeof(RUSB[0][0])), + SFVAR(RUSB_WP), + + SFVAR(ReverbCur), + SFVAR(IRQAsserted), + + SFVAR(clock_divider), + + SFARRAY16(SPURAM, 524288 / sizeof(uint16)), + SFEND + }; +#undef SFSWEEP + int ret = 1; + + ret &= MDFNSS_StateAction(sm, load, data_only, StateRegs, "SPU"); + + if(load) + { + + } + + return(ret); +} + +uint16 PS_SPU::PeekSPURAM(uint32 address) +{ + return(SPURAM[address & 0x3FFFF]); +} + +void PS_SPU::PokeSPURAM(uint32 address, uint16 value) +{ + SPURAM[address & 0x3FFFF] = value; +} + +uint32 PS_SPU::GetRegister(unsigned int which, char *special, const uint32 special_len) +{ + uint32 ret = 0xDEADBEEF; + + if(which >= 0x8000) + { + unsigned int v = (which - 0x8000) >> 8; + + switch((which & 0xFF) | 0x8000) + { + case GSREG_V0_VOL_CTRL_L: + ret = Regs[v * 8 + 0x0]; + break; + + case GSREG_V0_VOL_CTRL_R: + ret = Regs[v * 8 + 0x1]; + break; + + case GSREG_V0_VOL_L: + ret = Voices[v].Sweep[0].ReadVolume() & 0xFFFF; + break; + + case GSREG_V0_VOL_R: + ret = Voices[v].Sweep[1].ReadVolume() & 0xFFFF; + break; + + case GSREG_V0_PITCH: + ret = Voices[v].Pitch; + break; + + case GSREG_V0_STARTADDR: + ret = Voices[v].StartAddr; + break; + + case GSREG_V0_ADSR_CTRL: + ret = Voices[v].ADSRControl; + break; + + case GSREG_V0_ADSR_LEVEL: + ret = Voices[v].ADSR.EnvLevel; + break; + + case GSREG_V0_LOOP_ADDR: + ret = Voices[v].LoopAddr; + break; + + case GSREG_V0_READ_ADDR: + ret = Voices[v].CurAddr; + break; + } + } + else switch(which) + { + case GSREG_SPUCONTROL: + ret = SPUControl; + break; + + case GSREG_FM_ON: + ret = FM_Mode; + break; + + case GSREG_NOISE_ON: + ret = Noise_Mode; + break; + + case GSREG_REVERB_ON: + ret = Reverb_Mode; + break; + + case GSREG_CDVOL_L: + ret = (uint16)CDVol[0]; + break; + + case GSREG_CDVOL_R: + ret = (uint16)CDVol[1]; + break; + + case GSREG_DRYVOL_CTRL_L: + ret = Regs[0xC0]; + break; + + case GSREG_DRYVOL_CTRL_R: + ret = Regs[0xC1]; + break; + + case GSREG_DRYVOL_L: + ret = GlobalSweep[0].ReadVolume() & 0xFFFF; + break; + + case GSREG_DRYVOL_R: + ret = GlobalSweep[1].ReadVolume() & 0xFFFF; + break; + + case GSREG_WETVOL_L: + ret = (uint16)ReverbVol[0]; + break; + + case GSREG_WETVOL_R: + ret = (uint16)ReverbVol[1]; + break; + + case GSREG_RWADDR: + ret = RWAddr; + break; + + case GSREG_IRQADDR: + ret = IRQAddr; + break; + + case GSREG_REVERBWA: + ret = ReverbWA >> 2; + break; + + case GSREG_VOICEON: + ret = VoiceOn; + break; + + case GSREG_VOICEOFF: + ret = VoiceOff; + break; + + case GSREG_BLOCKEND: + ret = BlockEnd; + break; + + + case GSREG_FB_SRC_A ... GSREG_IN_COEF_R: + ret = ReverbRegs[which - GSREG_FB_SRC_A] & 0xFFFF; + break; + } + + return(ret); +} + +void PS_SPU::SetRegister(unsigned int which, uint32 value) +{ + + switch(which) + { + case GSREG_SPUCONTROL: + SPUControl = value; + break; + + case GSREG_FM_ON: + FM_Mode = value & 0xFFFFFF; + break; + + case GSREG_NOISE_ON: + Noise_Mode = value & 0xFFFFFF; + break; + + case GSREG_REVERB_ON: + Reverb_Mode = value & 0xFFFFFF; + break; + + case GSREG_CDVOL_L: + CDVol[0] = (int16)value; + break; + + case GSREG_CDVOL_R: + CDVol[1] = (int16)value; + break; + + case GSREG_DRYVOL_CTRL_L: + Regs[0xC0] = value; + GlobalSweep[0].WriteControl(value); + //GlobalSweep[0].Control = value; + break; + + case GSREG_DRYVOL_CTRL_R: + Regs[0xC1] = value; + GlobalSweep[1].WriteControl(value); + //GlobalSweep[1].Control = value; + break; + + case GSREG_DRYVOL_L: + GlobalSweep[0].WriteVolume(value); + break; + + case GSREG_DRYVOL_R: + GlobalSweep[1].WriteVolume(value); + break; + + case GSREG_WETVOL_L: + ReverbVol[0] = (int16)value; + break; + + case GSREG_WETVOL_R: + ReverbVol[1] = (int16)value; + break; + + case GSREG_RWADDR: + RWAddr = value & 0x3FFFF; + break; + + case GSREG_IRQADDR: + IRQAddr = value & 0x3FFFC; + break; + + // + // REVERB_WA + // + + case GSREG_VOICEON: + VoiceOn = value & 0xFFFFFF; + break; + + case GSREG_VOICEOFF: + VoiceOff = value & 0xFFFFFF; + break; + + case GSREG_BLOCKEND: + BlockEnd = value & 0xFFFFFF; + break; + + + } +} + + + +} diff --git a/mednafen/psx-0925/spu.h b/mednafen/psx-0925/spu.h new file mode 100644 index 00000000..fedf44e0 --- /dev/null +++ b/mednafen/psx-0925/spu.h @@ -0,0 +1,338 @@ +#ifndef __MDFN_PSX_SPU_H +#define __MDFN_PSX_SPU_H + +namespace MDFN_IEN_PSX +{ + +enum +{ + ADSR_ATTACK = 0, + ADSR_DECAY = 1, + ADSR_SUSTAIN = 2, + ADSR_RELEASE = 3 +}; + +struct SPU_ADSR +{ + uint16 EnvLevel; // We typecast it to (int16) in several places, but keep it here as (uint16) to prevent signed overflow/underflow, which compilers + // may not treat consistently. + uint32 Divider; + uint32 Phase; + + bool AttackExp; + bool SustainExp; + bool SustainDec; + bool ReleaseExp; + + int32 AttackRate; // Ar + int32 DecayRate; // Dr * 4 + int32 SustainRate; // Sr + int32 ReleaseRate; // Rr * 4 + + int32 SustainLevel; // (Sl + 1) << 11 +}; + +class PS_SPU; +class SPU_Sweep +{ + friend class PS_SPU; // For save states - FIXME(remove in future?) + + public: + SPU_Sweep() { } + ~SPU_Sweep() { } + + void Power(void); + + void WriteControl(uint16 value); + int16 ReadVolume(void); + + void WriteVolume(int16 value); + + void Clock(void); + + private: + uint16 Control; + int16 Current; + uint32 Divider; +}; + +struct SPU_Voice +{ + int32 DecodeBuffer[32 + 4]; // + 4 so we don't have to do & 0x1F in our MAC + int32 DecodeWritePos; + + uint8 DecodeFlags; + + SPU_Sweep Sweep[2]; + + uint16 Pitch; + uint32 CurPhase; + int32 CurPhase_SD; // Offseted compared to CurPhase, used for triggering sample decode. + + uint32 StartAddr; + + uint32 CurAddr; + + uint32 ADSRControl; + + uint32 LoopAddr; + + int32 PreLRSample; // After enveloping, but before L/R volume. Range of -32768 to 32767 + + SPU_ADSR ADSR; +}; + +class PS_SPU +{ + public: + + PS_SPU(); + ~PS_SPU(); + + int StateAction(StateMem *sm, int load, int data_only); + + void Power(void); + void Write(pscpu_timestamp_t timestamp, uint32 A, uint16 V); + uint16 Read(pscpu_timestamp_t timestamp, uint32 A); + + void WriteDMA(uint32 V); + uint32 ReadDMA(void); + + void StartFrame(double rate, uint32 quality); + int32 EndFrame(int16 *SoundBuf); + + int32 UpdateFromCDC(int32 clocks); + //pscpu_timestamp_t Update(pscpu_timestamp_t timestamp); + + + static void DecodeADPCM(const uint8 *input, int16 *output, const unsigned shift, const unsigned weight); + + private: + + void CheckIRQAddr(uint32 addr); + void WriteSPURAM(uint32 addr, uint16 value); + uint16 ReadSPURAM(uint32 addr); + + void DecodeSamples(SPU_Voice *voice); + + void CacheEnvelope(SPU_Voice *voice); + void ResetEnvelope(SPU_Voice *voice); + void ReleaseEnvelope(SPU_Voice *voice); + void RunEnvelope(SPU_Voice *voice); + + + void RunReverb(int32 in_l, int32 in_r, int32 &out_l, int32 &out_r); + bool GetCDAudio(int32 &l, int32 &r); + + SPU_Voice Voices[24]; + + uint32 NoiseCounter; + uint16 LFSR; + + uint32 FM_Mode; + uint32 Noise_Mode; + uint32 Reverb_Mode; + + int32 ReverbWA; + + SPU_Sweep GlobalSweep[2]; // Doesn't affect reverb volume! + + int32 ReverbVol[2]; + + int32 CDVol[2]; + int32 ExternVol[2]; + + uint32 IRQAddr; + + uint32 RWAddr; + + uint16 SPUControl; + + uint32 VoiceOn; + uint32 VoiceOff; + + uint32 BlockEnd; + + uint32 CWA; + + int32 CDXA_ResampBuffer[2][4]; + int32 CDXA_CurPhase; + + union + { + uint16 Regs[0x100]; + struct + { + uint16 VoiceRegs[0xC0]; + union + { + uint16 GlobalRegs[0x20]; + struct + { + uint16 _Global0[0x17]; + uint16 SPUStatus; + uint16 _Global1[0x08]; + }; + }; + union + { + int16 ReverbRegs[0x20]; + + struct + { + int16 FB_SRC_A; + int16 FB_SRC_B; + int16 IIR_ALPHA; + int16 ACC_COEF_A; + int16 ACC_COEF_B; + int16 ACC_COEF_C; + int16 ACC_COEF_D; + int16 IIR_COEF; + int16 FB_ALPHA; + int16 FB_X; + int16 IIR_DEST_A0; + int16 IIR_DEST_A1; + int16 ACC_SRC_A0; + int16 ACC_SRC_A1; + int16 ACC_SRC_B0; + int16 ACC_SRC_B1; + int16 IIR_SRC_A0; + int16 IIR_SRC_A1; + int16 IIR_DEST_B0; + int16 IIR_DEST_B1; + int16 ACC_SRC_C0; + int16 ACC_SRC_C1; + int16 ACC_SRC_D0; + int16 ACC_SRC_D1; + int16 IIR_SRC_B1; + int16 IIR_SRC_B0; + int16 MIX_DEST_A0; + int16 MIX_DEST_A1; + int16 MIX_DEST_B0; + int16 MIX_DEST_B1; + int16 IN_COEF_L; + int16 IN_COEF_R; + }; + }; + }; + }; + + uint16 AuxRegs[0x10]; + + int16 RDSB[2][128]; // [40] + int32 RDSB_WP; + + int16 RUSB[2][128]; + int32 RUSB_WP; + + int32 ReverbCur; + + int32 Get_Reverb_Offset(int32 offset); + int32 RD_RVB(int16 raw_offs); + void WR_RVB(int16 raw_offs, int32 sample, int32 extra_offs = 0); + + bool IRQAsserted; + + //pscpu_timestamp_t lastts; + int32 clock_divider; + + uint16 SPURAM[524288 / sizeof(uint16)]; + + int last_rate; + uint32 last_quality; + + // Buffers 44.1KHz samples, should have enough for one video frame(~735 frames NTSC, ~882 PAL) plus jitter plus enough for the resampler leftovers. + // We'll just go with 4096 because powers of 2 are AWESOME and such. + uint32 IntermediateBufferPos; + int16 IntermediateBuffer[4096][2]; + + public: + enum + { + GSREG_SPUCONTROL = 0, + + GSREG_FM_ON, + GSREG_NOISE_ON, + GSREG_REVERB_ON, + + GSREG_CDVOL_L, + GSREG_CDVOL_R, + + GSREG_DRYVOL_CTRL_L, + GSREG_DRYVOL_CTRL_R, + + GSREG_DRYVOL_L, + GSREG_DRYVOL_R, + + GSREG_WETVOL_L, + GSREG_WETVOL_R, + + GSREG_RWADDR, + + GSREG_IRQADDR, + + GSREG_REVERBWA, + + GSREG_VOICEON, + GSREG_VOICEOFF, + GSREG_BLOCKEND, + + // Note: the order of these should match the reverb reg array + GSREG_FB_SRC_A, + GSREG_FB_SRC_B, + GSREG_IIR_ALPHA, + GSREG_ACC_COEF_A, + GSREG_ACC_COEF_B, + GSREG_ACC_COEF_C, + GSREG_ACC_COEF_D, + GSREG_IIR_COEF, + GSREG_FB_ALPHA, + GSREG_FB_X, + GSREG_IIR_DEST_A0, + GSREG_IIR_DEST_A1, + GSREG_ACC_SRC_A0, + GSREG_ACC_SRC_A1, + GSREG_ACC_SRC_B0, + GSREG_ACC_SRC_B1, + GSREG_IIR_SRC_A0, + GSREG_IIR_SRC_A1, + GSREG_IIR_DEST_B0, + GSREG_IIR_DEST_B1, + GSREG_ACC_SRC_C0, + GSREG_ACC_SRC_C1, + GSREG_ACC_SRC_D0, + GSREG_ACC_SRC_D1, + GSREG_IIR_SRC_B1, + GSREG_IIR_SRC_B0, + GSREG_MIX_DEST_A0, + GSREG_MIX_DEST_A1, + GSREG_MIX_DEST_B0, + GSREG_MIX_DEST_B1, + GSREG_IN_COEF_L, + GSREG_IN_COEF_R, + + + // Multiply v * 256 for each extra voice + GSREG_V0_VOL_CTRL_L = 0x8000, + GSREG_V0_VOL_CTRL_R, + GSREG_V0_VOL_L, + GSREG_V0_VOL_R, + GSREG_V0_PITCH, + GSREG_V0_STARTADDR, + GSREG_V0_ADSR_CTRL, + GSREG_V0_ADSR_LEVEL, + GSREG_V0_LOOP_ADDR, + GSREG_V0_READ_ADDR + }; + + uint32 GetRegister(unsigned int which, char *special, const uint32 special_len); + void SetRegister(unsigned int which, uint32 value); + + uint16 PeekSPURAM(uint32 address); + void PokeSPURAM(uint32 address, uint16 value); +}; + + +} + +#endif diff --git a/mednafen/psx-0925/spu_fir_table.inc b/mednafen/psx-0925/spu_fir_table.inc new file mode 100644 index 00000000..dabee3cb --- /dev/null +++ b/mednafen/psx-0925/spu_fir_table.inc @@ -0,0 +1,256 @@ + { (int16)0x12c7, (int16)0x59b3, (int16)0x1307, (int16)0xffff }, + { (int16)0x1288, (int16)0x59b2, (int16)0x1347, (int16)0xffff }, + { (int16)0x1249, (int16)0x59b0, (int16)0x1388, (int16)0xffff }, + { (int16)0x120b, (int16)0x59ad, (int16)0x13c9, (int16)0xffff }, + { (int16)0x11cd, (int16)0x59a9, (int16)0x140b, (int16)0xffff }, + { (int16)0x118f, (int16)0x59a4, (int16)0x144d, (int16)0xffff }, + { (int16)0x1153, (int16)0x599e, (int16)0x1490, (int16)0xffff }, + { (int16)0x1116, (int16)0x5997, (int16)0x14d4, (int16)0xffff }, + { (int16)0x10db, (int16)0x598f, (int16)0x1517, (int16)0xffff }, + { (int16)0x109f, (int16)0x5986, (int16)0x155c, (int16)0xffff }, + { (int16)0x1065, (int16)0x597c, (int16)0x15a0, (int16)0xffff }, + { (int16)0x102a, (int16)0x5971, (int16)0x15e6, (int16)0xffff }, + { (int16)0x0ff1, (int16)0x5965, (int16)0x162c, (int16)0xffff }, + { (int16)0x0fb7, (int16)0x5958, (int16)0x1672, (int16)0xffff }, + { (int16)0x0f7f, (int16)0x5949, (int16)0x16b9, (int16)0xffff }, + { (int16)0x0f46, (int16)0x593a, (int16)0x1700, (int16)0xffff }, + { (int16)0x0f0f, (int16)0x592a, (int16)0x1747, (int16)0x0000 }, + { (int16)0x0ed7, (int16)0x5919, (int16)0x1790, (int16)0x0000 }, + { (int16)0x0ea1, (int16)0x5907, (int16)0x17d8, (int16)0x0000 }, + { (int16)0x0e6b, (int16)0x58f4, (int16)0x1821, (int16)0x0000 }, + { (int16)0x0e35, (int16)0x58e0, (int16)0x186b, (int16)0x0000 }, + { (int16)0x0e00, (int16)0x58cb, (int16)0x18b5, (int16)0x0000 }, + { (int16)0x0dcb, (int16)0x58b5, (int16)0x1900, (int16)0x0000 }, + { (int16)0x0d97, (int16)0x589e, (int16)0x194b, (int16)0x0001 }, + { (int16)0x0d63, (int16)0x5886, (int16)0x1996, (int16)0x0001 }, + { (int16)0x0d30, (int16)0x586d, (int16)0x19e2, (int16)0x0001 }, + { (int16)0x0cfd, (int16)0x5853, (int16)0x1a2e, (int16)0x0001 }, + { (int16)0x0ccb, (int16)0x5838, (int16)0x1a7b, (int16)0x0002 }, + { (int16)0x0c99, (int16)0x581c, (int16)0x1ac8, (int16)0x0002 }, + { (int16)0x0c68, (int16)0x57ff, (int16)0x1b16, (int16)0x0002 }, + { (int16)0x0c38, (int16)0x57e2, (int16)0x1b64, (int16)0x0003 }, + { (int16)0x0c07, (int16)0x57c3, (int16)0x1bb3, (int16)0x0003 }, + { (int16)0x0bd8, (int16)0x57a3, (int16)0x1c02, (int16)0x0003 }, + { (int16)0x0ba9, (int16)0x5782, (int16)0x1c51, (int16)0x0004 }, + { (int16)0x0b7a, (int16)0x5761, (int16)0x1ca1, (int16)0x0004 }, + { (int16)0x0b4c, (int16)0x573e, (int16)0x1cf1, (int16)0x0005 }, + { (int16)0x0b1e, (int16)0x571b, (int16)0x1d42, (int16)0x0005 }, + { (int16)0x0af1, (int16)0x56f6, (int16)0x1d93, (int16)0x0006 }, + { (int16)0x0ac4, (int16)0x56d1, (int16)0x1de5, (int16)0x0007 }, + { (int16)0x0a98, (int16)0x56ab, (int16)0x1e37, (int16)0x0007 }, + { (int16)0x0a6c, (int16)0x5684, (int16)0x1e89, (int16)0x0008 }, + { (int16)0x0a40, (int16)0x565b, (int16)0x1edc, (int16)0x0009 }, + { (int16)0x0a16, (int16)0x5632, (int16)0x1f2f, (int16)0x0009 }, + { (int16)0x09eb, (int16)0x5609, (int16)0x1f82, (int16)0x000a }, + { (int16)0x09c1, (int16)0x55de, (int16)0x1fd6, (int16)0x000b }, + { (int16)0x0998, (int16)0x55b2, (int16)0x202a, (int16)0x000c }, + { (int16)0x096f, (int16)0x5585, (int16)0x207f, (int16)0x000d }, + { (int16)0x0946, (int16)0x5558, (int16)0x20d4, (int16)0x000e }, + { (int16)0x091e, (int16)0x5529, (int16)0x2129, (int16)0x000f }, + { (int16)0x08f7, (int16)0x54fa, (int16)0x217f, (int16)0x0010 }, + { (int16)0x08d0, (int16)0x54ca, (int16)0x21d5, (int16)0x0011 }, + { (int16)0x08a9, (int16)0x5499, (int16)0x222c, (int16)0x0012 }, + { (int16)0x0883, (int16)0x5467, (int16)0x2282, (int16)0x0013 }, + { (int16)0x085d, (int16)0x5434, (int16)0x22da, (int16)0x0015 }, + { (int16)0x0838, (int16)0x5401, (int16)0x2331, (int16)0x0016 }, + { (int16)0x0813, (int16)0x53cc, (int16)0x2389, (int16)0x0018 }, + { (int16)0x07ef, (int16)0x5397, (int16)0x23e1, (int16)0x0019 }, + { (int16)0x07cb, (int16)0x5361, (int16)0x2439, (int16)0x001b }, + { (int16)0x07a7, (int16)0x532a, (int16)0x2492, (int16)0x001c }, + { (int16)0x0784, (int16)0x52f3, (int16)0x24eb, (int16)0x001e }, + { (int16)0x0762, (int16)0x52ba, (int16)0x2545, (int16)0x0020 }, + { (int16)0x0740, (int16)0x5281, (int16)0x259e, (int16)0x0021 }, + { (int16)0x071e, (int16)0x5247, (int16)0x25f8, (int16)0x0023 }, + { (int16)0x06fd, (int16)0x520c, (int16)0x2653, (int16)0x0025 }, + { (int16)0x06dc, (int16)0x51d0, (int16)0x26ad, (int16)0x0027 }, + { (int16)0x06bb, (int16)0x5194, (int16)0x2708, (int16)0x0029 }, + { (int16)0x069b, (int16)0x5156, (int16)0x2763, (int16)0x002c }, + { (int16)0x067c, (int16)0x5118, (int16)0x27be, (int16)0x002e }, + { (int16)0x065c, (int16)0x50da, (int16)0x281a, (int16)0x0030 }, + { (int16)0x063e, (int16)0x509a, (int16)0x2876, (int16)0x0033 }, + { (int16)0x061f, (int16)0x505a, (int16)0x28d2, (int16)0x0035 }, + { (int16)0x0601, (int16)0x5019, (int16)0x292e, (int16)0x0038 }, + { (int16)0x05e4, (int16)0x4fd7, (int16)0x298b, (int16)0x003a }, + { (int16)0x05c7, (int16)0x4f95, (int16)0x29e7, (int16)0x003d }, + { (int16)0x05aa, (int16)0x4f52, (int16)0x2a44, (int16)0x0040 }, + { (int16)0x058e, (int16)0x4f0e, (int16)0x2aa1, (int16)0x0043 }, + { (int16)0x0572, (int16)0x4ec9, (int16)0x2aff, (int16)0x0046 }, + { (int16)0x0556, (int16)0x4e84, (int16)0x2b5c, (int16)0x0049 }, + { (int16)0x053b, (int16)0x4e3e, (int16)0x2bba, (int16)0x004d }, + { (int16)0x0520, (int16)0x4df7, (int16)0x2c18, (int16)0x0050 }, + { (int16)0x0506, (int16)0x4db0, (int16)0x2c76, (int16)0x0054 }, + { (int16)0x04ec, (int16)0x4d68, (int16)0x2cd4, (int16)0x0057 }, + { (int16)0x04d2, (int16)0x4d20, (int16)0x2d33, (int16)0x005b }, + { (int16)0x04b9, (int16)0x4cd7, (int16)0x2d91, (int16)0x005f }, + { (int16)0x04a0, (int16)0x4c8d, (int16)0x2df0, (int16)0x0063 }, + { (int16)0x0488, (int16)0x4c42, (int16)0x2e4f, (int16)0x0067 }, + { (int16)0x0470, (int16)0x4bf7, (int16)0x2eae, (int16)0x006b }, + { (int16)0x0458, (int16)0x4bac, (int16)0x2f0d, (int16)0x006f }, + { (int16)0x0441, (int16)0x4b5f, (int16)0x2f6c, (int16)0x0074 }, + { (int16)0x042a, (int16)0x4b13, (int16)0x2fcc, (int16)0x0078 }, + { (int16)0x0413, (int16)0x4ac5, (int16)0x302b, (int16)0x007d }, + { (int16)0x03fc, (int16)0x4a77, (int16)0x308b, (int16)0x0082 }, + { (int16)0x03e7, (int16)0x4a29, (int16)0x30ea, (int16)0x0087 }, + { (int16)0x03d1, (int16)0x49d9, (int16)0x314a, (int16)0x008c }, + { (int16)0x03bc, (int16)0x498a, (int16)0x31aa, (int16)0x0091 }, + { (int16)0x03a7, (int16)0x493a, (int16)0x3209, (int16)0x0096 }, + { (int16)0x0392, (int16)0x48e9, (int16)0x3269, (int16)0x009c }, + { (int16)0x037e, (int16)0x4898, (int16)0x32c9, (int16)0x00a1 }, + { (int16)0x036a, (int16)0x4846, (int16)0x3329, (int16)0x00a7 }, + { (int16)0x0356, (int16)0x47f4, (int16)0x3389, (int16)0x00ad }, + { (int16)0x0343, (int16)0x47a1, (int16)0x33e9, (int16)0x00b3 }, + { (int16)0x0330, (int16)0x474e, (int16)0x3449, (int16)0x00ba }, + { (int16)0x031d, (int16)0x46fa, (int16)0x34a9, (int16)0x00c0 }, + { (int16)0x030b, (int16)0x46a6, (int16)0x3509, (int16)0x00c7 }, + { (int16)0x02f9, (int16)0x4651, (int16)0x3569, (int16)0x00cd }, + { (int16)0x02e7, (int16)0x45fc, (int16)0x35c9, (int16)0x00d4 }, + { (int16)0x02d6, (int16)0x45a6, (int16)0x3629, (int16)0x00db }, + { (int16)0x02c4, (int16)0x4550, (int16)0x3689, (int16)0x00e3 }, + { (int16)0x02b4, (int16)0x44fa, (int16)0x36e8, (int16)0x00ea }, + { (int16)0x02a3, (int16)0x44a3, (int16)0x3748, (int16)0x00f2 }, + { (int16)0x0293, (int16)0x444c, (int16)0x37a8, (int16)0x00fa }, + { (int16)0x0283, (int16)0x43f4, (int16)0x3807, (int16)0x0101 }, + { (int16)0x0273, (int16)0x439c, (int16)0x3867, (int16)0x010a }, + { (int16)0x0264, (int16)0x4344, (int16)0x38c6, (int16)0x0112 }, + { (int16)0x0255, (int16)0x42eb, (int16)0x3926, (int16)0x011b }, + { (int16)0x0246, (int16)0x4292, (int16)0x3985, (int16)0x0123 }, + { (int16)0x0237, (int16)0x4239, (int16)0x39e4, (int16)0x012c }, + { (int16)0x0229, (int16)0x41df, (int16)0x3a43, (int16)0x0135 }, + { (int16)0x021b, (int16)0x4185, (int16)0x3aa2, (int16)0x013f }, + { (int16)0x020d, (int16)0x412a, (int16)0x3b00, (int16)0x0148 }, + { (int16)0x0200, (int16)0x40d0, (int16)0x3b5f, (int16)0x0152 }, + { (int16)0x01f2, (int16)0x4074, (int16)0x3bbd, (int16)0x015c }, + { (int16)0x01e5, (int16)0x4019, (int16)0x3c1b, (int16)0x0166 }, + { (int16)0x01d9, (int16)0x3fbd, (int16)0x3c79, (int16)0x0171 }, + { (int16)0x01cc, (int16)0x3f62, (int16)0x3cd7, (int16)0x017b }, + { (int16)0x01c0, (int16)0x3f05, (int16)0x3d35, (int16)0x0186 }, + { (int16)0x01b4, (int16)0x3ea9, (int16)0x3d92, (int16)0x0191 }, + { (int16)0x01a8, (int16)0x3e4c, (int16)0x3def, (int16)0x019c }, + { (int16)0x019c, (int16)0x3def, (int16)0x3e4c, (int16)0x01a8 }, + { (int16)0x0191, (int16)0x3d92, (int16)0x3ea9, (int16)0x01b4 }, + { (int16)0x0186, (int16)0x3d35, (int16)0x3f05, (int16)0x01c0 }, + { (int16)0x017b, (int16)0x3cd7, (int16)0x3f62, (int16)0x01cc }, + { (int16)0x0171, (int16)0x3c79, (int16)0x3fbd, (int16)0x01d9 }, + { (int16)0x0166, (int16)0x3c1b, (int16)0x4019, (int16)0x01e5 }, + { (int16)0x015c, (int16)0x3bbd, (int16)0x4074, (int16)0x01f2 }, + { (int16)0x0152, (int16)0x3b5f, (int16)0x40d0, (int16)0x0200 }, + { (int16)0x0148, (int16)0x3b00, (int16)0x412a, (int16)0x020d }, + { (int16)0x013f, (int16)0x3aa2, (int16)0x4185, (int16)0x021b }, + { (int16)0x0135, (int16)0x3a43, (int16)0x41df, (int16)0x0229 }, + { (int16)0x012c, (int16)0x39e4, (int16)0x4239, (int16)0x0237 }, + { (int16)0x0123, (int16)0x3985, (int16)0x4292, (int16)0x0246 }, + { (int16)0x011b, (int16)0x3926, (int16)0x42eb, (int16)0x0255 }, + { (int16)0x0112, (int16)0x38c6, (int16)0x4344, (int16)0x0264 }, + { (int16)0x010a, (int16)0x3867, (int16)0x439c, (int16)0x0273 }, + { (int16)0x0101, (int16)0x3807, (int16)0x43f4, (int16)0x0283 }, + { (int16)0x00fa, (int16)0x37a8, (int16)0x444c, (int16)0x0293 }, + { (int16)0x00f2, (int16)0x3748, (int16)0x44a3, (int16)0x02a3 }, + { (int16)0x00ea, (int16)0x36e8, (int16)0x44fa, (int16)0x02b4 }, + { (int16)0x00e3, (int16)0x3689, (int16)0x4550, (int16)0x02c4 }, + { (int16)0x00db, (int16)0x3629, (int16)0x45a6, (int16)0x02d6 }, + { (int16)0x00d4, (int16)0x35c9, (int16)0x45fc, (int16)0x02e7 }, + { (int16)0x00cd, (int16)0x3569, (int16)0x4651, (int16)0x02f9 }, + { (int16)0x00c7, (int16)0x3509, (int16)0x46a6, (int16)0x030b }, + { (int16)0x00c0, (int16)0x34a9, (int16)0x46fa, (int16)0x031d }, + { (int16)0x00ba, (int16)0x3449, (int16)0x474e, (int16)0x0330 }, + { (int16)0x00b3, (int16)0x33e9, (int16)0x47a1, (int16)0x0343 }, + { (int16)0x00ad, (int16)0x3389, (int16)0x47f4, (int16)0x0356 }, + { (int16)0x00a7, (int16)0x3329, (int16)0x4846, (int16)0x036a }, + { (int16)0x00a1, (int16)0x32c9, (int16)0x4898, (int16)0x037e }, + { (int16)0x009c, (int16)0x3269, (int16)0x48e9, (int16)0x0392 }, + { (int16)0x0096, (int16)0x3209, (int16)0x493a, (int16)0x03a7 }, + { (int16)0x0091, (int16)0x31aa, (int16)0x498a, (int16)0x03bc }, + { (int16)0x008c, (int16)0x314a, (int16)0x49d9, (int16)0x03d1 }, + { (int16)0x0087, (int16)0x30ea, (int16)0x4a29, (int16)0x03e7 }, + { (int16)0x0082, (int16)0x308b, (int16)0x4a77, (int16)0x03fc }, + { (int16)0x007d, (int16)0x302b, (int16)0x4ac5, (int16)0x0413 }, + { (int16)0x0078, (int16)0x2fcc, (int16)0x4b13, (int16)0x042a }, + { (int16)0x0074, (int16)0x2f6c, (int16)0x4b5f, (int16)0x0441 }, + { (int16)0x006f, (int16)0x2f0d, (int16)0x4bac, (int16)0x0458 }, + { (int16)0x006b, (int16)0x2eae, (int16)0x4bf7, (int16)0x0470 }, + { (int16)0x0067, (int16)0x2e4f, (int16)0x4c42, (int16)0x0488 }, + { (int16)0x0063, (int16)0x2df0, (int16)0x4c8d, (int16)0x04a0 }, + { (int16)0x005f, (int16)0x2d91, (int16)0x4cd7, (int16)0x04b9 }, + { (int16)0x005b, (int16)0x2d33, (int16)0x4d20, (int16)0x04d2 }, + { (int16)0x0057, (int16)0x2cd4, (int16)0x4d68, (int16)0x04ec }, + { (int16)0x0054, (int16)0x2c76, (int16)0x4db0, (int16)0x0506 }, + { (int16)0x0050, (int16)0x2c18, (int16)0x4df7, (int16)0x0520 }, + { (int16)0x004d, (int16)0x2bba, (int16)0x4e3e, (int16)0x053b }, + { (int16)0x0049, (int16)0x2b5c, (int16)0x4e84, (int16)0x0556 }, + { (int16)0x0046, (int16)0x2aff, (int16)0x4ec9, (int16)0x0572 }, + { (int16)0x0043, (int16)0x2aa1, (int16)0x4f0e, (int16)0x058e }, + { (int16)0x0040, (int16)0x2a44, (int16)0x4f52, (int16)0x05aa }, + { (int16)0x003d, (int16)0x29e7, (int16)0x4f95, (int16)0x05c7 }, + { (int16)0x003a, (int16)0x298b, (int16)0x4fd7, (int16)0x05e4 }, + { (int16)0x0038, (int16)0x292e, (int16)0x5019, (int16)0x0601 }, + { (int16)0x0035, (int16)0x28d2, (int16)0x505a, (int16)0x061f }, + { (int16)0x0033, (int16)0x2876, (int16)0x509a, (int16)0x063e }, + { (int16)0x0030, (int16)0x281a, (int16)0x50da, (int16)0x065c }, + { (int16)0x002e, (int16)0x27be, (int16)0x5118, (int16)0x067c }, + { (int16)0x002c, (int16)0x2763, (int16)0x5156, (int16)0x069b }, + { (int16)0x0029, (int16)0x2708, (int16)0x5194, (int16)0x06bb }, + { (int16)0x0027, (int16)0x26ad, (int16)0x51d0, (int16)0x06dc }, + { (int16)0x0025, (int16)0x2653, (int16)0x520c, (int16)0x06fd }, + { (int16)0x0023, (int16)0x25f8, (int16)0x5247, (int16)0x071e }, + { (int16)0x0021, (int16)0x259e, (int16)0x5281, (int16)0x0740 }, + { (int16)0x0020, (int16)0x2545, (int16)0x52ba, (int16)0x0762 }, + { (int16)0x001e, (int16)0x24eb, (int16)0x52f3, (int16)0x0784 }, + { (int16)0x001c, (int16)0x2492, (int16)0x532a, (int16)0x07a7 }, + { (int16)0x001b, (int16)0x2439, (int16)0x5361, (int16)0x07cb }, + { (int16)0x0019, (int16)0x23e1, (int16)0x5397, (int16)0x07ef }, + { (int16)0x0018, (int16)0x2389, (int16)0x53cc, (int16)0x0813 }, + { (int16)0x0016, (int16)0x2331, (int16)0x5401, (int16)0x0838 }, + { (int16)0x0015, (int16)0x22da, (int16)0x5434, (int16)0x085d }, + { (int16)0x0013, (int16)0x2282, (int16)0x5467, (int16)0x0883 }, + { (int16)0x0012, (int16)0x222c, (int16)0x5499, (int16)0x08a9 }, + { (int16)0x0011, (int16)0x21d5, (int16)0x54ca, (int16)0x08d0 }, + { (int16)0x0010, (int16)0x217f, (int16)0x54fa, (int16)0x08f7 }, + { (int16)0x000f, (int16)0x2129, (int16)0x5529, (int16)0x091e }, + { (int16)0x000e, (int16)0x20d4, (int16)0x5558, (int16)0x0946 }, + { (int16)0x000d, (int16)0x207f, (int16)0x5585, (int16)0x096f }, + { (int16)0x000c, (int16)0x202a, (int16)0x55b2, (int16)0x0998 }, + { (int16)0x000b, (int16)0x1fd6, (int16)0x55de, (int16)0x09c1 }, + { (int16)0x000a, (int16)0x1f82, (int16)0x5609, (int16)0x09eb }, + { (int16)0x0009, (int16)0x1f2f, (int16)0x5632, (int16)0x0a16 }, + { (int16)0x0009, (int16)0x1edc, (int16)0x565b, (int16)0x0a40 }, + { (int16)0x0008, (int16)0x1e89, (int16)0x5684, (int16)0x0a6c }, + { (int16)0x0007, (int16)0x1e37, (int16)0x56ab, (int16)0x0a98 }, + { (int16)0x0007, (int16)0x1de5, (int16)0x56d1, (int16)0x0ac4 }, + { (int16)0x0006, (int16)0x1d93, (int16)0x56f6, (int16)0x0af1 }, + { (int16)0x0005, (int16)0x1d42, (int16)0x571b, (int16)0x0b1e }, + { (int16)0x0005, (int16)0x1cf1, (int16)0x573e, (int16)0x0b4c }, + { (int16)0x0004, (int16)0x1ca1, (int16)0x5761, (int16)0x0b7a }, + { (int16)0x0004, (int16)0x1c51, (int16)0x5782, (int16)0x0ba9 }, + { (int16)0x0003, (int16)0x1c02, (int16)0x57a3, (int16)0x0bd8 }, + { (int16)0x0003, (int16)0x1bb3, (int16)0x57c3, (int16)0x0c07 }, + { (int16)0x0003, (int16)0x1b64, (int16)0x57e2, (int16)0x0c38 }, + { (int16)0x0002, (int16)0x1b16, (int16)0x57ff, (int16)0x0c68 }, + { (int16)0x0002, (int16)0x1ac8, (int16)0x581c, (int16)0x0c99 }, + { (int16)0x0002, (int16)0x1a7b, (int16)0x5838, (int16)0x0ccb }, + { (int16)0x0001, (int16)0x1a2e, (int16)0x5853, (int16)0x0cfd }, + { (int16)0x0001, (int16)0x19e2, (int16)0x586d, (int16)0x0d30 }, + { (int16)0x0001, (int16)0x1996, (int16)0x5886, (int16)0x0d63 }, + { (int16)0x0001, (int16)0x194b, (int16)0x589e, (int16)0x0d97 }, + { (int16)0x0000, (int16)0x1900, (int16)0x58b5, (int16)0x0dcb }, + { (int16)0x0000, (int16)0x18b5, (int16)0x58cb, (int16)0x0e00 }, + { (int16)0x0000, (int16)0x186b, (int16)0x58e0, (int16)0x0e35 }, + { (int16)0x0000, (int16)0x1821, (int16)0x58f4, (int16)0x0e6b }, + { (int16)0x0000, (int16)0x17d8, (int16)0x5907, (int16)0x0ea1 }, + { (int16)0x0000, (int16)0x1790, (int16)0x5919, (int16)0x0ed7 }, + { (int16)0x0000, (int16)0x1747, (int16)0x592a, (int16)0x0f0f }, + { (int16)0xffff, (int16)0x1700, (int16)0x593a, (int16)0x0f46 }, + { (int16)0xffff, (int16)0x16b9, (int16)0x5949, (int16)0x0f7f }, + { (int16)0xffff, (int16)0x1672, (int16)0x5958, (int16)0x0fb7 }, + { (int16)0xffff, (int16)0x162c, (int16)0x5965, (int16)0x0ff1 }, + { (int16)0xffff, (int16)0x15e6, (int16)0x5971, (int16)0x102a }, + { (int16)0xffff, (int16)0x15a0, (int16)0x597c, (int16)0x1065 }, + { (int16)0xffff, (int16)0x155c, (int16)0x5986, (int16)0x109f }, + { (int16)0xffff, (int16)0x1517, (int16)0x598f, (int16)0x10db }, + { (int16)0xffff, (int16)0x14d4, (int16)0x5997, (int16)0x1116 }, + { (int16)0xffff, (int16)0x1490, (int16)0x599e, (int16)0x1153 }, + { (int16)0xffff, (int16)0x144d, (int16)0x59a4, (int16)0x118f }, + { (int16)0xffff, (int16)0x140b, (int16)0x59a9, (int16)0x11cd }, + { (int16)0xffff, (int16)0x13c9, (int16)0x59ad, (int16)0x120b }, + { (int16)0xffff, (int16)0x1388, (int16)0x59b0, (int16)0x1249 }, + { (int16)0xffff, (int16)0x1347, (int16)0x59b2, (int16)0x1288 }, + { (int16)0xffff, (int16)0x1307, (int16)0x59b3, (int16)0x12c7 }, diff --git a/mednafen/psx-0925/spu_nft.inc b/mednafen/psx-0925/spu_nft.inc new file mode 100644 index 00000000..95b8f49c --- /dev/null +++ b/mednafen/psx-0925/spu_nft.inc @@ -0,0 +1,64 @@ +0x00000001, +0x00000001, +0x00000001, +0x00000001, +0x00000002, +0x00000002, +0x00000002, +0x00000002, +0x00000004, +0x00000005, +0x00000006, +0x00000007, +0x00000008, +0x0000000a, +0x0000000c, +0x0000000e, +0x00000010, +0x00000014, +0x00000018, +0x0000001c, +0x00000020, +0x00000028, +0x00000030, +0x00000038, +0x00000040, +0x00000050, +0x00000060, +0x00000070, +0x00000080, +0x000000a0, +0x000000c0, +0x000000e0, +0x00000100, +0x00000140, +0x00000180, +0x000001c0, +0x00000200, +0x00000280, +0x00000300, +0x00000380, +0x00000400, +0x00000500, +0x00000600, +0x00000700, +0x00000800, +0x00000a00, +0x00000c00, +0x00000e00, +0x00001000, +0x00001400, +0x00001800, +0x00001c00, +0x00002000, +0x00002800, +0x00003000, +0x00003800, +0x00004000, +0x00005000, +0x00006000, +0x00007000, +0x00008000, +0x00008000, +0x00008000, +0x00008000, diff --git a/mednafen/psx-0925/spu_reverb.inc b/mednafen/psx-0925/spu_reverb.inc new file mode 100644 index 00000000..8192fd9c --- /dev/null +++ b/mednafen/psx-0925/spu_reverb.inc @@ -0,0 +1,237 @@ +static int16 ReverbSat(int32 samp) MDFN_WARN_UNUSED_RESULT; +static INLINE int16 ReverbSat(int32 samp) +{ + if(samp > 32767) + samp = 32767; + + if(samp < -32768) + samp = -32768; + + return(samp); +} + + +INLINE int32 PS_SPU::Get_Reverb_Offset(int32 in_offset) +{ + int32 offset = in_offset & 0x3FFFF; + int32 wa_size = 0x40000 - ReverbWA; + + if(offset & 0x20000) + { + offset -= ReverbWA; + + if(offset < 0) + { + offset = 0; + //PSX_WARNING("[SPU] A reverb offset is broken(-)."); + } + } + else + { + if(offset >= wa_size) + { + offset = wa_size - 1; + //PSX_WARNING("[SPU] A reverb offset is broken(+): WASize=0x%04x, 0x%04x.", wa_size >> 2, in_offset >> 2); + } + } + + offset += ReverbCur; + + if(offset >= 0x40000) + offset = (offset & 0x3FFFF) + ReverbWA; + + assert(offset >= ReverbWA && offset < 0x40000); + + return(offset); +} + +int32 PS_SPU::RD_RVB(int16 raw_offs) +{ + //raw_offs = rand() & 0xFFFF; + + return((int16)SPURAM[Get_Reverb_Offset(raw_offs << 2)]); +} + +void PS_SPU::WR_RVB(int16 raw_offs, int32 sample, int32 extra_offs) +{ + //raw_offs = rand() & 0xFFFF; + + SPURAM[Get_Reverb_Offset((raw_offs << 2) + extra_offs)] = ReverbSat(sample); +} + +static INLINE int32 Reverb4422(const int16 *src) +{ + static const int16 ResampTable[40] = + { + (int16)0xffff, + (int16)0x0000, + (int16)0x0002, + (int16)0x0000, + (int16)0xfff6, + (int16)0x0000, + (int16)0x0023, + (int16)0x0000, + (int16)0xff99, + (int16)0x0000, + (int16)0x010a, + (int16)0x0000, + (int16)0xfd98, + (int16)0x0000, + (int16)0x0534, + (int16)0x0000, + (int16)0xf470, + (int16)0x0000, + (int16)0x2806, + (int16)0x4000, + (int16)0x2806, + (int16)0x0000, + (int16)0xf470, + (int16)0x0000, + (int16)0x0534, + (int16)0x0000, + (int16)0xfd98, + (int16)0x0000, + (int16)0x010a, + (int16)0x0000, + (int16)0xff99, + (int16)0x0000, + (int16)0x0023, + (int16)0x0000, + (int16)0xfff6, + (int16)0x0000, + (int16)0x0002, + (int16)0x0000, + (int16)0xffff, + (int16)0x0000, + }; + int32 out = 0; // 32-bits is adequate(it won't overflow) + + for(int i = 0; i < 40; i += 2) + out += ResampTable[i] * src[i]; + + // Middle non-zero + out += 0x4000 * src[19]; + + out >>= 15; + + if(out < -32768) + out = -32768; + + if(out > 32767) + out = 32767; + + return(out); +} + +void PS_SPU::RunReverb(int32 in_l, int32 in_r, int32 &out_l, int32 &out_r) +{ + int32 upsampled[2] = { 0, 0 }; + + RDSB[0][RDSB_WP] = in_l; + RDSB[1][RDSB_WP] = in_r; + RDSB[0][RDSB_WP | 0x40] = in_l; // So we don't have to &/bounds check in our MAC loop + RDSB[1][RDSB_WP | 0x40] = in_r; + + RDSB_WP = (RDSB_WP + 1) & 0x3F; + + if(!(RDSB_WP & 1)) + { + int32 downsampled[2]; + + for(int lr = 0; lr < 2; lr++) + downsampled[lr] = Reverb4422(&RDSB[lr][(RDSB_WP - 40) & 0x3F]); + + // + // Run algorithm + /// + if(SPUControl & 0x80) + { + int32 IIR_INPUT_A0; + int32 IIR_INPUT_A1; + int32 IIR_INPUT_B0; + int32 IIR_INPUT_B1; + int32 IIR_A0, IIR_A1, IIR_B0, IIR_B1; + int32 ACC0, ACC1; + int32 FB_A0, FB_A1, FB_B0, FB_B1; + + IIR_INPUT_A0 = ((RD_RVB(IIR_SRC_A0) * IIR_COEF) >> 15) + ((downsampled[0] * IN_COEF_L) >> 15); + IIR_INPUT_A1 = ((RD_RVB(IIR_SRC_A1) * IIR_COEF) >> 15) + ((downsampled[1] * IN_COEF_R) >> 15); + IIR_INPUT_B0 = ((RD_RVB(IIR_SRC_B0) * IIR_COEF) >> 15) + ((downsampled[0] * IN_COEF_L) >> 15); + IIR_INPUT_B1 = ((RD_RVB(IIR_SRC_B1) * IIR_COEF) >> 15) + ((downsampled[1] * IN_COEF_R) >> 15); + + + IIR_A0 = (((int64)IIR_INPUT_A0 * IIR_ALPHA) >> 15) + ((RD_RVB(IIR_DEST_A0) * (32768 - IIR_ALPHA)) >> 15); + IIR_A1 = (((int64)IIR_INPUT_A1 * IIR_ALPHA) >> 15) + ((RD_RVB(IIR_DEST_A1) * (32768 - IIR_ALPHA)) >> 15); + IIR_B0 = (((int64)IIR_INPUT_B0 * IIR_ALPHA) >> 15) + ((RD_RVB(IIR_DEST_B0) * (32768 - IIR_ALPHA)) >> 15); + IIR_B1 = (((int64)IIR_INPUT_B1 * IIR_ALPHA) >> 15) + ((RD_RVB(IIR_DEST_B1) * (32768 - IIR_ALPHA)) >> 15); + + WR_RVB(IIR_DEST_A0, IIR_A0, 1); + WR_RVB(IIR_DEST_A1, IIR_A1, 1); + WR_RVB(IIR_DEST_B0, IIR_B0, 1); + WR_RVB(IIR_DEST_B1, IIR_B1, 1); + +#if 0 + ACC0 = ((RD_RVB(ACC_SRC_A0) * ACC_COEF_A) >> 15) + + ((RD_RVB(ACC_SRC_B0) * ACC_COEF_B) >> 15) + + ((RD_RVB(ACC_SRC_C0) * ACC_COEF_C) >> 15) + + ((RD_RVB(ACC_SRC_D0) * ACC_COEF_D) >> 15); + + ACC1 = ((RD_RVB(ACC_SRC_A1) * ACC_COEF_A) >> 15) + + ((RD_RVB(ACC_SRC_B1) * ACC_COEF_B) >> 15) + + ((RD_RVB(ACC_SRC_C1) * ACC_COEF_C) >> 15) + + ((RD_RVB(ACC_SRC_D1) * ACC_COEF_D) >> 15); +#endif + + ACC0 = ((int64)(RD_RVB(ACC_SRC_A0) * ACC_COEF_A) + + (RD_RVB(ACC_SRC_B0) * ACC_COEF_B) + + (RD_RVB(ACC_SRC_C0) * ACC_COEF_C) + + (RD_RVB(ACC_SRC_D0) * ACC_COEF_D)) >> 15; + + + ACC1 = ((int64)(RD_RVB(ACC_SRC_A1) * ACC_COEF_A) + + (RD_RVB(ACC_SRC_B1) * ACC_COEF_B) + + (RD_RVB(ACC_SRC_C1) * ACC_COEF_C) + + (RD_RVB(ACC_SRC_D1) * ACC_COEF_D)) >> 15; + + + FB_A0 = RD_RVB(MIX_DEST_A0 - FB_SRC_A); + FB_A1 = RD_RVB(MIX_DEST_A1 - FB_SRC_A); + FB_B0 = RD_RVB(MIX_DEST_B0 - FB_SRC_B); + FB_B1 = RD_RVB(MIX_DEST_B1 - FB_SRC_B); + + WR_RVB(MIX_DEST_A0, ACC0 - ((FB_A0 * FB_ALPHA) >> 15)); + WR_RVB(MIX_DEST_A1, ACC1 - ((FB_A1 * FB_ALPHA) >> 15)); + + WR_RVB(MIX_DEST_B0, (((int64)FB_ALPHA * ACC0) >> 15) - ((FB_A0 * (int16)(0x8000 ^ FB_ALPHA)) >> 15) - ((FB_B0 * FB_X) >> 15)); + WR_RVB(MIX_DEST_B1, (((int64)FB_ALPHA * ACC1) >> 15) - ((FB_A1 * (int16)(0x8000 ^ FB_ALPHA)) >> 15) - ((FB_B1 * FB_X) >> 15)); + } + + // + // Get output samples + // +// RUSB[0][RUSB_WP | 0x40] = RUSB[0][RUSB_WP] = (short)rand(); +// RUSB[1][RUSB_WP | 0x40] = RUSB[1][RUSB_WP] = (short)rand(); + RUSB[0][RUSB_WP | 0x40] = RUSB[0][RUSB_WP] = (RD_RVB(MIX_DEST_A0) + RD_RVB(MIX_DEST_B0)) >> 1; + RUSB[1][RUSB_WP | 0x40] = RUSB[1][RUSB_WP] = (RD_RVB(MIX_DEST_A1) + RD_RVB(MIX_DEST_B1)) >> 1; + + RUSB_WP = (RUSB_WP + 1) & 0x3F; + + ReverbCur = (ReverbCur + 1) & 0x3FFFF; + if(!ReverbCur) + ReverbCur = ReverbWA; + } + else + { + RUSB[0][RUSB_WP | 0x40] = RUSB[0][RUSB_WP] = 0; + RUSB[1][RUSB_WP | 0x40] = RUSB[1][RUSB_WP] = 0; + + RUSB_WP = (RUSB_WP + 1) & 0x3F; + } + + for(int lr = 0; lr < 2; lr++) + upsampled[lr] = Reverb4422(&RUSB[lr][(RUSB_WP - 40) & 0x3F]); + + out_l = upsampled[0]; + out_r = upsampled[1]; +} + diff --git a/mednafen/psx-0925/timer.cpp b/mednafen/psx-0925/timer.cpp new file mode 100644 index 00000000..f3b9815e --- /dev/null +++ b/mednafen/psx-0925/timer.cpp @@ -0,0 +1,512 @@ +/* Mednafen - Multi-system Emulator + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "psx.h" +#include "timer.h" + +/* + Notes(some of it may be incomplete or wrong in subtle ways) + + Control bits: + Lower 3 bits of mode, for timer1: + 0x1 = don't count during vblank + 0x3 = vblank going inactive triggers timer reset + 0x5 = vblank going inactive triggers timer reset, and only count within vblank. + 0x7 = Wait until vblank goes active then inactive, then start counting? + For timer2: + 0x1 = timer stopped(TODO: confirm on real system) + + Target mode enabled 0x008 + IRQ enable 0x010 + --?Affects 0x400 status flag?-- 0x020 + IRQ evaluation auto-reset 0x040 + --unknown-- 0x080 + Clock selection 0x100 + Divide by 8(timer 2 only?) 0x200 + + Counter: + Reset to 0 on writes to the mode/status register. + + Status flags: + Unknown flag 0x0400 + Compare flag 0x0800 + Cleared on mode/status read. + Set when: //ever Counter == 0(proooobably, need to investigate lower 3 bits in relation to this). + + + Overflow/Carry flag 0x1000 + Cleared on mode/status read. + Set when counter overflows from 0xFFFF->0. + + Hidden flags: + IRQ done + Cleared on writes to the mode/status register, on writes to the count register, and apparently automatically when the counter + increments if (Mode & 0x40) [Note: If target mode is enabled, and target is 0, IRQ done flag won't be automatically reset] + + There seems to be a brief period(edge condition?) where, if count to target is enabled, you can (sometimes?) read the target value in the count + register before it's reset to 0. I doubt any games rely on this, but who knows. Maybe a PSX equivalent of the PC Engine "Battle Royale"? ;) + + When the counter == 0, the compare flag is set. An IRQ will be generated if (Mode & 0x10), and the hidden IRQ done flag will be set. +*/ + +/* + Dec. 26, 2011 Note + Due to problems I've had with my GPU timing test program, timer2 appears to be unreliable(clocks are skipped?) when target mode is enabled and the full + 33MHz clock is used(rather than 33MHz / 8). TODO: Investigate further and confirm(or not). +*/ + +/* + FIXME: Clock appropriately(and update events) when using SetRegister() via the debugger. +*/ + +namespace MDFN_IEN_PSX +{ + +extern PS_GPU *GPU; + +struct Timer +{ + uint32 Mode; + int32 Counter; // Only 16-bit, but 32-bit here for detecting counting past target. + int32 Target; + + int32 Div8Counter; + + bool IRQDone; + int32 DoZeCounting; +}; + +static bool vblank; +static bool hretrace; +static Timer Timers[3]; +static pscpu_timestamp_t lastts; + +static int32 CalcNextEvent(int32 next_event) +{ + for(int i = 0; i < 3; i++) + { + int32 target; + int32 count_delta; + + if((i == 0 || i == 1) && (Timers[i].Mode & 0x100)) // If clocked by GPU, abort for this timer(will result in poor granularity for pixel-clock-derived timer IRQs, but whatever). + continue; + + if(!(Timers[i].Mode & 0x10)) // If IRQ is disabled, abort for this timer. + continue; + + if((Timers[i].Mode & 0x8) && (Timers[i].Counter == 0) && (Timers[i].Target == 0) && !Timers[i].IRQDone) + { + next_event = 1; + continue; + } + + target = ((Timers[i].Mode & 0x8) && (Timers[i].Counter < Timers[i].Target)) ? Timers[i].Target : 0x10000; + + count_delta = target - Timers[i].Counter; + if(count_delta <= 0) + { + fprintf(stderr, "timer %d count_delta <= 0!!! %d %d\n", i, target, Timers[i].Counter); + continue; + } + + { + int32 tmp_clocks; + + if(Timers[i].DoZeCounting <= 0) + continue; + + if((i == 0x2) && (Timers[i].Mode & 0x1)) + continue; + + if((i == 0x2) && (Timers[i].Mode & 0x200)) + { + assert(Timers[i].Div8Counter >= 0 && Timers[i].Div8Counter < 8); + tmp_clocks = ((count_delta - 1) * 8) + (8 - Timers[i].Div8Counter); + } + else + tmp_clocks = count_delta; + + assert(tmp_clocks > 0); + + if(next_event > tmp_clocks) + next_event = tmp_clocks; + } + } + + return(next_event); +} + +static void ClockTimer(int i, uint32 clocks) +{ + int32 before = Timers[i].Counter; + int32 target = 0x10000; + bool zero_tm = false; + + if(Timers[i].DoZeCounting <= 0) + clocks = 0; + + if(i == 0x2) + { + uint32 d8_clocks; + + Timers[i].Div8Counter += clocks; + d8_clocks = Timers[i].Div8Counter >> 3; + Timers[i].Div8Counter -= d8_clocks << 3; + + if(Timers[i].Mode & 0x200) // Divide by 8, at least for timer 0x2 + clocks = d8_clocks; + + if(Timers[i].Mode & 1) + clocks = 0; + } + + if(Timers[i].Mode & 0x008) + target = Timers[i].Target; + + if(target == 0 && Timers[i].Counter == 0) + zero_tm = true; + else + Timers[i].Counter += clocks; + + if(clocks && (Timers[i].Mode & 0x40)) + Timers[i].IRQDone = false; + + if((before < target && Timers[i].Counter >= target) || zero_tm || Timers[i].Counter > 0xFFFF) + { +#if 1 + if(Timers[i].Mode & 0x10) + { + if((Timers[i].Counter - target) > 3) + printf("Timer %d IRQ trigger error: %d\n", i, Timers[i].Counter - target); + } + +#endif + + + Timers[i].Mode |= 0x0800; + + if(Timers[i].Counter > 0xFFFF) + { + Timers[i].Counter -= 0x10000; + + if(target == 0x10000) + Timers[i].Mode |= 0x1000; + + if(!target) + Timers[i].Counter = 0; + } + + if(target) + Timers[i].Counter -= (Timers[i].Counter / target) * target; + + if((Timers[i].Mode & 0x10) && !Timers[i].IRQDone) + { + Timers[i].IRQDone = true; + + IRQ_Assert(IRQ_TIMER_0 + i, true); + IRQ_Assert(IRQ_TIMER_0 + i, false); + } + + if(Timers[i].Counter && (Timers[i].Mode & 0x40)) + Timers[i].IRQDone = false; + } + +} + +void TIMER_SetVBlank(bool status) +{ + switch(Timers[1].Mode & 0x7) + { + case 0x1: + Timers[1].DoZeCounting = !status; + break; + + case 0x3: + if(vblank && !status) + Timers[1].Counter = 0; + break; + + case 0x5: + Timers[1].DoZeCounting = status; + if(vblank && !status) + Timers[1].Counter = 0; + break; + + case 0x7: + if(Timers[1].DoZeCounting == -1) + { + if(!vblank && status) + Timers[1].DoZeCounting = 0; + } + else if(Timers[1].DoZeCounting == 0) + { + if(vblank && !status) + Timers[1].DoZeCounting = 1; + } + break; + } + vblank = status; +} + +void TIMER_SetHRetrace(bool status) +{ + if(hretrace && !status) + { + if((Timers[0].Mode & 0x7) == 0x3) + Timers[0].Counter = 0; + } + + hretrace = status; +} + +void TIMER_AddDotClocks(uint32 count) +{ + if(Timers[0].Mode & 0x100) + ClockTimer(0, count); +} + +void TIMER_ClockHRetrace(void) +{ + if(Timers[1].Mode & 0x100) + ClockTimer(1, 1); +} + +pscpu_timestamp_t TIMER_Update(const pscpu_timestamp_t timestamp) +{ + int32 cpu_clocks = timestamp - lastts; + + for(int i = 0; i < 3; i++) + { + uint32 timer_clocks = cpu_clocks; + + if(Timers[i].Mode & 0x100) + continue; + + ClockTimer(i, timer_clocks); + } + + lastts = timestamp; + + return(timestamp + CalcNextEvent(1024)); +} + +static void CalcCountingStart(unsigned which) +{ + Timers[which].DoZeCounting = true; + + switch(which) + { + case 1: + switch(Timers[which].Mode & 0x07) + { + case 0x1: + Timers[which].DoZeCounting = !vblank; + break; + + case 0x5: + Timers[which].DoZeCounting = vblank; + break; + + case 0x7: + Timers[which].DoZeCounting = -1; + break; + } + break; + + + } +} + +void TIMER_Write(const pscpu_timestamp_t timestamp, uint32 A, uint16 V) +{ + TIMER_Update(timestamp); + + int which = (A >> 4) & 0x3; + + assert(!(A & 3)); + + PSX_DBGINFO("[TIMER] Write: %08x %04x\n", A, V); + + if(which >= 3) + return; + + // TODO: See if the "Timers[which].Counter" part of the IRQ if() statements below is what a real PSX does. + switch(A & 0xC) + { + case 0x0: Timers[which].IRQDone = false; +#if 1 + if(Timers[which].Counter && (V & 0xFFFF) == 0) + { + Timers[which].Mode |= 0x0800; + if((Timers[which].Mode & 0x10) && !Timers[which].IRQDone) + { + Timers[which].IRQDone = true; + IRQ_Assert(IRQ_TIMER_0 + which, true); + IRQ_Assert(IRQ_TIMER_0 + which, false); + } + } +#endif + Timers[which].Counter = V & 0xFFFF; + break; + + case 0x4: Timers[which].Mode = (V & 0x3FF) | (Timers[which].Mode & 0x1C00); + Timers[which].IRQDone = false; +#if 1 + if(Timers[which].Counter) + { + Timers[which].Mode |= 0x0800; + if((Timers[which].Mode & 0x10) && !Timers[which].IRQDone) + { + Timers[which].IRQDone = true; + IRQ_Assert(IRQ_TIMER_0 + which, true); + IRQ_Assert(IRQ_TIMER_0 + which, false); + } + } + Timers[which].Counter = 0; +#endif + CalcCountingStart(which); // Call after setting .Mode + break; + + case 0x8: Timers[which].Target = V & 0xFFFF; + break; + + default: assert(0); + } + + // TIMER_Update(timestamp); + + PSX_SetEventNT(PSX_EVENT_TIMER, timestamp + CalcNextEvent(1024)); +} + +uint16 TIMER_Read(const pscpu_timestamp_t timestamp, uint32 A) +{ + uint16 ret = 0; + int which = (A >> 4) & 0x3; + + assert(!(A & 3)); + + if(which >= 3) + assert(0); + + TIMER_Update(timestamp); + + switch(A & 0xC) + { + case 0x0: ret = Timers[which].Counter; + break; + + case 0x4: ret = Timers[which].Mode; + Timers[which].Mode &= ~0x1800; + break; + + case 0x8: ret = Timers[which].Target; + break; + + default: assert(0); + } + + return(ret); +} + + +void TIMER_ResetTS(void) +{ + lastts = 0; +} + + +void TIMER_Power(void) +{ + lastts = 0; + + hretrace = false; + vblank = false; + memset(Timers, 0, sizeof(Timers)); +} + +int TIMER_StateAction(StateMem *sm, int load, int data_only) +{ + SFORMAT StateRegs[] = + { +#define SFTIMER(n) SFVARN(Timers[n].Mode, #n "Mode"), \ + SFVARN(Timers[n].Counter, #n "Counter"), \ + SFVARN(Timers[n].Target, #n "Target"), \ + SFVARN(Timers[n].Div8Counter, #n "Div8Counter"), \ + SFVARN(Timers[n].IRQDone, #n "IRQDone") + SFTIMER(0), + SFTIMER(1), + SFTIMER(2), +#undef SFTIMER + SFVAR(lastts), + SFEND + }; + int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "TIMER"); + + if(load) + { + + } + + return(ret); +} + +uint32 TIMER_GetRegister(unsigned int which, char *special, const uint32 special_len) +{ + int tw = (which >> 4) & 0x3; + uint32 ret = 0; + + switch(which & 0xF) + { + case TIMER_GSREG_COUNTER0: + ret = Timers[tw].Counter; + break; + + case TIMER_GSREG_MODE0: + ret = Timers[tw].Mode; + break; + + case TIMER_GSREG_TARGET0: + ret = Timers[tw].Target; + break; + } + + return(ret); +} + +void TIMER_SetRegister(unsigned int which, uint32 value) +{ + int tw = (which >> 4) & 0x3; + + switch(which & 0xF) + { + case TIMER_GSREG_COUNTER0: + Timers[tw].Counter = value & 0xFFFF; + break; + + case TIMER_GSREG_MODE0: + Timers[tw].Mode = value & 0xFFFF; + break; + + case TIMER_GSREG_TARGET0: + Timers[tw].Target = value & 0xFFFF; + break; + } + +} + + +} diff --git a/mednafen/psx-0925/timer.h b/mednafen/psx-0925/timer.h new file mode 100644 index 00000000..a816ad05 --- /dev/null +++ b/mednafen/psx-0925/timer.h @@ -0,0 +1,42 @@ +#ifndef __MDFN_PSX_TIMER_H +#define __MDFN_PSX_TIMER_H + +namespace MDFN_IEN_PSX +{ + +enum +{ + TIMER_GSREG_COUNTER0 = 0x00, + TIMER_GSREG_MODE0, + TIMER_GSREG_TARGET0, + + TIMER_GSREG_COUNTER1 = 0x10, + TIMER_GSREG_MODE1, + TIMER_GSREG_TARGET1, + + TIMER_GSREG_COUNTER2 = 0x20, + TIMER_GSREG_MODE2, + TIMER_GSREG_TARGET2, +}; + +uint32 TIMER_GetRegister(unsigned int which, char *special, const uint32 special_len); +void TIMER_SetRegister(unsigned int which, uint32 value); + + +void TIMER_Write(const pscpu_timestamp_t timestamp, uint32 A, uint16 V); +uint16 TIMER_Read(const pscpu_timestamp_t timestamp, uint32 A); + +void TIMER_AddDotClocks(uint32 count); +void TIMER_ClockHRetrace(void); +void TIMER_SetHRetrace(bool status); +void TIMER_SetVBlank(bool status); + +pscpu_timestamp_t TIMER_Update(const pscpu_timestamp_t); +void TIMER_ResetTS(void); + +void TIMER_Power(void); +int TIMER_StateAction(StateMem *sm, int load, int data_only); + +} + +#endif diff --git a/mednafen/psx/PSX-TODO b/mednafen/psx/PSX-TODO index 9d19939b..7d081352 100644 --- a/mednafen/psx/PSX-TODO +++ b/mednafen/psx/PSX-TODO @@ -5,22 +5,17 @@ Battle Arena Toshinden, Final Fantasy 7 have some kind of GPU timing issues. Zero Divide runs too fast(related to CPU emulation speed?). Chrono Cross has several-second freezes during some large special attack/magic sequences. +----------------------------------------------------------------------------------------------- + Tiny Toon Adventures - Plucky's Big Adventure is failing and BREAK'ing for some reason, maybe memcard related. -Shadow Master has broken startup images. +Shadow Master might have broken startup images. Crusaders of Might and Magic - The CD-XA buffering increase for ToD II is apparently exacerbating the early voice cutoff problem in this game. Crash Team Racing - Noticed a game lockup once in the arcade mode stage select screen, having trouble reproducing it. - -Misadventures of Trone Bonne - Voice problems, lockup, possibly due to excessively long seek delays? - -Dance Dance Revolution - The music is...totally wonky. - -Medal of Honor - Sound issues. - -Fuuraiki - Hangs at black screen when trying to start a new game. +----------------------------------------------------------------------------------------------- Test time delta between GPU LL DMA end and GPU non-busy status for various primitive types in sequence on a PS1. diff --git a/mednafen/psx/cdc.cpp b/mednafen/psx/cdc.cpp index 1b7cf7bb..ec741d84 100644 --- a/mednafen/psx/cdc.cpp +++ b/mednafen/psx/cdc.cpp @@ -554,8 +554,8 @@ void PS_CDC::XA_ProcessSector(const uint8 *sdata, CD_Audio_Buffer *ab) uint8 ibuffer[28]; int16 obuffer[2 + 28]; - //if(param != param_copy) - // printf("%d %02x %02x\n", unit, param, param_copy); + if(param != param_copy) + printf("%d %02x %02x\n", unit, param, param_copy); for(unsigned i = 0; i < 28; i++) { @@ -775,8 +775,8 @@ pscpu_timestamp_t PS_CDC::Update(const pscpu_timestamp_t timestamp) { if(XA_Test(buf)) { - //if(AudioBuffer_ReadPos & 0xFFF) - //printf("readpos=%04x(rabl=%04x) writepos=%04x\n", AudioBuffer_ReadPos, AudioBuffer[AudioBuffer_ReadPos >> 12].Size, AudioBuffer_WritePos); + if(AudioBuffer_ReadPos & 0xFFF) + printf("readpos=%04x(rabl=%04x) writepos=%04x\n", AudioBuffer_ReadPos, AudioBuffer[AudioBuffer_ReadPos >> 12].Size, AudioBuffer_WritePos); //if(AudioBuffer_UsedCount == 0) // AudioBuffer_InPrebuffer = true; @@ -986,7 +986,7 @@ pscpu_timestamp_t PS_CDC::Update(const pscpu_timestamp_t timestamp) const CDC_CTEntry *command = &Commands[PendingCommand]; //PSX_WARNING("[CDC] Command: %s --- %d", command->name, Results.CanRead()); -#if 0 +#if 1 printf("[CDC] Command: %s --- ", command->name); for(unsigned int i = 0; i < ArgsIn; i++) printf(" 0x%02x", ArgsBuf[i]); @@ -1327,7 +1327,7 @@ int32 PS_CDC::CalcSeekTime(int32 initial, int32 target, bool motor_on, bool paus } } - //printf("%d\n", ret); + printf("%d\n", ret); return(ret); } diff --git a/mednafen/psx/cpu.cpp b/mednafen/psx/cpu.cpp index b6fbe57f..4147a501 100644 --- a/mednafen/psx/cpu.cpp +++ b/mednafen/psx/cpu.cpp @@ -54,7 +54,7 @@ void PS_CPU::SetFastMap(void *region_mem, uint32 region_address, uint32 region_s // FAST_MAP_SHIFT // FAST_MAP_PSIZE - for(uint64 A = region_address; A < region_address + region_size; A += FAST_MAP_PSIZE) + for(uint64 A = region_address; A < (uint64)region_address + region_size; A += FAST_MAP_PSIZE) { FastMap[A >> FAST_MAP_SHIFT] = ((uint8 *)region_mem - region_address); } diff --git a/mednafen/psx/debug.cpp b/mednafen/psx/debug.cpp index 5d5fb9e4..c96e2b4a 100644 --- a/mednafen/psx/debug.cpp +++ b/mednafen/psx/debug.cpp @@ -546,10 +546,15 @@ static RegType Regs_SPU_Voices[] = VOICE_HELPER(2), VOICE_HELPER(3), #else - VOICE_HELPER(20), - VOICE_HELPER(21), + VOICE_HELPER(9), + VOICE_HELPER(12), + VOICE_HELPER(17), VOICE_HELPER(22), - VOICE_HELPER(23), + + //VOICE_HELPER(20), + //VOICE_HELPER(21), + //VOICE_HELPER(22), + //VOICE_HELPER(23), #endif { 0, "", "", 0 }, }; diff --git a/mednafen/psx/dis.cpp b/mednafen/psx/dis.cpp index 3da0a36f..bc5ec174 100644 --- a/mednafen/psx/dis.cpp +++ b/mednafen/psx/dis.cpp @@ -28,24 +28,24 @@ struct OpEntry const char *format; }; -#define MASK_OP (0x3F << 26) -#define MASK_FUNC (0x3F) -#define MASK_RS (0x1F << 21) -#define MASK_RT (0x1F << 16) -#define MASK_RD (0x1F << 11) -#define MASK_SA (0x1F << 6) +#define MASK_OP (0x3FU << 26) +#define MASK_FUNC (0x3FU) +#define MASK_RS (0x1FU << 21) +#define MASK_RT (0x1FU << 16) +#define MASK_RD (0x1FU << 11) +#define MASK_SA (0x1FU << 6) -#define MK_OP(mnemonic, format, op, func, extra_mask) { MASK_OP | (op ? 0 : MASK_FUNC) | extra_mask, (op << 26) | func, mnemonic, format } +#define MK_OP(mnemonic, format, op, func, extra_mask) { MASK_OP | (op ? 0 : MASK_FUNC) | extra_mask, ((unsigned)op << 26) | func, mnemonic, format } -#define MK_OP_REGIMM(mnemonic, regop) { MASK_OP | MASK_RT, (0x01 << 26) | (regop << 16), mnemonic, "s, p" } +#define MK_OP_REGIMM(mnemonic, regop) { MASK_OP | MASK_RT, (0x01U << 26) | (regop << 16), mnemonic, "s, p" } -#define MK_COPZ(z) { MASK_OP | (0x1 << 25), (0x1 << 25) | ((0x10 | z) << 26), "cop" #z, "F" } -#define MK_COP0_FUNC(mnemonic, func) { MASK_OP | (0x1 << 25) | MASK_FUNC, (0x10 << 26) | (0x1 << 25) | func, mnemonic, "" } +#define MK_COPZ(z) { MASK_OP | (0x1U << 25), (0x1U << 25) | ((0x10U | z) << 26), "cop" #z, "F" } +#define MK_COP0_FUNC(mnemonic, func) { MASK_OP | (0x1U << 25) | MASK_FUNC, (0x10U << 26) | (0x1U << 25) | func, mnemonic, "" } -#define MK_COPZ_XFER(z, mnemonic, format, xf) { MASK_OP | (0x1F << 21), ((0x10 | z) << 26) | (xf << 21), mnemonic, format } +#define MK_COPZ_XFER(z, mnemonic, format, xf) { MASK_OP | (0x1FU << 21), ((0x10U | z) << 26) | (xf << 21), mnemonic, format } -#define MK_GTE(mnemonic, format, func) { MASK_OP | (0x1 << 25) | MASK_FUNC, (0x1 << 25) | (0x12 << 26) | func, mnemonic, format } +#define MK_GTE(mnemonic, format, func) { MASK_OP | (0x1U << 25) | MASK_FUNC, (0x1U << 25) | (0x12U << 26) | func, mnemonic, format } static OpEntry ops[] = { diff --git a/mednafen/psx/dma.cpp b/mednafen/psx/dma.cpp index 82b76278..85dfca4a 100644 --- a/mednafen/psx/dma.cpp +++ b/mednafen/psx/dma.cpp @@ -434,6 +434,7 @@ void DMA_Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) { int ch = (A & 0x7F) >> 4; + //if(ch == 2 || ch == 7) //PSX_WARNING("[DMA] Write: %08x %08x, DMAIntStatus=%08x", A, V, DMAIntStatus); // FIXME if we ever have "accurate" bus emulation @@ -548,11 +549,6 @@ uint32 DMA_Read(const pscpu_timestamp_t timestamp, uint32 A) { int ch = (A & 0x7F) >> 4; uint32 ret = 0; - - //assert(!(A & 3)); - - //if(ch == 2) - // printf("DMA Read: %08x --- %d\n", A, GPU->GetScanlineNum()); if(ch == 7) { diff --git a/mednafen/psx/frontio.cpp b/mednafen/psx/frontio.cpp index 263f3499..e40fc9e1 100644 --- a/mednafen/psx/frontio.cpp +++ b/mednafen/psx/frontio.cpp @@ -674,7 +674,7 @@ void FrontIO::SetInput(unsigned int port, const char *type, void *ptr) if(port < 2) irq10_pulse_ts[port] = PSX_EVENT_MAXTS; - if(!strcmp(type, "gamepad")) + if(!strcmp(type, "gamepad") || !strcmp(type, "dancepad")) Devices[port] = Device_Gamepad_Create(); else if(!strcmp(type, "dualanalog")) Devices[port] = Device_DualAnalog_Create(false); @@ -882,6 +882,15 @@ static InputDeviceInfoStruct InputDeviceInfoPSXPort[] = Device_Justifier_IDII, }, + { + "dancepad", + "Dance Pad", + "Dingo Dingo Rodeo!", + NULL, + sizeof(Device_Dancepad_IDII) / sizeof(InputDeviceInputInfoStruct), + Device_Dancepad_IDII, + }, + }; static const InputPortInfoStruct PortInfo[] = diff --git a/mednafen/psx/gpu.cpp b/mednafen/psx/gpu.cpp index 3b036588..f032dbe2 100644 --- a/mednafen/psx/gpu.cpp +++ b/mednafen/psx/gpu.cpp @@ -787,6 +787,8 @@ INLINE void PS_GPU::WriteCB(uint32 InData) void PS_GPU::Write(const pscpu_timestamp_t timestamp, uint32 A, uint32 V) { + V <<= (A & 3) * 8; + if(A & 4) // GP1 ("Control") { uint32 command = V >> 24; @@ -965,7 +967,7 @@ uint32 PS_GPU::Read(const pscpu_timestamp_t timestamp, uint32 A) //PSX_WARNING("[GPU READ WHEN (DMACONTROL&2)] 0x%08x - ret=0x%08x, scanline=%d", A, ret, scanline); } - return(ret); + return(ret >> ((A & 3) * 8)); } INLINE void PS_GPU::ReorderRGB_Var(uint32 out_Rshift, uint32 out_Gshift, uint32 out_Bshift, bool bpp24, const uint16 *src, uint32 *dest, const int32 dx_start, const int32 dx_end, int32 fb_x) @@ -1155,11 +1157,7 @@ pscpu_timestamp_t PS_GPU::Update(const pscpu_timestamp_t sys_timestamp) } char buffer[256]; - trio_snprintf(buffer, sizeof(buffer), _("VIDEO STANDARD MISMATCH")); -#ifndef __LIBRETRO__ - DrawTextTrans(surface->pixels + ((DisplayRect->h / 2) - (13 / 2)) * surface->pitch32, surface->pitch32 << 2, DisplayRect->w, (UTF8*)buffer, - surface->MakeColor(0x00, 0xFF, 0x00), true, MDFN_FONT_6x13_12x13); -#endif + /* trio_snprintf(buffer, sizeof(buffer), _("VIDEO STANDARD MISMATCH")); */ } else { diff --git a/mednafen/psx/input/gamepad.cpp b/mednafen/psx/input/gamepad.cpp index d04bb388..d3a6dd84 100644 --- a/mednafen/psx/input/gamepad.cpp +++ b/mednafen/psx/input/gamepad.cpp @@ -211,6 +211,28 @@ InputDeviceInputInfoStruct Device_Gamepad_IDII[16] = { "square", "â–¡ (left)", 8, IDIT_BUTTON_CAN_RAPID, NULL }, }; +InputDeviceInputInfoStruct Device_Dancepad_IDII[16] = +{ + { "select", "SELECT", 0, IDIT_BUTTON, NULL }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { "start", "START", 1, IDIT_BUTTON, NULL }, + + { "up", "UP ↑", 3, IDIT_BUTTON, NULL }, + { "right", "RIGHT →", 6, IDIT_BUTTON, NULL }, + { "down", "DOWN ↓", 8, IDIT_BUTTON, NULL }, + { "left", "LEFT â†", 5, IDIT_BUTTON, NULL }, + + { NULL, "empty", 0, IDIT_BUTTON, NULL }, + { NULL, "empty", 0, IDIT_BUTTON, NULL }, + { NULL, "empty", 0, IDIT_BUTTON, NULL }, + { NULL, "empty", 0, IDIT_BUTTON, NULL }, + + { "triangle", "â–³ (lower left)", 7, IDIT_BUTTON, NULL }, + { "circle", "â—‹ (upper right)", 4, IDIT_BUTTON, NULL }, + { "cross", "x (upper left)", 2, IDIT_BUTTON, NULL }, + { "square", "â–¡ (lower right)", 9, IDIT_BUTTON, NULL }, +}; } diff --git a/mednafen/psx/input/gamepad.h b/mednafen/psx/input/gamepad.h index e43e6de1..5c652b15 100644 --- a/mednafen/psx/input/gamepad.h +++ b/mednafen/psx/input/gamepad.h @@ -6,6 +6,7 @@ namespace MDFN_IEN_PSX InputDevice *Device_Gamepad_Create(void); extern InputDeviceInputInfoStruct Device_Gamepad_IDII[16]; +extern InputDeviceInputInfoStruct Device_Dancepad_IDII[16]; } #endif diff --git a/mednafen/psx/psx.cpp b/mednafen/psx/psx.cpp index 45df1247..220bf3c4 100644 --- a/mednafen/psx/psx.cpp +++ b/mednafen/psx/psx.cpp @@ -15,10 +15,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __LIBRETRO__ -#define HAVE_PSF 1 -#endif - #include "psx.h" #include "mdec.h" #include "frontio.h" @@ -26,13 +22,7 @@ #include "sio.h" #include "cdc.h" #include "spu.h" -#include "../mednafen-endian.h" #include "../mempatcher.h" -#ifdef HAVE_PSF -#include "../PSFLoader.h" -#include "../player.h" -#endif - #include "../cputest/cputest.h" extern MDFNGI EmulatedPSX; @@ -40,20 +30,6 @@ extern MDFNGI EmulatedPSX; namespace MDFN_IEN_PSX { -#ifdef HAVE_PSF -class PSF1Loader : public PSFLoader -{ - public: - - PSF1Loader(MDFNFILE *fp); - virtual ~PSF1Loader(); - - virtual void HandleEXE(const uint8 *data, uint32 len, bool ignore_pcsp = false); - - PSFTags tags; -}; -#endif - enum { REGION_JP = 0, @@ -67,10 +43,6 @@ static uint32 ReadCounter = 0; static uint32 WriteCounter = 0; #endif -#ifdef HAVE_PSF -static PSF1Loader *psf_loader = NULL; -#endif - static std::vector *cdifs = NULL; static std::vector cdifs_scex_ids; static bool CD_TrayOpen; @@ -587,7 +559,7 @@ template static INLINE void return; } - if(A >= 0x1F801100 && A <= 0x1F80112F) // Root counters + if(A >= 0x1F801100 && A <= 0x1F80113F) // Root counters { if(IsWrite) TIMER_Write(timestamp, A, V); @@ -777,15 +749,11 @@ static void Emulate(EmulateSpecStruct *espec) { pscpu_timestamp_t timestamp = 0; -#ifdef __LIBRETRO__ - espec->skip = false; -#else if(FIO->RequireNoFrameskip()) { //puts("MEOW"); espec->skip = false; //TODO: Save here, and restore at end of Emulate() ? } -#endif MDFNGameInfo->mouse_sensitivity = MDFN_GetSettingF("psx.input.mouse_sensitivity"); @@ -796,19 +764,11 @@ static void Emulate(EmulateSpecStruct *espec) espec->SoundBufSize = 0; FIO->UpdateInput(); -#ifdef HAVE_PSF - GPU->StartFrame(psf_loader ? NULL : espec); -#else GPU->StartFrame(espec); -#endif SPU->StartFrame(espec->SoundRate, MDFN_GetSettingUI("psx.spu.resamp_quality")); Running = -1; -#ifdef HAVE_PSF - timestamp = CPU->Run(timestamp, psf_loader != NULL); -#else timestamp = CPU->Run(timestamp, false); -#endif assert(timestamp); @@ -830,17 +790,6 @@ static void Emulate(EmulateSpecStruct *espec) espec->MasterCycles = timestamp; -#ifdef HAVE_PSF - if(psf_loader) - { - if(!espec->skip) - { - espec->LineWidths[0].w = ~0; - Player_Draw(espec->surface, &espec->DisplayRect, 0, espec->SoundBuf, espec->SoundBufSize); - } - } -#endif - // Save memcards if dirty. for(int i = 0; i < 8; i++) { @@ -857,7 +806,7 @@ static void Emulate(EmulateSpecStruct *espec) Memcard_SaveDelay[i] += timestamp; if(Memcard_SaveDelay[i] >= (33868800 * 2)) // Wait until about 2 seconds of no new writes. { - //fprintf(stderr, "Saving memcard %d...\n", i); + fprintf(stderr, "Saving memcard %d...\n", i); try { char ext[64]; @@ -893,11 +842,6 @@ static void Emulate(EmulateSpecStruct *espec) static bool TestMagic(const char *name, MDFNFILE *fp) { -#ifdef HAVE_PSF - if(PSFLoader::TestMagic(0x01, fp)) - return(true); -#endif - if(fp->size < 0x800) return(false); @@ -1461,31 +1405,10 @@ static void LoadEXE(const uint8 *data, const uint32 size, bool ignore_pcsp = fal } -#ifdef HAVE_PSF -PSF1Loader::PSF1Loader(MDFNFILE *fp) -{ - tags = Load(0x01, 2033664, fp); -} - -PSF1Loader::~PSF1Loader() -{ - -} - -void PSF1Loader::HandleEXE(const uint8 *data, uint32 size, bool ignore_pcsp) -{ - LoadEXE(data, size, ignore_pcsp); -} -#endif - static void Cleanup(void); static int Load(const char *name, MDFNFILE *fp) { -#ifdef HAVE_PSF - const bool IsPSF = PSFLoader::TestMagic(0x01, fp); -#else - const bool IsPSF = false; -#endif + const bool IsPSF = false; if(!TestMagic(name, fp)) { @@ -1514,19 +1437,6 @@ static int Load(const char *name, MDFNFILE *fp) try { -#ifdef HAVE_PSF - if(IsPSF) - { - psf_loader = new PSF1Loader(fp); - - std::vector SongNames; - - SongNames.push_back(psf_loader->tags.GetTag("title")); - - Player_Init(1, psf_loader->tags.GetTag("game"), psf_loader->tags.GetTag("artist"), psf_loader->tags.GetTag("copyright"), SongNames); - } - else -#endif LoadEXE(fp->data, fp->size); } catch(std::exception &e) @@ -1544,8 +1454,8 @@ static int LoadCD(std::vector *CDInterfaces) int ret = InitCommon(CDInterfaces); // TODO: fastboot setting - if(MDFN_GetSettingB("psx.fastboot")) - BIOSROM->WriteU32(0x6990, 0); + //if(MDFN_GetSettingB("psx.fastboot")) + // BIOSROM->WriteU32(0x6990, 0); MDFNGameInfo->GameType = GMT_CDROM; @@ -1556,14 +1466,6 @@ static void Cleanup(void) { TextMem.resize(0); -#ifdef HAVE_PSF - if(psf_loader) - { - delete psf_loader; - psf_loader = NULL; - } -#endif - if(CDC) { delete CDC; @@ -1613,9 +1515,6 @@ static void Cleanup(void) static void CloseGame(void) { -#ifdef HAVE_PSF - if(!psf_loader) -#endif { for(int i = 0; i < 8; i++) { @@ -1641,11 +1540,6 @@ static void CloseGame(void) static void SetInput(int port, const char *type, void *ptr) { -#ifdef HAVE_PSF - if(psf_loader) - FIO->SetInput(port, "none", NULL); - else -#endif FIO->SetInput(port, type, ptr); } @@ -1761,10 +1655,8 @@ static void DoSimpleCommand(int cmd) static const FileExtensionSpecStruct KnownExtensions[] = { -#ifdef HAVE_PSF { ".psf", gettext_noop("PSF1 Rip") }, { ".minipsf", gettext_noop("MiniPSF1 Rip") }, -#endif { ".psx", gettext_noop("PS-X Executable") }, { ".exe", gettext_noop("PS-X Executable") }, { NULL, NULL } @@ -1806,7 +1698,7 @@ static MDFNSetting PSXSettings[] = { "psx.input.port7.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 2C."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0x0080FF", "0x000000", "0x1000000" }, { "psx.input.port8.gun_chairs", MDFNSF_NOFLAGS, gettext_noop("Crosshairs color for lightgun on port 2D."), gettext_noop("A value of 0x1000000 disables crosshair drawing."), MDFNST_UINT, "0x8000FF", "0x000000", "0x1000000" }, - { "psx.fastboot", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Skip BIOS intro sequence."), gettext_noop("MAY BREAK GAMES."), MDFNST_BOOL, "0" }, + //{ "psx.fastboot", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Skip BIOS intro sequence."), gettext_noop("MAY BREAK GAMES."), MDFNST_BOOL, "0" }, { "psx.region_autodetect", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Attempt to auto-detect region of game."), NULL, MDFNST_BOOL, "1" }, { "psx.region_default", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Default region to use."), gettext_noop("Used if region autodetection fails or is disabled."), MDFNST_ENUM, "jp", NULL, NULL, NULL, NULL, Region_List }, diff --git a/mednafen/psx/psx.h b/mednafen/psx/psx.h index c197bd4d..334159ca 100644 --- a/mednafen/psx/psx.h +++ b/mednafen/psx/psx.h @@ -9,10 +9,8 @@ #include "../general.h" #include "../FileWrapper.h" -//#define PSX_WARNING(format, ...) { printf(format "\n", ## __VA_ARGS__); } -//#define PSX_DBGINFO(format, ...) { /*printf(format "\n", ## __VA_ARGS__);*/ } -#define PSX_WARNING(format, ...) -#define PSX_DBGINFO(format, ...) +#define PSX_WARNING(format, ...) { printf(format "\n", ## __VA_ARGS__); } +#define PSX_DBGINFO(format, ...) { /*printf(format "\n", ## __VA_ARGS__);*/ } namespace MDFN_IEN_PSX { diff --git a/mednafen/psx/spu.cpp b/mednafen/psx/spu.cpp index 4eaa54fa..227b0532 100644 --- a/mednafen/psx/spu.cpp +++ b/mednafen/psx/spu.cpp @@ -770,7 +770,7 @@ int32 PS_SPU::UpdateFromCDC(int32 clocks) voice->CurPhase_SD += phase_inc; } - if(!(SPUControl & 0x8000) || (VoiceOff & (1 << voice_num))) + if(VoiceOff & (1 << voice_num)) { if(voice->ADSR.Phase != ADSR_RELEASE) { @@ -778,7 +778,7 @@ int32 PS_SPU::UpdateFromCDC(int32 clocks) } } - if((SPUControl & 0x8000) && (VoiceOn & (1 << voice_num))) + if(VoiceOn & (1 << voice_num)) { ResetEnvelope(voice); @@ -796,6 +796,12 @@ int32 PS_SPU::UpdateFromCDC(int32 clocks) voice->CurAddr = voice->StartAddr & ~0x7; } + + if(!(SPUControl & 0x8000)) + { + voice->ADSR.Phase = ADSR_RELEASE; + voice->ADSR.EnvLevel = 0; + } } VoiceOff = 0; @@ -1173,6 +1179,7 @@ void PS_SPU::StartFrame(double rate, uint32 quality) { if((int)rate != last_rate || quality != last_quality) { + //double ratio = (double)44100 / (rate ? rate : 44100); int err = 0; last_rate = (int)rate; diff --git a/mednafen/psx/timer.cpp b/mednafen/psx/timer.cpp index f3b9815e..1e348e79 100644 --- a/mednafen/psx/timer.cpp +++ b/mednafen/psx/timer.cpp @@ -71,13 +71,13 @@ /* FIXME: Clock appropriately(and update events) when using SetRegister() via the debugger. + + TODO: If we ever return randomish values to "simulate" open bus, remember to change the return type and such of the TIMER_Read() function to full 32-bit too. */ namespace MDFN_IEN_PSX { -extern PS_GPU *GPU; - struct Timer { uint32 Mode; @@ -337,7 +337,7 @@ void TIMER_Write(const pscpu_timestamp_t timestamp, uint32 A, uint16 V) int which = (A >> 4) & 0x3; - assert(!(A & 3)); + V <<= (A & 3) * 8; PSX_DBGINFO("[TIMER] Write: %08x %04x\n", A, V); @@ -384,7 +384,8 @@ void TIMER_Write(const pscpu_timestamp_t timestamp, uint32 A, uint16 V) case 0x8: Timers[which].Target = V & 0xFFFF; break; - default: assert(0); + case 0xC: // Open bus + break; } // TIMER_Update(timestamp); @@ -397,10 +398,12 @@ uint16 TIMER_Read(const pscpu_timestamp_t timestamp, uint32 A) uint16 ret = 0; int which = (A >> 4) & 0x3; - assert(!(A & 3)); - if(which >= 3) - assert(0); + { + PSX_WARNING("[TIMER] Open Bus Read: 0x%08x", A); + + return(ret >> ((A & 3) * 8)); + } TIMER_Update(timestamp); @@ -416,10 +419,11 @@ uint16 TIMER_Read(const pscpu_timestamp_t timestamp, uint32 A) case 0x8: ret = Timers[which].Target; break; - default: assert(0); + case 0xC: PSX_WARNING("[TIMER] Open Bus Read: 0x%08x", A); + break; } - return(ret); + return(ret >> ((A & 3) * 8)); } diff --git a/mednafen/tremor/Makefile.am b/mednafen/tremor/Makefile.am deleted file mode 100644 index 371106cd..00000000 --- a/mednafen/tremor/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -DEFS = @DEFS@ @CFLAG_VISIBILITY@ -INCLUDES = -I./ - -noinst_LIBRARIES = libvorbisidec.a - -libvorbisidec_a_SOURCES = mdct.c block.c window.c \ - synthesis.c info.c \ - floor1.c floor0.c vorbisfile.c \ - res012.c mapping0.c registry.c codebook.c \ - sharedbook.c framing.c bitwise.c \ - codebook.h misc.h mdct_lookup.h\ - os.h mdct.h block.h ivorbisfile.h lsp_lookup.h\ - registry.h window.h window_lookup.h\ - codec_internal.h backends.h ogg.h \ - asm_arm.h ivorbiscodec.h diff --git a/mednafen/tremor/Makefile.in b/mednafen/tremor/Makefile.in deleted file mode 100644 index ac7dbd0d..00000000 --- a/mednafen/tremor/Makefile.in +++ /dev/null @@ -1,623 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@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@ -subdir = src/tremor -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - COPYING -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_gcc_option.m4 \ - $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/fcntl-o.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \ - $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \ - $(top_srcdir)/m4/inttypes-pri.m4 \ - $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \ - $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/uintmax_t.m4 \ - $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/m4/wchar_t.m4 \ - $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xsize.m4 \ - $(top_srcdir)/acinclude.m4 $(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 = -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -AM_V_AR = $(am__v_AR_$(V)) -am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) -am__v_AR_0 = @echo " AR " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -libvorbisidec_a_AR = $(AR) $(ARFLAGS) -libvorbisidec_a_LIBADD = -am_libvorbisidec_a_OBJECTS = mdct.$(OBJEXT) block.$(OBJEXT) \ - window.$(OBJEXT) synthesis.$(OBJEXT) info.$(OBJEXT) \ - floor1.$(OBJEXT) floor0.$(OBJEXT) vorbisfile.$(OBJEXT) \ - res012.$(OBJEXT) mapping0.$(OBJEXT) registry.$(OBJEXT) \ - codebook.$(OBJEXT) sharedbook.$(OBJEXT) framing.$(OBJEXT) \ - bitwise.$(OBJEXT) -libvorbisidec_a_OBJECTS = $(am_libvorbisidec_a_OBJECTS) -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) -am__v_lt_0 = --silent -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) -am__v_CC_0 = @echo " CC " $@; -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libvorbisidec_a_SOURCES) -DIST_SOURCES = $(libvorbisidec_a_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CXXFLAGS = @AM_CXXFLAGS@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ @CFLAG_VISIBILITY@ -DEPDIR = @DEPDIR@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GBA_EXTRA_FLAGS = @GBA_EXTRA_FLAGS@ -GENCAT = @GENCAT@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GLIBC2 = @GLIBC2@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GREP = @GREP@ -HAVE_ASPRINTF = @HAVE_ASPRINTF@ -HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ -HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ -HAVE_SNPRINTF = @HAVE_SNPRINTF@ -HAVE_VISIBILITY = @HAVE_VISIBILITY@ -HAVE_WPRINTF = @HAVE_WPRINTF@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_DEFAULT_VERBOSITY = @INTL_DEFAULT_VERBOSITY@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -JACK_CFLAGS = @JACK_CFLAGS@ -JACK_LIBS = @JACK_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@ -LIBCDIO_LIBS = @LIBCDIO_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBMULTITHREAD = @LIBMULTITHREAD@ -LIBOBJS = @LIBOBJS@ -LIBPTH = @LIBPTH@ -LIBPTH_PREFIX = @LIBPTH_PREFIX@ -LIBS = @LIBS@ -LIBTHREAD = @LIBTHREAD@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBC = @LTLIBC@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ -LTLIBOBJS = @LTLIBOBJS@ -LTLIBPTH = @LTLIBPTH@ -LTLIBTHREAD = @LTLIBTHREAD@ -MAKEINFO = @MAKEINFO@ -MATH_OPTIMIZER_FLAGS = @MATH_OPTIMIZER_FLAGS@ -MKDIR_P = @MKDIR_P@ -MMX_CFLAGS = @MMX_CFLAGS@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POSUB = @POSUB@ -PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ -SNDFILE_LIBS = @SNDFILE_LIBS@ -SNES_EXTRA_CXXFLAGS = @SNES_EXTRA_CXXFLAGS@ -SNES_EXTRA_FLAGS = @SNES_EXTRA_FLAGS@ -SSE2_CFLAGS = @SSE2_CFLAGS@ -SSE3_CFLAGS = @SSE3_CFLAGS@ -SSE_CFLAGS = @SSE_CFLAGS@ -STRIP = @STRIP@ -TRIO_CFLAGS = @TRIO_CFLAGS@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WARNING_FLAGS = @WARNING_FLAGS@ -WINDRES = @WINDRES@ -WOE32 = @WOE32@ -WOE32DLL = @WOE32DLL@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -XMKMF = @XMKMF@ -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_DUMPBIN = @ac_ct_DUMPBIN@ -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@ -lt_ECHO = @lt_ECHO@ -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 = -I./ -noinst_LIBRARIES = libvorbisidec.a -libvorbisidec_a_SOURCES = mdct.c block.c window.c \ - synthesis.c info.c \ - floor1.c floor0.c vorbisfile.c \ - res012.c mapping0.c registry.c codebook.c \ - sharedbook.c framing.c bitwise.c \ - codebook.h misc.h mdct_lookup.h\ - os.h mdct.h block.h ivorbisfile.h lsp_lookup.h\ - registry.h window.h window_lookup.h\ - codec_internal.h backends.h ogg.h \ - asm_arm.h ivorbiscodec.h - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tremor/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/tremor/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: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libvorbisidec.a: $(libvorbisidec_a_OBJECTS) $(libvorbisidec_a_DEPENDENCIES) - $(AM_V_at)-rm -f libvorbisidec.a - $(AM_V_AR)$(libvorbisidec_a_AR) libvorbisidec.a $(libvorbisidec_a_OBJECTS) $(libvorbisidec_a_LIBADD) - $(AM_V_at)$(RANLIB) libvorbisidec.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitwise.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/block.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebook.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/floor0.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/floor1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/framing.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapping0.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdct.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/registry.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/res012.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sharedbook.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synthesis.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vorbisfile.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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 $@ $< - -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; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - 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; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - 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)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__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 "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$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) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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 - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -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/mednafen/trio/CHANGES b/mednafen/trio/CHANGES deleted file mode 100644 index fec2926f..00000000 --- a/mednafen/trio/CHANGES +++ /dev/null @@ -1,785 +0,0 @@ -CHANGES -- trio - - -The changes listed without a name attributed to them were most likely done by -Bjorn Reese and/or Daniel Stenberg. - -Version 1.14 - 2010/01/26 -------------------------- -* David Byron - Added trio_xstring_append_max. - -* Fixed compilation problem on Cygwin due to lack of long double math - (reported by Matthias Andree). - -* David Boyce - Added #undef of standard stdio function names before assigning trio functions - to them. - -* Matthias Andree - Upgraded configure.in to use new macros instead of obsoleted macros. - -* Matthias Andree - Added VPATH to Makefile.in - -* Tom Honermann - Fixed problem with subnormal numbers which caused an infinite loop outputting - leading spaces. - -* Adam McLaurin - Improved parsing performance by avoiding memset() and memcpy() on character - arrays. - -* Gideon Smeding - Fixed %u scanning of signed numbers. - -* Gideon Smeding - Fixed group scanning for non-matching input. - -* Fixed missing undo of look-ahead reading for scanf functions. This does only - work for the scanf* and fscanf* functions, not dscanf* and cscanf* functions - (reported by Gideon Smeding). - -* If the format string is empty, scanf does not attempt to read any input. - -* Ralf Junker - Fixed Borland compilation for user-defined specifiers. - - -Version 1.13 - 2008/11/09 -------------------------- -* Ives Aerts - Added the $ format for user-defined specifiers, which is - compatible with compiler warnings about mismatches between specifiers and - arguments. - -* Added TRIO_DEPRECATED flag (reported by David Boyce) - -* Fixed rounding adjustment for long double (reported as bug item #2136686). - -* Added Makefile dependency for test target (reported as bug item #2136636). - -* David Boyce - Fixed long long support for MSVC. - -* Fixed potential problem with read after buffer end for non-zero terminated - strings (reported as bug item #1828465). - -* Andreas Stricker - Added WinCE support. - -* Fixed number of significant digits for %g. - - -Version 1.12 - 2006/10/22 -------------------------- -* Fixed scanning of floats (reported by Bernd Ahlers). - -* Fixed configure.in for GCC on Tru64 and MIPSpro on IRIX (reported by Andreas - Maus). - -* Olli Savia - Added support for LynxOS. - - -Version 1.11 - 2006/04/08 -------------------------- -* Mark Pickelmann - Fixed trio_unregister. If the first element was removed, the remaining - list would be removed as well. - -* Fixed unintended formatting of %e that would result in non-zero numbers - starting with zero (reported by Mark Pickelmann and Gisli Ottarsson). - -* Fixed compilation with Sun Workshop 6 (reported by Matthias Andree). - -* Fixed accuracy for denormalized numbers (bug item #758327). - -* Glen Davidson - Fixed scanning of floating-point numbers without a decimal-point (bug item - #1370427). - -* David Byron - Fixed more compiler warnings. - -* Fixed compilation of trio_to_long_double and TRIO_FEATURE_FLOAT (reported by - David Byron). - -* Fixed precision of large floating-point numbers (bug item #1314524). - -* Karl Bochert - Fixed trio_fpclassify_and_signbit to only restore the floating-point - precision. - -* Fixed detection of need for ieee option on FreeBSD/Alpha. - -* Added TRIO_SNPRINTF_ONLY compilation. - -* Fixed trio_to_double by not using strtod() on Tru64/DECC because it does not - support hex-floats. - -* Fixed crash on 64 bits machines related to a previous workaround in version - 1.9 for uninitialized va_list (reported by Nicolai Tufar, suggestion by - Douglas Gwyn). - -* Patrick Jessee - Fixed width calculation for %g. - -* Added macros for internal features. - -* Jon Foster - Added macros for conditional compilation of many features. Documented all - the features. - -* Karl Bochert - Fixed problem with Borland C++, which changes the floating-point precision - for certain math functions (log10() and _fpclass()). - -* Karl Bochert - Fixed compilation warnings on Borland C++. - -* Removed any occurrence of #elif because Borland C++ reports wrong line - numbers when they are present (reported by Karl Bochert). - -* David Byron - Added trio_asprintfv. - -* Brian Chapman - Fixed Mac OS X compilation. - -* David Byron - Fixed several compiler warnings. - -* Fixed printing of out-of-range arguments for %hhd and %hd. These arguments - can be out of range because of default integer promotion. - -* Bob Friesenhahn - Fixed installation of header files. - -* Joe Orton - Added SHELL to Makefile.in to avoid problems with CShells. - -* Shaun Tancheff - Fixed regresion tests for MSVC. - -* Craig Berry - Fixed the VMS C99 workaround. - - -Version 1.10 - 2003/03/06 -------------------------- -* Rearranged some include files to accommodate large file support (reported by - Albert Chin-A-Young). - -* Added support for SunOS 4.1.x lack of strerror, tolower, and toupper - (reported by Peter McCluskey). - -* Fixed pedantic compilation with TRIO_MINIMAL. - -* Jose Kahan - Moved to avoid redefinition problems. - -* Fixed hex-float exponents (reported by Matthias Clasen). - -* Fixed handling of negative width and precision via paramters (reported by - Jacob Navia). - -* Nigel Hall - Fixed TRIO_VA_START for VMS. - -* Rune Enggaard Lausen - Fixed compilation for Borland C++ Builder. - -* Fixed precision of hex-float numbers (reported by James Antill). - -* Fixed plus sign only to be added for signed numbers. - -* Fixed printing of integers with value and precision of zero (reported by - James Antill). - -* Fixed %#.o to only print one zero if the value is zero (reported by James - Antill). - -* Rewrote check for IEEE compilation option to remove dependency on additional - scripts. - -* Mehdi Lavasani - Makefile install target fixed to work with older install programs. - -* Collapsed the DECC, MSVC, HP-UX, and AIX code for trio_fpclassify_and_sign() - with further preprocessing. - - -Version 1.9 - 2002/10/13 ------------------------- -* Fixed trio_fpclassify_and_signbit on AIX 3.2 - -* Added configure check for -ieee/-mieee compilation option for Alpha machines. - -* Craig Berry - Fixed compilation on VMS. - -* Albert Chin-A-Young - Fixed incorrect conditional expression in trio_isinf. - -* Fixed the warnings about uninitialized va_list in the printfv and scanfv - family without the use of compiler specific pragmas (suggested by Ian - Pilcher). - -* Fixed space flag for floating-point numbers (reported by Ian Main). - - -Version 1.8 - 2002/07/10 ------------------------- -* Fixed infinite loop in multibyte handling (reported by Gisli Ottarsson). - -* Added the customizable cprintf/cscanf family which enables to user to specify - input and output stream functions (suggested by Florian Schulze). - -* Fixed trio_isinf by removing the HP-UX workaround, and instead making sure - that the C99 macro will adhere to the trio return values (reported by Luke - Dunstan). - -* Alexander Lukyanov - Fixed boundary case for scanning and EOF. - -* Jacob Navia - Enabled the L modifier for formatting. - -* Added TRIO_MINIMAL to build trio without the string functions. - -* Added the R modifier to print rounded floating-point numbers. - -* Added trio_to_long_double and long double scanning (the L modifier). - -* Added trio_locale_decimal_point, trio_locale_thousand_separator, - trio_locale_grouping to overwrite locale settings. - -* Rewrote TrioWriteDouble to avoid temporary buffers and thus the danger of - buffer overflows (for instance %.5000f). - -* Improved floating-point formatting accuracy. - -* Fixed formatting of non-decimal exponents. - -* Fixed thousand separator checking. - -* Fixed %f scanning to get a float and %lf to get a double. - -* Fixed WIN32 compilation (reported by Emmanuel Mogenet) - -* Fixed regression test cases to exclude disabled features. - - -Version 1.7 - 2002/05/07 ------------------------- -* Fixed trio_to_double to handle hex-floats properly. - -* Fixed printing of %a-format to be like %e, not like %g. - -* Fixed floating-point printing of values beyond the machine accuracy. - -* Fixed %f for printing with large precision. - -* Fixed the usage of C99 nan(), which caused a crash on OSF/1 (reported by - Georg Bolz) - -* Joe Orton - Fixed %p on 64-bit platforms. - -* Made trio compile with K&R compilers. - -* Emmanuel Mogenet - Fixed bug in trio_asprintf. - -* Emmanuel Mogenet - Various WIN32 fixes. - -* Joe Orton - Fixed trio_isinf() on HP-UX, and added test cases. - -* Joe Orton - Fixed non-portable use of $^ in Makefile. - -* Joe Orton - Added autoconf. - -* Alexander Lukyanov - Fixed a number of bugs in the scanning of EOF and the count specifier. - -* Richard Jinks - Added trio_nzero - -* Fixed incorrect handling of return code from TrioReadChar (reported by - Henrik Löf) - -* Fixed parsing of character class expressions. - -* Fixed trio_to_double which did not work with long fractions. - -* Fixed %f for printing of large numbers. - -* Fixed %#s to handle whitespaces as non-printable characters. - -* Added trio_isfinite, trio_signbit, and trio_fpclassify. - -* Added new test cases. - - -Version 1.6 - 2002/01/13 ------------------------- -* Added dynamic string functions. - -* Rewrote and extended documentation in JavaDoc (using Doxygen). - -* Moved and renamed strio functions to triostr. - -* Robert Collins - Added definition for Cygwin. - -* Markus Henke - Added long double workaround for the HP C/iX compiler. - -* Marc Verwerft - Improved error handling for dynamically allocated strings. - -* John Fotheringham - Made trionan compile on OpenVMS. - -* Added 'd' and 'D' as exponent letters when using TRIO_MICROSOFT. - -* Fixed uninitial memory read for the parameter modifiers. - - -Version 1.5 - 2001/09/08 ------------------------- -* Merged with libxml changes. - -* Moved NaN and Inf handling to separate file to enable reuse in other - projects. - -* Igor Zlatkovic - Fixed TrioGenerateNan for MSVC. - -* Fixed lots of preprocessor macros and internal data structure names. - - -Version 1.4 - 2001/06/03 ------------------------- -* Added hex-float (%a and %A) for scanning. - -* Added wide character arguments (%ls, %ws, %S, %lc, %wc, and %C) for both - printf and scanf. - -* Added mutex callbacks for user-specified specifiers to enable applications to - add thread-safety. These are registered with trio_register, where the - namespace is set to either ":enter" to lock a mutex, or ":leave" to unlock a - mutex. - -* Added equivalence class expressions for scanning. For example, %[[=a=]] scans - for all letters in the same equivalence class as the letter 'a' as defined - by the locale. - -* Changed character class expressions for scanning. The expressions must now - be embedded withing an extra set of brackets, e.g. %[[:alpha:]]. This was - done to adhere to the syntax of UNIX98 regular expressions. - -* Added the possibility to specify standard support (TRIO_C99 etc.) as compiler - options. - -* Fixed conversion of hex-float in StrToDouble. - -* Fixed formatting of hex-float numbers. - -* Stan Boehm - Fixed crash on QNX, which happend because some buffers on the stack were too - big. - -* Fixed default precision for %f and %g (reported by Jose Ortiz) - -* Howard Kapustein - Added the I8, I16, I32, and I64 modifiers. - -* Jose Ortiz - Fixed rounding problem for %e. - -* Jose Ortiz - Fixed various problems with the xlC and Sun C++ compilers. - - -Version 1.3 - 2001/05/16 ------------------------- -* trio's treatment of the field width when the %e code was used was not - correct (reported by Gisli Ottarsson). It turns out the fraction part should - be zero-padded by default and the exponent part should be zero-prefixed if - it is only one digit. At least that's how the GNU and Sun libc's work. The - trio floating point output looks identical to them now. - -* Fixed group scanning with modifiers. - -* Fixed compilation for 64-bit Digital Unix. - -* Igor Zlatkovic - Fixed compilation of dprintf, which uses read/write, for MSVC. - -* Fixed various compilation problems on Digital Unix (mainly associated with - va_list). - - -Version 1.2 - 2001/04/11 ------------------------- -* Added autoconf integration. If compiled with HAVE_CONFIG_H the following - happens. Firstly, is included. Secondly, trio will only be - compiled if WITH_TRIO is defined herein. Thirdly, if TRIO_REPLACE_STDIO is - defined, only stdio functions that have not been detected by autoconf, i.e. - those not defined by HAVE_PRINTF or similar, will be replaced by trio - functions (suggested by Daniel Veillard). - -* Fixed '%m.nf' output. Previously trio did not treat the width properly - in all cases (reported by Gisli Ottarsson). - -* Added explicit promotion for the scanfv family. - -* Fixed more C++ compilation warnings. - - -Version 1.1 - 2001/02/25 ------------------------- -* Added explicit promotion for the printfv familiy. A float must be specified - by %hf. - -* Fixed positionals for printfv (reported by Gisli Ottarsson). - -* Fixed an integer to pointer conversion problem on the SGI MIPS C compiler - (reported by Gisli Ottarsson). - -* Fixed ANSI C++ warnings (type casting, and namespace is a reserved keyword). - -* Added \n to all examples in the documentation to prevent confusion. - -* Fixed StrSubstringMax - - -Version 1.0 - 2000/12/10 ------------------------- -* Bumped Version number. - - -Version 0.25 - 2000/12/09 -------------------------- -* Wrote more documentation. - -* Improved NaN support and added NaN to regression test. - -* Fixed C99 support. - -* Added missing getter/setter functions. - - -Version 0.24 - 2000/12/02 -------------------------- -* Added callback functionality for the user-defined specifier (<>). All - the necessary functions are defined in triop.h header file. See the - documentation for trio_register for further detail. - -* Wrote initial documentation on the callback functionality. - -* Added the printfv and scanfv family of functions, which takes a pointer - array rather than variadic arguments. Each pointer in the array must point - to the associated data (requested by Bruce Korb). - -* As indicated in version 0.21 the extension modifiers (<>) have now been - completely removed. - -* Added skipping of thousand-separators in floating-point number scanning. - - -Version 0.23 - 2000/10/21 -------------------------- -* Added width to scanning of floating-point numbers. - -* Wrote more documentation on trio_printf. - -* Fixed problem with trailing zeroes after decimal-point. - - -Version 0.22 - 2000/08/06 -------------------------- -* Added LC_CTYPE locale dependent character class expressions to scan lists. - Included are [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:], - [:lower:], [:print:], [:punct:], [:space:], [:upper:], [:xdigit:] - -* Added C escapes to alternative string formatting and scanning. - -* Added StrSubstringMax. - -* Wrote a little more documentation. - -* Fixed scanf return values. - -* Fixed a sign error for non-ascii characters. - - -Version 0.21 - 2000/07/19 -------------------------- -* Converted the documentation to TeX. With latex2man the documentation can - automatically be converted into man pages. - -* Added trio_scanf, trio_vscanf, trio_fscanf, and trio_vfscanf. - -* Added trio_dprintf, trio_vdprintf, trio_dscanf, and trio_vdscanf. These - functions can be used to write and read directly to pipes and sockets (the - assume blocking sockets). Stdio buffering is surpassed, so the functions are - async-safe. However, reading from stdin (STDIN_FILENO) or writing to stdout - (STDOUT_FILENO) reintroduces the buffering. - -* Paul Janzen - Added trio_asprintf and trio_vasprintf, which are compatible with the GNU - and BSD interfaces. - -* Added scanlist ranges for group scanning (%[]). - -* Added width for scanning (missing for floating-point numbers though). - -* Added variable size modifier (&) to handle system defined types of unknown - size. This modifier makes certain assumptions about the integer sizes, which - may not be valid on any machine. Consequently, the modifier will remain - undocumented, as it may be removed later. - -* Added \777 and \xFF to alternative string scanning (%#s) - -* Added the TRIO_REPLACE_STDIO check in the header. - -* Improved performance of the multibyte character parsing. - -* Fixed positionals (%n$) which had stopped working. - -* Fixed hh and ll modifiers to allow exactly two letters and no more. - -* Fixed ANSI C++ warnings. Also fixed the compiler warning about casting - between integer and pointer (this has been annoying me for ages). - -* Fixed snprintf and vsnprintf with zero buffer size. - -* Fixed NAN problems (reported by Keith Briggs). - -* Fixed parsing of multibyte characters. The format string was not correctly - advanced in case of a multibyte character. - -* Renamed many of the internal functions to have more consistant names. - -* Removed the and modifiers. They are not really worth - including. The other <> modifiers may disappear as well. - - -Version 0.20 - 2000/06/05 -------------------------- -* Added intmax_t and ptrdiff_t support. - -* Added support for LC_NUMERIC grouping. - -* Added double-dot notation for the conversion base. The style is now - %width.precision.base, where any argument can be a number, an asterix - indicating a parameter, or be omitted entirely. For example, %*..2i is - to specify binary numbers without precision, and with width as a parameter - on the va_list. - -* Added sticky modifier (!), which makes subsequent specifiers of the same - type reuse the current modifiers. Inspired by a suggestion from Gary Porter. - -* Added group scanning (%[]). Scanlist ranges and multibyte sequences are not - supported yet. - -* Added count scanning (%n). - -* Changed the number scanning to accept thousand separators and any base. - -* Fixed positional for parameters. It is possible to write something like - %3$*1$.*2$d (which happens to be the same as %*.*d). - -* Fixed precision of integers. - -* Fixed parameter flags. Before trio could only handle one parameter flag per - specifier, although two (three with double-dot base) were possible. - -* Fixed isinf() for those platforms where it is unimplemented. - - -Version 0.18 - 2000/05/27 -------------------------- -* Rewrote the entire floating-point formatting function (Danny Dulai had - reported several errors and even supplied some patches, which unfortunately - were lost due to the refactoring). - -* Removed the use of strlen() in the declaration of a stack array. This - caused problems on some compilers (besides it isn't really ANSI C compliant - anyways). Using some arbitrarily chosen maximum value; should examine if - some standard defines an upper limit on the length of decimal-point and - thousands-separator (sizeof(wchar_t) perhaps?) - -* Changed the parsing of the format string to be multibyte aware. - - -Version 0.17 - 2000/05/19 -------------------------- -* Added INF, -INF, and NAN for floating-point numbers. - -* Fixed %#.9g -- alternative with precision. - -* Ken Gibson - Fixed printing of negative hex numbers - -* Joerg (last name unknown) - Fixed convertion of non-ASCII characters - - -Version 0.16 - 1999/08/06 -------------------------- -* Changed the constness of the second argument of StrFloat and StrDouble. The - lack of parameter overloading in C is the reason for the strange use of - constness in strtof and strtod. - -* Cleaned up constness. - - -Version 0.15 - 1999/07/23 -------------------------- -* Fixed the internal representation of numbers from signed to unsigned. Signed - numbers posed a problem for large unsigned numbers (reported by Tero) - -* Fixed a tiny bug in trio_vsprintfcat - -* Changed the meaning of the max argument of StrAppendMax to be consistant - with StrFormatAppendMax. Now it is the maximal size of the entire target - buffer, not just the appended size. This makes it easier to avoid buffer - overflows (requested by Tero) - - -Version 0.14 - 1999/05/16 -------------------------- -* Added size_t support (just waiting for a C99 compliant compiler to add - ptrdiff_t and intmax_t) - -* Rewrote TrioOutStreamDouble so it does not use the libc sprintf to emulate - floating-point anylonger. - -* Fixed width, precision, and adjustment for numbers and doubles. - - -Version 0.13 - 1999/05/06 -------------------------- -* Fixed zero padding for %d. Now %d will only zero pad if explicitly requested - to do so with the 0 flag (reported by Tero). - -* Fixed an incorrect while() condition in TrioGetString (reported by Tero). - - -Version 0.12 - 1999/04/19 -------------------------- -* Fixed incorrect zero padding of pointers - -* Added StrHash with STRIO_HASH_PLAIN - -* Added StrFormatDateMax - - -Version 0.11 - 1999/03/25 -------------------------- -* Made it compile under cygwin - -* Fixed a bug were TrioPreprocess would return an error if no formatting chars - were found (reported by Tero). - - -Version - 1999/03/19 --------------------- -* Added trio_strerror and TRIO_ERROR_NAME. - -* Changed the error codes to be positive (as errno) - -* Fixed two reads of uninitialized memory reported by Purify - -* Added binary specifiers 'b' and 'B' (like SCO.) ThousandSeparator can be - used to separate nibbles (4 bit) - -* Renamed all Internal* functions to Trio*, which seems like a better - namespace (even though it is of no practical interest because these - functions are not visible beyond the scope of this file.) - - -Version - 1999/03/12 --------------------- -* Added hex-float format for StrToDouble - -* Double references and gaps in the arguments are not allowed (for the %n$ - format) and in both cases an error code is returned. - -* Added StrToDouble (and StrToFloat) - - -Version - 1999/03/08 --------------------- -* Added InStream and OutStream to the trio_T structure. - -* Started work on TrioScan. - -* Return values for errors changed. Two macros to unpack the error code has - been added to the header. - -* Shortshort (hh) flag added. - -* %#s also quotes the quote-char now. - -* Removed the 'errorInFormat' boolean, which isn't used anymore after the - functions bail out with an error instead. - - -Version - 1999/03/04 --------------------- -* More than MAX_PARAMETERS parametes will now cause the TrioPreprocess() - function to return error. - -* Unknown flags and/or specifiers cause errors too. - -* Added trio_snprintfcat and trio_vsnprintfcat and the defined name - StrFormatAppendMax. They append a formatted string to the end of a string. - -* Define MAX_PARAMETERS to 128 at all times instead of using NL_ARGMAX when - that exists. - -* Added platform fixes for Amiga as suggested by Tero Jänkä - - -Version - 1999/01/31 --------------------- -* vaprintf did add a zero byte even when it had failed. - -* Cleaned up the code for locale handling and thousand separator - -* Added trio_aprintf() and trio_vaprintf(). They return an allocated string. - -* Added thousands separator for numbers - -* Added floating point support for *printf - - -Version - 1998/10/20 --------------------- -* StrMatchCase() called StrMatch() instead of itself recursively - -* Rewrote the implementation of *printf and *scanf and put all the code in - this file. Extended qualifiers and qualifiers from other standards were - added. - -* Added StrSpanFunction, StrToLong, and StrToUnsignedLong - - -Version - 1998/05/23 --------------------- -* Made the StrEqual* functions resistant to NULL pointers - -* Turns out strdup() is no standard at all, and some platforms (I seem to - recall HP-UX) has problems with it. Made our own StrDuplicate() instead. - -* Added StrFormat() and StrFormatMax() to serve as sprintf() and snprintf() - respectively. diff --git a/mednafen/trio/Makefile.am b/mednafen/trio/Makefile.am deleted file mode 100644 index f27970ff..00000000 --- a/mednafen/trio/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects -DEFS = -DLOCALEDIR=\"$(datadir)/locale\" @DEFS@ @TRIO_CFLAGS@ -DEFAULT_INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/intl - -noinst_LIBRARIES = libtrio.a -libtrio_a_SOURCES = trio.c trionan.c triostr.c diff --git a/mednafen/trio/Makefile.in b/mednafen/trio/Makefile.in deleted file mode 100644 index 7e36a3d8..00000000 --- a/mednafen/trio/Makefile.in +++ /dev/null @@ -1,599 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@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@ -subdir = src/trio -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_gcc_option.m4 \ - $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/fcntl-o.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \ - $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \ - $(top_srcdir)/m4/inttypes-pri.m4 \ - $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \ - $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/uintmax_t.m4 \ - $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/m4/wchar_t.m4 \ - $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xsize.m4 \ - $(top_srcdir)/acinclude.m4 $(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 = -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -AM_V_AR = $(am__v_AR_$(V)) -am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) -am__v_AR_0 = @echo " AR " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -libtrio_a_AR = $(AR) $(ARFLAGS) -libtrio_a_LIBADD = -am_libtrio_a_OBJECTS = trio.$(OBJEXT) trionan.$(OBJEXT) \ - triostr.$(OBJEXT) -libtrio_a_OBJECTS = $(am_libtrio_a_OBJECTS) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) -am__v_lt_0 = --silent -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) -am__v_CC_0 = @echo " CC " $@; -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libtrio_a_SOURCES) -DIST_SOURCES = $(libtrio_a_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CXXFLAGS = @AM_CXXFLAGS@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = -DLOCALEDIR=\"$(datadir)/locale\" @DEFS@ @TRIO_CFLAGS@ -DEPDIR = @DEPDIR@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GBA_EXTRA_FLAGS = @GBA_EXTRA_FLAGS@ -GENCAT = @GENCAT@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GLIBC2 = @GLIBC2@ -GLIBC21 = @GLIBC21@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GREP = @GREP@ -HAVE_ASPRINTF = @HAVE_ASPRINTF@ -HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ -HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ -HAVE_SNPRINTF = @HAVE_SNPRINTF@ -HAVE_VISIBILITY = @HAVE_VISIBILITY@ -HAVE_WPRINTF = @HAVE_WPRINTF@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLBISON = @INTLBISON@ -INTLLIBS = @INTLLIBS@ -INTLOBJS = @INTLOBJS@ -INTL_DEFAULT_VERBOSITY = @INTL_DEFAULT_VERBOSITY@ -INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -JACK_CFLAGS = @JACK_CFLAGS@ -JACK_LIBS = @JACK_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@ -LIBCDIO_LIBS = @LIBCDIO_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBMULTITHREAD = @LIBMULTITHREAD@ -LIBOBJS = @LIBOBJS@ -LIBPTH = @LIBPTH@ -LIBPTH_PREFIX = @LIBPTH_PREFIX@ -LIBS = @LIBS@ -LIBTHREAD = @LIBTHREAD@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBC = @LTLIBC@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ -LTLIBOBJS = @LTLIBOBJS@ -LTLIBPTH = @LTLIBPTH@ -LTLIBTHREAD = @LTLIBTHREAD@ -MAKEINFO = @MAKEINFO@ -MATH_OPTIMIZER_FLAGS = @MATH_OPTIMIZER_FLAGS@ -MKDIR_P = @MKDIR_P@ -MMX_CFLAGS = @MMX_CFLAGS@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POSUB = @POSUB@ -PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ -SNDFILE_LIBS = @SNDFILE_LIBS@ -SNES_EXTRA_CXXFLAGS = @SNES_EXTRA_CXXFLAGS@ -SNES_EXTRA_FLAGS = @SNES_EXTRA_FLAGS@ -SSE2_CFLAGS = @SSE2_CFLAGS@ -SSE3_CFLAGS = @SSE3_CFLAGS@ -SSE_CFLAGS = @SSE_CFLAGS@ -STRIP = @STRIP@ -TRIO_CFLAGS = @TRIO_CFLAGS@ -USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WARNING_FLAGS = @WARNING_FLAGS@ -WINDRES = @WINDRES@ -WOE32 = @WOE32@ -WOE32DLL = @WOE32DLL@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -XMKMF = @XMKMF@ -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_DUMPBIN = @ac_ct_DUMPBIN@ -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@ -lt_ECHO = @lt_ECHO@ -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@ -AUTOMAKE_OPTIONS = subdir-objects -DEFAULT_INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/intl -noinst_LIBRARIES = libtrio.a -libtrio_a_SOURCES = trio.c trionan.c triostr.c -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/trio/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/trio/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: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libtrio.a: $(libtrio_a_OBJECTS) $(libtrio_a_DEPENDENCIES) - $(AM_V_at)-rm -f libtrio.a - $(AM_V_AR)$(libtrio_a_AR) libtrio.a $(libtrio_a_OBJECTS) $(libtrio_a_LIBADD) - $(AM_V_at)$(RANLIB) libtrio.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trio.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trionan.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triostr.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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 -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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 -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@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 $@ $< - -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; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - 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; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - 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)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__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 "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$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) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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 - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -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/mednafen/video-driver.h b/mednafen/video-driver.h index 535121f5..a584b718 100644 --- a/mednafen/video-driver.h +++ b/mednafen/video-driver.h @@ -4,6 +4,5 @@ #include "video.h" void MDFND_DispMessage(UTF8 *text); -void MDFNI_SaveSnapshot(const MDFN_Surface *src, const MDFN_Rect *rect, const MDFN_Rect *LineWidths); #endif diff --git a/mednafen/video/surface.h b/mednafen/video/surface.h index 79c5714e..b0bfafdc 100644 --- a/mednafen/video/surface.h +++ b/mednafen/video/surface.h @@ -160,14 +160,6 @@ class MDFN_PixelFormat }; // MDFN_PixelFormat; -struct MDFN_PaletteEntry -{ - uint8 r, g, b; -}; - -#include -typedef std::vector MDFN_Palette; - // Supports 32-bit RGBA // 16-bit is WIP class MDFN_Surface //typedef struct