mirror of
https://github.com/libretro/beetle-pcfx-libretro.git
synced 2025-02-18 15:10:31 +00:00
(Mednafen PCE-Fast) Update to 0.9.26 core - rewinds now
This commit is contained in:
parent
6702f7efa2
commit
0a0fb41c98
5
Makefile
5
Makefile
@ -69,16 +69,13 @@ else ifeq ($(core), pce-fast)
|
||||
NEED_SCSI_CD = 1
|
||||
NEED_CRC32 = 1
|
||||
CORE_DEFINE := -DWANT_PCE_FAST_EMU
|
||||
CORE_DIR := $(MEDNAFEN_DIR)/pce_fast-0924
|
||||
CORE_DIR := $(MEDNAFEN_DIR)/pce_fast
|
||||
|
||||
CORE_SOURCES := $(CORE_DIR)/huc.cpp \
|
||||
$(CORE_DIR)/pce_huc6280.cpp \
|
||||
$(CORE_DIR)/input.cpp \
|
||||
$(CORE_DIR)/pce.cpp \
|
||||
$(CORE_DIR)/tsushin.cpp \
|
||||
$(CORE_DIR)/input/gamepad.cpp \
|
||||
$(CORE_DIR)/input/mouse.cpp \
|
||||
$(CORE_DIR)/input/tsushinkb.cpp \
|
||||
$(CORE_DIR)/vdc.cpp
|
||||
TARGET_NAME := mednafen_pce_fast_libretro
|
||||
|
||||
|
84
libretro.cpp
84
libretro.cpp
@ -47,7 +47,7 @@ static Deinterlacer deint;
|
||||
#elif defined(WANT_PCE_FAST_EMU)
|
||||
#define MEDNAFEN_CORE_NAME_MODULE "pce_fast"
|
||||
#define MEDNAFEN_CORE_NAME "Mednafen PCE Fast"
|
||||
#define MEDNAFEN_CORE_VERSION "v0.9.24"
|
||||
#define MEDNAFEN_CORE_VERSION "v0.9.26"
|
||||
#define MEDNAFEN_CORE_EXTENSIONS "pce|PCE|cue|CUE|zip|ZIP"
|
||||
#define MEDNAFEN_CORE_TIMING_FPS 59.82
|
||||
#define MEDNAFEN_CORE_GEOMETRY_BASE_W (game->nominal_width)
|
||||
@ -750,3 +750,85 @@ void retro_cheat_reset(void)
|
||||
void retro_cheat_set(unsigned, bool, const char *)
|
||||
{}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static const unsigned long crc_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
#define DO1_CRC32(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
#define DO2_CRC32(buf) DO1_CRC32(buf); DO1_CRC32(buf);
|
||||
#define DO4_CRC32(buf) DO2_CRC32(buf); DO2_CRC32(buf);
|
||||
#define DO8_CRC32(buf) DO4_CRC32(buf); DO4_CRC32(buf);
|
||||
|
||||
unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
if (buf == 0) return 0L;
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len >= 8)
|
||||
{
|
||||
DO8_CRC32(buf);
|
||||
len -= 8;
|
||||
}
|
||||
if (len) do {
|
||||
DO1_CRC32(buf);
|
||||
} while (--len);
|
||||
return crc ^ 0xffffffffL;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
8
mednafen/pce_fast/Makefile.am
Normal file
8
mednafen/pce_fast/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
DEFS = -DLOCALEDIR=\"$(datadir)/locale\" @DEFS@ @MATH_OPTIMIZER_FLAGS@
|
||||
DEFAULT_INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/intl -I$(top_srcdir)/src/hw_misc -I$(top_srcdir)/src/hw_sound
|
||||
|
||||
noinst_LIBRARIES = libpce_fast.a
|
||||
mednafen_SOURCES = huc6280.cpp pce.cpp vdc.cpp input.cpp huc.cpp hes.cpp tsushin.cpp
|
||||
|
||||
libpce_fast_a_SOURCES = $(mednafen_SOURCES)
|
605
mednafen/pce_fast/Makefile.in
Normal file
605
mednafen/pce_fast/Makefile.in
Normal file
@ -0,0 +1,605 @@
|
||||
# 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/pce_fast
|
||||
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 = @
|
||||
libpce_fast_a_AR = $(AR) $(ARFLAGS)
|
||||
libpce_fast_a_LIBADD =
|
||||
am__objects_1 = huc6280.$(OBJEXT) pce.$(OBJEXT) vdc.$(OBJEXT) \
|
||||
input.$(OBJEXT) huc.$(OBJEXT) hes.$(OBJEXT) tsushin.$(OBJEXT)
|
||||
am_libpce_fast_a_OBJECTS = $(am__objects_1)
|
||||
libpce_fast_a_OBJECTS = $(am_libpce_fast_a_OBJECTS)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
AM_V_lt = $(am__v_lt_$(V))
|
||||
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_lt_0 = --silent
|
||||
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
AM_V_CXX = $(am__v_CXX_$(V))
|
||||
am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_CXX_0 = @echo " CXX " $@;
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CXXLD = $(am__v_CXXLD_$(V))
|
||||
am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_CXXLD_0 = @echo " CXXLD " $@;
|
||||
AM_V_GEN = $(am__v_GEN_$(V))
|
||||
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
SOURCES = $(libpce_fast_a_SOURCES)
|
||||
DIST_SOURCES = $(libpce_fast_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@ @MATH_OPTIMIZER_FLAGS@
|
||||
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 -I$(top_srcdir)/src/hw_misc -I$(top_srcdir)/src/hw_sound
|
||||
noinst_LIBRARIES = libpce_fast.a
|
||||
mednafen_SOURCES = huc6280.cpp pce.cpp vdc.cpp input.cpp huc.cpp hes.cpp tsushin.cpp
|
||||
libpce_fast_a_SOURCES = $(mednafen_SOURCES)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cpp .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/pce_fast/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu src/pce_fast/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)
|
||||
libpce_fast.a: $(libpce_fast_a_OBJECTS) $(libpce_fast_a_DEPENDENCIES)
|
||||
$(AM_V_at)-rm -f libpce_fast.a
|
||||
$(AM_V_AR)$(libpce_fast_a_AR) libpce_fast.a $(libpce_fast_a_OBJECTS) $(libpce_fast_a_LIBADD)
|
||||
$(AM_V_at)$(RANLIB) libpce_fast.a
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hes.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huc.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huc6280.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pce.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsushin.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vdc.Po@am__quote@
|
||||
|
||||
.cpp.o:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.obj:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.cpp.lo:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
||||
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -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:
|
249
mednafen/pce_fast/hes.cpp
Normal file
249
mednafen/pce_fast/hes.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
/* 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 "pce.h"
|
||||
#include "hes.h"
|
||||
#include "huc.h"
|
||||
#include "../cdrom/pcecd.h"
|
||||
#include "../player.h"
|
||||
#include "../endian.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
|
||||
static uint8 mpr_start[8];
|
||||
static uint8 IBP_Bank[0x2000];
|
||||
static uint8 *rom = NULL, *rom_backup = NULL;
|
||||
|
||||
static uint8 CurrentSong;
|
||||
static bool bootstrap;
|
||||
static bool ROMWriteWarningGiven;
|
||||
|
||||
uint8 ReadIBP(unsigned int A)
|
||||
{
|
||||
if(!(A & 0x100))
|
||||
return(IBP_Bank[0x1C00 + (A & 0xF)]);
|
||||
|
||||
if(bootstrap)
|
||||
{
|
||||
memcpy(rom + 0x1FF0, rom_backup + 0x1FF0, 16);
|
||||
bootstrap = false;
|
||||
return(CurrentSong);
|
||||
}
|
||||
return(0xFF);
|
||||
}
|
||||
|
||||
static DECLFW(HESROMWrite)
|
||||
{
|
||||
rom[A] = V;
|
||||
//printf("%08x: %02x\n", A, V);
|
||||
if(!ROMWriteWarningGiven)
|
||||
{
|
||||
MDFN_printf(_("Warning: HES is writing to physical address %08x. Future warnings of this nature are temporarily disabled for this HES file.\n"), A);
|
||||
ROMWriteWarningGiven = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFR(HESROMRead)
|
||||
{
|
||||
return(rom[A]);
|
||||
}
|
||||
|
||||
int PCE_HESLoad(const uint8 *buf, uint32 size)
|
||||
{
|
||||
uint32 LoadAddr, LoadSize;
|
||||
uint32 CurPos;
|
||||
uint16 InitAddr;
|
||||
uint8 StartingSong;
|
||||
int TotalSongs;
|
||||
|
||||
InitAddr = MDFN_de16lsb(&buf[0x6]);
|
||||
|
||||
CurPos = 0x10;
|
||||
|
||||
if(!(rom = (uint8 *)MDFN_malloc(0x88 * 8192, _("HES ROM"))))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(!(rom_backup = (uint8 *)MDFN_malloc(0x88 * 8192, _("HES ROM"))))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
memset(rom, 0, 0x88 * 8192);
|
||||
memset(rom_backup, 0, 0x88 * 8192);
|
||||
|
||||
while(CurPos < (size - 0x10))
|
||||
{
|
||||
LoadSize = MDFN_de32lsb(&buf[CurPos + 0x4]);
|
||||
LoadAddr = MDFN_de32lsb(&buf[CurPos + 0x8]);
|
||||
|
||||
//printf("Size: %08x(%d), Addr: %08x, La: %02x\n", LoadSize, LoadSize, LoadAddr, LoadAddr / 8192);
|
||||
|
||||
CurPos += 0x10;
|
||||
|
||||
if(((uint64)LoadSize + CurPos) > size)
|
||||
{
|
||||
uint32 NewLoadSize = size - CurPos;
|
||||
|
||||
MDFN_printf(_("Warning: HES is trying to load more data than is present in the file(%u attempted, %u left)!\n"), LoadSize, NewLoadSize);
|
||||
|
||||
LoadSize = NewLoadSize;
|
||||
}
|
||||
|
||||
// 0x88 * 8192 = 0x110000
|
||||
if(((uint64)LoadAddr + LoadSize) > 0x110000)
|
||||
{
|
||||
MDFN_printf(_("Warning: HES is trying to load data past boundary.\n"));
|
||||
|
||||
if(LoadAddr >= 0x110000)
|
||||
break;
|
||||
|
||||
LoadSize = 0x110000 - LoadAddr;
|
||||
}
|
||||
|
||||
memcpy(rom + LoadAddr, &buf[CurPos], LoadSize);
|
||||
CurPos += LoadSize;
|
||||
}
|
||||
|
||||
for(int x = 0; x < 8; x++)
|
||||
mpr_start[x] = buf[0x8 + x];
|
||||
|
||||
memcpy(rom_backup, rom, 0x88 * 8192);
|
||||
|
||||
CurrentSong = StartingSong = buf[5];
|
||||
TotalSongs = 256;
|
||||
|
||||
memset(IBP_Bank, 0, 0x2000);
|
||||
|
||||
uint8 *IBP_WR = IBP_Bank + 0x1C00;
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
*IBP_WR++ = 0xA9; // LDA (immediate)
|
||||
*IBP_WR++ = mpr_start[i];
|
||||
*IBP_WR++ = 0x53; // TAM
|
||||
*IBP_WR++ = 1 << i;
|
||||
}
|
||||
|
||||
*IBP_WR++ = 0xAD; // LDA(absolute)
|
||||
*IBP_WR++ = 0x00; //
|
||||
*IBP_WR++ = 0x1D; //
|
||||
*IBP_WR++ = 0x20; // JSR
|
||||
*IBP_WR++ = InitAddr; // JSR target LSB
|
||||
*IBP_WR++ = InitAddr >> 8; // JSR target MSB
|
||||
*IBP_WR++ = 0x58; // CLI
|
||||
*IBP_WR++ = 0xFC; // (Mednafen Special)
|
||||
*IBP_WR++ = 0x80; // BRA
|
||||
*IBP_WR++ = 0xFD; // -3
|
||||
|
||||
Player_Init(TotalSongs, "", "", ""); //NULL, NULL, NULL, NULL); //UTF8 **snames);
|
||||
|
||||
for(int x = 0; x < 0x80; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = rom;
|
||||
PCERead[x] = HESROMRead;
|
||||
PCEWrite[x] = HESROMWrite;
|
||||
}
|
||||
|
||||
HuCPUFastMap[0xFF] = IBP_Bank - (0xFF * 8192);
|
||||
|
||||
// FIXME: If a HES rip tries to execute a SCSI command, the CD emulation code will probably crash. Obviously, a HES rip shouldn't do this,
|
||||
// but Mednafen shouldn't crash either. ;)
|
||||
PCE_IsCD = 1;
|
||||
PCE_InitCD();
|
||||
|
||||
ROMWriteWarningGiven = FALSE;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static const uint8 BootROM[16] = { 0xA9, 0xFF, 0x53, 0x01, 0xEA, 0xEA, 0xEA, 0xEA,
|
||||
0xEA, 0xEA, 0xEA, 0x4C, 0x00, 0x1C, 0xF0, 0xFF };
|
||||
void HES_Reset(void)
|
||||
{
|
||||
memcpy(rom, rom_backup, 0x88 * 8192);
|
||||
memcpy(rom + 0x1FF0, BootROM, 16);
|
||||
bootstrap = true;
|
||||
}
|
||||
|
||||
|
||||
void HES_Draw(MDFN_Surface *surface, MDFN_Rect *DisplayRect, int16 *SoundBuf, int32 SoundBufSize)
|
||||
{
|
||||
extern uint16 pce_jp_data[5];
|
||||
static uint8 last = 0;
|
||||
bool needreload = 0;
|
||||
uint8 newset = (pce_jp_data[0] ^ last) & pce_jp_data[0];
|
||||
|
||||
if(newset & 0x20)
|
||||
{
|
||||
CurrentSong++;
|
||||
needreload = 1;
|
||||
}
|
||||
|
||||
if(newset & 0x80)
|
||||
{
|
||||
CurrentSong--;
|
||||
needreload = 1;
|
||||
}
|
||||
|
||||
if(newset & 0x08)
|
||||
needreload = 1;
|
||||
|
||||
if(newset & 0x10)
|
||||
{
|
||||
CurrentSong += 10;
|
||||
needreload = 1;
|
||||
}
|
||||
|
||||
if(newset & 0x40)
|
||||
{
|
||||
CurrentSong -= 10;
|
||||
needreload = 1;
|
||||
}
|
||||
|
||||
last = pce_jp_data[0];
|
||||
|
||||
if(needreload)
|
||||
PCE_Power();
|
||||
|
||||
Player_Draw(surface, DisplayRect, CurrentSong, SoundBuf, SoundBufSize);
|
||||
}
|
||||
|
||||
void HES_Close(void)
|
||||
{
|
||||
PCECD_Close();
|
||||
|
||||
if(rom)
|
||||
{
|
||||
MDFN_free(rom);
|
||||
rom = NULL;
|
||||
}
|
||||
|
||||
if(rom_backup)
|
||||
{
|
||||
MDFN_free(rom_backup);
|
||||
rom_backup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
10
mednafen/pce_fast/hes.h
Normal file
10
mednafen/pce_fast/hes.h
Normal file
@ -0,0 +1,10 @@
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
uint8 ReadIBP(unsigned int A);
|
||||
int PCE_HESLoad(const uint8 *buf, uint32 size);
|
||||
void HES_Reset(void);
|
||||
void HES_Draw(MDFN_Surface *surface, MDFN_Rect *DisplayRect, int16 *samples, int32 sampcount);
|
||||
void HES_Close(void);
|
||||
|
||||
};
|
447
mednafen/pce_fast/huc.cpp
Normal file
447
mednafen/pce_fast/huc.cpp
Normal file
@ -0,0 +1,447 @@
|
||||
/* Mednafen - Multi-system Emulator
|
||||
*
|
||||
* Portions of this file Copyright (C) 2004 Ki
|
||||
*
|
||||
* 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 "pce.h"
|
||||
#include <errno.h>
|
||||
#include "../cdrom/pcecd.h"
|
||||
#include "../hw_misc/arcade_card/arcade_card.h"
|
||||
#include "../md5.h"
|
||||
#include "../file.h"
|
||||
#include "../cdrom/cdromif.h"
|
||||
#include "../mempatcher.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
static const uint8 BRAM_Init_String[8] = { 'H', 'U', 'B', 'M', 0x00, 0x88, 0x10, 0x80 }; //"HUBM\x00\x88\x10\x80";
|
||||
|
||||
ArcadeCard *arcade_card = NULL;
|
||||
|
||||
static uint8 *HuCROM = NULL;
|
||||
|
||||
static bool IsPopulous;
|
||||
bool IsTsushin;
|
||||
bool PCE_IsCD;
|
||||
|
||||
static uint8 *TsushinRAM = NULL; // 0x8000
|
||||
static uint8 SaveRAM[2048];
|
||||
|
||||
static DECLFW(ACPhysWrite)
|
||||
{
|
||||
arcade_card->PhysWrite(A, V);
|
||||
}
|
||||
|
||||
static DECLFR(ACPhysRead)
|
||||
{
|
||||
return(arcade_card->PhysRead(A));
|
||||
}
|
||||
|
||||
static DECLFR(SaveRAMRead)
|
||||
{
|
||||
if((!PCE_IsCD || PCECD_IsBRAMEnabled()) && (A & 8191) < 2048)
|
||||
return(SaveRAM[A & 2047]);
|
||||
else
|
||||
return(0xFF);
|
||||
}
|
||||
|
||||
static DECLFW(SaveRAMWrite)
|
||||
{
|
||||
if((!PCE_IsCD || PCECD_IsBRAMEnabled()) && (A & 8191) < 2048)
|
||||
SaveRAM[A & 2047] = V;
|
||||
}
|
||||
|
||||
static DECLFR(HuCRead)
|
||||
{
|
||||
return ROMSpace[A];
|
||||
}
|
||||
|
||||
static DECLFW(HuCRAMWrite)
|
||||
{
|
||||
ROMSpace[A] = V;
|
||||
}
|
||||
|
||||
static DECLFW(HuCRAMWriteCDSpecial) // Hyper Dyne Special hack
|
||||
{
|
||||
BaseRAM[0x2000 | (A & 0x1FFF)] = V;
|
||||
ROMSpace[A] = V;
|
||||
}
|
||||
|
||||
static uint8 HuCSF2Latch = 0;
|
||||
|
||||
static DECLFR(HuCSF2Read)
|
||||
{
|
||||
return(HuCROM[(A & 0x7FFFF) + 0x80000 + HuCSF2Latch * 0x80000 ]); // | (HuCSF2Latch << 19) ]);
|
||||
}
|
||||
|
||||
static DECLFW(HuCSF2Write)
|
||||
{
|
||||
if((A & 0x1FFC) == 0x1FF0)
|
||||
{
|
||||
HuCSF2Latch = (A & 0x3);
|
||||
}
|
||||
}
|
||||
|
||||
int HuCLoad(const uint8 *data, uint32 len, uint32 crc32)
|
||||
{
|
||||
uint32 sf2_threshold = 2048 * 1024;
|
||||
uint32 sf2_required_size = 2048 * 1024 + 512 * 1024;
|
||||
uint32 m_len = (len + 8191)&~8191;
|
||||
bool sf2_mapper = FALSE;
|
||||
|
||||
if(m_len >= sf2_threshold)
|
||||
{
|
||||
sf2_mapper = TRUE;
|
||||
|
||||
if(m_len != sf2_required_size)
|
||||
m_len = sf2_required_size;
|
||||
}
|
||||
|
||||
IsPopulous = 0;
|
||||
PCE_IsCD = 0;
|
||||
|
||||
md5_context md5;
|
||||
md5.starts();
|
||||
md5.update(data, len);
|
||||
md5.finish(MDFNGameInfo->MD5);
|
||||
|
||||
MDFN_printf(_("ROM: %dKiB\n"), (len + 1023) / 1024);
|
||||
MDFN_printf(_("ROM CRC32: 0x%04x\n"), crc32);
|
||||
MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());
|
||||
|
||||
if(!(HuCROM = (uint8 *)MDFN_malloc(m_len, _("HuCard ROM"))))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
memset(HuCROM, 0xFF, m_len);
|
||||
memcpy(HuCROM, data, len);
|
||||
|
||||
memset(ROMSpace, 0xFF, 0x88 * 8192 + 8192);
|
||||
|
||||
if(m_len == 0x60000)
|
||||
{
|
||||
memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x20 * 8192);
|
||||
memcpy(ROMSpace + 0x20 * 8192, HuCROM, 0x20 * 8192);
|
||||
memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
|
||||
memcpy(ROMSpace + 0x50 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
|
||||
memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
|
||||
memcpy(ROMSpace + 0x70 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
|
||||
}
|
||||
else if(m_len == 0x80000)
|
||||
{
|
||||
memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x40 * 8192);
|
||||
memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192);
|
||||
memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ROMSpace + 0x00 * 8192, HuCROM, (m_len < 1024 * 1024) ? m_len : 1024 * 1024);
|
||||
}
|
||||
|
||||
for(int x = 0x00; x < 0x80; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = ROMSpace;
|
||||
PCERead[x] = HuCRead;
|
||||
}
|
||||
|
||||
if(!memcmp(HuCROM + 0x1F26, "POPULOUS", strlen("POPULOUS")))
|
||||
{
|
||||
uint8 *PopRAM = ROMSpace + 0x40 * 8192;
|
||||
FILE *fp;
|
||||
|
||||
memset(PopRAM, 0xFF, 32768);
|
||||
if((fp = fopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
|
||||
{
|
||||
fread(PopRAM, 32768, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
IsPopulous = 1;
|
||||
|
||||
MDFN_printf("Populous\n");
|
||||
|
||||
for(int x = 0x40; x < 0x44; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = &PopRAM[(x & 3) * 8192] - x * 8192;
|
||||
PCERead[x] = HuCRead;
|
||||
PCEWrite[x] = HuCRAMWrite;
|
||||
}
|
||||
MDFNMP_AddRAM(32768, 0x40 * 8192, PopRAM);
|
||||
}
|
||||
else if(crc32 == 0x34dc65c4) // Tsushin Booster
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if(!(TsushinRAM = (uint8*)MDFN_calloc(1, 0x8000 + 8192, _("Tsushin Booster RAM")))) // + 8192 for PC-as-ptr safety padding
|
||||
{
|
||||
MDFN_free(HuCROM);
|
||||
return(0);
|
||||
}
|
||||
memset(TsushinRAM, 0xFF, 0x8000);
|
||||
|
||||
if((fp = fopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
|
||||
{
|
||||
fread(TsushinRAM, 32768, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
IsTsushin = 1;
|
||||
MDFN_printf("Tsushin Booster\n");
|
||||
for(int x = 0x88; x < 0x8C; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = &TsushinRAM[(x & 3) * 8192] - x * 8192;
|
||||
PCERead[x] = HuCRead;
|
||||
PCEWrite[x] = HuCRAMWrite;
|
||||
}
|
||||
MDFNMP_AddRAM(32768, 0x88 * 8192, TsushinRAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
memset(SaveRAM, 0x00, 2048);
|
||||
memcpy(SaveRAM, BRAM_Init_String, 8); // So users don't have to manually intialize the file cabinet
|
||||
// in the CD BIOS screen.
|
||||
if((fp = fopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
|
||||
{
|
||||
fread(SaveRAM, 2048, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
PCEWrite[0xF7] = SaveRAMWrite;
|
||||
PCERead[0xF7] = SaveRAMRead;
|
||||
MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM);
|
||||
}
|
||||
|
||||
// 0x1A558
|
||||
//if(len >= 0x20000 && !memcmp(HuCROM + 0x1A558, "STREET FIGHTER#", strlen("STREET FIGHTER#")))
|
||||
if(sf2_mapper)
|
||||
{
|
||||
for(int x = 0x40; x < 0x80; x++)
|
||||
{
|
||||
// FIXME: PCE_FAST
|
||||
HuCPUFastMap[x] = NULL; // Make sure our reads go through our read function, and not a table lookup
|
||||
PCERead[x] = HuCSF2Read;
|
||||
}
|
||||
PCEWrite[0] = HuCSF2Write;
|
||||
MDFN_printf("Street Fighter 2 Mapper\n");
|
||||
HuCSF2Latch = 0;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
bool IsBRAMUsed(void)
|
||||
{
|
||||
if(memcmp(SaveRAM, BRAM_Init_String, 8)) // HUBM string is modified/missing
|
||||
return(1);
|
||||
|
||||
for(int x = 8; x < 2048; x++)
|
||||
if(SaveRAM[x]) return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int HuCLoadCD(const char *bios_path)
|
||||
{
|
||||
static const FileExtensionSpecStruct KnownBIOSExtensions[] =
|
||||
{
|
||||
{ ".pce", gettext_noop("PC Engine ROM Image") },
|
||||
{ ".bin", gettext_noop("PC Engine ROM Image") },
|
||||
{ ".bios", gettext_noop("BIOS Image") },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
MDFNFILE fp;
|
||||
|
||||
if(!fp.Open(bios_path, KnownBIOSExtensions, _("CD BIOS")))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
memset(ROMSpace, 0xFF, 262144);
|
||||
|
||||
memcpy(ROMSpace, fp.Data() + (fp.Size() & 512), ((fp.Size() & ~512) > 262144) ? 262144 : (fp.Size() &~ 512) );
|
||||
|
||||
fp.Close();
|
||||
|
||||
PCE_IsCD = 1;
|
||||
PCE_InitCD();
|
||||
|
||||
md5_context md5;
|
||||
md5.starts();
|
||||
// md5_update(&md5, HuCROM, 262144);
|
||||
|
||||
#if 0
|
||||
int32 track = CDIF_GetFirstTrack();
|
||||
int32 last_track = CDIF_GetLastTrack();
|
||||
bool DTFound = 0;
|
||||
for(; track <= last_track; track++)
|
||||
{
|
||||
CDIF_Track_Format format;
|
||||
|
||||
if(CDIF_GetTrackFormat(track, format) && format == CDIF_FORMAT_MODE1)
|
||||
{
|
||||
DTFound = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(DTFound) // Only add the MD5 hash if we were able to find a data track.
|
||||
{
|
||||
uint32 start_sector = CDIF_GetTrackStartPositionLBA(track);
|
||||
uint8 sector_buffer[2048];
|
||||
|
||||
for(int x = 0; x < 128; x++)
|
||||
{
|
||||
memset(sector_buffer, 0, 2048);
|
||||
CDIF_ReadSector(sector_buffer, NULL, start_sector + x, 1);
|
||||
md5.update(sector_buffer, 2048);
|
||||
}
|
||||
}
|
||||
md5.finish(MDFNGameInfo->MD5);
|
||||
MDFN_printf(_("CD MD5(first 256KiB): 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());
|
||||
#endif
|
||||
|
||||
MDFN_printf(_("Arcade Card Emulation: %s\n"), PCE_ACEnabled ? _("Enabled") : _("Disabled"));
|
||||
for(int x = 0; x < 0x40; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = ROMSpace;
|
||||
PCERead[x] = HuCRead;
|
||||
}
|
||||
|
||||
for(int x = 0x68; x < 0x88; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = ROMSpace;
|
||||
PCERead[x] = HuCRead;
|
||||
PCEWrite[x] = HuCRAMWrite;
|
||||
}
|
||||
PCEWrite[0x80] = HuCRAMWriteCDSpecial; // Hyper Dyne Special hack
|
||||
MDFNMP_AddRAM(262144, 0x68 * 8192, ROMSpace + 0x68 * 8192);
|
||||
|
||||
if(PCE_ACEnabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
arcade_card = new ArcadeCard();
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
MDFN_PrintError(_("Error creating %s object: %s"), "ArcadeCard", e.what());
|
||||
//Cleanup(); // TODO
|
||||
return(0);
|
||||
}
|
||||
|
||||
for(int x = 0x40; x < 0x44; x++)
|
||||
{
|
||||
HuCPUFastMap[x] = NULL;
|
||||
PCERead[x] = ACPhysRead;
|
||||
PCEWrite[x] = ACPhysWrite;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *srp;
|
||||
|
||||
memset(SaveRAM, 0x00, 2048);
|
||||
memcpy(SaveRAM, BRAM_Init_String, 8); // So users don't have to manually intialize the file cabinet
|
||||
// in the CD BIOS screen.
|
||||
|
||||
if((srp = fopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
|
||||
{
|
||||
fread(SaveRAM, 2048, 1, srp);
|
||||
fclose(srp);
|
||||
}
|
||||
PCEWrite[0xF7] = SaveRAMWrite;
|
||||
PCERead[0xF7] = SaveRAMRead;
|
||||
MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM);
|
||||
return(1);
|
||||
}
|
||||
|
||||
int HuC_StateAction(StateMem *sm, int load, int data_only)
|
||||
{
|
||||
SFORMAT StateRegs[] =
|
||||
{
|
||||
SFARRAY(ROMSpace + 0x40 * 8192, IsPopulous ? 32768 : 0),
|
||||
SFARRAY(TsushinRAM, IsTsushin ? 32768 : 0),
|
||||
SFARRAY(SaveRAM, (IsPopulous || IsTsushin) ? 0 : 2048),
|
||||
SFARRAY(ROMSpace + 0x68 * 8192, PCE_IsCD ? 262144 : 0),
|
||||
SFVAR(HuCSF2Latch),
|
||||
SFEND
|
||||
};
|
||||
int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "HuC");
|
||||
|
||||
if(load)
|
||||
HuCSF2Latch &= 0x3;
|
||||
|
||||
if(PCE_IsCD)
|
||||
{
|
||||
ret &= PCECD_StateAction(sm, load, data_only);
|
||||
|
||||
if(arcade_card)
|
||||
ret &= arcade_card->StateAction(sm, load, data_only);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void HuCClose(void)
|
||||
{
|
||||
if(IsPopulous)
|
||||
{
|
||||
MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, ROMSpace + 0x40 * 8192, 32768);
|
||||
}
|
||||
else if(IsTsushin)
|
||||
{
|
||||
if(TsushinRAM)
|
||||
{
|
||||
MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, TsushinRAM, 32768);
|
||||
MDFN_free(TsushinRAM);
|
||||
TsushinRAM = NULL;
|
||||
}
|
||||
}
|
||||
else if(IsBRAMUsed())
|
||||
{
|
||||
MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, SaveRAM, 2048);
|
||||
}
|
||||
|
||||
if(arcade_card)
|
||||
{
|
||||
delete arcade_card;
|
||||
arcade_card = NULL;
|
||||
}
|
||||
|
||||
if(PCE_IsCD)
|
||||
{
|
||||
PCECD_Close();
|
||||
}
|
||||
|
||||
if(HuCROM)
|
||||
{
|
||||
MDFN_free(HuCROM);
|
||||
HuCROM = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void HuC_Power(void)
|
||||
{
|
||||
if(PCE_IsCD)
|
||||
memset(ROMSpace + 0x68 * 8192, 0x00, 262144);
|
||||
|
||||
if(arcade_card)
|
||||
arcade_card->Power();
|
||||
}
|
||||
|
||||
};
|
17
mednafen/pce_fast/huc.h
Normal file
17
mednafen/pce_fast/huc.h
Normal file
@ -0,0 +1,17 @@
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
int HuCLoad(const uint8 *data, uint32 len, uint32 crc32);
|
||||
int HuCLoadCD(const char *bios_path);
|
||||
void HuCClose(void);
|
||||
int HuC_StateAction(StateMem *sm, int load, int data_only);
|
||||
|
||||
void HuC_Power(void);
|
||||
|
||||
DECLFR(PCE_ACRead);
|
||||
DECLFW(PCE_ACWrite);
|
||||
|
||||
extern bool PCE_IsCD;
|
||||
extern bool IsTsushin;
|
||||
|
||||
};
|
156
mednafen/pce_fast/huc6280.h
Normal file
156
mednafen/pce_fast/huc6280.h
Normal file
@ -0,0 +1,156 @@
|
||||
#ifndef _HuC6280H
|
||||
|
||||
#define HUC6280_CRAZY_VERSION
|
||||
//#define HUC6280_EXTRA_CRAZY
|
||||
|
||||
#define HUC6280_LAZY_FLAGS
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
|
||||
typedef struct __HuC6280
|
||||
{
|
||||
#ifdef HUC6280_CRAZY_VERSION
|
||||
uint8 *PC, *PC_base;
|
||||
#else
|
||||
uint16 PC;
|
||||
#endif
|
||||
|
||||
uint8 A,X,Y,S,P,mooPI;
|
||||
#ifdef HUC6280_LAZY_FLAGS
|
||||
uint32 ZNFlags;
|
||||
#endif
|
||||
uint8 MPR[9]; // 8, + 1 for PC overflow from $ffff to $10000
|
||||
uint8 *FastPageR[9];
|
||||
uint8 *Page1;
|
||||
//uint8 *PAGE1_W;
|
||||
//const uint8 *PAGE1_R;
|
||||
|
||||
uint32 IRQlow; /* Simulated IRQ pin held low(or is it high?).
|
||||
And other junk hooked on for speed reasons.*/
|
||||
int32 timestamp;
|
||||
|
||||
uint8 IRQMask, IRQMaskDelay;
|
||||
uint8 timer_status;
|
||||
int32 timer_value, timer_load;
|
||||
int32 timer_next_timestamp;
|
||||
|
||||
uint32 in_block_move;
|
||||
uint16 bmt_src, bmt_dest, bmt_length;
|
||||
uint32 bmt_alternate;
|
||||
#define IBM_TIA 1
|
||||
#define IBM_TAI 2
|
||||
#define IBM_TDD 3
|
||||
#define IBM_TII 4
|
||||
#define IBM_TIN 5
|
||||
|
||||
int32 previous_next_user_event;
|
||||
} HuC6280;
|
||||
|
||||
void HuC6280_Run(int32 cycles);
|
||||
void HuC6280_ResetTS(void);
|
||||
|
||||
extern HuC6280 HuCPU;
|
||||
extern uint8 *HuCPUFastMap[0x100];
|
||||
|
||||
#define N_FLAG 0x80
|
||||
#define V_FLAG 0x40
|
||||
#define T_FLAG 0x20
|
||||
#define B_FLAG 0x10
|
||||
#define D_FLAG 0x08
|
||||
#define I_FLAG 0x04
|
||||
#define Z_FLAG 0x02
|
||||
#define C_FLAG 0x01
|
||||
|
||||
#define NTSC_CPU 1789772.7272727272727272
|
||||
#define PAL_CPU 1662607.125
|
||||
|
||||
#define MDFN_IQIRQ1 0x002
|
||||
#define MDFN_IQIRQ2 0x001
|
||||
#define MDFN_IQTIMER 0x004
|
||||
#define MDFN_IQRESET 0x020
|
||||
|
||||
void HuC6280_Init(void);
|
||||
void HuC6280_Reset(void);
|
||||
void HuC6280_Power(void);
|
||||
|
||||
void HuC6280_IRQBegin(int w);
|
||||
void HuC6280_IRQEnd(int w);
|
||||
|
||||
int HuC6280_StateAction(StateMem *sm, int load, int data_only);
|
||||
|
||||
static INLINE void HuC6280_StealCycle(void)
|
||||
{
|
||||
HuCPU.timestamp++;
|
||||
}
|
||||
|
||||
static INLINE uint8 HuC6280_TimerRead(unsigned int A)
|
||||
{
|
||||
#if 0
|
||||
return(HuCPU.timer_value | (PCEIODataBuffer & 0x80));
|
||||
#endif
|
||||
|
||||
uint8 tvr = HuCPU.timer_value;
|
||||
|
||||
if(HuCPU.timer_next_timestamp == HuCPU.timestamp)
|
||||
tvr = (tvr - 1) & 0x7F;
|
||||
|
||||
return(tvr | (PCEIODataBuffer & 0x80));
|
||||
}
|
||||
|
||||
static INLINE void HuC6280_TimerWrite(unsigned int A, uint8 V)
|
||||
{
|
||||
switch(A & 1)
|
||||
{
|
||||
case 0: HuCPU.timer_load = (V & 0x7F); break;
|
||||
case 1: if(V & 1) // Enable counter
|
||||
{
|
||||
if(HuCPU.timer_status == 0)
|
||||
{
|
||||
HuCPU.timer_next_timestamp = HuCPU.timestamp + 1024;
|
||||
HuCPU.timer_value = HuCPU.timer_load;
|
||||
}
|
||||
}
|
||||
HuCPU.timer_status = V & 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE uint8 HuC6280_IRQStatusRead(unsigned int A)
|
||||
{
|
||||
if(!(A & 2))
|
||||
return(PCEIODataBuffer);
|
||||
|
||||
switch(A & 1)
|
||||
{
|
||||
case 0:
|
||||
HuC6280_IRQEnd(MDFN_IQTIMER);
|
||||
return(HuCPU.IRQMask ^ 0x7);
|
||||
case 1:
|
||||
{
|
||||
int status = 0;
|
||||
if(HuCPU.IRQlow & MDFN_IQIRQ1) status |= 2;
|
||||
if(HuCPU.IRQlow & MDFN_IQIRQ2) status |= 1;
|
||||
if(HuCPU.IRQlow & MDFN_IQTIMER) status |= 4;
|
||||
return(status | (PCEIODataBuffer & ~(1 | 2 | 4)));
|
||||
}
|
||||
}
|
||||
return(PCEIODataBuffer);
|
||||
}
|
||||
|
||||
static INLINE void HuC6280_IRQStatusWrite(unsigned int A, uint8 V)
|
||||
{
|
||||
if(!(A & 2)) return;
|
||||
switch(A & 1)
|
||||
{
|
||||
case 0: HuCPU.IRQMask = (V & 0x7) ^ 0x7; break;
|
||||
case 1: HuC6280_IRQEnd(MDFN_IQTIMER); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#define _HuC6280H
|
||||
#endif
|
635
mednafen/pce_fast/huc6280_ops.inc
Normal file
635
mednafen/pce_fast/huc6280_ops.inc
Normal file
@ -0,0 +1,635 @@
|
||||
/* Mednafen - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define TEST_WEIRD_TFLAG(n) { if(HU_P & T_FLAG) puts("RAWR" n); }
|
||||
|
||||
case 0x00: /* BRK */
|
||||
IncPC();
|
||||
HU_P &= ~T_FLAG;
|
||||
PUSH_PC();
|
||||
|
||||
COMPRESS_FLAGS();
|
||||
PUSH(HU_P|B_FLAG);
|
||||
HU_P|=I_FLAG;
|
||||
HU_P &= ~D_FLAG;
|
||||
HU_PI|=I_FLAG;
|
||||
{
|
||||
unsigned int npc;
|
||||
|
||||
npc=RdOp(0xFFF6);
|
||||
npc|=RdOp(0xFFF7)<<8;
|
||||
|
||||
SetPC(npc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x40: /* RTI */
|
||||
HU_P = POP();
|
||||
EXPAND_FLAGS();
|
||||
/* HU_PI=HU_P; This is probably incorrect, so it's commented out. */
|
||||
HU_PI = HU_P;
|
||||
POP_PC();
|
||||
|
||||
// T-flag handling here:
|
||||
TEST_WEIRD_TFLAG("RTI");
|
||||
break;
|
||||
|
||||
case 0x60: /* RTS */
|
||||
POP_PC_AP();
|
||||
break;
|
||||
|
||||
case 0x48: /* PHA */
|
||||
PUSH(HU_A);
|
||||
break;
|
||||
|
||||
case 0x08: /* PHP */
|
||||
HU_P &= ~T_FLAG;
|
||||
COMPRESS_FLAGS();
|
||||
PUSH(HU_P|B_FLAG);
|
||||
break;
|
||||
|
||||
case 0xDA: // PHX 65C02
|
||||
PUSH(HU_X);
|
||||
break;
|
||||
|
||||
case 0x5A: // PHY 65C02
|
||||
PUSH(HU_Y);
|
||||
break;
|
||||
|
||||
case 0x68: /* PLA */
|
||||
HU_A = POP();
|
||||
X_ZN(HU_A);
|
||||
break;
|
||||
|
||||
case 0xFA: // PLX 65C02
|
||||
HU_X = POP();
|
||||
X_ZN(HU_X);
|
||||
break;
|
||||
|
||||
case 0x7A: // PLY 65C02
|
||||
HU_Y = POP();
|
||||
X_ZN(HU_Y);
|
||||
break;
|
||||
|
||||
case 0x28: /* PLP */
|
||||
HU_P = POP();
|
||||
EXPAND_FLAGS();
|
||||
|
||||
// T-flag handling here:
|
||||
TEST_WEIRD_TFLAG("PLP");
|
||||
break;
|
||||
|
||||
case 0x4C:
|
||||
{
|
||||
unsigned int npc;
|
||||
|
||||
npc = RdAtPC();
|
||||
IncPC();
|
||||
npc|=RdAtPC() << 8;
|
||||
|
||||
SetPC(npc);
|
||||
}
|
||||
break; /* JMP ABSOLUTE */
|
||||
|
||||
case 0x6C: /* JMP Indirect */
|
||||
{
|
||||
uint32 tmp;
|
||||
unsigned int npc;
|
||||
|
||||
GetAB(tmp);
|
||||
|
||||
npc=RdMem(tmp);
|
||||
npc|=RdMem(tmp + 1)<<8;
|
||||
|
||||
SetPC(npc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7C: // JMP Indirect X - 65C02
|
||||
{
|
||||
uint32 tmp;
|
||||
unsigned int npc;
|
||||
|
||||
GetAB(tmp);
|
||||
tmp += HU_X;
|
||||
|
||||
npc=RdMem(tmp);
|
||||
npc|=RdMem(tmp + 1)<<8;
|
||||
|
||||
SetPC(npc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20: /* JSR */
|
||||
{
|
||||
unsigned int npc;
|
||||
|
||||
npc = RdAtPC();
|
||||
|
||||
IncPC();
|
||||
PUSH_PC();
|
||||
|
||||
npc |= RdAtPC() <<8;
|
||||
|
||||
SetPC(npc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xAA: /* TAX */
|
||||
HU_X=HU_A;
|
||||
X_ZN(HU_A);
|
||||
break;
|
||||
|
||||
case 0x8A: /* TXA */
|
||||
HU_A=HU_X;
|
||||
X_ZN(HU_A);
|
||||
break;
|
||||
|
||||
case 0xA8: /* TAY */
|
||||
HU_Y=HU_A;
|
||||
X_ZN(HU_A);
|
||||
break;
|
||||
case 0x98: /* TYA */
|
||||
HU_A=HU_Y;
|
||||
X_ZN(HU_A);
|
||||
break;
|
||||
|
||||
case 0xBA: /* TSX */
|
||||
HU_X=HU_S;
|
||||
X_ZN(HU_X);
|
||||
break;
|
||||
case 0x9A: /* TXS */
|
||||
HU_S=HU_X;
|
||||
break;
|
||||
|
||||
case 0xCA: /* DEX */
|
||||
HU_X--;
|
||||
X_ZN(HU_X);
|
||||
break;
|
||||
case 0x88: /* DEY */
|
||||
HU_Y--;
|
||||
X_ZN(HU_Y);
|
||||
break;
|
||||
|
||||
case 0xE8: /* INX */
|
||||
HU_X++;
|
||||
X_ZN(HU_X);
|
||||
break;
|
||||
case 0xC8: /* INY */
|
||||
HU_Y++;
|
||||
X_ZN(HU_Y);
|
||||
break;
|
||||
|
||||
case 0x54: CSL; break;
|
||||
case 0xD4: CSH; break;
|
||||
|
||||
case 0x62: HU_A = 0; break; // CLA
|
||||
case 0x82: HU_X = 0; break; // CLX
|
||||
case 0xC2: HU_Y = 0; break; // CLY
|
||||
|
||||
case 0x18: /* CLC */
|
||||
HU_P&=~C_FLAG;
|
||||
break;
|
||||
|
||||
case 0xD8: /* CLD */
|
||||
HU_P&=~D_FLAG;
|
||||
break;
|
||||
|
||||
case 0x58: /* CLI */
|
||||
if((HU_P & I_FLAG) && (HU_IRQlow & MDFN_IQIRQ1))
|
||||
{
|
||||
uint8 moo_op = RdAtPC();
|
||||
if((moo_op == 0xAC || moo_op == 0xAD || moo_op == 0xAE) &&
|
||||
((RdOp(GetRealPC() + 1) & 0x3) == 0) && ((RdOp(GetRealPC() + 2) & 0xFC) == 0))
|
||||
{
|
||||
HU_IRQlow |= 0x200;
|
||||
//puts("CLI/LDA madness!");
|
||||
}
|
||||
}
|
||||
HU_P&=~I_FLAG;
|
||||
break;
|
||||
|
||||
case 0xB8: /* CLV */
|
||||
HU_P&=~V_FLAG;
|
||||
break;
|
||||
|
||||
case 0x38: /* SEC */
|
||||
HU_P|=C_FLAG;
|
||||
break;
|
||||
|
||||
case 0xF8: /* SED */
|
||||
HU_P|=D_FLAG;
|
||||
break;
|
||||
|
||||
case 0x78: /* SEI */
|
||||
HU_P|=I_FLAG;
|
||||
break;
|
||||
|
||||
case 0xEA: /* NOP */
|
||||
break;
|
||||
|
||||
case 0x0A: RMW_A(ASL);
|
||||
case 0x06: RMW_ZP(ASL);
|
||||
case 0x16: RMW_ZPX(ASL);
|
||||
case 0x0E: RMW_AB(ASL);
|
||||
case 0x1E: RMW_ABX(ASL);
|
||||
|
||||
case 0x3A: RMW_A(DEC);
|
||||
case 0xC6: RMW_ZP(DEC);
|
||||
case 0xD6: RMW_ZPX(DEC);
|
||||
case 0xCE: RMW_AB(DEC);
|
||||
case 0xDE: RMW_ABX(DEC);
|
||||
|
||||
case 0x1A: RMW_A(INC); // 65C02
|
||||
case 0xE6: RMW_ZP(INC);
|
||||
case 0xF6: RMW_ZPX(INC);
|
||||
case 0xEE: RMW_AB(INC);
|
||||
case 0xFE: RMW_ABX(INC);
|
||||
|
||||
case 0x4A: RMW_A(LSR);
|
||||
case 0x46: RMW_ZP(LSR);
|
||||
case 0x56: RMW_ZPX(LSR);
|
||||
case 0x4E: RMW_AB(LSR);
|
||||
case 0x5E: RMW_ABX(LSR);
|
||||
|
||||
case 0x2A: RMW_A(ROL);
|
||||
case 0x26: RMW_ZP(ROL);
|
||||
case 0x36: RMW_ZPX(ROL);
|
||||
case 0x2E: RMW_AB(ROL);
|
||||
case 0x3E: RMW_ABX(ROL);
|
||||
|
||||
case 0x6A: RMW_A(ROR);
|
||||
case 0x66: RMW_ZP(ROR);
|
||||
case 0x76: RMW_ZPX(ROR);
|
||||
case 0x6E: RMW_AB(ROR);
|
||||
case 0x7E: RMW_ABX(ROR);
|
||||
|
||||
case 0x69: LD_IM(ADC);
|
||||
case 0x65: LD_ZP(ADC);
|
||||
case 0x75: LD_ZPX(ADC);
|
||||
case 0x6D: LD_AB(ADC);
|
||||
case 0x7D: LD_ABX(ADC);
|
||||
case 0x79: LD_ABY(ADC);
|
||||
case 0x72: LD_IND(ADC);
|
||||
case 0x61: LD_IX(ADC);
|
||||
case 0x71: LD_IY(ADC);
|
||||
|
||||
case 0x29: LD_IM(AND);
|
||||
case 0x25: LD_ZP(AND);
|
||||
case 0x35: LD_ZPX(AND);
|
||||
case 0x2D: LD_AB(AND);
|
||||
case 0x3D: LD_ABX(AND);
|
||||
case 0x39: LD_ABY(AND);
|
||||
case 0x32: LD_IND(AND);
|
||||
case 0x21: LD_IX(AND);
|
||||
case 0x31: LD_IY(AND);
|
||||
|
||||
case 0x89: LD_IM(BIT);
|
||||
case 0x24: LD_ZP(BIT);
|
||||
case 0x34: LD_ZPX(BIT);
|
||||
case 0x2C: LD_AB(BIT);
|
||||
case 0x3C: LD_ABX(BIT);
|
||||
|
||||
case 0xC9: LD_IM(CMP);
|
||||
case 0xC5: LD_ZP(CMP);
|
||||
case 0xD5: LD_ZPX(CMP);
|
||||
case 0xCD: LD_AB(CMP);
|
||||
case 0xDD: LD_ABX(CMP);
|
||||
case 0xD9: LD_ABY(CMP);
|
||||
case 0xD2: LD_IND(CMP);
|
||||
case 0xC1: LD_IX(CMP);
|
||||
case 0xD1: LD_IY(CMP);
|
||||
|
||||
case 0xE0: LD_IM(CPX);
|
||||
case 0xE4: LD_ZP(CPX);
|
||||
case 0xEC: LD_AB(CPX);
|
||||
|
||||
case 0xC0: LD_IM(CPY);
|
||||
case 0xC4: LD_ZP(CPY);
|
||||
case 0xCC: LD_AB(CPY);
|
||||
|
||||
case 0x49: LD_IM(EOR);
|
||||
case 0x45: LD_ZP(EOR);
|
||||
case 0x55: LD_ZPX(EOR);
|
||||
case 0x4D: LD_AB(EOR);
|
||||
case 0x5D: LD_ABX(EOR);
|
||||
case 0x59: LD_ABY(EOR);
|
||||
case 0x52: LD_IND(EOR);
|
||||
case 0x41: LD_IX(EOR);
|
||||
case 0x51: LD_IY(EOR);
|
||||
|
||||
case 0xA9: LD_IM(LDA);
|
||||
case 0xA5: LD_ZP(LDA);
|
||||
case 0xB5: LD_ZPX(LDA);
|
||||
case 0xAD: LD_AB(LDA);
|
||||
case 0xBD: LD_ABX(LDA);
|
||||
case 0xB9: LD_ABY(LDA);
|
||||
case 0xB2: LD_IND(LDA);
|
||||
case 0xA1: LD_IX(LDA);
|
||||
case 0xB1: LD_IY(LDA);
|
||||
|
||||
case 0xA2: LD_IM(LDX);
|
||||
case 0xA6: LD_ZP(LDX);
|
||||
case 0xB6: LD_ZPY(LDX);
|
||||
case 0xAE: LD_AB(LDX);
|
||||
case 0xBE: LD_ABY(LDX);
|
||||
|
||||
case 0xA0: LD_IM(LDY);
|
||||
case 0xA4: LD_ZP(LDY);
|
||||
case 0xB4: LD_ZPX(LDY);
|
||||
case 0xAC: LD_AB(LDY);
|
||||
case 0xBC: LD_ABX(LDY);
|
||||
|
||||
case 0x09: LD_IM(ORA);
|
||||
case 0x05: LD_ZP(ORA);
|
||||
case 0x15: LD_ZPX(ORA);
|
||||
case 0x0D: LD_AB(ORA);
|
||||
case 0x1D: LD_ABX(ORA);
|
||||
case 0x19: LD_ABY(ORA);
|
||||
case 0x12: LD_IND(ORA);
|
||||
case 0x01: LD_IX(ORA);
|
||||
case 0x11: LD_IY(ORA);
|
||||
|
||||
case 0xE9: LD_IM(SBC);
|
||||
case 0xE5: LD_ZP(SBC);
|
||||
case 0xF5: LD_ZPX(SBC);
|
||||
case 0xED: LD_AB(SBC);
|
||||
case 0xFD: LD_ABX(SBC);
|
||||
case 0xF9: LD_ABY(SBC);
|
||||
case 0xF2: LD_IND(SBC);
|
||||
case 0xE1: LD_IX(SBC);
|
||||
case 0xF1: LD_IY(SBC);
|
||||
|
||||
case 0x85: ST_ZP(HU_A);
|
||||
case 0x95: ST_ZPX(HU_A);
|
||||
case 0x8D: ST_AB(HU_A);
|
||||
case 0x9D: ST_ABX(HU_A);
|
||||
case 0x99: ST_ABY(HU_A);
|
||||
case 0x92: ST_IND(HU_A);
|
||||
case 0x81: ST_IX(HU_A);
|
||||
case 0x91: ST_IY(HU_A);
|
||||
|
||||
case 0x86: ST_ZP(HU_X);
|
||||
case 0x96: ST_ZPY(HU_X);
|
||||
case 0x8E: ST_AB(HU_X);
|
||||
|
||||
case 0x84: ST_ZP(HU_Y);
|
||||
case 0x94: ST_ZPX(HU_Y);
|
||||
case 0x8C: ST_AB(HU_Y);
|
||||
|
||||
/* BBRi */
|
||||
case 0x0F: LD_ZP(BBRi(0));
|
||||
case 0x1F: LD_ZP(BBRi(1));
|
||||
case 0x2F: LD_ZP(BBRi(2));
|
||||
case 0x3F: LD_ZP(BBRi(3));
|
||||
case 0x4F: LD_ZP(BBRi(4));
|
||||
case 0x5F: LD_ZP(BBRi(5));
|
||||
case 0x6F: LD_ZP(BBRi(6));
|
||||
case 0x7F: LD_ZP(BBRi(7));
|
||||
|
||||
/* BBSi */
|
||||
case 0x8F: LD_ZP(BBSi(0));
|
||||
case 0x9F: LD_ZP(BBSi(1));
|
||||
case 0xAF: LD_ZP(BBSi(2));
|
||||
case 0xBF: LD_ZP(BBSi(3));
|
||||
case 0xCF: LD_ZP(BBSi(4));
|
||||
case 0xDF: LD_ZP(BBSi(5));
|
||||
case 0xEF: LD_ZP(BBSi(6));
|
||||
case 0xFF: LD_ZP(BBSi(7));
|
||||
|
||||
/* BRA */
|
||||
case 0x80: BRA; break;
|
||||
|
||||
/* BSR */
|
||||
case 0x44:
|
||||
{
|
||||
PUSH_PC();
|
||||
BRA;
|
||||
}
|
||||
break;
|
||||
|
||||
/* BCC */
|
||||
case 0x90: JR(!(HU_P&C_FLAG)); break;
|
||||
|
||||
/* BCS */
|
||||
case 0xB0: JR(HU_P&C_FLAG); break;
|
||||
|
||||
/* BVC */
|
||||
case 0x50: JR(!(HU_P&V_FLAG)); break;
|
||||
|
||||
/* BVS */
|
||||
case 0x70: JR(HU_P&V_FLAG); break;
|
||||
|
||||
#ifdef HUC6280_LAZY_FLAGS
|
||||
|
||||
/* BEQ */
|
||||
case 0xF0: JR(!(HU_ZNFlags & 0xFF)); break;
|
||||
|
||||
/* BNE */
|
||||
case 0xD0: JR((HU_ZNFlags & 0xFF)); break;
|
||||
|
||||
/* BMI */
|
||||
case 0x30: JR((HU_ZNFlags & 0x80000000)); break;
|
||||
|
||||
/* BPL */
|
||||
case 0x10: JR(!(HU_ZNFlags & 0x80000000)); break;
|
||||
|
||||
#else
|
||||
|
||||
/* BEQ */
|
||||
case 0xF0: JR(HU_P&Z_FLAG); break;
|
||||
|
||||
/* BNE */
|
||||
case 0xD0: JR(!(HU_P&Z_FLAG)); break;
|
||||
|
||||
/* BMI */
|
||||
case 0x30: JR(HU_P&N_FLAG); break;
|
||||
|
||||
/* BPL */
|
||||
case 0x10: JR(!(HU_P&N_FLAG)); break;
|
||||
|
||||
#endif
|
||||
|
||||
// RMB 65SC02
|
||||
case 0x07: RMW_ZP(RMB(0));
|
||||
case 0x17: RMW_ZP(RMB(1));
|
||||
case 0x27: RMW_ZP(RMB(2));
|
||||
case 0x37: RMW_ZP(RMB(3));
|
||||
case 0x47: RMW_ZP(RMB(4));
|
||||
case 0x57: RMW_ZP(RMB(5));
|
||||
case 0x67: RMW_ZP(RMB(6));
|
||||
case 0x77: RMW_ZP(RMB(7));
|
||||
|
||||
// SMB 65SC02
|
||||
case 0x87: RMW_ZP(SMB(0));
|
||||
case 0x97: RMW_ZP(SMB(1));
|
||||
case 0xa7: RMW_ZP(SMB(2));
|
||||
case 0xb7: RMW_ZP(SMB(3));
|
||||
case 0xc7: RMW_ZP(SMB(4));
|
||||
case 0xd7: RMW_ZP(SMB(5));
|
||||
case 0xe7: RMW_ZP(SMB(6));
|
||||
case 0xf7: RMW_ZP(SMB(7));
|
||||
|
||||
// STZ 65C02
|
||||
case 0x64: ST_ZP(0);
|
||||
case 0x74: ST_ZPX(0);
|
||||
case 0x9C: ST_AB(0);
|
||||
case 0x9E: ST_ABX(0);
|
||||
|
||||
// TRB 65SC02
|
||||
case 0x14: RMW_ZP(TRB);
|
||||
case 0x1C: RMW_AB(TRB);
|
||||
|
||||
// TSB 65SC02
|
||||
case 0x04: RMW_ZP(TSB);
|
||||
case 0x0C: RMW_AB(TSB);
|
||||
|
||||
// TST
|
||||
case 0x83: { uint8 zoomhack=RdAtPC(); IncPC(); LD_ZP(TST); }
|
||||
case 0xA3: { uint8 zoomhack=RdAtPC(); IncPC(); LD_ZPX(TST); }
|
||||
case 0x93: { uint8 zoomhack=RdAtPC(); IncPC(); LD_AB(TST); }
|
||||
case 0xB3: { uint8 zoomhack=RdAtPC(); IncPC(); LD_ABX(TST); }
|
||||
|
||||
case 0x22: // SAX(amaphone!)
|
||||
{
|
||||
uint8 tmp = HU_X;
|
||||
HU_X = HU_A;
|
||||
HU_A = tmp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x42: // SAY(what?)
|
||||
{
|
||||
uint8 tmp = HU_Y;
|
||||
HU_Y = HU_A;
|
||||
HU_A = tmp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02: // SXY
|
||||
{
|
||||
uint8 tmp = HU_X;
|
||||
HU_X = HU_Y;
|
||||
HU_Y = tmp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x73: // TII
|
||||
LD_BMT(BMT_TII);
|
||||
|
||||
case 0xC3: // TDD
|
||||
LD_BMT(BMT_TDD);
|
||||
|
||||
case 0xD3: // TIN
|
||||
LD_BMT(BMT_TIN);
|
||||
|
||||
case 0xE3: // TIA
|
||||
LD_BMT(BMT_TIA);
|
||||
|
||||
case 0xF3: // TAI
|
||||
LD_BMT(BMT_TAI);
|
||||
|
||||
case 0x43: // TMAi
|
||||
LD_IM(TMA);
|
||||
|
||||
case 0x53: // TAMi
|
||||
LD_IM(TAM);
|
||||
|
||||
case 0x03: // ST0
|
||||
LD_IM(ST0);
|
||||
|
||||
case 0x13: // ST1
|
||||
LD_IM(ST1);
|
||||
|
||||
case 0x23: // ST2
|
||||
LD_IM(ST2);
|
||||
|
||||
|
||||
case 0xF4: /* SET */
|
||||
{
|
||||
// AND, EOR, ORA, ADC
|
||||
uint8 Abackup = HU_A;
|
||||
|
||||
ADDCYC(3);
|
||||
HU_A = HU_Page1[HU_X]; //PAGE1_R[HU_X];
|
||||
|
||||
switch(RdAtPC())
|
||||
{
|
||||
default: //puts("Bad SET");
|
||||
break;
|
||||
|
||||
case 0x69: IncPC(); LD_IM(ADC);
|
||||
case 0x65: IncPC(); LD_ZP(ADC);
|
||||
case 0x75: IncPC(); LD_ZPX(ADC);
|
||||
case 0x6D: IncPC(); LD_AB(ADC);
|
||||
case 0x7D: IncPC(); LD_ABX(ADC);
|
||||
case 0x79: IncPC(); LD_ABY(ADC);
|
||||
case 0x72: IncPC(); LD_IND(ADC);
|
||||
case 0x61: IncPC(); LD_IX(ADC);
|
||||
case 0x71: IncPC(); LD_IY(ADC);
|
||||
|
||||
case 0x29: IncPC(); LD_IM(AND);
|
||||
case 0x25: IncPC(); LD_ZP(AND);
|
||||
case 0x35: IncPC(); LD_ZPX(AND);
|
||||
case 0x2D: IncPC(); LD_AB(AND);
|
||||
case 0x3D: IncPC(); LD_ABX(AND);
|
||||
case 0x39: IncPC(); LD_ABY(AND);
|
||||
case 0x32: IncPC(); LD_IND(AND);
|
||||
case 0x21: IncPC(); LD_IX(AND);
|
||||
case 0x31: IncPC(); LD_IY(AND);
|
||||
|
||||
case 0x49: IncPC(); LD_IM(EOR);
|
||||
case 0x45: IncPC(); LD_ZP(EOR);
|
||||
case 0x55: IncPC(); LD_ZPX(EOR);
|
||||
case 0x4D: IncPC(); LD_AB(EOR);
|
||||
case 0x5D: IncPC(); LD_ABX(EOR);
|
||||
case 0x59: IncPC(); LD_ABY(EOR);
|
||||
case 0x52: IncPC(); LD_IND(EOR);
|
||||
case 0x41: IncPC(); LD_IX(EOR);
|
||||
case 0x51: IncPC(); LD_IY(EOR);
|
||||
|
||||
case 0x09: IncPC(); LD_IM(ORA);
|
||||
case 0x05: IncPC(); LD_ZP(ORA);
|
||||
case 0x15: IncPC(); LD_ZPX(ORA);
|
||||
case 0x0D: IncPC(); LD_AB(ORA);
|
||||
case 0x1D: IncPC(); LD_ABX(ORA);
|
||||
case 0x19: IncPC(); LD_ABY(ORA);
|
||||
case 0x12: IncPC(); LD_IND(ORA);
|
||||
case 0x01: IncPC(); LD_IX(ORA);
|
||||
case 0x11: IncPC(); LD_IY(ORA);
|
||||
}
|
||||
HU_Page1[HU_X] /*PAGE1_W[HU_X]*/ = HU_A;
|
||||
HU_A = Abackup;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xFC:
|
||||
{
|
||||
int32 ec_tmp;
|
||||
ec_tmp = next_event - HuCPU.timestamp;
|
||||
if(ec_tmp > 0)
|
||||
{
|
||||
ADDCYC(ec_tmp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: MDFN_printf("Bad %02x at $%04x\n", b1, GetRealPC());
|
||||
break;
|
337
mednafen/pce_fast/input.cpp
Normal file
337
mednafen/pce_fast/input.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/* 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 "pce.h"
|
||||
#include "input.h"
|
||||
#include "huc.h"
|
||||
#include "../mednafen-endian.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
static int InputTypes[5];
|
||||
static uint8 *data_ptr[5];
|
||||
|
||||
static bool AVPad6Which[5]; // Lower(8 buttons) or higher(4 buttons).
|
||||
static bool AVPad6Enabled[5];
|
||||
|
||||
uint16 pce_jp_data[5];
|
||||
|
||||
static int64 mouse_last_meow[5];
|
||||
|
||||
static int32 mouse_x[5], mouse_y[5];
|
||||
static uint16 mouse_rel[5];
|
||||
|
||||
uint8 pce_mouse_button[5];
|
||||
uint8 mouse_index[5];
|
||||
|
||||
static uint8 sel;
|
||||
static uint8 read_index = 0;
|
||||
|
||||
static void SyncSettings(void);
|
||||
|
||||
void PCEINPUT_SettingChanged(const char *name)
|
||||
{
|
||||
SyncSettings();
|
||||
}
|
||||
|
||||
void PCEINPUT_Init(void)
|
||||
{
|
||||
SyncSettings();
|
||||
}
|
||||
|
||||
void PCEINPUT_SetInput(int port, const char *type, void *ptr)
|
||||
{
|
||||
assert(port < 5);
|
||||
|
||||
if(!strcasecmp(type, "gamepad"))
|
||||
InputTypes[port] = 1;
|
||||
else if(!strcasecmp(type, "mouse"))
|
||||
InputTypes[port] = 2;
|
||||
else
|
||||
InputTypes[port] = 0;
|
||||
data_ptr[port] = (uint8 *)ptr;
|
||||
}
|
||||
|
||||
void INPUT_Frame(void)
|
||||
{
|
||||
for(int x = 0; x < 5; x++)
|
||||
{
|
||||
if(InputTypes[x] == 1)
|
||||
{
|
||||
uint16 new_data = data_ptr[x][0] | (data_ptr[x][1] << 8);
|
||||
|
||||
if((new_data & 0x1000) && !(pce_jp_data[x] & 0x1000))
|
||||
{
|
||||
AVPad6Enabled[x] = !AVPad6Enabled[x];
|
||||
MDFN_DispMessage("%d-button mode selected for pad %d", AVPad6Enabled[x] ? 6 : 2, x + 1);
|
||||
}
|
||||
|
||||
pce_jp_data[x] = new_data;
|
||||
}
|
||||
else if(InputTypes[x] == 2)
|
||||
{
|
||||
mouse_x[x] += (int32)MDFN_de32lsb(data_ptr[x] + 0);
|
||||
mouse_y[x] += (int32)MDFN_de32lsb(data_ptr[x] + 4);
|
||||
pce_mouse_button[x] = *(uint8 *)(data_ptr[x] + 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void INPUT_FixTS(void)
|
||||
{
|
||||
for(int x = 0; x < 5; x++)
|
||||
{
|
||||
if(InputTypes[x] == 2)
|
||||
mouse_last_meow[x] -= HuCPU.timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE bool CheckLM(int n)
|
||||
{
|
||||
if((int64)HuCPU.timestamp - mouse_last_meow[n] > 10000)
|
||||
{
|
||||
mouse_last_meow[n] = HuCPU.timestamp;
|
||||
|
||||
int32 rel_x = (int32)((0-mouse_x[n]));
|
||||
int32 rel_y = (int32)((0-mouse_y[n]));
|
||||
|
||||
if(rel_x < -127) rel_x = -127;
|
||||
if(rel_x > 127) rel_x = 127;
|
||||
if(rel_y < -127) rel_y = -127;
|
||||
if(rel_y > 127) rel_y = 127;
|
||||
|
||||
mouse_rel[n] = ((rel_x & 0xF0) >> 4) | ((rel_x & 0x0F) << 4);
|
||||
mouse_rel[n] |= (((rel_y & 0xF0) >> 4) | ((rel_y & 0x0F) << 4)) << 8;
|
||||
|
||||
mouse_x[n] += (int32)(rel_x);
|
||||
mouse_y[n] += (int32)(rel_y);
|
||||
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint8 INPUT_Read(unsigned int A)
|
||||
{
|
||||
uint8 ret = 0xF;
|
||||
int tmp_ri = read_index;
|
||||
|
||||
if(tmp_ri > 4)
|
||||
ret ^= 0xF;
|
||||
else
|
||||
{
|
||||
if(!InputTypes[tmp_ri])
|
||||
ret ^= 0xF;
|
||||
else if(InputTypes[tmp_ri] == 2) // Mouse
|
||||
{
|
||||
if(sel & 1)
|
||||
{
|
||||
CheckLM(tmp_ri);
|
||||
ret ^= 0xF;
|
||||
ret ^= mouse_rel[tmp_ri] & 0xF;
|
||||
|
||||
mouse_rel[tmp_ri] >>= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pce_mouse_button[tmp_ri] & 1)
|
||||
ret ^= 0x3; //pce_mouse_button[tmp_ri];
|
||||
|
||||
if(pce_mouse_button[tmp_ri] & 0x2)
|
||||
ret ^= 0x8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(InputTypes[tmp_ri] == 1) // Gamepad
|
||||
{
|
||||
if(AVPad6Which[tmp_ri] && AVPad6Enabled[tmp_ri])
|
||||
{
|
||||
if(sel & 1)
|
||||
ret ^= 0x0F;
|
||||
else
|
||||
ret ^= (pce_jp_data[tmp_ri] >> 8) & 0x0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sel & 1)
|
||||
ret ^= (pce_jp_data[tmp_ri] >> 4) & 0x0F;
|
||||
else
|
||||
ret ^= pce_jp_data[tmp_ri] & 0x0F;
|
||||
}
|
||||
if(!(sel & 1))
|
||||
AVPad6Which[tmp_ri] = !AVPad6Which[tmp_ri];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!PCE_IsCD)
|
||||
ret |= 0x80; // Set when CDROM is not attached
|
||||
|
||||
//ret |= 0x40; // PC Engine if set, TG16 if clear. Let's leave it clear, PC Engine games don't seem to mind if it's clear, but TG16 games barf if it's set.
|
||||
|
||||
ret |= 0x30; // Always-set?
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void INPUT_Write(unsigned int A, uint8 V)
|
||||
{
|
||||
if((V & 1) && !(sel & 2) && (V & 2))
|
||||
{
|
||||
read_index = 0;
|
||||
}
|
||||
else if((V & 1) && !(sel & 1))
|
||||
{
|
||||
if(read_index < 255)
|
||||
read_index++;
|
||||
}
|
||||
sel = V & 3;
|
||||
}
|
||||
|
||||
int INPUT_StateAction(StateMem *sm, int load, int data_only)
|
||||
{
|
||||
SFORMAT StateRegs[] =
|
||||
{
|
||||
// 0.8.A fix:
|
||||
SFARRAYB(AVPad6Enabled, 5),
|
||||
SFARRAYB(AVPad6Which, 5),
|
||||
|
||||
SFVARN(mouse_last_meow[0], "mlm_0"),
|
||||
SFVARN(mouse_last_meow[1], "mlm_1"),
|
||||
SFVARN(mouse_last_meow[2], "mlm_2"),
|
||||
SFVARN(mouse_last_meow[3], "mlm_3"),
|
||||
SFVARN(mouse_last_meow[4], "mlm_4"),
|
||||
|
||||
SFARRAY32(mouse_x, 5),
|
||||
SFARRAY32(mouse_y, 5),
|
||||
SFARRAY16(mouse_rel, 5),
|
||||
SFARRAY(pce_mouse_button, 5),
|
||||
SFARRAY(mouse_index, 5),
|
||||
// end 0.8.A fix
|
||||
|
||||
SFARRAY16(pce_jp_data, 5),
|
||||
SFVAR(sel),
|
||||
SFVAR(read_index),
|
||||
SFEND
|
||||
};
|
||||
int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "JOY");
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// GamepadIDII and GamepadIDII_DSR must be EXACTLY the same except for the RUN+SELECT exclusion in the latter.
|
||||
static const InputDeviceInputInfoStruct GamepadIDII[] =
|
||||
{
|
||||
{ "i", "I", 12, IDIT_BUTTON_CAN_RAPID, NULL },
|
||||
{ "ii", "II", 11, IDIT_BUTTON_CAN_RAPID, NULL },
|
||||
{ "select", "SELECT", 4, IDIT_BUTTON, NULL },
|
||||
{ "run", "RUN", 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" },
|
||||
{ "iii", "III", 10, IDIT_BUTTON, NULL },
|
||||
{ "iv", "IV", 7, IDIT_BUTTON, NULL },
|
||||
{ "v", "V", 8, IDIT_BUTTON, NULL },
|
||||
{ "vi", "VI", 9, IDIT_BUTTON, NULL },
|
||||
{ "mode_select", "2/6 Mode Select", 6, IDIT_BUTTON, NULL },
|
||||
};
|
||||
static const InputDeviceInputInfoStruct GamepadIDII_DSR[] =
|
||||
{
|
||||
{ "i", "I", 12, IDIT_BUTTON_CAN_RAPID, NULL },
|
||||
{ "ii", "II", 11, IDIT_BUTTON_CAN_RAPID, NULL },
|
||||
{ "select", "SELECT", 4, IDIT_BUTTON, "run" },
|
||||
{ "run", "RUN", 5, IDIT_BUTTON, "select" },
|
||||
{ "up", "UP ↑", 0, IDIT_BUTTON, "down" },
|
||||
{ "right", "RIGHT →", 3, IDIT_BUTTON, "left" },
|
||||
{ "down", "DOWN ↓", 1, IDIT_BUTTON, "up" },
|
||||
{ "left", "LEFT ←", 2, IDIT_BUTTON, "right" },
|
||||
{ "iii", "III", 10, IDIT_BUTTON, NULL },
|
||||
{ "iv", "IV", 7, IDIT_BUTTON, NULL },
|
||||
{ "v", "V", 8, IDIT_BUTTON, NULL },
|
||||
{ "vi", "VI", 9, IDIT_BUTTON, NULL },
|
||||
{ "mode_select", "2/6 Mode Select", 6, IDIT_BUTTON, NULL },
|
||||
};
|
||||
|
||||
static const InputDeviceInputInfoStruct MouseIDII[] =
|
||||
{
|
||||
{ "x_axis", "X Axis", -1, IDIT_X_AXIS_REL },
|
||||
{ "y_axis", "Y Axis", -1, IDIT_Y_AXIS_REL },
|
||||
{ "left", "Left Button", 0, IDIT_BUTTON, NULL },
|
||||
{ "right", "Right Button", 1, IDIT_BUTTON, NULL },
|
||||
};
|
||||
|
||||
// If we add more devices to this array, REMEMBER TO UPDATE the hackish array indexing in the SyncSettings() function
|
||||
// below.
|
||||
static InputDeviceInfoStruct InputDeviceInfo[] =
|
||||
{
|
||||
// None
|
||||
{
|
||||
"none",
|
||||
"none",
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
|
||||
// Gamepad
|
||||
{
|
||||
"gamepad",
|
||||
"Gamepad",
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(GamepadIDII) / sizeof(InputDeviceInputInfoStruct),
|
||||
GamepadIDII,
|
||||
},
|
||||
|
||||
// Mouse
|
||||
{
|
||||
"mouse",
|
||||
"Mouse",
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(MouseIDII) / sizeof(InputDeviceInputInfoStruct),
|
||||
MouseIDII,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static const InputPortInfoStruct PortInfo[] =
|
||||
{
|
||||
{ "port1", "Port 1", sizeof(InputDeviceInfo) / sizeof(InputDeviceInfoStruct), InputDeviceInfo, "gamepad" },
|
||||
{ "port2", "Port 2", sizeof(InputDeviceInfo) / sizeof(InputDeviceInfoStruct), InputDeviceInfo, "gamepad" },
|
||||
{ "port3", "Port 3", sizeof(InputDeviceInfo) / sizeof(InputDeviceInfoStruct), InputDeviceInfo, "gamepad" },
|
||||
{ "port4", "Port 4", sizeof(InputDeviceInfo) / sizeof(InputDeviceInfoStruct), InputDeviceInfo, "gamepad" },
|
||||
{ "port5", "Port 5", sizeof(InputDeviceInfo) / sizeof(InputDeviceInfoStruct), InputDeviceInfo, "gamepad" },
|
||||
};
|
||||
|
||||
InputInfoStruct PCEInputInfo =
|
||||
{
|
||||
sizeof(PortInfo) / sizeof(InputPortInfoStruct),
|
||||
PortInfo
|
||||
};
|
||||
|
||||
static void SyncSettings(void)
|
||||
{
|
||||
MDFNGameInfo->mouse_sensitivity = MDFN_GetSettingF("pce_fast.mouse_sensitivity");
|
||||
InputDeviceInfo[1].IDII = MDFN_GetSettingB("pce_fast.disable_softreset") ? GamepadIDII_DSR : GamepadIDII;
|
||||
}
|
||||
|
||||
};
|
19
mednafen/pce_fast/input.h
Normal file
19
mednafen/pce_fast/input.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef __PCE_INPUT_H
|
||||
#define __PCE_INPUT_H
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
void PCEINPUT_Init(void);
|
||||
void PCEINPUT_SettingChanged(const char *name);
|
||||
void PCEINPUT_SetInput(int port, const char *type, void *ptr);
|
||||
uint8 INPUT_Read(unsigned int A);
|
||||
void INPUT_Write(unsigned int A, uint8 V);
|
||||
void INPUT_Frame(void);
|
||||
int INPUT_StateAction(StateMem *sm, int load, int data_only);
|
||||
extern InputInfoStruct PCEInputInfo;
|
||||
void INPUT_FixTS(void);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
116
mednafen/pce_fast/ioread.inc
Normal file
116
mednafen/pce_fast/ioread.inc
Normal file
@ -0,0 +1,116 @@
|
||||
const void * const IOReadHandlers[0x20] =
|
||||
{
|
||||
&&VDC_00, &&VDC_01, &&VDC_02, &&VDC_03,
|
||||
&&VCE_00, &&VCE_01, &&VCE_02, &&VCE_03,
|
||||
&&PSG, &&PSG, &&PSG, &&PSG,
|
||||
&&TIMER_00, &&TIMER_01, &&TIMER_02, &&TIMER_03,
|
||||
&&INPUT_00, &&INPUT_01, &&INPUT_02, &&INPUT_03,
|
||||
&&IRQ_00, &&IRQ_01, &&IRQ_02, &&IRQ_03,
|
||||
&&CDROM, &&CDROM, &&CDROM, &&CDROM,
|
||||
&&EXP, &&EXP, &&EXP, &&EXP
|
||||
};
|
||||
|
||||
A &= 0x1FFF;
|
||||
|
||||
goto *IOReadHandlers[((A & 0x1C00) >> 8) | (A & 0x3)];
|
||||
|
||||
#if IOREAD_SGX==1
|
||||
VDC_00:
|
||||
VDC_01:
|
||||
VDC_02:
|
||||
VDC_03: HuC6280_StealCycle();
|
||||
return(VDC_Read(A&0x1F, TRUE));
|
||||
#else
|
||||
|
||||
VDC_00:
|
||||
HuC6280_StealCycle();
|
||||
return(VDC_Read(0, FALSE));
|
||||
|
||||
VDC_01:
|
||||
HuC6280_StealCycle();
|
||||
return(VDC_Read(1, FALSE));
|
||||
|
||||
VDC_02:
|
||||
HuC6280_StealCycle();
|
||||
return(VDC_Read(2, FALSE));
|
||||
|
||||
VDC_03:
|
||||
HuC6280_StealCycle();
|
||||
return(VDC_Read(3, FALSE));
|
||||
#endif
|
||||
|
||||
VCE_00:
|
||||
VCE_01:
|
||||
VCE_02:
|
||||
VCE_03:
|
||||
HuC6280_StealCycle();
|
||||
return(VCE_Read(A));
|
||||
|
||||
PSG:
|
||||
if(HuCPU.in_block_move)
|
||||
return(0);
|
||||
return(PCEIODataBuffer);
|
||||
|
||||
|
||||
TIMER_00:
|
||||
TIMER_01:
|
||||
TIMER_02:
|
||||
TIMER_03:
|
||||
|
||||
if(HuCPU.in_block_move)
|
||||
return(0);
|
||||
{
|
||||
uint8 ret = HuC6280_TimerRead(A);
|
||||
PCEIODataBuffer = ret;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
INPUT_00:
|
||||
INPUT_01:
|
||||
INPUT_02:
|
||||
INPUT_03:
|
||||
if(HuCPU.in_block_move)
|
||||
return(0);
|
||||
{
|
||||
uint8 ret = INPUT_Read(A);
|
||||
PCEIODataBuffer = ret;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
IRQ_00:
|
||||
IRQ_01:
|
||||
IRQ_02:
|
||||
IRQ_03:
|
||||
if(HuCPU.in_block_move)
|
||||
return(0);
|
||||
{
|
||||
uint8 ret = HuC6280_IRQStatusRead(A);
|
||||
PCEIODataBuffer = ret;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
CDROM:
|
||||
if(IsTsushin)
|
||||
return(PCE_TsushinRead(A));
|
||||
|
||||
if(!PCE_IsCD)
|
||||
return(0xFF);
|
||||
|
||||
if((A & 0x1E00) == 0x1A00)
|
||||
{
|
||||
if(arcade_card)
|
||||
return(arcade_card->Read(A & 0x1FFF));
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 next_cd_event;
|
||||
|
||||
return(PCECD_Read(HuCPU.timestamp * 3, A, next_cd_event));
|
||||
}
|
||||
|
||||
|
||||
EXP:
|
||||
//printf("Meow: %08x, %02x:%04x\n", A, A >> 13, A & 0x1FFF);
|
||||
return(0xFF);
|
649
mednafen/pce_fast/pce.cpp
Normal file
649
mednafen/pce_fast/pce.cpp
Normal file
@ -0,0 +1,649 @@
|
||||
/* 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 "pce.h"
|
||||
#include <zlib.h>
|
||||
#include "vdc.h"
|
||||
#include "../hw_sound/pce_psg/pce_psg.h"
|
||||
#include "input.h"
|
||||
#include "huc.h"
|
||||
#include "../cdrom/pcecd.h"
|
||||
#include "../cdrom/scsicd.h"
|
||||
#include "tsushin.h"
|
||||
#include "../hw_misc/arcade_card/arcade_card.h"
|
||||
#include "../mempatcher.h"
|
||||
#include "../cdrom/cdromif.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
static PCE_PSG *psg = NULL;
|
||||
extern ArcadeCard *arcade_card; // Bah, lousy globals.
|
||||
|
||||
static Blip_Buffer sbuf[2];
|
||||
|
||||
bool PCE_ACEnabled;
|
||||
|
||||
static bool IsSGX;
|
||||
int pce_overclocked;
|
||||
|
||||
// Statically allocated for speed...or something.
|
||||
uint8 ROMSpace[0x88 * 8192 + 8192]; // + 8192 for PC-as-pointer safety padding
|
||||
|
||||
uint8 BaseRAM[32768 + 8192]; // 8KB for PCE, 32KB for Super Grafx // + 8192 for PC-as-pointer safety padding
|
||||
|
||||
uint8 PCEIODataBuffer;
|
||||
readfunc PCERead[0x100];
|
||||
writefunc PCEWrite[0x100];
|
||||
|
||||
static DECLFR(PCEBusRead)
|
||||
{
|
||||
//printf("BUS Read: %02x %04x\n", A >> 13, A);
|
||||
return(0xFF);
|
||||
}
|
||||
|
||||
static DECLFW(PCENullWrite)
|
||||
{
|
||||
//printf("Null Write: %02x, %08x %02x\n", A >> 13, A, V);
|
||||
}
|
||||
|
||||
static DECLFR(BaseRAMReadSGX)
|
||||
{
|
||||
return((BaseRAM - (0xF8 * 8192))[A]);
|
||||
}
|
||||
|
||||
static DECLFW(BaseRAMWriteSGX)
|
||||
{
|
||||
(BaseRAM - (0xF8 * 8192))[A] = V;
|
||||
}
|
||||
|
||||
static DECLFR(BaseRAMRead)
|
||||
{
|
||||
return((BaseRAM - (0xF8 * 8192))[A]);
|
||||
}
|
||||
|
||||
static DECLFR(BaseRAMRead_Mirrored)
|
||||
{
|
||||
return(BaseRAM[A & 0x1FFF]);
|
||||
}
|
||||
|
||||
static DECLFW(BaseRAMWrite)
|
||||
{
|
||||
(BaseRAM - (0xF8 * 8192))[A] = V;
|
||||
}
|
||||
|
||||
static DECLFW(BaseRAMWrite_Mirrored)
|
||||
{
|
||||
BaseRAM[A & 0x1FFF] = V;
|
||||
}
|
||||
|
||||
static DECLFR(IORead)
|
||||
{
|
||||
#define IOREAD_SGX 0
|
||||
#include "ioread.inc"
|
||||
#undef IOREAD_SGX
|
||||
}
|
||||
|
||||
static DECLFR(IOReadSGX)
|
||||
{
|
||||
#define IOREAD_SGX 1
|
||||
#include "ioread.inc"
|
||||
#undef IOREAD_SGX
|
||||
}
|
||||
|
||||
static DECLFW(IOWrite)
|
||||
{
|
||||
A &= 0x1FFF;
|
||||
|
||||
switch(A & 0x1c00)
|
||||
{
|
||||
case 0x0000: HuC6280_StealCycle();
|
||||
VDC_Write(A, V);
|
||||
break;
|
||||
case 0x0400: HuC6280_StealCycle();
|
||||
VCE_Write(A, V);
|
||||
break;
|
||||
|
||||
case 0x0800: PCEIODataBuffer = V;
|
||||
psg->Write(HuCPU.timestamp / pce_overclocked, A, V);
|
||||
break;
|
||||
|
||||
case 0x0c00: PCEIODataBuffer = V;
|
||||
HuC6280_TimerWrite(A, V);
|
||||
break;
|
||||
|
||||
case 0x1000: PCEIODataBuffer = V; INPUT_Write(A, V); break;
|
||||
case 0x1400: PCEIODataBuffer = V; HuC6280_IRQStatusWrite(A, V); break;
|
||||
case 0x1800: if(IsTsushin)
|
||||
PCE_TsushinWrite(A, V);
|
||||
|
||||
if(!PCE_IsCD)
|
||||
break;
|
||||
|
||||
if((A & 0x1E00) == 0x1A00)
|
||||
{
|
||||
if(arcade_card)
|
||||
arcade_card->Write(A & 0x1FFF, V);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 dummy_ne;
|
||||
|
||||
dummy_ne = PCECD_Write(HuCPU.timestamp * 3, A, V);
|
||||
}
|
||||
break;
|
||||
//case 0x1C00: break; // Expansion
|
||||
//default: printf("Eep: %04x\n", A); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void PCECDIRQCB(bool asserted)
|
||||
{
|
||||
if(asserted)
|
||||
HuC6280_IRQBegin(MDFN_IQIRQ2);
|
||||
else
|
||||
HuC6280_IRQEnd(MDFN_IQIRQ2);
|
||||
}
|
||||
|
||||
bool PCE_InitCD(void)
|
||||
{
|
||||
PCECD_Settings cd_settings;
|
||||
memset(&cd_settings, 0, sizeof(PCECD_Settings));
|
||||
|
||||
cd_settings.CDDA_Volume = (double)MDFN_GetSettingUI("pce_fast.cddavolume") / 100;
|
||||
cd_settings.CD_Speed = MDFN_GetSettingUI("pce_fast.cdspeed");
|
||||
|
||||
cd_settings.ADPCM_Volume = (double)MDFN_GetSettingUI("pce_fast.adpcmvolume") / 100;
|
||||
cd_settings.ADPCM_LPF = MDFN_GetSettingB("pce_fast.adpcmlp");
|
||||
|
||||
if(cd_settings.CDDA_Volume != 1.0)
|
||||
MDFN_printf(_("CD-DA Volume: %d%%\n"), (int)(100 * cd_settings.CDDA_Volume));
|
||||
|
||||
if(cd_settings.ADPCM_Volume != 1.0)
|
||||
MDFN_printf(_("ADPCM Volume: %d%%\n"), (int)(100 * cd_settings.ADPCM_Volume));
|
||||
|
||||
return(PCECD_Init(&cd_settings, PCECDIRQCB, PCE_MASTER_CLOCK, pce_overclocked, &sbuf[0], &sbuf[1]));
|
||||
}
|
||||
|
||||
|
||||
static int LoadCommon(void);
|
||||
static void LoadCommonPre(void);
|
||||
|
||||
static bool TestMagic(const char *name, MDFNFILE *fp)
|
||||
{
|
||||
if(strcasecmp(fp->ext, "pce") && strcasecmp(fp->ext, "sgx"))
|
||||
return(FALSE);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static int Load(const char *name, MDFNFILE *fp)
|
||||
{
|
||||
uint32 headerlen = 0;
|
||||
uint32 r_size;
|
||||
|
||||
IsSGX = 0;
|
||||
|
||||
LoadCommonPre();
|
||||
|
||||
{
|
||||
if(fp->size & 0x200) // 512 byte header!
|
||||
headerlen = 512;
|
||||
}
|
||||
|
||||
r_size = fp->size - headerlen;
|
||||
if(r_size > 4096 * 1024) r_size = 4096 * 1024;
|
||||
|
||||
for(int x = 0; x < 0x100; x++)
|
||||
{
|
||||
PCERead[x] = PCEBusRead;
|
||||
PCEWrite[x] = PCENullWrite;
|
||||
}
|
||||
|
||||
uint32 crc = crc32(0, fp->data + headerlen, fp->size - headerlen);
|
||||
|
||||
|
||||
HuCLoad(fp->data + headerlen, fp->size - headerlen, crc);
|
||||
|
||||
if(!strcasecmp(fp->ext, "sgx"))
|
||||
IsSGX = TRUE;
|
||||
|
||||
if(fp->size >= 8192 && !memcmp(fp->data + headerlen, "DARIUS Version 1.11b", strlen("DARIUS VERSION 1.11b")))
|
||||
{
|
||||
MDFN_printf("SuperGfx: Darius Plus\n");
|
||||
IsSGX = 1;
|
||||
}
|
||||
|
||||
if(crc == 0x4c2126b0)
|
||||
{
|
||||
MDFN_printf("SuperGfx: Aldynes\n");
|
||||
IsSGX = 1;
|
||||
}
|
||||
|
||||
if(crc == 0x8c4588e2)
|
||||
{
|
||||
MDFN_printf("SuperGfx: 1941 - Counter Attack\n");
|
||||
IsSGX = 1;
|
||||
}
|
||||
if(crc == 0x1f041166)
|
||||
{
|
||||
MDFN_printf("SuperGfx: Madouou Granzort\n");
|
||||
IsSGX = 1;
|
||||
}
|
||||
if(crc == 0xb486a8ed)
|
||||
{
|
||||
MDFN_printf("SuperGfx: Daimakaimura\n");
|
||||
IsSGX = 1;
|
||||
}
|
||||
if(crc == 0x3b13af61)
|
||||
{
|
||||
MDFN_printf("SuperGfx: Battle Ace\n");
|
||||
IsSGX = 1;
|
||||
}
|
||||
|
||||
return(LoadCommon());
|
||||
}
|
||||
|
||||
static void LoadCommonPre(void)
|
||||
{
|
||||
// FIXME: Make these globals less global!
|
||||
pce_overclocked = MDFN_GetSettingUI("pce_fast.ocmultiplier");
|
||||
PCE_ACEnabled = MDFN_GetSettingB("pce_fast.arcadecard");
|
||||
|
||||
if(pce_overclocked > 1)
|
||||
MDFN_printf(_("CPU overclock: %dx\n"), pce_overclocked);
|
||||
|
||||
if(MDFN_GetSettingUI("pce_fast.cdspeed") > 1)
|
||||
MDFN_printf(_("CD-ROM speed: %ux\n"), (unsigned int)MDFN_GetSettingUI("pce_fast.cdspeed"));
|
||||
|
||||
memset(HuCPUFastMap, 0, sizeof(HuCPUFastMap));
|
||||
for(int x = 0; x < 0x100; x++)
|
||||
{
|
||||
PCERead[x] = PCEBusRead;
|
||||
PCEWrite[x] = PCENullWrite;
|
||||
}
|
||||
|
||||
MDFNMP_Init(1024, (1 << 21) / 1024);
|
||||
}
|
||||
|
||||
static int LoadCommon(void)
|
||||
{
|
||||
IsSGX |= MDFN_GetSettingB("pce_fast.forcesgx") ? 1 : 0;
|
||||
|
||||
// Don't modify IsSGX past this point.
|
||||
|
||||
VDC_Init(IsSGX);
|
||||
|
||||
if(IsSGX)
|
||||
{
|
||||
MDFN_printf("SuperGrafx Emulation Enabled.\n");
|
||||
PCERead[0xF8] = PCERead[0xF9] = PCERead[0xFA] = PCERead[0xFB] = BaseRAMReadSGX;
|
||||
PCEWrite[0xF8] = PCEWrite[0xF9] = PCEWrite[0xFA] = PCEWrite[0xFB] = BaseRAMWriteSGX;
|
||||
|
||||
for(int x = 0xf8; x < 0xfb; x++)
|
||||
HuCPUFastMap[x] = BaseRAM - 0xf8 * 8192;
|
||||
|
||||
PCERead[0xFF] = IOReadSGX;
|
||||
}
|
||||
else
|
||||
{
|
||||
PCERead[0xF8] = BaseRAMRead;
|
||||
PCERead[0xF9] = PCERead[0xFA] = PCERead[0xFB] = BaseRAMRead_Mirrored;
|
||||
|
||||
PCEWrite[0xF8] = BaseRAMWrite;
|
||||
PCEWrite[0xF9] = PCEWrite[0xFA] = PCEWrite[0xFB] = BaseRAMWrite_Mirrored;
|
||||
|
||||
for(int x = 0xf8; x < 0xfb; x++)
|
||||
HuCPUFastMap[x] = BaseRAM - x * 8192;
|
||||
|
||||
PCERead[0xFF] = IORead;
|
||||
}
|
||||
|
||||
MDFNMP_AddRAM(IsSGX ? 32768 : 8192, 0xf8 * 8192, BaseRAM);
|
||||
|
||||
PCEWrite[0xFF] = IOWrite;
|
||||
|
||||
HuC6280_Init();
|
||||
|
||||
psg = new PCE_PSG(&sbuf[0], &sbuf[1], PCE_PSG::REVISION_ENHANCED); //HUC6280A);
|
||||
|
||||
psg->SetVolume(1.0);
|
||||
|
||||
if(PCE_IsCD)
|
||||
{
|
||||
unsigned int cdpsgvolume = MDFN_GetSettingUI("pce_fast.cdpsgvolume");
|
||||
|
||||
if(cdpsgvolume != 100)
|
||||
{
|
||||
MDFN_printf(_("CD PSG Volume: %d%%\n"), cdpsgvolume);
|
||||
}
|
||||
|
||||
psg->SetVolume(0.678 * cdpsgvolume / 100);
|
||||
|
||||
}
|
||||
|
||||
PCEINPUT_Init();
|
||||
|
||||
PCE_Power();
|
||||
|
||||
MDFNGameInfo->LayerNames = IsSGX ? "BG0\0SPR0\0BG1\0SPR1\0" : "Background\0Sprites\0";
|
||||
MDFNGameInfo->fps = (uint32)((double)7159090.90909090 / 455 / 263 * 65536 * 256);
|
||||
|
||||
// Clean this up:
|
||||
if(!MDFN_GetSettingB("pce_fast.correct_aspect"))
|
||||
MDFNGameInfo->fb_width = 682;
|
||||
|
||||
{
|
||||
MDFNGameInfo->nominal_width = MDFN_GetSettingB("pce_fast.correct_aspect") ? 320 : 341;
|
||||
MDFNGameInfo->nominal_height = MDFN_GetSettingUI("pce_fast.slend") - MDFN_GetSettingUI("pce_fast.slstart") + 1;
|
||||
|
||||
MDFNGameInfo->lcm_width = MDFN_GetSettingB("pce_fast.correct_aspect") ? 1024 : 341;
|
||||
MDFNGameInfo->lcm_height = MDFNGameInfo->nominal_height;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static bool TestMagicCD(std::vector<CDIF *> *CDInterfaces)
|
||||
{
|
||||
static const uint8 magic_test[0x20] = { 0x82, 0xB1, 0x82, 0xCC, 0x83, 0x76, 0x83, 0x8D, 0x83, 0x4F, 0x83, 0x89, 0x83, 0x80, 0x82, 0xCC,
|
||||
0x92, 0x98, 0x8D, 0xEC, 0x8C, 0xA0, 0x82, 0xCD, 0x8A, 0x94, 0x8E, 0xAE, 0x89, 0xEF, 0x8E, 0xD0
|
||||
};
|
||||
uint8 sector_buffer[2048];
|
||||
CDIF *cdiface = (*CDInterfaces)[0];
|
||||
CDUtility::TOC toc;
|
||||
bool ret = FALSE;
|
||||
|
||||
memset(sector_buffer, 0, sizeof(sector_buffer));
|
||||
|
||||
cdiface->ReadTOC(&toc);
|
||||
|
||||
for(int32 track = toc.first_track; track <= toc.last_track; track++)
|
||||
{
|
||||
if(toc.tracks[track].control & 0x4)
|
||||
{
|
||||
cdiface->ReadSector(sector_buffer, toc.tracks[track].lba, 1);
|
||||
|
||||
if(!memcmp((char*)sector_buffer, (char *)magic_test, 0x20))
|
||||
ret = TRUE;
|
||||
|
||||
// PCE CD BIOS apparently only looks at the first data track.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If it's a PC-FX CD(Battle Heat), return false.
|
||||
// This is very kludgy.
|
||||
for(int32 track = toc.first_track; track <= toc.last_track; track++)
|
||||
{
|
||||
if(toc.tracks[track].control & 0x4)
|
||||
{
|
||||
cdiface->ReadSector(sector_buffer, toc.tracks[track].lba, 1);
|
||||
if(!strncmp("PC-FX:Hu_CD-ROM", (char*)sector_buffer, strlen("PC-FX:Hu_CD-ROM")))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now, test for the Games Express CD games. The GE BIOS seems to always look at sector 0x10, but only if the first track is a
|
||||
// data track.
|
||||
if(toc.first_track == 1 && (toc.tracks[1].control & 0x4))
|
||||
{
|
||||
if(cdiface->ReadSector(sector_buffer, 0x10, 1))
|
||||
{
|
||||
if(!memcmp((char *)sector_buffer + 0x8, "HACKER CD ROM SYSTEM", 0x14))
|
||||
{
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int LoadCD(std::vector<CDIF *> *CDInterfaces)
|
||||
{
|
||||
std::string bios_path = MDFN_MakeFName(MDFNMKF_FIRMWARE, 0, MDFN_GetSettingS("pce_fast.cdbios").c_str() );
|
||||
|
||||
IsSGX = 0;
|
||||
|
||||
LoadCommonPre();
|
||||
|
||||
if(!HuCLoadCD(bios_path.c_str()))
|
||||
return(0);
|
||||
|
||||
SCSICD_SetDisc(true, NULL, true);
|
||||
SCSICD_SetDisc(false, (*CDInterfaces)[0], true);
|
||||
|
||||
return(LoadCommon());
|
||||
}
|
||||
|
||||
|
||||
static void CloseGame(void)
|
||||
{
|
||||
{
|
||||
HuCClose();
|
||||
}
|
||||
VDC_Close();
|
||||
if(psg)
|
||||
{
|
||||
delete psg;
|
||||
psg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void Emulate(EmulateSpecStruct *espec)
|
||||
{
|
||||
INPUT_Frame();
|
||||
|
||||
MDFNMP_ApplyPeriodicCheats();
|
||||
|
||||
if(espec->VideoFormatChanged)
|
||||
VDC_SetPixelFormat(espec->surface->format); //.Rshift, espec->surface->format.Gshift, espec->surface->format.Bshift);
|
||||
|
||||
if(espec->SoundFormatChanged)
|
||||
{
|
||||
for(int y = 0; y < 2; y++)
|
||||
{
|
||||
sbuf[y].set_sample_rate(espec->SoundRate ? espec->SoundRate : 44100, 50);
|
||||
sbuf[y].clock_rate((long)(PCE_MASTER_CLOCK / 3));
|
||||
sbuf[y].bass_freq(20);
|
||||
}
|
||||
}
|
||||
VDC_RunFrame(espec->surface, &espec->DisplayRect, espec->LineWidths, espec->skip);
|
||||
|
||||
|
||||
if(PCE_IsCD)
|
||||
{
|
||||
int32 dummy_ne;
|
||||
|
||||
dummy_ne = PCECD_Run(HuCPU.timestamp * 3);
|
||||
}
|
||||
|
||||
psg->EndFrame(HuCPU.timestamp / pce_overclocked);
|
||||
|
||||
if(espec->SoundBuf)
|
||||
{
|
||||
for(int y = 0; y < 2; y++)
|
||||
{
|
||||
sbuf[y].end_frame(HuCPU.timestamp / pce_overclocked);
|
||||
espec->SoundBufSize = sbuf[y].read_samples(espec->SoundBuf + y, espec->SoundBufMaxSize, 1);
|
||||
}
|
||||
}
|
||||
|
||||
espec->MasterCycles = HuCPU.timestamp * 3;
|
||||
|
||||
INPUT_FixTS();
|
||||
|
||||
HuC6280_ResetTS();
|
||||
|
||||
if(PCE_IsCD)
|
||||
PCECD_ResetTS();
|
||||
}
|
||||
|
||||
static int StateAction(StateMem *sm, int load, int data_only)
|
||||
{
|
||||
SFORMAT StateRegs[] =
|
||||
{
|
||||
SFARRAY(BaseRAM, IsSGX? 32768 : 8192),
|
||||
SFVAR(PCEIODataBuffer),
|
||||
SFEND
|
||||
};
|
||||
|
||||
//for(int i = 8192; i < 32768; i++)
|
||||
// if(BaseRAM[i] != 0xFF)
|
||||
// printf("%d %02x\n", i, BaseRAM[i]);
|
||||
|
||||
int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "MAIN");
|
||||
|
||||
ret &= HuC6280_StateAction(sm, load, data_only);
|
||||
ret &= VDC_StateAction(sm, load, data_only);
|
||||
ret &= psg->StateAction(sm, load, data_only);
|
||||
ret &= INPUT_StateAction(sm, load, data_only);
|
||||
ret &= HuC_StateAction(sm, load, data_only);
|
||||
|
||||
if(load)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void PCE_Power(void)
|
||||
{
|
||||
memset(BaseRAM, 0x00, sizeof(BaseRAM));
|
||||
|
||||
if(!IsSGX)
|
||||
for(int i = 8192; i < 32768; i++)
|
||||
BaseRAM[i] = 0xFF;
|
||||
|
||||
PCEIODataBuffer = 0xFF;
|
||||
|
||||
HuC6280_Power();
|
||||
VDC_Power();
|
||||
psg->Power(HuCPU.timestamp / pce_overclocked);
|
||||
HuC_Power();
|
||||
|
||||
if(PCE_IsCD)
|
||||
{
|
||||
int32 dummy_ne;
|
||||
|
||||
dummy_ne = PCECD_Power(HuCPU.timestamp * 3);
|
||||
}
|
||||
}
|
||||
|
||||
static void DoSimpleCommand(int cmd)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case MDFN_MSC_RESET: PCE_Power(); break;
|
||||
case MDFN_MSC_POWER: PCE_Power(); break;
|
||||
}
|
||||
}
|
||||
|
||||
static MDFNSetting PCESettings[] =
|
||||
{
|
||||
/*
|
||||
{ "pce_fast.input.port1", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Input device for input port 1."), NULL, MDFNST_STRING, "gamepad", NULL, NULL },
|
||||
{ "pce_fast.input.port2", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Input device for input port 2."), NULL, MDFNST_STRING, "gamepad", NULL, NULL },
|
||||
{ "pce_fast.input.port3", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Input device for input port 3."), NULL, MDFNST_STRING, "gamepad", NULL, NULL },
|
||||
{ "pce_fast.input.port4", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Input device for input port 4."), NULL, MDFNST_STRING, "gamepad", NULL, NULL },
|
||||
{ "pce_fast.input.port5", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Input device for input port 5."), NULL, MDFNST_STRING, "gamepad", NULL, NULL },
|
||||
*/
|
||||
|
||||
{ "pce_fast.correct_aspect", MDFNSF_CAT_VIDEO, gettext_noop("Correct the aspect ratio."), NULL, MDFNST_BOOL, "1" },
|
||||
{ "pce_fast.slstart", MDFNSF_NOFLAGS, gettext_noop("First rendered scanline."), NULL, MDFNST_UINT, "4", "0", "239" },
|
||||
{ "pce_fast.slend", MDFNSF_NOFLAGS, gettext_noop("Last rendered scanline."), NULL, MDFNST_UINT, "235", "0", "239" },
|
||||
{ "pce_fast.mouse_sensitivity", MDFNSF_NOFLAGS, gettext_noop("Mouse sensitivity."), NULL, MDFNST_FLOAT, "0.50", NULL, NULL, NULL, PCEINPUT_SettingChanged },
|
||||
{ "pce_fast.disable_softreset", MDFNSF_NOFLAGS, gettext_noop("If set, when RUN+SEL are pressed simultaneously, disable both buttons temporarily."), NULL, MDFNST_BOOL, "0", NULL, NULL, NULL, PCEINPUT_SettingChanged },
|
||||
{ "pce_fast.forcesgx", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Force SuperGrafx emulation."), NULL, MDFNST_BOOL, "0" },
|
||||
{ "pce_fast.arcadecard", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Enable Arcade Card emulation."), NULL, MDFNST_BOOL, "1" },
|
||||
{ "pce_fast.ocmultiplier", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("CPU overclock multiplier."), NULL, MDFNST_UINT, "1", "1", "100"},
|
||||
{ "pce_fast.cdspeed", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("CD-ROM data transfer speed multiplier."), NULL, MDFNST_UINT, "1", "1", "100" },
|
||||
{ "pce_fast.nospritelimit", MDFNSF_NOFLAGS, gettext_noop("Remove 16-sprites-per-scanline hardware limit."), NULL, MDFNST_BOOL, "0" },
|
||||
|
||||
{ "pce_fast.cdbios", MDFNSF_EMU_STATE, gettext_noop("Path to the CD BIOS"), NULL, MDFNST_STRING, "syscard3.pce" },
|
||||
{ "pce_fast.adpcmlp", MDFNSF_NOFLAGS, gettext_noop("Enable lowpass filter dependent on playback-frequency."), NULL, MDFNST_BOOL, "0" },
|
||||
{ "pce_fast.cdpsgvolume", MDFNSF_NOFLAGS, gettext_noop("PSG volume when playing a CD game."), NULL, MDFNST_UINT, "100", "0", "200" },
|
||||
{ "pce_fast.cddavolume", MDFNSF_NOFLAGS, gettext_noop("CD-DA volume."), NULL, MDFNST_UINT, "100", "0", "200" },
|
||||
{ "pce_fast.adpcmvolume", MDFNSF_NOFLAGS, gettext_noop("ADPCM volume."), NULL, MDFNST_UINT, "100", "0", "200" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static uint8 MemRead(uint32 addr)
|
||||
{
|
||||
return(PCERead[(addr / 8192) & 0xFF](addr));
|
||||
}
|
||||
|
||||
static const FileExtensionSpecStruct KnownExtensions[] =
|
||||
{
|
||||
{ ".pce", gettext_noop("PC Engine ROM Image") },
|
||||
{ ".sgx", gettext_noop("SuperGrafx ROM Image") },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
MDFNGI EmulatedPCE_Fast =
|
||||
{
|
||||
"pce_fast",
|
||||
"PC Engine (CD)/TurboGrafx 16 (CD)/SuperGrafx",
|
||||
KnownExtensions,
|
||||
MODPRIO_INTERNAL_LOW,
|
||||
NULL,
|
||||
&PCEInputInfo,
|
||||
Load,
|
||||
TestMagic,
|
||||
LoadCD,
|
||||
TestMagicCD,
|
||||
CloseGame,
|
||||
VDC_SetLayerEnableMask,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
MemRead,
|
||||
false,
|
||||
StateAction,
|
||||
Emulate,
|
||||
PCEINPUT_SetInput,
|
||||
DoSimpleCommand,
|
||||
PCESettings,
|
||||
MDFN_MASTERCLOCK_FIXED(PCE_MASTER_CLOCK),
|
||||
0,
|
||||
|
||||
true, // Multires possible?
|
||||
|
||||
0, // lcm_width
|
||||
0, // lcm_height
|
||||
NULL, // Dummy
|
||||
|
||||
320, // Nominal width
|
||||
232, // Nominal height
|
||||
|
||||
512, // Framebuffer width
|
||||
242, // Framebuffer height
|
||||
|
||||
2, // Number of output sound channels
|
||||
};
|
||||
|
45
mednafen/pce_fast/pce.h
Normal file
45
mednafen/pce_fast/pce.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef _PCE_H
|
||||
#define _PCE_H
|
||||
|
||||
#include "../mednafen-types.h"
|
||||
#include "../mednafen.h"
|
||||
#include "../state.h"
|
||||
#include "../general.h"
|
||||
#include "../mednafen-memory.h"
|
||||
|
||||
#define PCE_MASTER_CLOCK 21477272.727273
|
||||
|
||||
#define DECLFR(x) uint8 MDFN_FASTCALL x (uint32 A)
|
||||
#define DECLFW(x) void MDFN_FASTCALL x (uint32 A, uint8 V)
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
extern uint8 ROMSpace[0x88 * 8192 + 8192];
|
||||
|
||||
typedef void (MDFN_FASTCALL *writefunc)(uint32 A, uint8 V);
|
||||
typedef uint8 (MDFN_FASTCALL *readfunc)(uint32 A);
|
||||
|
||||
extern uint8 PCEIODataBuffer;
|
||||
|
||||
bool PCE_InitCD(void);
|
||||
|
||||
};
|
||||
|
||||
#include "huc6280.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
extern bool PCE_ACEnabled; // Arcade Card emulation enabled?
|
||||
void PCE_Power(void);
|
||||
|
||||
extern readfunc PCERead[0x100];
|
||||
extern writefunc PCEWrite[0x100];
|
||||
extern int pce_overclocked;
|
||||
|
||||
extern uint8 BaseRAM[32768 + 8192];
|
||||
|
||||
};
|
||||
|
||||
using namespace PCE_Fast;
|
||||
|
||||
#endif
|
784
mednafen/pce_fast/pce_huc6280.cpp
Normal file
784
mednafen/pce_fast/pce_huc6280.cpp
Normal file
@ -0,0 +1,784 @@
|
||||
/* 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 "pce.h"
|
||||
#include "vdc.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
HuC6280 HuCPU;
|
||||
uint8 *HuCPUFastMap[0x100];
|
||||
|
||||
#define HU_PC PC_local //HuCPU.PC
|
||||
#define HU_PC_base HuCPU.PC_base
|
||||
#define HU_A HuCPU.A
|
||||
#define HU_X X_local //HuCPU.X
|
||||
#define HU_Y Y_local //HuCPU.Y
|
||||
#define HU_S HuCPU.S
|
||||
#define HU_P P_local //HuCPU.P
|
||||
#define HU_PI HuCPU.mooPI
|
||||
#define HU_IRQlow HuCPU.IRQlow
|
||||
#define HU_Page1 Page1_local
|
||||
//HuCPU.Page1
|
||||
//Page1_local //HuCPU.Page1
|
||||
|
||||
#ifdef HUC6280_LAZY_FLAGS
|
||||
#define HU_ZNFlags HuCPU.ZNFlags
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HUC6280_CRAZY_VERSION
|
||||
#define LOAD_LOCALS_PC() register uint8 *PC_local = HuCPU.PC;
|
||||
#else
|
||||
#define LOAD_LOCALS_PC() register uint32 PC_local /*asm ("edi")*/ = HuCPU.PC; // asm ("edi") = HuCPU.PC;
|
||||
#endif
|
||||
|
||||
#define LOAD_LOCALS() \
|
||||
LOAD_LOCALS_PC(); \
|
||||
uint8 X_local = HuCPU.X; \
|
||||
uint8 Y_local = HuCPU.Y; \
|
||||
uint8 P_local = HuCPU.P; \
|
||||
uint8 *Page1_local = HuCPU.Page1;
|
||||
|
||||
#define SAVE_LOCALS() HuCPU.PC = PC_local; \
|
||||
HuCPU.X = X_local; \
|
||||
HuCPU.Y = Y_local; \
|
||||
HuCPU.P = P_local; \
|
||||
HuCPU.Page1 = Page1_local;
|
||||
|
||||
#ifdef HUC6280_LAZY_FLAGS
|
||||
#define COMPRESS_FLAGS() HU_P &= ~(N_FLAG | Z_FLAG); HU_P |= ((HU_ZNFlags >> 24) & 0x80) | ((HU_ZNFlags & 0xFF) ? 0 : Z_FLAG);
|
||||
//((((HU_ZNFlags & 0xFF) - 1) >> 8) & Z_FLAG);
|
||||
#define EXPAND_FLAGS() HU_ZNFlags = (HU_P << 24) | ((HU_P & Z_FLAG) ^ Z_FLAG);
|
||||
#else
|
||||
#define COMPRESS_FLAGS()
|
||||
#define EXPAND_FLAGS()
|
||||
#endif
|
||||
|
||||
#ifdef HUC6280_CRAZY_VERSION
|
||||
#define GetRealPC() ((unsigned int)(HU_PC - HU_PC_base))
|
||||
#define GetRealPC_EXTERNAL() ((unsigned int)(HuCPU.PC - HuCPU.PC_base))
|
||||
#else
|
||||
#define GetRealPC() (HU_PC)
|
||||
#define GetRealPC_EXTERNAL() (HuCPU.PC)
|
||||
#endif
|
||||
|
||||
#ifdef HUC6280_CRAZY_VERSION
|
||||
#define SetPC(value) { unsigned int tempmoo = value; HU_PC = &HuCPU.FastPageR[tempmoo >> 13][tempmoo]; \
|
||||
HU_PC_base = HU_PC - tempmoo; }
|
||||
#define SetPC_EXTERNAL(value) { unsigned int tempmoo = value; \
|
||||
HuCPU.PC = &HuCPU.FastPageR[tempmoo >> 13][tempmoo]; HuCPU.PC_base = HuCPU.PC - tempmoo; }
|
||||
#else
|
||||
#define SetPC(value) { HU_PC = (value); }
|
||||
#define SetPC_EXTERNAL(value) { HuCPU.PC = (value); }
|
||||
#endif
|
||||
|
||||
// Page change PC, GET IT?!
|
||||
#ifdef HUC6280_CRAZY_VERSION
|
||||
#define FixPC_PC() SetPC(GetRealPC());
|
||||
#else
|
||||
#define FixPC_PC()
|
||||
#endif
|
||||
|
||||
//#define IncPC() { HU_PC++; if(!(GetRealPC() & 0x1FFF)) printf("Bank crossing: %04x\n", GetRealPC()); }
|
||||
//#define IncPC() HU_PC++;
|
||||
#if 0
|
||||
#define IncPC() { HU_PC++; if(!(GetRealPC() & 0x1FFF) && \
|
||||
HuCPU.MPR[(GetRealPC() - 1) >> 13] != (HuCPU.MPR[(GetRealPC()) >> 13] - 1)) \
|
||||
printf("Bank crossing: %04x, %02x, %02x\n", GetRealPC(), HuCPU.MPR[(GetRealPC() - 1) >> 13], \
|
||||
HuCPU.MPR[GetRealPC() >> 13]); }
|
||||
#else
|
||||
#define IncPC() HU_PC++;
|
||||
#endif
|
||||
|
||||
#ifdef HUC6280_CRAZY_VERSION
|
||||
#define RdAtPC() (*HU_PC)
|
||||
//#define RdAtAndIncPC_16() (HU_PC += 2, *(uint16 *)(HU_PC - 2))
|
||||
#else
|
||||
#define RdAtPC() RdOp(HU_PC)
|
||||
//#define RdAtAndIncPC_16() (RdOp(HU_PC++) | ((RdOp(HU_PC++) << 8)))
|
||||
#endif
|
||||
|
||||
// If we change this definition, we'll need to also fix HuC6280_StealCycle() in huc6280.h
|
||||
#define ADDCYC(x) { HuCPU.timestamp += x; }
|
||||
|
||||
static uint8 dummy_bank[8192 + 8192]; // + 8192 for PC-as-ptr safety padding
|
||||
|
||||
#define SET_MPR(arg_i, arg_v) \
|
||||
{ \
|
||||
const unsigned int wmpr = arg_i, wbank = arg_v; \
|
||||
if(wmpr == 1) \
|
||||
{ \
|
||||
if(wbank != 0xF8 || !HuCPUFastMap[wbank]) \
|
||||
printf("Crazy page 1: %02x\n", wbank); \
|
||||
HU_Page1 = HuCPUFastMap[wbank] ? HuCPUFastMap[wbank] + wbank * 8192 : dummy_bank; \
|
||||
} \
|
||||
HuCPU.MPR[wmpr] = wbank; \
|
||||
HuCPU.FastPageR[wmpr] = HuCPUFastMap[wbank] ? (HuCPUFastMap[wbank] + wbank * 8192) - wmpr * 8192 : (dummy_bank - wmpr * 8192); \
|
||||
}
|
||||
|
||||
void HuC6280_SetMPR(int i, int v)
|
||||
{
|
||||
uint8 *Page1_local = HuCPU.Page1;
|
||||
|
||||
SET_MPR(i, v);
|
||||
|
||||
HuCPU.Page1 = Page1_local;
|
||||
}
|
||||
|
||||
|
||||
static void HuC6280_FlushMPRCache(void)
|
||||
{
|
||||
for(int x = 0; x < 9; x++)
|
||||
HuC6280_SetMPR(x, HuCPU.MPR[x & 0x7]);
|
||||
}
|
||||
|
||||
static INLINE uint8 RdMem(unsigned int A)
|
||||
{
|
||||
uint8 wmpr = HuCPU.MPR[A >> 13];
|
||||
return(PCERead[wmpr]((wmpr << 13) | (A & 0x1FFF)));
|
||||
}
|
||||
|
||||
static INLINE uint16 RdMem16(unsigned int A)
|
||||
{
|
||||
return(RdMem(A) | (RdMem(A + 1) << 8));
|
||||
}
|
||||
|
||||
static INLINE void WrMem(unsigned int A, uint8 V)
|
||||
{
|
||||
uint8 wmpr = HuCPU.MPR[A >> 13];
|
||||
PCEWrite[wmpr]((wmpr << 13) | (A & 0x1FFF), V);
|
||||
}
|
||||
|
||||
static INLINE uint8 RdOp(unsigned int A)
|
||||
{
|
||||
return(HuCPU.FastPageR[A >> 13][A]);
|
||||
}
|
||||
|
||||
#define PUSH(V) \
|
||||
{ \
|
||||
HU_Page1[0x100 + HU_S] = V; \
|
||||
HU_S--; \
|
||||
}
|
||||
|
||||
#define PUSH_PC() \
|
||||
{ \
|
||||
unsigned int real_pc = GetRealPC(); \
|
||||
PUSH(real_pc >> 8); \
|
||||
PUSH(real_pc); \
|
||||
}
|
||||
|
||||
#define POP() HU_Page1[0x100 + ++HU_S]
|
||||
|
||||
#define POP_PC() \
|
||||
{ \
|
||||
unsigned int npc; \
|
||||
npc = POP(); \
|
||||
npc |= POP() << 8; \
|
||||
SetPC(npc); \
|
||||
}
|
||||
|
||||
// Hopefully we never RTS to 0x0000. ;)
|
||||
#define POP_PC_AP() \
|
||||
{ \
|
||||
uint32 npc; \
|
||||
npc = POP(); \
|
||||
npc |= POP() << 8; \
|
||||
npc++; \
|
||||
SetPC(npc); \
|
||||
}
|
||||
|
||||
/* Some of these operations will only make sense if you know what the flag
|
||||
constants are. */
|
||||
|
||||
#ifdef HUC6280_LAZY_FLAGS
|
||||
#define X_ZN(zort) { HU_ZNFlags = (int32)(int8)(uint8)(zort); }
|
||||
#define X_ZN_BIT(opres, argie) { HU_ZNFlags = (opres) | ((argie) << 24); }
|
||||
#else
|
||||
static uint8 ZNTable[256];
|
||||
#define X_ZN(zort) HU_P&=~(Z_FLAG|N_FLAG);HU_P|=ZNTable[zort]
|
||||
#define X_ZN_BIT(opres, argie) { HU_P &= ~(Z_FLAG | N_FLAG); HU_P |= ZNTable[opres] & Z_FLAG; HU_P |= argie & N_FLAG; }
|
||||
#endif
|
||||
|
||||
#define JR(cond) \
|
||||
{ \
|
||||
if(cond) \
|
||||
{ \
|
||||
int32 disp; \
|
||||
disp = 1 + (int8)RdAtPC(); \
|
||||
ADDCYC(2); \
|
||||
HU_PC+=disp; \
|
||||
} \
|
||||
else IncPC(); \
|
||||
}
|
||||
|
||||
#define BRA \
|
||||
{ \
|
||||
int32 disp; \
|
||||
disp = 1 + (int8)RdAtPC(); \
|
||||
HU_PC+=disp; \
|
||||
}
|
||||
|
||||
#define BBRi(bitto) JR(!(x & (1 << bitto)))
|
||||
#define BBSi(bitto) JR(x & (1 << bitto))
|
||||
|
||||
#define ST0 VDC_Write_ST(0, x)
|
||||
#define ST1 VDC_Write_ST(2, x)
|
||||
#define ST2 VDC_Write_ST(3, x)
|
||||
|
||||
#define LDA HU_A=x;X_ZN(HU_A)
|
||||
#define LDX HU_X=x;X_ZN(HU_X)
|
||||
#define LDY HU_Y=x;X_ZN(HU_Y)
|
||||
|
||||
/* All of the freaky arithmetic operations. */
|
||||
#define AND HU_A&=x;X_ZN(HU_A);
|
||||
|
||||
// FIXME:
|
||||
#define BIT HU_P&=~V_FLAG; X_ZN_BIT(x & HU_A, x); HU_P |= x & V_FLAG;
|
||||
#define EOR HU_A^=x;X_ZN(HU_A);
|
||||
#define ORA HU_A|=x;X_ZN(HU_A);
|
||||
|
||||
#define ADC { \
|
||||
if(HU_P & D_FLAG) \
|
||||
{ \
|
||||
uint32 low = (HU_A & 0x0F) + (x & 0x0F) + (HU_P & 1); \
|
||||
uint32 high = (HU_A & 0xF0) + (x & 0xF0); \
|
||||
HU_P &= ~C_FLAG; \
|
||||
if(low > 0x09) { high += 0x10; low += 0x06; } \
|
||||
if(high > 0x90) { high += 0x60; } \
|
||||
HU_P |= (high >> 8) & C_FLAG; \
|
||||
HU_A = (low & 0x0F) | (high & 0xF0); \
|
||||
X_ZN(HU_A); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
uint32 l=HU_A+x+(HU_P&1); \
|
||||
HU_P&=~(C_FLAG|V_FLAG); \
|
||||
HU_P|=((((HU_A^x)&0x80)^0x80) & ((HU_A^l)&0x80))>>1; \
|
||||
HU_P|=(l>>8)&C_FLAG; \
|
||||
HU_A=l; \
|
||||
X_ZN(HU_A); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SBC if(HU_P & D_FLAG) \
|
||||
{ \
|
||||
uint32 c = (HU_P & 1) ^ 1; \
|
||||
uint32 l = HU_A - x - c; \
|
||||
uint32 low = (HU_A & 0x0f) - (x & 0x0f) - c; \
|
||||
uint32 high = (HU_A & 0xf0) - (x & 0xf0); \
|
||||
HU_P &= ~(C_FLAG); \
|
||||
if(low & 0xf0) low -= 0x06; \
|
||||
if(low & 0x80) high -= 0x10; \
|
||||
if(high & 0x0f00) high -= 0x60; \
|
||||
HU_P |= ((l >> 8) & C_FLAG) ^ C_FLAG; \
|
||||
HU_A = (low & 0x0F) | (high & 0xf0); \
|
||||
X_ZN(HU_A); \
|
||||
} else { \
|
||||
uint32 l=HU_A-x-((HU_P&1)^1); \
|
||||
HU_P&=~(C_FLAG|V_FLAG); \
|
||||
HU_P|=((HU_A^l)&(HU_A^x)&0x80)>>1; \
|
||||
HU_P|=((l>>8)&C_FLAG)^C_FLAG; \
|
||||
HU_A=l; \
|
||||
X_ZN(HU_A); \
|
||||
}
|
||||
|
||||
#define CMPL(a1,a2) { \
|
||||
uint32 t=a1-a2; \
|
||||
X_ZN(t&0xFF); \
|
||||
HU_P&=~C_FLAG; \
|
||||
HU_P|=((t>>8)&C_FLAG)^C_FLAG; \
|
||||
}
|
||||
|
||||
#define TAM for(int i = 0; i < 8; i ++) { \
|
||||
if(x & (1 << i)) \
|
||||
{ \
|
||||
SET_MPR(i, HU_A); \
|
||||
} \
|
||||
} SET_MPR(8, HuCPU.MPR[0]);
|
||||
|
||||
#define TMA for(int i = 0; i < 8; i ++) { \
|
||||
if(x & (1 << i)) \
|
||||
HU_A = HuCPU.MPR[i]; \
|
||||
}
|
||||
|
||||
#define CSL
|
||||
#define CSH
|
||||
|
||||
#define RMB(bitto) x &= ~(1 << (bitto & 7))
|
||||
#define SMB(bitto) x |= 1 << (bitto & 7)
|
||||
|
||||
// FIXME
|
||||
#define TSB { HU_P &= ~V_FLAG; X_ZN_BIT(x | HU_A, x); HU_P |= x & V_FLAG; x |= HU_A; }
|
||||
#define TRB { HU_P &= ~V_FLAG; X_ZN_BIT(x & ~HU_A, x); HU_P |= x & V_FLAG; x &= ~HU_A; }
|
||||
#define TST { HU_P &= ~V_FLAG; X_ZN_BIT(x & zoomhack, x); HU_P |= x & V_FLAG; }
|
||||
|
||||
#define CMP CMPL(HU_A,x)
|
||||
#define CPX CMPL(HU_X,x)
|
||||
#define CPY CMPL(HU_Y,x)
|
||||
|
||||
/* The following operations modify the byte being worked on. */
|
||||
#define DEC x--;X_ZN(x)
|
||||
#define INC x++;X_ZN(x)
|
||||
|
||||
#define ASL HU_P&=~C_FLAG;HU_P|=x>>7;x<<=1;X_ZN(x)
|
||||
#define LSR HU_P&=~C_FLAG;HU_P|=x&1;x>>=1;X_ZN(x)
|
||||
|
||||
#define ROL { \
|
||||
uint8 l=x>>7; \
|
||||
x<<=1; \
|
||||
x|=HU_P&C_FLAG; \
|
||||
HU_P&=~C_FLAG; \
|
||||
HU_P|=l; \
|
||||
X_ZN(x); \
|
||||
}
|
||||
#define ROR { \
|
||||
uint8 l=x&1; \
|
||||
x>>=1; \
|
||||
x|=(HU_P&C_FLAG)<<7; \
|
||||
HU_P&=~C_FLAG; \
|
||||
HU_P|=l; \
|
||||
X_ZN(x); \
|
||||
}
|
||||
|
||||
/* Absolute */
|
||||
#define GetAB(target) \
|
||||
{ \
|
||||
target=RdAtPC(); \
|
||||
IncPC(); \
|
||||
target|=RdAtPC()<<8; \
|
||||
IncPC(); \
|
||||
}
|
||||
|
||||
/* Absolute Indexed(for reads) */
|
||||
#define GetABI(target, i) \
|
||||
{ \
|
||||
unsigned int tmp; \
|
||||
GetAB(tmp); \
|
||||
target=tmp; \
|
||||
target+=i; \
|
||||
}
|
||||
|
||||
/* Zero Page */
|
||||
#define GetZP(target) \
|
||||
{ \
|
||||
target=RdAtPC(); \
|
||||
IncPC(); \
|
||||
}
|
||||
|
||||
/* Zero Page Indexed */
|
||||
#define GetZPI(target,i) \
|
||||
{ \
|
||||
target=i+RdAtPC(); \
|
||||
IncPC(); \
|
||||
}
|
||||
|
||||
/* Indirect */
|
||||
#define GetIND(target) \
|
||||
{ \
|
||||
uint8 tmp; \
|
||||
tmp=RdAtPC(); \
|
||||
IncPC(); \
|
||||
target=HU_Page1[tmp]; \
|
||||
tmp++; \
|
||||
target|=HU_Page1[tmp]<<8; \
|
||||
}
|
||||
|
||||
|
||||
/* Indexed Indirect */
|
||||
#define GetIX(target) \
|
||||
{ \
|
||||
uint8 tmp; \
|
||||
tmp=RdAtPC(); \
|
||||
IncPC(); \
|
||||
tmp+=HU_X; \
|
||||
target=HU_Page1[tmp]; \
|
||||
tmp++; \
|
||||
target|=HU_Page1[tmp] <<8; \
|
||||
}
|
||||
|
||||
/* Indirect Indexed(for reads) */
|
||||
#define GetIY(target) \
|
||||
{ \
|
||||
unsigned int rt; \
|
||||
uint8 tmp; \
|
||||
tmp=RdAtPC(); \
|
||||
rt=HU_Page1[tmp]; \
|
||||
tmp++; \
|
||||
rt|=HU_Page1[tmp]<<8; \
|
||||
target = (rt + HU_Y); \
|
||||
IncPC(); \
|
||||
}
|
||||
|
||||
/* Now come the macros to wrap up all of the above stuff addressing mode functions
|
||||
and operation macros. Note that operation macros will always operate(redundant
|
||||
redundant) on the variable "x".
|
||||
*/
|
||||
|
||||
#define RMW_A(op) {uint8 x=HU_A; op; HU_A=x; break; } /* Meh... */
|
||||
#define RMW_AB(op) {unsigned int EA; uint8 x; GetAB(EA); x=RdMem(EA); op; WrMem(EA,x); break; }
|
||||
#define RMW_ABI(reg,op) {unsigned int EA; uint8 x; GetABI(EA,reg); x=RdMem(EA); op; WrMem(EA,x); break; }
|
||||
#define RMW_ABX(op) RMW_ABI(HU_X,op)
|
||||
#define RMW_ABY(op) RMW_ABI(HU_Y,op)
|
||||
#define RMW_IND(op) { unsigned int EA; uint8 x; GetIND(EA); x = RdMem(EA); op; WrMem(EA, x); break; }
|
||||
#define RMW_IX(op) { unsigned int EA; uint8 x; GetIX(EA); x=RdMem(EA); op; WrMem(EA,x); break; }
|
||||
#define RMW_IY(op) { unsigned int EA; uint8 x; GetIY(EA); x=RdMem(EA); op; WrMem(EA,x); break; }
|
||||
#define RMW_ZP(op) { uint8 EA; uint8 x; GetZP(EA); x=HU_Page1[EA]; op; HU_Page1[EA] = x; break; }
|
||||
#define RMW_ZPX(op) { uint8 EA; uint8 x; GetZPI(EA,HU_X); x=HU_Page1[EA]; op; HU_Page1[EA] = x; break;}
|
||||
|
||||
#define LD_IM(op) { uint8 x; x=RdAtPC(); IncPC(); op; break; }
|
||||
#define LD_ZP(op) { uint8 EA; uint8 x; GetZP(EA); x=HU_Page1[EA]; op; break; }
|
||||
#define LD_ZPX(op) { uint8 EA; uint8 x; GetZPI(EA,HU_X); x=HU_Page1[EA]; op; break; }
|
||||
#define LD_ZPY(op) { uint8 EA; uint8 x; GetZPI(EA,HU_Y); x=HU_Page1[EA]; op; break; }
|
||||
#define LD_AB(op) { unsigned int EA; uint8 x; GetAB(EA); x=RdMem(EA); op; break; }
|
||||
#define LD_ABI(reg,op) { unsigned int EA; uint8 x; GetABI(EA,reg); x=RdMem(EA); op; break; }
|
||||
#define LD_ABX(op) LD_ABI(HU_X,op)
|
||||
#define LD_ABY(op) LD_ABI(HU_Y,op)
|
||||
|
||||
#define LD_IND(op) { unsigned int EA; uint8 x; GetIND(EA); x=RdMem(EA); op; break; }
|
||||
#define LD_IX(op) { unsigned int EA; uint8 x; GetIX(EA); x=RdMem(EA); op; break; }
|
||||
#define LD_IY(op) { unsigned int EA; uint8 x; GetIY(EA); x=RdMem(EA); op; break; }
|
||||
|
||||
#define BMT_PREHONK(pork) HuCPU.in_block_move = IBM_##pork;
|
||||
#define BMT_HONKHONK(pork) if(HuCPU.timestamp >= next_user_event) goto GetOutBMT; continue_the_##pork:
|
||||
|
||||
#define BMT_TDD BMT_PREHONK(TDD); do { ADDCYC(6); WrMem(HuCPU.bmt_dest, RdMem(HuCPU.bmt_src)); HuCPU.bmt_src--; HuCPU.bmt_dest--; BMT_HONKHONK(TDD); HuCPU.bmt_length--; } while(HuCPU.bmt_length);
|
||||
#define BMT_TAI BMT_PREHONK(TAI); {HuCPU.bmt_alternate = 0; do { ADDCYC(6); WrMem(HuCPU.bmt_dest, RdMem(HuCPU.bmt_src + HuCPU.bmt_alternate)); HuCPU.bmt_dest++; HuCPU.bmt_alternate ^= 1; BMT_HONKHONK(TAI); HuCPU.bmt_length--; } while(HuCPU.bmt_length); }
|
||||
#define BMT_TIA BMT_PREHONK(TIA); {HuCPU.bmt_alternate = 0; do { ADDCYC(6); WrMem(HuCPU.bmt_dest + HuCPU.bmt_alternate, RdMem(HuCPU.bmt_src)); HuCPU.bmt_src++; HuCPU.bmt_alternate ^= 1; BMT_HONKHONK(TIA); HuCPU.bmt_length--; } while(HuCPU.bmt_length); }
|
||||
#define BMT_TII BMT_PREHONK(TII); do { ADDCYC(6); WrMem(HuCPU.bmt_dest, RdMem(HuCPU.bmt_src)); HuCPU.bmt_src++; HuCPU.bmt_dest++; BMT_HONKHONK(TII); HuCPU.bmt_length--; } while(HuCPU.bmt_length);
|
||||
#define BMT_TIN BMT_PREHONK(TIN); do { ADDCYC(6); WrMem(HuCPU.bmt_dest, RdMem(HuCPU.bmt_src)); HuCPU.bmt_src++; BMT_HONKHONK(TIN); HuCPU.bmt_length--; } while(HuCPU.bmt_length);
|
||||
|
||||
// Block memory transfer load
|
||||
#define LD_BMT(op) { PUSH(HU_Y); PUSH(HU_A); PUSH(HU_X); GetAB(HuCPU.bmt_src); GetAB(HuCPU.bmt_dest); GetAB(HuCPU.bmt_length); op; HuCPU.in_block_move = 0; HU_X = POP(); HU_A = POP(); HU_Y = POP(); break; }
|
||||
|
||||
#define ST_ZP(r) {uint8 EA; GetZP(EA); HU_Page1[EA] = r; break;}
|
||||
#define ST_ZPX(r) {uint8 EA; GetZPI(EA,HU_X); HU_Page1[EA] = r; break;}
|
||||
#define ST_ZPY(r) {uint8 EA; GetZPI(EA,HU_Y); HU_Page1[EA] = r; break;}
|
||||
#define ST_AB(r) {unsigned int EA; GetAB(EA); WrMem(EA, r); break;}
|
||||
#define ST_ABI(reg,r) {unsigned int EA; GetABI(EA,reg); WrMem(EA,r); break; }
|
||||
#define ST_ABX(r) ST_ABI(HU_X,r)
|
||||
#define ST_ABY(r) ST_ABI(HU_Y,r)
|
||||
|
||||
#define ST_IND(r) {unsigned int EA; GetIND(EA); WrMem(EA,r); break; }
|
||||
#define ST_IX(r) {unsigned int EA; GetIX(EA); WrMem(EA,r); break; }
|
||||
#define ST_IY(r) {unsigned int EA; GetIY(EA); WrMem(EA,r); break; }
|
||||
|
||||
static const uint8 CycTable[256] =
|
||||
{
|
||||
/*0x00*/ 8, 7, 3, 4, 6, 4, 6, 7, 3, 2, 2, 2, 7, 5, 7, 6,
|
||||
/*0x10*/ 2, 7, 7, 4, 6, 4, 6, 7, 2, 5, 2, 2, 7, 5, 7, 6,
|
||||
/*0x20*/ 7, 7, 3, 4, 4, 4, 6, 7, 4, 2, 2, 2, 5, 5, 7, 6,
|
||||
/*0x30*/ 2, 7, 7, 2, 4, 4, 6, 7, 2, 5, 2, 2, 5, 5, 7, 6,
|
||||
/*0x40*/ 7, 7, 3, 4, 8, 4, 6, 7, 3, 2, 2, 2, 4, 5, 7, 6,
|
||||
/*0x50*/ 2, 7, 7, 5, 3, 4, 6, 7, 2, 5, 3, 2, 2, 5, 7, 6,
|
||||
/*0x60*/ 7, 7, 2, 2, 4, 4, 6, 7, 4, 2, 2, 2, 7, 5, 7, 6,
|
||||
/*0x70*/ 2, 7, 7, 17, 4, 4, 6, 7, 2, 5, 4, 2, 7, 5, 7, 6,
|
||||
|
||||
/*0x80*/ 4, 7, 2, 7, 4, 4, 4, 7, 2, 2, 2, 2, 5, 5, 5, 6,
|
||||
/*0x90*/ 2, 7, 7, 8, 4, 4, 4, 7, 2, 5, 2, 2, 5, 5, 5, 6,
|
||||
/*0xA0*/ 2, 7, 2, 7, 4, 4, 4, 7, 2, 2, 2, 2, 5, 5, 5, 6,
|
||||
/*0xB0*/ 2, 7, 7, 8, 4, 4, 4, 7, 2, 5, 2, 2, 5, 5, 5, 6,
|
||||
/*0xC0*/ 2, 7, 2, 17, 4, 4, 6, 7, 2, 2, 2, 2, 5, 5, 7, 6,
|
||||
/*0xD0*/ 2, 7, 7, 17, 3, 4, 6, 7, 2, 5, 3, 2, 2, 5, 7, 6,
|
||||
/*0xE0*/ 2, 7, 2, 17, 4, 4, 6, 7, 2, 2, 2, 2, 5, 5, 7, 6,
|
||||
/*0xF0*/ 2, 7, 7, 17, 2, 4, 6, 7, 2, 5, 4, 2, 2, 5, 7, 6,
|
||||
};
|
||||
#if 0
|
||||
static bool WillIRQOccur(void) NO_INLINE;
|
||||
static bool WillIRQOccur(void)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if(HU_IRQlow)
|
||||
{
|
||||
if(!(HU_PI&I_FLAG))
|
||||
{
|
||||
if(HU_IRQlow & MDFN_IQTIMER & HuCPU.IRQMaskDelay)
|
||||
ret = true;
|
||||
else if((HU_IRQlow & MDFN_IQIRQ1 & HuCPU.IRQMaskDelay) || ((HU_IRQlow >> 8) & MDFN_IQIRQ1 & HuCPU.IRQMaskDelay))
|
||||
ret = true;
|
||||
else if(HU_IRQlow & MDFN_IQIRQ2 & HuCPU.IRQMaskDelay)
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void HuC6280_IRQBegin(int w)
|
||||
{
|
||||
HU_IRQlow|=w;
|
||||
}
|
||||
|
||||
void HuC6280_IRQEnd(int w)
|
||||
{
|
||||
HU_IRQlow&=~w;
|
||||
}
|
||||
|
||||
void HuC6280_Reset(void)
|
||||
{
|
||||
HuCPU.timer_next_timestamp = HuCPU.timestamp + 1024;
|
||||
|
||||
HuCPU.timer_load = 0;
|
||||
HuCPU.timer_value = 0;
|
||||
HuCPU.timer_status = 0;
|
||||
HuCPU.in_block_move = 0;
|
||||
|
||||
unsigned int npc;
|
||||
|
||||
HuCPU.IRQMask = HuCPU.IRQMaskDelay = 7;
|
||||
|
||||
HuC6280_SetMPR(0, 0xFF);
|
||||
HuC6280_SetMPR(1, 0xF8);
|
||||
|
||||
for(int i = 2; i < 8; i++)
|
||||
HuC6280_SetMPR(i, 0);
|
||||
|
||||
npc = RdMem16(0xFFFE);
|
||||
|
||||
#define PC_local HuCPU.PC
|
||||
SetPC(npc);
|
||||
#undef PC_local
|
||||
|
||||
HuCPU.mooPI = I_FLAG;
|
||||
HuCPU.P = I_FLAG;
|
||||
|
||||
HU_IRQlow = 0;
|
||||
}
|
||||
|
||||
void HuC6280_Init(void)
|
||||
{
|
||||
memset((void *)&HuCPU,0,sizeof(HuCPU));
|
||||
memset(dummy_bank, 0, sizeof(dummy_bank));
|
||||
|
||||
#ifdef HUC6280_LAZY_FLAGS
|
||||
|
||||
#else
|
||||
for(int x=0; x < 256; x++)
|
||||
if(!x) ZNTable[x]=Z_FLAG;
|
||||
else if (x&0x80) ZNTable[x]=N_FLAG;
|
||||
else ZNTable[x]=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HuC6280_Power(void)
|
||||
{
|
||||
HuCPU.IRQlow = 0;
|
||||
|
||||
HuCPU.A = 0;
|
||||
HuCPU.X = 0;
|
||||
HuCPU.Y = 0;
|
||||
HuCPU.S = 0;
|
||||
HuCPU.P = 0;
|
||||
HuCPU.mooPI = 0;
|
||||
|
||||
#if 0
|
||||
HU_PC = HU_PC_base = NULL;
|
||||
#else
|
||||
HuCPU.PC = 0;
|
||||
#endif
|
||||
|
||||
HuCPU.timestamp = 0;
|
||||
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
HuCPU.MPR[i] = 0;
|
||||
HuCPU.FastPageR[i] = NULL;
|
||||
}
|
||||
HuC6280_Reset();
|
||||
}
|
||||
|
||||
void HuC6280_Run(int32 cycles)
|
||||
{
|
||||
const int32 next_user_event = HuCPU.previous_next_user_event + cycles * pce_overclocked;
|
||||
|
||||
HuCPU.previous_next_user_event = next_user_event;
|
||||
|
||||
LOAD_LOCALS();
|
||||
|
||||
if(HuCPU.timestamp >= next_user_event)
|
||||
return;
|
||||
|
||||
int32 next_event;
|
||||
|
||||
if(HuCPU.in_block_move)
|
||||
{
|
||||
next_event = (next_user_event < HuCPU.timer_next_timestamp) ? next_user_event : HuCPU.timer_next_timestamp;
|
||||
|
||||
switch(HuCPU.in_block_move)
|
||||
{
|
||||
case IBM_TIA: goto continue_the_TIA;
|
||||
case IBM_TAI: goto continue_the_TAI;
|
||||
case IBM_TDD: goto continue_the_TDD;
|
||||
case IBM_TII: goto continue_the_TII;
|
||||
case IBM_TIN: goto continue_the_TIN;
|
||||
}
|
||||
}
|
||||
|
||||
while(HuCPU.timestamp < next_user_event)
|
||||
{
|
||||
next_event = (next_user_event < HuCPU.timer_next_timestamp) ? next_user_event : HuCPU.timer_next_timestamp;
|
||||
|
||||
while(HuCPU.timestamp < next_event)
|
||||
{
|
||||
uint8 b1;
|
||||
|
||||
if(HU_IRQlow)
|
||||
{
|
||||
if(!(HU_PI&I_FLAG))
|
||||
{
|
||||
uint32 tmpa = 0;
|
||||
|
||||
if(HU_IRQlow & MDFN_IQTIMER & HuCPU.IRQMaskDelay)
|
||||
tmpa = 0xFFFA;
|
||||
else if((HU_IRQlow & MDFN_IQIRQ1 & HuCPU.IRQMaskDelay) || ((HU_IRQlow >> 8) & MDFN_IQIRQ1 & HuCPU.IRQMaskDelay))
|
||||
tmpa = 0xFFF8;
|
||||
else if(HU_IRQlow & MDFN_IQIRQ2 & HuCPU.IRQMaskDelay)
|
||||
tmpa = 0xFFF6;
|
||||
|
||||
if(tmpa)
|
||||
{
|
||||
unsigned int npc;
|
||||
|
||||
ADDCYC(8);
|
||||
PUSH_PC();
|
||||
|
||||
COMPRESS_FLAGS();
|
||||
PUSH((HU_P&~B_FLAG));
|
||||
HU_P |= I_FLAG;
|
||||
HU_P &= ~(T_FLAG | D_FLAG);
|
||||
HU_PI = HU_P;
|
||||
|
||||
npc = RdMem16(tmpa);
|
||||
SetPC(npc);
|
||||
|
||||
if(tmpa == 0xFFF8)
|
||||
HU_IRQlow &= ~0x200;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} // end if(HU_IRQlow)
|
||||
|
||||
//printf("%04x\n", GetRealPC());
|
||||
HU_PI = HU_P;
|
||||
HuCPU.IRQMaskDelay = HuCPU.IRQMask;
|
||||
|
||||
b1 = RdAtPC();
|
||||
|
||||
ADDCYC(CycTable[b1]);
|
||||
|
||||
IncPC();
|
||||
|
||||
switch(b1)
|
||||
{
|
||||
#include "huc6280_ops.inc"
|
||||
}
|
||||
|
||||
#ifndef HUC6280_EXTRA_CRAZY
|
||||
FixPC_PC();
|
||||
#endif
|
||||
} // end while(HuCPU.timestamp < next_event)
|
||||
|
||||
while(HuCPU.timestamp >= HuCPU.timer_next_timestamp)
|
||||
{
|
||||
HuCPU.timer_next_timestamp += 1024 * pce_overclocked;
|
||||
|
||||
if(HuCPU.timer_status)
|
||||
{
|
||||
HuCPU.timer_value --;
|
||||
if(HuCPU.timer_value < 0)
|
||||
{
|
||||
HuCPU.timer_value = HuCPU.timer_load;
|
||||
HuC6280_IRQBegin(MDFN_IQTIMER);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end while(HuCPU.timestamp < next_user_event)
|
||||
|
||||
GetOutBMT:
|
||||
|
||||
SAVE_LOCALS();
|
||||
}
|
||||
|
||||
void HuC6280_ResetTS(void)
|
||||
{
|
||||
HuCPU.timer_next_timestamp -= HuCPU.timestamp;
|
||||
HuCPU.previous_next_user_event -= HuCPU.timestamp;
|
||||
HuCPU.timestamp = 0;
|
||||
}
|
||||
|
||||
int HuC6280_StateAction(StateMem *sm, int load, int data_only)
|
||||
{
|
||||
uint16 tmp_PC = GetRealPC_EXTERNAL();
|
||||
|
||||
#define P_local HuCPU.P
|
||||
COMPRESS_FLAGS();
|
||||
|
||||
SFORMAT SFCPU[]=
|
||||
{
|
||||
SFVARN(tmp_PC, "PC"),
|
||||
SFVARN(HuCPU.A, "A"),
|
||||
SFVARN(HuCPU.P, "P"),
|
||||
SFVARN(HuCPU.X, "X"),
|
||||
SFVARN(HuCPU.Y, "Y"),
|
||||
SFVARN(HuCPU.S, "S"),
|
||||
SFVARN(HuCPU.mooPI, "PI"),
|
||||
|
||||
SFVARN(HuCPU.IRQMask, "IRQMask"),
|
||||
SFVARN(HuCPU.IRQMaskDelay, "IRQMaskDelay"),
|
||||
SFARRAYN(HuCPU.MPR, 8, "MPR"),
|
||||
SFVARN(HuCPU.timer_status, "timer_status"),
|
||||
SFVARN(HuCPU.timer_value, "timer_value"),
|
||||
SFVARN(HuCPU.timer_load, "timer_load"),
|
||||
|
||||
|
||||
SFVARN(HuCPU.IRQlow, "IRQlow"),
|
||||
SFVARN(HuCPU.in_block_move, "IBM"),
|
||||
SFVARN(HuCPU.bmt_src, "IBM_SRC"),
|
||||
SFVARN(HuCPU.bmt_dest, "IBM_DEST"),
|
||||
SFVARN(HuCPU.bmt_length, "IBM_LENGTH"),
|
||||
SFVARN(HuCPU.bmt_alternate, "IBM_ALTERNATE"),
|
||||
|
||||
SFVARN(HuCPU.timestamp, "timestamp"),
|
||||
SFVARN(HuCPU.timer_next_timestamp, "timer_next_timestamp"),
|
||||
SFVARN(HuCPU.previous_next_user_event, "previous_next_user_event"),
|
||||
|
||||
SFEND
|
||||
};
|
||||
|
||||
int ret = MDFNSS_StateAction(sm, load, data_only, SFCPU, "CPU");
|
||||
|
||||
if(load)
|
||||
{
|
||||
// Update MPR cache
|
||||
HuC6280_FlushMPRCache();
|
||||
|
||||
// This must be after the MPR cache is updated:
|
||||
SetPC_EXTERNAL(tmp_PC);
|
||||
}
|
||||
|
||||
EXPAND_FLAGS();
|
||||
#undef P_local
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
};
|
53
mednafen/pce_fast/tsushin.cpp
Normal file
53
mednafen/pce_fast/tsushin.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* 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 "pce.h"
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
/*
|
||||
Startup:
|
||||
0x80 -> $1830
|
||||
0x40 -> $1823
|
||||
0x50 -> $1823
|
||||
0x02 -> $1821
|
||||
0x40 -> $1823
|
||||
|
||||
Read from $1822 16 times, expecting (return value & 0xC0) == 0x80 each time
|
||||
|
||||
0x50 -> $1823
|
||||
0x01 -> $1821
|
||||
0x40 -> $1823
|
||||
0x04 -> $1822
|
||||
|
||||
*/
|
||||
|
||||
DECLFR(PCE_TsushinRead)
|
||||
{
|
||||
printf("Read: %04x\n", A);
|
||||
|
||||
return(0x80);
|
||||
}
|
||||
|
||||
DECLFW(PCE_TsushinWrite)
|
||||
{
|
||||
printf("Write: %04x %02x\n", A, V);
|
||||
}
|
||||
|
||||
};
|
12
mednafen/pce_fast/tsushin.h
Normal file
12
mednafen/pce_fast/tsushin.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef __PCE_TSUSHIN_H
|
||||
#define __PCE_TSUSHIN_H
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
DECLFR(PCE_TsushinRead);
|
||||
DECLFW(PCE_TsushinWrite);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
1748
mednafen/pce_fast/vdc.cpp
Normal file
1748
mednafen/pce_fast/vdc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
211
mednafen/pce_fast/vdc.h
Normal file
211
mednafen/pce_fast/vdc.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef _PCE_VDC_H
|
||||
#define _PCE_VDC_H
|
||||
|
||||
namespace PCE_Fast
|
||||
{
|
||||
|
||||
#define REGSETP(_reg, _data, _msb) { _reg &= 0xFF << ((_msb) ? 0 : 8); _reg |= (_data) << ((_msb) ? 8 : 0); }
|
||||
#define REGGETP(_reg, _msb) ((_reg >> ((_msb) ? 8 : 0)) & 0xFF)
|
||||
|
||||
#define VDC_DEBUG(x)
|
||||
//printf("%s: %d\n", x, vdc->display_counter);
|
||||
#define VDC_UNDEFINED(x) { }
|
||||
//{ printf("%s: %d\n", x, vdc->display_counter); }
|
||||
|
||||
static const unsigned int vram_inc_tab[4] = { 1, 32, 64, 128 };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 priority[2];
|
||||
uint16 winwidths[2];
|
||||
uint8 st_mode;
|
||||
} vpc_t;
|
||||
|
||||
extern vpc_t vpc;
|
||||
|
||||
static const int VRAM_Size = 0x8000;
|
||||
static const int VRAM_SizeMask = VRAM_Size - 1; //0x7FFF;
|
||||
static const int VRAM_BGTileNoMask = VRAM_SizeMask / 16; //0x7FF;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 CR;
|
||||
|
||||
bool lc263; // 263 line count if set, 262 if not
|
||||
bool bw; // Black and White
|
||||
uint8 dot_clock; // Dot Clock(5, 7, or 10 MHz = 0, 1, 2)
|
||||
uint16 color_table[0x200];
|
||||
uint32 color_table_cache[0x200];
|
||||
uint16 ctaddress;
|
||||
} vce_t;
|
||||
|
||||
extern vce_t vce;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16 y;
|
||||
uint16 height;
|
||||
uint16 x;
|
||||
uint16 no;
|
||||
uint16 flags;
|
||||
bool cgmode;
|
||||
} SAT_Cache_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 display_counter;
|
||||
|
||||
int32 sat_dma_slcounter;
|
||||
|
||||
uint8 select;
|
||||
uint16 MAWR; // Memory Address Write Register
|
||||
uint16 MARR; // Memory Address Read Register
|
||||
|
||||
uint16 CR; // Control Register
|
||||
uint16 RCR; // Raster Compare Register
|
||||
uint16 BXR; // Background X-Scroll Register
|
||||
uint16 BYR; // Background Y-Scroll Register
|
||||
uint16 MWR; // Memory Width Register
|
||||
|
||||
uint16 HSR; // Horizontal Sync Register
|
||||
uint16 HDR; // Horizontal Display Register
|
||||
uint16 VSR;
|
||||
uint16 VDR;
|
||||
|
||||
uint16 VCR;
|
||||
uint16 DCR;
|
||||
uint16 SOUR;
|
||||
uint16 DESR;
|
||||
uint16 LENR;
|
||||
uint16 SATB;
|
||||
|
||||
uint32 RCRCount;
|
||||
|
||||
uint16 read_buffer;
|
||||
uint8 write_latch;
|
||||
uint8 status;
|
||||
|
||||
uint16 DMAReadBuffer;
|
||||
bool DMAReadWrite;
|
||||
bool DMARunning;
|
||||
bool SATBPending;
|
||||
bool burst_mode;
|
||||
|
||||
uint32 BG_YOffset;
|
||||
uint32 BG_XOffset;
|
||||
|
||||
|
||||
|
||||
int SAT_Cache_Valid; // 64 through 128, depending on the number of 32-pixel-wide sprites.
|
||||
SAT_Cache_t SAT_Cache[128]; //64];
|
||||
|
||||
uint16 SAT[0x100];
|
||||
|
||||
uint16 VRAM[65536]; //VRAM_Size];
|
||||
uint64 bg_tile_cache[65536][8]; // Tile, y, x
|
||||
uint8 spr_tile_cache[1024][16][16]; // Tile, y, x
|
||||
uint8 spr_tile_clean[1024]; //VRAM_Size / 64];
|
||||
} vdc_t;
|
||||
|
||||
extern vdc_t *vdc_chips[2];
|
||||
extern int VDC_TotalChips;
|
||||
|
||||
|
||||
void VDC_SetPixelFormat(const MDFN_PixelFormat &format);
|
||||
void VDC_RunFrame(MDFN_Surface *surface, MDFN_Rect *DisplayRect, MDFN_Rect *LineWidths, int skip);
|
||||
void VDC_SetLayerEnableMask(uint64 mask);
|
||||
|
||||
DECLFW(VDC_Write);
|
||||
DECLFW(VDC_Write_ST);
|
||||
|
||||
DECLFR(VCE_Read);
|
||||
|
||||
static INLINE uint8 VDC_Read(unsigned int A, bool SGX)
|
||||
{
|
||||
uint8 ret = 0;
|
||||
int msb = A & 1;
|
||||
int chip = 0;
|
||||
vdc_t *vdc;
|
||||
|
||||
if(SGX)
|
||||
{
|
||||
A &= 0x1F;
|
||||
switch(A)
|
||||
{
|
||||
case 0x8: return(vpc.priority[0]);
|
||||
case 0x9: return(vpc.priority[1]);
|
||||
case 0xA: return(vpc.winwidths[0]);
|
||||
case 0xB: return(vpc.winwidths[0] >> 8);
|
||||
case 0xC: return(vpc.winwidths[1]);
|
||||
case 0xD: return(vpc.winwidths[1] >> 8);
|
||||
case 0xE: return(0);
|
||||
}
|
||||
if(A & 0x8) return(0);
|
||||
chip = (A & 0x10) >> 4;
|
||||
vdc = vdc_chips[chip];
|
||||
A &= 0x3;
|
||||
}
|
||||
else
|
||||
{
|
||||
vdc = vdc_chips[0];
|
||||
A &= 0x3;
|
||||
}
|
||||
|
||||
switch(A)
|
||||
{
|
||||
case 0x0: ret = vdc->status;
|
||||
|
||||
vdc->status &= ~0x3F;
|
||||
|
||||
if(SGX)
|
||||
{
|
||||
if(!(vdc_chips[0]->status & 0x3F) && !(vdc_chips[1]->status & 0x3F))
|
||||
HuC6280_IRQEnd(MDFN_IQIRQ1);
|
||||
}
|
||||
else
|
||||
HuC6280_IRQEnd(MDFN_IQIRQ1); // Clear VDC IRQ line
|
||||
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
case 0x3:
|
||||
ret = REGGETP(vdc->read_buffer, msb);
|
||||
if(vdc->select == 0x2) // VRR - VRAM Read Register
|
||||
{
|
||||
if(msb)
|
||||
{
|
||||
vdc->MARR += vram_inc_tab[(vdc->CR >> 11) & 0x3];
|
||||
|
||||
if(vdc->MARR >= VRAM_Size)
|
||||
VDC_UNDEFINED("Unmapped VRAM VRR read");
|
||||
|
||||
vdc->read_buffer = vdc->VRAM[vdc->MARR & VRAM_SizeMask];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//if(HuCPU.isopread && (A == 1 || A == 3)) //(A == 2 || A == 3)) // && A == 1)
|
||||
if(A == 1)
|
||||
{
|
||||
//if(vdc->display_counter >= (VDS + VSW) && vdc->display_counter < (VDS + VSW + VDW + 1) && vce.dot_clock > 0)
|
||||
if(vce.dot_clock > 0)
|
||||
ret = 0x40;
|
||||
//printf("%d %d %02x\n", vdc->display_counter, vce.dot_clock, ret);
|
||||
//ret = 0x40;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
DECLFW(VCE_Write);
|
||||
|
||||
void VDC_Init(int sgx);
|
||||
void VDC_Close(void);
|
||||
void VDC_Reset(void);
|
||||
void VDC_Power(void);
|
||||
|
||||
int VDC_StateAction(StateMem *sm, int load, int data_only);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
35
mednafen/pce_fast/vpc_mix_inner.inc
Normal file
35
mednafen/pce_fast/vpc_mix_inner.inc
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
uint32 vdc2_pixel, vdc1_pixel;
|
||||
|
||||
vdc2_pixel = vdc1_pixel = vce.color_table_cache[0];
|
||||
|
||||
if(pb & 1)
|
||||
vdc1_pixel = lb0[x];
|
||||
|
||||
if(pb & 2)
|
||||
vdc2_pixel = lb1[x];
|
||||
|
||||
/* Dai MakaiMura uses setting 1, and expects VDC #2 sprites in front of VDC #1 background, but
|
||||
behind VDC #1's sprites.
|
||||
*/
|
||||
switch(pb >> 2)
|
||||
{
|
||||
case 1:
|
||||
//if((vdc2_pixel & (amask << 2)) && !(vdc1_pixel & (amask << 2)))
|
||||
// vdc1_pixel |= amask;
|
||||
vdc1_pixel |= (((vdc2_pixel ^ vdc1_pixel) & vdc2_pixel) >> 2) & amask;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
//if((vdc1_pixel & (amask << 2)) && !(vdc2_pixel & (amask << 2)) && !(vdc2_pixel & amask))
|
||||
// vdc1_pixel |= amask;
|
||||
puts("MOO");
|
||||
// TODO: Verify that this is correct logic.
|
||||
{
|
||||
const uint32 intermediate = ((vdc1_pixel ^ vdc2_pixel) & vdc1_pixel) >> 2;
|
||||
vdc1_pixel |= (intermediate ^ vdc2_pixel) & intermediate & amask;
|
||||
}
|
||||
break;
|
||||
}
|
||||
target[x] = (vdc1_pixel & amask) ? vdc2_pixel : vdc1_pixel;
|
||||
|
74
scrc32.cpp
74
scrc32.cpp
@ -1,74 +0,0 @@
|
||||
static const unsigned long crc_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
#define DO1_CRC32(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
#define DO2_CRC32(buf) DO1_CRC32(buf); DO1_CRC32(buf);
|
||||
#define DO4_CRC32(buf) DO2_CRC32(buf); DO2_CRC32(buf);
|
||||
#define DO8_CRC32(buf) DO4_CRC32(buf); DO4_CRC32(buf);
|
||||
|
||||
unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
if (buf == 0) return 0L;
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len >= 8)
|
||||
{
|
||||
DO8_CRC32(buf);
|
||||
len -= 8;
|
||||
}
|
||||
if (len) do {
|
||||
DO1_CRC32(buf);
|
||||
} while (--len);
|
||||
return crc ^ 0xffffffffL;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user