diff --git a/.bash_history b/.bash_history new file mode 100644 index 0000000..d7d1676 --- /dev/null +++ b/.bash_history @@ -0,0 +1,6 @@ +cd /developer +make -f Makefile.libretro platform=wiiu -j3 DEBUG_ALLOW_DIRTY_SUBMODULES=1 +make -f Makefile platform=wiiu -j3 DEBUG_ALLOW_DIRTY_SUBMODULES=1 +make clean +make -f Makefile platform=wiiu -j3 DEBUG_ALLOW_DIRTY_SUBMODULES=1 +exit diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d5d08d6..50cabd7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,6 +29,10 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/linux-i686.yml' + # MacOS ARM 64-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/osx-arm64.yml' + # MacOS 64-bit - project: 'libretro-infrastructure/ci-templates' file: '/osx-x64.yml' @@ -38,7 +42,11 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/android-jni.yml' - # iOS 9 + # iOS + - project: 'libretro-infrastructure/ci-templates' + file: '/ios-arm64.yml' + + # iOS (armv7) - project: 'libretro-infrastructure/ci-templates' file: '/ios9.yml' @@ -62,7 +70,11 @@ include: # Nintendo Switch - project: 'libretro-infrastructure/ci-templates' file: '/libnx-static.yml' - + + # PlayStation 2 + - project: 'libretro-infrastructure/ci-templates' + file: '/ps2-static.yml' + # PlayStation Portable - project: 'libretro-infrastructure/ci-templates' file: '/psp-static.yml' @@ -71,6 +83,20 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/vita-static.yml' + # tvOS (AppleTV) + - project: 'libretro-infrastructure/ci-templates' + file: '/tvos-arm64.yml' + + # OpenDingux + - project: 'libretro-infrastructure/ci-templates' + file: '/dingux-mips32.yml' + + # OpenDingux (ARM) + - project: 'libretro-infrastructure/ci-templates' + file: '/dingux-arm32.yml' + + #################################### MISC ################################## + # Stages for building stages: - build-prepare @@ -105,7 +131,13 @@ libretro-build-linux-i686: # MacOS 64-bit libretro-build-osx-x64: extends: - - .libretro-osx-x64-make-default + - .libretro-osx-x64-make-10-7 + - .core-defs + +# MacOS ARM 64-bit +libretro-build-osx-arm64: + extends: + - .libretro-osx-arm64-make-default - .core-defs ################################### CELLULAR ################################# @@ -133,14 +165,31 @@ android-x86: - .libretro-android-jni-x86 - .core-defs -# iOS 9 -libretro-build-ios-9: +# iOS +libretro-build-ios-arm64: + extends: + - .libretro-ios-arm64-make-default + - .core-defs + +# iOS (armv7) [iOS 9 and up] +libretro-build-ios9: extends: - .libretro-ios9-make-default - .core-defs +# tvOS +libretro-build-tvos-arm64: + extends: + - .libretro-tvos-arm64-make-default + - .core-defs ################################### CONSOLES ################################# +# PlayStation 2 +libretro-build-ps2: + extends: + - .libretro-ps2-static-retroarch-master + - .core-defs + # PlayStation Portable libretro-build-psp: extends: @@ -182,3 +231,15 @@ libretro-build-libnx-aarch64: extends: - .libretro-libnx-static-retroarch-master - .core-defs + +# RetroFW +libretro-build-retrofw-mips32: + extends: + - .libretro-retrofw-mips32-make-default + - .core-defs + +# Miyoo +libretro-build-miyoo-arm32: + extends: + - .libretro-miyoo-arm32-make-default + - .core-defs \ No newline at end of file diff --git a/Makefile b/Makefile index ca284bb..7bc450b 100644 --- a/Makefile +++ b/Makefile @@ -83,18 +83,29 @@ else ifeq ($(platform), osx) fpic := -fPIC SHARED := -dynamiclib OSXVER = `sw_vers -productVersion | cut -d. -f 2` + CFLAGS += -DHAVE_POSIX_MEMALIGN OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` ifeq ($(OSX_LT_MAVERICKS),"YES") fpic += -mmacosx-version-min=10.5 endif + ifeq ($(CROSS_COMPILE),1) + TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT) + CFLAGS += $(TARGET_RULE) + CPPFLAGS += $(TARGET_RULE) + CXXFLAGS += $(TARGET_RULE) + LDFLAGS += $(TARGET_RULE) + endif + + # iOS else ifneq (,$(findstring ios,$(platform))) TARGET := $(TARGET_NAME)_libretro_ios.dylib fpic := -fPIC SHARED := -dynamiclib - CFLAGS += -Wno-error=implicit-function-declaration -DHAVE_POSIX_MEMALIGN + MINVERSION := + CFLAGS += -Wno-error=implicit-function-declaration -DHAVE_POSIX_MEMALIGN -DIOS ifeq ($(IOSSDK),) IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path) @@ -102,25 +113,23 @@ else ifneq (,$(findstring ios,$(platform))) ifeq ($(platform),$(filter $(platform),ios-arm64)) CC = cc -arch arm64 -isysroot $(IOSSDK) + CC_AS = cc -arch arm64 -isysroot $(IOSSDK) CXX = c++ -arch arm64 -isysroot $(IOSSDK) else - CC = cc -arch armv7 -isysroot $(IOSSDK) - CXX = c++ -arch armv7 -isysroot $(IOSSDK) + CC = cc -marm -arch armv7 -isysroot $(IOSSDK) + CC_AS = cc -marm -arch armv7 -isysroot $(IOSSDK) + CXX = c++ -marm -arch armv7 -isysroot $(IOSSDK) endif CC_AS = perl ./tools/gas-preprocessor.pl $(CC) ifeq ($(platform),$(filter $(platform),ios9 ios-arm64)) - CC += -miphoneos-version-min=8.0 - CXX += -miphoneos-version-min=8.0 - CC_AS += -miphoneos-version-min=8.0 - PLATFORM_DEFINES := -miphoneos-version-min=8.0 -DIOS + MINVERSION = -miphoneos-version-min=8.0 else - CC += -miphoneos-version-min=5.0 - CXX += -miphoneos-version-min=5.0 - CC_AS += -miphoneos-version-min=5.0 - PLATFORM_DEFINES := -miphoneos-version-min=5.0 -DIOS + MINVERSION = -miphoneos-version-min=5.0 endif + PLATFORM_DEFINES := $(MINVERSION) -DIOS + LDFLAGS += $(MINVERSION) # tvOS else ifeq ($(platform), tvos-arm64) @@ -134,6 +143,15 @@ else ifeq ($(platform), tvos-arm64) IOSSDK := $(shell xcodebuild -version -sdk appletvos Path) endif + CC = cc -arch arm64 -isysroot $(IOSSDK) + CC_AS = cc -arch arm64 -isysroot $(IOSSDK) + CXX = c++ -arch arm64 -isysroot $(IOSSDK) + + CC_AS = perl ./tools/gas-preprocessor.pl $(CC) + MINVERSION = -mappletvos-version-min=11.0 + PLATFORM_DEFINES := $(MINVERSION) + LDFLAGS += $(MINVERSION) + # Theos else ifeq ($(platform), theos_ios) DEPLOYMENT_IOSVERSION = 5.0 @@ -157,19 +175,33 @@ else ifeq ($(platform), qnx) PLATFORM_DEFINES := -D__BLACKBERRY_QNX__ -fexceptions -marm -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp # Lightweight PS3 Homebrew SDK -else ifeq ($(platform), psl1ght) - TARGET := $(TARGET_NAME)_libretro_psl1ght.a - CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT) - CC_AS = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT) - CXX = $(PS3DEV)/ppu/bin/ppu-g++$(EXE_EXT) - AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT) - PLATFORM_DEFINES := +else ifneq (,$(filter $(platform), ps3 psl1ght)) + ifeq ($(platform), psl1ght) + PLATFORM_DEFINES := -D__PS3__ -D__PSLIGHT__ + else + PLATFORM_DEFINES := -D__PS3__ + endif + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)gcc$(EXE_EXT) + CC_AS = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)gcc$(EXE_EXT) + CXX = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)g++$(EXE_EXT) + AR = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)ar$(EXE_EXT) STATIC_LINKING = 1 HAVE_COMPAT = 1 +# PS2 +else ifeq ($(platform), ps2) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = mips64r5900el-ps2-elf-gcc$(EXE_EXT) + AR = mips64r5900el-ps2-elf-ar$(EXE_EXT) + PLATFORM_DEFINES := -DPS2 -D_EE -DABGR1555 -G0 -O3 + STATIC_LINKING = 1 + HAVE_COMPAT = 1 + EXTRA_INCLUDES := -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include + # PSP else ifeq ($(platform), psp1) - TARGET := $(TARGET_NAME)_libretro_psp1.a + TARGET := $(TARGET_NAME)_libretro_$(platform).a CC = psp-gcc$(EXE_EXT) AR = psp-ar$(EXE_EXT) PLATFORM_DEFINES := -DPSP @@ -218,16 +250,15 @@ else ifneq (,$(filter $(platform), ngc wii wiiu)) CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) PLATFORM_DEFINES += -DGEKKO -mcpu=750 -meabi -mhard-float -DHAVE_STRTOF_L -DHAVE_LOCALE - PLATFORM_DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int -D_GNU_SOURCE STATIC_LINKING = 1 HAVE_COMPAT = 1 ifneq (,$(findstring wiiu,$(platform))) - CFLAGS += -DDEFAULT_CFG_NAME="\"sd:/retroarch/cores/system/atari800.cfg\"" - PLATFORM_DEFINES += -DWIIU -DHW_RVL + CFLAGS += -DDEFAULT_CFG_NAME="\"fs:/vol/external01/retroarch/cores/system/atari800.cfg\"" + PLATFORM_DEFINES += -DWIIU -DHW_RVL -ffunction-sections -fdata-sections -D__wiiu__ -D__wut__ -D_GNU_SOURCE else ifneq (,$(findstring wii,$(platform))) - PLATFORM_DEFINES += -DHW_RVL -mrvl + PLATFORM_DEFINES += -DHW_RVL -mrvl -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int -D_GNU_SOURCE else ifneq (,$(findstring ngc,$(platform))) - PLATFORM_DEFINES += -DHW_DOL -mrvl + PLATFORM_DEFINES += -DHW_DOL -mrvl -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int -D_GNU_SOURCE endif # Nintendo Switch (libnx) @@ -318,9 +349,31 @@ else ifeq ($(platform), classic_armv8_a35) LDFLAGS += -static-libgcc -static-libstdc++ ####################################### +#RETROFW +else ifeq ($(platform), retrofw) + TARGET := $(TARGET_NAME)_libretro.so + CC = /opt/retrofw-toolchain/usr/bin/mipsel-linux-gcc + CXX = /opt/retrofw-toolchain/usr/bin/mipsel-linux-g++ + AR = /opt/retrofw-toolchain/usr/bin/mipsel-linux-ar + fpic := -fPIC + SHARED := -shared -Wl,-version-script=link.T -Wl,-no-undefined + CFLAGS += -fomit-frame-pointer -march=mips32 -mtune=mips32 -mhard-float + PLATFORM_DEFINES += -DRETROFW + +#MIYOO +else ifeq ($(platform), miyoo) + TARGET := $(TARGET_NAME)_libretro.so + CC = /opt/miyoo/usr/bin/arm-linux-gcc + CXX = /opt/miyoo/usr/bin/arm-linux-g++ + AR = /opt/miyoo/usr/bin/arm-linux-ar + fpic := -fPIC + SHARED := -shared -Wl,-version-script=link.T -Wl,-no-undefined + CFLAGS += -fomit-frame-pointer -march=armv5te -mtune=arm926ej-s + # emscripten else ifeq ($(platform), emscripten) TARGET := $(TARGET_NAME)_libretro_emscripten.bc + STATIC_LINKING=1 # cross Windows else ifeq ($(platform), wincross64) TARGET := $(TARGET_NAME)_libretro.dll @@ -458,8 +511,7 @@ ifeq ($(LOG_PERFORMANCE), 1) endif -DEFINES := -D__LIBRETRO__ $(PLATFORM_DEFINES) -DINLINE="inline" -DEFINES += -DHAVE_CONFIG_H +DEFINES := -D__LIBRETRO__ $(PLATFORM_DEFINES) -DINLINE="inline" -DHAVE_CONFIG_H CFLAGS += $(fpic) $(DEFINES) CFLAGS += -Wall @@ -477,7 +529,7 @@ include Makefile.common HEADERS += $(ROMS:.rom=.h) $(SNAPS:.szx=.h) OBJECTS += $(SOURCES_C:.c=.o) $(SOURCES_CXX:.cpp=.o) -INCDIRS := $(EXTRA_INCLUDES) $(INCFLAGS) +INCDIRS := $(INCFLAGS) $(EXTRA_INCLUDES) OBJOUT = -o LINKOUT = -o @@ -487,7 +539,7 @@ ifneq (,$(findstring msvc,$(platform))) LINKOUT = -out: LD = link.exe else ifneq ($(platform),genode) - LD = $(CXX) + LD = $(CC) endif %.o: %.cpp diff --git a/Makefile.common b/Makefile.common index cf75483..da1b323 100644 --- a/Makefile.common +++ b/Makefile.common @@ -19,15 +19,20 @@ SOURCES_C := \ $(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \ $(LIBRETRO_COMM_DIR)/file/file_path.c \ $(LIBRETRO_COMM_DIR)/file/file_path_io.c \ + $(LIBRETRO_COMM_DIR)/streams/memory_stream.c \ $(LIBRETRO_COMM_DIR)/string/stdstring.c \ $(LIBRETRO_COMM_DIR)/time/rtime.c \ $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c SOURCES_C += \ + $(CORE_DIR)/libretro/carts_hash.c \ $(CORE_DIR)/libretro/libretro-core.c \ $(CORE_DIR)/libretro/core-mapper.c \ $(CORE_DIR)/libretro/graph.c \ - $(CORE_DIR)/libretro/vkbd.c + $(CORE_DIR)/libretro/vkbd.c \ + $(CORE_DIR)/libretro/retro_strings.c \ + $(CORE_DIR)/libretro/retro_utils.c \ + $(CORE_DIR)/libretro/retro_disk_control.c SOURCES_C += \ $(CORE_DIR)/atari800/src/afile.c \ @@ -85,10 +90,15 @@ SOURCES_C += \ # $(CORE_DIR)/atari800/src/videomode.c\ # $(CORE_DIR)/atari800/src/pal_blending.c \ +SOURCES_C += \ + $(CORE_DIR)/atari800/src/roms/altirraos_xl.c \ + $(CORE_DIR)/atari800/src/roms/altirraos_800.c \ + $(CORE_DIR)/atari800/src/roms/altirra_basic.c \ + $(CORE_DIR)/atari800/src/roms/altirra_5200_os.c + ZLIB_INCFLAGS = -I$(DEPS_DIR)/zlib ZLIB_SOURCES_C = \ $(DEPS_DIR)/zlib/adler32.c \ - $(DEPS_DIR)/zlib/compress.c \ $(DEPS_DIR)/zlib/crc32.c \ $(DEPS_DIR)/zlib/deflate.c \ $(DEPS_DIR)/zlib/gzclose.c \ @@ -99,7 +109,6 @@ ZLIB_SOURCES_C = \ $(DEPS_DIR)/zlib/inflate.c \ $(DEPS_DIR)/zlib/inftrees.c \ $(DEPS_DIR)/zlib/trees.c \ - $(DEPS_DIR)/zlib/uncompr.c \ $(DEPS_DIR)/zlib/zutil.c ifeq ($(SYSTEM_ZLIB), 1) diff --git a/atari800/src/afile.c b/atari800/src/afile.c index 7181d05..e88473f 100644 --- a/atari800/src/afile.c +++ b/atari800/src/afile.c @@ -39,7 +39,10 @@ #include #endif #include - +#ifdef __LIBRETRO__ +#include "crc32.h" +#include "carts_hash.h" +#endif int AFILE_DetectFileType(const char *filename) { @@ -48,6 +51,18 @@ int AFILE_DetectFileType(const char *filename) FILE *fp = fopen(filename, "rb"); if (fp == NULL) return AFILE_ERROR; + + #ifdef __LIBRETRO__ + // False positives - hack for raw images + ULONG crc; + CRC32_FromFile(fp, &crc); + Util_rewind(fp); + if (is_cart(crc)) { + fclose(fp); + return AFILE_ROM; + } + #endif // __LIBRETRO__ + if (fread(header, 1, 4, fp) != 4) { fclose(fp); return AFILE_ERROR; diff --git a/atari800/src/android/jni/jni.c b/atari800/src/android/jni/jni.c index 01aac59..9e50ca4 100644 --- a/atari800/src/android/jni/jni.c +++ b/atari800/src/android/jni/jni.c @@ -254,7 +254,16 @@ static jint JNICALL NativeRunAtariProgram(JNIEnv *env, jobject this, CARTRIDGE_MEGA_2048_DESC, CARTRIDGE_THECART_32M_DESC, CARTRIDGE_THECART_64M_DESC, - CARTRIDGE_XEGS_8F_64_DESC + CARTRIDGE_XEGS_8F_64_DESC, + CARTRIDGE_ATRAX_128_DESC, + CARTRIDGE_ADAWLIAH_32_DESC, + CARTRIDGE_ADAWLIAH_64_DESC, + CARTRIDGE_5200_SUPER_64_DESC, + CARTRIDGE_5200_SUPER_128_DESC, + CARTRIDGE_5200_SUPER_256_DESC, + CARTRIDGE_5200_SUPER_512_DESC, + CARTRIDGE_ATMAX_NEW_1024_DESC, + CARTRIDGE_5200_40_ALT_DESC }; const jbyte *img_utf = NULL; diff --git a/atari800/src/antic.c b/atari800/src/antic.c index b24c473..e6084bd 100644 --- a/atari800/src/antic.c +++ b/atari800/src/antic.c @@ -4085,6 +4085,63 @@ case we have ANTIC_cpu2antic_ptr[ANTIC_WSYNC_C+1]-1 = 8 and in the 2nd =12 */ #ifndef BASIC +#if defined(__LIBRETRO__) +void Retro_ANTIC_StateSave(void) +{ + Retro_SaveUBYTE(&ANTIC_DMACTL, 1); + Retro_SaveUBYTE(&ANTIC_CHACTL, 1); + Retro_SaveUBYTE(&ANTIC_HSCROL, 1); + Retro_SaveUBYTE(&ANTIC_VSCROL, 1); + Retro_SaveUBYTE(&ANTIC_PMBASE, 1); + Retro_SaveUBYTE(&ANTIC_CHBASE, 1); + Retro_SaveUBYTE(&ANTIC_NMIEN, 1); + Retro_SaveUBYTE(&ANTIC_NMIST, 1); + Retro_SaveUBYTE(&IR, 1); + Retro_SaveUBYTE(&anticmode, 1); + Retro_SaveUBYTE(&dctr, 1); + Retro_SaveUBYTE(&lastline, 1); + Retro_SaveUBYTE(&need_dl, 1); + Retro_SaveUBYTE(&vscrol_off, 1); + + Retro_SaveUWORD(&ANTIC_dlist, 1); + Retro_SaveUWORD(&screenaddr, 1); + + Retro_SaveINT(&ANTIC_xpos, 1); + Retro_SaveINT(&ANTIC_xpos_limit, 1); + Retro_SaveINT(&ANTIC_ypos, 1); +} + +void Retro_ANTIC_StateRead(void) +{ + Retro_ReadUBYTE(&ANTIC_DMACTL, 1); + Retro_ReadUBYTE(&ANTIC_CHACTL, 1); + Retro_ReadUBYTE(&ANTIC_HSCROL, 1); + Retro_ReadUBYTE(&ANTIC_VSCROL, 1); + Retro_ReadUBYTE(&ANTIC_PMBASE, 1); + Retro_ReadUBYTE(&ANTIC_CHBASE, 1); + Retro_ReadUBYTE(&ANTIC_NMIEN, 1); + Retro_ReadUBYTE(&ANTIC_NMIST, 1); + Retro_ReadUBYTE(&IR, 1); + Retro_ReadUBYTE(&anticmode, 1); + Retro_ReadUBYTE(&dctr, 1); + Retro_ReadUBYTE(&lastline, 1); + Retro_ReadUBYTE(&need_dl, 1); + Retro_ReadUBYTE(&vscrol_off, 1); + + Retro_ReadUWORD(&ANTIC_dlist, 1); + Retro_ReadUWORD(&screenaddr, 1); + + Retro_ReadINT(&ANTIC_xpos, 1); + Retro_ReadINT(&ANTIC_xpos_limit, 1); + Retro_ReadINT(&ANTIC_ypos, 1); + + ANTIC_PutByte(ANTIC_OFFSET_DMACTL, ANTIC_DMACTL); + ANTIC_PutByte(ANTIC_OFFSET_CHACTL, ANTIC_CHACTL); + ANTIC_PutByte(ANTIC_OFFSET_PMBASE, ANTIC_PMBASE); + ANTIC_PutByte(ANTIC_OFFSET_CHBASE, ANTIC_CHBASE); +} +#endif /* __LIBRETRO__ */ + void ANTIC_StateSave(void) { StateSav_SaveUBYTE(&ANTIC_DMACTL, 1); diff --git a/atari800/src/antic.h b/atari800/src/antic.h index 769bde0..8102378 100644 --- a/atari800/src/antic.h +++ b/atari800/src/antic.h @@ -94,6 +94,11 @@ void ANTIC_SetPrior(UBYTE prior); void ANTIC_StateSave(void); void ANTIC_StateRead(void); +#if defined(__LIBRETRO__) +void Retro_ANTIC_StateSave(void); +void Retro_ANTIC_StateRead(void); +#endif + /* Pointer to 16 KB seen by ANTIC in 0x4000-0x7fff. If it's the same what the CPU sees (and what's in memory[0x4000..0x7fff], then NULL. */ diff --git a/atari800/src/atari.c b/atari800/src/atari.c index f71bc4a..d036b8a 100644 --- a/atari800/src/atari.c +++ b/atari800/src/atari.c @@ -147,7 +147,8 @@ #endif #if defined(__LIBRETRO__) extern const char *retro_system_directory; -#endif +extern int legacy_configuration_file; +#endif /* __LIBRETRO__ */ int Atari800_machine_type = Atari800_MACHINE_XLXE; @@ -308,7 +309,7 @@ static int load_roms(void) int basic_ver, xegame_ver; SYSROM_ChooseROMs(Atari800_machine_type, MEMORY_ram_size, Atari800_tv_mode, &Atari800_os_version, &basic_ver, &xegame_ver); if (Atari800_os_version == -1 - || !Atari800_LoadImage(SYSROM_roms[Atari800_os_version].filename, MEMORY_os, SYSROM_roms[Atari800_os_version].size)) { + || !SYSROM_LoadImage(Atari800_os_version, MEMORY_os)) { /* Missing OS ROM. */ Atari800_os_version = -1; if (Atari800_machine_type != Atari800_MACHINE_5200 && emuos_mode == 1) @@ -319,7 +320,7 @@ static int load_roms(void) } else if (Atari800_machine_type != Atari800_MACHINE_5200) { /* OS ROM found, try loading BASIC. */ - MEMORY_have_basic = basic_ver != -1 && Atari800_LoadImage(SYSROM_roms[basic_ver].filename, MEMORY_basic, SYSROM_roms[basic_ver].size); + MEMORY_have_basic = basic_ver != -1 && SYSROM_LoadImage(basic_ver, MEMORY_basic); if (!MEMORY_have_basic) /* Missing BASIC ROM. Don't fail when it happens. */ Atari800_builtin_basic = FALSE; @@ -327,7 +328,7 @@ static int load_roms(void) if (Atari800_builtin_game) { /* Try loading built-in XEGS game. */ if (xegame_ver == -1 - || !Atari800_LoadImage(SYSROM_roms[xegame_ver].filename, MEMORY_xegame, SYSROM_roms[xegame_ver].size)) + || !SYSROM_LoadImage(xegame_ver, MEMORY_xegame)) /* Missing XEGS game ROM. */ Atari800_builtin_game = FALSE; } @@ -427,29 +428,38 @@ int Atari800_Initialise(int *argc, char *argv[]) } *argc = j; } + //LIBRETRO HACK -//#ifndef ANDROID -#if !defined(ANDROID) || defined(__LIBRETRO__) +#if !defined(ANDROID) || defined(__LIBRETRO__) +#if defined(__LIBRETRO__) + if (legacy_configuration_file) + got_config = CFG_LoadConfig(rtconfig_filename); + else + got_config = FALSE; +#else got_config = CFG_LoadConfig(rtconfig_filename); +#endif // __LIBRETRO__ #else got_config = TRUE; /* pretend we got a config file -- not needed in Android */ #endif - +//LIBRETRO HACK /* try to find ROM images if the configuration file is not found or it does not specify some ROM paths (blank paths count as specified) */ -//LIBRETRO HACK -//#ifndef ANDROID + + #if !defined(ANDROID) || defined(__LIBRETRO__) #if defined(__LIBRETRO__) SYSROM_FindInDir(retro_system_directory, TRUE); #endif +#if !defined(__PS3__) && !defined(__PSL1GHT__) SYSROM_FindInDir(".", TRUE); /* current directory */ +#endif #if defined(unix) || defined(__unix__) || defined(__linux__) SYSROM_FindInDir("/usr/share/atari800", TRUE); #endif #if defined(WIIU) && defined(__LIBRETRO__) -SYSROM_FindInDir("sd:/retroarch/cores/system/atari800", TRUE); +SYSROM_FindInDir("fs:/vol/external01/retroarch/cores/system/atari800", TRUE); #endif if (*argc > 0 && argv[0] != NULL) { @@ -474,7 +484,11 @@ SYSROM_FindInDir("sd:/retroarch/cores/system/atari800", TRUE); SYSROM_SetDefaults(); /* if no configuration file read, try to save one with the defaults */ +#if defined(__LIBRETRO__) + if (!got_config && legacy_configuration_file) +#else if (!got_config) +#endif /* __LIBRETRO__*/ CFG_WriteConfig(); #endif /* __PLUS */ @@ -822,6 +836,8 @@ SYSROM_FindInDir("sd:/retroarch/cores/system/atari800", TRUE); /* Auto-start files left on the command line */ j = 1; /* diskno */ for (i = 1; i < *argc; i++) { + if (strcmp(argv[i], "") == 0) // Core started with no content + break; if (j > 8) { /* The remaining arguments are not necessary disk images, but ignore them... */ Log_print("Too many disk image filenames on the command line (max. 8)."); @@ -970,7 +986,11 @@ int Atari800_Exit(int run_monitor) if (!restart) { /* We'd better save the configuration before calling the *_Exit() functions - there's a danger that they might change some emulator settings. */ +#if defined(__LIBRETRO__) + if (CFG_save_on_exit && legacy_configuration_file) +#else if (CFG_save_on_exit) +#endif CFG_WriteConfig(); /* Cleanup functions, in reverse order as the init functions in @@ -1375,6 +1395,131 @@ void Atari800_Frame(void) #ifndef BASIC +#if defined(__LIBRETRO__) +void Retro_Atari800_StateSave(void) +{ + UBYTE temp = Atari800_tv_mode == Atari800_TV_PAL; + Retro_SaveUBYTE(&temp, 1); + temp = Atari800_machine_type; + Retro_SaveUBYTE(&temp, 1); + if (Atari800_machine_type == Atari800_MACHINE_XLXE) { + temp = Atari800_builtin_basic; + Retro_SaveUBYTE(&temp, 1); + temp = Atari800_keyboard_leds; + Retro_SaveUBYTE(&temp, 1); + temp = Atari800_f_keys; + Retro_SaveUBYTE(&temp, 1); + temp = Atari800_jumper; + Retro_SaveUBYTE(&temp, 1); + temp = Atari800_builtin_game; + Retro_SaveUBYTE(&temp, 1); + temp = Atari800_keyboard_detached; + Retro_SaveUBYTE(&temp, 1); + } +} + +void Retro_Atari800_StateRead(UBYTE version) +{ + if (version >= 7) { + UBYTE temp; + Retro_ReadUBYTE(&temp, 1); + Atari800_SetTVMode(temp ? Atari800_TV_PAL : Atari800_TV_NTSC); + Retro_ReadUBYTE(&temp, 1); + if (temp < 0 || temp >= Atari800_MACHINE_SIZE) { + temp = Atari800_MACHINE_XLXE; + Log_print("Warning: Bad machine type read in from state save, defaulting to XL/XE"); + } + Atari800_SetMachineType(temp); + if (Atari800_machine_type == Atari800_MACHINE_XLXE) { + Retro_ReadUBYTE(&temp, 1); + Atari800_builtin_basic = temp != 0; + Retro_ReadUBYTE(&temp, 1); + Atari800_keyboard_leds = temp != 0; + Retro_ReadUBYTE(&temp, 1); + Atari800_f_keys = temp != 0; + Retro_ReadUBYTE(&temp, 1); + Atari800_jumper = temp != 0; + Atari800_UpdateJumper(); + Retro_ReadUBYTE(&temp, 1); + Atari800_builtin_game = temp != 0; + Retro_ReadUBYTE(&temp, 1); + Atari800_keyboard_detached = temp != 0; + Atari800_UpdateKeyboardDetached(); + } + } + else { /* savestate from version 2.2.1 or earlier */ + int new_tv_mode; + /* these are all for compatibility with previous versions */ + UBYTE temp; + int default_tv_mode; + int os; + int default_system; + int pil_on; + + Retro_ReadUBYTE(&temp, 1); + new_tv_mode = (temp == 0) ? Atari800_TV_PAL : Atari800_TV_NTSC; + Atari800_SetTVMode(new_tv_mode); + + Retro_ReadUBYTE(&temp, 1); + Retro_ReadINT(&os, 1); + switch (temp) { + case 0: + Atari800_machine_type = Atari800_MACHINE_800; + MEMORY_ram_size = 48; + break; + case 1: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 64; + break; + case 2: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 128; + break; + case 3: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = MEMORY_RAM_320_COMPY_SHOP; + break; + case 4: + Atari800_machine_type = Atari800_MACHINE_5200; + MEMORY_ram_size = 16; + break; + case 5: + Atari800_machine_type = Atari800_MACHINE_800; + MEMORY_ram_size = 16; + break; + case 6: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 16; + break; + case 7: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 576; + break; + case 8: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 1088; + break; + case 9: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 192; + break; + default: + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 64; + Log_print("Warning: Bad machine type read in from state save, defaulting to 800 XL"); + break; + } + + Retro_ReadINT(&pil_on, 1); + Retro_ReadINT(&default_tv_mode, 1); + Retro_ReadINT(&default_system, 1); + Atari800_SetMachineType(Atari800_machine_type); + } + load_roms(); + /* XXX: what about patches? */ +} +#endif /* __LIBRETRO__ */ + void Atari800_StateSave(void) { UBYTE temp = Atari800_tv_mode == Atari800_TV_PAL; diff --git a/atari800/src/atari.h b/atari800/src/atari.h index de52cba..b1b58c5 100644 --- a/atari800/src/atari.h +++ b/atari800/src/atari.h @@ -187,4 +187,10 @@ void Atari800_StateRead(UBYTE version); /* Change TV mode. */ void Atari800_SetTVMode(int mode); +#if defined(__LIBRETRO__) +/* Save State */ +void Retro_Atari800_StateSave(void); +void Retro_Atari800_StateRead(UBYTE version); +#endif + #endif /* ATARI_H_ */ diff --git a/atari800/src/cartridge.c b/atari800/src/cartridge.c index 390af97..75674e5 100644 --- a/atari800/src/cartridge.c +++ b/atari800/src/cartridge.c @@ -119,7 +119,16 @@ int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1] = { 2048, /* CARTRIDGE_MEGA_2048 */ 32*1024, /* CARTRIDGE_THECART_32M */ 64*1024, /* CARTRIDGE_THECART_64M */ - 64 /* CARTRIDGE_XEGS_64_8F */ + 64, /* CARTRIDGE_XEGS_64_8F */ + 128, /* CARTRIDGE_ATRAX_128_RAW */ + 32, /* CARTRIDGE_ADAWLIAH_32 */ + 64, /* CARTRIDGE_ADAWLIAH_64 */ + 64, /* CARTRIDGE_5200_SUPER_64 */ + 128, /* CARTRIDGE_5200_SUPER_128 */ + 256, /* CARTRIDGE_5200_SUPER_256 */ + 512, /* CARTRIDGE_5200_SUPER_512 */ + 1024, /* CARTRIDGE_ATMAX_NEW_1024 */ + 40, /* CARTRIDGE_5200_40_ALT */ }; int CARTRIDGE_autoreboot = TRUE; @@ -130,9 +139,14 @@ static int CartIsFor5200(int type) case CARTRIDGE_5200_32: case CARTRIDGE_5200_EE_16: case CARTRIDGE_5200_40: + case CARTRIDGE_5200_40_ALT: case CARTRIDGE_5200_NS_16: case CARTRIDGE_5200_8: case CARTRIDGE_5200_4: + case CARTRIDGE_5200_SUPER_64: + case CARTRIDGE_5200_SUPER_128: + case CARTRIDGE_5200_SUPER_256: + case CARTRIDGE_5200_SUPER_512: return TRUE; default: break; @@ -226,6 +240,11 @@ static void set_bank_80BF(void) } } +static void set_bank_5200_SUPER(void) +{ + MEMORY_CopyROM(0x4000, 0xbfff, active_cart->image + active_cart->state * 0x8000); +} + static void set_bank_SDX_128(void) { if (active_cart->state & 8) @@ -402,7 +421,20 @@ static void MapActiveCart(void) if (Atari800_machine_type == Atari800_MACHINE_5200) { MEMORY_SetROM(0x4ff6, 0x4ff9); /* disable Bounty Bob bank switching */ MEMORY_SetROM(0x5ff6, 0x5ff9); + MEMORY_SetROM(0xbfc0, 0xbfff); /* disable Super Cart bank switching */ switch (active_cart->type) { + case CARTRIDGE_5200_SUPER_64: + case CARTRIDGE_5200_SUPER_128: + case CARTRIDGE_5200_SUPER_256: + case CARTRIDGE_5200_SUPER_512: + set_bank_5200_SUPER(); +#ifndef PAGED_ATTRIB + MEMORY_SetHARDWARE(0xbfc0, 0xbfff); +#else + MEMORY_readmap[0xbf] = CARTRIDGE_5200SuperCartGetByte; + MEMORY_writemap[0xbf] = CARTRIDGE_5200SuperCartPutByte; +#endif + break; case CARTRIDGE_5200_32: MEMORY_CopyROM(0x4000, 0xbfff, active_cart->image); break; @@ -424,6 +456,21 @@ static void MapActiveCart(void) MEMORY_readmap[0x5f] = CARTRIDGE_BountyBob2GetByte; MEMORY_writemap[0x4f] = CARTRIDGE_BountyBob1PutByte; MEMORY_writemap[0x5f] = CARTRIDGE_BountyBob2PutByte; +#endif + break; + case CARTRIDGE_5200_40_ALT: + MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + 0x2000 + (active_cart->state & 0x03) * 0x1000); + MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x6000 + ((active_cart->state & 0x0c) >> 2) * 0x1000); + MEMORY_CopyROM(0x8000, 0x9fff, active_cart->image); + MEMORY_CopyROM(0xa000, 0xbfff, active_cart->image); +#ifndef PAGED_ATTRIB + MEMORY_SetHARDWARE(0x4ff6, 0x4ff9); + MEMORY_SetHARDWARE(0x5ff6, 0x5ff9); +#else + MEMORY_readmap[0x4f] = CARTRIDGE_BountyBob1GetByte; + MEMORY_readmap[0x5f] = CARTRIDGE_BountyBob2GetByte; + MEMORY_writemap[0x4f] = CARTRIDGE_BountyBob1PutByte; + MEMORY_writemap[0x5f] = CARTRIDGE_BountyBob2PutByte; #endif break; case CARTRIDGE_5200_NS_16: @@ -1096,7 +1143,10 @@ void CARTRIDGE_BountyBob1(UWORD addr) if (Atari800_machine_type == Atari800_MACHINE_5200) { if (addr >= 0x4ff6 && addr <= 0x4ff9) { addr -= 0x4ff6; - MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + addr * 0x1000); + if (active_cart->type == CARTRIDGE_5200_40_ALT) + MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + 0x2000 + addr * 0x1000); + else + MEMORY_CopyROM(0x4000, 0x4fff, active_cart->image + addr * 0x1000); active_cart->state = (active_cart->state & 0x0c) | addr; } } else { @@ -1113,7 +1163,10 @@ void CARTRIDGE_BountyBob2(UWORD addr) if (Atari800_machine_type == Atari800_MACHINE_5200) { if (addr >= 0x5ff6 && addr <= 0x5ff9) { addr -= 0x5ff6; - MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x4000 + addr * 0x1000); + if (active_cart->type == CARTRIDGE_5200_40_ALT) + MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x6000 + addr * 0x1000); + else + MEMORY_CopyROM(0x5000, 0x5fff, active_cart->image + 0x4000 + addr * 0x1000); active_cart->state = (active_cart->state & 0x03) | (addr << 2); } } @@ -1151,12 +1204,10 @@ UBYTE CARTRIDGE_BountyBob2GetByte(UWORD addr, int no_side_effects) if (Atari800_machine_type == Atari800_MACHINE_5200) { if (addr >= 0x5ff6 && addr <= 0x5ff9) { CARTRIDGE_BountyBob2(addr); - return 0; } } else { if (addr >= 0x9ff6 && addr <= 0x9ff9) { CARTRIDGE_BountyBob2(addr); - return 0; } } } @@ -1200,6 +1251,45 @@ int CARTRIDGE_Checksum(const UBYTE *image, int nbytes) return checksum; } +/* addr must be $bfxx in 5200 mode only. */ +static void access_5200SuperCart(UWORD addr) +{ + int old_state = active_cart->state; + int new_state = old_state; + + if ((addr & 0xc0) == 0xc0) { + switch (addr & 0x30) { + case 0x00: /* $BFCx */ + new_state = (new_state & 0x03) | (addr & 0x0c); + break; + case 0x10: /* $BFDx */ + new_state = (new_state & 0x0c) | ((addr & 0x0c) >> 2); + break; + default: /* 0x20 or 0x30, i.e. $BFEx or $BFFx */ + new_state = 0x0f; + break; + } + new_state &= ((active_cart->size >> 5) - 1); + } + + if (old_state != new_state) { + active_cart->state = new_state; + set_bank_5200_SUPER(); + } +} + +UBYTE CARTRIDGE_5200SuperCartGetByte(UWORD addr, int no_side_effects) +{ + if (!no_side_effects) + access_5200SuperCart(addr); + return MEMORY_dGetByte(addr); +} + +void CARTRIDGE_5200SuperCartPutByte(UWORD addr, UBYTE value) +{ + access_5200SuperCart(addr); +} + static void ResetCartState(CARTRIDGE_image_t *cart) { switch (cart->type) { @@ -1371,10 +1461,15 @@ void CARTRIDGE_ColdStart(void) { ResetCartState(&CARTRIDGE_piggyback); MapActiveCart(); } + #ifdef __LIBRETRO__ -#include "atari5200_hash.h" -extern int autorun5200; -#endif +#include "carts_hash.h" +#include "esc.h" +#include "pokeysnd.h" +extern int autorunCartridge; +extern void retro_message(const char* text, unsigned int frames, int alt); +#endif /* __LIBRETRO __ */ + /* Loads a cartridge from FILENAME. Copies FILENAME to CART_FILENAME. Allocates a buffer with cartridge image data and puts it in *CART_IMAGE. Sets *CART_TYPE to the cartridge type. */ @@ -1385,7 +1480,8 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart) int type; UBYTE header[16]; #ifdef __LIBRETRO__ - ULONG crc; + ULONG crc; + static int RetroMsgShown = FALSE; #endif /* open file */ fp = fopen(filename, "rb"); @@ -1395,7 +1491,7 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart) len = Util_flen(fp); Util_rewind(fp); #ifdef __LIBRETRO__ - if(autorun5200){ + if(autorunCartridge){ CRC32_FromFile(fp, &crc); Util_rewind(fp); } @@ -1408,7 +1504,7 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart) /* if full kilobytes, assume it is raw image */ if ((len & 0x3ff) == 0) { /* alloc memory and read data */ - cart->image = (UBYTE *) Util_malloc(len); + cart->image = (UBYTE*)Util_malloc(len); if (fread(cart->image, 1, len, fp) < len) { Log_print("Error reading cartridge.\n"); } @@ -1418,40 +1514,191 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart) len >>= 10; /* number of kilobytes */ cart->size = len; #ifdef __LIBRETRO__ - if(autorun5200){ - int match=0,i=0; - printf("Hack Libretro:crc A5200 ON sz:%d crc:%x\n",cart->size,crc); - while(a5200_game[i].type!=-1){ - if(crc==a5200_game[i].crc){ - match=1; - if(a5200_game[i].type==0) - switch(cart->size*1024){ - case 4096: - cart->type =CARTRIDGE_5200_4; - break; - case 8192: - cart->type =CARTRIDGE_5200_8; - break; - case 16384: - cart->type =CARTRIDGE_5200_NS_16; - break; - case 32768: - cart->type =CARTRIDGE_5200_32; - break; + if (autorunCartridge == A5200_CART) { + int match = 0, i = 0; + printf("Hack Libretro:crc A5200 ON sz:%d crc:%x\n", cart->size, crc); + while (a5200_game[i].type != -1) { + if (crc == a5200_game[i].crc) { + match = 1; + if (a5200_game[i].type == 0) + switch (cart->size * 1024) { + case 4096: + cart->type = CARTRIDGE_5200_4; + break; + case 8192: + cart->type = CARTRIDGE_5200_8; + break; + case 16384: + cart->type = CARTRIDGE_5200_NS_16; + break; + case 32768: + cart->type = CARTRIDGE_5200_32; + break; + } + else if (a5200_game[i].type == a5200_40) { + /* Bounty Bob don't like stereo pokey (game locks) */ + cart->type = CARTRIDGE_5200_40; + POKEYSND_stereo_enabled = FALSE; + } + else if (a5200_game[i].type == a5200_40_ALT) { + /* Bounty Bob don't like stereo pokey (game locks) */ + cart->type = CARTRIDGE_5200_40_ALT; + POKEYSND_stereo_enabled = FALSE; + } + else if (a5200_game[i].type == a5200_ee_16) + cart->type = CARTRIDGE_5200_EE_16; + else if (a5200_game[i].type == a5200_64) + cart->type = CARTRIDGE_5200_SUPER_64; + else if (a5200_game[i].type == a5200_128) + cart->type = CARTRIDGE_5200_SUPER_128; // I've yet to see this type + else if (a5200_game[i].type == a5200_256) + cart->type = CARTRIDGE_5200_SUPER_256; // I've yet to see this type + else if (a5200_game[i].type == a5200_512) + cart->type = CARTRIDGE_5200_SUPER_512; + else if (a5200_game[i].type == a5200_unsupported) { + match = 3; + cart->type = CARTRIDGE_NONE; + } + else if (a5200_game[i].type == a5200_incomplete) { + match = 4; + cart->type = CARTRIDGE_NONE; + } + else if (a5200_game[i].type == a5200_bad_dump) { + match = 5; + cart->type = CARTRIDGE_NONE; + } + + printf("Hack Libretro:A5200 cart name:%s type:%d crc32:%x\n", a5200_game[i].name,cart->type, crc); + break; + } + i++; + } + if (match == 1) { + if (!RetroMsgShown) + retro_message("Atari 5200 cart detected.", 1000, 0); + goto label_fin; + } + else if (match == 3) { + if (!RetroMsgShown) + retro_message("Atari 5200 unsupported cart detected.", 1000, 0); + goto label_fin; + } + else if (match == 4) { + if (!RetroMsgShown) + retro_message("Atari 5200 incomplete cart detected.", 1000, 0); + goto label_fin; + } + else if (match == 5) { + if (!RetroMsgShown) + retro_message("Atari 5200 bad dump detected.", 1000, 0); + goto label_fin; + } + } + else if (autorunCartridge == A800_CART) { + int match = 0, i = 0; + printf("Hack Libretro:crc A800 ON sz:%d crc:%x\n", cart->size, crc); + while (a800_game[i].type != -1) { + if (crc == a800_game[i].crc) { + match = 1; + if (a800_game[i].type == 0) + switch (cart->size * 1024) { + case 8192: + cart->type = CARTRIDGE_STD_8; + break; + case 16384: + cart->type = CARTRIDGE_STD_16; + break; + case 32768: + cart->type = CARTRIDGE_XEGS_32; + break; } - else if(a5200_game[i].type==1)cart->type =CARTRIDGE_5200_40; - else if(a5200_game[i].type==2)cart->type =CARTRIDGE_5200_EE_16; - printf("Hack Libretro:A5200 cart->type:%d %x\n",cart->type,crc); + else if (a800_game[i].type == a800_40) { + /* Bounty Bob don't like stereo pokey (game locks) */ + cart->type = CARTRIDGE_BBSB_40; + POKEYSND_stereo_enabled = FALSE; + } + else if (a800_game[i].type == a800_WILL_64) + cart->type = CARTRIDGE_WILL_64; + else if (a800_game[i].type == a800_XE_07_64) + cart->type = CARTRIDGE_XEGS_07_64; + else if (a800_game[i].type == a800_XE_128) + cart->type = CARTRIDGE_XEGS_128; + else if (a800_game[i].type == a800_MAX_128) { + /* Some ATMAX 1024 carts dislike Hi Speed SIO*/ + match = 2; + cart->type = CARTRIDGE_ATMAX_128; + } + else if (a800_game[i].type == a800_MAX_1024) { + /* Some ATMAX 1024 carts dislike Hi Speed SIO*/ + match = 2; + cart->type = CARTRIDGE_ATMAX_1024; + } + else if (a800_game[i].type == a800_TURBOSOFT_64) { + match = 2; + cart->type = CARTRIDGE_TURBOSOFT_64; + } + else if (a800_game[i].type == a800_TURBOSOFT_128) { + match = 2; + cart->type = CARTRIDGE_TURBOSOFT_128; + } + else if (a800_game[i].type == a800_TURBOSOFT_64_WILL) { + match = 2; + cart->type = CARTRIDGE_WILL_64; + } + else if (a800_game[i].type == a800_OSS_M091_16) { + cart->type = CARTRIDGE_OSS_M091_16; + } + else if (a800_game[i].type == a800_unsupported) { + match = 3; + cart->type = CARTRIDGE_NONE; + } + else if (a800_game[i].type == a800_incomplete) { + match = 4; + cart->type = CARTRIDGE_NONE; + } + else if (a800_game[i].type == a800_bad_dump) { + match = 5; + cart->type = CARTRIDGE_NONE; + } + + printf("Hack Libretro:A800 cart name:%s type:%d crc32:%x\n", a800_game[i].name, cart->type, crc); break; } - i++; } - if(match==1)goto label_fin; - } -#endif + if (match == 1) { + if (!RetroMsgShown) + retro_message("Atari 800 cart detected.", 1000, 0); + goto label_fin; + } + else if (match == 2) { + if (!RetroMsgShown) + retro_message("Atari 800 cart detected. This cart may need SIO Acceleration disabled.", 1000, 0); + goto label_fin; + } + else if (match == 3) { + if (!RetroMsgShown) + retro_message("Atari 800 unsupported cart detected.", 1000, 0); + goto label_fin; + } + else if (match == 4) { + if (!RetroMsgShown) + retro_message("Atari 800 incomplete cart detected.", 1000, 0); + goto label_fin; + } + else if (match == 5) { + if (!RetroMsgShown) + retro_message("Atari 800 bad dump detected.", 1000, 0); + goto label_fin; + } + else if (!RetroMsgShown) + retro_message("Atari 800 unknown cart (not in DB).", 6000, 0); + } + + RetroMsgShown = TRUE; +#endif /* __LIBRETRO__ */ for (type = 1; type <= CARTRIDGE_LAST_SUPPORTED; type++) if (CARTRIDGE_kb[type] == len) { if (cart->type == CARTRIDGE_NONE) { @@ -1464,7 +1711,9 @@ static int InsertCartridge(const char *filename, CARTRIDGE_image_t *cart) } #ifdef __LIBRETRO__ label_fin: + RetroMsgShown = TRUE; #endif + if (cart->type != CARTRIDGE_NONE) { InitCartridge(cart); return 0; /* ok */ @@ -1712,6 +1961,30 @@ void CARTRIDGE_Exit(void) #ifndef BASIC +void CARTRIDGE_StateSave(void) +{ + int cart_save = CARTRIDGE_main.type; + + if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) + /* Save the cart type as negative, to indicate to CARTStateRead that there is a + second cartridge */ + cart_save = -cart_save; + + /* Save the cartridge type, or CARTRIDGE_NONE if there isn't one...*/ + StateSav_SaveINT(&cart_save, 1); + if (CARTRIDGE_main.type != CARTRIDGE_NONE) { + StateSav_SaveFNAME(CARTRIDGE_main.filename); + StateSav_SaveINT(&CARTRIDGE_main.state, 1); + } + + if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) { + /* Save the second cartridge type and name*/ + StateSav_SaveINT(&CARTRIDGE_piggyback.type, 1); + StateSav_SaveFNAME(CARTRIDGE_piggyback.filename); + StateSav_SaveINT(&CARTRIDGE_piggyback.state, 1); + } +} + void CARTRIDGE_StateRead(UBYTE version) { int saved_type = CARTRIDGE_NONE; @@ -1777,29 +2050,96 @@ void CARTRIDGE_StateRead(UBYTE version) MapActiveCart(); } -void CARTRIDGE_StateSave(void) +#if defined(__LIBRETRO__) +void Retro_CARTRIDGE_StateSave(void) { int cart_save = CARTRIDGE_main.type; - + if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) - /* Save the cart type as negative, to indicate to CARTStateRead that there is a + /* Save the cart type as negative, to indicate to CARTStateRead that there is a second cartridge */ cart_save = -cart_save; - + /* Save the cartridge type, or CARTRIDGE_NONE if there isn't one...*/ - StateSav_SaveINT(&cart_save, 1); + Retro_SaveINT(&cart_save, 1); if (CARTRIDGE_main.type != CARTRIDGE_NONE) { - StateSav_SaveFNAME(CARTRIDGE_main.filename); - StateSav_SaveINT(&CARTRIDGE_main.state, 1); + Retro_SaveFNAME(CARTRIDGE_main.filename); + Retro_SaveINT(&CARTRIDGE_main.state, 1); } if (CARTRIDGE_piggyback.type != CARTRIDGE_NONE) { /* Save the second cartridge type and name*/ - StateSav_SaveINT(&CARTRIDGE_piggyback.type, 1); - StateSav_SaveFNAME(CARTRIDGE_piggyback.filename); - StateSav_SaveINT(&CARTRIDGE_piggyback.state, 1); + Retro_SaveINT(&CARTRIDGE_piggyback.type, 1); + Retro_SaveFNAME(CARTRIDGE_piggyback.filename); + Retro_SaveINT(&CARTRIDGE_piggyback.state, 1); + } +} + +void Retro_CARTRIDGE_StateRead(UBYTE version) +{ + int saved_type = CARTRIDGE_NONE; + char filename[FILENAME_MAX]; + + /* Read the cart type from the file. If there is no cart type, becaused we have + reached the end of the file, this will just default to CART_NONE */ + Retro_ReadINT(&saved_type, 1); + if (saved_type != CARTRIDGE_NONE) { + Retro_ReadFNAME(filename); + if (filename[0]) { + /* Insert the cartridge... */ + if (CARTRIDGE_Insert(filename) >= 0) { + /* And set the type to the saved type, in case it was a raw cartridge image */ + CARTRIDGE_main.type = saved_type; + } + } + if (version >= 7) + /* Read the cartridge's state (current bank etc.). */ + Retro_ReadINT(&CARTRIDGE_main.state, 1); } + else + CARTRIDGE_main.type = saved_type; + + if (saved_type < 0) { + /* Minus value indicates a piggyback cartridge present. */ + CARTRIDGE_main.type = -saved_type; + + Retro_ReadINT(&saved_type, 1); + Retro_ReadFNAME(filename); + if (filename[0]) { + /* Insert the cartridge... */ + if (CARTRIDGE_Insert_Second(filename) >= 0) { + /* And set the type to the saved type, in case it was a raw cartridge image */ + CARTRIDGE_piggyback.type = saved_type; + } + } + if (version >= 7) + /* Read the cartridge's state (current bank etc.). */ + Retro_ReadINT(&CARTRIDGE_piggyback.state, 1); + else { + /* Savestate version 6 explicitely stored information about + the active cartridge. */ + int piggyback_active; + Retro_ReadINT(&piggyback_active, 1); + if (piggyback_active) + active_cart = &CARTRIDGE_piggyback; + else + active_cart = &CARTRIDGE_main; + /* The "Determine active cartridge" code below makes no + sense when loading ver.6 savestates, because they + did not store the cartridge state. */ + return; + } + } + + /* Determine active cartridge (main or piggyback. */ + if (CartIsPassthrough(CARTRIDGE_main.type) && (CARTRIDGE_main.state & 0x0c) == 0x08) + active_cart = &CARTRIDGE_piggyback; + else + active_cart = &CARTRIDGE_main; + + MapActiveCart(); } +#endif /* __LIBRETRO__ */ #endif diff --git a/atari800/src/cartridge.h b/atari800/src/cartridge.h index 288814a..e2cb7c1 100644 --- a/atari800/src/cartridge.h +++ b/atari800/src/cartridge.h @@ -74,7 +74,19 @@ enum { CARTRIDGE_THECART_32M = 65, CARTRIDGE_THECART_64M = 66, CARTRIDGE_XEGS_8F_64 = 67, - CARTRIDGE_LAST_SUPPORTED = 67 + + CARTRIDGE_ATRAX_128_RAW = 68, + CARTRIDGE_ADAWLIAH_32 = 69, + CARTRIDGE_ADAWLIAH_64 = 70, + CARTRIDGE_5200_SUPER_64 = 71, + CARTRIDGE_5200_SUPER_128 = 72, + CARTRIDGE_5200_SUPER_256 = 73, + CARTRIDGE_5200_SUPER_512 = 74, + CARTRIDGE_ATMAX_NEW_1024 = 75, + + CARTRIDGE_5200_40_ALT = 76, // Bounty Bob (5200) - Alternate layout + + CARTRIDGE_LAST_SUPPORTED = 76 }; #define CARTRIDGE_MAX_SIZE (128 * 1024 * 1024) @@ -121,7 +133,7 @@ extern int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1]; #define CARTRIDGE_PHOENIX_8_DESC "Phoenix 8 KB cartridge" #define CARTRIDGE_BLIZZARD_16_DESC "Blizzard 16 KB cartridge" #define CARTRIDGE_ATMAX_128_DESC "Atarimax 128 KB Flash cartridge" -#define CARTRIDGE_ATMAX_1024_DESC "Atarimax 1 MB Flash cartridge" +#define CARTRIDGE_ATMAX_1024_DESC "Atarimax 1 MB Flash cartridge (old)" #define CARTRIDGE_SDX_128_DESC "SpartaDOS X 128 KB cartridge" #define CARTRIDGE_OSS_8_DESC "OSS 8 KB cartridge" #define CARTRIDGE_OSS_043M_16_DESC "OSS two chip 16 KB cartridge (043M)" @@ -147,6 +159,15 @@ extern int const CARTRIDGE_kb[CARTRIDGE_LAST_SUPPORTED + 1]; #define CARTRIDGE_THECART_32M_DESC "The!Cart 32 MB cartridge" #define CARTRIDGE_THECART_64M_DESC "The!Cart 64 MB cartridge" #define CARTRIDGE_XEGS_8F_64_DESC "XEGS 64 KB cartridge (banks 8-15)" +#define CARTRIDGE_ATRAX_128_RAW_DESC "Atrax 128 KB cartridge" +#define CARTRIDGE_ADAWLIAH_32_DESC "aDawliah 32 KB cartridge" +#define CARTRIDGE_ADAWLIAH_64_DESC "aDawliah 64 KB cartridge" +#define CARTRIDGE_5200_SUPER_64_DESC "64 KB Atari 5200 Super Cart" +#define CARTRIDGE_5200_SUPER_128_DESC "128 KB Atari 5200 Super Cart" +#define CARTRIDGE_5200_SUPER_256_DESC "256 KB Atari 5200 Super Cart" +#define CARTRIDGE_5200_SUPER_512_DESC "512 KB Atari 5200 Super Cart" +#define CARTRIDGE_ATMAX_NEW_1024_DESC "Atarimax 1 MB Flash cartridge" +#define CARTRIDGE_5200_40_ALT_DESC "Bounty Bob (5200) - Alternate layout" /* Indicates whether the emulator should automatically reboot (coldstart) after inserting/removing a cartridge. (Doesn't affect the piggyback @@ -203,6 +224,19 @@ void CARTRIDGE_BountyBob1(UWORD addr); void CARTRIDGE_BountyBob2(UWORD addr); void CARTRIDGE_StateSave(void); void CARTRIDGE_StateRead(UBYTE version); + +/* addr must be $bfxx in 5200 mode only. */ +UBYTE CARTRIDGE_5200SuperCartGetByte(UWORD addr, int no_side_effects); + +/* addr must be $bfxx in 5200 mode only. */ +void CARTRIDGE_5200SuperCartPutByte(UWORD addr, UBYTE value); + + +#if defined(__LIBRETRO__) +void Retro_CARTRIDGE_StateSave(void); +void Retro_CARTRIDGE_StateRead(UBYTE version); +#endif + #ifdef PAGED_ATTRIB UBYTE CARTRIDGE_BountyBob1GetByte(UWORD addr, int no_side_effects); UBYTE CARTRIDGE_BountyBob2GetByte(UWORD addr, int no_side_effects); diff --git a/atari800/src/cassette.c b/atari800/src/cassette.c index fe9b54b..cefca91 100644 --- a/atari800/src/cassette.c +++ b/atari800/src/cassette.c @@ -412,10 +412,6 @@ void CASSETTE_LeaderLoad(void) CASSETTE_ToggleRecord(); CASSETTE_TapeMotor(TRUE); cassette_gapdelay = 9600; - /* registers for SETVBV: third system timer, ~0.1 sec */ - CPU_regA = 3; - CPU_regX = 0; - CPU_regY = 5; } /* indicates that a save leader is written by the OS */ @@ -425,10 +421,6 @@ void CASSETTE_LeaderSave(void) CASSETTE_ToggleRecord(); CASSETTE_TapeMotor(TRUE); cassette_gapdelay = 19200; - /* registers for SETVBV: third system timer, ~0.1 sec */ - CPU_regA = 3; - CPU_regX = 0; - CPU_regY = 5; } int CASSETTE_ReadToMemory(UWORD dest_addr, int length) diff --git a/atari800/src/cfg.c b/atari800/src/cfg.c index 224c8ff..cbd82df 100644 --- a/atari800/src/cfg.c +++ b/atari800/src/cfg.c @@ -64,6 +64,9 @@ #endif int CFG_save_on_exit = FALSE; +#if defined(__LIBRETRO__) +extern const char *retro_system_directory; +#endif /* If another default path config path is defined use it otherwise use the default one */ @@ -75,9 +78,13 @@ int CFG_save_on_exit = FALSE; #define SYSTEM_WIDE_CFG_FILE "/etc/atari800.cfg" #endif +#if defined (__PS3__) || defined(__PSL1GHT__) +#define DEFAULT_CFG_NAME "/atari800.cfg" +#endif + #ifdef WIIU -#define DEFAULT_CFG_NAME "sd:/retroarch/cores/system/atari800.cfg" -#define SYSTEM_WIDE_CFG_FILE "sd:/retroarch/cores/system/atari800.cfg" +#define DEFAULT_CFG_NAME "fs:/vol/external01/retroarch/cores/system/atari800.cfg" +#define SYSTEM_WIDE_CFG_FILE "fs:/vol/external01/retroarch/cores/system/atari800.cfg" #endif static char rtconfig_filename[FILENAME_MAX]; @@ -101,11 +108,16 @@ int CFG_LoadConfig(const char *alternate_config_filename) } /* else use the default config name under the HOME folder */ else { +#if !defined(__PS3__) && !defined(__PSL1GHT__) char *home = getenv("HOME"); if (home != NULL) Util_catpath(rtconfig_filename, home, DEFAULT_CFG_NAME); else strcpy(rtconfig_filename, DEFAULT_CFG_NAME); +#else + strcpy(rtconfig_filename, retro_system_directory); + strcat(rtconfig_filename, DEFAULT_CFG_NAME); +#endif } fp = fopen(fname, "r"); diff --git a/atari800/src/cpu.c b/atari800/src/cpu.c index 2a1bdd8..88dfac1 100644 --- a/atari800/src/cpu.c +++ b/atari800/src/cpu.c @@ -2385,6 +2385,42 @@ void CPU_Reset(void) #if !defined(BASIC) && !defined(ASAP) +#if defined(__LIBRETRO__) +void Retro_CPU_StateSave(UBYTE SaveVerbose) +{ + Retro_SaveUBYTE(&CPU_regA, 1); + + CPU_GetStatus(); /* Make sure flags are all updated */ + Retro_SaveUBYTE(&CPU_regP, 1); + + Retro_SaveUBYTE(&CPU_regS, 1); + Retro_SaveUBYTE(&CPU_regX, 1); + Retro_SaveUBYTE(&CPU_regY, 1); + Retro_SaveUBYTE(&CPU_IRQ, 1); + + Retro_MEMORY_StateSave(SaveVerbose); + + Retro_SaveUWORD(&CPU_regPC, 1); +} + +void Retro_CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion) +{ + Retro_ReadUBYTE(&CPU_regA, 1); + + Retro_ReadUBYTE(&CPU_regP, 1); + CPU_PutStatus(); /* Make sure flags are all updated */ + + Retro_ReadUBYTE(&CPU_regS, 1); + Retro_ReadUBYTE(&CPU_regX, 1); + Retro_ReadUBYTE(&CPU_regY, 1); + Retro_ReadUBYTE(&CPU_IRQ, 1); + + Retro_MEMORY_StateRead(SaveVerbose, StateVersion); + + Retro_ReadUWORD(&CPU_regPC, 1); +} +#endif /* __LIBRETRO__ */ + void CPU_StateSave(UBYTE SaveVerbose) { StateSav_SaveUBYTE(&CPU_regA, 1); diff --git a/atari800/src/cpu.h b/atari800/src/cpu.h index 5e64ca2..cab4e53 100644 --- a/atari800/src/cpu.h +++ b/atari800/src/cpu.h @@ -22,6 +22,12 @@ void CPU_PutStatus(void); void CPU_Reset(void); void CPU_StateSave(UBYTE SaveVerbose); void CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion); + +#if defined(__LIBRETRO__) +void Retro_CPU_StateSave(UBYTE SaveVerbose); +void Retro_CPU_StateRead(UBYTE SaveVerbose, UBYTE StateVersion); +#endif + void CPU_NMI(void); void CPU_GO(int limit); #define CPU_GenerateIRQ() (CPU_IRQ = 1) diff --git a/atari800/src/devices.c b/atari800/src/devices.c index 72afa16..2f5c320 100644 --- a/atari800/src/devices.c +++ b/atari800/src/devices.c @@ -2440,6 +2440,12 @@ int Devices_PatchOS(void) case SYSROM_CC01R4: addr = 0xc3eb; break; + case SYSROM_ALTIRRA_800: + addr = 0xefd4; /* labeled InitHandlerTable in OS sources */ + break; + case SYSROM_ALTIRRA_XL: + addr = 0xee90; /* labeled InitHandlerTable in OS sources */ + break; default: return FALSE; } diff --git a/atari800/src/devices.h b/atari800/src/devices.h index 9c707d1..b24bef1 100644 --- a/atari800/src/devices.h +++ b/atari800/src/devices.h @@ -4,6 +4,12 @@ #include /* FILENAME_MAX */ #include "atari.h" /* UWORD */ +#if defined(__PS3__) && !defined(__PSL1GHT__) +#define S_IREAD S_IRUSR +#define S_IWRITE S_IWUSR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif + int Devices_Initialise(int *argc, char *argv[]); void Devices_Exit(void); int Devices_PatchOS(void); diff --git a/atari800/src/esc.c b/atari800/src/esc.c index 46dc34e..07d5a69 100644 --- a/atari800/src/esc.c +++ b/atari800/src/esc.c @@ -49,6 +49,42 @@ int ESC_enable_sio_patch = TRUE; static UWORD esc_address[256]; static ESC_FunctionType esc_function[256]; +/* Esc function that removes the wait loop when reading the tape leader. For + use with standard Atari OSes only. */ +static void CassetteLeaderLoad(void) +{ + CASSETTE_LeaderLoad(); + + /* registers for SETVBV: third system timer, ~0.1 sec */ + CPU_regA = 3; + CPU_regX = 0; + CPU_regY = 5; +} + +/* Esc function that removes the wait loop when writing the tape leader. For + use with standard Atari OSes only. */ +static void CassetteLeaderSave(void) +{ + CASSETTE_LeaderSave(); + + /* registers for SETVBV: third system timer, ~0.1 sec */ + CPU_regA = 3; + CPU_regX = 0; + CPU_regY = 5; +} + +/* Esc function that removes the wait loop in AltirraOS's "CassetteWait" + routine when reading or writing the tape leader. */ +static void CassetteLeaderAltirra(void) +{ + if (CPU_regX == 1) + CASSETTE_LeaderLoad(); + else + CASSETTE_LeaderSave(); + /* Routine expects Y = 1 on exit. */ + CPU_regY = 1; +} + void ESC_ClearAll(void) { int i; @@ -124,6 +160,7 @@ void ESC_PatchOS(void) UWORD addr_s; UBYTE check_s_0; UBYTE check_s_1; + int altirra = FALSE; /* patch Open() of C: so we know when a leader is processed */ switch (Atari800_os_version) { case SYSROM_A_NTSC: @@ -167,19 +204,32 @@ void ESC_PatchOS(void) check_s_0 = 0xa9; check_s_1 = 0x03; break; + case SYSROM_ALTIRRA_800: + altirra = TRUE; + addr_l = 0xef91; /* points to CassetteWait */ + /* Fall through. */ + case SYSROM_ALTIRRA_XL: + altirra = TRUE; + addr_l = 0xee4a; /* points to CassetteWait */ + break; default: return; } - /* don't hurt non-standard OSes that may not support cassette at all */ - if (MEMORY_dGetByte(addr_l) == 0xa9 && MEMORY_dGetByte(addr_l + 1) == 0x03 - && MEMORY_dGetByte(addr_l + 2) == 0x8d && MEMORY_dGetByte(addr_l + 3) == 0x2a - && MEMORY_dGetByte(addr_l + 4) == 0x02 - && MEMORY_dGetByte(addr_s) == check_s_0 - && MEMORY_dGetByte(addr_s + 1) == check_s_1 - && MEMORY_dGetByte(addr_s + 2) == 0x20 && MEMORY_dGetByte(addr_s + 3) == 0x5c - && MEMORY_dGetByte(addr_s + 4) == 0xe4) { - ESC_Add(addr_l, ESC_COPENLOAD, CASSETTE_LeaderLoad); - ESC_Add(addr_s, ESC_COPENSAVE, CASSETTE_LeaderSave); + if (altirra) + ESC_AddEscRts(addr_l, ESC_COPENLOAD, CassetteLeaderAltirra); + else + { + /* don't hurt non-standard OSes that may not support cassette at all */ + if (MEMORY_dGetByte(addr_l) == 0xa9 && MEMORY_dGetByte(addr_l + 1) == 0x03 + && MEMORY_dGetByte(addr_l + 2) == 0x8d && MEMORY_dGetByte(addr_l + 3) == 0x2a + && MEMORY_dGetByte(addr_l + 4) == 0x02 + && MEMORY_dGetByte(addr_s) == check_s_0 + && MEMORY_dGetByte(addr_s + 1) == check_s_1 + && MEMORY_dGetByte(addr_s + 2) == 0x20 && MEMORY_dGetByte(addr_s + 3) == 0x5c + && MEMORY_dGetByte(addr_s + 4) == 0xe4) { + ESC_Add(addr_l, ESC_COPENLOAD, CassetteLeaderLoad); + ESC_Add(addr_s, ESC_COPENSAVE, CassetteLeaderSave); + } } ESC_AddEscRts(0xe459, ESC_SIOV, SIO_Handler); patched = TRUE; diff --git a/atari800/src/gtia.c b/atari800/src/gtia.c index cc982f0..f14e5b9 100644 --- a/atari800/src/gtia.c +++ b/atari800/src/gtia.c @@ -1199,6 +1199,145 @@ void GTIA_PutByte(UWORD addr, UBYTE byte) #ifndef BASIC +#if defined(__LIBRETRO__) +void Retro_GTIA_StateSave(void) +{ + int next_console_value = 7; + + Retro_SaveUBYTE(>IA_HPOSP0, 1); + Retro_SaveUBYTE(>IA_HPOSP1, 1); + Retro_SaveUBYTE(>IA_HPOSP2, 1); + Retro_SaveUBYTE(>IA_HPOSP3, 1); + Retro_SaveUBYTE(>IA_HPOSM0, 1); + Retro_SaveUBYTE(>IA_HPOSM1, 1); + Retro_SaveUBYTE(>IA_HPOSM2, 1); + Retro_SaveUBYTE(>IA_HPOSM3, 1); + Retro_SaveUBYTE(&PF0PM, 1); + Retro_SaveUBYTE(&PF1PM, 1); + Retro_SaveUBYTE(&PF2PM, 1); + Retro_SaveUBYTE(&PF3PM, 1); + Retro_SaveUBYTE(>IA_M0PL, 1); + Retro_SaveUBYTE(>IA_M1PL, 1); + Retro_SaveUBYTE(>IA_M2PL, 1); + Retro_SaveUBYTE(>IA_M3PL, 1); + Retro_SaveUBYTE(>IA_P0PL, 1); + Retro_SaveUBYTE(>IA_P1PL, 1); + Retro_SaveUBYTE(>IA_P2PL, 1); + Retro_SaveUBYTE(>IA_P3PL, 1); + Retro_SaveUBYTE(>IA_SIZEP0, 1); + Retro_SaveUBYTE(>IA_SIZEP1, 1); + Retro_SaveUBYTE(>IA_SIZEP2, 1); + Retro_SaveUBYTE(>IA_SIZEP3, 1); + Retro_SaveUBYTE(>IA_SIZEM, 1); + Retro_SaveUBYTE(>IA_GRAFP0, 1); + Retro_SaveUBYTE(>IA_GRAFP1, 1); + Retro_SaveUBYTE(>IA_GRAFP2, 1); + Retro_SaveUBYTE(>IA_GRAFP3, 1); + Retro_SaveUBYTE(>IA_GRAFM, 1); + Retro_SaveUBYTE(>IA_COLPM0, 1); + Retro_SaveUBYTE(>IA_COLPM1, 1); + Retro_SaveUBYTE(>IA_COLPM2, 1); + Retro_SaveUBYTE(>IA_COLPM3, 1); + Retro_SaveUBYTE(>IA_COLPF0, 1); + Retro_SaveUBYTE(>IA_COLPF1, 1); + Retro_SaveUBYTE(>IA_COLPF2, 1); + Retro_SaveUBYTE(>IA_COLPF3, 1); + Retro_SaveUBYTE(>IA_COLBK, 1); + Retro_SaveUBYTE(>IA_PRIOR, 1); + Retro_SaveUBYTE(>IA_VDELAY, 1); + Retro_SaveUBYTE(>IA_GRACTL, 1); + + Retro_SaveUBYTE(&consol_mask, 1); + Retro_SaveINT(>IA_speaker, 1); + Retro_SaveINT(&next_console_value, 1); + Retro_SaveUBYTE(GTIA_TRIG_latch, 4); +} + +void Retro_GTIA_StateRead(UBYTE version) +{ + int next_console_value; /* ignored */ + + Retro_ReadUBYTE(>IA_HPOSP0, 1); + Retro_ReadUBYTE(>IA_HPOSP1, 1); + Retro_ReadUBYTE(>IA_HPOSP2, 1); + Retro_ReadUBYTE(>IA_HPOSP3, 1); + Retro_ReadUBYTE(>IA_HPOSM0, 1); + Retro_ReadUBYTE(>IA_HPOSM1, 1); + Retro_ReadUBYTE(>IA_HPOSM2, 1); + Retro_ReadUBYTE(>IA_HPOSM3, 1); + Retro_ReadUBYTE(&PF0PM, 1); + Retro_ReadUBYTE(&PF1PM, 1); + Retro_ReadUBYTE(&PF2PM, 1); + Retro_ReadUBYTE(&PF3PM, 1); + Retro_ReadUBYTE(>IA_M0PL, 1); + Retro_ReadUBYTE(>IA_M1PL, 1); + Retro_ReadUBYTE(>IA_M2PL, 1); + Retro_ReadUBYTE(>IA_M3PL, 1); + Retro_ReadUBYTE(>IA_P0PL, 1); + Retro_ReadUBYTE(>IA_P1PL, 1); + Retro_ReadUBYTE(>IA_P2PL, 1); + Retro_ReadUBYTE(>IA_P3PL, 1); + Retro_ReadUBYTE(>IA_SIZEP0, 1); + Retro_ReadUBYTE(>IA_SIZEP1, 1); + Retro_ReadUBYTE(>IA_SIZEP2, 1); + Retro_ReadUBYTE(>IA_SIZEP3, 1); + Retro_ReadUBYTE(>IA_SIZEM, 1); + Retro_ReadUBYTE(>IA_GRAFP0, 1); + Retro_ReadUBYTE(>IA_GRAFP1, 1); + Retro_ReadUBYTE(>IA_GRAFP2, 1); + Retro_ReadUBYTE(>IA_GRAFP3, 1); + Retro_ReadUBYTE(>IA_GRAFM, 1); + Retro_ReadUBYTE(>IA_COLPM0, 1); + Retro_ReadUBYTE(>IA_COLPM1, 1); + Retro_ReadUBYTE(>IA_COLPM2, 1); + Retro_ReadUBYTE(>IA_COLPM3, 1); + Retro_ReadUBYTE(>IA_COLPF0, 1); + Retro_ReadUBYTE(>IA_COLPF1, 1); + Retro_ReadUBYTE(>IA_COLPF2, 1); + Retro_ReadUBYTE(>IA_COLPF3, 1); + Retro_ReadUBYTE(>IA_COLBK, 1); + Retro_ReadUBYTE(>IA_PRIOR, 1); + Retro_ReadUBYTE(>IA_VDELAY, 1); + Retro_ReadUBYTE(>IA_GRACTL, 1); + + Retro_ReadUBYTE(&consol_mask, 1); + Retro_ReadINT(>IA_speaker, 1); + Retro_ReadINT(&next_console_value, 1); + if (version >= 7) + Retro_ReadUBYTE(GTIA_TRIG_latch, 4); + + GTIA_PutByte(GTIA_OFFSET_HPOSP0, GTIA_HPOSP0); + GTIA_PutByte(GTIA_OFFSET_HPOSP1, GTIA_HPOSP1); + GTIA_PutByte(GTIA_OFFSET_HPOSP2, GTIA_HPOSP2); + GTIA_PutByte(GTIA_OFFSET_HPOSP3, GTIA_HPOSP3); + GTIA_PutByte(GTIA_OFFSET_HPOSM0, GTIA_HPOSM0); + GTIA_PutByte(GTIA_OFFSET_HPOSM1, GTIA_HPOSM1); + GTIA_PutByte(GTIA_OFFSET_HPOSM2, GTIA_HPOSM2); + GTIA_PutByte(GTIA_OFFSET_HPOSM3, GTIA_HPOSM3); + GTIA_PutByte(GTIA_OFFSET_SIZEP0, GTIA_SIZEP0); + GTIA_PutByte(GTIA_OFFSET_SIZEP1, GTIA_SIZEP1); + GTIA_PutByte(GTIA_OFFSET_SIZEP2, GTIA_SIZEP2); + GTIA_PutByte(GTIA_OFFSET_SIZEP3, GTIA_SIZEP3); + GTIA_PutByte(GTIA_OFFSET_SIZEM, GTIA_SIZEM); + GTIA_PutByte(GTIA_OFFSET_GRAFP0, GTIA_GRAFP0); + GTIA_PutByte(GTIA_OFFSET_GRAFP1, GTIA_GRAFP1); + GTIA_PutByte(GTIA_OFFSET_GRAFP2, GTIA_GRAFP2); + GTIA_PutByte(GTIA_OFFSET_GRAFP3, GTIA_GRAFP3); + GTIA_PutByte(GTIA_OFFSET_GRAFM, GTIA_GRAFM); + GTIA_PutByte(GTIA_OFFSET_COLPM0, GTIA_COLPM0); + GTIA_PutByte(GTIA_OFFSET_COLPM1, GTIA_COLPM1); + GTIA_PutByte(GTIA_OFFSET_COLPM2, GTIA_COLPM2); + GTIA_PutByte(GTIA_OFFSET_COLPM3, GTIA_COLPM3); + GTIA_PutByte(GTIA_OFFSET_COLPF0, GTIA_COLPF0); + GTIA_PutByte(GTIA_OFFSET_COLPF1, GTIA_COLPF1); + GTIA_PutByte(GTIA_OFFSET_COLPF2, GTIA_COLPF2); + GTIA_PutByte(GTIA_OFFSET_COLPF3, GTIA_COLPF3); + GTIA_PutByte(GTIA_OFFSET_COLBK, GTIA_COLBK); + GTIA_PutByte(GTIA_OFFSET_PRIOR, GTIA_PRIOR); + GTIA_PutByte(GTIA_OFFSET_GRACTL, GTIA_GRACTL); +} +#endif /* __LIBRETRO__ */ + void GTIA_StateSave(void) { int next_console_value = 7; diff --git a/atari800/src/gtia.h b/atari800/src/gtia.h index 2a00f95..7f62849 100644 --- a/atari800/src/gtia.h +++ b/atari800/src/gtia.h @@ -132,6 +132,11 @@ void GTIA_PutByte(UWORD addr, UBYTE byte); void GTIA_StateSave(void); void GTIA_StateRead(UBYTE version); +#if defined(__LIBRETRO__) +void Retro_GTIA_StateSave(void); +void Retro_GTIA_StateRead(UBYTE version); +#endif + #ifdef NEW_CYCLE_EXACT void GTIA_UpdatePmplColls(void); #endif diff --git a/atari800/src/ide.c b/atari800/src/ide.c index 7ce2a7b..f8413d3 100644 --- a/atari800/src/ide.c +++ b/atari800/src/ide.c @@ -81,7 +81,7 @@ # define fseeko _fseek # define ftello _ftell # define PRId64 "lld" -#elif defined (__DJGPP__) +#elif defined (__DJGPP__) || defined(__PS3__) && !defined(__PSL1GHT__) # define fseeko fseek # define ftello ftell # define PRId64 "lld" diff --git a/atari800/src/input.c b/atari800/src/input.c index 69a6edb..5fcf69e 100644 --- a/atari800/src/input.c +++ b/atari800/src/input.c @@ -48,7 +48,7 @@ #include #endif -#ifdef DREAMCAST +#if defined (DREAMCAST) || defined(__LIBRETRO__) extern int Atari_POT(int); #else #define Atari_POT(x) 228 @@ -68,6 +68,12 @@ int INPUT_joy_5200_min = 6; int INPUT_joy_5200_center = 114; int INPUT_joy_5200_max = 220; +#if defined(__LIBRETRO__) +int INPUT_digital_5200_min = 6; +int INPUT_digital_5200_center = 114; +int INPUT_digital_5200_max = 220; +#endif + int INPUT_cx85 = 0; int INPUT_mouse_mode = INPUT_MOUSE_OFF; @@ -625,15 +631,38 @@ void INPUT_Frame(void) } else { for (i = 0; i < 4; i++) { -#ifdef DREAMCAST +#if defined (DREAMCAST) /* first get analog js data */ POKEY_POT_input[2 * i] = Atari_POT(2 * i); /* x */ POKEY_POT_input[2 * i + 1] = Atari_POT(2 * i + 1); /* y */ if (POKEY_POT_input[2 * i] != INPUT_joy_5200_center || POKEY_POT_input[2 * i + 1] != INPUT_joy_5200_center) continue; - /* if analog js is unused, alternatively try keypad */ #endif +#if defined(__LIBRETRO__) + /* first get analog js data */ + POKEY_POT_input[2 * i] = Atari_POT(2 * i); /* x */ + POKEY_POT_input[2 * i + 1] = Atari_POT(2 * i + 1); /* y */ + if (POKEY_POT_input[2 * i] != INPUT_joy_5200_center + || POKEY_POT_input[2 * i + 1] != INPUT_joy_5200_center) + continue; + + /* if analog js is unused, alternatively try keypad */ + if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_LEFT)) == 0) + POKEY_POT_input[2 * i] = INPUT_digital_5200_min; + else if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_RIGHT)) == 0) + POKEY_POT_input[2 * i] = INPUT_digital_5200_max; + else + POKEY_POT_input[2 * i] = INPUT_digital_5200_center; + if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_FORWARD)) == 0) + POKEY_POT_input[2 * i + 1] = INPUT_digital_5200_min; + else if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_BACK)) == 0) + POKEY_POT_input[2 * i + 1] = INPUT_digital_5200_max; + else + POKEY_POT_input[2 * i + 1] = INPUT_digital_5200_center; + } +#else + /* if analog js is unused, alternatively try keypad */ if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_LEFT)) == 0) POKEY_POT_input[2 * i] = INPUT_joy_5200_min; else if ((STICK[i] & (INPUT_STICK_CENTRE ^ INPUT_STICK_RIGHT)) == 0) @@ -647,6 +676,7 @@ void INPUT_Frame(void) else POKEY_POT_input[2 * i + 1] = INPUT_joy_5200_center; } +#endif } /* handle mouse */ diff --git a/atari800/src/memory.c b/atari800/src/memory.c index e816176..e64d465 100644 --- a/atari800/src/memory.c +++ b/atari800/src/memory.c @@ -31,7 +31,7 @@ #include "antic.h" #include "cpu.h" #include "cartridge.h" -#include "emuos.h" +#include "roms/altirra_5200_os.h" #include "esc.h" #include "gtia.h" #include "log.h" @@ -339,6 +339,351 @@ void MEMORY_InitialiseMachine(void) #ifndef BASIC +#if defined(__LIBRETRO__) +void Retro_MEMORY_StateSave(UBYTE SaveVerbose) +{ + int temp; + UBYTE byte; + + /* Axlon/Mosaic for 400/800 */ + if (Atari800_machine_type == Atari800_MACHINE_800) { + Retro_SaveINT(&MEMORY_axlon_num_banks, 1); + if (MEMORY_axlon_num_banks > 0) { + Retro_SaveINT(&axlon_curbank, 1); + Retro_SaveINT(&MEMORY_axlon_0f_mirror, 1); + Retro_SaveUBYTE(axlon_ram, MEMORY_axlon_num_banks * 0x4000); + } + Retro_SaveINT(&mosaic_current_num_banks, 1); + if (mosaic_current_num_banks > 0) { + Retro_SaveINT(&mosaic_curbank, 1); + Retro_SaveUBYTE(mosaic_ram, mosaic_current_num_banks * 0x1000); + } + } + + /* Save amount of base RAM in kilobytes. */ + temp = MEMORY_ram_size > 64 ? 64 : MEMORY_ram_size; + Retro_SaveINT(&temp, 1); + Retro_SaveUBYTE(&MEMORY_mem[0], 65536); +#ifndef PAGED_ATTRIB + Retro_SaveUBYTE(&MEMORY_attrib[0], 65536); +#else + { + /* I assume here that consecutive calls to StateSav_SaveUBYTE() + are equivalent to a single call with all the values + (i.e. StateSav_SaveUBYTE() doesn't write any headers). */ + UBYTE attrib_page[256]; + int i; + for (i = 0; i < 256; i++) { + if (MEMORY_writemap[i] == NULL) + memset(attrib_page, MEMORY_RAM, 256); + else if (MEMORY_writemap[i] == MEMORY_ROM_PutByte) + memset(attrib_page, MEMORY_ROM, 256); + else if (i == 0x4f || i == 0x5f || i == 0x8f || i == 0x9f) { + /* special case: Bounty Bob bank switching registers */ + memset(attrib_page, MEMORY_ROM, 256); + attrib_page[0xf6] = MEMORY_HARDWARE; + attrib_page[0xf7] = MEMORY_HARDWARE; + attrib_page[0xf8] = MEMORY_HARDWARE; + attrib_page[0xf9] = MEMORY_HARDWARE; + } + else { + memset(attrib_page, MEMORY_HARDWARE, 256); + } + Retro_SaveUBYTE(&attrib_page[0], 256); + } + } +#endif + + if (Atari800_machine_type == Atari800_MACHINE_XLXE) { + if (SaveVerbose != 0) + Retro_SaveUBYTE(&MEMORY_basic[0], 8192); + Retro_SaveUBYTE(&under_cartA0BF[0], 8192); + + if (SaveVerbose != 0) + Retro_SaveUBYTE(&MEMORY_os[0], 16384); + Retro_SaveUBYTE(&under_atarixl_os[0], 16384); + if (SaveVerbose != 0) + Retro_SaveUBYTE(MEMORY_xegame, 0x2000); + } + + /* Save amount of XE RAM in 16KB banks. */ + temp = (MEMORY_ram_size - 64) / 16; + if (temp < 0) + temp = 0; + Retro_SaveINT(&temp, 1); + if (MEMORY_ram_size == MEMORY_RAM_320_RAMBO || MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP) { + /* Save specific banking type. */ + temp = MEMORY_ram_size - 320; + Retro_SaveINT(&temp, 1); + } + byte = PIA_PORTB | PIA_PORTB_mask; + Retro_SaveUBYTE(&byte, 1); + + Retro_SaveINT(&MEMORY_cartA0BF_enabled, 1); + + if (MEMORY_ram_size > 64) { + Retro_SaveUBYTE(&atarixe_memory[0], atarixe_memory_size); + if (ANTIC_xe_ptr != NULL && MEMORY_selftest_enabled) + Retro_SaveUBYTE(antic_bank_under_selftest, 0x800); + } + + /* Simius XL/XE MapRAM expansion */ + if (Atari800_machine_type == Atari800_MACHINE_XLXE && MEMORY_ram_size > 20) { + Retro_SaveINT(&MEMORY_enable_mapram, 1); + if (MEMORY_enable_mapram) { + Retro_SaveUBYTE(mapram_memory, 0x800); + } + } +} + +void Retro_MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion) +{ + int base_ram_kb; + int num_xe_banks; + UBYTE portb; + + /* Axlon/Mosaic for 400/800 */ + if (Atari800_machine_type == Atari800_MACHINE_800 && StateVersion >= 5) { + Retro_ReadINT(&MEMORY_axlon_num_banks, 1); + if (MEMORY_axlon_num_banks > 0) { + Retro_ReadINT(&axlon_curbank, 1); + if (StateVersion < 7) { + /* Read bank mask, then increase by 1 to get number of banks. */ + Retro_ReadINT(&MEMORY_axlon_num_banks, 1); + ++MEMORY_axlon_num_banks; + } + Retro_ReadINT(&MEMORY_axlon_0f_mirror, 1); + if (StateVersion < 7) { + int temp; + /* Ignore saved RAM size - can be derived. */ + Retro_ReadINT(&temp, 1); + } + alloc_axlon_memory(); + Retro_ReadUBYTE(axlon_ram, MEMORY_axlon_num_banks * 0x4000); + } + Retro_ReadINT(&MEMORY_mosaic_num_banks, 1); + if (MEMORY_mosaic_num_banks > 0) { + Retro_ReadINT(&mosaic_curbank, 1); + if (StateVersion < 7) { + int temp; + /* Read max bank number, then increase by 1 to get number of banks. */ + Retro_ReadINT(&MEMORY_mosaic_num_banks, 1); + ++MEMORY_mosaic_num_banks; + Retro_ReadINT(&temp, 1); /* Ignore Mosaic RAM size - can be derived. */ + } + alloc_mosaic_memory(); + Retro_ReadUBYTE(mosaic_ram, mosaic_current_num_banks * 0x1000); + } + } + + if (StateVersion >= 7) + /* Read amount of base RAM in kilobytes. */ + Retro_ReadINT(&base_ram_kb, 1); + Retro_ReadUBYTE(&MEMORY_mem[0], 65536); +#ifndef PAGED_ATTRIB + Retro_ReadUBYTE(&MEMORY_attrib[0], 65536); +#else + { + UBYTE attrib_page[256]; + int i; + for (i = 0; i < 256; i++) { + Retro_ReadUBYTE(&attrib_page[0], 256); + /* note: 0x40 is intentional here: + we want ROM on page 0xd1 if H: patches are enabled */ + switch (attrib_page[0x40]) { + case MEMORY_RAM: + MEMORY_readmap[i] = NULL; + MEMORY_writemap[i] = NULL; + break; + case MEMORY_ROM: + if (i != 0xd1 && attrib_page[0xf6] == MEMORY_HARDWARE) { + if (i == 0x4f || i == 0x8f) { + MEMORY_readmap[i] = CARTRIDGE_BountyBob1GetByte; + MEMORY_writemap[i] = CARTRIDGE_BountyBob1PutByte; + } + else if (i == 0x5f || i == 0x9f) { + MEMORY_readmap[i] = CARTRIDGE_BountyBob2GetByte; + MEMORY_writemap[i] = CARTRIDGE_BountyBob2PutByte; + } + else if (i == 0xbf) { + MEMORY_readmap[i] = CARTRIDGE_5200SuperCartGetByte; + MEMORY_writemap[i] = CARTRIDGE_5200SuperCartPutByte; + } + /* else something's wrong, so we keep current values */ + } + else { + MEMORY_readmap[i] = NULL; + MEMORY_writemap[i] = MEMORY_ROM_PutByte; + } + break; + case MEMORY_HARDWARE: + switch (i) { + case 0xc0: + case 0xd0: + MEMORY_readmap[i] = GTIA_GetByte; + MEMORY_writemap[i] = GTIA_PutByte; + break; + case 0xd1: + MEMORY_readmap[i] = PBI_D1GetByte; + MEMORY_writemap[i] = PBI_D1PutByte; + break; + case 0xd2: + case 0xe8: + case 0xeb: + MEMORY_readmap[i] = POKEY_GetByte; + MEMORY_writemap[i] = POKEY_PutByte; + break; + case 0xd3: + MEMORY_readmap[i] = PIA_GetByte; + MEMORY_writemap[i] = PIA_PutByte; + break; + case 0xd4: + MEMORY_readmap[i] = ANTIC_GetByte; + MEMORY_writemap[i] = ANTIC_PutByte; + break; + case 0xd5: + MEMORY_readmap[i] = CARTRIDGE_GetByte; + MEMORY_writemap[i] = CARTRIDGE_PutByte; + break; + case 0xd6: + MEMORY_readmap[i] = PBI_D6GetByte; + MEMORY_writemap[i] = PBI_D6PutByte; + break; + case 0xd7: + MEMORY_readmap[i] = PBI_D7GetByte; + MEMORY_writemap[i] = PBI_D7PutByte; + break; + case 0xff: + if (MEMORY_mosaic_num_banks > 0) MEMORY_writemap[0xff] = MosaicPutByte; + break; + case 0xcf: + if (MEMORY_axlon_num_banks > 0) MEMORY_writemap[0xcf] = AxlonPutByte; + break; + case 0x0f: + if (MEMORY_axlon_num_banks > 0 && MEMORY_axlon_0f_mirror) MEMORY_writemap[0x0f] = AxlonPutByte; + break; + default: + /* something's wrong, so we keep current values */ + break; + } + break; + default: + /* something's wrong, so we keep current values */ + break; + } + } + } +#endif + + if (Atari800_machine_type == Atari800_MACHINE_XLXE) { + if (SaveVerbose) + Retro_ReadUBYTE(&MEMORY_basic[0], 8192); + Retro_ReadUBYTE(&under_cartA0BF[0], 8192); + + if (SaveVerbose) + Retro_ReadUBYTE(&MEMORY_os[0], 16384); + Retro_ReadUBYTE(&under_atarixl_os[0], 16384); + if (StateVersion >= 7 && SaveVerbose) + Retro_ReadUBYTE(MEMORY_xegame, 0x2000); + } + + if (StateVersion >= 7) { + /* Read amount of XE RAM in 16KB banks. */ + Retro_ReadINT(&num_xe_banks, 1); + /* Compute value of MEMORY_ram_size. */ + MEMORY_ram_size = base_ram_kb + num_xe_banks * 16; + if (MEMORY_ram_size == 320) { + /* There are 2 different memory mappings for 320 KB. */ + /* In savestate version <= 6 this variable is read in PIA_StateRead. */ + int xe_type; + Retro_ReadINT(&xe_type, 1); + MEMORY_ram_size += xe_type; + } + if (!MEMORY_SizeValid(MEMORY_ram_size)) { + MEMORY_ram_size = 64; + Log_print("Warning: Bad RAM size read in from state save, defaulting to 64 KB"); + } + + /* Read PORTB and set variables that are based on it. */ + Retro_ReadUBYTE(&portb, 1); + MEMORY_xe_bank = 0; + if (MEMORY_ram_size > 64 && (portb & 0x30) != 0x30) { + switch (MEMORY_ram_size) { + case 128: + MEMORY_xe_bank = ((portb & 0x0c) >> 2) + 1; + break; + case 192: + MEMORY_xe_bank = (((portb & 0x0c) + ((portb & 0x40) >> 2)) >> 2) + 1; + break; + case MEMORY_RAM_320_RAMBO: + MEMORY_xe_bank = (((portb & 0x0c) + ((portb & 0x60) >> 1)) >> 2) + 1; + break; + case MEMORY_RAM_320_COMPY_SHOP: + MEMORY_xe_bank = (((portb & 0x0c) + ((portb & 0xc0) >> 2)) >> 2) + 1; + break; + case 576: + MEMORY_xe_bank = (((portb & 0x0e) + ((portb & 0x60) >> 1)) >> 1) + 1; + break; + case 1088: + MEMORY_xe_bank = (((portb & 0x0e) + ((portb & 0xe0) >> 1)) >> 1) + 1; + break; + } + } + /* In savestate version <= 6 this variable is read in PIA_StateRead. */ + MEMORY_selftest_enabled = (portb & 0x81) == 0x01 + && !((portb & 0x30) != 0x30 && MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP) + && !((portb & 0x10) == 0 && MEMORY_ram_size == 1088); + + Retro_ReadINT(&MEMORY_cartA0BF_enabled, 1); + if (Atari800_machine_type == Atari800_MACHINE_XLXE) { + GTIA_TRIG[3] = MEMORY_cartA0BF_enabled; + if (MEMORY_cartA0BF_enabled == 0 && (GTIA_GRACTL & 4)) + GTIA_TRIG_latch[3] = 0; + } + } + ANTIC_xe_ptr = NULL; + AllocXEMemory(); + if (MEMORY_ram_size > 64) { + Retro_ReadUBYTE(&atarixe_memory[0], atarixe_memory_size); + /* a hack that makes state files compatible with previous versions: + for 130 XE there's written 192 KB of unused data */ + if (MEMORY_ram_size == 128 && StateVersion <= 6) { + UBYTE buffer[256]; + int i; + for (i = 0; i < 192 * 4; i++) + Retro_ReadUBYTE(&buffer[0], 256); + } + if (StateVersion >= 7 && (MEMORY_ram_size == 128 || MEMORY_ram_size == MEMORY_RAM_320_COMPY_SHOP)) { + switch (portb & 0x30) { + case 0x20: /* ANTIC: base, CPU: extended */ + ANTIC_xe_ptr = atarixe_memory; + break; + case 0x10: /* ANTIC: extended, CPU: base */ + ANTIC_xe_ptr = atarixe_memory + (MEMORY_xe_bank << 14); + break; + default: /* ANTIC same as CPU */ + ANTIC_xe_ptr = NULL; + break; + } + + if (ANTIC_xe_ptr != NULL && MEMORY_selftest_enabled) + /* Also read ANTIC-visible memory shadowed by Self Test. */ + Retro_ReadUBYTE(antic_bank_under_selftest, 0x800); + + } + } + + /* Simius XL/XE MapRAM expansion */ + if (StateVersion >= 7 && Atari800_machine_type == Atari800_MACHINE_XLXE && MEMORY_ram_size > 20) { + Retro_ReadINT(&MEMORY_enable_mapram, 1); + AllocMapRAM(); + if (mapram_memory != NULL) { + Retro_ReadUBYTE(mapram_memory, 0x800); + } + } +} +#endif /* __LIBRETRO__ */ + void MEMORY_StateSave(UBYTE SaveVerbose) { int temp; @@ -504,6 +849,10 @@ void MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion) MEMORY_readmap[i] = CARTRIDGE_BountyBob2GetByte; MEMORY_writemap[i] = CARTRIDGE_BountyBob2PutByte; } + else if (i == 0xbf) { + MEMORY_readmap[i] = CARTRIDGE_5200SuperCartGetByte; + MEMORY_writemap[i] = CARTRIDGE_5200SuperCartPutByte; + } /* else something's wrong, so we keep current values */ } else { @@ -1054,9 +1403,9 @@ void MEMORY_CartA0bfEnable(void) void MEMORY_GetCharset(UBYTE *cs) { /* copy font, but change screencode order to ATASCII order */ - memcpy(cs, emuos_h + 0x200, 0x100); /* control chars */ - memcpy(cs + 0x100, emuos_h, 0x200); /* !"#$..., uppercase letters */ - memcpy(cs + 0x300, emuos_h + 0x300, 0x100); /* lowercase letters */ + memcpy(cs, ROM_altirra_5200_os + 0x200, 0x100); /* control chars */ + memcpy(cs + 0x100, ROM_altirra_5200_os, 0x200); /* !"#$..., uppercase letters */ + memcpy(cs + 0x300, ROM_altirra_5200_os + 0x300, 0x100); /* lowercase letters */ } #ifndef PAGED_MEM @@ -1068,13 +1417,16 @@ UBYTE MEMORY_HwGetByte(UWORD addr, int no_side_effects) case 0x8f00: if (!no_side_effects) CARTRIDGE_BountyBob1(addr); - byte = 0; + byte = MEMORY_dGetByte(addr); break; case 0x5f00: case 0x9f00: if (!no_side_effects) CARTRIDGE_BountyBob2(addr); - byte = 0; + byte = MEMORY_dGetByte(addr); + break; + case 0xbf00: + byte = CARTRIDGE_5200SuperCartGetByte(addr, no_side_effects); break; case 0xd000: /* GTIA */ case 0xc000: /* GTIA - 5200 */ @@ -1153,6 +1505,9 @@ void MEMORY_HwPutByte(UWORD addr, UBYTE byte) case 0x9f00: CARTRIDGE_BountyBob2(addr); break; + case 0xbf00: + CARTRIDGE_5200SuperCartPutByte(addr, byte); + break; case 0xd000: /* GTIA */ case 0xc000: /* GTIA - 5200 */ case 0xc100: /* GTIA - 5200 */ diff --git a/atari800/src/memory.h b/atari800/src/memory.h index 7518121..16e9c4a 100644 --- a/atari800/src/memory.h +++ b/atari800/src/memory.h @@ -109,6 +109,12 @@ int MEMORY_SizeValid(int size); void MEMORY_InitialiseMachine(void); void MEMORY_StateSave(UBYTE SaveVerbose); void MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion); + +#if defined(__LIBRETRO__) +void Retro_MEMORY_StateSave(UBYTE SaveVerbose); +void Retro_MEMORY_StateRead(UBYTE SaveVerbose, UBYTE StateVersion); +#endif + void MEMORY_CopyFromMem(UWORD from, UBYTE *to, int size); void MEMORY_CopyToMem(const UBYTE *from, UWORD to, int size); void MEMORY_HandlePORTB(UBYTE byte, UBYTE oldval); diff --git a/atari800/src/mzpokeysnd.c b/atari800/src/mzpokeysnd.c index 3805853..0be8d72 100644 --- a/atari800/src/mzpokeysnd.c +++ b/atari800/src/mzpokeysnd.c @@ -264,6 +264,11 @@ typedef struct stPokeyState } PokeyState; +static struct { + double s16; + double s8; +} volume; + PokeyState pokey_states[NPOKEYS]; /* Forward declarations for ResetPokeyState */ @@ -1421,6 +1426,10 @@ int MZPOKEYSND_Init(ULONG freq17, int playback_freq, UBYTE num_pokeys, #ifdef SYNCHRONIZED_SOUND init_syncsound(); #endif + + volume.s8 = POKEYSND_volume * 0xff / 256.0; + volume.s16 = POKEYSND_volume * 0xffff / 256.0; + return 0; /* OK */ } @@ -2341,16 +2350,16 @@ static void mzpokeysnd_process_8(void* sndbuffer, int sndn) #endif #ifdef VOL_ONLY_SOUND - buffer[0] = (UBYTE)floor((generate_sample(pokey_states) + POKEYSND_sampout - MAX_SAMPLE / 2.0) - * (255.0 / MAX_SAMPLE / 4 * M_PI * 0.95) + 128 + 0.5 + 0.5 * rand() / RAND_MAX - 0.25); + buffer[0] = (UBYTE)floor((generate_sample(pokey_states) + POKEYSND_sampout) + * (255.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95) + 128 + 0.5 + 0.5 * rand() / RAND_MAX - 0.25); #else - buffer[0] = (UBYTE)floor((generate_sample(pokey_states) - MAX_SAMPLE / 2.0) - * (255.0 / MAX_SAMPLE / 4 * M_PI * 0.95) + 128 + 0.5 + 0.5 * rand() / RAND_MAX - 0.25); + buffer[0] = (UBYTE)floor(generate_sample(pokey_states) + * (255.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95) + 128 + 0.5 + 0.5 * rand() / RAND_MAX - 0.25); #endif for(i=1; i= 8) { + Retro_ReadINT(&temp, 1); + set_CA2(temp); + Retro_ReadINT(&PIA_CA2_negpending, 1); + Retro_ReadINT(&PIA_CA2_pospending, 1); + Retro_ReadINT(&temp, 1); + set_CB2(temp); + Retro_ReadINT(&PIA_CB2_negpending, 1); + Retro_ReadINT(&PIA_CB2_pospending, 1); + update_PIA_IRQ(); + } +} +#endif /* __LIBRETRO__ */ + void PIA_StateSave(void) { StateSav_SaveUBYTE( &PIA_PACTL, 1 ); diff --git a/atari800/src/pia.h b/atari800/src/pia.h index a86dd24..6524a5e 100644 --- a/atari800/src/pia.h +++ b/atari800/src/pia.h @@ -26,4 +26,9 @@ void PIA_PutByte(UWORD addr, UBYTE byte); void PIA_StateSave(void); void PIA_StateRead(UBYTE version); +#if defined(__LIBRETRO__) +void Retro_PIA_StateSave(void); +void Retro_PIA_StateRead(UBYTE version); +#endif + #endif /* PIA_H_ */ diff --git a/atari800/src/pokey.c b/atari800/src/pokey.c index b1f4440..bb9587d 100644 --- a/atari800/src/pokey.c +++ b/atari800/src/pokey.c @@ -634,6 +634,80 @@ static void Update_Counter(int chan_mask) #ifndef BASIC +#if defined(__LIBRETRO__) +void Retro_POKEY_StateSave(void) +{ + int shift_key = 0; + int keypressed = 0; + UWORD random_scanline_counter_lo; + UWORD random_scanline_counter_hi; + + Retro_SaveUBYTE(&POKEY_KBCODE, 1); + Retro_SaveUBYTE(&POKEY_IRQST, 1); + Retro_SaveUBYTE(&POKEY_IRQEN, 1); + Retro_SaveUBYTE(&POKEY_SKCTL, 1); + + Retro_SaveINT(&shift_key, 1); + Retro_SaveINT(&keypressed, 1); + Retro_SaveINT(&POKEY_DELAYED_SERIN_IRQ, 1); + Retro_SaveINT(&POKEY_DELAYED_SEROUT_IRQ, 1); + Retro_SaveINT(&POKEY_DELAYED_XMTDONE_IRQ, 1); + + Retro_SaveUBYTE(&POKEY_AUDF[0], 4); + Retro_SaveUBYTE(&POKEY_AUDC[0], 4); + Retro_SaveUBYTE(&POKEY_AUDCTL[0], 1); + + Retro_SaveINT(&POKEY_DivNIRQ[0], 4); + Retro_SaveINT(&POKEY_DivNMax[0], 4); + Retro_SaveINT(&POKEY_Base_mult[0], 1); + + // Store the random number generator for runahead and netplay. It's not seed based on the Atari like it is on other systems + random_scanline_counter_lo = random_scanline_counter & 0xFFFF; + random_scanline_counter_hi = (random_scanline_counter >> 16) & 0xFFFF; + + Retro_SaveUWORD(&random_scanline_counter_lo, 1); + Retro_SaveUWORD(&random_scanline_counter_hi, 1); +} + +void Retro_POKEY_StateRead(void) +{ + int i, shift_key, keypressed; + UWORD random_scanline_counter_lo = 0; + UWORD random_scanline_counter_hi = 0; + + Retro_ReadUBYTE(&POKEY_KBCODE, 1); + Retro_ReadUBYTE(&POKEY_IRQST, 1); + Retro_ReadUBYTE(&POKEY_IRQEN, 1); + Retro_ReadUBYTE(&POKEY_SKCTL, 1); + + Retro_ReadINT(&shift_key, 1); + Retro_ReadINT(&keypressed, 1); + Retro_ReadINT(&POKEY_DELAYED_SERIN_IRQ, 1); + Retro_ReadINT(&POKEY_DELAYED_SEROUT_IRQ, 1); + Retro_ReadINT(&POKEY_DELAYED_XMTDONE_IRQ, 1); + + Retro_ReadUBYTE(&POKEY_AUDF[0], 4); + Retro_ReadUBYTE(&POKEY_AUDC[0], 4); + Retro_ReadUBYTE(&POKEY_AUDCTL[0], 1); + for (i = 0; i < 4; i++) { + POKEY_PutByte((UWORD)(POKEY_OFFSET_AUDF1 + i * 2), POKEY_AUDF[i]); + POKEY_PutByte((UWORD)(POKEY_OFFSET_AUDC1 + i * 2), POKEY_AUDC[i]); + } + POKEY_PutByte(POKEY_OFFSET_AUDCTL, POKEY_AUDCTL[0]); + + Retro_ReadINT(&POKEY_DivNIRQ[0], 4); + Retro_ReadINT(&POKEY_DivNMax[0], 4); + Retro_ReadINT(&POKEY_Base_mult[0], 1); + + Retro_ReadUWORD(&random_scanline_counter_lo, 1); + Retro_ReadUWORD(&random_scanline_counter_hi, 1); + + // Restore the random number generator for runahead and netplay. It's not seed based on the Atari like it is on other systems + random_scanline_counter = (random_scanline_counter_hi << 16) | + random_scanline_counter_lo; +} +#endif /* __LIBRETRO__ */ + void POKEY_StateSave(void) { int shift_key = 0; diff --git a/atari800/src/pokey.h b/atari800/src/pokey.h index b4fa847..7581378 100644 --- a/atari800/src/pokey.h +++ b/atari800/src/pokey.h @@ -63,6 +63,11 @@ void POKEY_Scanline(void); void POKEY_StateSave(void); void POKEY_StateRead(void); +#if defined(__LIBRETRO__) +void Retro_POKEY_StateSave(void); +void Retro_POKEY_StateRead(void); +#endif + #endif /* CONSTANT DEFINITIONS */ diff --git a/atari800/src/pokeysnd.c b/atari800/src/pokeysnd.c index 8f8e1c5..a77c37e 100644 --- a/atari800/src/pokeysnd.c +++ b/atari800/src/pokeysnd.c @@ -1,1377 +1,1397 @@ -/* - * pokeysnd.c - POKEY sound chip emulation, v2.4 - * - * Copyright (C) 1996-1998 Ron Fries - * Copyright (C) 1998-2014 Atari800 development team (see DOC/CREDITS) - * - * This file is part of the Atari800 emulator project which emulates - * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. - * - * Atari800 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. - * - * Atari800 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 Atari800; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "config.h" -#include -#include - -#ifdef ASAP /* external project, see http://asap.sf.net */ -#include "asap_internal.h" -#else -#include "atari.h" -#ifndef __PLUS -#include "sndsave.h" -#else -#include "sound_win.h" -#endif -#endif -#include "mzpokeysnd.h" -#include "pokeysnd.h" -#if defined(PBI_XLD) || defined (VOICEBOX) -#include "votraxsnd.h" -#endif -#include "antic.h" -#include "gtia.h" -#include "util.h" - -#ifdef WORDS_UNALIGNED_OK -# define READ_U32(x) (*(ULONG *) (x)) -# define WRITE_U32(x, d) (*(ULONG *) (x) = (d)) -#else -# ifdef WORDS_BIGENDIAN -# define READ_U32(x) (((*(unsigned char *)(x)) << 24) | ((*((unsigned char *)(x) + 1)) << 16) | \ - ((*((unsigned char *)(x) + 2)) << 8) | ((*((unsigned char *)(x) + 3)))) -# define WRITE_U32(x, d) \ - { \ - ULONG i = d; \ - (*(unsigned char *) (x)) = (((i) >> 24) & 255); \ - (*((unsigned char *) (x) + 1)) = (((i) >> 16) & 255); \ - (*((unsigned char *) (x) + 2)) = (((i) >> 8) & 255); \ - (*((unsigned char *) (x) + 3)) = ((i) & 255); \ - } -# else -# define READ_U32(x) ((*(unsigned char *) (x)) | ((*((unsigned char *) (x) + 1)) << 8) | \ - ((*((unsigned char *) (x) + 2)) << 16) | ((*((unsigned char *) (x) + 3)) << 24)) -# define WRITE_U32(x, d) \ - { \ - ULONG i = d; \ - (*(unsigned char *)(x)) = ((i) & 255); \ - (*((unsigned char *)(x) + 1)) = (((i) >> 8) & 255); \ - (*((unsigned char *)(x) + 2)) = (((i) >> 16) & 255); \ - (*((unsigned char *)(x) + 3)) = (((i) >> 24) & 255); \ - } -# endif -#endif - -/* GLOBAL VARIABLE DEFINITIONS */ - -/* number of pokey chips currently emulated */ -static UBYTE Num_pokeys; - -static UBYTE pokeysnd_AUDV[4 * POKEY_MAXPOKEYS]; /* Channel volume - derived */ - -static UBYTE Outbit[4 * POKEY_MAXPOKEYS]; /* current state of the output (high or low) */ - -static UBYTE Outvol[4 * POKEY_MAXPOKEYS]; /* last output volume for each channel */ - -/* Initialize the bit patterns for the polynomials. */ - -/* The 4bit and 5bit patterns are the identical ones used in the pokey chip. */ -/* Though the patterns could be packed with 8 bits per byte, using only a */ -/* single bit per byte keeps the math simple, which is important for */ -/* efficient processing. */ - -static UBYTE bit4[POKEY_POLY4_SIZE] = -#ifndef POKEY23_POLY -{1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0}; /* new table invented by Perry */ -#else -{1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}; /* original POKEY 2.3 table */ -#endif - -static UBYTE bit5[POKEY_POLY5_SIZE] = -#ifndef POKEY23_POLY -{1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0}; -#else -{0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1}; -#endif - -static ULONG P4 = 0, /* Global position pointer for the 4-bit POLY array */ - P5 = 0, /* Global position pointer for the 5-bit POLY array */ - P9 = 0, /* Global position pointer for the 9-bit POLY array */ - P17 = 0; /* Global position pointer for the 17-bit POLY array */ - -static ULONG Div_n_cnt[4 * POKEY_MAXPOKEYS], /* Divide by n counter. one for each channel */ - Div_n_max[4 * POKEY_MAXPOKEYS]; /* Divide by n maximum, one for each channel */ - -static ULONG Samp_n_max, /* Sample max. For accuracy, it is *256 */ - Samp_n_cnt[2]; /* Sample cnt. */ - -#ifdef INTERPOLATE_SOUND -static UWORD last_val = 0; /* last output value */ -#ifdef STEREO_SOUND -static UWORD last_val2 = 0; /* last output value */ -#endif -#endif - -/* Volume only emulations declarations */ -#ifdef VOL_ONLY_SOUND - -int POKEYSND_sampbuf_val[POKEYSND_SAMPBUF_MAX]; /* volume values */ -int POKEYSND_sampbuf_cnt[POKEYSND_SAMPBUF_MAX]; /* relative start time */ -int POKEYSND_sampbuf_ptr = 0; /* pointer to sampbuf */ -int POKEYSND_sampbuf_rptr = 0; /* pointer to read from sampbuf */ -int POKEYSND_sampbuf_last = 0; /* last absolute time */ -int POKEYSND_sampbuf_AUDV[4 * POKEY_MAXPOKEYS]; /* prev. channel volume */ -int POKEYSND_sampbuf_lastval = 0; /* last volume */ -int POKEYSND_sampout; /* last out volume */ -int POKEYSND_samp_freq; -int POKEYSND_samp_consol_val = 0; /* actual value of console sound */ -#ifdef STEREO_SOUND -static int sampbuf_val2[POKEYSND_SAMPBUF_MAX]; /* volume values */ -static int sampbuf_cnt2[POKEYSND_SAMPBUF_MAX]; /* relative start time */ -static int sampbuf_ptr2 = 0; /* pointer to sampbuf */ -static int sampbuf_rptr2 = 0; /* pointer to read from sampbuf */ -static int sampbuf_last2 = 0; /* last absolute time */ -static int sampbuf_lastval2 = 0; /* last volume */ -static int sampout2; /* last out volume */ -#endif -#endif /* VOL_ONLY_SOUND */ - -static ULONG snd_freq17 = POKEYSND_FREQ_17_EXACT; -int POKEYSND_playback_freq = 44100; -UBYTE POKEYSND_num_pokeys = 1; -int POKEYSND_snd_flags = 0; -static int mz_quality = 0; /* default quality for mzpokeysnd */ -#ifdef __PLUS -int mz_clear_regs = 0; -#endif - -int POKEYSND_enable_new_pokey = TRUE; -int POKEYSND_bienias_fix = TRUE; /* when TRUE, high frequencies get emulated: better sound but slower */ -#if defined(__PLUS) && !defined(_WX_) -#define BIENIAS_FIX (g_Sound.nBieniasFix) -#else -#define BIENIAS_FIX POKEYSND_bienias_fix -#endif -#ifndef ASAP -int POKEYSND_stereo_enabled = FALSE; -#endif - -/* multiple sound engine interface */ -static void pokeysnd_process_8(void *sndbuffer, int sndn); -static void pokeysnd_process_16(void *sndbuffer, int sndn); -static void null_pokey_process(void *sndbuffer, int sndn) {} -void (*POKEYSND_Process_ptr)(void *sndbuffer, int sndn) = null_pokey_process; - -static void Update_pokey_sound_rf(UWORD, UBYTE, UBYTE, UBYTE); -static void null_pokey_sound(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) {} -void (*POKEYSND_Update_ptr) (UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) - = null_pokey_sound; - -#ifdef SERIO_SOUND -static void Update_serio_sound_rf(int out, UBYTE data); -static void null_serio_sound(int out, UBYTE data) {} -void (*POKEYSND_UpdateSerio)(int out, UBYTE data) = null_serio_sound; -int POKEYSND_serio_sound_enabled = 1; -#endif - -#ifdef CONSOLE_SOUND -static void Update_consol_sound_rf(int set); -static void null_consol_sound(int set) {} -void (*POKEYSND_UpdateConsol_ptr)(int set) = null_consol_sound; -int POKEYSND_console_sound_enabled = 1; -#endif - -#ifdef VOL_ONLY_SOUND -static void Update_vol_only_sound_rf(void); -static void null_vol_only_sound(void) {} -void (*POKEYSND_UpdateVolOnly)(void) = null_vol_only_sound; -#endif - -#ifdef SYNCHRONIZED_SOUND -UBYTE *POKEYSND_process_buffer = NULL; -unsigned int POKEYSND_process_buffer_length; -unsigned int POKEYSND_process_buffer_fill; -static unsigned int prev_update_tick; - -static void Generate_sync_rf(unsigned int num_ticks); -static void null_generate_sync(unsigned int num_ticks) {} -void (*POKEYSND_GenerateSync)(unsigned int num_ticks) = null_generate_sync; - -static double ticks_per_sample; -static double samp_pos; -static int speaker; -static int const CONSOLE_VOL = 32; -#endif /* SYNCHRONIZED_SOUND */ - -/*****************************************************************************/ -/* In my routines, I treat the sample output as another divide by N counter */ -/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ -/* which has 8 binary digits to the right of the decimal point. I use a two */ -/* byte array to give me a minimum of 40 bits, and then use pointer math to */ -/* reference either the 24.8 whole/fraction combination or the 32-bit whole */ -/* only number. This is mainly used to keep the math simple for */ -/* optimization. See below: */ -/* */ -/* Representation on little-endian machines: */ -/* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx */ -/* fraction whole whole whole whole unused unused unused */ -/* */ -/* Samp_n_cnt[0] gives me a 32-bit int 24 whole bits with 8 fractional bits, */ -/* while (ULONG *)((UBYTE *)(&Samp_n_cnt[0])+1) gives me the 32-bit whole */ -/* number only. */ -/* */ -/* Representation on big-endian machines: */ -/* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx.xxxxxxxx */ -/* unused unused unused whole whole whole whole fraction */ -/* */ -/* Samp_n_cnt[1] gives me a 32-bit int 24 whole bits with 8 fractional bits, */ -/* while (ULONG *)((UBYTE *)(&Samp_n_cnt[0])+3) gives me the 32-bit whole */ -/* number only. */ -/*****************************************************************************/ - - -/*****************************************************************************/ -/* Module: pokeysnd_init_rf() */ -/* Purpose: to handle the power-up initialization functions */ -/* these functions should only be executed on a cold-restart */ -/* */ -/* Author: Ron Fries */ -/* Date: January 1, 1997 */ -/* */ -/* Inputs: freq17 - the value for the '1.79MHz' Pokey audio clock */ -/* playback_freq - the playback frequency in samples per second */ -/* num_pokeys - specifies the number of pokey chips to be emulated */ -/* */ -/* Outputs: Adjusts local globals - no return value */ -/* */ -/*****************************************************************************/ - -static int pokeysnd_init_rf(ULONG freq17, int playback_freq, - UBYTE num_pokeys, int flags); - -#ifdef VOL_ONLY_SOUND -/* Initialise variables related to volume-only sound. */ -static void init_vol_only(void) -{ - POKEYSND_sampbuf_rptr = POKEYSND_sampbuf_ptr; - POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; - POKEYSND_sampbuf_lastval = 0; - POKEYSND_samp_consol_val = 0; -#ifdef STEREO_SOUND - sampbuf_rptr2 = sampbuf_ptr2; - sampbuf_last2 = ANTIC_CPU_CLOCK; - sampbuf_lastval2 = 0; -#endif /* STEREO_SOUND */ -} -#endif /* VOL_ONLY_SOUND */ - -int POKEYSND_DoInit(void) -{ - SndSave_CloseSoundFile(); - -#ifdef VOL_ONLY_SOUND - init_vol_only(); -#endif /* VOL_ONLY_SOUND */ - - if (POKEYSND_enable_new_pokey) - return MZPOKEYSND_Init(snd_freq17, POKEYSND_playback_freq, - POKEYSND_num_pokeys, POKEYSND_snd_flags, mz_quality -#ifdef __PLUS - , mz_clear_regs -#endif - ); - else - return pokeysnd_init_rf(snd_freq17, POKEYSND_playback_freq, - POKEYSND_num_pokeys, POKEYSND_snd_flags); -} - -int POKEYSND_Init(ULONG freq17, int playback_freq, UBYTE num_pokeys, - int flags -#ifdef __PLUS - , int clear_regs -#endif -) -{ - snd_freq17 = freq17; - POKEYSND_playback_freq = playback_freq; - POKEYSND_num_pokeys = num_pokeys; - POKEYSND_snd_flags = flags; -#ifdef __PLUS - mz_clear_regs = clear_regs; -#endif -#ifdef SYNCHRONIZED_SOUND - { - /* A single call to Atari800_Frame may emulate a bit more CPU ticks than the exact number of - ticks per frame (Atari800_tv_mode*114). So we add a few ticks to buffer size just to be safe. */ - unsigned int const surplus_ticks = 10; - double samples_per_frame = (double)POKEYSND_playback_freq/(Atari800_tv_mode == Atari800_TV_PAL ? Atari800_FPS_PAL : Atari800_FPS_NTSC); - unsigned int ticks_per_frame = Atari800_tv_mode*114; - unsigned int max_ticks_per_frame = ticks_per_frame + surplus_ticks; - double ticks_per_sample = (double)ticks_per_frame / samples_per_frame; - POKEYSND_process_buffer_length = POKEYSND_num_pokeys * (unsigned int)ceil((double)max_ticks_per_frame / ticks_per_sample) * ((POKEYSND_snd_flags & POKEYSND_BIT16) ? 2:1); - free(POKEYSND_process_buffer); - POKEYSND_process_buffer = (UBYTE *)Util_malloc(POKEYSND_process_buffer_length); - POKEYSND_process_buffer_fill = 0; - prev_update_tick = ANTIC_CPU_CLOCK; - } -#endif /* SYNCHRONIZED_SOUND */ - -#if defined(PBI_XLD) || defined (VOICEBOX) - VOTRAXSND_Init(playback_freq, num_pokeys, (flags & POKEYSND_BIT16)); -#endif - return POKEYSND_DoInit(); -} - -void POKEYSND_SetMzQuality(int quality) /* specially for win32, perhaps not needed? */ -{ - mz_quality = quality; -} - -void POKEYSND_Process(void *sndbuffer, int sndn) -{ - POKEYSND_Process_ptr(sndbuffer, sndn); -#if defined(PBI_XLD) || defined (VOICEBOX) - VOTRAXSND_Process(sndbuffer,sndn); -#endif -#if !defined(__PLUS) && !defined(ASAP) - SndSave_WriteToSoundFile((const unsigned char *)sndbuffer, sndn); -#endif -} - -#ifdef SYNCHRONIZED_SOUND -static void Update_synchronized_sound(void) -{ - POKEYSND_GenerateSync(ANTIC_CPU_CLOCK - prev_update_tick); - prev_update_tick = ANTIC_CPU_CLOCK; -} - -int POKEYSND_UpdateProcessBuffer(void) -{ - int sndn; - Update_synchronized_sound(); - sndn = POKEYSND_process_buffer_fill / ((POKEYSND_snd_flags & POKEYSND_BIT16) ? 2 : 1); - POKEYSND_process_buffer_fill = 0; - -#if defined(PBI_XLD) || defined (VOICEBOX) - VOTRAXSND_Process(POKEYSND_process_buffer, sndn); -#endif -#if !defined(__PLUS) && !defined(ASAP) - SndSave_WriteToSoundFile((const unsigned char *)POKEYSND_process_buffer, sndn); -#endif - return sndn; -} -#endif /* SYNCHRONIZED_SOUND */ - -#ifdef SYNCHRONIZED_SOUND -static void init_syncsound(void) -{ - double samples_per_frame = (double)POKEYSND_playback_freq/(Atari800_tv_mode == Atari800_TV_PAL ? Atari800_FPS_PAL : Atari800_FPS_NTSC); - unsigned int ticks_per_frame = Atari800_tv_mode*114; - ticks_per_sample = (double)ticks_per_frame / samples_per_frame; - samp_pos = 0.0; - POKEYSND_GenerateSync = Generate_sync_rf; - speaker = 0; -} -#endif /* SYNCHRONIZED_SOUND */ - -static int pokeysnd_init_rf(ULONG freq17, int playback_freq, - UBYTE num_pokeys, int flags) -{ - UBYTE chan; - - POKEYSND_Update_ptr = Update_pokey_sound_rf; -#ifdef SERIO_SOUND - POKEYSND_UpdateSerio = Update_serio_sound_rf; -#endif -#ifdef CONSOLE_SOUND - POKEYSND_UpdateConsol_ptr = Update_consol_sound_rf; -#endif -#ifdef VOL_ONLY_SOUND - POKEYSND_UpdateVolOnly = Update_vol_only_sound_rf; -#endif - - POKEYSND_Process_ptr = (flags & POKEYSND_BIT16) ? pokeysnd_process_16 : pokeysnd_process_8; - -#ifdef VOL_ONLY_SOUND - POKEYSND_samp_freq = playback_freq; -#endif - - /* start all of the polynomial counters at zero */ - P4 = 0; - P5 = 0; - P9 = 0; - P17 = 0; - - /* calculate the sample 'divide by N' value based on the playback freq. */ - Samp_n_max = ((ULONG) freq17 << 8) / playback_freq; - - Samp_n_cnt[0] = 0; /* initialize all bits of the sample */ - Samp_n_cnt[1] = 0; /* 'divide by N' counter */ - - for (chan = 0; chan < (POKEY_MAXPOKEYS * 4); chan++) { - Outvol[chan] = 0; - Outbit[chan] = 0; - Div_n_cnt[chan] = 0; - Div_n_max[chan] = 0x7fffffffL; - pokeysnd_AUDV[chan] = 0; -#ifdef VOL_ONLY_SOUND - POKEYSND_sampbuf_AUDV[chan] = 0; -#endif - } - - /* set the number of pokey chips currently emulated */ - Num_pokeys = num_pokeys; - -#ifdef SYNCHRONIZED_SOUND - init_syncsound(); -#endif - return 0; /* OK */ -} - - -/*****************************************************************************/ -/* Module: Update_pokey_sound_rf() */ -/* Purpose: To process the latest control values stored in the AUDF, AUDC, */ -/* and AUDCTL registers. It pre-calculates as much information as */ -/* possible for better performance. This routine has not been */ -/* optimized. */ -/* */ -/* Author: Ron Fries */ -/* Date: January 1, 1997 */ -/* */ -/* Inputs: addr - the address of the parameter to be changed */ -/* val - the new value to be placed in the specified address */ -/* gain - specified as an 8-bit fixed point number - use 1 for no */ -/* amplification (output is multiplied by gain) */ -/* */ -/* Outputs: Adjusts local globals - no return value */ -/* */ -/*****************************************************************************/ - -void POKEYSND_Update(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) -{ -#ifdef SYNCHRONIZED_SOUND - Update_synchronized_sound(); -#endif /* SYNCHRONIZED_SOUND */ - POKEYSND_Update_ptr(addr, val, chip, gain); -} - -static void Update_pokey_sound_rf(UWORD addr, UBYTE val, UBYTE chip, - UBYTE gain) -{ - ULONG new_val = 0; - UBYTE chan; - UBYTE chan_mask; - UBYTE chip_offs; - - /* calculate the chip_offs for the channel arrays */ - chip_offs = chip << 2; - - /* determine which address was changed */ - switch (addr & 0x0f) { - case POKEY_OFFSET_AUDF1: - /* POKEY_AUDF[POKEY_CHAN1 + chip_offs] = val; */ - chan_mask = 1 << POKEY_CHAN1; - if (POKEY_AUDCTL[chip] & POKEY_CH1_CH2) /* if ch 1&2 tied together */ - chan_mask |= 1 << POKEY_CHAN2; /* then also change on ch2 */ - break; - case POKEY_OFFSET_AUDC1: - /* POKEY_AUDC[POKEY_CHAN1 + chip_offs] = val; */ - pokeysnd_AUDV[POKEY_CHAN1 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; - chan_mask = 1 << POKEY_CHAN1; - break; - case POKEY_OFFSET_AUDF2: - /* POKEY_AUDF[POKEY_CHAN2 + chip_offs] = val; */ - chan_mask = 1 << POKEY_CHAN2; - break; - case POKEY_OFFSET_AUDC2: - /* POKEY_AUDC[POKEY_CHAN2 + chip_offs] = val; */ - pokeysnd_AUDV[POKEY_CHAN2 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; - chan_mask = 1 << POKEY_CHAN2; - break; - case POKEY_OFFSET_AUDF3: - /* POKEY_AUDF[POKEY_CHAN3 + chip_offs] = val; */ - chan_mask = 1 << POKEY_CHAN3; - if (POKEY_AUDCTL[chip] & POKEY_CH3_CH4) /* if ch 3&4 tied together */ - chan_mask |= 1 << POKEY_CHAN4; /* then also change on ch4 */ - break; - case POKEY_OFFSET_AUDC3: - /* POKEY_AUDC[POKEY_CHAN3 + chip_offs] = val; */ - pokeysnd_AUDV[POKEY_CHAN3 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; - chan_mask = 1 << POKEY_CHAN3; - break; - case POKEY_OFFSET_AUDF4: - /* POKEY_AUDF[POKEY_CHAN4 + chip_offs] = val; */ - chan_mask = 1 << POKEY_CHAN4; - break; - case POKEY_OFFSET_AUDC4: - /* POKEY_AUDC[POKEY_CHAN4 + chip_offs] = val; */ - pokeysnd_AUDV[POKEY_CHAN4 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; - chan_mask = 1 << POKEY_CHAN4; - break; - case POKEY_OFFSET_AUDCTL: - /* POKEY_AUDCTL[chip] = val; */ - chan_mask = 15; /* all channels */ - break; - default: - chan_mask = 0; - break; - } - - /************************************************************/ - /* As defined in the manual, the exact Div_n_cnt values are */ - /* different depending on the frequency and resolution: */ - /* 64 kHz or 15 kHz - AUDF + 1 */ - /* 1 MHz, 8-bit - AUDF + 4 */ - /* 1 MHz, 16-bit - POKEY_AUDF[POKEY_CHAN1]+256*POKEY_AUDF[POKEY_CHAN2] + 7 */ - /************************************************************/ - - /* only reset the channels that have changed */ - - if (chan_mask & (1 << POKEY_CHAN1)) { - /* process channel 1 frequency */ - if (POKEY_AUDCTL[chip] & POKEY_CH1_179) - new_val = POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 4; - else - new_val = (POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 1) * POKEY_Base_mult[chip]; - - if (new_val != Div_n_max[POKEY_CHAN1 + chip_offs]) { - Div_n_max[POKEY_CHAN1 + chip_offs] = new_val; - - if (Div_n_cnt[POKEY_CHAN1 + chip_offs] > new_val) { - Div_n_cnt[POKEY_CHAN1 + chip_offs] = new_val; - } - } - } - - if (chan_mask & (1 << POKEY_CHAN2)) { - /* process channel 2 frequency */ - if (POKEY_AUDCTL[chip] & POKEY_CH1_CH2) { - if (POKEY_AUDCTL[chip] & POKEY_CH1_179) - new_val = POKEY_AUDF[POKEY_CHAN2 + chip_offs] * 256 + - POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 7; - else - new_val = (POKEY_AUDF[POKEY_CHAN2 + chip_offs] * 256 + - POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 1) * POKEY_Base_mult[chip]; - } - else - new_val = (POKEY_AUDF[POKEY_CHAN2 + chip_offs] + 1) * POKEY_Base_mult[chip]; - - if (new_val != Div_n_max[POKEY_CHAN2 + chip_offs]) { - Div_n_max[POKEY_CHAN2 + chip_offs] = new_val; - - if (Div_n_cnt[POKEY_CHAN2 + chip_offs] > new_val) { - Div_n_cnt[POKEY_CHAN2 + chip_offs] = new_val; - } - } - } - - if (chan_mask & (1 << POKEY_CHAN3)) { - /* process channel 3 frequency */ - if (POKEY_AUDCTL[chip] & POKEY_CH3_179) - new_val = POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 4; - else - new_val = (POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 1) * POKEY_Base_mult[chip]; - - if (new_val != Div_n_max[POKEY_CHAN3 + chip_offs]) { - Div_n_max[POKEY_CHAN3 + chip_offs] = new_val; - - if (Div_n_cnt[POKEY_CHAN3 + chip_offs] > new_val) { - Div_n_cnt[POKEY_CHAN3 + chip_offs] = new_val; - } - } - } - - if (chan_mask & (1 << POKEY_CHAN4)) { - /* process channel 4 frequency */ - if (POKEY_AUDCTL[chip] & POKEY_CH3_CH4) { - if (POKEY_AUDCTL[chip] & POKEY_CH3_179) - new_val = POKEY_AUDF[POKEY_CHAN4 + chip_offs] * 256 + - POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 7; - else - new_val = (POKEY_AUDF[POKEY_CHAN4 + chip_offs] * 256 + - POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 1) * POKEY_Base_mult[chip]; - } - else - new_val = (POKEY_AUDF[POKEY_CHAN4 + chip_offs] + 1) * POKEY_Base_mult[chip]; - - if (new_val != Div_n_max[POKEY_CHAN4 + chip_offs]) { - Div_n_max[POKEY_CHAN4 + chip_offs] = new_val; - - if (Div_n_cnt[POKEY_CHAN4 + chip_offs] > new_val) { - Div_n_cnt[POKEY_CHAN4 + chip_offs] = new_val; - } - } - } - - /* if channel is volume only, set current output */ - for (chan = POKEY_CHAN1; chan <= POKEY_CHAN4; chan++) { - if (chan_mask & (1 << chan)) { - -#ifdef VOL_ONLY_SOUND - -#ifdef __PLUS - if (g_Sound.nDigitized) -#endif - if ((POKEY_AUDC[chan + chip_offs] & POKEY_VOL_ONLY)) { - -#ifdef STEREO_SOUND - -#ifdef __PLUS - if (POKEYSND_stereo_enabled && chip & 0x01) -#else - if (chip & 0x01) -#endif - { - sampbuf_lastval2 += pokeysnd_AUDV[chan + chip_offs] - - POKEYSND_sampbuf_AUDV[chan + chip_offs]; - - sampbuf_val2[sampbuf_ptr2] = sampbuf_lastval2; - POKEYSND_sampbuf_AUDV[chan + chip_offs] = pokeysnd_AUDV[chan + chip_offs]; - sampbuf_cnt2[sampbuf_ptr2] = - (ANTIC_CPU_CLOCK - sampbuf_last2) * 128 * POKEYSND_samp_freq / 178979; - sampbuf_last2 = ANTIC_CPU_CLOCK; - sampbuf_ptr2++; - if (sampbuf_ptr2 >= POKEYSND_SAMPBUF_MAX) - sampbuf_ptr2 = 0; - if (sampbuf_ptr2 == sampbuf_rptr2) { - sampbuf_rptr2++; - if (sampbuf_rptr2 >= POKEYSND_SAMPBUF_MAX) - sampbuf_rptr2 = 0; - } - } - else -#endif /* STEREO_SOUND */ - { - POKEYSND_sampbuf_lastval += pokeysnd_AUDV[chan + chip_offs] - -POKEYSND_sampbuf_AUDV[chan + chip_offs]; - - POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; - POKEYSND_sampbuf_AUDV[chan + chip_offs] = pokeysnd_AUDV[chan + chip_offs]; - POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = - (ANTIC_CPU_CLOCK - POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; - POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; - POKEYSND_sampbuf_ptr++; - if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX) - POKEYSND_sampbuf_ptr = 0; - if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr) { - POKEYSND_sampbuf_rptr++; - if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) - POKEYSND_sampbuf_rptr = 0; - } - } - } - -#endif /* VOL_ONLY_SOUND */ - - /* I've disabled any frequencies that exceed the sampling - frequency. There isn't much point in processing frequencies - that the hardware can't reproduce. I've also disabled - processing if the volume is zero. */ - - /* if the channel is volume only */ - /* or the channel is off (volume == 0) */ - /* or the channel freq is greater than the playback freq */ - if ( (POKEY_AUDC[chan + chip_offs] & POKEY_VOL_ONLY) || - ((POKEY_AUDC[chan + chip_offs] & POKEY_VOLUME_MASK) == 0) - || (!BIENIAS_FIX && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))) - ) { - /* indicate the channel is 'on' */ - Outvol[chan + chip_offs] = 1; - - /* can only ignore channel if filtering off */ - if ((chan == POKEY_CHAN3 && !(POKEY_AUDCTL[chip] & POKEY_CH1_FILTER)) || - (chan == POKEY_CHAN4 && !(POKEY_AUDCTL[chip] & POKEY_CH2_FILTER)) || - (chan == POKEY_CHAN1) || - (chan == POKEY_CHAN2) - || (!BIENIAS_FIX && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))) - ) { - /* and set channel freq to max to reduce processing */ - Div_n_max[chan + chip_offs] = 0x7fffffffL; - Div_n_cnt[chan + chip_offs] = 0x7fffffffL; - } - } - } - } - - /* _enable(); */ /* RSF - removed for portability 31-MAR-97 */ -} - - -/*****************************************************************************/ -/* Module: pokeysnd_process() */ -/* Purpose: To fill the output buffer with the sound output based on the */ -/* pokey chip parameters. */ -/* */ -/* Author: Ron Fries */ -/* Date: January 1, 1997 */ -/* */ -/* Inputs: *buffer - pointer to the buffer where the audio output will */ -/* be placed */ -/* sndn - for mono, size of the playback buffer in samples */ -/* for stereo, size of the playback buffer in left samples */ -/* plus right samples. */ -/* num_pokeys - number of currently active pokeys to process */ -/* */ -/* Outputs: the buffer will be filled with n bytes of audio - no return val */ -/* Also the buffer will be written to disk if Sound recording is ON */ -/* */ -/*****************************************************************************/ - -static void pokeysnd_process_8(void *sndbuffer, int sndn) -{ - register UBYTE *buffer = (UBYTE *) sndbuffer; - register int n = sndn; - - register ULONG *div_n_ptr; - register UBYTE *samp_cnt_w_ptr; - register ULONG event_min; - register UBYTE next_event; -#ifdef CLIP_SOUND - register SWORD cur_val; /* then we have to count as 16-bit signed */ -#ifdef STEREO_SOUND - register SWORD cur_val2; -#endif -#else /* CLIP_SOUND */ - register UBYTE cur_val; /* otherwise we'll simplify as 8-bit unsigned */ -#ifdef STEREO_SOUND - register UBYTE cur_val2; -#endif -#endif /* CLIP_SOUND */ - register UBYTE *out_ptr; - register UBYTE audc; - register UBYTE toggle; - register UBYTE count; - register UBYTE *vol_ptr; - - /* set a pointer to the whole portion of the samp_n_cnt */ -#ifdef WORDS_BIGENDIAN - samp_cnt_w_ptr = ((UBYTE *) (&Samp_n_cnt[0]) + 3); -#else - samp_cnt_w_ptr = ((UBYTE *) (&Samp_n_cnt[0]) + 1); -#endif - - /* set a pointer for optimization */ - out_ptr = Outvol; - vol_ptr = pokeysnd_AUDV; - - /* The current output is pre-determined and then adjusted based on each */ - /* output change for increased performance (less over-all math). */ - /* add the output values of all 4 channels */ - cur_val = POKEYSND_SAMP_MIN; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - cur_val2 = POKEYSND_SAMP_MIN; -#endif /* STEREO_SOUND */ - - count = Num_pokeys; - do { - if (*out_ptr++) - cur_val += *vol_ptr; - vol_ptr++; - - if (*out_ptr++) - cur_val += *vol_ptr; - vol_ptr++; - - if (*out_ptr++) - cur_val += *vol_ptr; - vol_ptr++; - - if (*out_ptr++) - cur_val += *vol_ptr; - vol_ptr++; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - { - count--; - if (count) { - if (*out_ptr++) - cur_val2 += *vol_ptr; - vol_ptr++; - - if (*out_ptr++) - cur_val2 += *vol_ptr; - vol_ptr++; - - if (*out_ptr++) - cur_val2 += *vol_ptr; - vol_ptr++; - - if (*out_ptr++) - cur_val2 += *vol_ptr; - vol_ptr++; - } - else - break; - } -#endif /* STEREO_SOUND */ - count--; - } while (count); - -#ifdef SYNCHRONIZED_SOUND - cur_val += speaker; -#endif - - /* loop until the buffer is filled */ - while (n) { - /* Normally the routine would simply decrement the 'div by N' */ - /* counters and react when they reach zero. Since we normally */ - /* won't be processing except once every 80 or so counts, */ - /* I've optimized by finding the smallest count and then */ - /* 'accelerated' time by adjusting all pointers by that amount. */ - - /* find next smallest event (either sample or chan 1-4) */ - next_event = POKEY_SAMPLE; - event_min = READ_U32(samp_cnt_w_ptr); - - div_n_ptr = Div_n_cnt; - - count = 0; - do { - /* Though I could have used a loop here, this is faster */ - if (*div_n_ptr <= event_min) { - event_min = *div_n_ptr; - next_event = POKEY_CHAN1 + (count << 2); - } - div_n_ptr++; - if (*div_n_ptr <= event_min) { - event_min = *div_n_ptr; - next_event = POKEY_CHAN2 + (count << 2); - } - div_n_ptr++; - if (*div_n_ptr <= event_min) { - event_min = *div_n_ptr; - next_event = POKEY_CHAN3 + (count << 2); - } - div_n_ptr++; - if (*div_n_ptr <= event_min) { - event_min = *div_n_ptr; - next_event = POKEY_CHAN4 + (count << 2); - } - div_n_ptr++; - - count++; - } while (count < Num_pokeys); - - /* if the next event is a channel change */ - if (next_event != POKEY_SAMPLE) { - /* shift the polynomial counters */ - - count = Num_pokeys; - do { - /* decrement all counters by the smallest count found */ - /* again, no loop for efficiency */ - div_n_ptr--; - *div_n_ptr -= event_min; - div_n_ptr--; - *div_n_ptr -= event_min; - div_n_ptr--; - *div_n_ptr -= event_min; - div_n_ptr--; - *div_n_ptr -= event_min; - - count--; - } while (count); - - - WRITE_U32(samp_cnt_w_ptr, READ_U32(samp_cnt_w_ptr) - event_min); - - /* since the polynomials require a mod (%) function which is - division, I don't adjust the polynomials on the SAMPLE events, - only the CHAN events. I have to keep track of the change, - though. */ - - P4 = (P4 + event_min) % POKEY_POLY4_SIZE; - P5 = (P5 + event_min) % POKEY_POLY5_SIZE; - P9 = (P9 + event_min) % POKEY_POLY9_SIZE; - P17 = (P17 + event_min) % POKEY_POLY17_SIZE; - - /* adjust channel counter */ - Div_n_cnt[next_event] += Div_n_max[next_event]; - - /* get the current AUDC into a register (for optimization) */ - audc = POKEY_AUDC[next_event]; - - /* set a pointer to the current output (for opt...) */ - out_ptr = &Outvol[next_event]; - - /* assume no changes to the output */ - toggle = FALSE; - - /* From here, a good understanding of the hardware is required */ - /* to understand what is happening. I won't be able to provide */ - /* much description to explain it here. */ - - /* if VOLUME only then nothing to process */ - if (!(audc & POKEY_VOL_ONLY)) { - /* if the output is pure or the output is poly5 and the poly5 bit */ - /* is set */ - if ((audc & POKEY_NOTPOLY5) || bit5[P5]) { - /* if the PURETONE bit is set */ - if (audc & POKEY_PURETONE) { - /* then simply toggle the output */ - toggle = TRUE; - } - /* otherwise if POLY4 is selected */ - else if (audc & POKEY_POLY4) { - /* then compare to the poly4 bit */ - toggle = (bit4[P4] == !(*out_ptr)); - } - else { - /* if 9-bit poly is selected on this chip */ - if (POKEY_AUDCTL[next_event >> 2] & POKEY_POLY9) { - /* compare to the poly9 bit */ - toggle = ((POKEY_poly9_lookup[P9] & 1) == !(*out_ptr)); - } - else { - /* otherwise compare to the poly17 bit */ - toggle = (((POKEY_poly17_lookup[P17 >> 3] >> (P17 & 7)) & 1) == !(*out_ptr)); - } - } - } - } - - /* check channel 1 filter (clocked by channel 3) */ - if ( POKEY_AUDCTL[next_event >> 2] & POKEY_CH1_FILTER) { - /* if we're processing channel 3 */ - if ((next_event & 0x03) == POKEY_CHAN3) { - /* check output of channel 1 on same chip */ - if (Outvol[next_event & 0xfd]) { - /* if on, turn it off */ - Outvol[next_event & 0xfd] = 0; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled && (next_event & 0x04)) -#else - if ((next_event & 0x04)) -#endif - cur_val2 -= pokeysnd_AUDV[next_event & 0xfd]; - else -#endif /* STEREO_SOUND */ - cur_val -= pokeysnd_AUDV[next_event & 0xfd]; - } - } - } - - /* check channel 2 filter (clocked by channel 4) */ - if ( POKEY_AUDCTL[next_event >> 2] & POKEY_CH2_FILTER) { - /* if we're processing channel 4 */ - if ((next_event & 0x03) == POKEY_CHAN4) { - /* check output of channel 2 on same chip */ - if (Outvol[next_event & 0xfd]) { - /* if on, turn it off */ - Outvol[next_event & 0xfd] = 0; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled && (next_event & 0x04)) -#else - if ((next_event & 0x04)) -#endif - cur_val2 -= pokeysnd_AUDV[next_event & 0xfd]; - else -#endif /* STEREO_SOUND */ - cur_val -= pokeysnd_AUDV[next_event & 0xfd]; - } - } - } - - /* if the current output bit has changed */ - if (toggle) { - if (*out_ptr) { - /* remove this channel from the signal */ -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled && (next_event & 0x04)) -#else - if ((next_event & 0x04)) -#endif - cur_val2 -= pokeysnd_AUDV[next_event]; - else -#endif /* STEREO_SOUND */ - cur_val -= pokeysnd_AUDV[next_event]; - - /* and turn the output off */ - *out_ptr = 0; - } - else { - /* turn the output on */ - *out_ptr = 1; - - /* and add it to the output signal */ -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled && (next_event & 0x04)) -#else - if ((next_event & 0x04)) -#endif - cur_val2 += pokeysnd_AUDV[next_event]; - else -#endif /* STEREO_SOUND */ - cur_val += pokeysnd_AUDV[next_event]; - } - } - } - else { /* otherwise we're processing a sample */ - /* adjust the sample counter - note we're using the 24.8 integer - which includes an 8 bit fraction for accuracy */ - - int iout; -#ifdef STEREO_SOUND - int iout2; -#endif -#ifdef INTERPOLATE_SOUND - if (cur_val != last_val) { - if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */ - iout = (cur_val * (*Samp_n_cnt) + - last_val * (Samp_n_max - *Samp_n_cnt)) - / Samp_n_max; - } - else - iout = cur_val; - last_val = cur_val; - } - else - iout = cur_val; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - if (cur_val2 != last_val2) { - if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */ - iout2 = (cur_val2 * (*Samp_n_cnt) + - last_val2 * (Samp_n_max - *Samp_n_cnt)) - / Samp_n_max; - } - else - iout2 = cur_val2; - last_val2 = cur_val2; - } - else - iout2 = cur_val2; -#endif /* STEREO_SOUND */ -#else /* INTERPOLATE_SOUND */ - iout = cur_val; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - iout2 = cur_val2; -#endif /* STEREO_SOUND */ -#endif /* INTERPOLATE_SOUND */ - -#ifdef VOL_ONLY_SOUND -#ifdef __PLUS - if (g_Sound.nDigitized) -#endif - { - if (POKEYSND_sampbuf_rptr != POKEYSND_sampbuf_ptr) { - int l; - if (POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] > 0) - POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] -= 1280; - while ((l = POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr]) <= 0) { - POKEYSND_sampout = POKEYSND_sampbuf_val[POKEYSND_sampbuf_rptr]; - POKEYSND_sampbuf_rptr++; - if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) - POKEYSND_sampbuf_rptr = 0; - if (POKEYSND_sampbuf_rptr != POKEYSND_sampbuf_ptr) - POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] += l; - else - break; - } - } - iout += POKEYSND_sampout; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - { - if (sampbuf_rptr2 != sampbuf_ptr2) { - int l; - if (sampbuf_cnt2[sampbuf_rptr2] > 0) - sampbuf_cnt2[sampbuf_rptr2] -= 1280; - while ((l = sampbuf_cnt2[sampbuf_rptr2]) <= 0) { - sampout2 = sampbuf_val2[sampbuf_rptr2]; - sampbuf_rptr2++; - if (sampbuf_rptr2 >= POKEYSND_SAMPBUF_MAX) - sampbuf_rptr2 = 0; - if (sampbuf_rptr2 != sampbuf_ptr2) - sampbuf_cnt2[sampbuf_rptr2] += l; - else - break; - } - } - iout2 += sampout2; - } -#endif /* STEREO_SOUND */ - } -#endif /* VOL_ONLY_SOUND */ - -#ifdef CLIP_SOUND - if (iout > POKEYSND_SAMP_MAX) { /* then check high limit */ - *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; /* and limit if greater */ - } - else if (iout < POKEYSND_SAMP_MIN) { /* else check low limit */ - *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; /* and limit if less */ - } - else { /* otherwise use raw value */ - *buffer++ = (UBYTE) iout; - } -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) { - if (iout2 > POKEYSND_SAMP_MAX) - *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; - else if (iout2 < POKEYSND_SAMP_MIN) - *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; - else - *buffer++ = (UBYTE) iout2; - } -#else /* __PLUS */ - if (Num_pokeys > 1) { - if ((POKEYSND_stereo_enabled ? iout2 : iout) > POKEYSND_SAMP_MAX) { /* then check high limit */ - *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; /* and limit if greater */ - } - else if ((POKEYSND_stereo_enabled ? iout2 : iout) < POKEYSND_SAMP_MIN) { /* else check low limit */ - *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; /* and limit if less */ - } - else { /* otherwise use raw value */ - *buffer++ = (UBYTE) (POKEYSND_stereo_enabled ? iout2 : iout); - } - } -#endif /* __PLUS */ -#endif /* STEREO_SOUND */ -#else /* CLIP_SOUND */ - *buffer++ = (UBYTE) iout; /* clipping not selected, use value */ -#ifdef STEREO_SOUND - if (Num_pokeys > 1) -#ifdef ASAP - *buffer++ = (UBYTE) iout2; -#else - *buffer++ = (UBYTE) (POKEYSND_stereo_enabled ? iout2 : iout); -#endif -#endif /* STEREO_SOUND */ -#endif /* CLIP_SOUND */ - -#ifdef WORDS_BIGENDIAN - *(Samp_n_cnt + 1) += Samp_n_max; -#else - *Samp_n_cnt += Samp_n_max; -#endif - /* and indicate one less byte in the buffer */ - n--; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - if (Num_pokeys > 1) - n--; -#endif - } - } -#ifdef VOL_ONLY_SOUND -#ifdef __PLUS - if (g_Sound.nDigitized) -#endif - { - if (POKEYSND_sampbuf_rptr == POKEYSND_sampbuf_ptr) - POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; -#ifdef STEREO_SOUND -#ifdef __PLUS - if (POKEYSND_stereo_enabled) -#endif - if (sampbuf_rptr2 == sampbuf_ptr2) - sampbuf_last2 = ANTIC_CPU_CLOCK; -#endif /* STEREO_SOUND */ - } -#endif /* VOL_ONLY_SOUND */ -} - -#ifdef SERIO_SOUND -static void Update_serio_sound_rf(int out, UBYTE data) -{ -#ifdef VOL_ONLY_SOUND -#ifdef __PLUS - if (g_Sound.nDigitized) { -#endif - int bits, pv, future; - if (!POKEYSND_serio_sound_enabled) return; - - pv = 0; - future = 0; - bits = (data << 1) | 0x200; - while (bits) - { - POKEYSND_sampbuf_lastval -= pv; - pv = (bits & 0x01) * pokeysnd_AUDV[3]; /* FIXME!!! - set volume from AUDV */ - POKEYSND_sampbuf_lastval += pv; - - POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; - POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = - (ANTIC_CPU_CLOCK + future-POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; - POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK + future; - POKEYSND_sampbuf_ptr++; - if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX ) - POKEYSND_sampbuf_ptr = 0; - if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr ) { - POKEYSND_sampbuf_rptr++; - if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) - POKEYSND_sampbuf_rptr = 0; - } - /* 1789790/19200 = 93 */ - future += 93; /* ~ 19200 bit/s - FIXME!!! set speed form AUDF [2] ??? */ - bits >>= 1; - } - POKEYSND_sampbuf_lastval -= pv; -#ifdef __PLUS - } -#endif -#endif /* VOL_ONLY_SOUND */ -} -#endif /* SERIO_SOUND */ - -static void pokeysnd_process_16(void *sndbuffer, int sndn) -{ - UWORD *buffer = (UWORD *) sndbuffer; - int i; - - pokeysnd_process_8(buffer, sndn); - - for (i = sndn - 1; i >= 0; i--) { - int smp = ((int) (((UBYTE *) buffer)[i]) - 0x80) * 0x100; - - if (smp > 32767) - smp = 32767; - else if (smp < -32768) - smp = -32768; - - buffer[i] = smp; - } -} - -#ifdef SYNCHRONIZED_SOUND -static void Generate_sync_rf(unsigned int num_ticks) -{ - double new_samp_pos; - unsigned int ticks; - UBYTE *buffer = POKEYSND_process_buffer + POKEYSND_process_buffer_fill; - UBYTE *buffer_end = POKEYSND_process_buffer + POKEYSND_process_buffer_length; - - for (;;) { - double int_part; - new_samp_pos = samp_pos + ticks_per_sample; - new_samp_pos = modf(new_samp_pos, &int_part); - ticks = (unsigned int)int_part; - if (ticks > num_ticks) { - samp_pos -= num_ticks; - break; - } - if (buffer >= buffer_end) - break; - - samp_pos = new_samp_pos; - num_ticks -= ticks; - - if (POKEYSND_snd_flags & POKEYSND_BIT16) { - pokeysnd_process_16(buffer, POKEYSND_num_pokeys); - buffer += 2 * POKEYSND_num_pokeys; - } - else { - pokeysnd_process_8(buffer, POKEYSND_num_pokeys); - buffer += POKEYSND_num_pokeys; - } - - } - - POKEYSND_process_buffer_fill = buffer - POKEYSND_process_buffer; -} -#endif /* SYNCHRONIZED_SOUND */ - -#ifdef CONSOLE_SOUND -void POKEYSND_UpdateConsol(int set) -{ - if (!POKEYSND_console_sound_enabled) - return; -#ifdef SYNCHRONIZED_SOUND - if (set) - Update_synchronized_sound(); -#endif /* SYNCHRONIZED_SOUND */ - POKEYSND_UpdateConsol_ptr(set); -} - -static void Update_consol_sound_rf(int set) -{ -#ifdef SYNCHRONIZED_SOUND - if (set) - speaker = CONSOLE_VOL * GTIA_speaker; -#elif defined(VOL_ONLY_SOUND) - static int prev_atari_speaker = 0; - static unsigned int prev_cpu_clock = 0; - int d; -#ifdef __PLUS - if (!g_Sound.nDigitized) - return; -#endif - - if (!set && POKEYSND_samp_consol_val == 0) - return; - POKEYSND_sampbuf_lastval -= POKEYSND_samp_consol_val; - if (prev_atari_speaker != GTIA_speaker) { - POKEYSND_samp_consol_val = GTIA_speaker * 8 * 4; /* gain */ - prev_cpu_clock = ANTIC_CPU_CLOCK; - } - else if (!set) { - d = ANTIC_CPU_CLOCK - prev_cpu_clock; - if (d < 114) { - POKEYSND_sampbuf_lastval += POKEYSND_samp_consol_val; - return; - } - while (d >= 114 /* CPUL */) { - POKEYSND_samp_consol_val = POKEYSND_samp_consol_val * 99 / 100; - d -= 114; - } - prev_cpu_clock = ANTIC_CPU_CLOCK - d; - } - POKEYSND_sampbuf_lastval += POKEYSND_samp_consol_val; - prev_atari_speaker = GTIA_speaker; - - POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; - POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = - (ANTIC_CPU_CLOCK - POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; - POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; - POKEYSND_sampbuf_ptr++; - if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX) - POKEYSND_sampbuf_ptr = 0; - if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr) { - POKEYSND_sampbuf_rptr++; - if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) - POKEYSND_sampbuf_rptr = 0; - } -#endif /* !SYNCHRONIZED_SOUND && VOL_ONLY_SOUND */ -} -#endif /* CONSOLE_SOUND */ - -#ifdef VOL_ONLY_SOUND -static void Update_vol_only_sound_rf(void) -{ -#ifdef CONSOLE_SOUND - POKEYSND_UpdateConsol(0); /* mmm */ -#endif /* CONSOLE_SOUND */ -} -#endif /* VOL_ONLY_SOUND */ +/* + * pokeysnd.c - POKEY sound chip emulation, v2.4 + * + * Copyright (C) 1996-1998 Ron Fries + * Copyright (C) 1998-2014 Atari800 development team (see DOC/CREDITS) + * + * This file is part of the Atari800 emulator project which emulates + * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers. + * + * Atari800 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. + * + * Atari800 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 Atari800; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "config.h" +#include +#include + +#ifdef ASAP /* external project, see http://asap.sf.net */ +#include "asap_internal.h" +#else +#include "atari.h" +#ifndef __PLUS +#include "sndsave.h" +#else +#include "sound_win.h" +#endif +#endif +#include "mzpokeysnd.h" +#include "pokeysnd.h" +#if defined(PBI_XLD) || defined (VOICEBOX) +#include "votraxsnd.h" +#endif +#include "antic.h" +#include "gtia.h" +#include "util.h" + +#ifdef WORDS_UNALIGNED_OK +# define READ_U32(x) (*(ULONG *) (x)) +# define WRITE_U32(x, d) (*(ULONG *) (x) = (d)) +#else +# ifdef WORDS_BIGENDIAN +# define READ_U32(x) (((*(unsigned char *)(x)) << 24) | ((*((unsigned char *)(x) + 1)) << 16) | \ + ((*((unsigned char *)(x) + 2)) << 8) | ((*((unsigned char *)(x) + 3)))) +# define WRITE_U32(x, d) \ + { \ + ULONG i = d; \ + (*(unsigned char *) (x)) = (((i) >> 24) & 255); \ + (*((unsigned char *) (x) + 1)) = (((i) >> 16) & 255); \ + (*((unsigned char *) (x) + 2)) = (((i) >> 8) & 255); \ + (*((unsigned char *) (x) + 3)) = ((i) & 255); \ + } +# else +# define READ_U32(x) ((*(unsigned char *) (x)) | ((*((unsigned char *) (x) + 1)) << 8) | \ + ((*((unsigned char *) (x) + 2)) << 16) | ((*((unsigned char *) (x) + 3)) << 24)) +# define WRITE_U32(x, d) \ + { \ + ULONG i = d; \ + (*(unsigned char *)(x)) = ((i) & 255); \ + (*((unsigned char *)(x) + 1)) = (((i) >> 8) & 255); \ + (*((unsigned char *)(x) + 2)) = (((i) >> 16) & 255); \ + (*((unsigned char *)(x) + 3)) = (((i) >> 24) & 255); \ + } +# endif +#endif + +/* GLOBAL VARIABLE DEFINITIONS */ + +/* number of pokey chips currently emulated */ +static UBYTE Num_pokeys; + +static UBYTE pokeysnd_AUDV[4 * POKEY_MAXPOKEYS]; /* Channel volume - derived */ + +static UBYTE Outbit[4 * POKEY_MAXPOKEYS]; /* current state of the output (high or low) */ + +static UBYTE Outvol[4 * POKEY_MAXPOKEYS]; /* last output volume for each channel */ + +/* Initialize the bit patterns for the polynomials. */ + +/* The 4bit and 5bit patterns are the identical ones used in the pokey chip. */ +/* Though the patterns could be packed with 8 bits per byte, using only a */ +/* single bit per byte keeps the math simple, which is important for */ +/* efficient processing. */ + +static UBYTE bit4[POKEY_POLY4_SIZE] = +#ifndef POKEY23_POLY +{1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0}; /* new table invented by Perry */ +#else +{1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}; /* original POKEY 2.3 table */ +#endif + +static UBYTE bit5[POKEY_POLY5_SIZE] = +#ifndef POKEY23_POLY +{1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0}; +#else +{0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1}; +#endif + +static ULONG P4 = 0, /* Global position pointer for the 4-bit POLY array */ + P5 = 0, /* Global position pointer for the 5-bit POLY array */ + P9 = 0, /* Global position pointer for the 9-bit POLY array */ + P17 = 0; /* Global position pointer for the 17-bit POLY array */ + +static ULONG Div_n_cnt[4 * POKEY_MAXPOKEYS], /* Divide by n counter. one for each channel */ + Div_n_max[4 * POKEY_MAXPOKEYS]; /* Divide by n maximum, one for each channel */ + +static ULONG Samp_n_max, /* Sample max. For accuracy, it is *256 */ + Samp_n_cnt[2]; /* Sample cnt. */ + +#ifdef INTERPOLATE_SOUND +static UWORD last_val = 0; /* last output value */ +#ifdef STEREO_SOUND +static UWORD last_val2 = 0; /* last output value */ +#endif +#endif + +/* Volume only emulations declarations */ +#ifdef VOL_ONLY_SOUND + +int POKEYSND_sampbuf_val[POKEYSND_SAMPBUF_MAX]; /* volume values */ +int POKEYSND_sampbuf_cnt[POKEYSND_SAMPBUF_MAX]; /* relative start time */ +int POKEYSND_sampbuf_ptr = 0; /* pointer to sampbuf */ +int POKEYSND_sampbuf_rptr = 0; /* pointer to read from sampbuf */ +int POKEYSND_sampbuf_last = 0; /* last absolute time */ +int POKEYSND_sampbuf_AUDV[4 * POKEY_MAXPOKEYS]; /* prev. channel volume */ +int POKEYSND_sampbuf_lastval = 0; /* last volume */ +int POKEYSND_sampout; /* last out volume */ +int POKEYSND_samp_freq; +int POKEYSND_samp_consol_val = 0; /* actual value of console sound */ +#ifdef STEREO_SOUND +static int sampbuf_val2[POKEYSND_SAMPBUF_MAX]; /* volume values */ +static int sampbuf_cnt2[POKEYSND_SAMPBUF_MAX]; /* relative start time */ +static int sampbuf_ptr2 = 0; /* pointer to sampbuf */ +static int sampbuf_rptr2 = 0; /* pointer to read from sampbuf */ +static int sampbuf_last2 = 0; /* last absolute time */ +static int sampbuf_lastval2 = 0; /* last volume */ +static int sampout2; /* last out volume */ +#endif +#endif /* VOL_ONLY_SOUND */ + +static ULONG snd_freq17 = POKEYSND_FREQ_17_EXACT; +int POKEYSND_playback_freq = 44100; +UBYTE POKEYSND_num_pokeys = 1; +int POKEYSND_snd_flags = 0; +static int mz_quality = 0; /* default quality for mzpokeysnd */ +#ifdef __PLUS +int mz_clear_regs = 0; +#endif + +int POKEYSND_enable_new_pokey = TRUE; +int POKEYSND_bienias_fix = TRUE; /* when TRUE, high frequencies get emulated: better sound but slower */ +#if defined(__PLUS) && !defined(_WX_) +#define BIENIAS_FIX (g_Sound.nBieniasFix) +#else +#define BIENIAS_FIX POKEYSND_bienias_fix +#endif +#ifndef ASAP +#if defined(__LIBRETRO__) +int POKEYSND_stereo_enabled = TRUE; +#else /* __LIBRETRO__ */ +int POKEYSND_stereo_enabled = FALSE; +#endif +#endif + +int POKEYSND_volume = 0x100; + +/* multiple sound engine interface */ +static void pokeysnd_process_8(void *sndbuffer, int sndn); +static void pokeysnd_process_16(void *sndbuffer, int sndn); +static void null_pokey_process(void *sndbuffer, int sndn) {} +void (*POKEYSND_Process_ptr)(void *sndbuffer, int sndn) = null_pokey_process; + +static void Update_pokey_sound_rf(UWORD, UBYTE, UBYTE, UBYTE); +static void null_pokey_sound(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) {} +void (*POKEYSND_Update_ptr) (UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) + = null_pokey_sound; + +#ifdef SERIO_SOUND +static void Update_serio_sound_rf(int out, UBYTE data); +static void null_serio_sound(int out, UBYTE data) {} +void (*POKEYSND_UpdateSerio)(int out, UBYTE data) = null_serio_sound; +int POKEYSND_serio_sound_enabled = 1; +#endif + +#ifdef CONSOLE_SOUND +static void Update_consol_sound_rf(int set); +static void null_consol_sound(int set) {} +void (*POKEYSND_UpdateConsol_ptr)(int set) = null_consol_sound; +int POKEYSND_console_sound_enabled = 1; +#endif + +#ifdef VOL_ONLY_SOUND +static void Update_vol_only_sound_rf(void); +static void null_vol_only_sound(void) {} +void (*POKEYSND_UpdateVolOnly)(void) = null_vol_only_sound; +#endif + +#ifdef SYNCHRONIZED_SOUND +UBYTE *POKEYSND_process_buffer = NULL; +unsigned int POKEYSND_process_buffer_length; +unsigned int POKEYSND_process_buffer_fill; +static unsigned int prev_update_tick; + +static void Generate_sync_rf(unsigned int num_ticks); +static void null_generate_sync(unsigned int num_ticks) {} +void (*POKEYSND_GenerateSync)(unsigned int num_ticks) = null_generate_sync; + +static double ticks_per_sample; +static double samp_pos; +static int speaker; +static int const CONSOLE_VOL = 32; +#endif /* SYNCHRONIZED_SOUND */ + +/*****************************************************************************/ +/* In my routines, I treat the sample output as another divide by N counter */ +/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ +/* which has 8 binary digits to the right of the decimal point. I use a two */ +/* byte array to give me a minimum of 40 bits, and then use pointer math to */ +/* reference either the 24.8 whole/fraction combination or the 32-bit whole */ +/* only number. This is mainly used to keep the math simple for */ +/* optimization. See below: */ +/* */ +/* Representation on little-endian machines: */ +/* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx */ +/* fraction whole whole whole whole unused unused unused */ +/* */ +/* Samp_n_cnt[0] gives me a 32-bit int 24 whole bits with 8 fractional bits, */ +/* while (ULONG *)((UBYTE *)(&Samp_n_cnt[0])+1) gives me the 32-bit whole */ +/* number only. */ +/* */ +/* Representation on big-endian machines: */ +/* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx.xxxxxxxx */ +/* unused unused unused whole whole whole whole fraction */ +/* */ +/* Samp_n_cnt[1] gives me a 32-bit int 24 whole bits with 8 fractional bits, */ +/* while (ULONG *)((UBYTE *)(&Samp_n_cnt[0])+3) gives me the 32-bit whole */ +/* number only. */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Module: pokeysnd_init_rf() */ +/* Purpose: to handle the power-up initialization functions */ +/* these functions should only be executed on a cold-restart */ +/* */ +/* Author: Ron Fries */ +/* Date: January 1, 1997 */ +/* */ +/* Inputs: freq17 - the value for the '1.79MHz' Pokey audio clock */ +/* playback_freq - the playback frequency in samples per second */ +/* num_pokeys - specifies the number of pokey chips to be emulated */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +static int pokeysnd_init_rf(ULONG freq17, int playback_freq, + UBYTE num_pokeys, int flags); + +#ifdef VOL_ONLY_SOUND +/* Initialise variables related to volume-only sound. */ +static void init_vol_only(void) +{ + POKEYSND_sampbuf_rptr = POKEYSND_sampbuf_ptr; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; + POKEYSND_sampbuf_lastval = 0; + POKEYSND_samp_consol_val = 0; +#ifdef STEREO_SOUND + sampbuf_rptr2 = sampbuf_ptr2; + sampbuf_last2 = ANTIC_CPU_CLOCK; + sampbuf_lastval2 = 0; +#endif /* STEREO_SOUND */ +} +#endif /* VOL_ONLY_SOUND */ + +int POKEYSND_DoInit(void) +{ + SndSave_CloseSoundFile(); + +#ifdef VOL_ONLY_SOUND + init_vol_only(); +#endif /* VOL_ONLY_SOUND */ + + if (POKEYSND_enable_new_pokey) + return MZPOKEYSND_Init(snd_freq17, POKEYSND_playback_freq, + POKEYSND_num_pokeys, POKEYSND_snd_flags, mz_quality +#ifdef __PLUS + , mz_clear_regs +#endif + ); + else + return pokeysnd_init_rf(snd_freq17, POKEYSND_playback_freq, + POKEYSND_num_pokeys, POKEYSND_snd_flags); +} + +int POKEYSND_Init(ULONG freq17, int playback_freq, UBYTE num_pokeys, + int flags +#ifdef __PLUS + , int clear_regs +#endif +) +{ + snd_freq17 = freq17; + POKEYSND_playback_freq = playback_freq; + POKEYSND_num_pokeys = num_pokeys; + POKEYSND_snd_flags = flags; +#ifdef __PLUS + mz_clear_regs = clear_regs; +#endif +#ifdef SYNCHRONIZED_SOUND + { + /* A single call to Atari800_Frame may emulate a bit more CPU ticks than the exact number of + ticks per frame (Atari800_tv_mode*114). So we add a few ticks to buffer size just to be safe. */ + unsigned int const surplus_ticks = 10; + double samples_per_frame = (double)POKEYSND_playback_freq/(Atari800_tv_mode == Atari800_TV_PAL ? Atari800_FPS_PAL : Atari800_FPS_NTSC); + unsigned int ticks_per_frame = Atari800_tv_mode*114; + unsigned int max_ticks_per_frame = ticks_per_frame + surplus_ticks; + double ticks_per_sample = (double)ticks_per_frame / samples_per_frame; + POKEYSND_process_buffer_length = POKEYSND_num_pokeys * (unsigned int)ceil((double)max_ticks_per_frame / ticks_per_sample) * ((POKEYSND_snd_flags & POKEYSND_BIT16) ? 2:1); + free(POKEYSND_process_buffer); + POKEYSND_process_buffer = (UBYTE *)Util_malloc(POKEYSND_process_buffer_length); + POKEYSND_process_buffer_fill = 0; + prev_update_tick = ANTIC_CPU_CLOCK; + } +#endif /* SYNCHRONIZED_SOUND */ + +#if defined(PBI_XLD) || defined (VOICEBOX) + VOTRAXSND_Init(playback_freq, num_pokeys, (flags & POKEYSND_BIT16)); +#endif + return POKEYSND_DoInit(); +} + +void POKEYSND_SetMzQuality(int quality) /* specially for win32, perhaps not needed? */ +{ + mz_quality = quality; +} + +void POKEYSND_Process(void *sndbuffer, int sndn) +{ + POKEYSND_Process_ptr(sndbuffer, sndn); +#if defined(PBI_XLD) || defined (VOICEBOX) + VOTRAXSND_Process(sndbuffer,sndn); +#endif +#if !defined(__PLUS) && !defined(ASAP) + SndSave_WriteToSoundFile((const unsigned char *)sndbuffer, sndn); +#endif +} + +#ifdef SYNCHRONIZED_SOUND +static void Update_synchronized_sound(void) +{ + POKEYSND_GenerateSync(ANTIC_CPU_CLOCK - prev_update_tick); + prev_update_tick = ANTIC_CPU_CLOCK; +} + +int POKEYSND_UpdateProcessBuffer(void) +{ + int sndn; + Update_synchronized_sound(); + sndn = POKEYSND_process_buffer_fill / ((POKEYSND_snd_flags & POKEYSND_BIT16) ? 2 : 1); + POKEYSND_process_buffer_fill = 0; + +#if defined(PBI_XLD) || defined (VOICEBOX) + VOTRAXSND_Process(POKEYSND_process_buffer, sndn); +#endif +#if !defined(__PLUS) && !defined(ASAP) + SndSave_WriteToSoundFile((const unsigned char *)POKEYSND_process_buffer, sndn); +#endif + return sndn; +} +#endif /* SYNCHRONIZED_SOUND */ + +#ifdef SYNCHRONIZED_SOUND +static void init_syncsound(void) +{ + double samples_per_frame = (double)POKEYSND_playback_freq/(Atari800_tv_mode == Atari800_TV_PAL ? Atari800_FPS_PAL : Atari800_FPS_NTSC); + unsigned int ticks_per_frame = Atari800_tv_mode*114; + ticks_per_sample = (double)ticks_per_frame / samples_per_frame; + samp_pos = 0.0; + POKEYSND_GenerateSync = Generate_sync_rf; + speaker = 0; +} +#endif /* SYNCHRONIZED_SOUND */ + +static int pokeysnd_init_rf(ULONG freq17, int playback_freq, + UBYTE num_pokeys, int flags) +{ + UBYTE chan; + + POKEYSND_Update_ptr = Update_pokey_sound_rf; +#ifdef SERIO_SOUND + POKEYSND_UpdateSerio = Update_serio_sound_rf; +#endif +#ifdef CONSOLE_SOUND + POKEYSND_UpdateConsol_ptr = Update_consol_sound_rf; +#endif +#ifdef VOL_ONLY_SOUND + POKEYSND_UpdateVolOnly = Update_vol_only_sound_rf; +#endif + + POKEYSND_Process_ptr = (flags & POKEYSND_BIT16) ? pokeysnd_process_16 : pokeysnd_process_8; + +#ifdef VOL_ONLY_SOUND + POKEYSND_samp_freq = playback_freq; +#endif + + /* start all of the polynomial counters at zero */ + P4 = 0; + P5 = 0; + P9 = 0; + P17 = 0; + + /* calculate the sample 'divide by N' value based on the playback freq. */ + Samp_n_max = ((ULONG) freq17 << 8) / playback_freq; + + Samp_n_cnt[0] = 0; /* initialize all bits of the sample */ + Samp_n_cnt[1] = 0; /* 'divide by N' counter */ + + for (chan = 0; chan < (POKEY_MAXPOKEYS * 4); chan++) { + Outvol[chan] = 0; + Outbit[chan] = 0; + Div_n_cnt[chan] = 0; + Div_n_max[chan] = 0x7fffffffL; + pokeysnd_AUDV[chan] = 0; +#ifdef VOL_ONLY_SOUND + POKEYSND_sampbuf_AUDV[chan] = 0; +#endif + } + + /* set the number of pokey chips currently emulated */ + Num_pokeys = num_pokeys; + +#ifdef SYNCHRONIZED_SOUND + init_syncsound(); +#endif + return 0; /* OK */ +} + + +/*****************************************************************************/ +/* Module: Update_pokey_sound_rf() */ +/* Purpose: To process the latest control values stored in the AUDF, AUDC, */ +/* and AUDCTL registers. It pre-calculates as much information as */ +/* possible for better performance. This routine has not been */ +/* optimized. */ +/* */ +/* Author: Ron Fries */ +/* Date: January 1, 1997 */ +/* */ +/* Inputs: addr - the address of the parameter to be changed */ +/* val - the new value to be placed in the specified address */ +/* gain - specified as an 8-bit fixed point number - use 1 for no */ +/* amplification (output is multiplied by gain) */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +void POKEYSND_Update(UWORD addr, UBYTE val, UBYTE chip, UBYTE gain) +{ +#ifdef SYNCHRONIZED_SOUND + Update_synchronized_sound(); +#endif /* SYNCHRONIZED_SOUND */ + POKEYSND_Update_ptr(addr, val, chip, gain); +} + +static void Update_pokey_sound_rf(UWORD addr, UBYTE val, UBYTE chip, + UBYTE gain) +{ + ULONG new_val = 0; + UBYTE chan; + UBYTE chan_mask; + UBYTE chip_offs; + + /* calculate the chip_offs for the channel arrays */ + chip_offs = chip << 2; + + /* determine which address was changed */ + switch (addr & 0x0f) { + case POKEY_OFFSET_AUDF1: + /* POKEY_AUDF[POKEY_CHAN1 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN1; + if (POKEY_AUDCTL[chip] & POKEY_CH1_CH2) /* if ch 1&2 tied together */ + chan_mask |= 1 << POKEY_CHAN2; /* then also change on ch2 */ + break; + case POKEY_OFFSET_AUDC1: + /* POKEY_AUDC[POKEY_CHAN1 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN1 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN1; + break; + case POKEY_OFFSET_AUDF2: + /* POKEY_AUDF[POKEY_CHAN2 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN2; + break; + case POKEY_OFFSET_AUDC2: + /* POKEY_AUDC[POKEY_CHAN2 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN2 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN2; + break; + case POKEY_OFFSET_AUDF3: + /* POKEY_AUDF[POKEY_CHAN3 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN3; + if (POKEY_AUDCTL[chip] & POKEY_CH3_CH4) /* if ch 3&4 tied together */ + chan_mask |= 1 << POKEY_CHAN4; /* then also change on ch4 */ + break; + case POKEY_OFFSET_AUDC3: + /* POKEY_AUDC[POKEY_CHAN3 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN3 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN3; + break; + case POKEY_OFFSET_AUDF4: + /* POKEY_AUDF[POKEY_CHAN4 + chip_offs] = val; */ + chan_mask = 1 << POKEY_CHAN4; + break; + case POKEY_OFFSET_AUDC4: + /* POKEY_AUDC[POKEY_CHAN4 + chip_offs] = val; */ + pokeysnd_AUDV[POKEY_CHAN4 + chip_offs] = (val & POKEY_VOLUME_MASK) * gain; + chan_mask = 1 << POKEY_CHAN4; + break; + case POKEY_OFFSET_AUDCTL: + /* POKEY_AUDCTL[chip] = val; */ + chan_mask = 15; /* all channels */ + break; + default: + chan_mask = 0; + break; + } + + /************************************************************/ + /* As defined in the manual, the exact Div_n_cnt values are */ + /* different depending on the frequency and resolution: */ + /* 64 kHz or 15 kHz - AUDF + 1 */ + /* 1 MHz, 8-bit - AUDF + 4 */ + /* 1 MHz, 16-bit - POKEY_AUDF[POKEY_CHAN1]+256*POKEY_AUDF[POKEY_CHAN2] + 7 */ + /************************************************************/ + + /* only reset the channels that have changed */ + + if (chan_mask & (1 << POKEY_CHAN1)) { + /* process channel 1 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH1_179) + new_val = POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 4; + else + new_val = (POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN1 + chip_offs]) { + Div_n_max[POKEY_CHAN1 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN1 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN1 + chip_offs] = new_val; + } + } + } + + if (chan_mask & (1 << POKEY_CHAN2)) { + /* process channel 2 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH1_CH2) { + if (POKEY_AUDCTL[chip] & POKEY_CH1_179) + new_val = POKEY_AUDF[POKEY_CHAN2 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 7; + else + new_val = (POKEY_AUDF[POKEY_CHAN2 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN1 + chip_offs] + 1) * POKEY_Base_mult[chip]; + } + else + new_val = (POKEY_AUDF[POKEY_CHAN2 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN2 + chip_offs]) { + Div_n_max[POKEY_CHAN2 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN2 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN2 + chip_offs] = new_val; + } + } + } + + if (chan_mask & (1 << POKEY_CHAN3)) { + /* process channel 3 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH3_179) + new_val = POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 4; + else + new_val = (POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN3 + chip_offs]) { + Div_n_max[POKEY_CHAN3 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN3 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN3 + chip_offs] = new_val; + } + } + } + + if (chan_mask & (1 << POKEY_CHAN4)) { + /* process channel 4 frequency */ + if (POKEY_AUDCTL[chip] & POKEY_CH3_CH4) { + if (POKEY_AUDCTL[chip] & POKEY_CH3_179) + new_val = POKEY_AUDF[POKEY_CHAN4 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 7; + else + new_val = (POKEY_AUDF[POKEY_CHAN4 + chip_offs] * 256 + + POKEY_AUDF[POKEY_CHAN3 + chip_offs] + 1) * POKEY_Base_mult[chip]; + } + else + new_val = (POKEY_AUDF[POKEY_CHAN4 + chip_offs] + 1) * POKEY_Base_mult[chip]; + + if (new_val != Div_n_max[POKEY_CHAN4 + chip_offs]) { + Div_n_max[POKEY_CHAN4 + chip_offs] = new_val; + + if (Div_n_cnt[POKEY_CHAN4 + chip_offs] > new_val) { + Div_n_cnt[POKEY_CHAN4 + chip_offs] = new_val; + } + } + } + + /* if channel is volume only, set current output */ + for (chan = POKEY_CHAN1; chan <= POKEY_CHAN4; chan++) { + if (chan_mask & (1 << chan)) { + +#ifdef VOL_ONLY_SOUND + +#ifdef __PLUS + if (g_Sound.nDigitized) +#endif + if ((POKEY_AUDC[chan + chip_offs] & POKEY_VOL_ONLY)) { + +#ifdef STEREO_SOUND + +#ifdef __PLUS + if (POKEYSND_stereo_enabled && chip & 0x01) +#else + if (chip & 0x01) +#endif + { + sampbuf_lastval2 += pokeysnd_AUDV[chan + chip_offs] + - POKEYSND_sampbuf_AUDV[chan + chip_offs]; + + sampbuf_val2[sampbuf_ptr2] = sampbuf_lastval2; + POKEYSND_sampbuf_AUDV[chan + chip_offs] = pokeysnd_AUDV[chan + chip_offs]; + sampbuf_cnt2[sampbuf_ptr2] = + (ANTIC_CPU_CLOCK - sampbuf_last2) * 128 * POKEYSND_samp_freq / 178979; + sampbuf_last2 = ANTIC_CPU_CLOCK; + sampbuf_ptr2++; + if (sampbuf_ptr2 >= POKEYSND_SAMPBUF_MAX) + sampbuf_ptr2 = 0; + if (sampbuf_ptr2 == sampbuf_rptr2) { + sampbuf_rptr2++; + if (sampbuf_rptr2 >= POKEYSND_SAMPBUF_MAX) + sampbuf_rptr2 = 0; + } + } + else +#endif /* STEREO_SOUND */ + { + POKEYSND_sampbuf_lastval += pokeysnd_AUDV[chan + chip_offs] + -POKEYSND_sampbuf_AUDV[chan + chip_offs]; + + POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; + POKEYSND_sampbuf_AUDV[chan + chip_offs] = pokeysnd_AUDV[chan + chip_offs]; + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = + (ANTIC_CPU_CLOCK - POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; + POKEYSND_sampbuf_ptr++; + if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_ptr = 0; + if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr) { + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + } + } + } + +#endif /* VOL_ONLY_SOUND */ + + /* I've disabled any frequencies that exceed the sampling + frequency. There isn't much point in processing frequencies + that the hardware can't reproduce. I've also disabled + processing if the volume is zero. */ + + /* if the channel is volume only */ + /* or the channel is off (volume == 0) */ + /* or the channel freq is greater than the playback freq */ + if ( (POKEY_AUDC[chan + chip_offs] & POKEY_VOL_ONLY) || + ((POKEY_AUDC[chan + chip_offs] & POKEY_VOLUME_MASK) == 0) + || (!BIENIAS_FIX && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))) + ) { + /* indicate the channel is 'on' */ + Outvol[chan + chip_offs] = 1; + + /* can only ignore channel if filtering off */ + if ((chan == POKEY_CHAN3 && !(POKEY_AUDCTL[chip] & POKEY_CH1_FILTER)) || + (chan == POKEY_CHAN4 && !(POKEY_AUDCTL[chip] & POKEY_CH2_FILTER)) || + (chan == POKEY_CHAN1) || + (chan == POKEY_CHAN2) + || (!BIENIAS_FIX && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))) + ) { + /* and set channel freq to max to reduce processing */ + Div_n_max[chan + chip_offs] = 0x7fffffffL; + Div_n_cnt[chan + chip_offs] = 0x7fffffffL; + } + } + } + } + + /* _enable(); */ /* RSF - removed for portability 31-MAR-97 */ +} + + +/*****************************************************************************/ +/* Module: pokeysnd_process() */ +/* Purpose: To fill the output buffer with the sound output based on the */ +/* pokey chip parameters. */ +/* */ +/* Author: Ron Fries */ +/* Date: January 1, 1997 */ +/* */ +/* Inputs: *buffer - pointer to the buffer where the audio output will */ +/* be placed */ +/* sndn - for mono, size of the playback buffer in samples */ +/* for stereo, size of the playback buffer in left samples */ +/* plus right samples. */ +/* num_pokeys - number of currently active pokeys to process */ +/* */ +/* Outputs: the buffer will be filled with n bytes of audio - no return val */ +/* Also the buffer will be written to disk if Sound recording is ON */ +/* */ +/*****************************************************************************/ + +static void pokeysnd_process_8(void *sndbuffer, int sndn) +{ + register UBYTE *buffer = (UBYTE *) sndbuffer; + register int n = sndn; + + register ULONG *div_n_ptr; + register UBYTE *samp_cnt_w_ptr; + register ULONG event_min; + register UBYTE next_event; +#ifdef CLIP_SOUND + register SWORD cur_val; /* then we have to count as 16-bit signed */ +#ifdef STEREO_SOUND + register SWORD cur_val2; +#endif +#else /* CLIP_SOUND */ + register UBYTE cur_val; /* otherwise we'll simplify as 8-bit unsigned */ +#ifdef STEREO_SOUND + register UBYTE cur_val2; +#endif +#endif /* CLIP_SOUND */ + register UBYTE *out_ptr; + register UBYTE audc; + register UBYTE toggle; + register UBYTE count; + register UBYTE *vol_ptr; + + /* set a pointer to the whole portion of the samp_n_cnt */ +#ifdef WORDS_BIGENDIAN + samp_cnt_w_ptr = ((UBYTE *) (&Samp_n_cnt[0]) + 3); +#else + samp_cnt_w_ptr = ((UBYTE *) (&Samp_n_cnt[0]) + 1); +#endif + + /* set a pointer for optimization */ + out_ptr = Outvol; + vol_ptr = pokeysnd_AUDV; + + /* The current output is pre-determined and then adjusted based on each */ + /* output change for increased performance (less over-all math). */ + /* add the output values of all 4 channels */ + cur_val = POKEYSND_SAMP_MIN; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + cur_val2 = POKEYSND_SAMP_MIN; +#endif /* STEREO_SOUND */ + + count = Num_pokeys; + do { + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val += *vol_ptr; + vol_ptr++; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + { + count--; + if (count) { + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + + if (*out_ptr++) + cur_val2 += *vol_ptr; + vol_ptr++; + } + else + break; + } +#endif /* STEREO_SOUND */ + count--; + } while (count); + +#ifdef SYNCHRONIZED_SOUND + cur_val += speaker; +#endif + + /* loop until the buffer is filled */ + while (n) { + /* Normally the routine would simply decrement the 'div by N' */ + /* counters and react when they reach zero. Since we normally */ + /* won't be processing except once every 80 or so counts, */ + /* I've optimized by finding the smallest count and then */ + /* 'accelerated' time by adjusting all pointers by that amount. */ + + /* find next smallest event (either sample or chan 1-4) */ + next_event = POKEY_SAMPLE; + event_min = READ_U32(samp_cnt_w_ptr); + + div_n_ptr = Div_n_cnt; + + count = 0; + do { + /* Though I could have used a loop here, this is faster */ + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN1 + (count << 2); + } + div_n_ptr++; + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN2 + (count << 2); + } + div_n_ptr++; + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN3 + (count << 2); + } + div_n_ptr++; + if (*div_n_ptr <= event_min) { + event_min = *div_n_ptr; + next_event = POKEY_CHAN4 + (count << 2); + } + div_n_ptr++; + + count++; + } while (count < Num_pokeys); + + /* if the next event is a channel change */ + if (next_event != POKEY_SAMPLE) { + /* shift the polynomial counters */ + + count = Num_pokeys; + do { + /* decrement all counters by the smallest count found */ + /* again, no loop for efficiency */ + div_n_ptr--; + *div_n_ptr -= event_min; + div_n_ptr--; + *div_n_ptr -= event_min; + div_n_ptr--; + *div_n_ptr -= event_min; + div_n_ptr--; + *div_n_ptr -= event_min; + + count--; + } while (count); + + + WRITE_U32(samp_cnt_w_ptr, READ_U32(samp_cnt_w_ptr) - event_min); + + /* since the polynomials require a mod (%) function which is + division, I don't adjust the polynomials on the SAMPLE events, + only the CHAN events. I have to keep track of the change, + though. */ + + P4 = (P4 + event_min) % POKEY_POLY4_SIZE; + P5 = (P5 + event_min) % POKEY_POLY5_SIZE; + P9 = (P9 + event_min) % POKEY_POLY9_SIZE; + P17 = (P17 + event_min) % POKEY_POLY17_SIZE; + + /* adjust channel counter */ + Div_n_cnt[next_event] += Div_n_max[next_event]; + + /* get the current AUDC into a register (for optimization) */ + audc = POKEY_AUDC[next_event]; + + /* set a pointer to the current output (for opt...) */ + out_ptr = &Outvol[next_event]; + + /* assume no changes to the output */ + toggle = FALSE; + + /* From here, a good understanding of the hardware is required */ + /* to understand what is happening. I won't be able to provide */ + /* much description to explain it here. */ + + /* if VOLUME only then nothing to process */ + if (!(audc & POKEY_VOL_ONLY)) { + /* if the output is pure or the output is poly5 and the poly5 bit */ + /* is set */ + if ((audc & POKEY_NOTPOLY5) || bit5[P5]) { + /* if the PURETONE bit is set */ + if (audc & POKEY_PURETONE) { + /* then simply toggle the output */ + toggle = TRUE; + } + /* otherwise if POLY4 is selected */ + else if (audc & POKEY_POLY4) { + /* then compare to the poly4 bit */ + toggle = (bit4[P4] == !(*out_ptr)); + } + else { + /* if 9-bit poly is selected on this chip */ + if (POKEY_AUDCTL[next_event >> 2] & POKEY_POLY9) { + /* compare to the poly9 bit */ + toggle = ((POKEY_poly9_lookup[P9] & 1) == !(*out_ptr)); + } + else { + /* otherwise compare to the poly17 bit */ + toggle = (((POKEY_poly17_lookup[P17 >> 3] >> (P17 & 7)) & 1) == !(*out_ptr)); + } + } + } + } + + /* check channel 1 filter (clocked by channel 3) */ + if ( POKEY_AUDCTL[next_event >> 2] & POKEY_CH1_FILTER) { + /* if we're processing channel 3 */ + if ((next_event & 0x03) == POKEY_CHAN3) { + /* check output of channel 1 on same chip */ + if (Outvol[next_event & 0xfd]) { + /* if on, turn it off */ + Outvol[next_event & 0xfd] = 0; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 -= pokeysnd_AUDV[next_event & 0xfd]; + else +#endif /* STEREO_SOUND */ + cur_val -= pokeysnd_AUDV[next_event & 0xfd]; + } + } + } + + /* check channel 2 filter (clocked by channel 4) */ + if ( POKEY_AUDCTL[next_event >> 2] & POKEY_CH2_FILTER) { + /* if we're processing channel 4 */ + if ((next_event & 0x03) == POKEY_CHAN4) { + /* check output of channel 2 on same chip */ + if (Outvol[next_event & 0xfd]) { + /* if on, turn it off */ + Outvol[next_event & 0xfd] = 0; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 -= pokeysnd_AUDV[next_event & 0xfd]; + else +#endif /* STEREO_SOUND */ + cur_val -= pokeysnd_AUDV[next_event & 0xfd]; + } + } + } + + /* if the current output bit has changed */ + if (toggle) { + if (*out_ptr) { + /* remove this channel from the signal */ +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 -= pokeysnd_AUDV[next_event]; + else +#endif /* STEREO_SOUND */ + cur_val -= pokeysnd_AUDV[next_event]; + + /* and turn the output off */ + *out_ptr = 0; + } + else { + /* turn the output on */ + *out_ptr = 1; + + /* and add it to the output signal */ +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled && (next_event & 0x04)) +#else + if ((next_event & 0x04)) +#endif + cur_val2 += pokeysnd_AUDV[next_event]; + else +#endif /* STEREO_SOUND */ + cur_val += pokeysnd_AUDV[next_event]; + } + } + } + else { /* otherwise we're processing a sample */ + /* adjust the sample counter - note we're using the 24.8 integer + which includes an 8 bit fraction for accuracy */ + + int iout; +#ifdef STEREO_SOUND + int iout2; +#endif +#ifdef INTERPOLATE_SOUND + if (cur_val != last_val) { + if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */ + iout = (cur_val * (*Samp_n_cnt) + + last_val * (Samp_n_max - *Samp_n_cnt)) + / Samp_n_max; + } + else + iout = cur_val; + last_val = cur_val; + } + else + iout = cur_val; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + if (cur_val2 != last_val2) { + if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */ + iout2 = (cur_val2 * (*Samp_n_cnt) + + last_val2 * (Samp_n_max - *Samp_n_cnt)) + / Samp_n_max; + } + else + iout2 = cur_val2; + last_val2 = cur_val2; + } + else + iout2 = cur_val2; +#endif /* STEREO_SOUND */ +#else /* INTERPOLATE_SOUND */ + iout = cur_val; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + iout2 = cur_val2; +#endif /* STEREO_SOUND */ +#endif /* INTERPOLATE_SOUND */ + +#ifdef VOL_ONLY_SOUND +#ifdef __PLUS + if (g_Sound.nDigitized) +#endif + { + if (POKEYSND_sampbuf_rptr != POKEYSND_sampbuf_ptr) { + int l; + if (POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] > 0) + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] -= 1280; + while ((l = POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr]) <= 0) { + POKEYSND_sampout = POKEYSND_sampbuf_val[POKEYSND_sampbuf_rptr]; + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + if (POKEYSND_sampbuf_rptr != POKEYSND_sampbuf_ptr) + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_rptr] += l; + else + break; + } + } + iout += POKEYSND_sampout; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + { + if (sampbuf_rptr2 != sampbuf_ptr2) { + int l; + if (sampbuf_cnt2[sampbuf_rptr2] > 0) + sampbuf_cnt2[sampbuf_rptr2] -= 1280; + while ((l = sampbuf_cnt2[sampbuf_rptr2]) <= 0) { + sampout2 = sampbuf_val2[sampbuf_rptr2]; + sampbuf_rptr2++; + if (sampbuf_rptr2 >= POKEYSND_SAMPBUF_MAX) + sampbuf_rptr2 = 0; + if (sampbuf_rptr2 != sampbuf_ptr2) + sampbuf_cnt2[sampbuf_rptr2] += l; + else + break; + } + } + iout2 += sampout2; + } +#endif /* STEREO_SOUND */ + } +#endif /* VOL_ONLY_SOUND */ + +#ifdef CLIP_SOUND + if (iout > POKEYSND_SAMP_MAX) { /* then check high limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; /* and limit if greater */ + } + else if (iout < POKEYSND_SAMP_MIN) { /* else check low limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; /* and limit if less */ + } + else { /* otherwise use raw value */ + *buffer++ = (UBYTE) iout; + } +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) { + if (iout2 > POKEYSND_SAMP_MAX) + *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; + else if (iout2 < POKEYSND_SAMP_MIN) + *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; + else + *buffer++ = (UBYTE) iout2; + } +#else /* __PLUS */ + if (Num_pokeys > 1) { + if ((POKEYSND_stereo_enabled ? iout2 : iout) > POKEYSND_SAMP_MAX) { /* then check high limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MAX; /* and limit if greater */ + } + else if ((POKEYSND_stereo_enabled ? iout2 : iout) < POKEYSND_SAMP_MIN) { /* else check low limit */ + *buffer++ = (UBYTE) POKEYSND_SAMP_MIN; /* and limit if less */ + } + else { /* otherwise use raw value */ + *buffer++ = (UBYTE) (POKEYSND_stereo_enabled ? iout2 : iout); + } + } +#endif /* __PLUS */ +#endif /* STEREO_SOUND */ +#else /* CLIP_SOUND */ + *buffer++ = (UBYTE) iout; /* clipping not selected, use value */ +#ifdef STEREO_SOUND + if (Num_pokeys > 1) +#ifdef ASAP + *buffer++ = (UBYTE) iout2; +#else + *buffer++ = (UBYTE) (POKEYSND_stereo_enabled ? iout2 : iout); +#endif +#endif /* STEREO_SOUND */ +#endif /* CLIP_SOUND */ + +#ifdef WORDS_BIGENDIAN + *(Samp_n_cnt + 1) += Samp_n_max; +#else + *Samp_n_cnt += Samp_n_max; +#endif + /* and indicate one less byte in the buffer */ + n--; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + if (Num_pokeys > 1) + n--; +#endif + } + } +#ifdef VOL_ONLY_SOUND +#ifdef __PLUS + if (g_Sound.nDigitized) +#endif + { + if (POKEYSND_sampbuf_rptr == POKEYSND_sampbuf_ptr) + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; +#ifdef STEREO_SOUND +#ifdef __PLUS + if (POKEYSND_stereo_enabled) +#endif + if (sampbuf_rptr2 == sampbuf_ptr2) + sampbuf_last2 = ANTIC_CPU_CLOCK; +#endif /* STEREO_SOUND */ + } +#endif /* VOL_ONLY_SOUND */ +} + +#ifdef SERIO_SOUND +static void Update_serio_sound_rf(int out, UBYTE data) +{ +#ifdef VOL_ONLY_SOUND +#ifdef __PLUS + if (g_Sound.nDigitized) { +#endif + int bits, pv, future; + if (!POKEYSND_serio_sound_enabled) return; + + pv = 0; + future = 0; + bits = (data << 1) | 0x200; + while (bits) + { + POKEYSND_sampbuf_lastval -= pv; + pv = (bits & 0x01) * pokeysnd_AUDV[3]; /* FIXME!!! - set volume from AUDV */ + POKEYSND_sampbuf_lastval += pv; + + POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = + (ANTIC_CPU_CLOCK + future-POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK + future; + POKEYSND_sampbuf_ptr++; + if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX ) + POKEYSND_sampbuf_ptr = 0; + if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr ) { + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + } + /* 1789790/19200 = 93 */ + future += 93; /* ~ 19200 bit/s - FIXME!!! set speed form AUDF [2] ??? */ + bits >>= 1; + } + POKEYSND_sampbuf_lastval -= pv; +#ifdef __PLUS + } +#endif +#endif /* VOL_ONLY_SOUND */ +} +#endif /* SERIO_SOUND */ + +void POKEYSND_SetVolume(int vol) +{ + if (vol > 100) + vol = 100; + if (vol < 0) + vol = 0; + + POKEYSND_volume = vol * 0x100 / 100; +} + +static void pokeysnd_process_16(void *sndbuffer, int sndn) +{ + UWORD *buffer = (UWORD *) sndbuffer; + int i; + + pokeysnd_process_8(buffer, sndn); + + for (i = sndn - 1; i >= 0; i--) { +#ifndef POKEYSND_SIGNED_SAMPLES + int smp = ((int) (((UBYTE *) buffer)[i]) - 0x80) * POKEYSND_volume; +#else + int smp = ((int) ((SBYTE *) buffer)[i]) * POKEYSND_volume; +#endif + + if (smp > 32767) + smp = 32767; + else if (smp < -32768) + smp = -32768; + + buffer[i] = smp; + } +} + +#ifdef SYNCHRONIZED_SOUND +static void Generate_sync_rf(unsigned int num_ticks) +{ + double new_samp_pos; + unsigned int ticks; + UBYTE *buffer = POKEYSND_process_buffer + POKEYSND_process_buffer_fill; + UBYTE *buffer_end = POKEYSND_process_buffer + POKEYSND_process_buffer_length; + + for (;;) { + double int_part; + new_samp_pos = samp_pos + ticks_per_sample; + new_samp_pos = modf(new_samp_pos, &int_part); + ticks = (unsigned int)int_part; + if (ticks > num_ticks) { + samp_pos -= num_ticks; + break; + } + if (buffer >= buffer_end) + break; + + samp_pos = new_samp_pos; + num_ticks -= ticks; + + if (POKEYSND_snd_flags & POKEYSND_BIT16) { + pokeysnd_process_16(buffer, POKEYSND_num_pokeys); + buffer += 2 * POKEYSND_num_pokeys; + } + else { + pokeysnd_process_8(buffer, POKEYSND_num_pokeys); + buffer += POKEYSND_num_pokeys; + } + + } + + POKEYSND_process_buffer_fill = buffer - POKEYSND_process_buffer; +} +#endif /* SYNCHRONIZED_SOUND */ + +#ifdef CONSOLE_SOUND +void POKEYSND_UpdateConsol(int set) +{ + if (!POKEYSND_console_sound_enabled) + return; +#ifdef SYNCHRONIZED_SOUND + if (set) + Update_synchronized_sound(); +#endif /* SYNCHRONIZED_SOUND */ + POKEYSND_UpdateConsol_ptr(set); +} + +static void Update_consol_sound_rf(int set) +{ +#ifdef SYNCHRONIZED_SOUND + if (set) + speaker = CONSOLE_VOL * GTIA_speaker; +#elif defined(VOL_ONLY_SOUND) + static int prev_atari_speaker = 0; + static unsigned int prev_cpu_clock = 0; + int d; +#ifdef __PLUS + if (!g_Sound.nDigitized) + return; +#endif + + if (!set && POKEYSND_samp_consol_val == 0) + return; + POKEYSND_sampbuf_lastval -= POKEYSND_samp_consol_val; + if (prev_atari_speaker != GTIA_speaker) { + POKEYSND_samp_consol_val = GTIA_speaker * 8 * 4; /* gain */ + prev_cpu_clock = ANTIC_CPU_CLOCK; + } + else if (!set) { + d = ANTIC_CPU_CLOCK - prev_cpu_clock; + if (d < 114) { + POKEYSND_sampbuf_lastval += POKEYSND_samp_consol_val; + return; + } + while (d >= 114 /* CPUL */) { + POKEYSND_samp_consol_val = POKEYSND_samp_consol_val * 99 / 100; + d -= 114; + } + prev_cpu_clock = ANTIC_CPU_CLOCK - d; + } + POKEYSND_sampbuf_lastval += POKEYSND_samp_consol_val; + prev_atari_speaker = GTIA_speaker; + + POKEYSND_sampbuf_val[POKEYSND_sampbuf_ptr] = POKEYSND_sampbuf_lastval; + POKEYSND_sampbuf_cnt[POKEYSND_sampbuf_ptr] = + (ANTIC_CPU_CLOCK - POKEYSND_sampbuf_last) * 128 * POKEYSND_samp_freq / 178979; + POKEYSND_sampbuf_last = ANTIC_CPU_CLOCK; + POKEYSND_sampbuf_ptr++; + if (POKEYSND_sampbuf_ptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_ptr = 0; + if (POKEYSND_sampbuf_ptr == POKEYSND_sampbuf_rptr) { + POKEYSND_sampbuf_rptr++; + if (POKEYSND_sampbuf_rptr >= POKEYSND_SAMPBUF_MAX) + POKEYSND_sampbuf_rptr = 0; + } +#endif /* !SYNCHRONIZED_SOUND && VOL_ONLY_SOUND */ +} +#endif /* CONSOLE_SOUND */ + +#ifdef VOL_ONLY_SOUND +static void Update_vol_only_sound_rf(void) +{ +#ifdef CONSOLE_SOUND + POKEYSND_UpdateConsol(0); /* mmm */ +#endif /* CONSOLE_SOUND */ +} +#endif /* VOL_ONLY_SOUND */ diff --git a/atari800/src/pokeysnd.h b/atari800/src/pokeysnd.h index 8cf15a8..6267f18 100644 --- a/atari800/src/pokeysnd.h +++ b/atari800/src/pokeysnd.h @@ -84,6 +84,7 @@ extern "C" { extern SLONG POKEYSND_playback_freq; extern UBYTE POKEYSND_num_pokeys; extern int POKEYSND_snd_flags; +extern int POKEYSND_volume; extern int POKEYSND_enable_new_pokey; extern int POKEYSND_stereo_enabled; diff --git a/atari800/src/roms/LICENSE b/atari800/src/roms/LICENSE new file mode 100644 index 0000000..6488bc5 --- /dev/null +++ b/atari800/src/roms/LICENSE @@ -0,0 +1,8 @@ +Altirra - Atari 800/800XL emulator +Kernel ROM replacement +Copyright (C) 2008-2020 Avery Lee + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without any warranty. \ No newline at end of file diff --git a/atari800/src/roms/altirra_5200_os.c b/atari800/src/roms/altirra_5200_os.c new file mode 100644 index 0000000..3314bff --- /dev/null +++ b/atari800/src/roms/altirra_5200_os.c @@ -0,0 +1,277 @@ +/* + * altirra_5200_os.c - 5200 OS ROM replacement + * + * Compiled from the sources in the emuos folder. + * + * Altirra - Atari 800/800XL emulator + * 5200 OS ROM replacement + * Copyright (C) 2008-2018 Avery Lee + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include "config.h" +#include "atari.h" + +UBYTE const ROM_altirra_5200_os[0x800] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, + 0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + 0x00,0x66,0xff,0x66,0x66,0xff,0x66,0x00, + 0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00, + 0x00,0x66,0x6c,0x18,0x30,0x66,0x46,0x00, + 0x1c,0x36,0x1c,0x38,0x6f,0x66,0x3b,0x00, + 0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + 0x00,0x0e,0x1c,0x18,0x18,0x1c,0x0e,0x00, + 0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, + 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00, + 0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, + 0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, + 0x00,0x06,0x0c,0x18,0x30,0x60,0x40,0x00, + 0x00,0x3c,0x66,0x6e,0x76,0x66,0x3c,0x00, + 0x00,0x18,0x38,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x7e,0x0c,0x18,0x0c,0x66,0x3c,0x00, + 0x00,0x0c,0x1c,0x3c,0x6c,0x7e,0x0c,0x00, + 0x00,0x7e,0x60,0x7c,0x06,0x66,0x3c,0x00, + 0x00,0x3c,0x60,0x7c,0x66,0x66,0x3c,0x00, + 0x00,0x7e,0x06,0x0c,0x18,0x30,0x30,0x00, + 0x00,0x3c,0x66,0x3c,0x66,0x66,0x3c,0x00, + 0x00,0x3c,0x66,0x3e,0x06,0x0c,0x38,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, + 0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00, + 0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x00,0x18,0x00, + 0x00,0x3c,0x66,0x6e,0x6e,0x60,0x3e,0x00, + 0x00,0x18,0x3c,0x66,0x66,0x7e,0x66,0x00, + 0x00,0x7c,0x66,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x00, + 0x00,0x78,0x6c,0x66,0x66,0x6c,0x78,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x7e,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x60,0x00, + 0x00,0x3e,0x60,0x60,0x6e,0x66,0x3e,0x00, + 0x00,0x66,0x66,0x7e,0x66,0x66,0x66,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x06,0x06,0x06,0x06,0x66,0x3c,0x00, + 0x00,0x66,0x6c,0x78,0x78,0x6c,0x66,0x00, + 0x00,0x60,0x60,0x60,0x60,0x60,0x7e,0x00, + 0x00,0x63,0x77,0x7f,0x6b,0x63,0x63,0x00, + 0x00,0x66,0x76,0x7e,0x7e,0x6e,0x66,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x60,0x60,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x6c,0x36,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x6c,0x66,0x00, + 0x00,0x3c,0x60,0x3c,0x06,0x06,0x3c,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x00, + 0x00,0x66,0x66,0x66,0x66,0x66,0x7e,0x00, + 0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00, + 0x00,0x66,0x66,0x3c,0x3c,0x66,0x66,0x00, + 0x00,0x66,0x66,0x3c,0x18,0x18,0x18,0x00, + 0x00,0x7e,0x0c,0x18,0x30,0x60,0x7e,0x00, + 0x00,0x1e,0x18,0x18,0x18,0x18,0x1e,0x00, + 0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, + 0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0x36,0x7f,0x7f,0x3e,0x1c,0x08,0x00, + 0x18,0x18,0x18,0x1f,0x1f,0x18,0x18,0x18, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, + 0x18,0x18,0x18,0xf8,0xf8,0x00,0x00,0x00, + 0x18,0x18,0x18,0xf8,0xf8,0x18,0x18,0x18, + 0x00,0x00,0x00,0xf8,0xf8,0x18,0x18,0x18, + 0x03,0x07,0x0e,0x1c,0x38,0x70,0xe0,0xc0, + 0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x07,0x03, + 0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff, + 0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f, + 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff, + 0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00, + 0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0, + 0x00,0x1c,0x1c,0x77,0x77,0x08,0x1c,0x00, + 0x00,0x00,0x00,0x1f,0x1f,0x18,0x18,0x18, + 0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, + 0x18,0x18,0x18,0xff,0xff,0x18,0x18,0x18, + 0x00,0x00,0x3c,0x7e,0x7e,0x7e,0x3c,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0x00,0x00,0x00,0xff,0xff,0x18,0x18,0x18, + 0x18,0x18,0x18,0xff,0xff,0x00,0x00,0x00, + 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, + 0x18,0x18,0x18,0x1f,0x1f,0x00,0x00,0x00, + 0x78,0x60,0x78,0x60,0x7e,0x18,0x1e,0x00, + 0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x00, + 0x00,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00, + 0x00,0x18,0x30,0x7e,0x30,0x18,0x00,0x00, + 0x00,0x18,0x0c,0x7e,0x0c,0x18,0x00,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x3c,0x18,0x00, + 0x00,0x00,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x00,0x3c,0x60,0x60,0x60,0x3c,0x00, + 0x00,0x06,0x06,0x3e,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x00,0x0e,0x18,0x3e,0x18,0x18,0x18,0x00, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x7c, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x66,0x00, + 0x00,0x18,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3c, + 0x00,0x60,0x60,0x6c,0x78,0x6c,0x66,0x00, + 0x00,0x38,0x18,0x18,0x18,0x18,0x3c,0x00, + 0x00,0x00,0x66,0x7f,0x7f,0x6b,0x63,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x66,0x66,0x00, + 0x00,0x00,0x3c,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x7c,0x60,0x60, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x06, + 0x00,0x00,0x7c,0x66,0x60,0x60,0x60,0x00, + 0x00,0x00,0x3e,0x60,0x3c,0x06,0x7c,0x00, + 0x00,0x18,0x7e,0x18,0x18,0x18,0x0e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x00,0x63,0x6b,0x7f,0x3e,0x36,0x00, + 0x00,0x00,0x66,0x3c,0x18,0x3c,0x66,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3e,0x0c,0x78, + 0x00,0x00,0x7e,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x18,0x3c,0x00, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x00,0x7e,0x78,0x7c,0x6e,0x66,0x06,0x00, + 0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00, + 0x10,0x18,0x1c,0x1e,0x1c,0x18,0x10,0x00, + 0x6c,0x00,0x02,0x48,0xa9,0x20,0x2c,0x0e, + 0xe8,0xd0,0x0d,0x45,0x00,0x8d,0x0e,0xe8, + 0xa5,0x00,0x8d,0x0e,0xe8,0x6c,0x10,0x02, + 0x30,0x0f,0xa9,0x80,0x45,0x00,0x8d,0x0e, + 0xe8,0xa5,0x00,0x8d,0x0e,0xe8,0x6c,0x0c, + 0x02,0x70,0x0f,0xa9,0x40,0x45,0x00,0x8d, + 0x0e,0xe8,0xa5,0x00,0x8d,0x0e,0xe8,0x6c, + 0x08,0x02,0x6a,0x2c,0x0e,0xe8,0xf0,0x0d, + 0x45,0x00,0x8d,0x0e,0xe8,0xa5,0x00,0x8d, + 0x0e,0xe8,0x6c,0x12,0x02,0x6a,0x24,0x00, + 0xf0,0x12,0x2c,0x0e,0xe8,0xd0,0x0d,0x45, + 0x00,0x8d,0x0e,0xe8,0xa5,0x00,0x8d,0x0e, + 0xe8,0x6c,0x14,0x02,0xa9,0x01,0x2c,0x0e, + 0xe8,0xd0,0x0d,0x45,0x00,0x8d,0x0e,0xe8, + 0xa5,0x00,0x8d,0x0e,0xe8,0x6c,0x16,0x02, + 0x2a,0x2c,0x0e,0xe8,0xd0,0x0d,0x45,0x00, + 0x8d,0x0e,0xe8,0xa5,0x00,0x8d,0x0e,0xe8, + 0x6c,0x18,0x02,0x2a,0x2c,0x0e,0xe8,0xd0, + 0x0d,0x45,0x00,0x8d,0x0e,0xe8,0xa5,0x00, + 0x8d,0x0e,0xe8,0x6c,0x1a,0x02,0x8a,0x48, + 0xba,0xbd,0x01,0x01,0x29,0x10,0xd0,0x03, + 0x6c,0x0e,0x02,0x68,0xaa,0x68,0x40,0xff, + 0xff,0xff,0x68,0xa8,0x68,0xaa,0x68,0x40, + 0x48,0x8a,0x48,0x98,0x48,0xe6,0x02,0xd0, + 0x08,0xe6,0x01,0xa5,0x04,0x30,0x02,0xe6, + 0x04,0xa5,0x03,0xd0,0xe5,0xa5,0x05,0x8d, + 0x02,0xd4,0xa5,0x06,0x8d,0x03,0xd4,0xa5, + 0x07,0x8d,0x00,0xd4,0xa0,0x00,0x24,0x04, + 0x10,0x02,0xa4,0x01,0xa2,0x08,0x98,0x55, + 0x08,0x9d,0x12,0xc0,0xca,0x10,0xf7,0xa2, + 0x07,0xbd,0x00,0xe8,0x95,0x11,0xca,0x10, + 0xf8,0x8d,0x0b,0xe8,0x6c,0x04,0x02,0xff, + 0xff,0xff,0x8a,0x48,0x98,0x48,0xad,0x09, + 0xe8,0x4a,0x29,0x0f,0xaa,0xbd,0x13,0xfd, + 0x6c,0x0a,0x02,0xff,0x0b,0x00,0x0a,0x0e, + 0x09,0x08,0x07,0x0d,0x06,0x05,0x04,0x0c, + 0x03,0x02,0x01,0x2c,0x0f,0xd4,0x8d,0x0f, + 0xd4,0x10,0x03,0x6c,0x06,0x02,0x6c,0x02, + 0x02,0x78,0xd8,0xa2,0xff,0x9a,0xad,0xfd, + 0xbf,0xc9,0xff,0xd0,0x03,0x6c,0xfe,0xbf, + 0xa2,0x00,0xa9,0x00,0x95,0x00,0x9d,0x00, + 0xc0,0x9d,0x00,0xd4,0x9d,0x00,0xe8,0xe8, + 0xd0,0xf2,0xa9,0xf8,0x8d,0x09,0xd4,0xa2, + 0x0b,0xbd,0x95,0xfe,0x9d,0x00,0x02,0xca, + 0x10,0xf7,0xa2,0x4f,0xbd,0xcd,0xfd,0x9d, + 0x00,0x10,0xca,0x10,0xf7,0xa2,0x13,0xbd, + 0xe8,0xbf,0x9d,0x50,0x10,0xca,0x10,0xf7, + 0xa9,0x10,0x85,0x0c,0xa9,0x0f,0x85,0x0d, + 0xa9,0x00,0x85,0x0e,0xa9,0x00,0x85,0x0f, + 0xa9,0x00,0x85,0x10,0xa9,0x04,0x8d,0x1b, + 0xc0,0xa2,0x0a,0xbd,0xc2,0xfd,0x9d,0x00, + 0x20,0xca,0x10,0xf7,0xa9,0x22,0x85,0x07, + 0xa9,0xc0,0x8d,0x0e,0xd4,0xa9,0x00,0x85, + 0x05,0xa9,0x20,0x85,0x06,0xa9,0x02,0x8d, + 0x0f,0xe8,0xa9,0xc0,0x85,0x00,0x8d,0x0e, + 0xe8,0xa9,0x78,0xc5,0x02,0xd0,0xfc,0x6c, + 0xfe,0xbf,0x70,0x70,0x70,0x42,0x00,0x10, + 0x82,0x07,0x41,0xc2,0xfd,0x21,0x6c,0x74, + 0x69,0x72,0x72,0x61,0x00,0x15,0x12,0x10, + 0x10,0x00,0x32,0x2f,0x2d,0x00,0x2b,0x65, + 0x72,0x6e,0x65,0x6c,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x2e,0x6f,0x77, + 0x00,0x70,0x6c,0x61,0x79,0x69,0x6e,0x67, + 0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x03,0xfc,0xb8, + 0xfc,0xb2,0xfc,0xa1,0xfe,0x02,0xfd,0xb2, + 0xfc,0x48,0xe6,0x0c,0xd0,0x04,0xa9,0x10, + 0x85,0x0c,0x68,0x40,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0x23,0xfd,0x31,0xfd,0x00,0xfc +}; diff --git a/atari800/src/roms/altirra_5200_os.h b/atari800/src/roms/altirra_5200_os.h new file mode 100644 index 0000000..07b9edd --- /dev/null +++ b/atari800/src/roms/altirra_5200_os.h @@ -0,0 +1,9 @@ +#ifndef ROMS_ALTIRRA_5200_OS_H_ +#define ROMS_ALTIRRA_5200_OS_H_ + +#include "config.h" +#include "atari.h" + +extern UBYTE const ROM_altirra_5200_os[0x800]; + +#endif /* ROMS_ALTIRRA_5200_OS_H_ */ diff --git a/atari800/src/roms/altirra_basic.c b/atari800/src/roms/altirra_basic.c new file mode 100644 index 0000000..648a4fc --- /dev/null +++ b/atari800/src/roms/altirra_basic.c @@ -0,0 +1,1045 @@ +/* + * altirra_basic.c - BASIC ROM replacement + * + * Compiled from the sources in the emuos folder. + * + * Altirra BASIC, version 1.58 + * Copyright (C) 2008-2022 Avery Lee + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include "config.h" +#include "atari.h" + +UBYTE const ROM_altirra_basic[] = +{ + 0xa6,0x08,0x30,0x45,0x38,0x26,0xb3,0x20, + 0x12,0xbb,0x4c,0x54,0xac,0x41,0x6c,0x74, + 0x69,0x72,0x72,0x61,0x20,0x38,0x4b,0x20, + 0x42,0x41,0x53,0x49,0x43,0x20,0x31,0x2e, + 0x35,0x38,0x00,0x9b,0x52,0x65,0x61,0x64, + 0x79,0x9b,0x00,0x9b,0x53,0x74,0x6f,0x70, + 0x70,0x65,0x64,0x00,0x9b,0x45,0x72,0x72, + 0x6f,0x72,0x2d,0x20,0x20,0x20,0x00,0x20, + 0x61,0x74,0x20,0x6c,0x69,0x6e,0x65,0x20, + 0x00,0x20,0x33,0xb1,0xa2,0x00,0x86,0xa6, + 0xa2,0x16,0x20,0x12,0xbb,0xa2,0xff,0x9a, + 0xe8,0x86,0xf2,0xe8,0x86,0xc2,0xa6,0xa6, + 0x20,0xa3,0xbb,0xf0,0x0b,0x20,0xb0,0xaa, + 0x20,0x07,0xa5,0x90,0xe8,0x4c,0x96,0xa8, + 0x20,0xd2,0xbb,0x4c,0x4c,0xa0,0x4c,0x6a, + 0x33,0x85,0x23,0x3a,0x42,0x16,0x1a,0x2e, + 0x2d,0x58,0x48,0x64,0x42,0x42,0x84,0x3b, + 0xa2,0xd4,0xb0,0x95,0x69,0xb3,0x3b,0x3b, + 0x3b,0x3b,0x41,0x41,0x4e,0x40,0x41,0x41, + 0x4e,0x45,0x41,0xd0,0xd4,0xd4,0x7d,0xb5, + 0xb5,0xcf,0xbb,0x3a,0xe8,0x41,0x8d,0x4b, + 0x41,0xe4,0x41,0x41,0xe8,0x7d,0x81,0x3b, + 0x3a,0x3a,0x41,0x3a,0x39,0xb1,0x38,0xee, + 0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, + 0x41,0x41,0x3a,0x3b,0x00,0x00,0x00,0x3c, + 0x3c,0x00,0x41,0xd4,0xd4,0xd4,0xe4,0xd4, + 0x39,0x39,0x3b,0x39,0x3b,0xd6,0x31,0x31, + 0x29,0x25,0x25,0x25,0x25,0x1b,0x1b,0x1b, + 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b, + 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00, + 0x00,0x00,0x00,0x20,0x00,0x31,0x00,0x1b, + 0x00,0x1b,0x1b,0x1b,0x1b,0x20,0x06,0x28, + 0x37,0x02,0x12,0x09,0x91,0x05,0xfb,0x87, + 0x05,0x16,0x0f,0x09,0x20,0x06,0x28,0x37, + 0xf3,0x09,0x10,0xf7,0x10,0xf6,0x00,0x10, + 0xe4,0x07,0x38,0x87,0x06,0x2c,0x3c,0xe7, + 0x29,0x07,0x2c,0x09,0x20,0x06,0x22,0x0f, + 0xe1,0x0c,0xe7,0x0b,0xe7,0x00,0x87,0x20, + 0x2c,0x07,0x12,0x09,0x03,0x03,0x87,0x01, + 0x09,0x89,0x09,0x14,0x02,0x0b,0x01,0x00, + 0x10,0xfd,0x09,0x20,0x23,0x07,0x1c,0x87, + 0x09,0x28,0x07,0x3a,0x09,0x20,0x06,0x9b, + 0x00,0x24,0x05,0x01,0x0e,0x20,0x02,0x07, + 0x36,0x14,0x03,0x0b,0x02,0x00,0x8f,0x20, + 0x3d,0x10,0x04,0x07,0x2d,0x87,0x82,0x07, + 0x2e,0x89,0x82,0x20,0x06,0x3a,0x14,0xe4, + 0x06,0x9b,0x16,0x01,0x00,0x0e,0x04,0x00, + 0x8f,0x10,0xfc,0x01,0x05,0x39,0x0d,0x37, + 0x87,0x29,0x13,0x2c,0x32,0x01,0x20,0x06, + 0x28,0x2b,0xf5,0x06,0x24,0x00,0xef,0x0a, + 0x26,0x06,0x2b,0x35,0xf1,0x06,0x2d,0x36, + 0xed,0x03,0x07,0x4e,0x4f,0x54,0x01,0x13, + 0x28,0xe4,0x03,0x57,0x0c,0xd3,0x14,0xd0, + 0x0b,0xcf,0x00,0x06,0x3d,0x1d,0xd7,0x06, + 0x3e,0x1e,0xd3,0x13,0x20,0xd0,0x89,0x20, + 0x06,0x2b,0x25,0xca,0x06,0x2d,0x26,0xc6, + 0x06,0x2a,0x24,0xc2,0x06,0x2f,0x27,0xbe, + 0x06,0x5e,0x23,0xba,0x06,0x3c,0x00,0xdb, + 0x06,0x3e,0x00,0x20,0x06,0x3d,0x22,0xae, + 0x06,0x25,0x56,0xaa,0x06,0x21,0x57,0xa6, + 0x06,0x26,0x58,0xa2,0x03,0x06,0x41,0x4e, + 0x44,0x13,0x2a,0x99,0x03,0x05,0x4f,0x52, + 0x13,0x29,0x92,0x09,0x06,0x3d,0x1f,0x8e, + 0x13,0x21,0x8b,0x89,0x20,0x06,0x3c,0x00, + 0x09,0x06,0x3e,0x00,0x10,0x06,0x3d,0x34, + 0xad,0x00,0x06,0x3e,0x30,0xa8,0x06,0x3d, + 0x2f,0xa4,0x13,0x32,0xa1,0x06,0x3d,0x31, + 0x9d,0x13,0x33,0x9a,0x99,0x87,0x11,0x05, + 0x14,0x87,0x2c,0x13,0x3c,0xf7,0x99,0x89, + 0x05,0xf4,0x99,0x87,0x06,0x2c,0x3c,0xfb, + 0x05,0xec,0x99,0x87,0x12,0x29,0x07,0x2c, + 0x09,0x95,0x95,0x95,0x9a,0x8d,0x93,0x05, + 0xfa,0x8d,0x82,0x20,0x08,0x04,0x03,0x03, + 0x49,0x46,0x16,0x82,0x15,0xfd,0x9a,0x20, + 0x0c,0x02,0x14,0x01,0x00,0x20,0x10,0x05, + 0x07,0x39,0x91,0x05,0x07,0x07,0x3b,0x28, + 0x87,0x29,0x07,0x2c,0x20,0x06,0x2c,0x12, + 0xe6,0x82,0x8b,0x20,0x3d,0x07,0x2d,0x87, + 0x07,0x19,0x54,0x4f,0x87,0x06,0x53,0x1a, + 0x01,0x82,0x54,0x45,0x50,0x9a,0x8d,0x93, + 0x8b,0x82,0x8d,0x93,0x9a,0x03,0x07,0x8d, + 0x01,0x06,0x3b,0x15,0x01,0x93,0x0b,0x01, + 0x00,0x15,0xee,0x93,0x05,0xf8,0x87,0x15, + 0xe8,0x07,0x1b,0x54,0x48,0x45,0x4e,0x0a, + 0xe0,0x0e,0x80,0x15,0xdc,0x03,0x05,0x89, + 0x01,0x15,0xd6,0x93,0x87,0x15,0xd2,0x93, + 0x9a,0x96,0x95,0x95,0x8b,0x82,0x8d,0x93, + 0x8b,0x93,0x8b,0x82,0x87,0x47,0x4f,0x06, + 0x54,0x17,0x06,0x53,0x55,0x42,0x13,0x18, + 0x01,0x4f,0x87,0x06,0x2c,0x12,0xfb,0x82, + 0x95,0x8d,0x93,0x95,0x95,0x89,0x82,0x87, + 0x06,0x2c,0x12,0x05,0x06,0x3b,0x15,0x04, + 0x82,0x87,0x05,0xf8,0x9a,0x15,0x01,0x89, + 0x82,0x03,0x04,0x8d,0x01,0x05,0x0b,0x15, + 0xe5,0x06,0x2c,0x12,0xfa,0x06,0x3b,0x15, + 0xf6,0x85,0x15,0xda,0x06,0x2c,0x12,0xef, + 0x06,0x3b,0x15,0xeb,0x00,0x52,0x45,0xcd, + 0x44,0x41,0x54,0xc1,0x49,0x4e,0x50,0x55, + 0xd4,0x43,0x4f,0x4c,0x4f,0xd2,0x4c,0x49, + 0x53,0xd4,0x45,0x4e,0x54,0x45,0xd2,0x4c, + 0x45,0xd4,0x49,0xc6,0x46,0x4f,0xd2,0x4e, + 0x45,0x58,0xd4,0x47,0x4f,0x54,0xcf,0x47, + 0x4f,0x20,0x54,0xcf,0x47,0x4f,0x53,0x55, + 0xc2,0x54,0x52,0x41,0xd0,0x42,0x59,0xc5, + 0x43,0x4f,0x4e,0xd4,0x43,0x4f,0xcd,0x43, + 0x4c,0x4f,0x53,0xc5,0x43,0x4c,0xd2,0x44, + 0x45,0xc7,0x44,0x49,0xcd,0x45,0x4e,0xc4, + 0x4e,0x45,0xd7,0x4f,0x50,0x45,0xce,0x4c, + 0x4f,0x41,0xc4,0x53,0x41,0x56,0xc5,0x53, + 0x54,0x41,0x54,0x55,0xd3,0x4e,0x4f,0x54, + 0xc5,0x50,0x4f,0x49,0x4e,0xd4,0x58,0x49, + 0xcf,0x4f,0xce,0x50,0x4f,0x4b,0xc5,0x50, + 0x52,0x49,0x4e,0xd4,0x52,0x41,0xc4,0x52, + 0x45,0x41,0xc4,0x52,0x45,0x53,0x54,0x4f, + 0x52,0xc5,0x52,0x45,0x54,0x55,0x52,0xce, + 0x52,0x55,0xce,0x53,0x54,0x4f,0xd0,0x50, + 0x4f,0xd0,0xbf,0x47,0x45,0xd4,0x50,0x55, + 0xd4,0x47,0x52,0x41,0x50,0x48,0x49,0x43, + 0xd3,0x50,0x4c,0x4f,0xd4,0x50,0x4f,0x53, + 0x49,0x54,0x49,0x4f,0xce,0x44,0x4f,0xd3, + 0x44,0x52,0x41,0x57,0x54,0xcf,0x53,0x45, + 0x54,0x43,0x4f,0x4c,0x4f,0xd2,0x4c,0x4f, + 0x43,0x41,0x54,0xc5,0x53,0x4f,0x55,0x4e, + 0xc4,0x4c,0x50,0x52,0x49,0x4e,0xd4,0x43, + 0x53,0x41,0x56,0xc5,0x43,0x4c,0x4f,0x41, + 0xc4,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0x45, + 0x4c,0x53,0xc5,0x45,0x4e,0x44,0x49,0xc6, + 0x44,0x50,0x4f,0x4b,0xc5,0x4c,0x4f,0x4d, + 0x45,0xcd,0xbf,0xbf,0xbf,0x42,0x50,0x55, + 0xd4,0x42,0x47,0x45,0xd4,0xbf,0x43,0xd0, + 0x45,0x52,0x41,0x53,0xc5,0x50,0x52,0x4f, + 0x54,0x45,0x43,0xd4,0x55,0x4e,0x50,0x52, + 0x4f,0x54,0x45,0x43,0xd4,0x44,0x49,0xd2, + 0x52,0x45,0x4e,0x41,0x4d,0xc5,0x4d,0x4f, + 0x56,0xc5,0x4d,0x49,0x53,0x53,0x49,0x4c, + 0xc5,0x50,0x4d,0x43,0x4c,0xd2,0x50,0x4d, + 0x43,0x4f,0x4c,0x4f,0xd2,0x50,0x4d,0x47, + 0x52,0x41,0x50,0x48,0x49,0x43,0xd3,0x50, + 0x4d,0x4d,0x4f,0x56,0xc5,0x00,0xa5,0xa4, + 0xf0,0x13,0xa0,0x00,0xa2,0x8c,0x20,0x4d, + 0xbc,0xa4,0xa4,0xf0,0x08,0x88,0xb1,0x80, + 0x91,0x8a,0x98,0xd0,0xf8,0x06,0xbe,0x60, + 0x68,0xa0,0x00,0xa5,0xa4,0xc9,0x04,0xb0, + 0x06,0x84,0xa4,0xa5,0xbe,0x30,0xf0,0xb1, + 0x80,0xaa,0xa5,0xbe,0x20,0x13,0xaa,0x85, + 0xd4,0x84,0xd5,0x85,0x8a,0x84,0x8b,0xa0, + 0x02,0xa5,0xa4,0x91,0x80,0x90,0xbf,0xf1, + 0xd4,0xf0,0xc6,0xb0,0xbd,0x85,0xd8,0xa9, + 0xff,0x85,0xd9,0x38,0x45,0xd8,0x65,0xd4, + 0x85,0xd6,0xa5,0xd5,0x69,0x00,0x85,0xd7, + 0x38,0xa5,0x90,0xe5,0xd6,0x85,0xda,0xa5, + 0x91,0xe5,0xd7,0x85,0xdb,0x20,0x3b,0xb6, + 0xa2,0x8c,0x20,0x77,0xbc,0x4c,0x61,0xa4, + 0xe6,0xf2,0xa4,0xf2,0xb1,0xf3,0x20,0x6f, + 0xa7,0xc9,0x9b,0xd0,0xf3,0xa5,0xa4,0xa4, + 0xbd,0x91,0x80,0xd0,0x05,0x20,0x59,0xa6, + 0x24,0x48,0x20,0x59,0xa6,0x30,0x50,0xc9, + 0x20,0x90,0x12,0xd0,0x06,0x20,0xa1,0xdb, + 0x4c,0xe2,0xa4,0xa4,0xf2,0xd1,0xf3,0xd0, + 0x5f,0xe6,0xf2,0xd0,0xe5,0xaa,0xbd,0x42, + 0xa6,0x48,0xbd,0x2b,0xa6,0x48,0x60,0xa2, + 0x05,0xb5,0x84,0x95,0x98,0xca,0x10,0xf9, + 0xa9,0x00,0x85,0xbd,0x48,0x20,0x00,0xd8, + 0x90,0x08,0xa9,0x80,0xa2,0x00,0x86,0xf2, + 0xf0,0x05,0x20,0xea,0xb3,0x30,0x31,0xa0, + 0x01,0x91,0x80,0x85,0xbe,0x88,0x8a,0x91, + 0x80,0xa0,0x03,0x84,0xa4,0xa9,0x80,0x4a, + 0xaa,0x90,0x0a,0xa5,0xa2,0x48,0xa5,0xa3, + 0x48,0xa9,0xff,0x48,0x48,0xbd,0x36,0xa0, + 0xa0,0xa1,0x85,0xa2,0x84,0xa3,0xb0,0x92, + 0x68,0xf0,0x8e,0x68,0x68,0x68,0x90,0xf8, + 0x68,0xf0,0x6c,0xc9,0xff,0xd0,0x05,0x68, + 0x68,0x68,0xb0,0xf4,0x85,0xf2,0x68,0x85, + 0xa4,0x2c,0x68,0x68,0x68,0x85,0xa3,0x68, + 0x85,0xa2,0x4c,0xe2,0xa4,0x20,0x44,0xda, + 0xa2,0x01,0x20,0xaf,0xdb,0x90,0x0c,0x29, + 0xdf,0xc9,0x11,0x90,0x1b,0xc9,0x17,0xb0, + 0x17,0xe9,0x06,0xe6,0xf2,0xa2,0x04,0x06, + 0xd4,0x26,0xd5,0xca,0xd0,0xf9,0x05,0xd4, + 0x85,0xd4,0xa5,0xd5,0xc9,0x10,0x90,0xda, + 0x8a,0xd0,0xb5,0x20,0xaa,0xd9,0xa9,0x0d, + 0xd0,0x10,0xa5,0xf2,0x48,0x20,0x20,0xb5, + 0x68,0x90,0x05,0x85,0xf2,0x4c,0xdd,0xa4, + 0xa9,0x0e,0xa2,0x79,0x20,0x6f,0xa7,0xb5, + 0x5b,0xe8,0x10,0xf8,0x4c,0x38,0xa7,0xa9, + 0x00,0x85,0xa4,0xa2,0x28,0x20,0x12,0xbb, + 0xe6,0xf2,0xa6,0xa4,0xe6,0xa4,0xbd,0x80, + 0x05,0x48,0xc6,0xf2,0xd0,0x0d,0x49,0x80, + 0xc9,0x1b,0xd0,0x07,0xa9,0xa0,0x20,0x71, + 0xbb,0xa9,0x9b,0x20,0x71,0xbb,0x68,0xc9, + 0x9b,0xd0,0xdf,0xa2,0x84,0x20,0x00,0xa6, + 0xa2,0x88,0x20,0x00,0xa6,0x4c,0x55,0xa0, + 0x8a,0x48,0xa5,0x90,0x38,0xf5,0x00,0x85, + 0xda,0xa5,0x91,0xf5,0x01,0x85,0xdb,0xb5, + 0x14,0x85,0xd4,0xf5,0x00,0x85,0xd8,0xb5, + 0x15,0x85,0xd5,0xf5,0x01,0x85,0xd9,0xb4, + 0x00,0xb5,0x01,0x20,0x37,0xb6,0x68,0xaa, + 0x4c,0x77,0xbc,0x57,0x76,0x85,0x16,0x6f, + 0x37,0x3d,0x65,0xc9,0x69,0xa9,0x88,0x7d, + 0x74,0xd4,0x5b,0x2a,0x7a,0x7a,0x31,0x88, + 0x55,0x6f,0xa5,0xa6,0xa6,0xa7,0xa4,0xa7, + 0xa7,0xa7,0xa4,0xa5,0xa5,0xa7,0xa6,0xa5, + 0xa4,0xa8,0xa7,0xa8,0xa8,0xa7,0xa7,0xa7, + 0xa6,0xe6,0xa2,0xd0,0x02,0xe6,0xa3,0xa0, + 0x00,0xb1,0xa2,0x60,0x20,0x59,0xa6,0x10, + 0x02,0xc6,0xa3,0xa2,0xa2,0x4c,0x9b,0xba, + 0xa4,0xa4,0x88,0xa9,0x3d,0x91,0x80,0x68, + 0x68,0x68,0x68,0x4c,0xe2,0xa4,0xa2,0x6d, + 0xa9,0xbe,0xa0,0x3d,0xd0,0x0b,0x20,0x6f, + 0xa7,0x84,0xbd,0xa2,0x05,0xa9,0xa3,0xa0, + 0x00,0x84,0xd5,0x84,0xd4,0x86,0xa9,0x85, + 0xaa,0xa4,0xf2,0xb1,0xf3,0xc9,0x2e,0xd0, + 0x04,0xa5,0xd5,0xf0,0x07,0x38,0xe9,0x3f, + 0xc9,0x1c,0xb0,0x65,0xa0,0x00,0xa6,0xf2, + 0xb1,0xa9,0xf0,0x5d,0x29,0x7f,0xe8,0xdd, + 0x7f,0x05,0xd0,0x43,0xb1,0xa9,0x0a,0xc8, + 0x90,0xee,0xa4,0xd5,0xf0,0x0c,0xc9,0x50, + 0xf0,0x08,0xbd,0x80,0x05,0x20,0x7b,0xa7, + 0x90,0x38,0x86,0xf2,0xa5,0xd4,0x20,0x6f, + 0xa7,0xaa,0xbd,0x84,0xa0,0xa0,0xa2,0x46, + 0xd5,0x90,0x18,0x86,0xbc,0x20,0x64,0xa6, + 0xa5,0xa2,0x48,0xa5,0xa3,0x48,0xa5,0xa4, + 0x48,0xa9,0x00,0x48,0xa6,0xbc,0xbd,0x99, + 0xa0,0xa0,0xa2,0x18,0x4c,0x4a,0xa5,0xa4, + 0xd5,0xd0,0x07,0xbd,0x7f,0x05,0xc9,0x2e, + 0xf0,0xc8,0x20,0x90,0xba,0xe6,0xd4,0xd0, + 0x9b,0xa5,0xd5,0xf0,0x26,0xd0,0x18,0x20, + 0x59,0xa6,0x18,0x65,0xa2,0x48,0xa5,0xa3, + 0x69,0x00,0x48,0xa5,0xa4,0x48,0xa5,0xf2, + 0x4c,0xe1,0xa4,0xa5,0xd2,0x30,0x09,0x4c, + 0xdd,0xa4,0x20,0x59,0xa6,0x20,0x6f,0xa7, + 0x20,0x64,0xa6,0x4c,0xe2,0xa4,0x20,0x59, + 0xa6,0xa4,0xf2,0xd1,0xf3,0xf0,0x06,0x20, + 0x59,0xa6,0x4c,0xdd,0xa4,0xe6,0xf2,0x20, + 0x59,0xa6,0xf0,0xe4,0xd0,0xdf,0x20,0xa1, + 0xdb,0xb1,0xf3,0xc9,0x3a,0xf0,0xd9,0xc9, + 0x9b,0xf0,0xd5,0x4c,0xdd,0xa4,0x20,0x6c, + 0xa7,0x4c,0xe2,0xa4,0x20,0x59,0xa6,0xa4, + 0xa4,0xe6,0xa4,0xf0,0x03,0x91,0x80,0x60, + 0x4c,0xf9,0xbe,0x48,0x38,0xe9,0x30,0xc9, + 0x0a,0x90,0x04,0xe9,0x11,0xc9,0x1a,0x68, + 0x60,0xe0,0x14,0x66,0xdf,0x20,0xa1,0xdb, + 0xb1,0xf3,0x38,0xe9,0x41,0xc9,0x1a,0xb0, + 0x1c,0xc8,0xb1,0xf3,0x20,0x7b,0xa7,0xb0, + 0x03,0xc8,0xd0,0xf6,0xaa,0xa9,0x00,0x85, + 0xd3,0xe0,0x24,0xf0,0x0c,0xe0,0x28,0xf0, + 0x07,0x24,0xdf,0x10,0x06,0x4c,0xdd,0xa4, + 0x6a,0x6a,0xc8,0x85,0xd2,0x84,0xda,0xa5, + 0x82,0x85,0xa9,0xa5,0x83,0x85,0xaa,0xa0, + 0x00,0xa6,0xf2,0xe8,0xb1,0xa9,0xf0,0x28, + 0x30,0x08,0xdd,0x7f,0x05,0xd0,0x17,0xc8, + 0xd0,0xf1,0xe4,0xda,0xd0,0x10,0x49,0x80, + 0xdd,0x7f,0x05,0xd0,0x09,0x86,0xf2,0xa5, + 0xd3,0x09,0x80,0x4c,0x35,0xa7,0x20,0x90, + 0xba,0xe6,0xd3,0x10,0xd2,0x4c,0x0d,0xbf, + 0xa5,0x89,0x85,0xd5,0x48,0xa5,0x88,0x85, + 0xd4,0x48,0xa5,0xda,0xaa,0x38,0xe5,0xf2, + 0x86,0xf2,0x85,0xdc,0x69,0x07,0xa2,0x88, + 0x20,0x4d,0xbc,0x38,0x68,0x85,0xd6,0xe5, + 0x84,0x85,0xda,0x68,0x85,0xd7,0xe5,0x85, + 0x85,0xdb,0xa5,0x88,0xe9,0x08,0xa8,0xa5, + 0x89,0xe9,0x00,0x20,0x9a,0xbc,0xa6,0xf2, + 0xa4,0xdc,0xa9,0x80,0x2c,0xa9,0x00,0xca, + 0x5d,0x80,0x05,0x88,0x91,0x84,0xd0,0xf5, + 0xa2,0x86,0xa5,0xdc,0x20,0x9b,0xba,0xca, + 0xca,0xe0,0x82,0xd0,0xf5,0xa5,0xd3,0x20, + 0x5b,0xba,0x20,0x44,0xda,0xa8,0x20,0x80, + 0xae,0x4c,0xe7,0xa7,0xa4,0xa4,0x84,0xd4, + 0x20,0x6f,0xa7,0xa6,0xf2,0xbd,0x80,0x05, + 0xc9,0x9b,0xf0,0x06,0xe6,0xf2,0xc9,0x22, + 0xd0,0xee,0x98,0xe5,0xd4,0xa4,0xd4,0x91, + 0x80,0xa2,0x12,0xe0,0x12,0x66,0xd2,0x4c, + 0xe2,0xa4,0xa5,0x88,0x85,0x8a,0xa5,0x89, + 0x85,0x8b,0x20,0x41,0xae,0xa0,0x01,0xb1, + 0x8a,0x10,0x03,0x4c,0x49,0xa0,0x20,0xc8, + 0xaf,0xa5,0x11,0x10,0x35,0xc4,0x94,0xb0, + 0x14,0xb1,0x8a,0x85,0x93,0xc8,0xb1,0x8a, + 0xc8,0x84,0x92,0xaa,0x20,0xc9,0xa8,0xa4, + 0x93,0xd0,0xe6,0x68,0x68,0xa0,0x01,0xb1, + 0x8a,0x30,0x0b,0xc8,0xb1,0x8a,0xa2,0x8a, + 0x20,0x9b,0xba,0x4c,0x8d,0xa8,0x4c,0x50, + 0xa0,0xbd,0xc1,0xa9,0x48,0xbd,0x6f,0xa9, + 0x48,0x60,0xa0,0x80,0x2c,0xa0,0x1c,0x84, + 0xc2,0x4c,0x13,0xbf,0x20,0xdf,0xb2,0xa4, + 0x92,0xb1,0x8a,0xc9,0x1b,0xd0,0x19,0xa5, + 0xd4,0xf0,0xc8,0xc8,0xc4,0x93,0xf0,0xe1, + 0xa2,0x7a,0xc8,0xb1,0x8a,0x95,0x5a,0xe8, + 0x10,0xf8,0x20,0xfc,0xb3,0x4c,0xfe,0xaf, + 0xa5,0xd4,0xd0,0xcd,0x38,0x24,0x18,0x66, + 0xbc,0xa9,0xff,0x85,0xbd,0xe6,0xbd,0xa4, + 0x93,0xc4,0x94,0xd0,0x1a,0x98,0x48,0xa0, + 0x01,0xb1,0x8a,0x30,0xb8,0x68,0xa2,0x8a, + 0x20,0x9b,0xba,0xb1,0x8a,0x30,0xae,0xc8, + 0xb1,0x8a,0x85,0x94,0xc8,0xd0,0xe2,0xb1, + 0x8a,0x85,0x93,0xc8,0xb1,0x8a,0xc9,0x3d, + 0xd0,0x05,0xc6,0xbd,0x10,0xd1,0x60,0xc9, + 0x3c,0xd0,0x09,0xa5,0xbd,0xd0,0xc8,0x24, + 0xbc,0x10,0x8a,0x60,0xc9,0x07,0xd0,0xbf, + 0xc8,0xc4,0x93,0xf0,0xb8,0xb1,0x8a,0xc9, + 0x1b,0xf0,0xb4,0xc9,0x0f,0x90,0x07,0xd0, + 0xef,0xc8,0xb1,0x8a,0x18,0x2c,0xa9,0x06, + 0x84,0x92,0x65,0x92,0xa8,0xd0,0xe1,0xb2, + 0xb2,0xe9,0xc3,0xd2,0xc9,0xe1,0xdb,0xcb, + 0x69,0xfa,0xfa,0xef,0xc3,0x70,0x0e,0x36, + 0xd4,0x00,0x2e,0x36,0x48,0x53,0xa5,0xb0, + 0x28,0x53,0x64,0x88,0x9e,0xcf,0xc3,0xdc, + 0x31,0xf2,0x30,0x40,0xa7,0xd1,0x47,0xdc, + 0x68,0x8a,0x91,0xa7,0x24,0xad,0xb3,0x74, + 0x63,0x41,0x98,0x21,0x9d,0xe1,0xf2,0xf2, + 0xf2,0xf2,0xf2,0x05,0xd0,0xc3,0x4a,0xf2, + 0xf2,0xf2,0xea,0xed,0xf2,0xad,0xa5,0xa5, + 0xa5,0xda,0xa5,0xb5,0x13,0x84,0x6a,0x14, + 0x94,0xa8,0xa8,0xaa,0xab,0xbc,0xab,0xb2, + 0xa8,0xae,0xaf,0xaf,0xaf,0xaf,0xae,0xe4, + 0xb0,0xac,0xab,0xac,0xac,0xac,0xa0,0xac, + 0xad,0xac,0xad,0xad,0xad,0xad,0xad,0xaf, + 0xad,0xad,0xac,0xaa,0xae,0xaf,0xac,0xa8, + 0xae,0xad,0xae,0xae,0xae,0xae,0xb0,0xae, + 0xae,0xb0,0xae,0xb0,0xb0,0xad,0xac,0xb2, + 0xbe,0xbe,0xbe,0xbe,0xbe,0xa9,0xa8,0xad, + 0xac,0xbe,0xbe,0xbe,0xb0,0xb0,0xbe,0xae, + 0xb0,0xb0,0xb0,0xab,0xb0,0xb0,0xb2,0xb1, + 0xb0,0xb1,0xb1,0x86,0xd4,0x85,0xd5,0x8a, + 0xa2,0x00,0xc1,0x8a,0xa0,0x01,0xa5,0xd5, + 0xf1,0x8a,0xb0,0x02,0xa2,0xfe,0xb5,0x8b, + 0x85,0xaa,0xb5,0x8a,0xa2,0x00,0x85,0xa9, + 0xb1,0xa9,0xc5,0xd5,0x90,0x08,0xd0,0x14, + 0xa1,0xa9,0xc5,0xd4,0xb0,0x0c,0xc8,0xa5, + 0xa9,0x71,0xa9,0x88,0x90,0xe8,0xe6,0xaa, + 0xd0,0xe4,0xf0,0x01,0x18,0xa5,0xa9,0xa4, + 0xaa,0x60,0xa4,0x92,0xb1,0x8a,0xc9,0x14, + 0xf0,0x02,0xc9,0x16,0x60,0xa4,0x92,0xe6, + 0x92,0xb1,0x8a,0xc9,0x12,0x60,0x18,0x65, + 0x90,0xaa,0xa9,0x00,0x65,0x91,0xec,0xe5, + 0x02,0xed,0xe6,0x02,0x90,0x03,0x4c,0x11, + 0xbf,0x24,0x97,0x10,0x2f,0x46,0x97,0xa5, + 0x90,0x48,0xa5,0x91,0x48,0xd0,0x1a,0xa9, + 0xfc,0x20,0x5a,0xae,0xa0,0x01,0xb1,0x90, + 0xaa,0xc8,0xb1,0x90,0x20,0x13,0xaa,0x90, + 0x14,0xa6,0xaa,0x20,0x2c,0xaf,0x20,0x52, + 0xae,0x20,0x61,0xaf,0x90,0xe1,0x68,0x85, + 0x91,0x68,0x85,0x90,0x60,0x4c,0xf7,0xbe, + 0x24,0x97,0x30,0xf8,0x38,0x66,0x97,0xa5, + 0x90,0x48,0xa5,0x91,0x48,0x20,0x61,0xaf, + 0xb0,0xe4,0xa9,0xfc,0x20,0x5a,0xae,0xa0, + 0x02,0xb1,0x90,0x85,0xd5,0x88,0xb1,0x90, + 0x85,0xd4,0xb1,0xd4,0xaa,0x88,0xb1,0xd4, + 0x20,0x2c,0xaf,0x20,0x52,0xae,0x4c,0xbd, + 0xaa,0xa0,0x01,0xb1,0xc4,0x10,0x57,0x4c, + 0x09,0xbf,0x20,0x6c,0xb2,0xb0,0x0a,0xe6, + 0x92,0xd0,0x06,0xa9,0xff,0x85,0xa7,0x85, + 0xa8,0xa6,0xa8,0xd0,0x05,0xa9,0x3f,0x20, + 0x79,0xbb,0xa9,0x00,0x85,0xf2,0xa6,0xa7, + 0x10,0x65,0xa5,0xc5,0xd0,0x15,0xa6,0xb7, + 0xa5,0xb8,0x20,0x13,0xaa,0x85,0xc4,0x84, + 0xc5,0xa9,0x00,0x85,0xc6,0xa0,0x02,0xb1, + 0xc4,0x85,0xb0,0xa4,0xc6,0xf0,0xba,0xc4, + 0xb0,0x90,0x27,0xa5,0xb0,0xa2,0xc4,0x20, + 0x9b,0xba,0xa0,0x01,0xa1,0x00,0x85,0xb7, + 0xb1,0xc4,0x85,0xb8,0x10,0xdb,0xa0,0x03, + 0xc4,0xb0,0xf0,0xe7,0xc8,0xb1,0xc4,0xc9, + 0x01,0xf0,0x06,0x88,0xb1,0xc4,0xa8,0xd0, + 0xef,0xc8,0x84,0xf2,0xa5,0xc4,0xa4,0xc5, + 0x20,0x20,0xbc,0xd0,0x18,0xa4,0xb0,0x24, + 0xa7,0x10,0x02,0x84,0xc6,0x20,0x5d,0xaa, + 0xd0,0x4f,0x8a,0xd0,0x08,0xf0,0x8a,0x20, + 0x34,0xbc,0x20,0x02,0xbc,0x20,0xdf,0xb2, + 0xa5,0x9d,0x10,0x3e,0xa2,0xe0,0x20,0x46, + 0xda,0xa4,0xf2,0x84,0xe0,0xb1,0xf3,0xc9, + 0x9b,0xf0,0x0d,0x24,0xa7,0x10,0x04,0xc9, + 0x2c,0xf0,0x05,0xc8,0xe6,0xe2,0xd0,0xed, + 0x84,0xf2,0xa2,0xe0,0x86,0x9c,0xa0,0xf3, + 0x20,0xc3,0xbc,0x20,0xe5,0xb5,0xa4,0xf2, + 0xb1,0xf3,0x49,0x9b,0xaa,0xf0,0xae,0xc8, + 0x84,0xf2,0xc9,0xb7,0xf0,0xa9,0x4c,0x05, + 0xbf,0x60,0x20,0x20,0xb5,0xb0,0xf7,0x20, + 0x7e,0xae,0xf0,0xe2,0x20,0x66,0xb2,0x86, + 0xc8,0x60,0x20,0xcc,0xbb,0x20,0xb0,0xbb, + 0x86,0xa6,0x4c,0x55,0xa0,0x20,0x8b,0xb2, + 0x4c,0xd6,0xbb,0x20,0xcc,0xbb,0xa9,0x06, + 0xa4,0x99,0xd0,0x07,0xa0,0xb7,0x20,0xe6, + 0xbb,0x10,0x03,0x20,0xb2,0xbb,0xa2,0x70, + 0x20,0xa3,0xbb,0xf0,0xe3,0xa2,0x00,0x20, + 0x32,0xbc,0xa9,0x09,0x20,0xfd,0xbb,0x10, + 0xed,0x20,0x44,0xda,0x20,0x5b,0xba,0xd0, + 0x10,0x20,0x7e,0xae,0xa2,0x9e,0xa1,0x00, + 0x29,0xc0,0x81,0x00,0xa9,0x08,0x20,0x9b, + 0xba,0xa5,0x9e,0xc5,0x88,0xa5,0x9f,0xe5, + 0x89,0x90,0xe6,0xa2,0xfc,0xb5,0x90,0x95, + 0x92,0xe8,0xd0,0xf9,0x4c,0x82,0xbc,0xa9, + 0x06,0x2c,0xa9,0x00,0x85,0xfb,0x60,0xa9, + 0x40,0x20,0xe4,0xb2,0x20,0x5d,0xaa,0xf0, + 0xf6,0x60,0xa5,0xb3,0xf0,0xfb,0x30,0x15, + 0x4c,0x25,0xbc,0x20,0x66,0xb2,0x8e,0xe7, + 0x02,0x8d,0xe8,0x02,0x20,0x5d,0xac,0x20, + 0x41,0xae,0x4c,0x49,0xa0,0xac,0xe8,0x02, + 0xad,0xe7,0x02,0x85,0x80,0x18,0x69,0x6c, + 0x85,0xae,0x98,0x69,0x00,0x85,0xaf,0xc8, + 0x84,0x81,0xa2,0xf0,0x86,0x96,0x20,0x25, + 0xac,0x86,0xb3,0xc6,0x81,0xa9,0x0a,0x85, + 0xc9,0x86,0xfb,0x86,0xd9,0xe8,0x86,0xd8, + 0xa2,0x86,0x20,0x77,0xbc,0xa0,0x03,0x84, + 0xd8,0xb9,0xa5,0xbf,0x91,0x82,0x88,0x10, + 0xf8,0xa2,0x8c,0x4c,0x77,0xbc,0xa9,0x04, + 0x20,0xe0,0xbb,0x38,0x66,0xbc,0x30,0x12, + 0x46,0xbc,0x20,0x52,0xaa,0xf0,0x32,0xd0, + 0x03,0x38,0x66,0xbc,0x20,0xcc,0xbb,0x20, + 0xb0,0xbb,0xa9,0x07,0x20,0xf6,0xac,0xa5, + 0xd4,0x05,0xd5,0xd0,0x2e,0xc6,0xb3,0xa2, + 0x74,0xb5,0x62,0x18,0x65,0x80,0x95,0x0e, + 0xa8,0xb5,0x63,0x65,0x81,0x95,0x0f,0x20, + 0x89,0xbc,0xe8,0xe8,0x10,0xeb,0x20,0x09, + 0xad,0xe6,0xb3,0x20,0x33,0xb1,0x20,0x01, + 0xac,0x06,0xbc,0xb0,0x03,0x4c,0x82,0xa8, + 0x4c,0x4c,0xa0,0x4c,0xef,0xbe,0x48,0xa6, + 0xa7,0xa0,0x00,0xa9,0xd4,0x20,0x0d,0xb1, + 0xa0,0x0e,0x20,0x43,0xbc,0x68,0x4c,0xfd, + 0xbb,0xa6,0xa7,0xa5,0x82,0xa4,0x83,0x20, + 0x0d,0xb1,0x38,0xa5,0x8c,0xe5,0x82,0xa8, + 0xa5,0x8d,0xe5,0x83,0x20,0x45,0xbc,0x4c, + 0x02,0xbc,0xa9,0x08,0x20,0xe0,0xbb,0x10, + 0x08,0x20,0xcc,0xbb,0xa9,0x08,0x20,0xb2, + 0xbb,0x20,0x44,0xda,0xa2,0x0c,0x38,0xb5, + 0x80,0xe5,0x82,0x95,0xd4,0xb5,0x81,0xe5, + 0x83,0x69,0x00,0x95,0xd5,0xca,0xca,0xd0, + 0xed,0xa9,0x0b,0x20,0xf6,0xac,0x20,0x09, + 0xad,0x4c,0xd6,0xbb,0x20,0x8b,0xb2,0x20, + 0xdd,0xb2,0xa9,0x0d,0x20,0xfd,0xbb,0xbd, + 0x43,0x03,0x4c,0x7b,0xae,0x20,0x8b,0xb2, + 0xa9,0x26,0x20,0xfd,0xbb,0x20,0xdd,0xb2, + 0xa4,0xa7,0xb9,0x4c,0x03,0xbe,0x4d,0x03, + 0x20,0xf7,0xba,0x20,0x7e,0xae,0x20,0xdd, + 0xb2,0xa6,0xa7,0xbd,0x4e,0x03,0x4c,0x7b, + 0xae,0x20,0x8b,0xb2,0xa9,0x08,0x20,0x02, + 0xb1,0x20,0x64,0xb2,0x8a,0xa6,0xa7,0x9d, + 0x4e,0x03,0xa9,0x25,0x4c,0xfd,0xbb,0x20, + 0x66,0xb2,0xe6,0x92,0x8a,0x2c,0xa9,0x03, + 0x48,0x20,0x61,0xb2,0x8a,0x48,0x20,0x64, + 0xb2,0x8a,0x48,0x20,0xdd,0xb2,0xa6,0xa7, + 0x68,0x9d,0x4b,0x03,0x68,0x9d,0x4a,0x03, + 0x68,0x4c,0xb9,0xbb,0x86,0xbe,0x20,0x66, + 0xb2,0x85,0xbd,0x86,0xbc,0x20,0x64,0xb2, + 0xa0,0x01,0x46,0xbe,0xb0,0x02,0x91,0xbc, + 0x8a,0x88,0x91,0xbc,0x60,0xa5,0xc9,0x85, + 0xab,0x20,0x6c,0xb2,0x46,0xbc,0x10,0x11, + 0x20,0x6f,0xbb,0x20,0x6f,0xbb,0xa5,0xab, + 0xc5,0xc9,0xd0,0xf7,0x38,0x66,0xbc,0xe6, + 0x92,0x20,0x52,0xaa,0xd0,0x07,0x24,0xbc, + 0x30,0xda,0x4c,0x6c,0xbb,0xc9,0x15,0xf0, + 0xeb,0xc9,0x12,0xf0,0xdb,0x46,0xbc,0x20, + 0xdf,0xb2,0xa5,0x9d,0x30,0x05,0x20,0x27, + 0xbb,0x30,0xde,0x20,0x1c,0xbc,0xa5,0xd6, + 0xd0,0x04,0xc6,0xd7,0x30,0xd3,0xc6,0xd6, + 0xa0,0x00,0xb1,0xf3,0x20,0x64,0xbb,0x10, + 0xed,0x20,0x41,0xae,0x20,0x52,0xaa,0xf0, + 0x07,0x20,0xf9,0xb3,0x86,0xb7,0x85,0xb8, + 0x60,0xa9,0x00,0x85,0xc5,0xaa,0xf0,0xf4, + 0x20,0x61,0xaf,0xb0,0x16,0xa9,0xfc,0x20, + 0x5b,0xae,0xa0,0x00,0xb1,0x90,0x10,0x0b, + 0xa9,0xf4,0x18,0x65,0x90,0x85,0x90,0xb0, + 0x02,0xc6,0x91,0x60,0x20,0x25,0xb0,0xd0, + 0x03,0x20,0x8b,0xb2,0x20,0xdd,0xb2,0xa6, + 0xa7,0xa0,0x00,0x20,0x43,0xbc,0xa9,0x07, + 0x20,0xfd,0xbb,0x20,0xf5,0xba,0xa0,0x02, + 0xb9,0xd2,0x00,0x91,0x9e,0xc8,0xc0,0x08, + 0xd0,0xf6,0x60,0x20,0x61,0xb2,0x8a,0x4c, + 0x79,0xbb,0x20,0x66,0xb2,0x20,0x4a,0xb1, + 0xa5,0xd4,0x8d,0xab,0x03,0x29,0x30,0x49, + 0x1c,0xa0,0xb4,0xa2,0x60,0x4c,0xe8,0xbb, + 0x20,0x25,0xb0,0x4c,0x79,0xbb,0x20,0x33, + 0xb1,0x6c,0x0a,0x00,0xa9,0x0c,0x8d,0xaa, + 0x03,0x20,0x25,0xb0,0x8d,0xfb,0x02,0xa9, + 0x11,0x4c,0xfd,0xbb,0x20,0x66,0xb2,0x86, + 0x95,0x85,0x96,0x60,0xb1,0x8a,0x85,0xbc, + 0xa5,0x90,0x48,0xa5,0x91,0x48,0xd0,0x14, + 0xa9,0xfc,0x20,0x5a,0xae,0xa0,0x00,0xb1, + 0x90,0x10,0x0e,0xc5,0xbc,0x08,0x20,0x52, + 0xae,0x28,0xf0,0x0c,0x20,0x61,0xaf,0x90, + 0xe7,0x68,0x85,0x91,0x68,0x85,0x90,0x2c, + 0x68,0x68,0xa9,0x10,0x20,0x66,0xaa,0x20, + 0xe2,0xb2,0x20,0xdd,0xb2,0xa0,0x00,0x20, + 0x36,0xaf,0x20,0x48,0xb5,0x20,0x52,0xaa, + 0xf0,0x03,0x20,0xdd,0xb2,0xa0,0x06,0x20, + 0x36,0xaf,0xa5,0xbc,0xa6,0x8a,0x20,0x2e, + 0xaf,0xa5,0x8b,0xa6,0x93,0x20,0x2e,0xaf, + 0x98,0x4c,0xb5,0xaf,0xa0,0x01,0x91,0x90, + 0xc8,0x8a,0x91,0x90,0xc8,0x60,0xa2,0x7a, + 0xb5,0x5a,0x91,0x90,0xc8,0xe8,0x10,0xf8, + 0x60,0x20,0x5e,0xaf,0xb0,0x15,0xc6,0x91, + 0xa0,0xfc,0xb1,0x90,0x10,0x02,0xa0,0xf0, + 0x20,0x28,0xaf,0xc0,0xf0,0xf0,0xea,0xa0, + 0x01,0xd0,0x5f,0x4c,0xf5,0xbe,0x20,0x79, + 0xaa,0xa5,0x8e,0xc5,0x90,0xa5,0x8f,0xe5, + 0x91,0x60,0x20,0x5e,0xaf,0x90,0x03,0x4c, + 0xfb,0xbe,0xa9,0xf0,0x20,0x5a,0xae,0xa0, + 0x0c,0xb1,0x90,0xf0,0xf2,0xa4,0x92,0xd1, + 0x8a,0xd0,0xe7,0x20,0x5b,0xba,0x20,0x70, + 0xba,0xa0,0x0b,0xa2,0x05,0xb1,0x90,0x88, + 0x95,0xe0,0xca,0x10,0xf8,0x85,0xbc,0x20, + 0x66,0xda,0x20,0x7e,0xae,0xa6,0x90,0xa4, + 0x91,0x20,0x98,0xdd,0x20,0xa5,0xba,0xf0, + 0x05,0x6a,0x45,0xbc,0x30,0x21,0xa0,0x0d, + 0x20,0xba,0xaf,0xa9,0x10,0xa2,0x90,0x4c, + 0x9b,0xba,0xb1,0x90,0xc8,0x85,0x8a,0xb1, + 0x90,0xc8,0x85,0x8b,0xb1,0x90,0x85,0x93, + 0xa0,0x02,0xb1,0x8a,0xc8,0x85,0x94,0x60, + 0x20,0xf9,0xb3,0xd0,0x6a,0x8a,0xf0,0x13, + 0x85,0xbc,0x20,0x5d,0xaa,0x48,0xc6,0xbc, + 0xf0,0x0a,0x20,0xf9,0xb3,0x20,0x5d,0xaa, + 0xf0,0xf4,0x68,0x60,0x68,0x4a,0xb0,0x0b, + 0xa9,0x04,0x20,0x66,0xaa,0xa9,0x00,0xa8, + 0x20,0x1c,0xaf,0x20,0xf9,0xb3,0x20,0x13, + 0xaa,0x90,0x09,0x85,0x8a,0x84,0x8b,0x68, + 0x68,0x4c,0x8d,0xa8,0x4c,0xfd,0xbe,0xa0, + 0x01,0xb1,0x8a,0x10,0x29,0xa6,0xba,0xa5, + 0xbb,0x30,0xf1,0x20,0x13,0xaa,0x85,0x8a, + 0x84,0x8b,0x4c,0xb5,0xa8,0x20,0x66,0xb2, + 0x48,0x8a,0x48,0x20,0xf7,0xb3,0xd0,0x0f, + 0x86,0x54,0x68,0x85,0x55,0x68,0x85,0x56, + 0xa5,0xc8,0xa2,0x60,0x86,0xa7,0x60,0x4c, + 0x0f,0xbf,0x20,0xf9,0xb3,0xd0,0xf8,0x8a, + 0xc9,0x04,0xb0,0xf3,0x0a,0x85,0xbc,0x20, + 0x64,0xb2,0x8a,0x48,0x20,0x8a,0xb0,0xa6, + 0xbc,0x9d,0x01,0xd2,0x68,0x9d,0x00,0xd2, + 0xa9,0x00,0x8d,0x08,0xd2,0xa9,0x03,0x8d, + 0x0f,0xd2,0x60,0x20,0xf9,0xb3,0xe0,0x04, + 0xb0,0xcd,0x8a,0x10,0x0a,0x20,0xf9,0xb3, + 0xe0,0x05,0xb0,0xc3,0x8a,0x69,0x04,0x85, + 0xbc,0x20,0x8a,0xb0,0xa6,0xbc,0x9d,0xc0, + 0x02,0x60,0x20,0x8d,0xb0,0x0a,0x0a,0x0a, + 0x0a,0x48,0x20,0x64,0xb2,0x68,0x65,0xd4, + 0x60,0xa0,0xb6,0xa9,0x08,0x20,0xe6,0xbb, + 0x20,0xe4,0xad,0x4c,0xd6,0xbb,0xbd,0x6a, + 0xb0,0x48,0x20,0xcc,0xbb,0x68,0x4c,0xb9, + 0xbb,0x21,0x23,0x24,0x00,0x20,0x20,0x66, + 0xb2,0x48,0x8a,0x48,0x20,0x64,0xb2,0x48, + 0x8a,0x48,0x20,0xdd,0xb2,0x20,0xec,0xba, + 0x20,0xea,0xb3,0x86,0xda,0x85,0xdb,0xa2, + 0x7c,0x68,0x95,0x58,0xe8,0x10,0xfa,0x24, + 0xc0,0x30,0x03,0x4c,0x3b,0xb6,0xa0,0xda, + 0x20,0xc1,0xbc,0xa2,0xd6,0x20,0xc3,0xbc, + 0x4c,0x9e,0xbc,0xa9,0x0b,0x2c,0xa9,0x07, + 0x48,0x20,0x8b,0xb2,0xa9,0x00,0x20,0x02, + 0xb1,0xa9,0x04,0x20,0x02,0xb1,0x68,0x4c, + 0xfd,0xbb,0x05,0xa7,0x85,0xbc,0x20,0x64, + 0xb2,0xa8,0x8a,0xa6,0xbc,0x9d,0x44,0x03, + 0x98,0x9d,0x45,0x03,0x60,0x20,0xf9,0xb3, + 0xca,0x30,0x33,0xf0,0x02,0xa2,0x01,0xbc, + 0xa6,0xbf,0xbd,0x83,0xb1,0x2d,0xe6,0x02, + 0x18,0x7d,0x83,0xb1,0xc5,0x91,0xb0,0x27, + 0x4c,0x11,0xbf,0x20,0x42,0xac,0xa2,0x70, + 0x20,0xd8,0xbb,0x8a,0x38,0xe9,0x10,0xaa, + 0xd0,0xf6,0xa2,0x07,0x9d,0x00,0xd2,0xca, + 0x10,0xfa,0xa5,0xb1,0xf0,0x34,0xa2,0x02, + 0xa9,0x00,0xa8,0x8d,0x1d,0xd0,0x18,0x85, + 0xb1,0x8d,0x07,0xd4,0x84,0xb2,0x90,0x0d, + 0xa9,0x03,0x8d,0x1d,0xd0,0x0d,0x6f,0x02, + 0x29,0xc1,0x8d,0x6f,0x02,0xad,0x2f,0x02, + 0x29,0xe3,0x1d,0xa3,0xbf,0x8d,0x2f,0x02, + 0xa0,0x11,0xa9,0x00,0x99,0x00,0xd0,0x88, + 0x10,0xfa,0x60,0xf8,0xfc,0x20,0xf9,0xb3, + 0x20,0x3f,0xb2,0xa4,0xb2,0xa9,0x00,0x88, + 0x91,0xa2,0xd0,0xfb,0x60,0x20,0xf9,0xb3, + 0xe0,0x08,0xb0,0xf8,0x86,0xbd,0xbd,0xf2, + 0xbf,0x85,0xbf,0x20,0x3f,0xb2,0x85,0xaa, + 0x20,0x5d,0xaa,0xd0,0x0b,0x20,0xf9,0xb3, + 0x8a,0xa6,0xbd,0x9d,0x00,0xd0,0x10,0xf0, + 0xc9,0x15,0xd0,0xd8,0x20,0xdf,0xb2,0x20, + 0xec,0xba,0x20,0xea,0xb3,0x8a,0x05,0xb2, + 0x45,0xb2,0xf0,0xc8,0x85,0xbe,0x05,0xa2, + 0x85,0xa9,0xa5,0xb2,0x38,0xe5,0xbe,0x24, + 0xc0,0x10,0x1c,0xa8,0x88,0xb1,0xa2,0x51, + 0xa9,0x25,0xbf,0x51,0xa2,0x91,0xa9,0x98, + 0xd0,0xf2,0xa4,0xbe,0x88,0xb1,0xa2,0x25, + 0xbf,0x91,0xa2,0x98,0xd0,0xf6,0x60,0xa0, + 0x00,0xaa,0xb1,0xa9,0x51,0xa2,0x25,0xbf, + 0x51,0xa9,0x91,0xa2,0xc8,0xca,0xd0,0xf2, + 0xb1,0xa2,0x25,0xbf,0x91,0xa2,0xc8,0xc4, + 0xb2,0xd0,0xf5,0x60,0x20,0xf9,0xb3,0x8a, + 0x29,0x03,0xaa,0xbd,0xf6,0xbf,0x49,0xff, + 0x85,0xbc,0x20,0xf7,0xb3,0x86,0xbd,0xa2, + 0x04,0x20,0x3f,0xb2,0x20,0xf7,0xb3,0x8a, + 0xf0,0x0c,0xa4,0xbd,0xb1,0xa2,0x45,0xbc, + 0x91,0xa2,0xc8,0xca,0xd0,0xf6,0x60,0xa0, + 0x00,0x84,0xa2,0xa9,0x03,0xe0,0x04,0xb0, + 0x03,0x8a,0x09,0x04,0x24,0xb2,0x10,0x03, + 0x4a,0x66,0xa2,0x05,0xb1,0xc9,0x08,0x90, + 0x03,0x85,0xa3,0x60,0xa0,0x1e,0x4c,0xd7, + 0xa8,0x20,0x8b,0xb2,0xe6,0x92,0x20,0xdf, + 0xb2,0x4c,0xea,0xb3,0xa2,0x00,0x86,0xa7, + 0x20,0x52,0xaa,0xc9,0x1c,0x38,0xd0,0x0d, + 0x20,0xf7,0xb3,0x8a,0x0a,0x0a,0x0a,0x0a, + 0x30,0x06,0x85,0xa7,0x18,0x86,0xa8,0x60, + 0x4c,0xed,0xbe,0x20,0x78,0xb2,0x8a,0xf0, + 0xf7,0x60,0x85,0x9d,0x20,0x24,0xb4,0xa4, + 0x92,0xb1,0x8a,0xc8,0x85,0xd4,0xb1,0x8a, + 0xc8,0x85,0xd5,0xb1,0x8a,0xc8,0x85,0xd6, + 0xb1,0x8a,0xc8,0x85,0xd7,0xb1,0x8a,0xc8, + 0x85,0xd8,0xb1,0x8a,0xc8,0x85,0xd9,0x84, + 0x92,0xd0,0x33,0x20,0x24,0xb4,0xa9,0x83, + 0x85,0x9d,0xa4,0x92,0xb1,0x8a,0x85,0xd6, + 0x38,0x65,0x92,0x85,0x92,0x98,0x38,0x65, + 0x8a,0x85,0xd4,0xa9,0x00,0x85,0xd7,0x65, + 0x8b,0x85,0xd5,0xd0,0x11,0xe6,0x92,0xa9, + 0x00,0x2c,0xa9,0x80,0x85,0x9c,0xa0,0x00, + 0x84,0x98,0x84,0x99,0x84,0x9a,0xa4,0x92, + 0xe6,0x92,0xb1,0x8a,0x30,0x38,0xc9,0x0f, + 0x90,0x98,0xf0,0xbf,0x48,0xaa,0xbd,0x62, + 0xb3,0x30,0x1e,0x85,0xa5,0xa4,0x98,0xf0, + 0x14,0xb1,0x80,0xaa,0xbd,0x62,0xb3,0x29, + 0x7e,0xc5,0xa5,0x90,0x08,0xe6,0x98,0x20, + 0x6b,0xb3,0x4c,0x05,0xb3,0xa5,0xa5,0xf0, + 0x09,0xc6,0x98,0xa4,0x98,0x68,0x91,0x80, + 0xd0,0xc4,0x68,0xc6,0x92,0x60,0x20,0x5b, + 0xba,0xa4,0x99,0xd0,0x12,0xa5,0x9e,0x69, + 0x02,0x85,0xa0,0xa5,0x9f,0x69,0x00,0x85, + 0xa1,0xa0,0x03,0x84,0x99,0xd0,0x03,0x20, + 0x28,0xb4,0x20,0x70,0xba,0xa0,0x00,0xb1, + 0x9e,0x85,0x9d,0xc9,0x40,0x90,0x97,0x4a, + 0x90,0x0a,0x4a,0xb0,0x91,0xa0,0x8c,0x20, + 0xc1,0xbc,0xd0,0x8a,0x24,0x9c,0x70,0xf2, + 0x4c,0x03,0xbf,0xbd,0x73,0xb4,0x48,0xbd, + 0x2c,0xb4,0x48,0x60,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10, + 0x10,0x10,0x10,0x10,0x10,0x18,0x14,0x12, + 0x12,0x14,0x8e,0x0a,0x0c,0x84,0x02,0x08, + 0x08,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x9a, + 0x9a,0x84,0x84,0x84,0x84,0x84,0x07,0x9e, + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e, + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e, + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e, + 0x16,0x16,0x16,0x9e,0x84,0x9e,0x9e,0x9e, + 0x9e,0x9e,0x9e,0x9e,0x20,0xb6,0xdd,0xa4, + 0x99,0x88,0xb1,0xae,0x85,0xd9,0xb1,0x80, + 0x85,0xd8,0x88,0xb1,0xae,0x85,0xd7,0xb1, + 0x80,0x85,0xd6,0x88,0xb1,0xae,0x85,0xd5, + 0xb1,0x80,0x85,0xd4,0x84,0x99,0x60,0x20, + 0xc7,0xb3,0x20,0xd2,0xd9,0xb0,0x05,0xa6, + 0xd4,0xa5,0xd5,0x60,0x4c,0x0f,0xbf,0xe6, + 0x92,0x20,0xdf,0xb2,0x20,0xea,0xb3,0x10, + 0xf2,0x4c,0x07,0xbf,0xa4,0x99,0x88,0xb1, + 0xae,0x85,0xe5,0xb1,0x80,0x85,0xe4,0x88, + 0xb1,0xae,0x85,0xe3,0xb1,0x80,0x85,0xe2, + 0x88,0xb1,0xae,0x85,0xe1,0xb1,0x80,0x85, + 0xe0,0x84,0x99,0x60,0xa4,0x99,0xf0,0x1c, + 0xa5,0xd4,0x91,0x80,0xa5,0xd5,0x91,0xae, + 0xc8,0xa5,0xd6,0x91,0x80,0xa5,0xd7,0x91, + 0xae,0xc8,0xa5,0xd8,0x91,0x80,0xa5,0xd9, + 0x91,0xae,0xc8,0x2c,0xa0,0x03,0x84,0x99, + 0x60,0x27,0x27,0x27,0x27,0x27,0x27,0x65, + 0xc1,0xcd,0xca,0xd8,0x43,0x54,0x5b,0x3f, + 0x47,0xcc,0xe1,0xd6,0xd6,0xd6,0xd6,0xd6, + 0xd6,0x5d,0xb8,0x5e,0xdb,0x4e,0x3f,0x9e, + 0x5b,0xdd,0xf0,0x0a,0x3f,0x55,0x69,0x71, + 0x76,0xc0,0x3c,0xc3,0x32,0x4d,0x64,0x5e, + 0x6c,0x72,0xe7,0xeb,0xc1,0x29,0x29,0x29, + 0x29,0xf2,0x18,0x0d,0xff,0xf2,0x3d,0xf2, + 0xd7,0xf2,0x47,0xf2,0xca,0xca,0x31,0x23, + 0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5, + 0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb7,0xb4, + 0xb7,0xb5,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4, + 0xb6,0xb5,0xb6,0xb6,0xb7,0xb7,0xb7,0xb6, + 0xb7,0xb7,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8, + 0xb8,0xb8,0xb8,0xb9,0xb9,0xb9,0xb9,0xb9, + 0xb9,0xb9,0xba,0xba,0xb8,0xb8,0xb8,0xb8, + 0xbe,0xba,0xba,0xb9,0xbe,0xba,0xbe,0xb7, + 0xbe,0xb8,0xbe,0xb9,0xb9,0xba,0xba,0x86, + 0x9d,0xbd,0x20,0xb5,0x85,0xda,0x20,0x04, + 0xb4,0xa6,0xd7,0xe4,0xe3,0xd0,0x04,0xa5, + 0xd6,0xc5,0xe2,0x08,0x68,0x85,0xc0,0xa0, + 0x00,0x90,0x06,0xa5,0xe2,0x85,0xd6,0xa6, + 0xe3,0x8a,0xf0,0x19,0xb1,0xd4,0xd1,0xe0, + 0xd0,0x1b,0xc8,0xd0,0xf7,0xe6,0xd5,0xe6, + 0xe1,0xca,0xd0,0xf0,0xf0,0x07,0xb1,0xd4, + 0xd1,0xe0,0xd0,0x09,0xc8,0xc4,0xd6,0xd0, + 0xf5,0xa5,0xc0,0x48,0x28,0x4c,0x33,0xb5, + 0x20,0x00,0xd8,0xa5,0xd5,0xf0,0x1a,0x60, + 0xbd,0x32,0xb5,0x85,0xda,0x20,0x04,0xb4, + 0x20,0xa5,0xba,0xf0,0x06,0xa9,0x16,0x90, + 0x04,0x4a,0x2c,0xa9,0x25,0x25,0xda,0xd0, + 0x07,0x4c,0x44,0xda,0xa5,0xd5,0xd0,0xf9, + 0xa2,0xf0,0xa0,0xbf,0x4c,0x89,0xdd,0x01, + 0x02,0x04,0x08,0x10,0x20,0x20,0x04,0xb4, + 0xd0,0xee,0xf0,0x05,0x20,0x04,0xb4,0xf0, + 0xe0,0xa5,0xd4,0x4c,0x3f,0xb5,0xa2,0x06, + 0xb5,0xd3,0x48,0xca,0xd0,0xfa,0x86,0xc1, + 0x20,0xc7,0xb3,0x20,0xec,0xba,0xc9,0x01, + 0x66,0xc0,0x10,0x03,0x20,0x6d,0xb9,0xa2, + 0xfa,0x68,0x95,0xe6,0xe8,0xd0,0xfa,0xa5, + 0xe0,0xf0,0x1c,0x06,0xc0,0x90,0x25,0x10, + 0x16,0xe9,0xc5,0x10,0x12,0xc9,0xfb,0x90, + 0x3d,0xaa,0xb5,0xe6,0x85,0xc1,0xb0,0x04, + 0xb5,0xe6,0xd0,0x32,0xe8,0x30,0xf9,0x20, + 0xc5,0xb5,0x20,0xcc,0xdd,0xb0,0x27,0x46, + 0xc1,0xb0,0x06,0x60,0xa5,0xe0,0x30,0x1e, + 0x60,0xa5,0xd4,0xf0,0x04,0x49,0x80,0x85, + 0xd4,0x60,0x20,0x04,0xb4,0x20,0xdb,0xda, + 0x4c,0xd4,0xb5,0x20,0xb9,0xb5,0x20,0x04, + 0xb4,0x20,0x66,0xda,0x90,0xdd,0x4c,0xff, + 0xbe,0x20,0xc4,0xb3,0x20,0x28,0xdb,0x4c, + 0xd4,0xb5,0x20,0xc4,0xb3,0xa6,0xe3,0xa5, + 0xe2,0xe4,0xd9,0xd0,0x02,0xc5,0xd8,0x90, + 0x04,0xa6,0xd9,0xa5,0xd8,0x85,0xda,0x86, + 0xdb,0x38,0xa5,0xd4,0xe5,0x8c,0xaa,0xa5, + 0xd5,0xe5,0x8d,0xa8,0x18,0x8a,0x65,0xda, + 0xaa,0x98,0x65,0xdb,0x48,0xa0,0x00,0x38, + 0x8a,0xf1,0xa0,0xaa,0xc8,0x68,0xf1,0xa0, + 0x85,0xe5,0x24,0x9c,0x30,0x0b,0x8a,0xc8, + 0xd1,0xa0,0xc8,0xa5,0xe5,0xf1,0xa0,0x90, + 0x0a,0xa0,0x03,0xa5,0xe5,0x91,0xa0,0x88, + 0x8a,0x91,0xa0,0xa4,0xe0,0xa5,0xe1,0x84, + 0xd6,0x85,0xd7,0xa0,0x00,0xa6,0xdb,0xf0, + 0x0e,0xb1,0xd6,0x91,0xd4,0xc8,0xd0,0xf9, + 0xe6,0xd7,0xe6,0xd5,0xca,0xd0,0xf2,0xa6, + 0xda,0xf0,0x08,0xb1,0xd6,0x91,0xd4,0xc8, + 0xca,0xd0,0xf8,0x60,0xe6,0x9a,0x60,0xa5, + 0x9a,0xf0,0x0a,0x20,0xfc,0xb3,0x86,0xe4, + 0x85,0xe5,0x20,0xc7,0xb3,0x20,0xfc,0xb3, + 0xa8,0x8a,0xd0,0x03,0x88,0x30,0x28,0xca, + 0x86,0xe2,0x84,0xe3,0x20,0xc7,0xb3,0xa2, + 0x03,0xe4,0x99,0xd0,0x0c,0xa5,0x9c,0xf0, + 0x08,0xa2,0x05,0xa5,0x9a,0xf0,0x02,0x06, + 0x9c,0xa5,0x9a,0xf0,0x0f,0xb5,0xd3,0xc5, + 0xe4,0xb5,0xd4,0xe5,0xe5,0xb0,0x03,0x4c, + 0x0b,0xbf,0xa2,0x11,0xb5,0xd3,0x85,0xd8, + 0x18,0xe5,0xe2,0xb5,0xd4,0x85,0xd9,0xe5, + 0xe3,0x90,0xec,0xa0,0xe2,0x84,0x9d,0x20, + 0xc1,0xbc,0xa2,0x7c,0x38,0xb5,0x5a,0xe5, + 0xe2,0x95,0x5a,0xa8,0xb5,0x5b,0xe5,0xe3, + 0x95,0x5b,0xe8,0xe8,0x10,0xee,0xc4,0xd6, + 0xaa,0xe5,0xd7,0xb0,0x04,0x84,0xd6,0x86, + 0xd7,0x4c,0x40,0xb7,0xa5,0x9a,0xf0,0x25, + 0x20,0xea,0xb3,0x86,0xd8,0x85,0xd9,0xa5, + 0x99,0x38,0xe9,0x04,0xa8,0x8a,0xf1,0x80, + 0xa5,0xd5,0xf1,0xae,0xb0,0x56,0x88,0xb1, + 0xae,0x85,0xd7,0xb1,0x80,0x85,0xd6,0x20, + 0x6b,0xbf,0x20,0xc4,0xb3,0x20,0xea,0xb3, + 0xa4,0x99,0x88,0x88,0x8a,0xd1,0x80,0xa5, + 0xd5,0xf1,0xae,0x88,0x84,0x99,0xb0,0x34, + 0xa5,0x9a,0xf0,0x05,0xa0,0xe0,0x20,0xc1, + 0xbc,0x20,0x8f,0xbf,0xa4,0x99,0xb1,0x80, + 0x65,0xd4,0x85,0x9e,0xaa,0xb1,0xae,0x65, + 0xd5,0x85,0x9f,0xc0,0x03,0xd0,0x04,0x85, + 0xa1,0x86,0xa0,0xa0,0x00,0x20,0x72,0xba, + 0xa5,0x9a,0x85,0x9b,0xa0,0x00,0x68,0x68, + 0x68,0x4c,0xec,0xb2,0x4c,0x03,0xbf,0x20, + 0xea,0xb3,0xa4,0x9a,0x84,0xe0,0x84,0xe1, + 0xf0,0x06,0x20,0xb6,0xdd,0x20,0xe7,0xb3, + 0xa8,0xe8,0x86,0xd6,0xd0,0x01,0xc8,0xa5, + 0xe0,0x18,0x69,0x01,0xaa,0xa9,0x00,0x65, + 0xe1,0x85,0xd9,0x20,0xb6,0xb7,0x20,0x6b, + 0xbf,0xb0,0xd1,0xc9,0x1a,0xb0,0xcd,0x20, + 0x8f,0xbf,0xa8,0xa5,0xd4,0xa6,0x8e,0x86, + 0xd4,0xa6,0x8f,0x86,0xd5,0xa2,0x8e,0x20, + 0x4d,0xbc,0xa0,0xfe,0xc6,0xa1,0xb1,0xa0, + 0x09,0x01,0x91,0xa0,0x4c,0x40,0xb7,0x20, + 0xfc,0xb3,0x85,0xd9,0x05,0xd4,0xf0,0xa4, + 0xa0,0x00,0x84,0xd6,0x20,0xb6,0xb7,0xa5, + 0xd8,0xa4,0xd9,0x4c,0x85,0xb7,0x84,0xd7, + 0x86,0xd8,0xa0,0x03,0xb1,0xae,0xf0,0x8c, + 0xa5,0x8e,0x38,0xe5,0x8c,0x85,0xd4,0xa5, + 0x8f,0xe5,0x8d,0x85,0xd5,0xa0,0x05,0xb9, + 0xd4,0x00,0x91,0xa0,0x88,0x10,0xf8,0x60, + 0x18,0x20,0x38,0xbb,0xd0,0x0f,0x20,0xe6, + 0xd8,0xa0,0xff,0xc8,0xb1,0xf3,0x10,0xfb, + 0x49,0x80,0x91,0xf3,0xc8,0xa5,0xf3,0xd0, + 0x0a,0x20,0xea,0xb3,0x8e,0xc0,0x05,0xa9, + 0xc0,0xa0,0x01,0xa2,0x05,0x85,0xd4,0x86, + 0xd5,0x84,0xd6,0xa2,0x00,0x86,0xd7,0xca, + 0x86,0x9d,0x60,0xa5,0x9b,0x85,0xc0,0x20, + 0xea,0xb3,0x20,0x20,0xb8,0x4c,0xaa,0xd9, + 0x8a,0x48,0xa5,0xd5,0x48,0x20,0xe7,0xb3, + 0xc6,0x9b,0x10,0xf4,0xa5,0xc0,0x48,0x6c, + 0xd4,0x00,0xbd,0xe8,0xb7,0x48,0x20,0xfc, + 0xb3,0xa9,0x02,0x85,0xd5,0x68,0xa8,0x90, + 0x0b,0x70,0x78,0x7c,0x84,0x20,0xea,0xb3, + 0xa0,0x00,0x84,0x9d,0xa2,0x00,0xf0,0x09, + 0x20,0xea,0xb3,0xa0,0x01,0xb1,0xd4,0xaa, + 0x88,0xb1,0xd4,0x4c,0xf7,0xba,0xa9,0x00, + 0x85,0xf2,0x85,0x9d,0x20,0x08,0xbc,0x20, + 0x20,0xb5,0x20,0x25,0xbc,0x90,0x41,0x4c, + 0xf1,0xbe,0xa5,0xd6,0x85,0xd4,0xa5,0xd7, + 0x85,0xd5,0x46,0x9d,0x4c,0xaa,0xd9,0x20, + 0xec,0xba,0x0a,0x30,0x05,0x20,0xa9,0xb8, + 0x90,0x14,0x20,0xb6,0xdd,0x20,0x48,0xb5, + 0x20,0x28,0xdb,0x20,0xa9,0xb8,0xa2,0xdb, + 0x20,0x00,0xbb,0x20,0x60,0xda,0xa5,0xfb, + 0xf0,0x08,0xa2,0xea,0x20,0x00,0xbb,0x20, + 0xdb,0xda,0x06,0xd4,0x06,0xc0,0x66,0xd4, + 0x60,0x20,0x04,0xbb,0x20,0xb6,0xdd,0x20, + 0xdb,0xda,0xa2,0xae,0xa0,0xdf,0xa9,0x0b, + 0x20,0x40,0xdd,0x20,0x0b,0xbb,0x4c,0xdb, + 0xda,0xa2,0x01,0x2c,0xa2,0x00,0x86,0xc0, + 0xa9,0xdb,0x18,0x65,0xfb,0xaa,0x20,0x00, + 0xbb,0x20,0x28,0xdb,0x20,0x04,0xbb,0x20, + 0xc2,0xba,0xa5,0xd4,0x29,0x7f,0xaa,0xa9, + 0x00,0xe0,0x40,0x90,0x06,0xe0,0x45,0xb0, + 0x02,0xb5,0x95,0x29,0x1f,0xc9,0x10,0x90, + 0x02,0x69,0x01,0x24,0xd4,0x10,0x03,0x49, + 0x03,0x38,0x65,0xc0,0x85,0xc1,0x20,0x0b, + 0xbb,0x20,0x60,0xda,0x46,0xc1,0x90,0x06, + 0x20,0xfe,0xba,0x20,0x66,0xda,0x20,0xec, + 0xba,0x20,0x04,0xbb,0x20,0xb6,0xdd,0x20, + 0xdb,0xda,0xa2,0xbd,0xa0,0xbf,0xa9,0x06, + 0x20,0xb8,0xb8,0x46,0xc1,0x90,0x03,0x20, + 0xb9,0xb5,0x24,0xd4,0x50,0x04,0xa9,0x00, + 0x85,0xd9,0x60,0xa2,0x05,0xa9,0x3f,0x85, + 0xd4,0xad,0x0a,0xd2,0xc9,0xa0,0xb0,0xf9, + 0x95,0xd4,0x29,0x0f,0xc9,0x0a,0xb0,0xf1, + 0xca,0xd0,0xee,0x4c,0x00,0xdc,0xad,0xe5, + 0x02,0x38,0xe5,0x90,0xa8,0xad,0xe6,0x02, + 0xe5,0x91,0xaa,0x98,0x4c,0xf7,0xba,0x20, + 0xcd,0xde,0xb0,0x06,0x60,0x20,0xc0,0xdd, + 0x90,0xfa,0x4c,0x0f,0xbf,0x20,0xd1,0xde, + 0x4c,0x62,0xb9,0x20,0x04,0xbb,0xa5,0xd4, + 0xf0,0x47,0x30,0xee,0x18,0x69,0x40,0x85, + 0xd4,0xa2,0x09,0x86,0xc0,0xa9,0x00,0x69, + 0x11,0xca,0xbc,0xc2,0xb9,0xc4,0xd5,0x90, + 0xf6,0x46,0xd4,0xb0,0x02,0x29,0x0f,0x85, + 0xd5,0x20,0xb6,0xdd,0xa2,0xe0,0x20,0x06, + 0xbb,0xa2,0xe6,0xa0,0x05,0x20,0x89,0xdd, + 0x20,0x28,0xdb,0xa2,0xe0,0x20,0x0d,0xbb, + 0x20,0x66,0xda,0xa2,0x6c,0xa0,0xdf,0x20, + 0x98,0xdd,0x20,0xdb,0xda,0x06,0xc0,0x10, + 0xd8,0x60,0xff,0x87,0x66,0x55,0x36,0x24, + 0x14,0x07,0x02,0xe0,0x60,0x08,0x20,0xfc, + 0xb3,0xbd,0x78,0x02,0x48,0x20,0x44,0xda, + 0x68,0x28,0xf0,0x04,0x4a,0x4a,0x49,0x03, + 0x29,0x03,0xaa,0xbd,0xe6,0xbf,0x85,0xd4, + 0x06,0xd4,0xf0,0x0a,0xa9,0x80,0x6a,0x48, + 0x20,0x48,0xb5,0x68,0x85,0xd4,0x60,0x20, + 0xea,0xb3,0x20,0xb6,0xdd,0x4c,0xe7,0xb3, + 0x20,0xf7,0xb9,0x25,0xe1,0xa8,0x8a,0x25, + 0xe0,0x84,0xd5,0x4c,0xf9,0xba,0x20,0xf7, + 0xb9,0x05,0xe1,0xa8,0x8a,0x05,0xe0,0x90, + 0xf0,0x20,0xf7,0xb9,0x45,0xe1,0xa8,0x8a, + 0x45,0xe0,0x90,0xe5,0xa5,0xba,0xa6,0xd4, + 0xf0,0x03,0xa6,0xbb,0x2c,0xa5,0xc3,0x4c, + 0xf7,0xba,0x20,0xea,0xb3,0x20,0x3f,0xb2, + 0xaa,0xa5,0xa2,0x4c,0xf7,0xba,0x20,0xf7, + 0xb9,0xa5,0xe0,0x29,0x08,0x49,0x0c,0x45, + 0xd4,0xa8,0xa5,0xe0,0x29,0x03,0xaa,0xbd, + 0x4f,0xb5,0x39,0x00,0xd0,0x20,0x3f,0xb5, + 0x4c,0x40,0xb7,0x0a,0x0a,0x26,0x9f,0x0a, + 0x26,0x9f,0x18,0x65,0x86,0x85,0x9e,0xa5, + 0x9f,0x29,0x03,0x65,0x87,0x85,0x9f,0x60, + 0xa0,0x02,0xb1,0x9e,0xc8,0x85,0xd4,0xb1, + 0x9e,0xc8,0x85,0xd5,0xb1,0x9e,0xc8,0x85, + 0xd6,0xb1,0x9e,0xc8,0x85,0xd7,0xb1,0x9e, + 0xc8,0x85,0xd8,0xb1,0x9e,0x85,0xd9,0x60, + 0xa0,0x00,0xb1,0xa9,0xc8,0xaa,0x10,0xfa, + 0x98,0xa2,0xa9,0x18,0x75,0x00,0x95,0x00, + 0x90,0x02,0xf6,0x01,0x60,0xa5,0xe0,0x45, + 0xd4,0x10,0x07,0x24,0x6a,0x45,0xd4,0x38, + 0x2a,0x60,0x05,0xd4,0xf0,0xfb,0xa2,0xfa, + 0xb5,0xda,0xd5,0xe6,0xd0,0xee,0xe8,0xd0, + 0xf7,0x60,0xa5,0xd4,0x0a,0x30,0x08,0x08, + 0x20,0x44,0xda,0x28,0xb0,0x18,0x60,0x4a, + 0x69,0xbc,0xb0,0xfa,0xaa,0xa9,0x00,0xa8, + 0x15,0xda,0x94,0xda,0xe8,0xd0,0xf9,0xa8, + 0xf0,0xec,0xa5,0xd4,0x10,0xe8,0x20,0xfe, + 0xba,0x4c,0x60,0xda,0xa5,0xd4,0x85,0xc0, + 0x29,0x7f,0x85,0xd4,0x60,0xa2,0x00,0x86, + 0xd5,0x85,0xd4,0x4c,0xaa,0xd9,0xa2,0xf0, + 0xa0,0xbf,0xd0,0x0b,0xa2,0xe6,0xa0,0x05, + 0x4c,0xa7,0xdd,0xa2,0xe6,0xa0,0x05,0x4c, + 0x98,0xdd,0xa9,0x00,0x85,0xa7,0x86,0xf3, + 0xa6,0xf3,0xbd,0x0d,0xa0,0xf0,0x18,0x20, + 0x64,0xbb,0x10,0xf4,0x20,0xaa,0xd9,0x20, + 0xe6,0xd8,0xa0,0x00,0xb1,0xf3,0x48,0x29, + 0x7f,0x20,0x64,0xbb,0x68,0x10,0xf3,0x60, + 0x08,0x20,0x51,0xda,0x20,0xd2,0xd9,0xa0, + 0x00,0x28,0xa5,0xd5,0x90,0x02,0xf0,0x03, + 0x20,0x4d,0xbb,0xa5,0xd4,0x48,0x4a,0x4a, + 0x4a,0x4a,0x20,0x58,0xbb,0x68,0x29,0x0f, + 0xc9,0x0a,0x90,0x02,0x69,0x06,0x69,0x30, + 0x91,0xf3,0xc8,0x60,0xe6,0xf3,0xd0,0x02, + 0xe6,0xf4,0xd0,0x05,0xa9,0x9b,0x2c,0xa9, + 0x20,0xc6,0xab,0xd0,0x04,0xa6,0xc9,0x86, + 0xab,0xa6,0xa7,0x20,0x91,0xbb,0x98,0x10, + 0x21,0x84,0xc2,0xa5,0xa7,0x49,0x70,0xd0, + 0x05,0x85,0xa6,0x20,0xd6,0xbb,0x4c,0x13, + 0xbf,0x85,0x2f,0xbd,0x4a,0x03,0x85,0x2a, + 0xbd,0x47,0x03,0x48,0xbd,0x46,0x03,0x48, + 0xa5,0x2f,0x60,0x20,0x32,0xbc,0x20,0x56, + 0xe4,0x10,0xf7,0xc0,0x88,0xd0,0xd2,0x60, + 0xa9,0x04,0xa6,0xa7,0x9d,0x4a,0x03,0xa9, + 0x03,0xa6,0xa7,0x48,0x20,0x08,0xbc,0x20, + 0x0d,0xb1,0x68,0x20,0xda,0xbb,0x20,0x25, + 0xbc,0x4c,0x7f,0xbb,0x20,0xd2,0xbb,0x4c, + 0xdf,0xb2,0xa2,0x70,0x86,0xa7,0xa6,0xa7, + 0xa9,0x0c,0x9d,0x42,0x03,0x4c,0x56,0xe4, + 0x38,0x6e,0xbb,0x03,0xa0,0xb3,0xa2,0x70, + 0x86,0xa7,0x84,0xbf,0x48,0x20,0xd8,0xbb, + 0x68,0x9d,0x4a,0x03,0xa5,0xbf,0xa0,0xbf, + 0x20,0x0d,0xb1,0xa9,0x03,0xa6,0xa7,0x9d, + 0x42,0x03,0x20,0x56,0xe4,0x4c,0x7f,0xbb, + 0xa4,0xd6,0xa5,0xd7,0xf0,0x02,0xa0,0xff, + 0x84,0xad,0xb1,0xd4,0x85,0xac,0xe6,0xb3, + 0xa9,0x9b,0x91,0xd4,0xa5,0xd4,0xa4,0xd5, + 0x85,0xf3,0x84,0xf4,0x60,0x98,0x48,0xa4, + 0xad,0xa5,0xac,0x91,0xf3,0xc6,0xb3,0x68, + 0xa8,0x60,0x86,0xa7,0x20,0x51,0xda,0xa0, + 0x05,0xa9,0x80,0x20,0x0d,0xb1,0x9d,0x42, + 0x03,0xa0,0xff,0xa9,0x00,0x9d,0x49,0x03, + 0x98,0x9d,0x48,0x03,0x60,0x85,0xd8,0x84, + 0xd9,0x8a,0x48,0x38,0x38,0xa5,0x90,0xe5, + 0xd4,0x85,0xda,0xa5,0x91,0xe5,0xd5,0x85, + 0xdb,0x18,0xa5,0x90,0x85,0xd6,0x65,0xd8, + 0xa8,0xa5,0x91,0x85,0xd7,0x65,0xd9,0x20, + 0x89,0xbc,0x20,0x9a,0xbc,0x68,0xaa,0xa0, + 0xd8,0x20,0xc3,0xbc,0xe8,0xe8,0xe0,0x92, + 0xd0,0xf7,0x85,0x0f,0xa5,0x90,0x85,0x0e, + 0x60,0xb0,0x0c,0xcd,0xe6,0x02,0xd0,0x05, + 0xcc,0xe5,0x02,0xf0,0xf3,0x90,0xf1,0x4c, + 0x11,0xbf,0x84,0xd4,0x85,0xd5,0xa0,0x00, + 0xa6,0xdb,0xe8,0xd0,0x08,0x88,0xb1,0xd6, + 0x91,0xd4,0x98,0xd0,0xf8,0xc6,0xd5,0xc6, + 0xd7,0xca,0xd0,0xf1,0xa6,0xda,0xf0,0x08, + 0x88,0xb1,0xd6,0x91,0xd4,0xca,0xd0,0xf8, + 0x60,0xa2,0xd4,0xb5,0x00,0x18,0x79,0x00, + 0x00,0x95,0x00,0xb5,0x01,0x79,0x01,0x00, + 0x95,0x01,0x60,0xa9,0xff,0x85,0xbd,0x4a, + 0x85,0xbe,0xa9,0x00,0x85,0xa2,0x85,0xa3, + 0x85,0xa7,0x20,0xdf,0xb2,0xa4,0x99,0xf0, + 0x2f,0xa5,0x9d,0x10,0x16,0x20,0xd2,0xbb, + 0xa9,0x08,0x20,0xb2,0xbb,0x20,0xfb,0xbc, + 0x4c,0xd6,0xbb,0x20,0x52,0xaa,0xf0,0x18, + 0x20,0xdd,0xb2,0x20,0xfc,0xb3,0x86,0xa2, + 0x85,0xa3,0x20,0x52,0xaa,0xf0,0x03,0x20, + 0xf7,0xb3,0x86,0xbd,0xa5,0xd5,0x85,0xbe, + 0xa6,0xa2,0xa5,0xa3,0x20,0x13,0xaa,0x85, + 0xa2,0x84,0xa3,0x38,0x6e,0xfe,0x02,0xa0, + 0x00,0x18,0xb1,0xa2,0x85,0xd4,0xe5,0xbd, + 0xc8,0xb1,0xa2,0x85,0xd5,0xe5,0xbe,0x90, + 0x04,0x0e,0xfe,0x02,0x60,0x20,0x24,0xbb, + 0x20,0x6f,0xbb,0xa0,0x03,0xb1,0xa2,0xc8, + 0x85,0xbf,0xb1,0xa2,0xc8,0x84,0xa4,0xc9, + 0x36,0xf0,0x13,0xc9,0x37,0xf0,0x35,0x48, + 0xa0,0x05,0xa2,0xa3,0x20,0xf9,0xbd,0x20, + 0x6f,0xbb,0x68,0x4a,0xf0,0x2b,0x20,0x12, + 0xbe,0xc9,0x16,0xf0,0x09,0x20,0xea,0xbd, + 0xa4,0xa4,0xc4,0xbf,0xd0,0xf0,0xa0,0x02, + 0xb1,0xa2,0xc5,0xbf,0xf0,0x04,0xa4,0xbf, + 0xd0,0xc3,0xa2,0xa2,0x20,0x9b,0xba,0x20, + 0x6c,0xbb,0x10,0x9b,0xa2,0x28,0x20,0x16, + 0xbb,0x20,0x12,0xbe,0xc9,0x9b,0xf0,0xde, + 0x20,0x71,0xbb,0x10,0xf4,0x48,0xa2,0xfa, + 0x20,0x12,0xbe,0x95,0xda,0xe8,0xd0,0xf8, + 0x68,0xc9,0x0d,0xf0,0x03,0x4c,0x27,0xbb, + 0xa9,0x24,0x20,0x71,0xbb,0x38,0x20,0x38, + 0xbb,0x09,0x80,0x88,0x91,0xf3,0x4c,0x2a, + 0xbb,0x20,0xd5,0xbd,0x20,0x12,0xbe,0x85, + 0xd4,0xf0,0x0a,0x20,0x12,0xbe,0x20,0x71, + 0xbb,0xc6,0xd4,0xd0,0xf6,0xa9,0x22,0x4c, + 0x71,0xbb,0x29,0x7f,0xa4,0x82,0xa6,0x83, + 0x20,0xf9,0xbd,0xc9,0xa8,0xd0,0x02,0xe6, + 0xa4,0x60,0xaa,0x30,0xed,0xc9,0x0f,0x90, + 0xac,0xf0,0xce,0xe9,0x12,0xa0,0x19,0xa2, + 0xbe,0x85,0xbc,0x84,0xa9,0x86,0xaa,0x98, + 0x4c,0x06,0xbe,0x20,0x90,0xba,0xc6,0xbc, + 0x10,0xf9,0xa4,0xaa,0x20,0x20,0xbc,0x4c, + 0x2a,0xbb,0xa4,0xa4,0xe6,0xa4,0xb1,0xa2, + 0x60,0xac,0xa4,0xba,0xbb,0xbf,0x20,0x47, + 0x4f,0x54,0x4f,0xa0,0x20,0x47,0x4f,0x53, + 0x55,0x42,0xa0,0x20,0x54,0x4f,0xa0,0x20, + 0x53,0x54,0x45,0x50,0xa0,0x20,0x54,0x48, + 0x45,0x4e,0xa0,0xa3,0x3c,0xbd,0x3c,0xbe, + 0x3e,0xbd,0xbc,0xbe,0xbd,0xde,0xaa,0xab, + 0xad,0xaf,0x20,0x4e,0x4f,0x54,0xa0,0x20, + 0x4f,0x52,0xa0,0x20,0x41,0x4e,0x44,0xa0, + 0xa8,0xa9,0xbd,0xbd,0x3c,0xbd,0x3c,0xbe, + 0x3e,0xbd,0xbc,0xbe,0xbd,0xab,0xad,0xa8, + 0xa8,0xa8,0xa8,0xa8,0xac,0x53,0x54,0x52, + 0xa4,0x43,0x48,0x52,0xa4,0x55,0x53,0xd2, + 0x41,0x53,0xc3,0x56,0x41,0xcc,0x4c,0x45, + 0xce,0x41,0x44,0xd2,0x41,0x54,0xce,0x43, + 0x4f,0xd3,0x50,0x45,0x45,0xcb,0x53,0x49, + 0xce,0x52,0x4e,0xc4,0x46,0x52,0xc5,0x45, + 0x58,0xd0,0x4c,0x4f,0xc7,0x43,0x4c,0x4f, + 0xc7,0x53,0x51,0xd2,0x53,0x47,0xce,0x41, + 0x42,0xd3,0x49,0x4e,0xd4,0x50,0x41,0x44, + 0x44,0x4c,0xc5,0x53,0x54,0x49,0x43,0xcb, + 0x50,0x54,0x52,0x49,0xc7,0x53,0x54,0x52, + 0x49,0xc7,0x81,0xa5,0xa1,0xa6,0x81,0x42, + 0x55,0x4d,0x50,0xa8,0x81,0x48,0x45,0x58, + 0xa4,0x81,0x44,0x50,0x45,0x45,0xcb,0x81, + 0x56,0x53,0x54,0x49,0x43,0xcb,0x48,0x53, + 0x54,0x49,0x43,0xcb,0x50,0x4d,0x41,0x44, + 0xd2,0x45,0x52,0xd2,0x00,0xe6,0xc2,0xe6, + 0xc2,0xe6,0xc2,0xe6,0xc2,0xe6,0xc2,0xe6, + 0xc2,0xe6,0xc2,0xe6,0xc2,0xe6,0xc2,0xe6, + 0xc2,0xe6,0xc2,0xe6,0xc2,0xe6,0xc2,0xe6, + 0xc2,0xe6,0xc2,0xe6,0xc2,0xe6,0xc2,0xe6, + 0xc2,0xe6,0xc2,0xa2,0xff,0x9a,0x86,0x11, + 0x20,0x42,0xac,0xa0,0x00,0x8c,0xfe,0x02, + 0x84,0xd5,0xb1,0x8a,0x85,0xba,0xc8,0xb1, + 0x8a,0x85,0xbb,0xa5,0xc2,0x85,0xd4,0x84, + 0xc2,0xc9,0x80,0xd0,0x08,0xa2,0x1e,0x20, + 0x12,0xbb,0x4c,0x53,0xbf,0x85,0xc3,0xa5, + 0x96,0x30,0x08,0xa6,0x95,0x38,0x66,0x96, + 0x20,0xfe,0xaf,0xa2,0x27,0x20,0x12,0xbb, + 0x20,0x24,0xbb,0xa5,0xbb,0x85,0xd5,0x30, + 0x0c,0xa2,0x32,0x20,0x16,0xbb,0xa5,0xba, + 0x85,0xd4,0x20,0x24,0xbb,0x20,0x6c,0xbb, + 0x4c,0x55,0xa0,0xa9,0x00,0x85,0xd4,0xa2, + 0x10,0x06,0xd4,0x2a,0xb0,0x18,0xa8,0x06, + 0xd6,0x26,0xd7,0x90,0x0c,0x18,0xa5,0xd4, + 0x65,0xd8,0x85,0xd4,0x98,0x65,0xd9,0xb0, + 0x05,0xca,0xd0,0xe5,0x85,0xd5,0x60,0xa5, + 0xd4,0xa4,0xd5,0x0a,0x26,0xd5,0x65,0xd4, + 0x85,0xd4,0x98,0x65,0xd5,0x06,0xd4,0x2a, + 0x85,0xd5,0x60,0x1c,0x0c,0x00,0x00,0x80, + 0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x43,0x53,0x45,0x50,0x44, + 0x3a,0x2a,0x2e,0x2a,0x9b,0xbd,0x03,0x43, + 0x18,0x69,0x61,0x3e,0x01,0x60,0x25,0x47, + 0x91,0xbe,0x46,0x81,0x65,0x78,0x84,0x3f, + 0x07,0x96,0x92,0x60,0x37,0xbf,0x64,0x59, + 0x64,0x09,0x56,0x40,0x01,0x57,0x07,0x96, + 0x33,0x40,0x90,0x00,0x00,0x00,0x00,0xff, + 0x01,0x00,0x40,0x57,0x29,0x57,0x79,0x51, + 0x40,0x01,0x00,0x00,0x00,0x00,0xfc,0xf3, + 0xcf,0x3f,0x00,0xa0,0x00,0x05,0x51,0xaa +}; + diff --git a/atari800/src/roms/altirra_basic.h b/atari800/src/roms/altirra_basic.h new file mode 100644 index 0000000..10ec20e --- /dev/null +++ b/atari800/src/roms/altirra_basic.h @@ -0,0 +1,8 @@ +#ifndef ROMS_ATARI_BASIC_H_ +#define ROMS_ATARI_BASIC_H_ + +#include "atari.h" + +extern UBYTE const ROM_altirra_basic[0x2000]; + +#endif /* ROMS_ATARI_BASIC_H_ */ diff --git a/atari800/src/roms/altirraos_800.c b/atari800/src/roms/altirraos_800.c new file mode 100644 index 0000000..b56cd5a --- /dev/null +++ b/atari800/src/roms/altirraos_800.c @@ -0,0 +1,1300 @@ +/* + * altirraos_800.c - 400/800 OS ROM replacement + * + * Compiled from the sources in the emuos folder. + * + * Altirra - Atari 800/800XL emulator + * Kernel ROM replacement, version 3.11 + * Copyright (C) 2008-2018 Avery Lee + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include "atari.h" + +UBYTE const ROM_altirraos_800[0x2800] = +{ + 0x20,0xa1,0xdb,0xa9,0x7f,0x85,0xd4,0x85, + 0xea,0xa2,0xd5,0x20,0x46,0xda,0x85,0xe6, + 0x85,0xe9,0xa4,0xf2,0xb1,0xf3,0xc9,0x2b, + 0xf0,0x06,0xc9,0x2d,0xd0,0x03,0x66,0xe9, + 0xc8,0x84,0xe8,0xa9,0x30,0x20,0xa5,0xdb, + 0xb1,0xf3,0xc9,0x2e,0xd0,0x10,0xc8,0x66, + 0xe6,0xe6,0xe8,0xa9,0x30,0xd1,0xf3,0xd0, + 0x05,0xc6,0xd4,0xc8,0xd0,0xf7,0xa2,0x01, + 0xb1,0xf3,0xc9,0x45,0xf0,0x55,0xc8,0xc9, + 0x2e,0xf0,0x28,0x49,0x30,0xc9,0x0a,0xb0, + 0x2a,0xe0,0x06,0xb0,0x15,0x24,0xea,0x10, + 0x09,0xc6,0xea,0x15,0xd4,0x95,0xd4,0xe8, + 0xd0,0x08,0xe6,0xea,0x0a,0x0a,0x0a,0x0a, + 0x95,0xd4,0x24,0xe6,0x30,0x02,0xe6,0xd4, + 0x4c,0x40,0xd8,0xa5,0xe6,0xd0,0x04,0x66, + 0xe6,0xd0,0xc5,0x88,0xc4,0xe8,0xf0,0x1a, + 0x84,0xf2,0x26,0xe9,0x66,0xd4,0xb0,0x0f, + 0xa2,0x04,0x46,0xd5,0x66,0xd6,0x66,0xd7, + 0x66,0xd8,0x66,0xd9,0xca,0xd0,0xf3,0x4c, + 0x00,0xdc,0x60,0xc4,0xe8,0xf0,0xfb,0x84, + 0xf2,0xa2,0x00,0xc8,0xb1,0xf3,0xc9,0x2b, + 0xf0,0x05,0xc9,0x2d,0xd0,0x02,0xca,0xc8, + 0x86,0xe7,0x20,0xb1,0xdb,0xc8,0xb0,0xca, + 0xaa,0x20,0xb1,0xdb,0xb0,0x05,0xc8,0x7d, + 0x39,0xda,0xaa,0x8a,0xf0,0xbc,0x45,0xe7, + 0x26,0xe7,0x65,0xd4,0x85,0xd4,0x4c,0x80, + 0xd8,0x75,0xd4,0x95,0xd4,0xca,0xa9,0x00, + 0xb0,0xf7,0x60,0x00,0x64,0xc8,0x2c,0x90, + 0xf4,0x58,0xbc,0x20,0x84,0xff,0x20,0x51, + 0xda,0xa0,0x00,0xa5,0xd4,0xd0,0x05,0xa9, + 0xb0,0x91,0xf3,0x60,0x84,0xf8,0x10,0x08, + 0xa2,0x2d,0xc6,0xf3,0x8e,0x7f,0x05,0xc8, + 0x84,0xf9,0xa2,0xfb,0x0a,0x38,0xe9,0x7d, + 0xc9,0x0c,0x90,0x0a,0xe9,0x02,0x85,0xf8, + 0xa9,0x02,0xe6,0xf9,0xe6,0xf9,0x85,0xf7, + 0xc9,0x02,0xb0,0x06,0xca,0xc6,0xf9,0x4a, + 0xf0,0x33,0xb5,0xda,0xc9,0x10,0xb0,0x0c, + 0xc6,0xf9,0x46,0xf8,0x06,0xf8,0xd0,0x18, + 0xc6,0xf7,0x90,0x14,0xc6,0xf7,0xd0,0x05, + 0xa9,0x2e,0x91,0xf3,0xc8,0xb5,0xda,0x4a, + 0x4a,0x4a,0x4a,0x09,0x30,0x91,0xf3,0xc8, + 0xc6,0xf7,0xd0,0x05,0xa9,0x2e,0x91,0xf3, + 0xc8,0xb5,0xda,0x29,0x0f,0x09,0x30,0x91, + 0xf3,0xc8,0xe8,0xd0,0xd7,0xa5,0xf7,0x10, + 0x11,0xa9,0x30,0xc4,0xf9,0xf0,0x05,0x88, + 0xd1,0xf3,0xf0,0xf7,0xb1,0xf3,0xc9,0x2e, + 0xd0,0x03,0x88,0xb1,0xf3,0xa6,0xf8,0xf0, + 0x26,0xa9,0x45,0xc8,0x91,0xf3,0x8a,0x10, + 0x07,0x49,0xff,0xaa,0xe8,0xa9,0x2d,0x2c, + 0xa9,0x2b,0xc8,0x91,0xf3,0x8a,0x38,0xa2, + 0x2f,0xe8,0xe9,0x0a,0xb0,0xfb,0x48,0x8a, + 0xc8,0x91,0xf3,0x68,0x69,0x3a,0xc8,0x09, + 0x80,0x91,0xf3,0x60,0xff,0xff,0xff,0xff, + 0xff,0xff,0xf8,0xa2,0xd6,0xa0,0x05,0x20, + 0x48,0xda,0xa0,0x10,0x06,0xd4,0x26,0xd5, + 0xa5,0xd8,0x65,0xd8,0x85,0xd8,0xa5,0xd7, + 0x65,0xd7,0x85,0xd7,0x26,0xd6,0x88,0xd0, + 0xeb,0xa9,0x43,0x85,0xd4,0x4c,0xff,0xdb, + 0xff,0xff,0xa5,0xd4,0xc9,0x43,0xb0,0x60, + 0xe9,0x3e,0x90,0x68,0xaa,0xa9,0x00,0xb4, + 0xd5,0xc0,0x50,0x2a,0x85,0xd4,0xa9,0x00, + 0xca,0x30,0x4b,0xb5,0xd5,0x20,0xcd,0xda, + 0x65,0xd4,0x79,0xf6,0xdf,0x18,0x85,0xd4, + 0xa9,0x00,0xca,0x30,0x39,0xb5,0xd5,0x20, + 0xcd,0xda,0xa5,0xd4,0x79,0x48,0xdf,0x85, + 0xd4,0xb9,0x52,0xdf,0x69,0x00,0x48,0xb5, + 0xd5,0x29,0x0f,0xa8,0xa5,0xd4,0x79,0xdb, + 0xd8,0x85,0xd4,0x68,0x79,0x5c,0xdf,0xca, + 0x30,0x14,0xb4,0xd5,0xc0,0x07,0xb0,0x10, + 0xaa,0x98,0x0a,0x0a,0x0a,0x0a,0x65,0xd4, + 0x85,0xd4,0x8a,0x79,0x65,0xdf,0x85,0xd5, + 0x60,0x00,0x0a,0x14,0x1e,0x28,0x32,0x3c, + 0x46,0x50,0x5a,0xff,0xa2,0xd4,0xa0,0x06, + 0xa9,0x00,0x95,0x00,0xe8,0x88,0xd0,0xfa, + 0x60,0xa9,0x80,0x85,0xf3,0xa9,0x05,0x85, + 0xf4,0x60,0x06,0xf8,0x26,0xf7,0x60,0xff, + 0xa5,0xe0,0x49,0x80,0x85,0xe0,0xa5,0xe0, + 0xf0,0x4e,0xa5,0xd4,0xf0,0x0e,0xa5,0xe0, + 0x45,0xd4,0x29,0x80,0xaa,0x45,0xe0,0x18, + 0xe5,0xd4,0x90,0x05,0x20,0xee,0xdb,0x30, + 0xe5,0x69,0x06,0xa8,0x30,0x32,0xf8,0xe0, + 0x80,0xa2,0x05,0xb0,0x2e,0xa9,0x00,0xc0, + 0x05,0xb0,0x03,0xb9,0xe1,0x00,0xc9,0x50, + 0x98,0xf0,0x0b,0xb9,0xe0,0x00,0x75,0xd4, + 0x95,0xd4,0xca,0x88,0xd0,0xf5,0x90,0x10, + 0xb0,0x08,0xb5,0xd5,0x69,0x00,0x95,0xd5, + 0x90,0x06,0xca,0x10,0xf5,0x20,0x7a,0xdd, + 0x4c,0xff,0xdb,0x84,0xe0,0xb0,0x08,0xb5, + 0xd4,0xf9,0xe1,0x00,0x95,0xd4,0xca,0x88, + 0x10,0xf5,0x4c,0x60,0xdc,0x48,0x4a,0x4a, + 0x4a,0x4a,0xa8,0x68,0x18,0x60,0xa0,0xdb, + 0x20,0x98,0xdd,0xa5,0xd4,0xf0,0xf5,0xa5, + 0xe0,0x18,0xf0,0x17,0x20,0x7c,0xde,0xa5, + 0xe0,0x18,0x20,0x03,0xdb,0x85,0xd4,0xe6, + 0xd4,0xa2,0xd5,0xa0,0x0c,0xf8,0x4c,0xc5, + 0xdc,0x68,0x68,0x4c,0x44,0xda,0xa5,0xe0, + 0x49,0x7f,0x38,0xaa,0x45,0xd4,0x29,0x80, + 0x85,0xe0,0x8a,0x65,0xd4,0xaa,0x45,0xe0, + 0xc9,0x4f,0x90,0xe5,0xc9,0xb1,0xb0,0xe1, + 0x8a,0xe9,0x3f,0x60,0x40,0x10,0x00,0x00, + 0x00,0x00,0x40,0x02,0x30,0x25,0x85,0x09, + 0xa5,0xe0,0xf0,0x72,0xa5,0xd4,0xf0,0x6c, + 0x20,0xfe,0xda,0x20,0x2d,0xdc,0xa5,0xd4, + 0x05,0xd5,0xf0,0x3d,0x90,0x05,0x20,0xb9, + 0xdb,0x90,0x36,0xa9,0x00,0xe5,0xdb,0xa6, + 0xdc,0x75,0xee,0x95,0xee,0xa9,0x99,0xca, + 0x90,0xf7,0x18,0xa5,0xd9,0x65,0xe5,0x85, + 0xd9,0xa5,0xd8,0x65,0xe4,0x85,0xd8,0xa5, + 0xd7,0x65,0xe3,0x85,0xd7,0xa5,0xd6,0x65, + 0xe2,0x85,0xd6,0xa5,0xd5,0x65,0xe1,0x85, + 0xd5,0xa5,0xd4,0x65,0xe0,0x85,0xd4,0x90, + 0xca,0x08,0xa2,0x04,0x06,0xd9,0x26,0xd8, + 0x26,0xd7,0x26,0xd6,0x26,0xd5,0x26,0xd4, + 0xca,0xd0,0xf1,0x28,0xa5,0xdb,0x49,0x09, + 0x85,0xdb,0xf0,0xa2,0xe6,0xdc,0xd0,0x9e, + 0x20,0x64,0xde,0xd8,0x18,0x60,0x38,0x60, + 0xff,0xa9,0x20,0xa4,0xf2,0xd1,0xf3,0xd0, + 0x03,0xc8,0xd0,0xf9,0x84,0xf2,0x60,0xa4, + 0xf2,0xb1,0xf3,0x38,0xe9,0x30,0xc9,0x0a, + 0x60,0xa5,0xdb,0xa6,0xdc,0x75,0xee,0x95, + 0xee,0xa9,0x00,0xca,0xb0,0xf7,0x38,0xa5, + 0xd9,0xe5,0xe5,0x85,0xd9,0xa5,0xd8,0xe5, + 0xe4,0x85,0xd8,0xa5,0xd7,0xe5,0xe3,0x85, + 0xd7,0xa5,0xd6,0xe5,0xe2,0x85,0xd6,0xa5, + 0xd5,0xe5,0xe1,0x85,0xd5,0xa5,0xd4,0xe9, + 0x00,0x85,0xd4,0xb0,0xcc,0x60,0xa2,0x05, + 0xb5,0xd4,0xb4,0xe0,0x95,0xe0,0x94,0xd4, + 0xca,0x10,0xf5,0x60,0xff,0xff,0xff,0xd8, + 0xa0,0x05,0xa5,0xd4,0x29,0x7f,0xf0,0x21, + 0xa6,0xd5,0xf0,0x07,0xc9,0x0f,0x90,0x1a, + 0xc9,0x71,0x60,0xc6,0xd4,0xa2,0xfb,0xb5, + 0xdb,0x95,0xda,0xe8,0xd0,0xf9,0x86,0xda, + 0x88,0xd0,0xdf,0x84,0xd4,0x84,0xd5,0x18, + 0x60,0x18,0x4c,0x44,0xda,0x85,0xda,0xa2, + 0xe7,0x20,0x46,0xda,0xa9,0x50,0x85,0xed, + 0x85,0xe6,0xa2,0x00,0x86,0xd4,0x86,0xe0, + 0xa5,0xe1,0xc9,0x10,0xb0,0x11,0xa0,0x04, + 0x06,0xe5,0x26,0xe4,0x26,0xe3,0x26,0xe2, + 0x26,0xe1,0x88,0xd0,0xf3,0xa2,0x09,0x86, + 0xdb,0xf8,0xa2,0xf9,0x86,0xdc,0x38,0x60, + 0xb0,0x1f,0x90,0x08,0xb5,0xd5,0xe9,0x00, + 0x95,0xd5,0xb0,0x15,0xca,0x10,0xf5,0xa2, + 0x05,0x38,0xa9,0x00,0xf5,0xd4,0x95,0xd4, + 0xca,0xd0,0xf7,0xa9,0x80,0x45,0xd4,0x85, + 0xd4,0xa5,0xd4,0x29,0x7f,0xc9,0x0f,0x90, + 0x1f,0xa6,0xd5,0xf0,0x0f,0xa6,0xe0,0xe0, + 0x04,0xb0,0x06,0xb5,0xe2,0xc9,0x50,0xb0, + 0x27,0x18,0xd8,0x60,0xa2,0xfc,0xc6,0xd4, + 0xb4,0xda,0xd0,0x08,0xe8,0xd0,0xf7,0x18, + 0xd8,0x4c,0x44,0xda,0xa0,0x00,0xb5,0xda, + 0x99,0xd5,0x00,0xc8,0xe8,0xd0,0xf7,0x96, + 0xd5,0xc8,0xc0,0x06,0xd0,0xf9,0xf0,0xc1, + 0xa2,0x05,0x4c,0xaa,0xda,0x20,0x48,0xda, + 0xa0,0x07,0xa9,0x50,0x85,0xdb,0xa2,0x05, + 0x56,0xe6,0xb0,0x2d,0xb5,0xd9,0x65,0xe5, + 0x95,0xd9,0xb5,0xd8,0x65,0xe4,0x95,0xd8, + 0xb5,0xd7,0x65,0xe3,0x95,0xd7,0xb5,0xd6, + 0x65,0xe2,0x95,0xd6,0xb5,0xd5,0x65,0xe1, + 0x95,0xd5,0xb5,0xd4,0x65,0xe0,0x95,0xd4, + 0x90,0x07,0x86,0xe6,0x20,0xd5,0xd8,0xa6, + 0xe6,0xca,0xd0,0xcc,0x18,0xa5,0xe5,0x65, + 0xe5,0x85,0xe5,0xa5,0xe4,0x65,0xe4,0x85, + 0xe4,0xa5,0xe3,0x65,0xe3,0x85,0xe3,0xa5, + 0xe2,0x65,0xe2,0x85,0xe2,0xa5,0xe1,0x65, + 0xe1,0x85,0xe1,0xa5,0xe0,0x65,0xe0,0x85, + 0xe0,0x88,0xd0,0xa2,0xa5,0xd5,0xf0,0x07, + 0xa9,0x50,0xa2,0x06,0x20,0xd1,0xd8,0x4c, + 0xff,0xdb,0xff,0xff,0xff,0xff,0xa9,0x0a, + 0x86,0xfe,0x84,0xff,0x85,0xec,0xa2,0xe0, + 0xa0,0x05,0x20,0xa7,0xdd,0x20,0x44,0xda, + 0xa5,0xfe,0xaa,0x18,0x69,0x06,0x85,0xfe, + 0xa4,0xff,0x90,0x02,0xe6,0xff,0x20,0x98, + 0xdd,0x20,0x66,0xda,0xb0,0x0d,0xc6,0xec, + 0xf0,0x09,0xa2,0xe0,0xa0,0x05,0x20,0xd8, + 0xda,0x90,0xdd,0x60,0x3f,0x43,0x42,0x94, + 0x48,0x19,0xe6,0xd4,0xa2,0x04,0xb5,0xd4, + 0x95,0xd5,0xca,0xd0,0xf9,0xe8,0x86,0xd5, + 0x60,0x86,0xfc,0x84,0xfd,0xa0,0x05,0xb1, + 0xfc,0x99,0xd4,0x00,0x88,0x10,0xf8,0x60, + 0x86,0xfc,0x84,0xfd,0xa0,0x05,0xb1,0xfc, + 0x99,0xe0,0x00,0x88,0x10,0xf8,0x60,0x86, + 0xfc,0x84,0xfd,0xa0,0x05,0xb9,0xd4,0x00, + 0x91,0xfc,0x88,0x10,0xf8,0x60,0xa2,0x05, + 0xb5,0xd4,0x95,0xe0,0xca,0x10,0xf9,0x60, + 0xa2,0x74,0xa0,0xdd,0x20,0x98,0xdd,0x20, + 0xdb,0xda,0xb0,0x5b,0xa5,0xd4,0x85,0xf9, + 0x29,0x7f,0x85,0xd4,0xa0,0x00,0xc9,0x40, + 0x90,0x1e,0xf0,0x08,0xa5,0xf9,0x10,0x47, + 0x18,0x4c,0x44,0xda,0xa5,0xd5,0x20,0xcd, + 0xda,0x79,0xf6,0xdf,0x48,0xa9,0x00,0x85, + 0xd5,0x85,0xda,0x20,0x00,0xdc,0x68,0xa8, + 0x84,0xf8,0xa2,0x28,0xa0,0xde,0x20,0x3e, + 0xdd,0x46,0xf8,0x90,0x07,0xa2,0x1c,0x20, + 0xd6,0xda,0xb0,0xd0,0xa5,0xf8,0x65,0xd4, + 0xc9,0x71,0xb0,0xc8,0x85,0xd4,0x26,0xf9, + 0x90,0x0d,0x20,0xb6,0xdd,0xa2,0xea,0xa0, + 0xdf,0x20,0x89,0xdd,0x4c,0x28,0xdb,0x60, + 0x3f,0x01,0x46,0x90,0x83,0x08,0xbe,0x20, + 0x05,0x33,0x11,0x71,0x3f,0x09,0x19,0x45, + 0x20,0x45,0x3f,0x19,0x21,0x38,0x38,0x84, + 0x3f,0x54,0x47,0x32,0x51,0x97,0x40,0x01, + 0x17,0x01,0x82,0x50,0x40,0x02,0x03,0x47, + 0x85,0x81,0x40,0x02,0x65,0x09,0x44,0x94, + 0x40,0x02,0x30,0x25,0x85,0x12,0x40,0x01, + 0x00,0x00,0x00,0x00,0xa2,0xe6,0xa4,0xda, + 0xa5,0xe7,0xd0,0x02,0xe8,0x88,0x84,0xd4, + 0xa0,0x05,0xb5,0x05,0xca,0x99,0xd4,0x00, + 0x88,0xd0,0xf7,0x60,0xa2,0x04,0xb5,0xd5, + 0x4a,0x4a,0x4a,0x4a,0xa8,0x18,0xb5,0xd5, + 0x79,0xf6,0xdf,0x49,0xff,0x95,0xe7,0xca, + 0x10,0xec,0x60,0xff,0xff,0x86,0xfe,0x84, + 0xff,0x20,0x98,0xdd,0xa2,0xe6,0xa0,0x05, + 0x20,0xa7,0xdd,0x20,0x66,0xda,0xb0,0xea, + 0xa2,0xe0,0xa0,0x05,0x20,0xa7,0xdd,0xa2, + 0xe6,0xa0,0x05,0x20,0x89,0xdd,0xa6,0xfe, + 0xa4,0xff,0x20,0x98,0xdd,0x20,0x60,0xda, + 0xb0,0xd0,0xa2,0xe0,0xa0,0x05,0x20,0x98, + 0xdd,0x4c,0x28,0xdb,0xff,0x46,0xf9,0x10, + 0x03,0x38,0x66,0xf9,0xa5,0xd4,0x30,0x6e, + 0x0a,0x49,0x80,0x85,0xf8,0xa5,0xd5,0xf0, + 0x65,0xa2,0x40,0x86,0xd4,0xc9,0x03,0x90, + 0x13,0xc9,0x31,0x90,0x04,0xe6,0xf8,0xd0, + 0x07,0xa2,0x1c,0x20,0xd6,0xda,0xb0,0x4f, + 0xe6,0xf8,0xc6,0xd4,0xa2,0xea,0xa0,0xdf, + 0x20,0x95,0xde,0xa2,0xe6,0xa0,0x05,0x20, + 0xa7,0xdd,0x20,0xb6,0xdd,0x20,0xdb,0xda, + 0xa2,0x72,0xa0,0xdf,0x20,0x3e,0xdd,0xb0, + 0x2e,0xa2,0xe6,0xa0,0x05,0x20,0xd8,0xda, + 0x20,0xb6,0xdd,0xa9,0x00,0x85,0xd5,0xa6, + 0xf8,0x10,0x04,0x38,0xe5,0xf8,0xaa,0x86, + 0xd4,0x20,0xaa,0xd9,0x06,0xd4,0x06,0xf8, + 0x66,0xd4,0x20,0x66,0xda,0x24,0xf9,0x30, + 0x06,0xa2,0x22,0x4c,0xd6,0xda,0x38,0x60, + 0x00,0xe8,0xd0,0xb8,0xa0,0x88,0x70,0x58, + 0x40,0x28,0x00,0x03,0x07,0x0b,0x0f,0x13, + 0x17,0x1b,0x1f,0x23,0x00,0x00,0x00,0x01, + 0x01,0x01,0x02,0x02,0x03,0x03,0x27,0x4e, + 0x75,0x9c,0xc3,0xea,0x3f,0x50,0x00,0x00, + 0x00,0x00,0x3f,0x20,0x26,0x22,0x71,0x54, + 0xbf,0x07,0x32,0x04,0x49,0x21,0x3f,0x10, + 0x60,0x98,0x35,0x64,0x3f,0x05,0x60,0x41, + 0x73,0x29,0x3f,0x08,0x04,0x18,0x84,0x07, + 0x3f,0x09,0x63,0x91,0x60,0x15,0x3f,0x12, + 0x40,0x89,0x61,0x35,0x3f,0x17,0x37,0x17, + 0x66,0x46,0x3f,0x28,0x95,0x29,0x65,0x58, + 0x3f,0x86,0x85,0x88,0x96,0x38,0x3e,0x11, + 0x12,0x07,0x58,0x81,0xbe,0x73,0x04,0x08, + 0x75,0x20,0x3f,0x02,0x24,0x96,0x55,0x73, + 0xbf,0x04,0x46,0x18,0x51,0x72,0x3f,0x06, + 0x73,0x46,0x32,0x45,0xbf,0x08,0x80,0x69, + 0x06,0x64,0x3f,0x11,0x05,0x66,0x74,0x99, + 0xbf,0x14,0x27,0x94,0x93,0x12,0x3f,0x19, + 0x99,0x96,0x30,0x60,0xbf,0x33,0x33,0x33, + 0x24,0x72,0x40,0x01,0x00,0x00,0x00,0x00, + 0x3f,0x78,0x53,0x98,0x16,0x34,0x00,0xfa, + 0xf4,0xee,0xe8,0xe2,0xdc,0xd6,0xd0,0xca, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, + 0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + 0x00,0x66,0xff,0x66,0x66,0xff,0x66,0x00, + 0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00, + 0x00,0x66,0x6c,0x18,0x30,0x66,0x46,0x00, + 0x1c,0x36,0x1c,0x38,0x6f,0x66,0x3b,0x00, + 0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + 0x00,0x0e,0x1c,0x18,0x18,0x1c,0x0e,0x00, + 0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, + 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00, + 0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, + 0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, + 0x00,0x06,0x0c,0x18,0x30,0x60,0x40,0x00, + 0x00,0x3c,0x66,0x6e,0x76,0x66,0x3c,0x00, + 0x00,0x18,0x38,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x7e,0x0c,0x18,0x0c,0x66,0x3c,0x00, + 0x00,0x0c,0x1c,0x3c,0x6c,0x7e,0x0c,0x00, + 0x00,0x7e,0x60,0x7c,0x06,0x66,0x3c,0x00, + 0x00,0x3c,0x60,0x7c,0x66,0x66,0x3c,0x00, + 0x00,0x7e,0x06,0x0c,0x18,0x30,0x30,0x00, + 0x00,0x3c,0x66,0x3c,0x66,0x66,0x3c,0x00, + 0x00,0x3c,0x66,0x3e,0x06,0x0c,0x38,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, + 0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00, + 0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x00,0x18,0x00, + 0x00,0x3c,0x66,0x6e,0x6e,0x60,0x3e,0x00, + 0x00,0x18,0x3c,0x66,0x66,0x7e,0x66,0x00, + 0x00,0x7c,0x66,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x00, + 0x00,0x78,0x6c,0x66,0x66,0x6c,0x78,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x7e,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x60,0x00, + 0x00,0x3e,0x60,0x60,0x6e,0x66,0x3e,0x00, + 0x00,0x66,0x66,0x7e,0x66,0x66,0x66,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x06,0x06,0x06,0x06,0x66,0x3c,0x00, + 0x00,0x66,0x6c,0x78,0x78,0x6c,0x66,0x00, + 0x00,0x60,0x60,0x60,0x60,0x60,0x7e,0x00, + 0x00,0x63,0x77,0x7f,0x6b,0x63,0x63,0x00, + 0x00,0x66,0x76,0x7e,0x7e,0x6e,0x66,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x60,0x60,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x6c,0x36,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x6c,0x66,0x00, + 0x00,0x3c,0x60,0x3c,0x06,0x06,0x3c,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x00, + 0x00,0x66,0x66,0x66,0x66,0x66,0x7e,0x00, + 0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00, + 0x00,0x66,0x66,0x3c,0x3c,0x66,0x66,0x00, + 0x00,0x66,0x66,0x3c,0x18,0x18,0x18,0x00, + 0x00,0x7e,0x0c,0x18,0x30,0x60,0x7e,0x00, + 0x00,0x1e,0x18,0x18,0x18,0x18,0x1e,0x00, + 0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, + 0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0x36,0x7f,0x7f,0x3e,0x1c,0x08,0x00, + 0x18,0x18,0x18,0x1f,0x1f,0x18,0x18,0x18, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, + 0x18,0x18,0x18,0xf8,0xf8,0x00,0x00,0x00, + 0x18,0x18,0x18,0xf8,0xf8,0x18,0x18,0x18, + 0x00,0x00,0x00,0xf8,0xf8,0x18,0x18,0x18, + 0x03,0x07,0x0e,0x1c,0x38,0x70,0xe0,0xc0, + 0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x07,0x03, + 0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff, + 0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f, + 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff, + 0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00, + 0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0, + 0x00,0x1c,0x1c,0x77,0x77,0x08,0x1c,0x00, + 0x00,0x00,0x00,0x1f,0x1f,0x18,0x18,0x18, + 0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, + 0x18,0x18,0x18,0xff,0xff,0x18,0x18,0x18, + 0x00,0x00,0x3c,0x7e,0x7e,0x7e,0x3c,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0x00,0x00,0x00,0xff,0xff,0x18,0x18,0x18, + 0x18,0x18,0x18,0xff,0xff,0x00,0x00,0x00, + 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, + 0x18,0x18,0x18,0x1f,0x1f,0x00,0x00,0x00, + 0x78,0x60,0x78,0x60,0x7e,0x18,0x1e,0x00, + 0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x00, + 0x00,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00, + 0x00,0x18,0x30,0x7e,0x30,0x18,0x00,0x00, + 0x00,0x18,0x0c,0x7e,0x0c,0x18,0x00,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x3c,0x18,0x00, + 0x00,0x00,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x00,0x3c,0x60,0x60,0x60,0x3c,0x00, + 0x00,0x06,0x06,0x3e,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x00,0x0e,0x18,0x3e,0x18,0x18,0x18,0x00, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x7c, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x66,0x00, + 0x00,0x18,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3c, + 0x00,0x60,0x60,0x6c,0x78,0x6c,0x66,0x00, + 0x00,0x38,0x18,0x18,0x18,0x18,0x3c,0x00, + 0x00,0x00,0x66,0x7f,0x7f,0x6b,0x63,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x66,0x66,0x00, + 0x00,0x00,0x3c,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x7c,0x60,0x60, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x06, + 0x00,0x00,0x7c,0x66,0x60,0x60,0x60,0x00, + 0x00,0x00,0x3e,0x60,0x3c,0x06,0x7c,0x00, + 0x00,0x18,0x7e,0x18,0x18,0x18,0x0e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x00,0x63,0x6b,0x7f,0x3e,0x36,0x00, + 0x00,0x00,0x66,0x3c,0x18,0x3c,0x66,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3e,0x0c,0x78, + 0x00,0x00,0x7e,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x18,0x3c,0x00, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x00,0x7e,0x78,0x7c,0x6e,0x66,0x06,0x00, + 0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00, + 0x10,0x18,0x1c,0x1e,0x1c,0x18,0x10,0x00, + 0xeb,0xf9,0xc8,0xe4,0xf7,0xf9,0xa9,0xfa, + 0xc8,0xe4,0xca,0xe4,0x4c,0xcb,0xe4,0x00, + 0xf5,0xf3,0xc8,0xe4,0x9d,0xf5,0xdd,0xf5, + 0xc8,0xe4,0xc1,0xf6,0x20,0x90,0xf5,0x00, + 0xc8,0xe4,0xc8,0xe4,0x67,0xfe,0xca,0xe4, + 0xc8,0xe4,0xca,0xe4,0x4c,0x4d,0xfe,0x00, + 0x2a,0xee,0xf1,0xed,0xca,0xe4,0xd3,0xed, + 0x2e,0xee,0xca,0xe4,0x20,0xce,0xed,0x00, + 0x5a,0xee,0xaf,0xee,0xd0,0xee,0x10,0xef, + 0xc8,0xe4,0xca,0xe4,0x4c,0x50,0xee,0x00, + 0x4c,0x6e,0xed,0x4c,0x6f,0xed,0x4c,0xfc, + 0xe4,0x4c,0x5c,0xe9,0x4c,0x66,0xe8,0x4c, + 0x1d,0xe7,0x4c,0x61,0xe7,0x4c,0x51,0xe9, + 0x4c,0xa7,0xea,0x4c,0x8b,0xe8,0x4c,0xea, + 0xe4,0x4c,0x80,0xe4,0x4c,0x48,0xf0,0x4c, + 0xfc,0xef,0x4c,0x51,0xef,0x4c,0x6e,0xee, + 0xa9,0xa6,0x8d,0x44,0x03,0xa9,0xe4,0x8d, + 0x45,0x03,0x8d,0x48,0x03,0xa2,0x00,0x8e, + 0x49,0x03,0xa9,0x09,0x8d,0x42,0x03,0x20, + 0x56,0xe4,0x8e,0x48,0x03,0xa9,0x07,0xd0, + 0xf3,0xff,0xff,0xff,0xff,0xff,0x41,0x6c, + 0x74,0x69,0x72,0x72,0x61,0x4f,0x53,0x20, + 0x33,0x2e,0x34,0x31,0x20,0x6d,0x65,0x6d, + 0x6f,0x20,0x70,0x61,0x64,0x9b,0xff,0xff, + 0x60,0x80,0x40,0x20,0x10,0x08,0x04,0x02, + 0x01,0xa0,0x01,0x60,0x48,0xa9,0x08,0xa2, + 0x04,0x48,0xad,0x0b,0xd4,0xcd,0x0b,0xd4, + 0xf0,0xfb,0xca,0xd0,0xf5,0x68,0x49,0x08, + 0x8d,0x1f,0xd0,0xd0,0xea,0x88,0xd0,0xe7, + 0x68,0x60,0x38,0xa2,0x70,0xa9,0xff,0x9d, + 0x40,0x03,0x20,0x01,0xe7,0x8a,0xe9,0x10, + 0xaa,0x10,0xf2,0x60,0x85,0x2f,0x86,0x2e, + 0x20,0x0e,0xe5,0xa6,0x2e,0x98,0x9d,0x43, + 0x03,0xa5,0x2f,0xc0,0x00,0x60,0x8a,0x29, + 0x8f,0xf0,0x06,0xa0,0x86,0x60,0xa0,0x84, + 0x60,0x20,0xd1,0xe6,0xa5,0x22,0xc9,0x03, + 0xf0,0x66,0x90,0xf2,0xa4,0x20,0x10,0x1c, + 0xa0,0x01,0xa5,0x22,0xc9,0x0c,0xf0,0x06, + 0xc9,0x0d,0xb0,0x03,0xa0,0x85,0x60,0x20, + 0xe0,0xe6,0xa5,0x22,0xc9,0x0d,0xf0,0x40, + 0xc9,0x0e,0xb0,0x3f,0xa6,0x22,0xe0,0x0e, + 0x90,0x02,0xa2,0x0e,0xbd,0x8f,0xe6,0x30, + 0x04,0x24,0x2a,0xf0,0x26,0xbd,0xb0,0xe6, + 0x48,0xbd,0xa5,0xe6,0x48,0xbc,0x9a,0xe6, + 0xa6,0x20,0xbd,0x1b,0x03,0x85,0x2c,0xbd, + 0x1c,0x03,0x85,0x2d,0xb1,0x2c,0xaa,0x88, + 0xb1,0x2c,0x85,0x2c,0x86,0x2d,0xa5,0x28, + 0x05,0x29,0x60,0x18,0x69,0x7f,0xa8,0x60, + 0xa0,0x09,0x2c,0xa0,0x0b,0x4c,0xbf,0xe6, + 0xa4,0x20,0xc8,0xf0,0x03,0xa0,0x81,0x60, + 0x20,0xe0,0xe6,0xa0,0x01,0x20,0xbf,0xe6, + 0xa6,0x2e,0xa5,0x20,0x9d,0x40,0x03,0xa5, + 0x21,0x9d,0x41,0x03,0x98,0x10,0x01,0x60, + 0xa6,0x20,0xbd,0x1b,0x03,0x85,0x2c,0xbd, + 0x1c,0x03,0x85,0x2d,0xa0,0x06,0xb1,0x2c, + 0xa6,0x2e,0x9d,0x46,0x03,0xc8,0xb1,0x2c, + 0x9d,0x47,0x03,0xa0,0x01,0x60,0x20,0xc2, + 0xe6,0xa6,0x2e,0xa5,0x2a,0x9d,0x4a,0x03, + 0xa5,0x2b,0x9d,0x4b,0x03,0x60,0xf0,0x16, + 0x20,0xc2,0xe6,0xc0,0x00,0x30,0x1c,0xa2, + 0x00,0x81,0x24,0x49,0x9b,0xc9,0x01,0x20, + 0x72,0xe6,0x90,0x0f,0xd0,0xea,0x20,0xc2, + 0xe6,0xc0,0x00,0x30,0x06,0xc9,0x9b,0xd0, + 0xf5,0xa0,0x89,0xa6,0x2e,0x38,0xbd,0x48, + 0x03,0xe5,0x28,0x85,0x28,0x9d,0x48,0x03, + 0xbd,0x49,0x03,0xe5,0x29,0x85,0x29,0x9d, + 0x49,0x03,0xbd,0x44,0x03,0x85,0x24,0xbd, + 0x45,0x03,0x85,0x25,0x60,0xf0,0x15,0x20, + 0xc2,0xe6,0xc0,0x00,0x30,0x0b,0xa2,0x00, + 0x85,0x2f,0x81,0x24,0x20,0x72,0xe6,0xd0, + 0xee,0x4c,0xfb,0xe5,0x20,0xc2,0xe6,0x85, + 0x2f,0x60,0xf0,0x33,0xa0,0x00,0xb1,0x24, + 0x20,0xc2,0xe6,0x98,0x30,0x12,0x20,0x72, + 0xe6,0xf0,0x08,0xa9,0x9b,0xc5,0x2f,0xf0, + 0x07,0xd0,0xe7,0xa9,0x9b,0x20,0xc2,0xe6, + 0x4c,0xfb,0xe5,0xf0,0x12,0xa0,0x00,0xb1, + 0x24,0x20,0xc2,0xe6,0x98,0x30,0xf1,0x20, + 0x72,0xe6,0xd0,0xf1,0x4c,0xfb,0xe5,0x4c, + 0xc4,0xe6,0xe6,0x24,0xd0,0x02,0xe6,0x25, + 0xa5,0x28,0xd0,0x02,0xc6,0x29,0xc6,0x28, + 0xd0,0x02,0xa5,0x29,0x60,0x20,0xc2,0xe6, + 0xa6,0x2e,0x20,0x01,0xe7,0xa9,0xff,0x9d, + 0x40,0x03,0x60,0x04,0x04,0x04,0x04,0x08, + 0x08,0x08,0x08,0xff,0xff,0xff,0x05,0x05, + 0x05,0x05,0x07,0x07,0x07,0x07,0x03,0x09, + 0x0b,0xd5,0xd5,0x1c,0x1c,0x39,0x39,0x5a, + 0x5a,0x84,0xc1,0xc5,0xe5,0xe5,0xe6,0xe6, + 0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe5,0x20, + 0x60,0xe5,0x85,0x2f,0xa5,0x2d,0x48,0xa5, + 0x2c,0x48,0xa0,0x92,0xa6,0x2e,0xa5,0x2f, + 0x60,0xa0,0x00,0xbd,0x40,0x03,0x99,0x20, + 0x00,0xe8,0xc8,0xc0,0x0c,0xd0,0xf4,0x60, + 0xa2,0x01,0xa1,0x23,0x85,0x2d,0xa0,0x01, + 0xb1,0x24,0x38,0xe9,0x30,0xf0,0x06,0xc9, + 0x0a,0xb0,0x02,0xaa,0xc8,0x86,0x21,0x20, + 0x0c,0xe7,0xf0,0x04,0xa0,0x82,0x68,0x68, + 0x60,0xa9,0x33,0x9d,0x46,0x03,0xa9,0xe5, + 0x9d,0x47,0x03,0x60,0xa5,0x2d,0xa2,0x21, + 0xdd,0x1a,0x03,0xf0,0x05,0xca,0xca,0xca, + 0x10,0xf6,0x86,0x20,0x60,0xe6,0x14,0xd0, + 0x08,0xe6,0x4d,0xe6,0x13,0xd0,0x02,0xe6, + 0x12,0xa2,0xfe,0xa9,0x00,0xa4,0x4d,0x10, + 0x06,0x86,0x4d,0xa2,0xf6,0xa5,0x13,0x86, + 0x4e,0x85,0x4f,0x4d,0xc5,0x02,0x25,0x4e, + 0x8d,0x17,0xd0,0xad,0x18,0x02,0xd0,0x08, + 0xad,0x19,0x02,0xf0,0x10,0xce,0x19,0x02, + 0xce,0x18,0x02,0xd0,0x08,0xad,0x19,0x02, + 0xd0,0x03,0x20,0x67,0xe7,0xa5,0x42,0xf0, + 0x09,0x68,0xa8,0x68,0xaa,0x68,0x40,0x6c, + 0x26,0x02,0xa9,0x04,0xba,0x3d,0x04,0x01, + 0xd0,0xef,0x58,0xad,0x31,0x02,0x8d,0x03, + 0xd4,0xad,0x30,0x02,0x8d,0x02,0xd4,0xad, + 0x2f,0x02,0x8d,0x00,0xd4,0xad,0xf4,0x02, + 0x8d,0x09,0xd4,0xad,0xf3,0x02,0x8d,0x01, + 0xd4,0xad,0x6f,0x02,0x8d,0x1b,0xd0,0xa2, + 0x08,0x8e,0x1f,0xd0,0xbd,0xc0,0x02,0x45, + 0x4f,0x25,0x4e,0x9d,0x12,0xd0,0xca,0x10, + 0xf3,0xa2,0x03,0x20,0x4e,0xe8,0xd0,0x03, + 0x20,0x2c,0xe8,0xa2,0x09,0x18,0x20,0x4e, + 0xe8,0xb0,0x07,0xf0,0x02,0xa9,0xff,0x9d, + 0x25,0x02,0xca,0xca,0xe0,0x05,0xb0,0xed, + 0xad,0x0f,0xd2,0x29,0x04,0xd0,0x0f,0xce, + 0x2b,0x02,0xd0,0x17,0xad,0x09,0xd2,0x8d, + 0xfc,0x02,0xa9,0x06,0xd0,0x0a,0xad,0xf1, + 0x02,0xf0,0x03,0xce,0xf1,0x02,0xa9,0x00, + 0x8d,0x2b,0x02,0xa2,0x07,0xbd,0x00,0xd2, + 0x9d,0x70,0x02,0xa9,0x00,0x9d,0x7c,0x02, + 0xca,0x10,0xf2,0xa2,0x03,0xbd,0x10,0xd0, + 0x9d,0x84,0x02,0xca,0x10,0xf7,0xad,0x00, + 0xd3,0xa2,0x00,0xa0,0x00,0x20,0x2f,0xe8, + 0xad,0x01,0xd3,0xa2,0x04,0xa0,0x02,0x20, + 0x2f,0xe8,0x8d,0x0b,0xd2,0xad,0x0c,0xd4, + 0x8d,0x34,0x02,0xad,0x0d,0xd4,0x8d,0x35, + 0x02,0x6c,0x24,0x02,0x6c,0x28,0x02,0x48, + 0x29,0x0f,0x99,0x78,0x02,0x68,0x4a,0x4a, + 0x4a,0x3e,0x7c,0x02,0x4a,0x3e,0x7d,0x02, + 0x99,0x79,0x02,0x4a,0x4a,0x4a,0x3e,0x7e, + 0x02,0x4a,0x3e,0x7f,0x02,0x60,0xbd,0x17, + 0x02,0xd0,0x0a,0xdd,0x18,0x02,0xd0,0x02, + 0x8a,0x60,0xde,0x18,0x02,0xde,0x17,0x02, + 0xd0,0x03,0xbd,0x18,0x02,0x60,0x0a,0x8c, + 0x2d,0x02,0xa8,0x8a,0x08,0x78,0xee,0x0a, + 0xd4,0xa2,0x7c,0x08,0x28,0x08,0x28,0xec, + 0x0b,0xd4,0xf0,0x0b,0x99,0x17,0x02,0xad, + 0x2d,0x02,0x99,0x16,0x02,0x28,0x60,0x08, + 0x28,0xf0,0xf1,0xa9,0x40,0x8d,0x0e,0xd4, + 0x60,0x2c,0x0f,0xd4,0x10,0x06,0x6c,0x00, + 0x02,0x4c,0x74,0xe4,0x48,0xa9,0x20,0x2c, + 0x0f,0xd4,0xd0,0xf5,0x8a,0x48,0x98,0x48, + 0x8d,0x0f,0xd4,0x6c,0x22,0x02,0x6c,0x16, + 0x02,0xa9,0xef,0x20,0x48,0xe9,0x6c,0x0c, + 0x02,0x2c,0x0e,0xd2,0xd0,0x3c,0x6c,0x0e, + 0x02,0xa9,0xfe,0x20,0x48,0xe9,0x6c,0x10, + 0x02,0xa9,0xfd,0x20,0x48,0xe9,0x6c,0x12, + 0x02,0xa9,0xfb,0x20,0x48,0xe9,0x6c,0x14, + 0x02,0x48,0xa9,0x20,0x2c,0x0e,0xd2,0xd0, + 0x0d,0xa9,0xdf,0x8d,0x0e,0xd2,0xa5,0x10, + 0x8d,0x0e,0xd2,0x6c,0x0a,0x02,0xa9,0x10, + 0x2c,0x0e,0xd2,0xf0,0xbc,0x4a,0x24,0x10, + 0xd0,0xbf,0xad,0x0e,0xd2,0x4a,0x90,0xc1, + 0x4a,0x90,0xc6,0x4a,0x90,0xcb,0x2c,0x0e, + 0xd2,0x50,0x21,0x10,0x27,0x2c,0x02,0xd3, + 0x30,0x2a,0x2c,0x03,0xd3,0x30,0x2b,0x68, + 0x8d,0x8c,0x02,0x68,0x48,0x29,0x10,0xf0, + 0x07,0xad,0x8c,0x02,0x48,0x6c,0x06,0x02, + 0xad,0x8c,0x02,0x40,0xa9,0xbf,0x20,0x48, + 0xe9,0x6c,0x08,0x02,0xa9,0x7f,0x20,0x48, + 0xe9,0x6c,0x36,0x02,0xad,0x00,0xd3,0x6c, + 0x02,0x02,0xad,0x01,0xd3,0x6c,0x04,0x02, + 0x8d,0x0e,0xd2,0xa5,0x10,0x8d,0x0e,0xd2, + 0x60,0xa9,0x03,0x8d,0x0f,0xd2,0x8d,0x32, + 0x02,0x85,0x41,0x60,0xa9,0x01,0x8d,0xbd, + 0x02,0x85,0x42,0xba,0x8e,0x18,0x03,0x20, + 0x73,0xea,0xa2,0x00,0xad,0x00,0x03,0xc9, + 0x60,0xd0,0x01,0xca,0x8e,0x0f,0x03,0x20, + 0xc6,0xea,0x2c,0x0f,0x03,0x10,0x03,0x4c, + 0x3e,0xec,0xa9,0x0d,0x8d,0x9c,0x02,0xad, + 0x00,0x03,0x18,0x6d,0x01,0x03,0x38,0xe9, + 0x01,0x8d,0x3a,0x02,0xad,0x02,0x03,0x8d, + 0x3b,0x02,0xad,0x0a,0x03,0x8d,0x3c,0x02, + 0xad,0x0b,0x03,0x8d,0x3d,0x02,0xa9,0x34, + 0x8d,0x03,0xd3,0xa2,0x05,0xac,0x0b,0xd4, + 0xcc,0x0b,0xd4,0xf0,0xfb,0xc8,0xca,0xd0, + 0xf7,0xa9,0x00,0x85,0x3c,0xa9,0x02,0x85, + 0x33,0x85,0x35,0xa9,0x3a,0x85,0x32,0xa9, + 0x3e,0x85,0x34,0x20,0x2b,0xeb,0x30,0x67, + 0x20,0x7e,0xea,0x10,0x0a,0x20,0x9a,0xeb, + 0xce,0x9c,0x02,0x10,0xaa,0x30,0x4d,0x2c, + 0x03,0x03,0x10,0x0d,0x20,0x15,0xeb,0x20, + 0x2b,0xeb,0x30,0x4b,0x20,0x7e,0xea,0x30, + 0xe4,0xa2,0xff,0x86,0x3c,0xad,0x06,0x03, + 0x6a,0x6a,0x48,0x6a,0x29,0xc0,0xa8,0x68, + 0x29,0x3f,0xaa,0xa9,0x01,0x8d,0x17,0x03, + 0x20,0x5c,0xe4,0xa2,0x3e,0x86,0x32,0xe8, + 0x86,0x34,0xa2,0x02,0x86,0x33,0x86,0x35, + 0x20,0x5c,0xeb,0x30,0x0f,0xad,0x3e,0x02, + 0xc9,0x45,0xf0,0x34,0x09,0x02,0xc9,0x43, + 0xf0,0x2e,0xa0,0x90,0x20,0x9a,0xeb,0xce, + 0xbd,0x02,0x30,0x03,0x4c,0x82,0xe9,0xae, + 0x0f,0x03,0xd0,0x0c,0x8e,0x01,0xd2,0x8e, + 0x03,0xd2,0x8e,0x05,0xd2,0x8e,0x07,0xd2, + 0xae,0x18,0x03,0x9a,0xa9,0x00,0x85,0x42, + 0xc0,0x00,0x8c,0x03,0x03,0x84,0x30,0x60, + 0x2c,0x03,0x03,0x50,0x08,0x20,0x15,0xeb, + 0x20,0x5c,0xeb,0x30,0xc7,0x20,0x9a,0xeb, + 0xad,0x3e,0x02,0xc9,0x45,0xf0,0xbb,0xa0, + 0x01,0xd0,0xc4,0xa9,0x38,0x8d,0x26,0x02, + 0xa9,0xec,0x8d,0x27,0x02,0x60,0xa2,0xff, + 0x86,0x3c,0xe8,0xa9,0x01,0x8d,0x17,0x03, + 0xa0,0x02,0x84,0x33,0x84,0x35,0x20,0x5c, + 0xe4,0xa2,0x3e,0x86,0x32,0xe8,0x86,0x34, + 0x20,0x5c,0xeb,0x30,0x09,0xad,0x3e,0x02, + 0xc9,0x41,0xf0,0x02,0xa0,0x8b,0x60,0xa5, + 0x10,0x09,0x10,0x29,0xf7,0x85,0x10,0x8d, + 0x0e,0xd2,0xad,0x32,0x02,0x29,0x0f,0x09, + 0x20,0xae,0x0f,0x03,0xf0,0x02,0x09,0x08, + 0x8d,0x32,0x02,0x8d,0x0f,0xd2,0xa2,0x08, + 0xad,0x0f,0x03,0xf0,0x02,0xa2,0x11,0xa0, + 0x08,0xbd,0xfa,0xea,0xca,0x99,0x00,0xd2, + 0x88,0x10,0xf6,0xa5,0x41,0xf0,0x17,0xa9, + 0xa8,0x8d,0x07,0xd2,0xae,0x0f,0x03,0xf0, + 0x0d,0xa9,0x10,0x2c,0x32,0x02,0xd0,0x06, + 0x8d,0x01,0xd2,0x8d,0x03,0xd2,0x8d,0x0a, + 0xd2,0x60,0x00,0xa0,0x00,0xa0,0x28,0xa0, + 0x00,0xa0,0x28,0x05,0xa0,0x07,0xa0,0xcc, + 0xa0,0x05,0xa0,0x28,0x00,0xa0,0x00,0xa0, + 0xcc,0xa0,0x05,0xa0,0x28,0x18,0xad,0x04, + 0x03,0x85,0x32,0x6d,0x08,0x03,0x85,0x34, + 0xad,0x05,0x03,0x85,0x33,0x6d,0x09,0x03, + 0x85,0x35,0x60,0x78,0x20,0xa7,0xea,0xa0, + 0x00,0x84,0x3a,0x84,0x30,0x84,0x3b,0xb1, + 0x32,0x8d,0x0d,0xd2,0x85,0x31,0x58,0xa5, + 0x11,0xf0,0x06,0xa5,0x3a,0xf0,0xf8,0xd0, + 0x06,0xa0,0x80,0x84,0x30,0xc6,0x11,0x78, + 0xa5,0x10,0x29,0xe7,0x85,0x10,0x8d,0x0e, + 0xd2,0x58,0x98,0x60,0xa9,0x00,0x85,0x31, + 0xa2,0x00,0x86,0x39,0x86,0x38,0xe8,0x86, + 0x30,0x78,0xad,0x32,0x02,0x29,0x8f,0x09, + 0x10,0x8d,0x32,0x02,0x8d,0x0f,0xd2,0xa5, + 0x10,0x09,0x20,0x85,0x10,0x8d,0x0e,0xd2, + 0x58,0xa9,0x3c,0x8d,0x03,0xd3,0xad,0x17, + 0x03,0xf0,0x0b,0xa4,0x30,0x30,0x05,0xa5, + 0x39,0xf0,0xf3,0x98,0x78,0x60,0xa0,0x8a, + 0x78,0x60,0xa5,0x10,0x29,0xd7,0x85,0x10, + 0x8d,0x0e,0xd2,0x58,0x60,0xa5,0x38,0xd0, + 0x2a,0x98,0x48,0xad,0x0d,0xd2,0xa0,0x00, + 0x91,0x32,0x18,0x65,0x31,0x69,0x00,0x85, + 0x31,0x68,0xa8,0xe6,0x32,0xd0,0x02,0xe6, + 0x33,0xa5,0x32,0xc5,0x34,0xa5,0x33,0xe5, + 0x35,0x90,0x06,0xc6,0x38,0xa5,0x3c,0xd0, + 0x15,0x68,0x40,0xad,0x0d,0xd2,0xc5,0x31, + 0xd0,0x06,0xa9,0xff,0x85,0x39,0x68,0x40, + 0xa9,0x8f,0x85,0x30,0xd0,0xf4,0x85,0x39, + 0xa9,0x00,0x85,0x3c,0x68,0x40,0xe6,0x32, + 0xd0,0x02,0xe6,0x33,0xa5,0x32,0xc5,0x34, + 0xa5,0x33,0xe5,0x35,0xb0,0x13,0x98,0x48, + 0xa0,0x00,0xb1,0x32,0x8d,0x0d,0xd2,0x65, + 0x31,0x69,0x00,0x85,0x31,0x68,0xa8,0x68, + 0x40,0xa5,0x31,0x8d,0x0d,0xd2,0xa9,0xff, + 0x85,0x3b,0xa5,0x10,0x09,0x08,0x29,0xef, + 0x85,0x10,0x8d,0x0e,0xd2,0x68,0x40,0xa5, + 0x3b,0xf0,0x0b,0x85,0x3a,0xa5,0x10,0x29, + 0xf7,0x85,0x10,0x8d,0x0e,0xd2,0x68,0x40, + 0xa9,0x00,0x8d,0x17,0x03,0x60,0xad,0x02, + 0x03,0xc9,0x52,0xf0,0x0f,0xc9,0x50,0xf0, + 0x05,0xa0,0x8b,0x4c,0x37,0xea,0x20,0x5a, + 0xec,0x4c,0x37,0xea,0x20,0x6b,0xec,0x4c, + 0x37,0xea,0xa2,0x02,0x20,0x9c,0xef,0x20, + 0xa7,0xea,0x20,0x15,0xeb,0x20,0x2b,0xeb, + 0x4c,0x37,0xea,0xa2,0x04,0x20,0x9c,0xef, + 0xa2,0x1a,0x20,0xcf,0xea,0xad,0x32,0x02, + 0x29,0x8f,0x09,0x10,0x8d,0x32,0x02,0xa9, + 0x01,0x8d,0x17,0x03,0xa2,0x0e,0xa0,0x10, + 0x20,0x66,0xe8,0xa9,0x10,0xac,0x17,0x03, + 0xf0,0x2b,0x2c,0x0f,0xd2,0xd0,0xf6,0x20, + 0x57,0xed,0x8c,0x0d,0x03,0x8d,0x0c,0x03, + 0xa9,0x10,0xa2,0x0a,0xac,0x17,0x03,0xf0, + 0x14,0x2c,0x0f,0xd2,0xf0,0xf6,0xca,0xf0, + 0x11,0xac,0x17,0x03,0xf0,0x07,0x2c,0x0f, + 0xd2,0xd0,0xf6,0xf0,0xe7,0xa0,0x8a,0x4c, + 0x37,0xea,0x20,0x57,0xed,0x8d,0x10,0x03, + 0x8c,0x11,0x03,0xa2,0x83,0xad,0x14,0xd0, + 0x4a,0xd0,0x02,0xa2,0x9c,0x8e,0x15,0x03, + 0xad,0x0c,0x03,0x20,0x65,0xed,0x85,0x34, + 0xad,0x10,0x03,0x20,0x65,0xed,0x18,0xe5, + 0x34,0x85,0x34,0xa0,0x00,0xb0,0x01,0x88, + 0xad,0x11,0x03,0x38,0xed,0x0d,0x03,0xaa, + 0xf0,0x0c,0xa5,0x34,0x18,0x6d,0x15,0x03, + 0x90,0x01,0xc8,0xca,0xd0,0xf6,0x84,0x35, + 0x0a,0x26,0x35,0x85,0x34,0xa4,0x35,0x06, + 0x34,0x26,0x35,0x65,0x34,0xaa,0x98,0x65, + 0x35,0xca,0x8e,0x04,0xd2,0x8e,0xee,0x02, + 0xe8,0xd0,0x02,0xe9,0x00,0x8d,0x06,0xd2, + 0x8d,0xef,0x02,0xae,0x32,0x02,0x8a,0x29, + 0xfc,0x8d,0x0f,0xd2,0x8d,0x0a,0xd2,0x8e, + 0x0f,0xd2,0x20,0x15,0xeb,0xa9,0x55,0xa0, + 0x00,0xa2,0x02,0x91,0x32,0xe6,0x32,0xd0, + 0x02,0xe6,0x33,0xca,0xd0,0xf5,0x0a,0x85, + 0x31,0x20,0x5e,0xeb,0x4c,0x9a,0xeb,0xa4, + 0x14,0xad,0x0b,0xd4,0xc4,0x14,0xd0,0xf7, + 0xc9,0x7c,0xf0,0xf3,0x60,0x38,0xe9,0x7c, + 0xb0,0x03,0x6d,0x15,0x03,0x60,0x60,0xa9, + 0x31,0x8d,0x00,0x03,0xa9,0x0f,0x8d,0x06, + 0x03,0xad,0x02,0x03,0x8d,0x3b,0x02,0xc9, + 0x53,0xd0,0x20,0xa9,0xea,0x8d,0x04,0x03, + 0xa9,0x02,0x8d,0x05,0x03,0x0a,0x8d,0x08, + 0x03,0xa9,0x00,0x8d,0x09,0x03,0x20,0xbb, + 0xed,0x30,0x07,0xae,0xec,0x02,0x8e,0x46, + 0x02,0xaa,0x60,0xa0,0x80,0x8c,0x08,0x03, + 0xa0,0x00,0x8c,0x09,0x03,0xc9,0x57,0xf0, + 0x19,0xc9,0x21,0xd0,0x06,0xad,0x46,0x02, + 0x8d,0x06,0x03,0xa9,0x40,0x8d,0x03,0x03, + 0x20,0x59,0xe4,0xad,0x02,0x03,0xc0,0x00, + 0x38,0x60,0xa9,0x80,0xd0,0xef,0xa9,0x1e, + 0x8d,0x14,0x03,0x60,0xa2,0x28,0xa4,0x2b, + 0xc0,0x53,0xd0,0x02,0xa2,0x1d,0x86,0x1e, + 0xe6,0x1d,0xa6,0x1d,0x9d,0xbf,0x03,0xc9, + 0x9b,0xf0,0x0b,0xe4,0x1e,0xb0,0x11,0xa0, + 0x01,0x60,0xa6,0x1d,0xf0,0xf9,0xa9,0x20, + 0x9d,0xc0,0x03,0xe8,0xe4,0x1e,0x90,0xf8, + 0xa0,0x0a,0xb9,0x20,0xee,0x99,0xff,0x02, + 0x88,0xd0,0xf7,0x84,0x1d,0x8e,0x08,0x03, + 0x8a,0x29,0x1d,0x49,0x4e,0x8d,0x0a,0x03, + 0xad,0x14,0x03,0x8d,0x06,0x03,0x4c,0x59, + 0xe4,0x40,0x01,0x57,0x80,0xc0,0x03,0x00, + 0x00,0x00,0x00,0xa9,0x00,0x85,0x1d,0xa2, + 0x09,0xbd,0x46,0xee,0x9d,0x00,0x03,0xca, + 0x10,0xf7,0x20,0x18,0xee,0x30,0x06,0xad, + 0xec,0x02,0x8d,0x14,0x03,0x60,0x40,0x01, + 0x53,0x40,0xea,0x02,0x00,0x00,0x04,0x00, + 0xa9,0xcc,0x8d,0xee,0x02,0xa9,0x05,0x8d, + 0xef,0x02,0x60,0xa5,0x2b,0x85,0x3e,0xa2, + 0x80,0xa5,0x2a,0x29,0x0c,0xc9,0x04,0xf0, + 0x05,0xc9,0x08,0xf0,0x03,0x60,0xa2,0x00, + 0x8e,0x89,0x02,0xa9,0x80,0x85,0x3d,0x8d, + 0x8a,0x02,0x0a,0x85,0x3f,0x2c,0x89,0x02, + 0x10,0x05,0x06,0x3d,0x20,0xc8,0xef,0x20, + 0xc8,0xef,0x20,0x68,0xfe,0x30,0x20,0x2c, + 0x89,0x02,0x10,0x08,0xa9,0xff,0x8d,0x0f, + 0x03,0x20,0xb2,0xea,0xa9,0x34,0x8d,0x02, + 0xd3,0xa2,0x00,0x2c,0x89,0x02,0x30,0x02, + 0xa2,0x01,0x20,0xa2,0xef,0xa0,0x01,0x60, + 0xad,0x89,0x02,0x10,0x0a,0xa5,0x3d,0xf0, + 0x03,0x20,0x21,0xef,0x20,0x21,0xef,0xa9, + 0x3c,0x8d,0x02,0xd3,0xa0,0x00,0x8c,0x01, + 0xd2,0x8c,0x03,0xd2,0x8c,0x07,0xd2,0xc8, + 0x60,0xa5,0x3f,0xd0,0x1d,0xa6,0x3d,0xec, + 0x8a,0x02,0xf0,0x08,0xbd,0x00,0x04,0xe6, + 0x3d,0xa0,0x01,0x60,0x20,0x51,0xef,0x30, + 0x0b,0xad,0xff,0x03,0xc9,0xfe,0xd0,0x05, + 0x85,0x3f,0xa0,0x88,0x60,0xa2,0x00,0x86, + 0x3d,0xa2,0x80,0xc9,0xfc,0xd0,0x06,0x8e, + 0x8a,0x02,0x4c,0xd5,0xee,0xc9,0xfa,0xd0, + 0x05,0xae,0x7f,0x04,0xb0,0xf1,0xa0,0xa3, + 0x60,0xa6,0x3d,0x9d,0x00,0x04,0xe8,0x86, + 0x3d,0xec,0x8a,0x02,0xb0,0x03,0xa0,0x01, + 0x60,0xa9,0x00,0xa2,0xfe,0xa4,0x3d,0xd0, + 0x08,0x99,0x00,0x04,0xc8,0x10,0xfa,0x30, + 0x0c,0xa2,0xfc,0xcc,0x8a,0x02,0xb0,0x05, + 0xa2,0xfa,0x8c,0x7f,0x04,0x8e,0xff,0x03, + 0x85,0x3d,0xa9,0x55,0x8d,0xfd,0x03,0x8d, + 0xfe,0x03,0xa2,0x80,0xa0,0x50,0x4c,0x55, + 0xef,0xa2,0x40,0xa0,0x52,0xa9,0x34,0x8d, + 0x02,0xd3,0x8e,0x03,0x03,0x8c,0x02,0x03, + 0xa9,0xfd,0x8d,0x04,0x03,0xa9,0x03,0x8d, + 0x05,0x03,0xa9,0x83,0x8d,0x08,0x03,0xa9, + 0x00,0x8d,0x09,0x03,0xa9,0x60,0x8d,0x00, + 0x03,0xa9,0x00,0x8d,0x01,0x03,0xa5,0x3e, + 0x8d,0x0b,0x03,0x20,0x59,0xe4,0xa5,0x3e, + 0x30,0x0f,0x2c,0x89,0x02,0x10,0x05,0xa2, + 0x06,0x20,0xa2,0xef,0xa9,0x3c,0x8d,0x02, + 0xd3,0xa4,0x30,0x60,0x2c,0x0b,0x03,0x10, + 0x01,0xe8,0x20,0x73,0xea,0xbc,0xba,0xef, + 0xbd,0xc1,0xef,0xaa,0xa9,0x01,0x8d,0x17, + 0x03,0x20,0x66,0xe8,0xad,0x17,0x03,0xd0, + 0xfb,0x60,0x80,0x40,0xb4,0x0f,0x78,0x0a, + 0x3c,0x04,0x02,0x00,0x00,0x00,0x00,0x00, + 0xa0,0x00,0x98,0xa2,0x0a,0x48,0xad,0x0b, + 0xd4,0xcd,0x0b,0xd4,0xf0,0xfb,0xca,0xd0, + 0xf5,0x68,0x49,0x08,0x8d,0x1f,0xd0,0xd0, + 0xea,0x88,0xd0,0xe7,0x60,0x50,0x30,0xe4, + 0x43,0x40,0xe4,0x45,0x00,0xe4,0x53,0x10, + 0xe4,0x4b,0x20,0xe4,0x6c,0xfe,0xbf,0x78, + 0xd8,0xa2,0xff,0x9a,0x78,0xd8,0xa2,0xff, + 0x9a,0xe8,0x86,0x08,0xad,0xfc,0xbf,0xd0, + 0x17,0xa2,0xff,0xec,0xff,0xbf,0xf0,0x10, + 0x8e,0xfc,0xbf,0xcd,0xfc,0xbf,0x8d,0xfc, + 0xbf,0xd0,0x05,0x2c,0xfd,0xbf,0x30,0xd4, + 0x20,0x6f,0xf0,0x20,0x9b,0xf0,0xa6,0x06, + 0xa0,0x08,0xa9,0x00,0x85,0x66,0x85,0x67, + 0x91,0x66,0xc8,0xd0,0xfb,0xe6,0x67,0xca, + 0xd0,0xf6,0xa9,0x80,0x85,0x0a,0xa9,0xe4, + 0x85,0x0b,0xce,0x44,0x02,0x4c,0xd9,0xf0, + 0x78,0xad,0x44,0x02,0xd0,0xae,0xd8,0xa2, + 0xff,0x9a,0x86,0x08,0x20,0x6f,0xf0,0x20, + 0x9b,0xf0,0xa2,0x60,0xa9,0x00,0x95,0x0f, + 0xca,0xd0,0xfb,0x9d,0x00,0x02,0x9d,0xed, + 0x02,0xe8,0xd0,0xf7,0x4c,0xd9,0xf0,0xa0, + 0x00,0x98,0x99,0x00,0xd0,0x99,0x00,0xd2, + 0x99,0x00,0xd4,0xc8,0xd0,0xf4,0xa9,0x3c, + 0xa2,0x38,0x8e,0x02,0xd3,0x8e,0x03,0xd3, + 0x8c,0x00,0xd3,0x8c,0x01,0xd3,0x8d,0x02, + 0xd3,0x8d,0x03,0xd3,0x8c,0x00,0xd3,0x8c, + 0x01,0xd3,0x60,0xa0,0x00,0x84,0x64,0xa2, + 0x02,0x86,0x65,0xb1,0x64,0x49,0xff,0x91, + 0x64,0xd1,0x64,0xd0,0x09,0x49,0xff,0x91, + 0x64,0xe8,0xe0,0xd0,0xd0,0xeb,0x86,0x06, + 0x60,0x66,0xe7,0x65,0xe7,0x65,0xe7,0x65, + 0xe7,0xcc,0xfe,0xa5,0xeb,0xee,0xeb,0x27, + 0xec,0x65,0xe7,0x65,0xe7,0x65,0xe7,0xd9, + 0xe8,0x1d,0xe7,0x61,0xe7,0x00,0x00,0x30, + 0x28,0xa5,0x06,0x8d,0xe4,0x02,0xa9,0x02, + 0x85,0x52,0xa9,0x27,0x85,0x53,0xa2,0x17, + 0xbd,0xb9,0xf0,0x9d,0x00,0x02,0xca,0x10, + 0xf7,0xa2,0x05,0xbd,0xd1,0xf0,0x9d,0x22, + 0x02,0xca,0x10,0xf7,0xa9,0x00,0x8d,0x36, + 0x02,0xa9,0xff,0x8d,0x37,0x02,0xa2,0xff, + 0x86,0x11,0xe8,0x8e,0xe5,0x02,0x8e,0xe7, + 0x02,0xa5,0x06,0x8d,0xe6,0x02,0xa2,0x07, + 0x8e,0xe8,0x02,0x20,0x6e,0xed,0x20,0x90, + 0xf5,0x20,0x4d,0xfe,0x20,0xce,0xed,0xa2, + 0x0e,0xbd,0xe5,0xef,0x9d,0x1a,0x03,0xca, + 0x10,0xf7,0x20,0x6e,0xe4,0x20,0x51,0xe9, + 0x20,0x8b,0xe8,0xad,0x1f,0xd0,0x29,0x01, + 0x49,0x01,0x8d,0xe9,0x03,0x58,0xa9,0x00, + 0x85,0x07,0xad,0xfc,0x9f,0xd0,0x18,0xad, + 0xfb,0x9f,0xaa,0x49,0xff,0x8d,0xfb,0x9f, + 0xcd,0xfb,0x9f,0x8e,0xfb,0x9f,0xf0,0x07, + 0x20,0x10,0xf2,0xa9,0x01,0x85,0x07,0xa9, + 0x00,0x85,0x06,0xad,0xfc,0xbf,0xd0,0x18, + 0xad,0xfb,0xbf,0xaa,0x49,0xff,0x8d,0xfb, + 0xbf,0xcd,0xfb,0xbf,0x8e,0xfb,0xbf,0xf0, + 0x07,0x20,0x0d,0xf2,0xa9,0x01,0x85,0x06, + 0xa9,0x03,0x8d,0x42,0x03,0xa9,0x13,0x8d, + 0x44,0x03,0xa9,0xf2,0x8d,0x45,0x03,0xa9, + 0x0c,0x8d,0x4a,0x03,0xa2,0x00,0x8e,0x4b, + 0x03,0x20,0x56,0xe4,0xa5,0x14,0xc5,0x14, + 0xf0,0xfc,0xa5,0x08,0xd0,0x0b,0xad,0xe9, + 0x03,0xf0,0x0f,0x20,0x7a,0xf2,0x4c,0xc2, + 0xf1,0xa9,0x02,0x24,0x09,0xf0,0x03,0x20, + 0x17,0xf2,0xa5,0x08,0xd0,0x1d,0xa5,0x07, + 0xd0,0x06,0xa6,0x06,0xf0,0x0f,0xd0,0x07, + 0xad,0xfd,0x9f,0xa6,0x06,0xf0,0x03,0x0d, + 0xfd,0xbf,0x4a,0x90,0x0e,0x20,0x1b,0xf2, + 0x4c,0xeb,0xf1,0xa5,0x09,0x4a,0x90,0x03, + 0x20,0x14,0xf2,0xa2,0x00,0x8e,0x44,0x02, + 0xa9,0x04,0xa6,0x06,0xf0,0x08,0x2c,0xfd, + 0xbf,0xf0,0x03,0x6c,0xfa,0xbf,0xa6,0x07, + 0xf0,0x08,0x2c,0xfd,0x9f,0xf0,0x03,0x6c, + 0xfa,0x9f,0x6c,0x0a,0x00,0x6c,0xfe,0xbf, + 0x6c,0xfe,0x9f,0x45,0x6c,0x0c,0x00,0x6c, + 0x02,0x00,0xea,0xa9,0x53,0x8d,0x02,0x03, + 0xa2,0x01,0x8e,0x01,0x03,0x20,0x53,0xe4, + 0x30,0x3c,0xa2,0x01,0x8e,0x01,0x03,0x8e, + 0x0a,0x03,0xca,0x8e,0x04,0x03,0x8e,0x0b, + 0x03,0xa9,0x52,0x8d,0x02,0x03,0xa9,0x04, + 0x8d,0x05,0x03,0x20,0x53,0xe4,0x30,0x1a, + 0xa2,0x0c,0x20,0xb5,0xf2,0x20,0xe4,0xf2, + 0xce,0x41,0x02,0xf0,0x18,0xee,0x0a,0x03, + 0xd0,0x03,0xee,0x0b,0x03,0x20,0x53,0xe4, + 0x10,0xeb,0xc0,0x8a,0xd0,0x01,0x60,0x20, + 0xf9,0xf2,0x4c,0x1b,0xf2,0x20,0xd2,0xf2, + 0xb0,0xf5,0x20,0x14,0xf2,0xa9,0x01,0x85, + 0x09,0x60,0xa9,0x80,0x85,0x3e,0x20,0x7d, + 0xe4,0x20,0x7a,0xe4,0x30,0x24,0xa2,0x02, + 0x20,0xb5,0xf2,0x20,0xe4,0xf2,0x20,0x7a, + 0xe4,0x30,0x17,0xce,0x41,0x02,0xd0,0xf3, + 0x20,0xd2,0xf2,0x20,0x17,0xf2,0xa9,0x00, + 0x8d,0xe9,0x03,0xa9,0x02,0x85,0x09,0x6c, + 0x0a,0x00,0xa9,0x00,0x8d,0xe9,0x03,0x20, + 0xb0,0xee,0x4c,0xf9,0xf2,0xa0,0xfc,0xb9, + 0x04,0x03,0x99,0x44,0x01,0xc8,0xd0,0xf7, + 0x85,0x16,0xad,0x42,0x02,0x85,0x15,0xad, + 0x04,0x04,0x95,0x00,0xad,0x05,0x04,0x95, + 0x01,0x60,0xad,0x42,0x02,0x18,0x69,0x06, + 0x85,0x04,0xad,0x43,0x02,0x69,0x00,0x85, + 0x05,0x6c,0x04,0x00,0xa0,0x7f,0xb9,0x00, + 0x04,0x91,0x15,0x88,0x10,0xf8,0xa5,0x15, + 0x49,0x80,0x85,0x15,0x30,0x02,0xe6,0x16, + 0x60,0xa2,0xf5,0x8a,0x48,0xbd,0x14,0xf2, + 0x20,0xaa,0xfa,0x68,0xaa,0xe8,0xd0,0xf3, + 0x60,0x42,0x4f,0x4f,0x54,0x20,0x45,0x52, + 0x52,0x4f,0x52,0x9b,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xa9,0x0c, + 0x85,0x2a,0xa9,0x00,0x85,0x2b,0xad,0x2f, + 0x02,0x29,0xdc,0x8d,0x2f,0x02,0x8d,0x00, + 0xd4,0xa2,0x0b,0xa9,0x00,0x95,0x54,0x9d, + 0x90,0x02,0xca,0xd0,0xf8,0x86,0x7b,0xa5, + 0x2b,0x29,0x0f,0x85,0x57,0xaa,0xbd,0x18, + 0xfe,0x4d,0x6f,0x02,0x29,0xc0,0x4d,0x6f, + 0x02,0x8d,0x6f,0x02,0xc9,0x40,0x8a,0xf0, + 0x06,0xa5,0x2a,0x90,0x02,0x29,0xef,0x0a, + 0x0a,0x85,0x68,0xbc,0x28,0xfe,0xbe,0x38, + 0xfe,0x0a,0x10,0x03,0xbe,0xc9,0xf9,0x86, + 0x69,0xa5,0x6a,0xa6,0x57,0x18,0x7d,0x08, + 0xfe,0xb0,0x09,0x8a,0xf0,0x03,0x20,0xee, + 0xf3,0xa0,0x93,0x60,0x85,0x59,0xbc,0xf8, + 0xfd,0x84,0x58,0xbd,0x18,0xfe,0xa6,0x59, + 0x29,0x30,0xf0,0x03,0xa0,0x00,0xca,0x84, + 0x70,0x8e,0xe6,0x02,0x86,0x71,0x8e,0x31, + 0x02,0xc9,0x20,0xa9,0xf8,0x90,0x02,0xa9, + 0xf5,0xe5,0x69,0x24,0x68,0x50,0x02,0xe9, + 0x06,0x65,0x70,0x8d,0xe5,0x02,0x85,0x70, + 0x8d,0x30,0x02,0xe4,0x0f,0x90,0xbc,0xd0, + 0x04,0xc5,0x0e,0x90,0xb6,0xce,0xe5,0x02, + 0xa6,0x6a,0xca,0x8e,0x95,0x02,0xa9,0x60, + 0x8d,0x94,0x02,0x08,0x78,0x0a,0x05,0x10, + 0x85,0x10,0x8d,0x0e,0xd2,0x28,0xa0,0x18, + 0x8c,0xbf,0x02,0xa0,0x05,0xb9,0x87,0xf5, + 0x99,0xc3,0x02,0x88,0xd0,0xf7,0x8c,0xf0, + 0x02,0xa9,0x70,0xa2,0x03,0x20,0x6c,0xf5, + 0xa5,0x57,0xc9,0x0b,0xd0,0x05,0xa9,0x06, + 0x8d,0xc8,0x02,0x20,0x31,0xf5,0x84,0x7e, + 0x20,0x81,0xf5,0x24,0x68,0x50,0x12,0xa2, + 0x04,0x8e,0xbf,0x02,0x20,0x0d,0xf9,0xa4, + 0x7e,0x20,0x31,0xf5,0x84,0x7e,0x20,0x81, + 0xf5,0xa9,0x02,0x8d,0xf3,0x02,0xa2,0x0f, + 0x4a,0x9d,0xa2,0x02,0xca,0xd0,0xfa,0x86, + 0x6b,0xa2,0xe0,0x8e,0xf4,0x02,0xa2,0x40, + 0x8e,0x0e,0xd4,0xa4,0x7e,0xa2,0x70,0xa9, + 0x41,0x20,0x73,0xf5,0xad,0x2f,0x02,0x09, + 0x22,0x8d,0x2f,0x02,0xa5,0x14,0xc5,0x14, + 0xf0,0xfc,0xa5,0x2b,0x29,0x0f,0xd0,0x03, + 0x20,0x81,0xf6,0x20,0x63,0xfd,0xa2,0x00, + 0x60,0xa6,0x57,0xbd,0x18,0xfe,0x29,0x0f, + 0x48,0x09,0x40,0xa2,0x58,0x20,0x73,0xf5, + 0xa6,0x69,0xa5,0x57,0xd0,0x03,0xae,0xbf, + 0x02,0xca,0x68,0xc9,0x0e,0x90,0x1d,0xa2, + 0x5d,0x20,0x6c,0xf5,0x48,0x09,0x40,0x91, + 0x70,0xc8,0xa9,0x00,0x91,0x70,0xc8,0xa5, + 0x59,0x69,0x0e,0x91,0x70,0xc8,0xa5,0x69, + 0xe9,0x5e,0xaa,0x68,0x91,0x70,0xc8,0xca, + 0xd0,0xfa,0x60,0x91,0x70,0xc8,0xb5,0x00, + 0x91,0x70,0xc8,0xb5,0x01,0xa2,0x01,0xd0, + 0xeb,0x24,0x68,0x30,0xed,0x4c,0x16,0xf8, + 0x28,0xca,0x94,0x46,0x00,0x01,0x03,0x07, + 0xad,0xe6,0x02,0x85,0x6a,0xa9,0x00,0x85, + 0x4f,0xa9,0xfe,0x85,0x4e,0x60,0x20,0xc6, + 0xf8,0x30,0x3a,0xa4,0x54,0x20,0x45,0xf9, + 0xa5,0x55,0xa6,0x57,0xbc,0xd4,0xf9,0x59, + 0x8c,0xf5,0xaa,0xa5,0x56,0x20,0x8d,0xf9, + 0xa4,0x6f,0xb1,0x66,0x20,0x7a,0xf9,0x0a, + 0x08,0x10,0x02,0x49,0x40,0x69,0x40,0x28, + 0x6a,0xa6,0x57,0xbc,0xd4,0xf9,0x39,0xe4, + 0xf9,0xa6,0x57,0xf0,0x03,0x4c,0xa5,0xf9, + 0x20,0xd8,0xfd,0xa0,0x01,0x60,0x8d,0xfb, + 0x02,0x20,0xc6,0xf8,0x30,0x0c,0xad,0xfb, + 0x02,0xc9,0x7d,0xd0,0x0e,0x20,0x16,0xf8, + 0xa0,0x01,0x60,0x4c,0xbe,0xf9,0x20,0xc6, + 0xf8,0x30,0xf7,0x20,0xce,0xfd,0xad,0xfb, + 0x02,0xa6,0x57,0xf0,0x1e,0xc9,0x9b,0xf0, + 0xea,0xae,0xff,0x02,0xd0,0xfb,0x20,0x9a, + 0xf6,0x48,0x20,0x75,0xf9,0x68,0xa4,0x6f, + 0x51,0x66,0x25,0x6e,0x51,0x66,0x91,0x66, + 0x4c,0xa5,0xf9,0xc9,0x9b,0xd0,0x18,0xa5, + 0x52,0x85,0x55,0xe6,0x54,0xa5,0x54,0xcd, + 0xbf,0x02,0x90,0x08,0xae,0xbf,0x02,0x86, + 0x54,0x20,0xc3,0xfc,0x4c,0x81,0xf6,0xae, + 0xff,0x02,0xd0,0xfb,0x48,0x20,0xb7,0xfc, + 0x68,0x20,0xb7,0xf6,0xa0,0x00,0x91,0x5e, + 0xe6,0x5e,0xd0,0x02,0xe6,0x5f,0x20,0xd8, + 0xfd,0xb0,0x29,0xa5,0x54,0xcd,0xbf,0x02, + 0x90,0x12,0x20,0xc3,0xfc,0x20,0x87,0xf6, + 0x20,0x3b,0xfd,0x59,0xb2,0x02,0x99,0xb2, + 0x02,0x4c,0x81,0xf6,0x20,0x87,0xf6,0xa5, + 0x54,0x20,0x4a,0xfd,0xf0,0x03,0x20,0x59, + 0xf8,0x20,0xb7,0xfc,0x4c,0xe7,0xfd,0xa6, + 0x54,0xca,0x8a,0x20,0x53,0xfd,0x18,0x69, + 0x02,0xc5,0x54,0x90,0x01,0x60,0x68,0x68, + 0x90,0xe7,0xa6,0x57,0xbc,0xd4,0xf9,0xbe, + 0xe8,0xf9,0x86,0x77,0xbe,0xe4,0xf9,0x8e, + 0xa0,0x02,0x30,0x0b,0x2d,0xa0,0x02,0x19, + 0xa1,0xfd,0xaa,0xbd,0xa5,0xfd,0x60,0x0a, + 0x08,0xe9,0x3f,0x10,0x02,0x49,0x40,0x28, + 0x6a,0x60,0xa5,0x22,0xc9,0x11,0xf0,0x05, + 0xc9,0x12,0xf0,0x01,0x60,0xad,0xfd,0x02, + 0x20,0x9a,0xf6,0x8d,0xbc,0x02,0xad,0xfb, + 0x02,0x20,0x9a,0xf6,0x85,0x51,0x20,0x75, + 0xf9,0xa0,0x01,0x20,0x4f,0xf9,0x85,0x78, + 0xaa,0xa0,0x00,0xa5,0x54,0x38,0xe5,0x5a, + 0xb0,0x0c,0x49,0xff,0x69,0x01,0x48,0x8a, + 0x49,0xff,0xaa,0xe8,0x88,0x68,0x86,0x70, + 0x85,0x76,0x84,0x71,0xa2,0x00,0xa5,0x55, + 0x38,0xe5,0x5b,0x85,0x72,0xa5,0x56,0xe5, + 0x5c,0xb0,0x10,0x49,0xff,0xa8,0xa5,0x72, + 0x49,0xff,0x69,0x01,0x85,0x72,0x98,0x69, + 0x00,0xa2,0xcc,0x85,0x73,0x8a,0xa6,0x57, + 0xbc,0xd4,0xf9,0x18,0x79,0x79,0xf7,0x85, + 0x64,0xa9,0xf7,0x85,0x65,0x85,0x75,0xb9, + 0x79,0xf7,0x18,0x69,0xd9,0x85,0x74,0xa6, + 0x72,0x8a,0x38,0xe5,0x76,0x85,0x68,0xa4, + 0x73,0x98,0xe9,0x00,0x85,0x69,0xb0,0x04, + 0xa0,0x00,0xa6,0x76,0x86,0x7e,0x84,0x7f, + 0x98,0xd0,0x03,0x8a,0xf0,0x0d,0x4c,0xce, + 0xf7,0x20,0xce,0xfd,0xa4,0x57,0xd0,0x03, + 0x20,0xb7,0xfc,0xa0,0x01,0x60,0x86,0x6e, + 0x4c,0xce,0xf7,0xa4,0x6f,0xa6,0x6e,0xd0, + 0x33,0xb7,0xb1,0xb3,0xb4,0x0a,0x0a,0x0a, + 0x0a,0x90,0x05,0xc6,0x6f,0xad,0xa0,0x02, + 0xd0,0x31,0x4a,0x4a,0x4a,0x4a,0x90,0x09, + 0xa5,0x77,0xc8,0xc4,0x78,0x90,0x02,0xa0, + 0x00,0x85,0x6e,0xf0,0xd1,0xb1,0x66,0x24, + 0x6e,0xd0,0xcb,0x4d,0xbc,0x02,0x25,0x6e, + 0x51,0x66,0x91,0x66,0xa5,0x6e,0x6c,0x74, + 0x00,0x4a,0x4a,0x4a,0x4a,0x90,0x04,0xe6, + 0x6f,0xa5,0x77,0x85,0x6e,0xa4,0x6f,0xa5, + 0x51,0x51,0x66,0x25,0x6e,0x51,0x66,0x91, + 0x66,0xa5,0x22,0x4a,0x90,0xa5,0xa5,0x7e, + 0xd0,0x04,0xc6,0x7f,0x30,0x8b,0xc6,0x7e, + 0xa5,0x68,0x0a,0xa8,0xa5,0x69,0x2a,0xaa, + 0x98,0x18,0xe5,0x72,0x8a,0x48,0xe5,0x73, + 0x10,0x13,0xa2,0x02,0xb5,0x70,0x18,0x75, + 0x66,0x95,0x66,0xb5,0x71,0x75,0x67,0x95, + 0x67,0xca,0xca,0x10,0xef,0x98,0x18,0x65, + 0x76,0x68,0x69,0x00,0x30,0xb7,0xa5,0x68, + 0x38,0xe5,0x76,0x85,0x68,0xb0,0x02,0xc6, + 0x69,0xa5,0x6e,0x6c,0x64,0x00,0xa0,0x04, + 0xa6,0x7b,0xd0,0x08,0xa4,0x57,0xbe,0x28, + 0xfe,0xbc,0x38,0xfe,0x20,0x4f,0xf9,0x18, + 0xa6,0x57,0xf0,0x02,0x69,0xa0,0xa8,0xa5, + 0x65,0x69,0x00,0xaa,0x65,0x59,0x85,0x67, + 0xa5,0x58,0x85,0x66,0xa9,0x00,0x88,0x91, + 0x66,0xd0,0xfb,0xc6,0x67,0xca,0x10,0xf6, + 0x85,0x56,0x85,0x54,0x85,0x5d,0xa6,0x57, + 0xd0,0x02,0xa5,0x52,0x85,0x55,0x4c,0xbb, + 0xfd,0x18,0x08,0xac,0xbf,0x02,0x88,0x20, + 0x45,0xf9,0x20,0x8c,0xfd,0xae,0xbf,0x02, + 0xd0,0x09,0xa0,0x27,0xb1,0x68,0x91,0x66, + 0x88,0x10,0xf9,0xa5,0x68,0x85,0x66,0x38, + 0xe9,0x28,0x85,0x68,0xa5,0x69,0x85,0x67, + 0xe9,0x00,0x85,0x69,0xca,0xe4,0x54,0xd0, + 0xe1,0xa0,0x27,0xa9,0x00,0x91,0x66,0x88, + 0x10,0xfb,0x20,0x3b,0xfd,0x28,0xb0,0x02, + 0xa9,0x00,0x85,0x51,0xa9,0x00,0x38,0xfd, + 0xc1,0xe4,0x0a,0x39,0xb2,0x02,0x18,0x79, + 0xb2,0x02,0x6a,0x05,0x51,0x99,0xb2,0x02, + 0x88,0x10,0x03,0x6e,0xb3,0x02,0x88,0x10, + 0x03,0x6e,0xb4,0x02,0x60,0x48,0xa0,0x00, + 0xa5,0x5d,0x91,0x5e,0x68,0x60,0xad,0xbf, + 0x02,0xa6,0x57,0xd0,0x04,0x24,0x7b,0x30, + 0x06,0xbc,0x28,0xfe,0xb9,0x38,0xfe,0xa0, + 0x27,0xc4,0x53,0xb0,0x02,0x84,0x53,0x18, + 0xe5,0x54,0xb0,0x0e,0xa0,0x00,0x84,0x56, + 0x8a,0xd0,0x02,0xa4,0x52,0x84,0x55,0xa0, + 0x8d,0x60,0xbc,0x3d,0xfe,0xa5,0x55,0xd9, + 0xca,0xf9,0xa5,0x56,0xf9,0xcf,0xf9,0xb0, + 0xe3,0xa0,0xff,0xa5,0x11,0xd0,0x04,0x84, + 0x11,0xa0,0x7f,0xc8,0x60,0xa0,0x17,0xcc, + 0xbf,0x02,0x48,0xa9,0x00,0x65,0x7b,0xf0, + 0x14,0xa2,0x0b,0xb5,0x54,0xbc,0x90,0x02, + 0x94,0x54,0x9d,0x90,0x02,0xca,0x10,0xf3, + 0x8a,0x45,0x7b,0x85,0x7b,0x68,0x60,0x20, + 0x4f,0xf9,0x85,0x64,0x8a,0x18,0x65,0x64, + 0x90,0x02,0xe6,0x65,0x18,0x65,0x58,0xaa, + 0xa5,0x65,0x65,0x59,0x60,0xa2,0x00,0x20, + 0x2f,0xf9,0x86,0x66,0x85,0x67,0x60,0xa9, + 0x00,0x85,0x65,0x84,0x64,0xa4,0x57,0xb9, + 0x3d,0xfe,0x38,0xf9,0xd4,0xf9,0xa8,0xc8, + 0xa5,0x64,0x0a,0x26,0x65,0x0a,0x26,0x65, + 0x65,0x64,0x90,0x02,0xe6,0x65,0x0a,0x26, + 0x65,0x88,0x10,0xfa,0x60,0x20,0x84,0xf9, + 0xa5,0x77,0xca,0x30,0x04,0x4a,0xca,0x10, + 0xfc,0x85,0x6e,0x60,0xa4,0x5a,0x20,0x45, + 0xf9,0xa5,0x5c,0xa6,0x5b,0x6a,0x86,0x6f, + 0xa9,0x00,0xa6,0x57,0xbc,0xd4,0xf9,0xf0, + 0x06,0x66,0x6f,0x6a,0x88,0xd0,0xfa,0x2a, + 0x2a,0x2a,0x2a,0xaa,0x60,0xe6,0x55,0xd0, + 0x02,0xe6,0x56,0xa6,0x57,0xbc,0x3d,0xfe, + 0xbe,0xcf,0xf9,0xe4,0x56,0xd0,0x0f,0xbe, + 0xca,0xf9,0xe4,0x55,0xd0,0x08,0xa0,0x00, + 0x84,0x55,0x84,0x56,0xe6,0x54,0xa0,0x01, + 0x60,0x0a,0x14,0x28,0x50,0xa0,0x40,0x00, + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02, + 0x03,0x02,0x03,0x02,0x03,0x01,0x01,0x01, + 0x00,0x00,0x03,0x02,0xff,0x0f,0x03,0x01, + 0xff,0xf0,0xc0,0x80,0x20,0xbb,0xfd,0x8e, + 0xfe,0x02,0x8e,0xa2,0x02,0x4c,0xf2,0xf3, + 0xa5,0x6b,0xd0,0x06,0x20,0x18,0xfa,0x10, + 0x01,0x60,0x20,0x0d,0xf9,0xc6,0x6b,0xd0, + 0x09,0xa9,0x9b,0x20,0xde,0xf5,0xa9,0x9b, + 0xd0,0x03,0x20,0x9e,0xf5,0x4c,0x65,0xfd, + 0x20,0x0d,0xf9,0xa5,0x55,0x85,0x6d,0xa5, + 0x54,0x85,0x6c,0x20,0x65,0xfd,0xa5,0x2a, + 0x4a,0xb0,0x25,0x20,0x68,0xfe,0x10,0x01, + 0x60,0xc9,0x9b,0xf0,0x1d,0x20,0xaa,0xfa, + 0x30,0xf6,0xa5,0x55,0xc9,0x21,0xd0,0xeb, + 0x20,0x51,0xfd,0x18,0x69,0x02,0xc5,0x54, + 0xd0,0xe1,0x20,0x5e,0xfb,0x4c,0x2b,0xfa, + 0xa9,0x9b,0x20,0xaa,0xfa,0x30,0xd9,0x20, + 0x0d,0xf9,0x20,0xbd,0xf8,0xa2,0x00,0x86, + 0x63,0xa4,0x6c,0x84,0x54,0x20,0x47,0xf9, + 0xa4,0x6d,0xe6,0x63,0xb1,0x66,0xf0,0x04, + 0xa5,0x63,0x85,0x6b,0xc4,0x53,0xc8,0x90, + 0xf1,0x20,0x8c,0xfd,0xe6,0x54,0xa5,0x54, + 0xcd,0xbf,0x02,0xb0,0x0a,0x20,0x4a,0xfd, + 0xd0,0x08,0xa4,0x52,0x4c,0x6a,0xfa,0x20, + 0xc3,0xfc,0xe6,0x6b,0xa5,0x54,0x20,0x3d, + 0xfd,0x19,0xb2,0x02,0x99,0xb2,0x02,0xa6, + 0x6d,0x86,0x55,0xa4,0x6c,0x84,0x54,0x4c, + 0x63,0xfd,0xa4,0x57,0xf0,0x0c,0xac,0xbf, + 0x02,0xc0,0x04,0xf0,0x05,0x48,0x20,0xee, + 0xf3,0x68,0x20,0x0d,0xf9,0x20,0xbd,0xf8, + 0xa8,0x0e,0xa2,0x02,0xb0,0x1e,0x29,0x1f, + 0xc9,0x1b,0x90,0x18,0xa2,0x0e,0x98,0x20, + 0xae,0xfc,0xd0,0x10,0xad,0xfe,0x02,0xd0, + 0x0b,0x20,0x59,0xfc,0x20,0xb7,0xfc,0x20, + 0xe7,0xfd,0x10,0x06,0x8c,0xfb,0x02,0x20, + 0xf6,0xf5,0xad,0xfb,0x02,0x4c,0x65,0xfd, + 0x1b,0x1c,0x1d,0x1e,0x1f,0x7d,0x7e,0x7f, + 0x9c,0x9d,0x9e,0x9f,0xfd,0xfe,0xff,0x9b, + 0x0e,0x17,0x21,0xb7,0xc4,0x14,0x3c,0x7d, + 0xcd,0xd3,0x6a,0x62,0x5d,0xda,0xe6,0xa9, + 0x80,0x8d,0xa2,0x02,0x60,0x4c,0x16,0xf8, + 0xa6,0x54,0xd0,0x03,0xae,0xbf,0x02,0xca, + 0x10,0x0a,0xa6,0x54,0xe8,0xec,0xbf,0x02, + 0x90,0x02,0xa2,0x00,0x86,0x54,0x8a,0x20, + 0x53,0xfd,0xc5,0x6c,0xf0,0x06,0x85,0x6c, + 0xa5,0x52,0x85,0x6d,0x60,0xa5,0x52,0xc5, + 0x55,0xb0,0x0b,0xc6,0x55,0x20,0xb7,0xfc, + 0xa0,0x00,0x98,0x91,0x5e,0x60,0xa5,0x54, + 0x20,0x4a,0xfd,0xd0,0xf8,0xc6,0x54,0xa5, + 0x53,0x85,0x55,0x4c,0x45,0xfb,0xa0,0x00, + 0x4c,0xcc,0xe4,0x20,0x77,0xfb,0x1d,0xa3, + 0x02,0xd0,0x08,0x20,0x77,0xfb,0x49,0xff, + 0x3d,0xa3,0x02,0x9d,0xa3,0x02,0x60,0x20, + 0x6e,0xfd,0xa8,0x4c,0x7d,0xfd,0x20,0x6e, + 0xfd,0xa8,0x8a,0x38,0x65,0x54,0x85,0x54, + 0xc8,0xc0,0x78,0xb0,0x08,0x20,0x7d,0xfd, + 0x3d,0xa3,0x02,0xf0,0xf3,0x84,0x55,0xa5, + 0x55,0x38,0xe9,0x28,0x90,0x19,0x85,0x55, + 0xe6,0x54,0xa5,0x54,0xcd,0xbf,0x02,0xb0, + 0x07,0x20,0x4a,0xfd,0xf0,0xe9,0x10,0x03, + 0x20,0xc3,0xfc,0xa6,0x52,0x86,0x55,0x60, + 0xa6,0x52,0xe4,0x55,0xb0,0x03,0xc6,0x55, + 0x60,0xa6,0x53,0xb0,0xf0,0xa6,0x55,0xe4, + 0x53,0xb0,0xe8,0xe6,0x55,0x60,0x20,0x51, + 0xfd,0x4c,0xc5,0xfc,0x38,0x20,0x5a,0xf8, + 0x4c,0xb3,0xfb,0xa4,0x54,0x84,0x51,0x20, + 0x45,0xf9,0xa4,0x55,0x4c,0x72,0xfc,0x20, + 0x51,0xfd,0x18,0x69,0x03,0x85,0x76,0xa4, + 0x54,0x84,0x51,0x20,0x45,0xf9,0xa4,0x55, + 0xa2,0x00,0xf0,0x04,0xa4,0x52,0xa6,0x50, + 0x84,0x65,0xa4,0x53,0xb1,0x66,0x85,0x50, + 0x88,0xb1,0x66,0xc8,0x91,0x66,0x88,0xc4, + 0x65,0xd0,0xf5,0x8a,0x91,0x66,0xe6,0x51, + 0x20,0x8c,0xfd,0xa5,0x51,0xcd,0xbf,0x02, + 0xb0,0x05,0x20,0x4a,0xfd,0xf0,0xd5,0xa5, + 0x50,0xf0,0x2d,0xa5,0x54,0x48,0xa6,0x51, + 0xe4,0x76,0x08,0x86,0x54,0xa9,0x00,0x85, + 0x76,0xec,0xbf,0x02,0x90,0x03,0x20,0xc3, + 0xfc,0x28,0xb0,0x0e,0x20,0x59,0xf8,0xa4, + 0x54,0x20,0x45,0xf9,0xa5,0x50,0xa4,0x52, + 0x91,0x66,0x68,0x38,0xe5,0x76,0x85,0x54, + 0x60,0xa9,0xfb,0x48,0xbd,0x00,0xfb,0x48, + 0x60,0xa4,0x52,0xb1,0x66,0xa4,0x53,0x91, + 0x68,0xa4,0x52,0xc8,0xb1,0x66,0x88,0x91, + 0x66,0xc8,0xc4,0x53,0xd0,0xf5,0x20,0x8c, + 0xfd,0xa6,0x51,0xe8,0xec,0xbf,0x02,0xb0, + 0x08,0x86,0x51,0x8a,0x20,0x4a,0xfd,0xf0, + 0xd8,0xa4,0x53,0xa9,0x00,0x91,0x68,0xc4, + 0x52,0xf0,0x06,0x88,0xb1,0x68,0xf0,0xf7, + 0x60,0xc6,0x51,0xa5,0x51,0x20,0x4a,0xfd, + 0xd0,0x0b,0xa5,0x55,0x48,0xa5,0x51,0x20, + 0xc5,0xfc,0x68,0x85,0x55,0x60,0xdd,0xf0, + 0xfa,0xf0,0x03,0xca,0x10,0xf8,0x60,0xa6, + 0x55,0xa4,0x54,0x20,0x2f,0xf9,0x86,0x5e, + 0x85,0x5f,0x60,0xa9,0x00,0x85,0x51,0xa2, + 0x00,0x86,0x76,0xa4,0x51,0x20,0x45,0xf9, + 0xa6,0x51,0x10,0x0c,0x20,0x8c,0xfd,0xa0, + 0x27,0xb1,0x66,0x91,0x68,0x88,0x10,0xf9, + 0xe8,0xec,0xbf,0x02,0xd0,0xee,0xa0,0x27, + 0xa9,0x00,0x91,0x66,0x88,0x10,0xfb,0x20, + 0x24,0xfd,0xa5,0x51,0x20,0x3d,0xfd,0xbe, + 0x21,0xfd,0x38,0xf0,0x09,0x2e,0xb4,0x02, + 0xca,0xf0,0x03,0x2e,0xb3,0x02,0x85,0x64, + 0x49,0xff,0x39,0xb2,0x02,0x85,0x65,0xc6, + 0x64,0x25,0x64,0x65,0x65,0x99,0xb2,0x02, + 0xe6,0x76,0xe6,0x64,0x24,0x64,0xf0,0xab, + 0x60,0x02,0x01,0x00,0xa5,0x52,0xa2,0x6c, + 0x20,0x2d,0xfd,0xa2,0x54,0xb4,0x00,0xc4, + 0x51,0x90,0x07,0xd0,0x03,0x95,0x01,0x60, + 0xd6,0x00,0x60,0xa5,0x54,0x48,0x4a,0x4a, + 0x4a,0xa8,0x68,0x29,0x07,0xaa,0xbd,0xc1, + 0xe4,0x60,0x20,0x3d,0xfd,0x39,0xb2,0x02, + 0x60,0xa5,0x54,0x85,0x64,0xa5,0x64,0x20, + 0x4a,0xfd,0xd0,0x04,0xc6,0x64,0xd0,0xf5, + 0xa5,0x64,0x60,0xa0,0x01,0x84,0x64,0x18, + 0x20,0x12,0xf9,0xa4,0x64,0x60,0xa5,0x54, + 0x20,0x53,0xfd,0x18,0xe5,0x54,0xaa,0xbd, + 0xa2,0xfc,0x65,0x55,0x60,0x98,0x29,0x07, + 0xaa,0xbd,0xc1,0xe4,0x48,0x98,0x4a,0x4a, + 0x4a,0xaa,0x68,0x60,0xa5,0x66,0x85,0x68, + 0x18,0x69,0x28,0x85,0x66,0xa5,0x67,0x85, + 0x69,0x69,0x00,0x85,0x67,0x60,0x78,0x50, + 0x28,0x00,0x00,0x10,0x14,0x00,0x11,0x22, + 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa, + 0xbb,0xcc,0xdd,0xee,0xff,0x00,0x55,0xaa, + 0xff,0x00,0xff,0xa2,0xff,0x8e,0xb2,0x02, + 0x8e,0xb3,0x02,0x8e,0xb4,0x02,0xe8,0x86, + 0x6c,0xa5,0x52,0x85,0x6d,0x60,0xa2,0x02, + 0xb5,0x54,0x95,0x5a,0xca,0x10,0xf9,0x60, + 0xe6,0x55,0xa6,0x53,0xe4,0x55,0xb0,0x06, + 0xa6,0x52,0x86,0x55,0xe6,0x54,0x60,0xa0, + 0x00,0xb1,0x5e,0x85,0x5d,0xae,0xf0,0x02, + 0xd0,0x04,0x49,0x80,0x91,0x5e,0xc8,0x60, + 0x40,0x80,0x70,0x70,0x80,0xa0,0xe0,0x60, + 0x50,0x50,0x50,0x50,0xa0,0x80,0x60,0x50, + 0xfc,0xfd,0xfe,0xfe,0xfd,0xfb,0xf7,0xf0, + 0xe1,0xe1,0xe1,0xe1,0xfb,0xfd,0xf0,0xe1, + 0x02,0x06,0x07,0x08,0x09,0x0a,0x0b,0x1d, + 0x3f,0x7f,0xbf,0xff,0x04,0x05,0x1c,0x3e, + 0x01,0x01,0x00,0x01,0x02,0x02,0x03,0x03, + 0x04,0x04,0x04,0x04,0x01,0x00,0x04,0x04, + 0x0c,0x18,0x30,0x60,0xc0,0x01,0x00,0x00, + 0x01,0x02,0x02,0x03,0x03,0x04,0x02,0x02, + 0x02,0x01,0x01,0x03,0x03,0xa2,0xff,0x8e, + 0xfc,0x02,0x8e,0xf2,0x02,0xe8,0x8e,0xf1, + 0x02,0x8e,0xb6,0x02,0xa9,0x40,0x8d,0xbe, + 0x02,0x60,0x98,0x29,0xc0,0x8d,0xbe,0x02, + 0xa2,0xff,0xa5,0x11,0xf0,0x56,0xad,0xfc, + 0x02,0xc9,0xff,0xf0,0xf5,0x8e,0xfc,0x02, + 0xa0,0x0c,0x20,0xcc,0xe4,0xc9,0xc0,0xb0, + 0xe7,0xa8,0xb9,0x0c,0xff,0x10,0x10,0xc9, + 0x81,0x90,0xdd,0xf0,0x2d,0xc9,0x83,0x90, + 0xd1,0xc9,0x85,0x90,0xcd,0xf0,0x32,0xc9, + 0x61,0x90,0x0f,0xc9,0x7b,0xb0,0x0b,0x2c, + 0xbe,0x02,0x70,0x04,0x10,0x04,0x29,0x1f, + 0x29,0xdf,0xa2,0x0f,0x20,0xae,0xfc,0xf0, + 0x03,0x4d,0xb6,0x02,0x8d,0xfb,0x02,0xa0, + 0x01,0x60,0xad,0xb6,0x02,0x49,0x80,0x8d, + 0xb6,0x02,0xb0,0xa4,0x86,0x11,0xa0,0x80, + 0x60,0xa0,0x88,0x60,0xa9,0x30,0x8d,0x2b, + 0x02,0xad,0x09,0xd2,0xcd,0xf2,0x02,0xd0, + 0x08,0xad,0xf1,0x02,0xd0,0x16,0xad,0xf2, + 0x02,0xc9,0x9f,0xf0,0x11,0x8d,0xfc,0x02, + 0x8d,0xf2,0x02,0xa9,0x00,0x85,0x4d,0xa9, + 0x03,0x8d,0xf1,0x02,0x68,0x40,0xad,0xff, + 0x02,0x49,0xff,0x8d,0xff,0x02,0xb0,0xef, + 0xa9,0x00,0x85,0x11,0x8d,0xff,0x02,0x8d, + 0xf0,0x02,0x68,0x40,0x6c,0x6a,0x3b,0x80, + 0x80,0x6b,0x2b,0x2a,0x6f,0x80,0x70,0x75, + 0x9b,0x69,0x2d,0x3d,0x76,0x80,0x63,0x80, + 0x80,0x62,0x78,0x7a,0x34,0x80,0x33,0x36, + 0x1b,0x35,0x32,0x31,0x2c,0x20,0x2e,0x6e, + 0x80,0x6d,0x2f,0x81,0x72,0x80,0x65,0x79, + 0x7f,0x74,0x77,0x71,0x39,0x80,0x30,0x37, + 0x7e,0x38,0x3c,0x3e,0x66,0x68,0x64,0x80, + 0x82,0x67,0x73,0x61,0x4c,0x4a,0x3a,0x80, + 0x80,0x4b,0x5c,0x5e,0x4f,0x80,0x50,0x55, + 0x9b,0x49,0x5f,0x7c,0x56,0x80,0x43,0x80, + 0x80,0x42,0x58,0x5a,0x24,0x80,0x23,0x26, + 0x1b,0x25,0x22,0x21,0x5b,0x20,0x5d,0x4e, + 0x80,0x4d,0x3f,0x80,0x52,0x80,0x45,0x59, + 0x9f,0x54,0x57,0x51,0x28,0x80,0x29,0x27, + 0x9c,0x40,0x7d,0x9d,0x46,0x48,0x44,0x80, + 0x83,0x47,0x53,0x41,0x0c,0x0a,0x7b,0x80, + 0x80,0x0b,0x1e,0x1f,0x0f,0x80,0x10,0x15, + 0x9b,0x09,0x1c,0x1d,0x16,0x80,0x03,0x80, + 0x80,0x02,0x18,0x1a,0x80,0x80,0x85,0x80, + 0x1b,0x80,0xfd,0x80,0x00,0x20,0x60,0x0e, + 0x80,0x0d,0x80,0x80,0x12,0x80,0x05,0x19, + 0x9e,0x14,0x17,0x11,0x80,0x80,0x80,0x80, + 0xfe,0x80,0x7d,0xff,0x06,0x08,0x04,0x80, + 0x84,0x07,0x13,0x01,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0x91,0xe8,0xf7,0xef,0xae,0xe8 +}; diff --git a/atari800/src/roms/altirraos_800.h b/atari800/src/roms/altirraos_800.h new file mode 100644 index 0000000..01c5889 --- /dev/null +++ b/atari800/src/roms/altirraos_800.h @@ -0,0 +1,8 @@ +#ifndef ROMS_ALTIRRAOS_800_H_ +#define ROMS_ALTIRRAOS_800_H_ + +#include "atari.h" + +extern UBYTE const ROM_altirraos_800[0x2800]; + +#endif /* ROMS_ALTIRRAOS_800_H_ */ diff --git a/atari800/src/roms/altirraos_xl.c b/atari800/src/roms/altirraos_xl.c new file mode 100644 index 0000000..5d5a33a --- /dev/null +++ b/atari800/src/roms/altirraos_xl.c @@ -0,0 +1,2068 @@ +/* + * altirraos_xl.c - XL/XE/XEGS OS ROM replacement + * + * Compiled from the sources in the emuos folder. + * + * Altirra - Atari 800/800XL emulator + * Kernel ROM replacement, version 3.11 + * Copyright (C) 2008-2018 Avery Lee + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include "atari.h" + +UBYTE const ROM_altirraos_xl[0x4000] = +{ + 0x00,0x00,0x01,0x01,0x13,0x02,0x43,0x58, + 0x00,0x00,0x00,0x00,0xe6,0x14,0xd0,0x08, + 0xe6,0x4d,0xe6,0x13,0xd0,0x02,0xe6,0x12, + 0xa2,0xfe,0xa9,0x00,0xa4,0x4d,0x10,0x06, + 0x86,0x4d,0xa2,0xf6,0xa5,0x13,0x86,0x4e, + 0x85,0x4f,0x4d,0xc5,0x02,0x25,0x4e,0x8d, + 0x17,0xd0,0xad,0x18,0x02,0xd0,0x08,0xad, + 0x19,0x02,0xf0,0x10,0xce,0x19,0x02,0xce, + 0x18,0x02,0xd0,0x08,0xad,0x19,0x02,0xd0, + 0x03,0x20,0x56,0xc0,0xa5,0x42,0xf0,0x09, + 0x68,0xa8,0x68,0xaa,0x68,0x40,0x6c,0x26, + 0x02,0xa9,0x04,0xba,0x3d,0x04,0x01,0xd0, + 0xef,0x58,0xad,0x31,0x02,0x8d,0x03,0xd4, + 0xad,0x30,0x02,0x8d,0x02,0xd4,0xad,0x2f, + 0x02,0x8d,0x00,0xd4,0xad,0xf4,0x02,0x8d, + 0x09,0xd4,0xad,0xf3,0x02,0x8d,0x01,0xd4, + 0xad,0x6f,0x02,0x8d,0x1b,0xd0,0xa2,0x08, + 0x8e,0x1f,0xd0,0xbd,0xc0,0x02,0x45,0x4f, + 0x25,0x4e,0x9d,0x12,0xd0,0xca,0x10,0xf3, + 0xa2,0x03,0x20,0x45,0xc1,0xd0,0x03,0x20, + 0x42,0xc1,0xa2,0x09,0x18,0x20,0x45,0xc1, + 0xb0,0x07,0xf0,0x02,0xa9,0xff,0x9d,0x25, + 0x02,0xca,0xca,0xe0,0x05,0xb0,0xed,0xad, + 0x0f,0xd2,0x29,0x04,0xd0,0x11,0xce,0x2b, + 0x02,0xd0,0x19,0xad,0x09,0xd2,0x8d,0xfc, + 0x02,0xad,0xda,0x02,0x4c,0xd9,0xc0,0xad, + 0xf1,0x02,0xf0,0x03,0xce,0xf1,0x02,0xa9, + 0x00,0x8d,0x2b,0x02,0xad,0x00,0xd3,0xaa, + 0x29,0x0f,0x8d,0x78,0x02,0x8d,0x7a,0x02, + 0x8a,0x4a,0x4a,0xaa,0x4a,0x4a,0x8d,0x79, + 0x02,0x8d,0x7b,0x02,0x4a,0x4a,0xa8,0x29, + 0x01,0x8d,0x7e,0x02,0x98,0x4a,0x8d,0x7f, + 0x02,0x8a,0x29,0x01,0x8d,0x7c,0x02,0x8a, + 0x4a,0x29,0x01,0x8d,0x7d,0x02,0xa2,0x03, + 0xbd,0x00,0xd2,0x9d,0x70,0x02,0x9d,0x74, + 0x02,0xbd,0x7c,0x02,0x9d,0x80,0x02,0xca, + 0x10,0xee,0xa2,0x01,0xbd,0x10,0xd0,0x9d, + 0x84,0x02,0x9d,0x86,0x02,0xca,0x10,0xf4, + 0x8d,0x0b,0xd2,0xad,0x0c,0xd4,0x8d,0x34, + 0x02,0xad,0x0d,0xd4,0x8d,0x35,0x02,0x6c, + 0x24,0x02,0x6c,0x28,0x02,0xbd,0x17,0x02, + 0xd0,0x0a,0xdd,0x18,0x02,0xd0,0x02,0x8a, + 0x60,0xde,0x18,0x02,0xde,0x17,0x02,0xd0, + 0x03,0xbd,0x18,0x02,0x60,0x0a,0x8c,0x2d, + 0x02,0xa8,0x8a,0x08,0x78,0xee,0x0a,0xd4, + 0xa2,0x7c,0x08,0x28,0x08,0x28,0xec,0x0b, + 0xd4,0xf0,0x0b,0x99,0x17,0x02,0xad,0x2d, + 0x02,0x99,0x16,0x02,0x28,0x60,0x08,0x28, + 0xf0,0xf1,0xa9,0x40,0x8d,0x0e,0xd4,0xad, + 0x13,0xd0,0x8d,0xfa,0x03,0x60,0x2c,0x0f, + 0xd4,0x10,0x03,0x6c,0x00,0x02,0x48,0xd8, + 0x8a,0x48,0x98,0x48,0x8d,0x0f,0xd4,0x6c, + 0x22,0x02,0xd8,0x6c,0x16,0x02,0x2d,0xff, + 0xd1,0xf0,0x4d,0x8d,0x8c,0x02,0x8a,0x48, + 0xad,0x8c,0x02,0x6c,0x38,0x02,0xa9,0xef, + 0x20,0x52,0xc2,0x6c,0x0c,0x02,0x2c,0x0e, + 0xd2,0xd0,0x41,0x6c,0x0e,0x02,0xa9,0xfe, + 0x20,0x52,0xc2,0x6c,0x10,0x02,0xa9,0xfd, + 0x20,0x52,0xc2,0x6c,0x12,0x02,0xa9,0xfb, + 0x20,0x52,0xc2,0x6c,0x14,0x02,0x48,0xa9, + 0x20,0x2c,0x0e,0xd2,0xd0,0x0d,0xa9,0xdf, + 0x8d,0x0e,0xd2,0xa5,0x10,0x8d,0x0e,0xd2, + 0x6c,0x0a,0x02,0xad,0x49,0x02,0xd0,0xae, + 0xa9,0x10,0x2c,0x0e,0xd2,0xf0,0xb7,0x4a, + 0x24,0x10,0xd0,0xba,0xad,0x0e,0xd2,0x4a, + 0x90,0xbc,0x4a,0x90,0xc1,0x4a,0x90,0xc6, + 0x2c,0x0e,0xd2,0x50,0x21,0x10,0x27,0x2c, + 0x02,0xd3,0x30,0x2a,0x2c,0x03,0xd3,0x30, + 0x2b,0x68,0x8d,0x8c,0x02,0x68,0x48,0x29, + 0x10,0xf0,0x07,0xad,0x8c,0x02,0x48,0x6c, + 0x06,0x02,0xad,0x8c,0x02,0x40,0xa9,0xbf, + 0x20,0x52,0xc2,0x6c,0x08,0x02,0xa9,0x7f, + 0x20,0x52,0xc2,0x6c,0x36,0x02,0xad,0x00, + 0xd3,0x6c,0x02,0x02,0xad,0x01,0xd3,0x6c, + 0x04,0x02,0x8d,0x0e,0xd2,0xa5,0x10,0x8d, + 0x0e,0xd2,0x60,0xa9,0x8b,0x8d,0x38,0x02, + 0xa9,0xc2,0x8d,0x39,0x02,0xa9,0x01,0x8d, + 0x48,0x02,0x8d,0xff,0xd1,0xac,0x03,0xd8, + 0xc0,0x80,0xd0,0x0a,0xac,0x0b,0xd8,0xc0, + 0x91,0xd0,0x03,0x20,0x19,0xd8,0xad,0x48, + 0x02,0x0a,0xd0,0xe3,0x8d,0x48,0x02,0x8d, + 0xff,0xd1,0x60,0x8d,0x8c,0x02,0x49,0xff, + 0x18,0x69,0x01,0x2d,0x8c,0x02,0xae,0x48, + 0x02,0x8d,0x48,0x02,0x8d,0xff,0xd1,0x8a, + 0x48,0x20,0x08,0xd8,0x68,0x8d,0x48,0x02, + 0x8d,0xff,0xd1,0x68,0xaa,0x68,0x40,0xad, + 0x47,0x02,0xd0,0x08,0x8d,0x48,0x02,0x8d, + 0xff,0xd1,0x18,0x60,0xa9,0x00,0x38,0x2a, + 0xb0,0xf2,0x2c,0x47,0x02,0xf0,0xf8,0x8d, + 0x48,0x02,0x8d,0xff,0xd1,0x48,0x20,0x05, + 0xd8,0x68,0x90,0xeb,0xa9,0x00,0x8d,0x48, + 0x02,0x8d,0xff,0xd1,0x60,0xa0,0x00,0x10, + 0x0a,0xa0,0x02,0x10,0x06,0xa0,0x04,0x10, + 0x02,0xa0,0x06,0x8c,0x4a,0x02,0x8d,0x4b, + 0x02,0xa9,0x00,0x38,0x2a,0xb0,0x1b,0x2c, + 0x47,0x02,0xf0,0xf8,0x8d,0x48,0x02,0x8d, + 0xff,0xd1,0xa5,0x2f,0x20,0x16,0xc3,0x90, + 0xeb,0xa2,0x00,0x8e,0x48,0x02,0x8e,0xff, + 0xd1,0x60,0xa0,0x82,0xd0,0xf3,0xac,0x4a, + 0x02,0xb9,0x0e,0xd8,0x48,0xb9,0x0d,0xd8, + 0x48,0xad,0x4b,0x02,0xa0,0x92,0x60,0xa0, + 0x08,0x10,0xc0,0xa0,0x0a,0x10,0xbc,0x48, + 0x98,0x48,0x8a,0xa2,0x21,0xdd,0x1a,0x03, + 0xf0,0x17,0xca,0xca,0xca,0x10,0xf6,0xe8, + 0xe8,0xe8,0xbc,0x1a,0x03,0xf0,0x10,0xe0, + 0x24,0xd0,0xf4,0x68,0x68,0xa9,0xff,0x38, + 0x60,0x68,0xa8,0x68,0xe8,0x38,0x60,0x9d, + 0x1a,0x03,0x68,0x9d,0x1b,0x03,0x68,0x9d, + 0x1c,0x03,0x0a,0x18,0x60,0x8c,0x4a,0x02, + 0x8d,0x4b,0x02,0xa2,0xe9,0xa9,0x03,0xa8, + 0xd0,0x04,0xe0,0x00,0xf0,0x23,0x86,0x36, + 0x85,0x37,0xa0,0x12,0xb1,0x36,0xaa,0xc8, + 0xb1,0x36,0xcd,0x4b,0x02,0xd0,0xe8,0xec, + 0x4a,0x02,0xd0,0xe3,0x86,0x4a,0x85,0x4b, + 0xa0,0x10,0xb1,0x4a,0xc8,0x11,0x4a,0xf0, + 0x02,0x38,0x60,0xa0,0x12,0xb1,0x4a,0xaa, + 0xc8,0xb1,0x4a,0x91,0x36,0x88,0x8a,0x91, + 0x36,0x18,0x60,0x8c,0xec,0x02,0x8d,0xed, + 0x02,0x08,0xa2,0xe9,0xa9,0x03,0x86,0x4a, + 0x85,0x4b,0xa0,0x12,0xb1,0x4a,0xaa,0xc8, + 0xb1,0x4a,0xd0,0xf2,0xe0,0x00,0xd0,0xee, + 0xad,0xed,0x02,0x91,0x4a,0xaa,0x88,0xad, + 0xec,0x02,0x91,0x4a,0x86,0x4b,0x85,0x4a, + 0xa0,0x13,0xa9,0x00,0x91,0x4a,0x88,0x91, + 0x4a,0x20,0x2d,0xc4,0x90,0x0a,0xa5,0x4a, + 0xa4,0x4b,0x20,0x65,0xc3,0x28,0x38,0x60, + 0x28,0xb0,0x0a,0xa0,0x10,0xa9,0x00,0xaa, + 0x91,0x4a,0xc8,0x91,0x4a,0x20,0x16,0xc4, + 0xa0,0x0f,0xa9,0x00,0x91,0x4a,0xa0,0x11, + 0x18,0x71,0x4a,0x88,0x10,0xfb,0x69,0x00, + 0xa0,0x0f,0x91,0x4a,0x18,0x60,0xa0,0x11, + 0xb1,0x4a,0xaa,0x88,0xb1,0x4a,0x18,0x6d, + 0xe7,0x02,0x8d,0xe7,0x02,0x8a,0x6d,0xe8, + 0x02,0x8d,0xe8,0x02,0x60,0xa5,0x4a,0x18, + 0x69,0x0b,0xaa,0xa5,0x4b,0x69,0x00,0x48, + 0x8a,0x48,0x60,0xae,0xfb,0x03,0xad,0xfc, + 0x03,0x86,0x4a,0x85,0x4b,0x05,0x4a,0xf0, + 0x2d,0xa0,0x11,0x18,0xb1,0x4a,0x88,0x71, + 0x4a,0x88,0x88,0x71,0x4a,0x88,0x10,0xfb, + 0x69,0x00,0xa0,0x0f,0xd1,0x4a,0xd0,0x16, + 0x20,0x2d,0xc4,0xb0,0x11,0x20,0x16,0xc4, + 0xa0,0x13,0xb1,0x4a,0xaa,0xc8,0xb1,0x4a, + 0xd0,0xcf,0xe0,0x00,0xd0,0xcb,0x60,0xa2, + 0x4f,0x20,0xf1,0xc4,0xa9,0x00,0x8d,0x0a, + 0x03,0x8d,0x0b,0x03,0x8d,0x09,0x03,0xa9, + 0xea,0x8d,0x04,0x03,0xa9,0x02,0x8d,0x05, + 0x03,0xa9,0x04,0x8d,0x08,0x03,0xa9,0x40, + 0x8d,0x03,0x03,0x20,0x59,0xe4,0x10,0x11, + 0xc0,0x8a,0xd0,0x01,0x60,0xc0,0x80,0xf0, + 0xfb,0xa2,0x4e,0x20,0xf1,0xc4,0x4c,0x7c, + 0xc4,0xad,0xe7,0x02,0xaa,0x6a,0x8a,0x6d, + 0xea,0x02,0xaa,0xad,0xe8,0x02,0x6d,0xeb, + 0x02,0xcd,0xe6,0x02,0x90,0x09,0xd0,0xdd, + 0xec,0xe5,0x02,0xb0,0x02,0xd0,0xd6,0xad, + 0xe7,0x02,0xaa,0x6a,0x8a,0x69,0x00,0x8d, + 0xd1,0x02,0xad,0xe8,0x02,0x69,0x00,0x8d, + 0xd2,0x02,0xad,0xec,0x02,0x8d,0x00,0x03, + 0x38,0x20,0x0e,0xc5,0xb0,0xb7,0x4c,0x7c, + 0xc4,0xa9,0x4f,0x8d,0x00,0x03,0x8e,0x0a, + 0x03,0x8e,0x0b,0x03,0xa9,0x40,0x8d,0x02, + 0x03,0xa9,0x01,0x8d,0x01,0x03,0xa9,0x00, + 0x8d,0x03,0x03,0x4c,0x59,0xe4,0x08,0xa9, + 0x80,0x8d,0xd3,0x02,0xa9,0x4d,0x8d,0xcf, + 0x02,0xa9,0xc5,0x8d,0xd0,0x02,0xa9,0x26, + 0x8d,0x02,0x03,0xa2,0x00,0x8e,0x0a,0x03, + 0x8e,0x09,0x03,0x8e,0x04,0x03,0xca,0x86, + 0x3d,0xa9,0x04,0x8d,0x05,0x03,0xa9,0x80, + 0x8d,0x08,0x03,0x20,0x67,0xc5,0xb0,0x0b, + 0xac,0xd1,0x02,0xad,0xd2,0x02,0x28,0x20, + 0xab,0xc3,0x60,0x68,0x60,0xa6,0x3d,0x10, + 0x0c,0xa9,0x40,0x8d,0x03,0x03,0x20,0x59, + 0xe4,0x30,0x0a,0xa2,0x00,0xbd,0x00,0x04, + 0xe8,0x86,0x3d,0x18,0x60,0x38,0x60,0xa9, + 0x00,0x8d,0xd4,0x02,0x20,0x65,0xc6,0x8d, + 0x33,0x02,0x20,0x65,0xc6,0x8d,0x45,0x02, + 0x20,0x7e,0xc5,0x4c,0x6c,0xc5,0xae,0x33, + 0x02,0xbc,0x8d,0xc5,0xb9,0x9d,0xc5,0x48, + 0xb9,0x99,0xc5,0x48,0x60,0x00,0x00,0x01, + 0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x00, + 0x03,0xa0,0xdd,0x0e,0x2c,0xc5,0xc5,0xc6, + 0xc6,0x20,0x65,0xc6,0x85,0x36,0x20,0x65, + 0xc6,0x85,0x37,0xad,0x33,0x02,0xc9,0x0a, + 0xf0,0x11,0x0a,0xaa,0x18,0xbd,0xd1,0x02, + 0x65,0x36,0x85,0x36,0xbd,0xd2,0x02,0x65, + 0x37,0x85,0x37,0xa9,0x00,0x8d,0x33,0x02, + 0xce,0x45,0x02,0xd0,0x0b,0x20,0x65,0xc6, + 0xac,0x33,0x02,0xee,0x33,0x02,0x91,0x36, + 0xce,0x45,0x02,0xd0,0xf0,0x60,0xad,0x33, + 0x02,0x4a,0xae,0xd1,0x02,0xc9,0x02,0xd0, + 0x03,0xae,0xd3,0x02,0x86,0x4a,0xc9,0x03, + 0x66,0x4b,0x20,0x65,0xc6,0xa8,0xb1,0x36, + 0x18,0x65,0x4a,0x91,0x36,0x24,0x4b,0x10, + 0x08,0xc8,0xb1,0x36,0x6d,0xd2,0x02,0x91, + 0x36,0xce,0x45,0x02,0xd0,0xe4,0x60,0x20, + 0x65,0xc6,0x85,0x4a,0x20,0x65,0xc6,0x18, + 0x6d,0xd1,0x02,0xa4,0x4a,0xad,0xd2,0x02, + 0x71,0x36,0x91,0x36,0xce,0x45,0x02,0xce, + 0x45,0x02,0xd0,0xe3,0x60,0x20,0x65,0xc6, + 0x8d,0xc9,0x02,0x20,0x65,0xc6,0x8d,0xca, + 0x02,0xae,0x33,0x02,0xd0,0x0e,0xa9,0x00, + 0x8d,0xc9,0x02,0x8d,0xca,0x02,0x18,0x68, + 0x68,0xa0,0x01,0x60,0xca,0xf0,0xf7,0x18, + 0xad,0xc9,0x02,0x6d,0xd1,0x02,0x8d,0xc9, + 0x02,0xad,0xca,0x02,0x6d,0xd2,0x02,0x8d, + 0xca,0x02,0x4c,0x46,0xc6,0x20,0x6d,0xc6, + 0x90,0x02,0x68,0x68,0x60,0x6c,0xcf,0x02, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, + 0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + 0x00,0x66,0xff,0x66,0x66,0xff,0x66,0x00, + 0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00, + 0x00,0x66,0x6c,0x18,0x30,0x66,0x46,0x00, + 0x1c,0x36,0x1c,0x38,0x6f,0x66,0x3b,0x00, + 0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + 0x00,0x0e,0x1c,0x18,0x18,0x1c,0x0e,0x00, + 0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, + 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00, + 0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, + 0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, + 0x00,0x06,0x0c,0x18,0x30,0x60,0x40,0x00, + 0x00,0x3c,0x66,0x6e,0x76,0x66,0x3c,0x00, + 0x00,0x18,0x38,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x7e,0x0c,0x18,0x0c,0x66,0x3c,0x00, + 0x00,0x0c,0x1c,0x3c,0x6c,0x7e,0x0c,0x00, + 0x00,0x7e,0x60,0x7c,0x06,0x66,0x3c,0x00, + 0x00,0x3c,0x60,0x7c,0x66,0x66,0x3c,0x00, + 0x00,0x7e,0x06,0x0c,0x18,0x30,0x30,0x00, + 0x00,0x3c,0x66,0x3c,0x66,0x66,0x3c,0x00, + 0x00,0x3c,0x66,0x3e,0x06,0x0c,0x38,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, + 0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00, + 0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x00,0x18,0x00, + 0x00,0x3c,0x66,0x6e,0x6e,0x60,0x3e,0x00, + 0x00,0x18,0x3c,0x66,0x66,0x7e,0x66,0x00, + 0x00,0x7c,0x66,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x00, + 0x00,0x78,0x6c,0x66,0x66,0x6c,0x78,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x7e,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x60,0x00, + 0x00,0x3e,0x60,0x60,0x6e,0x66,0x3e,0x00, + 0x00,0x66,0x66,0x7e,0x66,0x66,0x66,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x06,0x06,0x06,0x06,0x66,0x3c,0x00, + 0x00,0x66,0x6c,0x78,0x78,0x6c,0x66,0x00, + 0x00,0x60,0x60,0x60,0x60,0x60,0x7e,0x00, + 0x00,0x63,0x77,0x7f,0x6b,0x63,0x63,0x00, + 0x00,0x66,0x76,0x7e,0x7e,0x6e,0x66,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x60,0x60,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x6c,0x36,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x6c,0x66,0x00, + 0x00,0x3c,0x60,0x3c,0x06,0x06,0x3c,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x00, + 0x00,0x66,0x66,0x66,0x66,0x66,0x7e,0x00, + 0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00, + 0x00,0x66,0x66,0x3c,0x3c,0x66,0x66,0x00, + 0x00,0x66,0x66,0x3c,0x18,0x18,0x18,0x00, + 0x00,0x7e,0x0c,0x18,0x30,0x60,0x7e,0x00, + 0x00,0x1e,0x18,0x18,0x18,0x18,0x1e,0x00, + 0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, + 0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x0c,0x18,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x30,0x18,0x00,0x66,0x66,0x66,0x3e,0x00, + 0x36,0x6c,0x00,0x76,0x76,0x7e,0x6e,0x00, + 0x0c,0x18,0x7e,0x60,0x7c,0x60,0x7e,0x00, + 0x00,0x00,0x3c,0x60,0x60,0x3c,0x18,0x30, + 0x3c,0x66,0x00,0x3c,0x66,0x66,0x3c,0x00, + 0x30,0x18,0x00,0x3c,0x66,0x66,0x3c,0x00, + 0x30,0x18,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x1c,0x30,0x30,0x78,0x30,0x30,0x7e,0x00, + 0x00,0x66,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x00,0x66,0x00,0x66,0x66,0x66,0x3e,0x00, + 0x36,0x00,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x66,0x00,0x3c,0x66,0x66,0x66,0x3c,0x00, + 0x0c,0x18,0x00,0x66,0x66,0x66,0x3e,0x00, + 0x0c,0x18,0x00,0x3c,0x66,0x66,0x3c,0x00, + 0x00,0x66,0x00,0x3c,0x66,0x66,0x3c,0x00, + 0x66,0x00,0x66,0x66,0x66,0x66,0x7e,0x00, + 0x3c,0x66,0x1c,0x06,0x3e,0x66,0x3e,0x00, + 0x3c,0x66,0x00,0x66,0x66,0x66,0x3e,0x00, + 0x3c,0x66,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x0c,0x18,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x30,0x18,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x36,0x6c,0x00,0x7c,0x66,0x66,0x66,0x00, + 0x3c,0xc3,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x18,0x00,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x30,0x18,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x18,0x00,0x18,0x3c,0x66,0x7e,0x66,0x00, + 0x78,0x60,0x78,0x60,0x7e,0x18,0x1e,0x00, + 0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x00, + 0x00,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00, + 0x00,0x18,0x30,0x7e,0x30,0x18,0x00,0x00, + 0x00,0x18,0x0c,0x7e,0x0c,0x18,0x00,0x00, + 0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00, + 0x00,0x00,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x00,0x3c,0x60,0x60,0x60,0x3c,0x00, + 0x00,0x06,0x06,0x3e,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x00,0x0e,0x18,0x3e,0x18,0x18,0x18,0x00, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x7c, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x66,0x00, + 0x00,0x18,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3c, + 0x00,0x60,0x60,0x6c,0x78,0x6c,0x66,0x00, + 0x00,0x38,0x18,0x18,0x18,0x18,0x3c,0x00, + 0x00,0x00,0x66,0x7f,0x7f,0x6b,0x63,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x66,0x66,0x00, + 0x00,0x00,0x3c,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x7c,0x60,0x60, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x06, + 0x00,0x00,0x7c,0x66,0x60,0x60,0x60,0x00, + 0x00,0x00,0x3e,0x60,0x3c,0x06,0x7c,0x00, + 0x00,0x18,0x7e,0x18,0x18,0x18,0x0e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x00,0x63,0x6b,0x7f,0x3e,0x36,0x00, + 0x00,0x00,0x66,0x3c,0x18,0x3c,0x66,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3e,0x0c,0x78, + 0x00,0x00,0x7e,0x0c,0x18,0x30,0x7e,0x00, + 0x66,0x66,0x18,0x3c,0x66,0x7e,0x66,0x00, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x00,0x7e,0x78,0x7c,0x6e,0x66,0x06,0x00, + 0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00, + 0x10,0x18,0x1c,0x1e,0x1c,0x18,0x10,0x00, + 0x18,0x24,0x38,0x08,0x20,0x6c,0x52,0x28, + 0x66,0x80,0xa9,0xd0,0x85,0x8a,0xa9,0x56, + 0x85,0x8b,0xa9,0x00,0x85,0x8c,0xa9,0x30, + 0x85,0x8d,0xb1,0x8a,0x91,0x8c,0xc8,0xc0, + 0x7a,0xd0,0xf7,0xa9,0x13,0x85,0x8c,0xa9, + 0x32,0x85,0x8d,0xa9,0xc8,0x85,0x8a,0xa9, + 0x54,0x85,0x8b,0xa2,0x28,0xa0,0x0c,0xb1, + 0x8a,0x91,0x8c,0x88,0x10,0xf9,0x18,0xa5, + 0x8c,0x69,0x20,0x85,0x8c,0x90,0x02,0xe6, + 0x8d,0xa5,0x8a,0x18,0x69,0x0d,0x85,0x8a, + 0x90,0x02,0xe6,0x8b,0xca,0xd0,0xde,0x78, + 0x20,0x9d,0x54,0xa9,0x00,0x8d,0x0e,0xd4, + 0xa9,0xc0,0x8d,0x0e,0xd4,0xa9,0x2c,0x8d, + 0x07,0xd4,0xa2,0x0c,0xbd,0x16,0x52,0x9d, + 0x00,0xd0,0xca,0x10,0xf7,0xa9,0x03,0x8d, + 0x1d,0xd0,0x58,0xa2,0x00,0xa0,0x20,0xbd, + 0x3f,0x54,0x99,0x00,0x2c,0xbd,0x47,0x54, + 0x99,0x00,0x2d,0xc8,0x98,0x29,0x0f,0xd0, + 0xee,0xe8,0xe0,0x08,0xd0,0xe9,0xa9,0x00, + 0x85,0x88,0x85,0x89,0x85,0x8e,0xa4,0x8e, + 0xe6,0x8e,0xb9,0xd6,0x52,0xc9,0xff,0xf0, + 0x06,0x20,0xa9,0x53,0x4c,0x9e,0x50,0xa9, + 0x00,0x85,0x9a,0xa2,0x00,0x8a,0x9d,0x00, + 0x2e,0x9d,0x00,0x2f,0xca,0xd0,0xf7,0xad, + 0x0b,0xd4,0xd0,0xfb,0xa2,0x02,0xb5,0x12, + 0x95,0x94,0xca,0x10,0xf9,0x86,0x11,0xa9, + 0x01,0x8d,0x01,0x03,0xa9,0x53,0x8d,0x02, + 0x03,0x20,0x53,0xe4,0x30,0x21,0xa9,0x52, + 0x8d,0x02,0x03,0xa9,0x00,0x8d,0x04,0x03, + 0xa9,0x04,0x8d,0x05,0x03,0xa9,0x01,0x8d, + 0x0a,0x03,0xa9,0x00,0x8d,0x0b,0x03,0x20, + 0x53,0xe4,0x30,0x03,0x4c,0x23,0x52,0xa5, + 0x14,0xc5,0x14,0xf0,0xfc,0xa5,0x14,0xc5, + 0x14,0xf0,0xfc,0xa6,0x9a,0xbd,0x87,0x51, + 0x85,0x92,0xbd,0x88,0x51,0x85,0x93,0xbc, + 0x86,0x51,0xa9,0x00,0x85,0x90,0x85,0x91, + 0x99,0x00,0x2b,0x99,0x00,0x2e,0x99,0x00, + 0x2f,0x88,0x30,0xf4,0xbc,0x86,0x51,0xa9, + 0xff,0xa6,0x91,0xbd,0x4f,0x54,0x99,0x00, + 0x2e,0xbd,0x6f,0x54,0x99,0x00,0x2f,0xc8, + 0x18,0xa5,0x90,0x65,0x92,0x85,0x90,0xa5, + 0x91,0x65,0x93,0x85,0x91,0xa5,0x91,0xc9, + 0x20,0x90,0xde,0xa9,0x00,0x99,0x00,0x2b, + 0x99,0x00,0x2e,0x99,0x00,0x2f,0xc8,0xc0, + 0x40,0xd0,0xf2,0xa5,0x9a,0xd0,0x0c,0xa2, + 0x19,0xa5,0x14,0xc5,0x14,0xf0,0xfc,0xca, + 0xd0,0xf7,0x8a,0x18,0x69,0x03,0x85,0x9a, + 0xc9,0x90,0xb0,0x03,0x4c,0xff,0x50,0xa9, + 0x00,0x85,0x9a,0x4c,0xb3,0x50,0x8a,0xaa, + 0x00,0x89,0xab,0x00,0x89,0xae,0x00,0x89, + 0xb3,0x00,0x88,0xba,0x00,0x88,0xc3,0x00, + 0x88,0xce,0x00,0x87,0xdb,0x00,0x87,0xea, + 0x00,0x87,0xfb,0x00,0x86,0x0e,0x01,0x86, + 0x23,0x01,0x86,0x3a,0x01,0x85,0x53,0x01, + 0x85,0x6e,0x01,0x85,0x8b,0x01,0x84,0xaa, + 0x01,0x84,0xcb,0x01,0x84,0xee,0x01,0x83, + 0x13,0x02,0x83,0x3a,0x02,0x83,0x63,0x02, + 0x82,0x8e,0x02,0x82,0xbb,0x02,0x82,0xea, + 0x02,0x81,0x1b,0x03,0x81,0x4e,0x03,0x81, + 0x83,0x03,0x80,0xba,0x03,0x80,0xf3,0x03, + 0x80,0x2e,0x04,0x7f,0x6b,0x04,0x7f,0xaa, + 0x04,0x7f,0xeb,0x04,0x7e,0x2e,0x05,0x7e, + 0x73,0x05,0x7e,0xba,0x05,0x7d,0x03,0x06, + 0x7d,0x4e,0x06,0x7d,0x9b,0x06,0x7c,0xea, + 0x06,0x7c,0x3b,0x07,0x7c,0x8e,0x07,0x7b, + 0xe3,0x07,0x7b,0x3a,0x08,0x7b,0x93,0x08, + 0x7a,0xee,0x08,0x7a,0x4b,0x09,0x40,0x60, + 0xa4,0x98,0x68,0x60,0x00,0x00,0x03,0x03, + 0x00,0x03,0x0f,0x78,0xa9,0x00,0x8d,0x0e, + 0xd4,0xa2,0x7c,0xec,0x0b,0xd4,0xd0,0xfb, + 0x8d,0x00,0xd4,0x8d,0x2f,0x02,0x9d,0x00, + 0xd0,0xe8,0x10,0xfa,0x24,0x80,0x30,0x03, + 0x4c,0x77,0xe4,0x20,0x9d,0x54,0x20,0x6c, + 0x52,0x58,0xa9,0x7d,0xa2,0x00,0x8e,0x48, + 0x03,0x8e,0x49,0x03,0xa0,0x0b,0x8c,0x42, + 0x03,0x20,0x56,0xe4,0xa9,0x40,0x8d,0x0e, + 0xd4,0xa9,0xff,0x8d,0x83,0x02,0x2c,0x83, + 0x02,0x30,0xfb,0x60,0xa9,0x00,0xa8,0x85, + 0x84,0xa2,0x20,0x86,0x85,0xa2,0x18,0x91, + 0x84,0xc8,0xd0,0xfb,0xe6,0x85,0xca,0xd0, + 0xf6,0x95,0x80,0xe8,0x10,0xfb,0x60,0xad, + 0x4e,0x30,0x49,0x05,0x8d,0x4e,0x30,0xad, + 0xc5,0x02,0x8d,0x17,0xd0,0xad,0xc6,0x02, + 0x8d,0x18,0xd0,0x6c,0x00,0x30,0x2c,0x0f, + 0xd4,0x10,0x20,0x48,0x8a,0x48,0xad,0x0b, + 0xd4,0xc9,0x48,0xb0,0x19,0x4a,0x4a,0xaa, + 0xbd,0x8a,0x54,0x8d,0x0a,0xd4,0x8d,0x12, + 0xd0,0x8d,0x13,0xd0,0x8d,0x0f,0xd4,0x68, + 0xaa,0x68,0x40,0x6c,0x02,0x30,0xa9,0x50, + 0xa2,0x5c,0x8d,0x0a,0xd4,0x8d,0x18,0xd0, + 0x8e,0x17,0xd0,0x4c,0xbc,0x52,0x21,0x6c, + 0x74,0x69,0x72,0x72,0x61,0x2f,0x33,0x00, + 0x66,0x6f,0x72,0x00,0x38,0x2c,0x0f,0x38, + 0x25,0x0f,0x38,0x25,0x27,0x33,0x00,0x13, + 0x0e,0x14,0x11,0x9b,0x23,0x6f,0x70,0x79, + 0x72,0x69,0x67,0x68,0x74,0x00,0x08,0x23, + 0x09,0x00,0x12,0x10,0x11,0x12,0x0d,0x12, + 0x10,0x12,0x13,0x00,0x21,0x76,0x65,0x72, + 0x79,0x00,0x2c,0x65,0x65,0x9b,0x21,0x6c, + 0x6c,0x00,0x32,0x69,0x67,0x68,0x74,0x73, + 0x00,0x32,0x65,0x73,0x65,0x72,0x76,0x65, + 0x64,0x9b,0x34,0x68,0x69,0x73,0x00,0x69, + 0x73,0x00,0x61,0x00,0x73,0x75,0x62,0x73, + 0x74,0x69,0x74,0x75,0x74,0x65,0x00,0x66, + 0x6f,0x72,0x00,0x74,0x68,0x65,0x00,0x73, + 0x74,0x61,0x6e,0x64,0x61,0x72,0x64,0x00, + 0x2f,0x33,0x00,0x32,0x2f,0x2d,0x0e,0x00, + 0x33,0x65,0x65,0x00,0x74,0x68,0x65,0x00, + 0x68,0x65,0x6c,0x70,0x00,0x66,0x69,0x6c, + 0x65,0x9b,0x66,0x6f,0x72,0x00,0x68,0x6f, + 0x77,0x00,0x74,0x6f,0x00,0x75,0x73,0x65, + 0x00,0x72,0x65,0x61,0x6c,0x00,0x21,0x74, + 0x61,0x72,0x69,0x00,0x32,0x2f,0x2d,0x00, + 0x69,0x6d,0x61,0x67,0x65,0x73,0x00,0x66, + 0x6f,0x72,0x00,0x68,0x69,0x67,0x68,0x65, + 0x72,0x00,0x63,0x6f,0x6d,0x70,0x61,0x74, + 0x69,0x62,0x69,0x6c,0x69,0x74,0x79,0x0e, + 0xff,0xc9,0x9b,0xd0,0x07,0xa9,0x00,0x85, + 0x88,0xe6,0x89,0x60,0x85,0x84,0xa9,0x00, + 0x85,0x8a,0x85,0x8c,0xa5,0x89,0x09,0x20, + 0x85,0x8b,0x18,0x69,0x05,0x85,0x8d,0xa5, + 0x88,0x4a,0x85,0x83,0x6a,0x85,0x87,0xa9, + 0x1c,0xa2,0x03,0x06,0x84,0x2a,0xca,0xd0, + 0xfa,0x85,0x85,0x18,0xa2,0x04,0xa0,0x00, + 0xb1,0x84,0x4a,0x4a,0x66,0x81,0x4a,0x66, + 0x82,0xca,0xd0,0xf7,0xa4,0x83,0x24,0x87, + 0x30,0x12,0xa5,0x82,0x51,0x8c,0x29,0x0f, + 0x45,0x82,0x91,0x8c,0xa5,0x81,0x51,0x8a, + 0x29,0x0f,0x10,0x1e,0xa5,0x81,0x4a,0x4a, + 0x4a,0x4a,0x85,0x81,0xa5,0x82,0x4a,0x4a, + 0x4a,0x4a,0x85,0x82,0x51,0x8c,0x29,0xf0, + 0x45,0x82,0x91,0x8c,0xa5,0x81,0x51,0x8a, + 0x29,0xf0,0x45,0x81,0x91,0x8a,0xe6,0x84, + 0x98,0x18,0x69,0x20,0x85,0x83,0x90,0xac, + 0xe6,0x88,0xa6,0x88,0xe0,0x40,0x90,0x06, + 0xa9,0x00,0x85,0x88,0xe6,0x89,0x60,0x00, + 0x03,0x0f,0x3c,0x3c,0x3f,0x3c,0x00,0x00, + 0xc0,0xf0,0x3c,0x3c,0xfc,0x3c,0x00,0x00, + 0x00,0x18,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c, + 0x18,0x00,0x00,0xe7,0x81,0x81,0x00,0x00, + 0x81,0x81,0xe7,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xe7,0xe7,0xe7,0xe7,0xe7, + 0xe7,0xe7,0xe7,0xff,0xff,0xff,0xff,0xff, + 0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0x1a, + 0xfa,0xea,0xda,0xca,0xba,0xaa,0x9a,0x8a, + 0x7a,0x6a,0x5a,0x0e,0x50,0xa2,0x13,0xbc, + 0xb4,0x54,0xb9,0x00,0x02,0x48,0xbd,0x00, + 0x30,0x99,0x00,0x02,0x68,0x9d,0x00,0x30, + 0xca,0x10,0xec,0x60,0x22,0x23,0x16,0x17, + 0x00,0x01,0x30,0x31,0xc0,0xc1,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7,0xc8,0x2f,0x6f,0x44, + 0x00,0x00,0x00,0x0a,0xaa,0xaa,0xaa,0xaa, + 0xaa,0x00,0x00,0x00,0x00,0x02,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xa8,0x00,0x0a,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x00,0x0a, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0x00,0x0a,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0x00,0x0a,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x5a,0x00,0x2a,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x5a,0x80,0x29,0x55,0x55,0x55,0x55, + 0x55,0xff,0xff,0x55,0x55,0x55,0x56,0x80, + 0x29,0x55,0x55,0x55,0x55,0x55,0xff,0xff, + 0x55,0x55,0x55,0x56,0x80,0x29,0x55,0x55, + 0x55,0x55,0x55,0xff,0xff,0x55,0x55,0x55, + 0x56,0x80,0x29,0x55,0x55,0x55,0x55,0x55, + 0xff,0xff,0x55,0x55,0x55,0x56,0x80,0xa9, + 0x55,0x55,0x55,0x55,0x55,0xff,0xff,0x55, + 0x55,0x55,0x56,0xa0,0xa9,0x55,0x55,0x55, + 0x55,0x55,0xff,0xff,0x55,0x55,0x55,0x56, + 0xa0,0xa9,0x55,0x55,0x55,0x55,0x55,0xff, + 0xff,0x55,0x55,0x55,0x56,0xa0,0xa9,0x55, + 0x55,0x55,0x55,0x55,0xff,0xff,0x55,0x55, + 0x55,0x56,0xa0,0xa5,0x55,0x55,0x55,0x55, + 0x55,0xff,0xff,0x55,0x55,0x55,0x55,0xa0, + 0xa5,0x55,0x55,0x55,0x55,0x55,0xff,0xff, + 0x55,0x55,0x55,0x55,0xa0,0xa5,0x55,0x57, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xd5,0xa0,0xa5,0x55,0x57,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xd5,0xa0,0xa5, + 0x55,0x57,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xd5,0xa0,0xa5,0x55,0x55,0x55, + 0x55,0x55,0xff,0xff,0x55,0x55,0x55,0x55, + 0xa0,0xa5,0x55,0x55,0x55,0x55,0x55,0xff, + 0xff,0x55,0x55,0x55,0x55,0xa0,0xa5,0x55, + 0x55,0x55,0x55,0x55,0xff,0xff,0x55,0x55, + 0x55,0x55,0xa0,0xa9,0x55,0x55,0x55,0x55, + 0x55,0xff,0xff,0x55,0x55,0x55,0x56,0xa0, + 0xa9,0x55,0x55,0x55,0x55,0x55,0xff,0xff, + 0x55,0x55,0x55,0x56,0xa0,0xa9,0x55,0x55, + 0x55,0x55,0x55,0xff,0xff,0x55,0x55,0x55, + 0x56,0xa0,0xa9,0x55,0x55,0x55,0x55,0x55, + 0xff,0xff,0x55,0x55,0x55,0x56,0xa0,0xa9, + 0x55,0x55,0x55,0x55,0x55,0xff,0xff,0x55, + 0x55,0x55,0x56,0xa0,0xa9,0x55,0x55,0x55, + 0x55,0x55,0xff,0xff,0x55,0x55,0x55,0x56, + 0xa0,0x29,0x55,0x55,0x55,0x55,0x55,0xff, + 0xff,0x55,0x55,0x55,0x56,0x80,0x29,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x56,0x80,0x29,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x56,0x80, + 0x29,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x56,0x80,0x2a,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x5a,0x80,0x0a,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x5a,0x00,0x0a, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0x00,0x0a,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0x00,0x0a,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0x00,0x02,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xa8,0x00,0x00,0x00,0x00,0x0a,0xaa, + 0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x00, + 0x87,0x52,0x9e,0x52,0xa3,0x52,0x14,0x30, + 0x00,0x00,0x02,0x00,0x08,0x0c,0x02,0x14, + 0x50,0x3d,0x01,0xff,0x70,0x70,0x70,0x70, + 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, + 0x4e,0x00,0x32,0x0e,0x0e,0x0e,0x0e,0x0e, + 0x0e,0x8e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e, + 0x0e,0x8e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e, + 0x0e,0x8e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e, + 0x0e,0x8e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e, + 0x0e,0x8e,0xf0,0x70,0x4f,0x00,0x20,0x0f, + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x70,0x0f, + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x41, + 0x14,0x30,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0x33,0x2e,0x34,0x31,0x00,0xff,0xff,0x00, + 0x20,0xa1,0xdb,0xa9,0x7f,0x85,0xd4,0x85, + 0xea,0xa2,0xd5,0x20,0x46,0xda,0x85,0xe6, + 0x85,0xe9,0xa4,0xf2,0xb1,0xf3,0xc9,0x2b, + 0xf0,0x06,0xc9,0x2d,0xd0,0x03,0x66,0xe9, + 0xc8,0x84,0xe8,0xa9,0x30,0x20,0xa5,0xdb, + 0xb1,0xf3,0xc9,0x2e,0xd0,0x10,0xc8,0x66, + 0xe6,0xe6,0xe8,0xa9,0x30,0xd1,0xf3,0xd0, + 0x05,0xc6,0xd4,0xc8,0xd0,0xf7,0xa2,0x01, + 0xb1,0xf3,0xc9,0x45,0xf0,0x55,0xc8,0xc9, + 0x2e,0xf0,0x28,0x49,0x30,0xc9,0x0a,0xb0, + 0x2a,0xe0,0x06,0xb0,0x15,0x24,0xea,0x10, + 0x09,0xc6,0xea,0x15,0xd4,0x95,0xd4,0xe8, + 0xd0,0x08,0xe6,0xea,0x0a,0x0a,0x0a,0x0a, + 0x95,0xd4,0x24,0xe6,0x30,0x02,0xe6,0xd4, + 0x4c,0x40,0xd8,0xa5,0xe6,0xd0,0x04,0x66, + 0xe6,0xd0,0xc5,0x88,0xc4,0xe8,0xf0,0x1a, + 0x84,0xf2,0x26,0xe9,0x66,0xd4,0xb0,0x0f, + 0xa2,0x04,0x46,0xd5,0x66,0xd6,0x66,0xd7, + 0x66,0xd8,0x66,0xd9,0xca,0xd0,0xf3,0x4c, + 0x00,0xdc,0x60,0xc4,0xe8,0xf0,0xfb,0x84, + 0xf2,0xa2,0x00,0xc8,0xb1,0xf3,0xc9,0x2b, + 0xf0,0x05,0xc9,0x2d,0xd0,0x02,0xca,0xc8, + 0x86,0xe7,0x20,0xb1,0xdb,0xc8,0xb0,0xca, + 0xaa,0x20,0xb1,0xdb,0xb0,0x05,0xc8,0x7d, + 0x39,0xda,0xaa,0x8a,0xf0,0xbc,0x45,0xe7, + 0x26,0xe7,0x65,0xd4,0x85,0xd4,0x4c,0x80, + 0xd8,0x75,0xd4,0x95,0xd4,0xca,0xa9,0x00, + 0xb0,0xf7,0x60,0x00,0x64,0xc8,0x2c,0x90, + 0xf4,0x58,0xbc,0x20,0x84,0xff,0x20,0x51, + 0xda,0xa0,0x00,0xa5,0xd4,0xd0,0x05,0xa9, + 0xb0,0x91,0xf3,0x60,0x84,0xf8,0x10,0x08, + 0xa2,0x2d,0xc6,0xf3,0x8e,0x7f,0x05,0xc8, + 0x84,0xf9,0xa2,0xfb,0x0a,0x38,0xe9,0x7d, + 0xc9,0x0c,0x90,0x0a,0xe9,0x02,0x85,0xf8, + 0xa9,0x02,0xe6,0xf9,0xe6,0xf9,0x85,0xf7, + 0xc9,0x02,0xb0,0x06,0xca,0xc6,0xf9,0x4a, + 0xf0,0x33,0xb5,0xda,0xc9,0x10,0xb0,0x0c, + 0xc6,0xf9,0x46,0xf8,0x06,0xf8,0xd0,0x18, + 0xc6,0xf7,0x90,0x14,0xc6,0xf7,0xd0,0x05, + 0xa9,0x2e,0x91,0xf3,0xc8,0xb5,0xda,0x4a, + 0x4a,0x4a,0x4a,0x09,0x30,0x91,0xf3,0xc8, + 0xc6,0xf7,0xd0,0x05,0xa9,0x2e,0x91,0xf3, + 0xc8,0xb5,0xda,0x29,0x0f,0x09,0x30,0x91, + 0xf3,0xc8,0xe8,0xd0,0xd7,0xa5,0xf7,0x10, + 0x11,0xa9,0x30,0xc4,0xf9,0xf0,0x05,0x88, + 0xd1,0xf3,0xf0,0xf7,0xb1,0xf3,0xc9,0x2e, + 0xd0,0x03,0x88,0xb1,0xf3,0xa6,0xf8,0xf0, + 0x26,0xa9,0x45,0xc8,0x91,0xf3,0x8a,0x10, + 0x07,0x49,0xff,0xaa,0xe8,0xa9,0x2d,0x2c, + 0xa9,0x2b,0xc8,0x91,0xf3,0x8a,0x38,0xa2, + 0x2f,0xe8,0xe9,0x0a,0xb0,0xfb,0x48,0x8a, + 0xc8,0x91,0xf3,0x68,0x69,0x3a,0xc8,0x09, + 0x80,0x91,0xf3,0x60,0xff,0xff,0xff,0xff, + 0xff,0xff,0xf8,0xa2,0xd6,0xa0,0x05,0x20, + 0x48,0xda,0xa0,0x10,0x06,0xd4,0x26,0xd5, + 0xa5,0xd8,0x65,0xd8,0x85,0xd8,0xa5,0xd7, + 0x65,0xd7,0x85,0xd7,0x26,0xd6,0x88,0xd0, + 0xeb,0xa9,0x43,0x85,0xd4,0x4c,0xff,0xdb, + 0xff,0xff,0xa5,0xd4,0xc9,0x43,0xb0,0x60, + 0xe9,0x3e,0x90,0x68,0xaa,0xa9,0x00,0xb4, + 0xd5,0xc0,0x50,0x2a,0x85,0xd4,0xa9,0x00, + 0xca,0x30,0x4b,0xb5,0xd5,0x20,0xcd,0xda, + 0x65,0xd4,0x79,0xf6,0xdf,0x18,0x85,0xd4, + 0xa9,0x00,0xca,0x30,0x39,0xb5,0xd5,0x20, + 0xcd,0xda,0xa5,0xd4,0x79,0x48,0xdf,0x85, + 0xd4,0xb9,0x52,0xdf,0x69,0x00,0x48,0xb5, + 0xd5,0x29,0x0f,0xa8,0xa5,0xd4,0x79,0xdb, + 0xd8,0x85,0xd4,0x68,0x79,0x5c,0xdf,0xca, + 0x30,0x14,0xb4,0xd5,0xc0,0x07,0xb0,0x10, + 0xaa,0x98,0x0a,0x0a,0x0a,0x0a,0x65,0xd4, + 0x85,0xd4,0x8a,0x79,0x65,0xdf,0x85,0xd5, + 0x60,0x00,0x0a,0x14,0x1e,0x28,0x32,0x3c, + 0x46,0x50,0x5a,0xff,0xa2,0xd4,0xa0,0x06, + 0xa9,0x00,0x95,0x00,0xe8,0x88,0xd0,0xfa, + 0x60,0xa9,0x80,0x85,0xf3,0xa9,0x05,0x85, + 0xf4,0x60,0x06,0xf8,0x26,0xf7,0x60,0xff, + 0xa5,0xe0,0x49,0x80,0x85,0xe0,0xa5,0xe0, + 0xf0,0x4e,0xa5,0xd4,0xf0,0x0e,0xa5,0xe0, + 0x45,0xd4,0x29,0x80,0xaa,0x45,0xe0,0x18, + 0xe5,0xd4,0x90,0x05,0x20,0xee,0xdb,0x30, + 0xe5,0x69,0x06,0xa8,0x30,0x32,0xf8,0xe0, + 0x80,0xa2,0x05,0xb0,0x2e,0xa9,0x00,0xc0, + 0x05,0xb0,0x03,0xb9,0xe1,0x00,0xc9,0x50, + 0x98,0xf0,0x0b,0xb9,0xe0,0x00,0x75,0xd4, + 0x95,0xd4,0xca,0x88,0xd0,0xf5,0x90,0x10, + 0xb0,0x08,0xb5,0xd5,0x69,0x00,0x95,0xd5, + 0x90,0x06,0xca,0x10,0xf5,0x20,0x7a,0xdd, + 0x4c,0xff,0xdb,0x84,0xe0,0xb0,0x08,0xb5, + 0xd4,0xf9,0xe1,0x00,0x95,0xd4,0xca,0x88, + 0x10,0xf5,0x4c,0x60,0xdc,0x48,0x4a,0x4a, + 0x4a,0x4a,0xa8,0x68,0x18,0x60,0xa0,0xdb, + 0x20,0x98,0xdd,0xa5,0xd4,0xf0,0xf5,0xa5, + 0xe0,0x18,0xf0,0x17,0x20,0x7c,0xde,0xa5, + 0xe0,0x18,0x20,0x03,0xdb,0x85,0xd4,0xe6, + 0xd4,0xa2,0xd5,0xa0,0x0c,0xf8,0x4c,0xc5, + 0xdc,0x68,0x68,0x4c,0x44,0xda,0xa5,0xe0, + 0x49,0x7f,0x38,0xaa,0x45,0xd4,0x29,0x80, + 0x85,0xe0,0x8a,0x65,0xd4,0xaa,0x45,0xe0, + 0xc9,0x4f,0x90,0xe5,0xc9,0xb1,0xb0,0xe1, + 0x8a,0xe9,0x3f,0x60,0x40,0x10,0x00,0x00, + 0x00,0x00,0x40,0x02,0x30,0x25,0x85,0x09, + 0xa5,0xe0,0xf0,0x72,0xa5,0xd4,0xf0,0x6c, + 0x20,0xfe,0xda,0x20,0x2d,0xdc,0xa5,0xd4, + 0x05,0xd5,0xf0,0x3d,0x90,0x05,0x20,0xb9, + 0xdb,0x90,0x36,0xa9,0x00,0xe5,0xdb,0xa6, + 0xdc,0x75,0xee,0x95,0xee,0xa9,0x99,0xca, + 0x90,0xf7,0x18,0xa5,0xd9,0x65,0xe5,0x85, + 0xd9,0xa5,0xd8,0x65,0xe4,0x85,0xd8,0xa5, + 0xd7,0x65,0xe3,0x85,0xd7,0xa5,0xd6,0x65, + 0xe2,0x85,0xd6,0xa5,0xd5,0x65,0xe1,0x85, + 0xd5,0xa5,0xd4,0x65,0xe0,0x85,0xd4,0x90, + 0xca,0x08,0xa2,0x04,0x06,0xd9,0x26,0xd8, + 0x26,0xd7,0x26,0xd6,0x26,0xd5,0x26,0xd4, + 0xca,0xd0,0xf1,0x28,0xa5,0xdb,0x49,0x09, + 0x85,0xdb,0xf0,0xa2,0xe6,0xdc,0xd0,0x9e, + 0x20,0x64,0xde,0xd8,0x18,0x60,0x38,0x60, + 0xff,0xa9,0x20,0xa4,0xf2,0xd1,0xf3,0xd0, + 0x03,0xc8,0xd0,0xf9,0x84,0xf2,0x60,0xa4, + 0xf2,0xb1,0xf3,0x38,0xe9,0x30,0xc9,0x0a, + 0x60,0xa5,0xdb,0xa6,0xdc,0x75,0xee,0x95, + 0xee,0xa9,0x00,0xca,0xb0,0xf7,0x38,0xa5, + 0xd9,0xe5,0xe5,0x85,0xd9,0xa5,0xd8,0xe5, + 0xe4,0x85,0xd8,0xa5,0xd7,0xe5,0xe3,0x85, + 0xd7,0xa5,0xd6,0xe5,0xe2,0x85,0xd6,0xa5, + 0xd5,0xe5,0xe1,0x85,0xd5,0xa5,0xd4,0xe9, + 0x00,0x85,0xd4,0xb0,0xcc,0x60,0xa2,0x05, + 0xb5,0xd4,0xb4,0xe0,0x95,0xe0,0x94,0xd4, + 0xca,0x10,0xf5,0x60,0xff,0xff,0xff,0xd8, + 0xa0,0x05,0xa5,0xd4,0x29,0x7f,0xf0,0x21, + 0xa6,0xd5,0xf0,0x07,0xc9,0x0f,0x90,0x1a, + 0xc9,0x71,0x60,0xc6,0xd4,0xa2,0xfb,0xb5, + 0xdb,0x95,0xda,0xe8,0xd0,0xf9,0x86,0xda, + 0x88,0xd0,0xdf,0x84,0xd4,0x84,0xd5,0x18, + 0x60,0x18,0x4c,0x44,0xda,0x85,0xda,0xa2, + 0xe7,0x20,0x46,0xda,0xa9,0x50,0x85,0xed, + 0x85,0xe6,0xa2,0x00,0x86,0xd4,0x86,0xe0, + 0xa5,0xe1,0xc9,0x10,0xb0,0x11,0xa0,0x04, + 0x06,0xe5,0x26,0xe4,0x26,0xe3,0x26,0xe2, + 0x26,0xe1,0x88,0xd0,0xf3,0xa2,0x09,0x86, + 0xdb,0xf8,0xa2,0xf9,0x86,0xdc,0x38,0x60, + 0xb0,0x1f,0x90,0x08,0xb5,0xd5,0xe9,0x00, + 0x95,0xd5,0xb0,0x15,0xca,0x10,0xf5,0xa2, + 0x05,0x38,0xa9,0x00,0xf5,0xd4,0x95,0xd4, + 0xca,0xd0,0xf7,0xa9,0x80,0x45,0xd4,0x85, + 0xd4,0xa5,0xd4,0x29,0x7f,0xc9,0x0f,0x90, + 0x1f,0xa6,0xd5,0xf0,0x0f,0xa6,0xe0,0xe0, + 0x04,0xb0,0x06,0xb5,0xe2,0xc9,0x50,0xb0, + 0x27,0x18,0xd8,0x60,0xa2,0xfc,0xc6,0xd4, + 0xb4,0xda,0xd0,0x08,0xe8,0xd0,0xf7,0x18, + 0xd8,0x4c,0x44,0xda,0xa0,0x00,0xb5,0xda, + 0x99,0xd5,0x00,0xc8,0xe8,0xd0,0xf7,0x96, + 0xd5,0xc8,0xc0,0x06,0xd0,0xf9,0xf0,0xc1, + 0xa2,0x05,0x4c,0xaa,0xda,0x20,0x48,0xda, + 0xa0,0x07,0xa9,0x50,0x85,0xdb,0xa2,0x05, + 0x56,0xe6,0xb0,0x2d,0xb5,0xd9,0x65,0xe5, + 0x95,0xd9,0xb5,0xd8,0x65,0xe4,0x95,0xd8, + 0xb5,0xd7,0x65,0xe3,0x95,0xd7,0xb5,0xd6, + 0x65,0xe2,0x95,0xd6,0xb5,0xd5,0x65,0xe1, + 0x95,0xd5,0xb5,0xd4,0x65,0xe0,0x95,0xd4, + 0x90,0x07,0x86,0xe6,0x20,0xd5,0xd8,0xa6, + 0xe6,0xca,0xd0,0xcc,0x18,0xa5,0xe5,0x65, + 0xe5,0x85,0xe5,0xa5,0xe4,0x65,0xe4,0x85, + 0xe4,0xa5,0xe3,0x65,0xe3,0x85,0xe3,0xa5, + 0xe2,0x65,0xe2,0x85,0xe2,0xa5,0xe1,0x65, + 0xe1,0x85,0xe1,0xa5,0xe0,0x65,0xe0,0x85, + 0xe0,0x88,0xd0,0xa2,0xa5,0xd5,0xf0,0x07, + 0xa9,0x50,0xa2,0x06,0x20,0xd1,0xd8,0x4c, + 0xff,0xdb,0xff,0xff,0xff,0xff,0xa9,0x0a, + 0x86,0xfe,0x84,0xff,0x85,0xec,0xa2,0xe0, + 0xa0,0x05,0x20,0xa7,0xdd,0x20,0x44,0xda, + 0xa5,0xfe,0xaa,0x18,0x69,0x06,0x85,0xfe, + 0xa4,0xff,0x90,0x02,0xe6,0xff,0x20,0x98, + 0xdd,0x20,0x66,0xda,0xb0,0x0d,0xc6,0xec, + 0xf0,0x09,0xa2,0xe0,0xa0,0x05,0x20,0xd8, + 0xda,0x90,0xdd,0x60,0x3f,0x43,0x42,0x94, + 0x48,0x19,0xe6,0xd4,0xa2,0x04,0xb5,0xd4, + 0x95,0xd5,0xca,0xd0,0xf9,0xe8,0x86,0xd5, + 0x60,0x86,0xfc,0x84,0xfd,0xa0,0x05,0xb1, + 0xfc,0x99,0xd4,0x00,0x88,0x10,0xf8,0x60, + 0x86,0xfc,0x84,0xfd,0xa0,0x05,0xb1,0xfc, + 0x99,0xe0,0x00,0x88,0x10,0xf8,0x60,0x86, + 0xfc,0x84,0xfd,0xa0,0x05,0xb9,0xd4,0x00, + 0x91,0xfc,0x88,0x10,0xf8,0x60,0xa2,0x05, + 0xb5,0xd4,0x95,0xe0,0xca,0x10,0xf9,0x60, + 0xa2,0x74,0xa0,0xdd,0x20,0x98,0xdd,0x20, + 0xdb,0xda,0xb0,0x5b,0xa5,0xd4,0x85,0xf9, + 0x29,0x7f,0x85,0xd4,0xa0,0x00,0xc9,0x40, + 0x90,0x1e,0xf0,0x08,0xa5,0xf9,0x10,0x47, + 0x18,0x4c,0x44,0xda,0xa5,0xd5,0x20,0xcd, + 0xda,0x79,0xf6,0xdf,0x48,0xa9,0x00,0x85, + 0xd5,0x85,0xda,0x20,0x00,0xdc,0x68,0xa8, + 0x84,0xf8,0xa2,0x28,0xa0,0xde,0x20,0x3e, + 0xdd,0x46,0xf8,0x90,0x07,0xa2,0x1c,0x20, + 0xd6,0xda,0xb0,0xd0,0xa5,0xf8,0x65,0xd4, + 0xc9,0x71,0xb0,0xc8,0x85,0xd4,0x26,0xf9, + 0x90,0x0d,0x20,0xb6,0xdd,0xa2,0xea,0xa0, + 0xdf,0x20,0x89,0xdd,0x4c,0x28,0xdb,0x60, + 0x3f,0x01,0x46,0x90,0x83,0x08,0xbe,0x20, + 0x05,0x33,0x11,0x71,0x3f,0x09,0x19,0x45, + 0x20,0x45,0x3f,0x19,0x21,0x38,0x38,0x84, + 0x3f,0x54,0x47,0x32,0x51,0x97,0x40,0x01, + 0x17,0x01,0x82,0x50,0x40,0x02,0x03,0x47, + 0x85,0x81,0x40,0x02,0x65,0x09,0x44,0x94, + 0x40,0x02,0x30,0x25,0x85,0x12,0x40,0x01, + 0x00,0x00,0x00,0x00,0xa2,0xe6,0xa4,0xda, + 0xa5,0xe7,0xd0,0x02,0xe8,0x88,0x84,0xd4, + 0xa0,0x05,0xb5,0x05,0xca,0x99,0xd4,0x00, + 0x88,0xd0,0xf7,0x60,0xa2,0x04,0xb5,0xd5, + 0x4a,0x4a,0x4a,0x4a,0xa8,0x18,0xb5,0xd5, + 0x79,0xf6,0xdf,0x49,0xff,0x95,0xe7,0xca, + 0x10,0xec,0x60,0xff,0xff,0x86,0xfe,0x84, + 0xff,0x20,0x98,0xdd,0xa2,0xe6,0xa0,0x05, + 0x20,0xa7,0xdd,0x20,0x66,0xda,0xb0,0xea, + 0xa2,0xe0,0xa0,0x05,0x20,0xa7,0xdd,0xa2, + 0xe6,0xa0,0x05,0x20,0x89,0xdd,0xa6,0xfe, + 0xa4,0xff,0x20,0x98,0xdd,0x20,0x60,0xda, + 0xb0,0xd0,0xa2,0xe0,0xa0,0x05,0x20,0x98, + 0xdd,0x4c,0x28,0xdb,0xff,0x46,0xf9,0x10, + 0x03,0x38,0x66,0xf9,0xa5,0xd4,0x30,0x6e, + 0x0a,0x49,0x80,0x85,0xf8,0xa5,0xd5,0xf0, + 0x65,0xa2,0x40,0x86,0xd4,0xc9,0x03,0x90, + 0x13,0xc9,0x31,0x90,0x04,0xe6,0xf8,0xd0, + 0x07,0xa2,0x1c,0x20,0xd6,0xda,0xb0,0x4f, + 0xe6,0xf8,0xc6,0xd4,0xa2,0xea,0xa0,0xdf, + 0x20,0x95,0xde,0xa2,0xe6,0xa0,0x05,0x20, + 0xa7,0xdd,0x20,0xb6,0xdd,0x20,0xdb,0xda, + 0xa2,0x72,0xa0,0xdf,0x20,0x3e,0xdd,0xb0, + 0x2e,0xa2,0xe6,0xa0,0x05,0x20,0xd8,0xda, + 0x20,0xb6,0xdd,0xa9,0x00,0x85,0xd5,0xa6, + 0xf8,0x10,0x04,0x38,0xe5,0xf8,0xaa,0x86, + 0xd4,0x20,0xaa,0xd9,0x06,0xd4,0x06,0xf8, + 0x66,0xd4,0x20,0x66,0xda,0x24,0xf9,0x30, + 0x06,0xa2,0x22,0x4c,0xd6,0xda,0x38,0x60, + 0x00,0xe8,0xd0,0xb8,0xa0,0x88,0x70,0x58, + 0x40,0x28,0x00,0x03,0x07,0x0b,0x0f,0x13, + 0x17,0x1b,0x1f,0x23,0x00,0x00,0x00,0x01, + 0x01,0x01,0x02,0x02,0x03,0x03,0x27,0x4e, + 0x75,0x9c,0xc3,0xea,0x3f,0x50,0x00,0x00, + 0x00,0x00,0x3f,0x20,0x26,0x22,0x71,0x54, + 0xbf,0x07,0x32,0x04,0x49,0x21,0x3f,0x10, + 0x60,0x98,0x35,0x64,0x3f,0x05,0x60,0x41, + 0x73,0x29,0x3f,0x08,0x04,0x18,0x84,0x07, + 0x3f,0x09,0x63,0x91,0x60,0x15,0x3f,0x12, + 0x40,0x89,0x61,0x35,0x3f,0x17,0x37,0x17, + 0x66,0x46,0x3f,0x28,0x95,0x29,0x65,0x58, + 0x3f,0x86,0x85,0x88,0x96,0x38,0x3e,0x11, + 0x12,0x07,0x58,0x81,0xbe,0x73,0x04,0x08, + 0x75,0x20,0x3f,0x02,0x24,0x96,0x55,0x73, + 0xbf,0x04,0x46,0x18,0x51,0x72,0x3f,0x06, + 0x73,0x46,0x32,0x45,0xbf,0x08,0x80,0x69, + 0x06,0x64,0x3f,0x11,0x05,0x66,0x74,0x99, + 0xbf,0x14,0x27,0x94,0x93,0x12,0x3f,0x19, + 0x99,0x96,0x30,0x60,0xbf,0x33,0x33,0x33, + 0x24,0x72,0x40,0x01,0x00,0x00,0x00,0x00, + 0x3f,0x78,0x53,0x98,0x16,0x34,0x00,0xfa, + 0xf4,0xee,0xe8,0xe2,0xdc,0xd6,0xd0,0xca, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x00, + 0x00,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + 0x00,0x66,0xff,0x66,0x66,0xff,0x66,0x00, + 0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00, + 0x00,0x66,0x6c,0x18,0x30,0x66,0x46,0x00, + 0x1c,0x36,0x1c,0x38,0x6f,0x66,0x3b,0x00, + 0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + 0x00,0x0e,0x1c,0x18,0x18,0x1c,0x0e,0x00, + 0x00,0x70,0x38,0x18,0x18,0x38,0x70,0x00, + 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00, + 0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, + 0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, + 0x00,0x06,0x0c,0x18,0x30,0x60,0x40,0x00, + 0x00,0x3c,0x66,0x6e,0x76,0x66,0x3c,0x00, + 0x00,0x18,0x38,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x7e,0x0c,0x18,0x0c,0x66,0x3c,0x00, + 0x00,0x0c,0x1c,0x3c,0x6c,0x7e,0x0c,0x00, + 0x00,0x7e,0x60,0x7c,0x06,0x66,0x3c,0x00, + 0x00,0x3c,0x60,0x7c,0x66,0x66,0x3c,0x00, + 0x00,0x7e,0x06,0x0c,0x18,0x30,0x30,0x00, + 0x00,0x3c,0x66,0x3c,0x66,0x66,0x3c,0x00, + 0x00,0x3c,0x66,0x3e,0x06,0x0c,0x38,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00, + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x30, + 0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00, + 0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00, + 0x00,0x3c,0x66,0x0c,0x18,0x00,0x18,0x00, + 0x00,0x3c,0x66,0x6e,0x6e,0x60,0x3e,0x00, + 0x00,0x18,0x3c,0x66,0x66,0x7e,0x66,0x00, + 0x00,0x7c,0x66,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x00, + 0x00,0x78,0x6c,0x66,0x66,0x6c,0x78,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x7e,0x00, + 0x00,0x7e,0x60,0x7c,0x60,0x60,0x60,0x00, + 0x00,0x3e,0x60,0x60,0x6e,0x66,0x3e,0x00, + 0x00,0x66,0x66,0x7e,0x66,0x66,0x66,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x7e,0x00, + 0x00,0x06,0x06,0x06,0x06,0x66,0x3c,0x00, + 0x00,0x66,0x6c,0x78,0x78,0x6c,0x66,0x00, + 0x00,0x60,0x60,0x60,0x60,0x60,0x7e,0x00, + 0x00,0x63,0x77,0x7f,0x6b,0x63,0x63,0x00, + 0x00,0x66,0x76,0x7e,0x7e,0x6e,0x66,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x60,0x60,0x00, + 0x00,0x3c,0x66,0x66,0x66,0x6c,0x36,0x00, + 0x00,0x7c,0x66,0x66,0x7c,0x6c,0x66,0x00, + 0x00,0x3c,0x60,0x3c,0x06,0x06,0x3c,0x00, + 0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x00, + 0x00,0x66,0x66,0x66,0x66,0x66,0x7e,0x00, + 0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00, + 0x00,0x66,0x66,0x3c,0x3c,0x66,0x66,0x00, + 0x00,0x66,0x66,0x3c,0x18,0x18,0x18,0x00, + 0x00,0x7e,0x0c,0x18,0x30,0x60,0x7e,0x00, + 0x00,0x1e,0x18,0x18,0x18,0x18,0x1e,0x00, + 0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x00, + 0x00,0x78,0x18,0x18,0x18,0x18,0x78,0x00, + 0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0x36,0x7f,0x7f,0x3e,0x1c,0x08,0x00, + 0x18,0x18,0x18,0x1f,0x1f,0x18,0x18,0x18, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, + 0x18,0x18,0x18,0xf8,0xf8,0x00,0x00,0x00, + 0x18,0x18,0x18,0xf8,0xf8,0x18,0x18,0x18, + 0x00,0x00,0x00,0xf8,0xf8,0x18,0x18,0x18, + 0x03,0x07,0x0e,0x1c,0x38,0x70,0xe0,0xc0, + 0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x07,0x03, + 0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff, + 0x00,0x00,0x00,0x00,0x0f,0x0f,0x0f,0x0f, + 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff, + 0x0f,0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00, + 0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00, + 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0x00,0xf0,0xf0,0xf0,0xf0, + 0x00,0x1c,0x1c,0x77,0x77,0x08,0x1c,0x00, + 0x00,0x00,0x00,0x1f,0x1f,0x18,0x18,0x18, + 0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, + 0x18,0x18,0x18,0xff,0xff,0x18,0x18,0x18, + 0x00,0x00,0x3c,0x7e,0x7e,0x7e,0x3c,0x00, + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0x00,0x00,0x00,0xff,0xff,0x18,0x18,0x18, + 0x18,0x18,0x18,0xff,0xff,0x00,0x00,0x00, + 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, + 0x18,0x18,0x18,0x1f,0x1f,0x00,0x00,0x00, + 0x78,0x60,0x78,0x60,0x7e,0x18,0x1e,0x00, + 0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x00, + 0x00,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00, + 0x00,0x18,0x30,0x7e,0x30,0x18,0x00,0x00, + 0x00,0x18,0x0c,0x7e,0x0c,0x18,0x00,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x3c,0x18,0x00, + 0x00,0x00,0x3c,0x06,0x3e,0x66,0x3e,0x00, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x7c,0x00, + 0x00,0x00,0x3c,0x60,0x60,0x60,0x3c,0x00, + 0x00,0x06,0x06,0x3e,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x3c,0x66,0x7e,0x60,0x3c,0x00, + 0x00,0x0e,0x18,0x3e,0x18,0x18,0x18,0x00, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x7c, + 0x00,0x60,0x60,0x7c,0x66,0x66,0x66,0x00, + 0x00,0x18,0x00,0x38,0x18,0x18,0x3c,0x00, + 0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x3c, + 0x00,0x60,0x60,0x6c,0x78,0x6c,0x66,0x00, + 0x00,0x38,0x18,0x18,0x18,0x18,0x3c,0x00, + 0x00,0x00,0x66,0x7f,0x7f,0x6b,0x63,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x66,0x66,0x00, + 0x00,0x00,0x3c,0x66,0x66,0x66,0x3c,0x00, + 0x00,0x00,0x7c,0x66,0x66,0x7c,0x60,0x60, + 0x00,0x00,0x3e,0x66,0x66,0x3e,0x06,0x06, + 0x00,0x00,0x7c,0x66,0x60,0x60,0x60,0x00, + 0x00,0x00,0x3e,0x60,0x3c,0x06,0x7c,0x00, + 0x00,0x18,0x7e,0x18,0x18,0x18,0x0e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3c,0x18,0x00, + 0x00,0x00,0x63,0x6b,0x7f,0x3e,0x36,0x00, + 0x00,0x00,0x66,0x3c,0x18,0x3c,0x66,0x00, + 0x00,0x00,0x66,0x66,0x66,0x3e,0x0c,0x78, + 0x00,0x00,0x7e,0x0c,0x18,0x30,0x7e,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x18,0x3c,0x00, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x00,0x7e,0x78,0x7c,0x6e,0x66,0x06,0x00, + 0x08,0x18,0x38,0x78,0x38,0x18,0x08,0x00, + 0x10,0x18,0x1c,0x1e,0x1c,0x18,0x10,0x00, + 0xfb,0xf9,0x29,0xfe,0x07,0xfa,0xb9,0xfa, + 0xc8,0xe4,0xca,0xe4,0x4c,0xcb,0xe4,0x00, + 0xf5,0xf3,0x29,0xfe,0xd0,0xf5,0x10,0xf6, + 0xc8,0xe4,0xf4,0xf6,0x20,0xc3,0xf5,0x00, + 0xc8,0xe4,0xc8,0xe4,0x6a,0xfe,0xca,0xe4, + 0xc8,0xe4,0xca,0xe4,0x4c,0x41,0xfe,0x00, + 0xe7,0xec,0xa8,0xec,0xca,0xe4,0x86,0xec, + 0xec,0xec,0xca,0xe4,0x20,0x81,0xec,0x00, + 0x18,0xed,0x6d,0xed,0x8e,0xed,0xce,0xed, + 0xc8,0xe4,0xca,0xe4,0x4c,0x0e,0xed,0x00, + 0x4c,0x11,0xec,0x4c,0x1c,0xec,0x4c,0xfc, + 0xe4,0x4c,0xf7,0xe7,0x4c,0x5d,0xc1,0x4c, + 0x0c,0xc0,0x4c,0x50,0xc0,0x4c,0xec,0xe7, + 0x4c,0x4a,0xe9,0x4c,0x82,0xc1,0x4c,0xea, + 0xe4,0x4c,0x9b,0xe4,0x4c,0x4e,0xef,0x4c, + 0xd5,0xee,0x4c,0x0f,0xee,0x4c,0x2c,0xed, + 0x4c,0x9b,0xe4,0x4c,0x00,0x50,0x4c,0x2f, + 0xc3,0x4c,0x65,0xc3,0x4c,0xab,0xc3,0xdc, + 0xc2,0xe0,0xc2,0xe4,0xc2,0xe8,0xc2,0x26, + 0xc3,0x2a,0xc3,0xad,0x01,0xd3,0x29,0x7f, + 0x8d,0x01,0xd3,0x4c,0x00,0x50,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0x60,0x80,0x40,0x20,0x10,0x08,0x04,0x02, + 0x01,0xa0,0x01,0x60,0x48,0xa9,0x08,0xa2, + 0x04,0x48,0xad,0x0b,0xd4,0xcd,0x0b,0xd4, + 0xf0,0xfb,0xca,0xd0,0xf5,0x68,0x49,0x08, + 0x8d,0x1f,0xd0,0xd0,0xea,0x88,0xd0,0xe7, + 0x68,0x60,0x38,0xa2,0x70,0xa9,0xff,0x9d, + 0x40,0x03,0x20,0x5e,0xe7,0x8a,0xe9,0x10, + 0xaa,0x10,0xf2,0x60,0x85,0x2f,0x86,0x2e, + 0x20,0x13,0xe5,0xa6,0x2e,0x98,0x9d,0x43, + 0x03,0xa9,0x00,0x8d,0xe9,0x02,0xa5,0x2f, + 0xc0,0x00,0x60,0x8a,0x29,0x8f,0xf0,0x06, + 0xa0,0x86,0x60,0xa0,0x84,0x60,0x20,0xeb, + 0xe6,0xa5,0x22,0xc9,0x03,0xf0,0x7b,0x90, + 0xf2,0xa4,0x20,0x30,0x15,0xc8,0x10,0x2e, + 0xc9,0x0c,0xd0,0x03,0x4c,0xa2,0xe6,0xad, + 0xe9,0x02,0xf0,0x06,0x20,0x9c,0xe7,0x10, + 0x1d,0x60,0xa0,0x01,0xa5,0x22,0xc9,0x0c, + 0xf0,0x06,0xc9,0x0d,0xb0,0x03,0xa0,0x85, + 0x60,0x20,0xfa,0xe6,0xa5,0x22,0xc9,0x0d, + 0xf0,0x40,0xc9,0x0e,0xb0,0x3f,0xa6,0x22, + 0xe0,0x0e,0x90,0x02,0xa2,0x0e,0xbd,0xa9, + 0xe6,0x30,0x04,0x24,0x2a,0xf0,0x26,0xbd, + 0xca,0xe6,0x48,0xbd,0xbf,0xe6,0x48,0xbc, + 0xb4,0xe6,0xa6,0x20,0xbd,0x1b,0x03,0x85, + 0x2c,0xbd,0x1c,0x03,0x85,0x2d,0xb1,0x2c, + 0xaa,0x88,0xb1,0x2c,0x85,0x2c,0x86,0x2d, + 0xa5,0x28,0x05,0x29,0x60,0x18,0x69,0x7f, + 0xa8,0x60,0xa0,0x09,0x2c,0xa0,0x0b,0x4c, + 0xd9,0xe6,0xa4,0x20,0xc8,0xf0,0x03,0xa0, + 0x81,0x60,0x20,0xfa,0xe6,0xa0,0x01,0x20, + 0xd9,0xe6,0xa6,0x2e,0xa5,0x20,0x9d,0x40, + 0x03,0xa5,0x21,0x9d,0x41,0x03,0x98,0x10, + 0x01,0x60,0xa6,0x20,0xbd,0x1b,0x03,0x85, + 0x2c,0xbd,0x1c,0x03,0x85,0x2d,0xa0,0x06, + 0xb1,0x2c,0xa6,0x2e,0x9d,0x46,0x03,0xc8, + 0xb1,0x2c,0x9d,0x47,0x03,0xa0,0x01,0x60, + 0x20,0xdc,0xe6,0xa6,0x2e,0xa5,0x2a,0x9d, + 0x4a,0x03,0xa5,0x2b,0x9d,0x4b,0x03,0x60, + 0xf0,0x16,0x20,0xdc,0xe6,0xc0,0x00,0x30, + 0x1c,0xa2,0x00,0x81,0x24,0x49,0x9b,0xc9, + 0x01,0x20,0x8c,0xe6,0x90,0x0f,0xd0,0xea, + 0x20,0xdc,0xe6,0xc0,0x00,0x30,0x06,0xc9, + 0x9b,0xd0,0xf5,0xa0,0x89,0xa6,0x2e,0x38, + 0xbd,0x48,0x03,0xe5,0x28,0x85,0x28,0x9d, + 0x48,0x03,0xbd,0x49,0x03,0xe5,0x29,0x85, + 0x29,0x9d,0x49,0x03,0xbd,0x44,0x03,0x85, + 0x24,0xbd,0x45,0x03,0x85,0x25,0x60,0xf0, + 0x15,0x20,0xdc,0xe6,0xc0,0x00,0x30,0x0b, + 0xa2,0x00,0x85,0x2f,0x81,0x24,0x20,0x8c, + 0xe6,0xd0,0xee,0x4c,0x15,0xe6,0x20,0xdc, + 0xe6,0x85,0x2f,0x60,0xf0,0x33,0xa0,0x00, + 0xb1,0x24,0x20,0xdc,0xe6,0x98,0x30,0x12, + 0x20,0x8c,0xe6,0xf0,0x08,0xa9,0x9b,0xc5, + 0x2f,0xf0,0x07,0xd0,0xe7,0xa9,0x9b,0x20, + 0xdc,0xe6,0x4c,0x15,0xe6,0xf0,0x12,0xa0, + 0x00,0xb1,0x24,0x20,0xdc,0xe6,0x98,0x30, + 0xf1,0x20,0x8c,0xe6,0xd0,0xf1,0x4c,0x15, + 0xe6,0x4c,0xde,0xe6,0xe6,0x24,0xd0,0x02, + 0xe6,0x25,0xa5,0x28,0xd0,0x02,0xc6,0x29, + 0xc6,0x28,0xd0,0x02,0xa5,0x29,0x60,0x20, + 0xdc,0xe6,0xa6,0x2e,0x20,0x5e,0xe7,0xa9, + 0xff,0x9d,0x40,0x03,0x60,0x04,0x04,0x04, + 0x04,0x08,0x08,0x08,0x08,0xff,0xff,0xff, + 0x05,0x05,0x05,0x05,0x07,0x07,0x07,0x07, + 0x03,0x09,0x0b,0xef,0xef,0x36,0x36,0x53, + 0x53,0x74,0x74,0x9e,0xdb,0xdf,0xe5,0xe5, + 0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6, + 0xe5,0x20,0x7a,0xe5,0x85,0x2f,0xa5,0x2d, + 0x48,0xa5,0x2c,0x48,0xa0,0x92,0xa6,0x2e, + 0xa5,0x2f,0x60,0xa0,0x00,0xbd,0x40,0x03, + 0x99,0x20,0x00,0xe8,0xc8,0xc0,0x0c,0xd0, + 0xf4,0x60,0xa2,0x01,0xa1,0x23,0x85,0x2d, + 0xa0,0x01,0xb1,0x24,0x38,0xe9,0x30,0xf0, + 0x06,0xc9,0x0a,0xb0,0x02,0xaa,0xc8,0x86, + 0x21,0xa5,0x22,0xc9,0x03,0xd0,0x3d,0xa9, + 0x00,0x8d,0xea,0x02,0x8d,0xeb,0x02,0xad, + 0xe9,0x02,0xd0,0x05,0x20,0x69,0xe7,0xf0, + 0x34,0x20,0x7a,0xe7,0x30,0x2b,0xa6,0x2e, + 0xa9,0x7f,0x9d,0x40,0x03,0xa5,0x2d,0x9d, + 0x4c,0x03,0xad,0xec,0x02,0x9d,0x4d,0x03, + 0xa9,0xc9,0x9d,0x46,0x03,0xa9,0xe7,0x9d, + 0x47,0x03,0xa5,0x21,0x9d,0x41,0x03,0x68, + 0x68,0xa0,0x01,0x60,0x20,0x69,0xe7,0xf0, + 0x04,0xa0,0x82,0x68,0x68,0x60,0xa9,0x4d, + 0x9d,0x46,0x03,0xa9,0xe5,0x9d,0x47,0x03, + 0x60,0xa5,0x2d,0xa2,0x21,0xdd,0x1a,0x03, + 0xf0,0x05,0xca,0xca,0xca,0x10,0xf6,0x86, + 0x20,0x60,0xa5,0x2d,0x8d,0x0a,0x03,0xa5, + 0x21,0x8d,0x0b,0x03,0xa2,0x09,0xbd,0x92, + 0xe7,0x9d,0x00,0x03,0xca,0x10,0xf7,0x4c, + 0x59,0xe4,0x4f,0x01,0x40,0x40,0xea,0x02, + 0x40,0x00,0x04,0x00,0xad,0xec,0x02,0x8d, + 0xd1,0x02,0xad,0xed,0x02,0x8d,0xd2,0x02, + 0xa6,0x2e,0xbd,0x4d,0x03,0x8d,0x00,0x03, + 0x18,0x20,0x0e,0xc5,0xb0,0x11,0xa6,0x2e, + 0xbd,0x4c,0x03,0x85,0x2d,0x20,0x69,0xe7, + 0xd0,0x05,0x20,0xad,0xe5,0x10,0x02,0xa0, + 0x82,0x60,0x85,0x2f,0x86,0x2e,0xad,0xe9, + 0x02,0xf0,0x10,0x20,0xeb,0xe6,0x20,0x9c, + 0xe7,0x30,0x08,0xa0,0x07,0x20,0xd9,0xe6, + 0x4c,0xe5,0xe7,0xa0,0x82,0x08,0xa5,0x2f, + 0xa6,0x2e,0x28,0x60,0xa9,0x03,0x8d,0x0f, + 0xd2,0x8d,0x32,0x02,0x85,0x41,0x60,0xa9, + 0x01,0x8d,0xbd,0x02,0x85,0x42,0x20,0xaf, + 0xc2,0x90,0x03,0x4c,0xef,0xe8,0xba,0x8e, + 0x18,0x03,0x20,0x16,0xe9,0xa2,0x00,0xad, + 0x00,0x03,0xc9,0x60,0xd0,0x01,0xca,0x8e, + 0x0f,0x03,0x20,0x69,0xe9,0x2c,0x0f,0x03, + 0x10,0x03,0x4c,0xe1,0xea,0xa9,0x0d,0x8d, + 0x9c,0x02,0xad,0x00,0x03,0x18,0x6d,0x01, + 0x03,0x38,0xe9,0x01,0x8d,0x3a,0x02,0xad, + 0x02,0x03,0x8d,0x3b,0x02,0xad,0x0a,0x03, + 0x8d,0x3c,0x02,0xad,0x0b,0x03,0x8d,0x3d, + 0x02,0xa9,0x34,0x8d,0x03,0xd3,0xa2,0x05, + 0xac,0x0b,0xd4,0xcc,0x0b,0xd4,0xf0,0xfb, + 0xc8,0xca,0xd0,0xf7,0xa9,0x00,0x85,0x3c, + 0xa9,0x02,0x85,0x33,0x85,0x35,0xa9,0x3a, + 0x85,0x32,0xa9,0x3e,0x85,0x34,0x20,0xce, + 0xe9,0x30,0x67,0x20,0x21,0xe9,0x10,0x0a, + 0x20,0x3d,0xea,0xce,0x9c,0x02,0x10,0xaa, + 0x30,0x4d,0x2c,0x03,0x03,0x10,0x0d,0x20, + 0xb8,0xe9,0x20,0xce,0xe9,0x30,0x4b,0x20, + 0x21,0xe9,0x30,0xe4,0xa2,0xff,0x86,0x3c, + 0xad,0x06,0x03,0x6a,0x6a,0x48,0x6a,0x29, + 0xc0,0xa8,0x68,0x29,0x3f,0xaa,0xa9,0x01, + 0x8d,0x17,0x03,0x20,0x5c,0xe4,0xa2,0x3e, + 0x86,0x32,0xe8,0x86,0x34,0xa2,0x02,0x86, + 0x33,0x86,0x35,0x20,0xff,0xe9,0x30,0x0f, + 0xad,0x3e,0x02,0xc9,0x45,0xf0,0x34,0x09, + 0x02,0xc9,0x43,0xf0,0x2e,0xa0,0x90,0x20, + 0x3d,0xea,0xce,0xbd,0x02,0x30,0x03,0x4c, + 0x25,0xe8,0xae,0x0f,0x03,0xd0,0x0c,0x8e, + 0x01,0xd2,0x8e,0x03,0xd2,0x8e,0x05,0xd2, + 0x8e,0x07,0xd2,0xae,0x18,0x03,0x9a,0xa9, + 0x00,0x85,0x42,0xc0,0x00,0x8c,0x03,0x03, + 0x84,0x30,0x60,0x2c,0x03,0x03,0x50,0x08, + 0x20,0xb8,0xe9,0x20,0xff,0xe9,0x30,0xc7, + 0x20,0x3d,0xea,0xad,0x3e,0x02,0xc9,0x45, + 0xf0,0xbb,0xa0,0x01,0xd0,0xc4,0xa9,0xdb, + 0x8d,0x26,0x02,0xa9,0xea,0x8d,0x27,0x02, + 0x60,0xa2,0xff,0x86,0x3c,0xe8,0xa9,0x01, + 0x8d,0x17,0x03,0xa0,0x02,0x84,0x33,0x84, + 0x35,0x20,0x5c,0xe4,0xa2,0x3e,0x86,0x32, + 0xe8,0x86,0x34,0x20,0xff,0xe9,0x30,0x09, + 0xad,0x3e,0x02,0xc9,0x41,0xf0,0x02,0xa0, + 0x8b,0x60,0xa5,0x10,0x09,0x10,0x29,0xf7, + 0x85,0x10,0x8d,0x0e,0xd2,0xad,0x32,0x02, + 0x29,0x0f,0x09,0x20,0xae,0x0f,0x03,0xf0, + 0x02,0x09,0x08,0x8d,0x32,0x02,0x8d,0x0f, + 0xd2,0xa2,0x08,0xad,0x0f,0x03,0xf0,0x02, + 0xa2,0x11,0xa0,0x08,0xbd,0x9d,0xe9,0xca, + 0x99,0x00,0xd2,0x88,0x10,0xf6,0xa5,0x41, + 0xf0,0x17,0xa9,0xa8,0x8d,0x07,0xd2,0xae, + 0x0f,0x03,0xf0,0x0d,0xa9,0x10,0x2c,0x32, + 0x02,0xd0,0x06,0x8d,0x01,0xd2,0x8d,0x03, + 0xd2,0x8d,0x0a,0xd2,0x60,0x00,0xa0,0x00, + 0xa0,0x28,0xa0,0x00,0xa0,0x28,0x05,0xa0, + 0x07,0xa0,0xcc,0xa0,0x05,0xa0,0x28,0x00, + 0xa0,0x00,0xa0,0xcc,0xa0,0x05,0xa0,0x28, + 0x18,0xad,0x04,0x03,0x85,0x32,0x6d,0x08, + 0x03,0x85,0x34,0xad,0x05,0x03,0x85,0x33, + 0x6d,0x09,0x03,0x85,0x35,0x60,0x78,0x20, + 0x4a,0xe9,0xa0,0x00,0x84,0x3a,0x84,0x30, + 0x84,0x3b,0xb1,0x32,0x8d,0x0d,0xd2,0x85, + 0x31,0x58,0xa5,0x11,0xf0,0x06,0xa5,0x3a, + 0xf0,0xf8,0xd0,0x06,0xa0,0x80,0x84,0x30, + 0xc6,0x11,0x78,0xa5,0x10,0x29,0xe7,0x85, + 0x10,0x8d,0x0e,0xd2,0x58,0x98,0x60,0xa9, + 0x00,0x85,0x31,0xa2,0x00,0x86,0x39,0x86, + 0x38,0xe8,0x86,0x30,0x78,0xad,0x32,0x02, + 0x29,0x8f,0x09,0x10,0x8d,0x32,0x02,0x8d, + 0x0f,0xd2,0xa5,0x10,0x09,0x20,0x85,0x10, + 0x8d,0x0e,0xd2,0x58,0xa9,0x3c,0x8d,0x03, + 0xd3,0xad,0x17,0x03,0xf0,0x0b,0xa4,0x30, + 0x30,0x05,0xa5,0x39,0xf0,0xf3,0x98,0x78, + 0x60,0xa0,0x8a,0x78,0x60,0xa5,0x10,0x29, + 0xd7,0x85,0x10,0x8d,0x0e,0xd2,0x58,0x60, + 0xa5,0x38,0xd0,0x2a,0x98,0x48,0xad,0x0d, + 0xd2,0xa0,0x00,0x91,0x32,0x18,0x65,0x31, + 0x69,0x00,0x85,0x31,0x68,0xa8,0xe6,0x32, + 0xd0,0x02,0xe6,0x33,0xa5,0x32,0xc5,0x34, + 0xa5,0x33,0xe5,0x35,0x90,0x06,0xc6,0x38, + 0xa5,0x3c,0xd0,0x15,0x68,0x40,0xad,0x0d, + 0xd2,0xc5,0x31,0xd0,0x06,0xa9,0xff,0x85, + 0x39,0x68,0x40,0xa9,0x8f,0x85,0x30,0xd0, + 0xf4,0x85,0x39,0xa9,0x00,0x85,0x3c,0x68, + 0x40,0xe6,0x32,0xd0,0x02,0xe6,0x33,0xa5, + 0x32,0xc5,0x34,0xa5,0x33,0xe5,0x35,0xb0, + 0x13,0x98,0x48,0xa0,0x00,0xb1,0x32,0x8d, + 0x0d,0xd2,0x65,0x31,0x69,0x00,0x85,0x31, + 0x68,0xa8,0x68,0x40,0xa5,0x31,0x8d,0x0d, + 0xd2,0xa9,0xff,0x85,0x3b,0xa5,0x10,0x09, + 0x08,0x29,0xef,0x85,0x10,0x8d,0x0e,0xd2, + 0x68,0x40,0xa5,0x3b,0xf0,0x0b,0x85,0x3a, + 0xa5,0x10,0x29,0xf7,0x85,0x10,0x8d,0x0e, + 0xd2,0x68,0x40,0xa9,0x00,0x8d,0x17,0x03, + 0x60,0xad,0x02,0x03,0xc9,0x52,0xf0,0x0f, + 0xc9,0x50,0xf0,0x05,0xa0,0x8b,0x4c,0xda, + 0xe8,0x20,0xfd,0xea,0x4c,0xda,0xe8,0x20, + 0x0e,0xeb,0x4c,0xda,0xe8,0xa2,0x02,0x20, + 0x5a,0xee,0x20,0x4a,0xe9,0x20,0xb8,0xe9, + 0x20,0xce,0xe9,0x4c,0xda,0xe8,0xa2,0x04, + 0x20,0x5a,0xee,0xa2,0x1a,0x20,0x72,0xe9, + 0xad,0x32,0x02,0x29,0x8f,0x09,0x10,0x8d, + 0x32,0x02,0xa9,0x01,0x8d,0x17,0x03,0xa2, + 0x0e,0xa0,0x10,0x20,0x5d,0xc1,0xa9,0x10, + 0xac,0x17,0x03,0xf0,0x2b,0x2c,0x0f,0xd2, + 0xd0,0xf6,0x20,0xfa,0xeb,0x8c,0x0d,0x03, + 0x8d,0x0c,0x03,0xa9,0x10,0xa2,0x0a,0xac, + 0x17,0x03,0xf0,0x14,0x2c,0x0f,0xd2,0xf0, + 0xf6,0xca,0xf0,0x11,0xac,0x17,0x03,0xf0, + 0x07,0x2c,0x0f,0xd2,0xd0,0xf6,0xf0,0xe7, + 0xa0,0x8a,0x4c,0xda,0xe8,0x20,0xfa,0xeb, + 0x8d,0x10,0x03,0x8c,0x11,0x03,0xa2,0x83, + 0xad,0x14,0xd0,0x4a,0xd0,0x02,0xa2,0x9c, + 0x8e,0x15,0x03,0xad,0x0c,0x03,0x20,0x08, + 0xec,0x85,0x34,0xad,0x10,0x03,0x20,0x08, + 0xec,0x18,0xe5,0x34,0x85,0x34,0xa0,0x00, + 0xb0,0x01,0x88,0xad,0x11,0x03,0x38,0xed, + 0x0d,0x03,0xaa,0xf0,0x0c,0xa5,0x34,0x18, + 0x6d,0x15,0x03,0x90,0x01,0xc8,0xca,0xd0, + 0xf6,0x84,0x35,0x0a,0x26,0x35,0x85,0x34, + 0xa4,0x35,0x06,0x34,0x26,0x35,0x65,0x34, + 0xaa,0x98,0x65,0x35,0xca,0x8e,0x04,0xd2, + 0x8e,0xee,0x02,0xe8,0xd0,0x02,0xe9,0x00, + 0x8d,0x06,0xd2,0x8d,0xef,0x02,0xae,0x32, + 0x02,0x8a,0x29,0xfc,0x8d,0x0f,0xd2,0x8d, + 0x0a,0xd2,0x8e,0x0f,0xd2,0x20,0xb8,0xe9, + 0xa9,0x55,0xa0,0x00,0xa2,0x02,0x91,0x32, + 0xe6,0x32,0xd0,0x02,0xe6,0x33,0xca,0xd0, + 0xf5,0x0a,0x85,0x31,0x20,0x01,0xea,0x4c, + 0x3d,0xea,0xa4,0x14,0xad,0x0b,0xd4,0xc4, + 0x14,0xd0,0xf7,0xc9,0x7c,0xf0,0xf3,0x60, + 0x38,0xe9,0x7c,0xb0,0x03,0x6d,0x15,0x03, + 0x60,0xa9,0x80,0x8d,0xd5,0x02,0xa9,0x00, + 0x8d,0xd6,0x02,0x60,0xa9,0x31,0x8d,0x00, + 0x03,0xa9,0x0f,0x8d,0x06,0x03,0xad,0x02, + 0x03,0x8d,0x3b,0x02,0xc9,0x53,0xd0,0x20, + 0xa9,0xea,0x8d,0x04,0x03,0xa9,0x02,0x8d, + 0x05,0x03,0x0a,0x8d,0x08,0x03,0xa9,0x00, + 0x8d,0x09,0x03,0x20,0x6e,0xec,0x30,0x07, + 0xae,0xec,0x02,0x8e,0x46,0x02,0xaa,0x60, + 0xac,0xd5,0x02,0x8c,0x08,0x03,0xac,0xd6, + 0x02,0x8c,0x09,0x03,0xc9,0x50,0xf0,0x1d, + 0xc9,0x57,0xf0,0x19,0xc9,0x21,0xd0,0x06, + 0xad,0x46,0x02,0x8d,0x06,0x03,0xa9,0x40, + 0x8d,0x03,0x03,0x20,0x59,0xe4,0xad,0x02, + 0x03,0xc0,0x00,0x38,0x60,0xa9,0x80,0xd0, + 0xef,0xa9,0x1e,0x8d,0x14,0x03,0x60,0xa2, + 0x28,0xa4,0x2b,0xc0,0x53,0xd0,0x02,0xa2, + 0x1d,0x8e,0xdf,0x02,0xee,0xde,0x02,0xae, + 0xde,0x02,0x9d,0xbf,0x03,0xc9,0x9b,0xf0, + 0x10,0xec,0xdf,0x02,0xb0,0x16,0xa0,0x01, + 0x60,0xae,0xde,0x02,0xf0,0xf8,0xa9,0x9b, + 0x2c,0xa9,0x20,0x9d,0xc0,0x03,0xe8,0xec, + 0xdf,0x02,0x90,0xf7,0xa0,0x0a,0xb9,0xdd, + 0xec,0x99,0xff,0x02,0x88,0xd0,0xf7,0x8c, + 0xde,0x02,0x8e,0x08,0x03,0x8a,0x29,0x1d, + 0x49,0x4e,0x8d,0x0a,0x03,0xad,0x14,0x03, + 0x8d,0x06,0x03,0x4c,0x59,0xe4,0x40,0x01, + 0x57,0x80,0xc0,0x03,0x00,0x00,0x00,0x00, + 0xa9,0x00,0x8d,0xde,0x02,0xa2,0x09,0xbd, + 0x04,0xed,0x9d,0x00,0x03,0xca,0x10,0xf7, + 0x20,0xd5,0xec,0x30,0x06,0xad,0xec,0x02, + 0x8d,0x14,0x03,0x60,0x40,0x01,0x53,0x40, + 0xea,0x02,0x00,0x00,0x04,0x00,0xa9,0xcc, + 0x8d,0xee,0x02,0xa9,0x05,0x8d,0xef,0x02, + 0x60,0xa5,0x2b,0x85,0x3e,0xa2,0x80,0xa5, + 0x2a,0x29,0x0c,0xc9,0x04,0xf0,0x05,0xc9, + 0x08,0xf0,0x03,0x60,0xa2,0x00,0x8e,0x89, + 0x02,0xa9,0x80,0x85,0x3d,0x8d,0x8a,0x02, + 0x0a,0x85,0x3f,0x2c,0x89,0x02,0x10,0x05, + 0x06,0x3d,0x20,0x86,0xee,0x20,0x86,0xee, + 0x20,0x6b,0xfe,0x30,0x20,0x2c,0x89,0x02, + 0x10,0x08,0xa9,0xff,0x8d,0x0f,0x03,0x20, + 0x55,0xe9,0xa9,0x34,0x8d,0x02,0xd3,0xa2, + 0x00,0x2c,0x89,0x02,0x30,0x02,0xa2,0x01, + 0x20,0x60,0xee,0xa0,0x01,0x60,0xad,0x89, + 0x02,0x10,0x0a,0xa5,0x3d,0xf0,0x03,0x20, + 0xdf,0xed,0x20,0xdf,0xed,0xa9,0x3c,0x8d, + 0x02,0xd3,0xa0,0x00,0x8c,0x01,0xd2,0x8c, + 0x03,0xd2,0x8c,0x07,0xd2,0xc8,0x60,0xa5, + 0x3f,0xd0,0x1d,0xa6,0x3d,0xec,0x8a,0x02, + 0xf0,0x08,0xbd,0x00,0x04,0xe6,0x3d,0xa0, + 0x01,0x60,0x20,0x0f,0xee,0x30,0x0b,0xad, + 0xff,0x03,0xc9,0xfe,0xd0,0x05,0x85,0x3f, + 0xa0,0x88,0x60,0xa2,0x00,0x86,0x3d,0xa2, + 0x80,0xc9,0xfc,0xd0,0x06,0x8e,0x8a,0x02, + 0x4c,0x93,0xed,0xc9,0xfa,0xd0,0x05,0xae, + 0x7f,0x04,0xb0,0xf1,0xa0,0xa3,0x60,0xa6, + 0x3d,0x9d,0x00,0x04,0xe8,0x86,0x3d,0xec, + 0x8a,0x02,0xb0,0x03,0xa0,0x01,0x60,0xa9, + 0x00,0xa2,0xfe,0xa4,0x3d,0xd0,0x08,0x99, + 0x00,0x04,0xc8,0x10,0xfa,0x30,0x0c,0xa2, + 0xfc,0xcc,0x8a,0x02,0xb0,0x05,0xa2,0xfa, + 0x8c,0x7f,0x04,0x8e,0xff,0x03,0x85,0x3d, + 0xa9,0x55,0x8d,0xfd,0x03,0x8d,0xfe,0x03, + 0xa2,0x80,0xa0,0x50,0x4c,0x13,0xee,0xa2, + 0x40,0xa0,0x52,0xa9,0x34,0x8d,0x02,0xd3, + 0x8e,0x03,0x03,0x8c,0x02,0x03,0xa9,0xfd, + 0x8d,0x04,0x03,0xa9,0x03,0x8d,0x05,0x03, + 0xa9,0x83,0x8d,0x08,0x03,0xa9,0x00,0x8d, + 0x09,0x03,0xa9,0x60,0x8d,0x00,0x03,0xa9, + 0x00,0x8d,0x01,0x03,0xa5,0x3e,0x8d,0x0b, + 0x03,0x20,0x59,0xe4,0xa5,0x3e,0x30,0x0f, + 0x2c,0x89,0x02,0x10,0x05,0xa2,0x06,0x20, + 0x60,0xee,0xa9,0x3c,0x8d,0x02,0xd3,0xa4, + 0x30,0x60,0x2c,0x0b,0x03,0x10,0x01,0xe8, + 0x20,0x16,0xe9,0xbc,0x78,0xee,0xbd,0x7f, + 0xee,0xaa,0xa9,0x01,0x8d,0x17,0x03,0x20, + 0x5d,0xc1,0xad,0x17,0x03,0xd0,0xfb,0x60, + 0x80,0x40,0xb4,0x0f,0x78,0x0a,0x3c,0x04, + 0x02,0x00,0x00,0x00,0x00,0x00,0xa0,0x00, + 0x98,0xa2,0x0a,0x48,0xad,0x0b,0xd4,0xcd, + 0x0b,0xd4,0xf0,0xfb,0xca,0xd0,0xf5,0x68, + 0x49,0x08,0x8d,0x1f,0xd0,0xd0,0xea,0x88, + 0xd0,0xe7,0x60,0x5c,0x93,0x25,0x50,0x30, + 0xe4,0x43,0x40,0xe4,0x45,0x00,0xe4,0x53, + 0x10,0xe4,0x4b,0x20,0xe4,0x6c,0xfe,0xbf, + 0x78,0xd8,0xa2,0xff,0x9a,0xa0,0x8c,0xca, + 0xd0,0xfd,0x88,0xd0,0xfa,0xa2,0x02,0xbd, + 0x3d,0x03,0xdd,0xa3,0xee,0xd0,0x06,0xca, + 0x10,0xf5,0x4c,0x4e,0xef,0x78,0xd8,0xa2, + 0xff,0x9a,0xe8,0x86,0x08,0xad,0xfc,0xbf, + 0xd0,0x17,0xa2,0xff,0xec,0xff,0xbf,0xf0, + 0x10,0x8e,0xfc,0xbf,0xcd,0xfc,0xbf,0x8d, + 0xfc,0xbf,0xd0,0x05,0x2c,0xfd,0xbf,0x30, + 0xbc,0x20,0x7f,0xef,0xa9,0x04,0x2c,0x1f, + 0xd0,0xf0,0x12,0xa2,0xfd,0xad,0x12,0xd0, + 0x0a,0x4d,0x1f,0xd0,0x29,0x02,0xf0,0x02, + 0xa2,0xbf,0x8e,0x01,0xd3,0x20,0xaf,0xef, + 0xa6,0x06,0xa0,0x08,0xa9,0x00,0x85,0x66, + 0x85,0x67,0x91,0x66,0xc8,0xd0,0xfb,0xe6, + 0x67,0xca,0xd0,0xf6,0xae,0x01,0xd3,0x8a, + 0x29,0x7f,0x8d,0x01,0xd3,0x8e,0x01,0xd3, + 0xa9,0x9b,0x85,0x0a,0xa9,0xe4,0x85,0x0b, + 0xce,0x44,0x02,0xad,0x01,0xd3,0x29,0x02, + 0x8d,0xf8,0x03,0x4c,0xed,0xef,0x78,0xad, + 0x44,0x02,0xd0,0x81,0xd8,0xa2,0xff,0x9a, + 0x86,0x08,0x20,0x7f,0xef,0xad,0xf8,0x03, + 0xd0,0x05,0xa9,0xfd,0x8d,0x01,0xd3,0x20, + 0xaf,0xef,0xa2,0x60,0xa9,0x00,0x95,0x0f, + 0xca,0xd0,0xfb,0x9d,0x00,0x02,0x9d,0xed, + 0x02,0xe8,0xd0,0xf7,0x4c,0xed,0xef,0xa0, + 0x00,0x98,0x99,0x00,0xd0,0x99,0x00,0xd2, + 0x99,0x00,0xd4,0xc8,0xd0,0xf4,0xa9,0x3c, + 0xa2,0x38,0x8e,0x02,0xd3,0x8c,0x00,0xd3, + 0x8d,0x02,0xd3,0x8c,0x00,0xd3,0x8d,0x03, + 0xd3,0x88,0x8c,0x01,0xd3,0x8e,0x03,0xd3, + 0x8c,0x01,0xd3,0x8d,0x03,0xd3,0x60,0xa0, + 0x00,0x84,0x64,0xa2,0x02,0x86,0x65,0xb1, + 0x64,0x49,0xff,0x91,0x64,0xd1,0x64,0xd0, + 0x09,0x49,0xff,0x91,0x64,0xe8,0xe0,0xc0, + 0xd0,0xeb,0x86,0x06,0x60,0x55,0xc0,0x54, + 0xc0,0x54,0xc0,0x54,0xc0,0xd3,0xfe,0x48, + 0xea,0x91,0xea,0xca,0xea,0x54,0xc0,0x54, + 0xc0,0x54,0xc0,0xde,0xc1,0x0c,0xc0,0x50, + 0xc0,0x00,0x00,0x30,0x28,0xa5,0x06,0x8d, + 0xe4,0x02,0xa2,0x03,0xbd,0xa2,0xee,0x9d, + 0x3c,0x03,0xca,0xd0,0xf7,0xa9,0x02,0x85, + 0x52,0xa9,0x27,0x85,0x53,0xa2,0x00,0xad, + 0x14,0xd0,0xa0,0x06,0x29,0x0e,0xd0,0x02, + 0xe8,0x88,0x86,0x62,0x8c,0xda,0x02,0xbd, + 0xeb,0xef,0x8d,0xd9,0x02,0xa2,0x17,0xbd, + 0xcd,0xef,0x9d,0x00,0x02,0xca,0x10,0xf7, + 0xa2,0x05,0xbd,0xe5,0xef,0x9d,0x22,0x02, + 0xca,0x10,0xf7,0xa9,0x16,0x8d,0x36,0x02, + 0xa9,0xff,0x8d,0x37,0x02,0xa2,0xff,0x86, + 0x11,0xe8,0x8e,0xe5,0x02,0x8e,0xe7,0x02, + 0xa5,0x06,0x8d,0xe6,0x02,0xa2,0x07,0x8e, + 0xe8,0x02,0x20,0x11,0xec,0x20,0xc3,0xf5, + 0x20,0x41,0xfe,0x20,0x81,0xec,0xa2,0x0e, + 0xbd,0xa6,0xee,0x9d,0x1a,0x03,0xca,0x10, + 0xf7,0x20,0x6e,0xe4,0x20,0xec,0xe7,0x20, + 0x82,0xc1,0xad,0x1f,0xd0,0x29,0x01,0x49, + 0x01,0x8d,0xe9,0x03,0x20,0x5b,0xc2,0x58, + 0xa9,0x00,0x85,0x07,0xa9,0x00,0x85,0x06, + 0xad,0xfc,0xbf,0xd0,0x18,0xad,0xfb,0xbf, + 0xaa,0x49,0xff,0x8d,0xfb,0xbf,0xcd,0xfb, + 0xbf,0x8e,0xfb,0xbf,0xf0,0x07,0x20,0x2a, + 0xf1,0xa9,0x01,0x85,0x06,0xa9,0x03,0x8d, + 0x42,0x03,0xa9,0x30,0x8d,0x44,0x03,0xa9, + 0xf1,0x8d,0x45,0x03,0xa9,0x0c,0x8d,0x4a, + 0x03,0xa2,0x00,0x8e,0x4b,0x03,0x20,0x56, + 0xe4,0xa5,0x14,0xc5,0x14,0xf0,0xfc,0xa5, + 0x08,0xd0,0x0b,0xad,0xe9,0x03,0xf0,0x0f, + 0x20,0xa1,0xf1,0x4c,0xdf,0xf0,0xa9,0x02, + 0x24,0x09,0xf0,0x03,0x20,0x34,0xf1,0xa5, + 0x08,0xd0,0x10,0xa5,0x06,0xf0,0x06,0xad, + 0xfd,0xbf,0x4a,0x90,0x1b,0x20,0x38,0xf1, + 0x4c,0xfb,0xf0,0xa5,0x09,0x4a,0x90,0x10, + 0x20,0x31,0xf1,0xa5,0x08,0xd0,0x06,0x20, + 0x77,0xc4,0x4c,0x08,0xf1,0x20,0x3b,0xc4, + 0xa2,0x00,0x8e,0x44,0x02,0xa9,0x04,0xa6, + 0x06,0xf0,0x08,0x2c,0xfd,0xbf,0xf0,0x03, + 0x6c,0xfa,0xbf,0xa6,0x07,0xf0,0x08,0x2c, + 0xfd,0x9f,0xf0,0x03,0x6c,0xfa,0x9f,0x6c, + 0x0a,0x00,0x6c,0xfe,0xbf,0x6c,0xfe,0x9f, + 0x45,0x6c,0x0c,0x00,0x6c,0x02,0x00,0xea, + 0xa9,0x53,0x8d,0x02,0x03,0xa2,0x01,0x8e, + 0x01,0x03,0x20,0x53,0xe4,0x30,0x3c,0xa2, + 0x01,0x8e,0x01,0x03,0x8e,0x0a,0x03,0xca, + 0x8e,0x04,0x03,0x8e,0x0b,0x03,0xa9,0x52, + 0x8d,0x02,0x03,0xa9,0x04,0x8d,0x05,0x03, + 0x20,0x53,0xe4,0x30,0x1a,0xa2,0x0c,0x20, + 0xdc,0xf1,0x20,0x0b,0xf2,0xce,0x41,0x02, + 0xf0,0x22,0xee,0x0a,0x03,0xd0,0x03,0xee, + 0x0b,0x03,0x20,0x53,0xe4,0x10,0xeb,0xc0, + 0x8a,0xd0,0x01,0x60,0xad,0x01,0xd3,0x49, + 0x80,0x8d,0x01,0xd3,0x30,0xd7,0x20,0x02, + 0x50,0x4c,0x84,0xf1,0x20,0xf9,0xf1,0xb0, + 0xeb,0x20,0x31,0xf1,0xa9,0x01,0x85,0x09, + 0x60,0xa9,0x80,0x85,0x3e,0x20,0x7d,0xe4, + 0x20,0x7a,0xe4,0x30,0x24,0xa2,0x02,0x20, + 0xdc,0xf1,0x20,0x0b,0xf2,0x20,0x7a,0xe4, + 0x30,0x17,0xce,0x41,0x02,0xd0,0xf3,0x20, + 0xf9,0xf1,0x20,0x34,0xf1,0xa9,0x00,0x8d, + 0xe9,0x03,0xa9,0x02,0x85,0x09,0x6c,0x0a, + 0x00,0xa9,0x00,0x8d,0xe9,0x03,0x20,0x6e, + 0xed,0x4c,0x20,0xf2,0xa0,0xfc,0xb9,0x04, + 0x03,0x99,0x44,0x01,0xc8,0xd0,0xf7,0x85, + 0x16,0xad,0x42,0x02,0x85,0x15,0xad,0x04, + 0x04,0x95,0x00,0xad,0x05,0x04,0x95,0x01, + 0x60,0xad,0x42,0x02,0x18,0x69,0x06,0x85, + 0x04,0xad,0x43,0x02,0x69,0x00,0x85,0x05, + 0x6c,0x04,0x00,0xa0,0x7f,0xb9,0x00,0x04, + 0x91,0x15,0x88,0x10,0xf8,0xa5,0x15,0x49, + 0x80,0x85,0x15,0x30,0x02,0xe6,0x16,0x60, + 0xa2,0xf5,0x8a,0x48,0xbd,0x3b,0xf1,0x20, + 0xba,0xfa,0x68,0xaa,0xe8,0xd0,0xf3,0x60, + 0x42,0x4f,0x4f,0x54,0x20,0x45,0x52,0x52, + 0x4f,0x52,0x9b,0x00,0x11,0x22,0x33,0x44, + 0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc, + 0xdd,0xee,0xff,0x00,0x55,0xaa,0xff,0x00, + 0xff,0x40,0x80,0x70,0x70,0x80,0xa0,0xe0, + 0x60,0x50,0x50,0x50,0x50,0xa0,0x80,0x60, + 0x50,0xfc,0xfd,0xfe,0xfe,0xfd,0xfb,0xf7, + 0xf0,0xe1,0xe1,0xe1,0xe1,0xfb,0xfd,0xf0, + 0xe1,0x02,0x06,0x07,0x08,0x09,0x0a,0x0b, + 0x1d,0x3f,0x7f,0xbf,0xff,0x04,0x05,0x1c, + 0x3e,0x01,0x01,0x00,0x01,0x02,0x02,0x03, + 0x03,0x04,0x04,0x04,0x04,0x01,0x00,0x04, + 0x04,0x0c,0x18,0x30,0x60,0xc0,0x01,0x00, + 0x00,0x01,0x02,0x02,0x03,0x03,0x04,0x02, + 0x02,0x02,0x01,0x01,0x03,0x03,0x0a,0x14, + 0x28,0x50,0xa0,0x40,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x02,0x03,0x02,0x03, + 0x02,0x03,0x01,0x01,0x01,0x00,0x00,0x03, + 0x02,0xff,0x0f,0x03,0x01,0xff,0xf0,0xc0, + 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xa9,0x0c, + 0x85,0x2a,0xa9,0x00,0x85,0x2b,0xad,0x2f, + 0x02,0x29,0xdc,0x8d,0x2f,0x02,0x8d,0x00, + 0xd4,0xa2,0x0b,0xa9,0x00,0x95,0x54,0x9d, + 0x90,0x02,0xca,0xd0,0xf8,0x86,0x7b,0xa5, + 0x2b,0x29,0x0f,0x85,0x57,0xaa,0xbd,0x71, + 0xf2,0x4d,0x6f,0x02,0x29,0xc0,0x4d,0x6f, + 0x02,0x8d,0x6f,0x02,0xc9,0x40,0x8a,0xf0, + 0x06,0xa5,0x2a,0x90,0x02,0x29,0xef,0x0a, + 0x0a,0x85,0x68,0xbc,0x81,0xf2,0xbe,0x91, + 0xf2,0x0a,0x10,0x03,0xbe,0xa6,0xf2,0x86, + 0x69,0xa5,0x6a,0xa6,0x57,0x18,0x7d,0x61, + 0xf2,0xb0,0x09,0x8a,0xf0,0x03,0x20,0xee, + 0xf3,0xa0,0x93,0x60,0x85,0x59,0xbc,0x51, + 0xf2,0x84,0x58,0xbd,0x71,0xf2,0xa6,0x59, + 0x29,0x30,0xf0,0x03,0xa0,0x00,0xca,0x84, + 0x70,0x8e,0xe6,0x02,0x86,0x71,0x8e,0x31, + 0x02,0xc9,0x20,0xa9,0xf8,0x90,0x02,0xa9, + 0xf5,0xe5,0x69,0x24,0x68,0x50,0x02,0xe9, + 0x06,0xa0,0x01,0xcc,0x6e,0x02,0x65,0x70, + 0x8d,0xe5,0x02,0x85,0x70,0x8d,0x30,0x02, + 0xe4,0x0f,0x90,0xb7,0xd0,0x04,0xc5,0x0e, + 0x90,0xb1,0xce,0xe5,0x02,0xa6,0x6a,0xca, + 0x8e,0x95,0x02,0xa9,0x60,0x8d,0x94,0x02, + 0x08,0x78,0x0a,0x05,0x10,0x85,0x10,0x8d, + 0x0e,0xd2,0x28,0xa0,0x18,0x8c,0xbf,0x02, + 0xa0,0x05,0xb9,0xba,0xf5,0x99,0xc3,0x02, + 0x88,0xd0,0xf7,0x8c,0xf0,0x02,0xa9,0x70, + 0xa2,0x03,0x20,0x84,0xf5,0xa5,0x57,0xc9, + 0x0b,0xd0,0x05,0xa9,0x06,0x8d,0xc8,0x02, + 0x20,0x3a,0xf5,0x84,0x7e,0x20,0xb4,0xf5, + 0x24,0x68,0x50,0x12,0xa2,0x04,0x8e,0xbf, + 0x02,0x20,0x40,0xf9,0xa4,0x7e,0x20,0x3a, + 0xf5,0x84,0x7e,0x20,0xb4,0xf5,0xa9,0x02, + 0x8d,0xf3,0x02,0xa2,0x0f,0x4a,0x9d,0xa2, + 0x02,0xca,0xd0,0xfa,0x86,0x6b,0xa2,0xe0, + 0x8e,0xf4,0x02,0x24,0x68,0xd0,0x02,0xa2, + 0x40,0x8e,0x0e,0xd4,0xa4,0x7e,0xa2,0x70, + 0xa9,0x41,0x20,0xa6,0xf5,0xad,0x2f,0x02, + 0x09,0x22,0x8d,0x2f,0x02,0xa5,0x14,0xc5, + 0x14,0xf0,0xfc,0xa5,0x2b,0x29,0x0f,0xd0, + 0x03,0x20,0xb4,0xf6,0x20,0x9e,0xfd,0xa2, + 0x00,0x60,0xa6,0x57,0xbd,0x71,0xf2,0x29, + 0x0f,0xa6,0x57,0xd0,0x07,0xae,0x6e,0x02, + 0xf0,0x02,0x09,0x20,0x48,0x09,0x40,0xa2, + 0x58,0x20,0xa6,0xf5,0xa6,0x69,0xa5,0x57, + 0xd0,0x03,0xae,0xbf,0x02,0xca,0x68,0xc9, + 0x22,0xf0,0x28,0xc9,0x0e,0x90,0x1d,0xa2, + 0x5d,0x20,0x84,0xf5,0x48,0x09,0x40,0x91, + 0x70,0xc8,0xa9,0x00,0x91,0x70,0xc8,0xa5, + 0x59,0x69,0x0e,0x91,0x70,0xc8,0xa5,0x69, + 0xe9,0x5e,0xaa,0x68,0x91,0x70,0xc8,0xca, + 0xd0,0xfa,0x60,0xca,0x20,0x84,0xf5,0x09, + 0x80,0x91,0x70,0xc8,0x29,0x5f,0x91,0x70, + 0xc8,0xe6,0x68,0xa2,0xe0,0xa9,0xfd,0x8e, + 0x00,0x02,0x8d,0x01,0x02,0x60,0x91,0x70, + 0xc8,0xb5,0x00,0x91,0x70,0xc8,0xb5,0x01, + 0xa2,0x01,0xd0,0xd0,0x24,0x68,0x30,0xd2, + 0x4c,0x49,0xf8,0x28,0xca,0x94,0x46,0x00, + 0x01,0x03,0x07,0xad,0xe6,0x02,0x85,0x6a, + 0xa9,0x00,0x85,0x4f,0xa9,0xfe,0x85,0x4e, + 0x60,0x20,0xf9,0xf8,0x30,0x3a,0xa4,0x54, + 0x20,0x78,0xf9,0xa5,0x55,0xa6,0x57,0xbc, + 0xb1,0xf2,0x59,0xbf,0xf5,0xaa,0xa5,0x56, + 0x20,0xc0,0xf9,0xa4,0x6f,0xb1,0x66,0x20, + 0xad,0xf9,0x0a,0x08,0x10,0x02,0x49,0x40, + 0x69,0x40,0x28,0x6a,0xa6,0x57,0xbc,0xb1, + 0xf2,0x39,0xc1,0xf2,0xa6,0x57,0xf0,0x03, + 0x4c,0xd8,0xf9,0x20,0x0a,0xfe,0xa0,0x01, + 0x60,0x8d,0xfb,0x02,0x20,0xf9,0xf8,0x30, + 0x0c,0xad,0xfb,0x02,0xc9,0x7d,0xd0,0x0e, + 0x20,0x49,0xf8,0xa0,0x01,0x60,0x4c,0xf1, + 0xf9,0x20,0xf9,0xf8,0x30,0xf7,0x20,0x00, + 0xfe,0xad,0xfb,0x02,0xa6,0x57,0xf0,0x1e, + 0xc9,0x9b,0xf0,0xea,0xae,0xff,0x02,0xd0, + 0xfb,0x20,0xcd,0xf6,0x48,0x20,0xa8,0xf9, + 0x68,0xa4,0x6f,0x51,0x66,0x25,0x6e,0x51, + 0x66,0x91,0x66,0x4c,0xd8,0xf9,0xc9,0x9b, + 0xd0,0x18,0xa5,0x52,0x85,0x55,0xe6,0x54, + 0xa5,0x54,0xcd,0xbf,0x02,0x90,0x08,0xae, + 0xbf,0x02,0x86,0x54,0x20,0xd3,0xfc,0x4c, + 0xb4,0xf6,0xae,0xff,0x02,0xd0,0xfb,0x48, + 0x20,0xc7,0xfc,0x68,0x20,0xea,0xf6,0xa0, + 0x00,0x91,0x5e,0xe6,0x5e,0xd0,0x02,0xe6, + 0x5f,0x20,0x0a,0xfe,0xb0,0x29,0xa5,0x54, + 0xcd,0xbf,0x02,0x90,0x12,0x20,0xd3,0xfc, + 0x20,0xba,0xf6,0x20,0x76,0xfd,0x59,0xb2, + 0x02,0x99,0xb2,0x02,0x4c,0xb4,0xf6,0x20, + 0xba,0xf6,0xa5,0x54,0x20,0x85,0xfd,0xf0, + 0x03,0x20,0x8c,0xf8,0x20,0xc7,0xfc,0x4c, + 0x19,0xfe,0xa6,0x54,0xca,0x8a,0x20,0x8e, + 0xfd,0x18,0x69,0x02,0xc5,0x54,0x90,0x01, + 0x60,0x68,0x68,0x90,0xe7,0xa6,0x57,0xbc, + 0xb1,0xf2,0xbe,0xc5,0xf2,0x86,0x77,0xbe, + 0xc1,0xf2,0x8e,0xa0,0x02,0x30,0x0b,0x2d, + 0xa0,0x02,0x19,0xdc,0xfd,0xaa,0xbd,0x3b, + 0xf2,0x60,0x0a,0x08,0xe9,0x3f,0x10,0x02, + 0x49,0x40,0x28,0x6a,0x60,0xa5,0x22,0xc9, + 0x11,0xf0,0x05,0xc9,0x12,0xf0,0x01,0x60, + 0xad,0xfd,0x02,0x20,0xcd,0xf6,0x8d,0xbc, + 0x02,0xad,0xfb,0x02,0x20,0xcd,0xf6,0x85, + 0x51,0x20,0xa8,0xf9,0xa0,0x01,0x20,0x82, + 0xf9,0x85,0x78,0xaa,0xa0,0x00,0xa5,0x54, + 0x38,0xe5,0x5a,0xb0,0x0c,0x49,0xff,0x69, + 0x01,0x48,0x8a,0x49,0xff,0xaa,0xe8,0x88, + 0x68,0x86,0x70,0x85,0x76,0x84,0x71,0xa2, + 0x00,0xa5,0x55,0x38,0xe5,0x5b,0x85,0x72, + 0xa5,0x56,0xe5,0x5c,0xb0,0x10,0x49,0xff, + 0xa8,0xa5,0x72,0x49,0xff,0x69,0x01,0x85, + 0x72,0x98,0x69,0x00,0xa2,0xcc,0x85,0x73, + 0x8a,0xa6,0x57,0xbc,0xb1,0xf2,0x18,0x79, + 0xac,0xf7,0x85,0x64,0xa9,0xf7,0x85,0x65, + 0x85,0x75,0xb9,0xac,0xf7,0x18,0x69,0xd9, + 0x85,0x74,0xa6,0x72,0x8a,0x38,0xe5,0x76, + 0x85,0x68,0xa4,0x73,0x98,0xe9,0x00,0x85, + 0x69,0xb0,0x04,0xa0,0x00,0xa6,0x76,0x86, + 0x7e,0x84,0x7f,0x98,0xd0,0x03,0x8a,0xf0, + 0x0d,0x4c,0x01,0xf8,0x20,0x00,0xfe,0xa4, + 0x57,0xd0,0x03,0x20,0xc7,0xfc,0xa0,0x01, + 0x60,0x86,0x6e,0x4c,0x01,0xf8,0xa4,0x6f, + 0xa6,0x6e,0xd0,0x33,0xea,0xe4,0xe6,0xe7, + 0x0a,0x0a,0x0a,0x0a,0x90,0x05,0xc6,0x6f, + 0xad,0xa0,0x02,0xd0,0x31,0x4a,0x4a,0x4a, + 0x4a,0x90,0x09,0xa5,0x77,0xc8,0xc4,0x78, + 0x90,0x02,0xa0,0x00,0x85,0x6e,0xf0,0xd1, + 0xb1,0x66,0x24,0x6e,0xd0,0xcb,0x4d,0xbc, + 0x02,0x25,0x6e,0x51,0x66,0x91,0x66,0xa5, + 0x6e,0x6c,0x74,0x00,0x4a,0x4a,0x4a,0x4a, + 0x90,0x04,0xe6,0x6f,0xa5,0x77,0x85,0x6e, + 0xa4,0x6f,0xa5,0x51,0x51,0x66,0x25,0x6e, + 0x51,0x66,0x91,0x66,0xa5,0x22,0x4a,0x90, + 0xa5,0xa5,0x7e,0xd0,0x04,0xc6,0x7f,0x30, + 0x8b,0xc6,0x7e,0xa5,0x68,0x0a,0xa8,0xa5, + 0x69,0x2a,0xaa,0x98,0x18,0xe5,0x72,0x8a, + 0x48,0xe5,0x73,0x10,0x13,0xa2,0x02,0xb5, + 0x70,0x18,0x75,0x66,0x95,0x66,0xb5,0x71, + 0x75,0x67,0x95,0x67,0xca,0xca,0x10,0xef, + 0x98,0x18,0x65,0x76,0x68,0x69,0x00,0x30, + 0xb7,0xa5,0x68,0x38,0xe5,0x76,0x85,0x68, + 0xb0,0x02,0xc6,0x69,0xa5,0x6e,0x6c,0x64, + 0x00,0xa0,0x04,0xa6,0x7b,0xd0,0x08,0xa4, + 0x57,0xbe,0x81,0xf2,0xbc,0x91,0xf2,0x20, + 0x82,0xf9,0x18,0xa6,0x57,0xf0,0x02,0x69, + 0xa0,0xa8,0xa5,0x65,0x69,0x00,0xaa,0x65, + 0x59,0x85,0x67,0xa5,0x58,0x85,0x66,0xa9, + 0x00,0x88,0x91,0x66,0xd0,0xfb,0xc6,0x67, + 0xca,0x10,0xf6,0x85,0x56,0x85,0x54,0x85, + 0x5d,0xa6,0x57,0xd0,0x02,0xa5,0x52,0x85, + 0x55,0x4c,0xed,0xfd,0x18,0x08,0xac,0xbf, + 0x02,0x88,0x20,0x78,0xf9,0x20,0xc7,0xfd, + 0xae,0xbf,0x02,0xd0,0x09,0xa0,0x27,0xb1, + 0x68,0x91,0x66,0x88,0x10,0xf9,0xa5,0x68, + 0x85,0x66,0x38,0xe9,0x28,0x85,0x68,0xa5, + 0x69,0x85,0x67,0xe9,0x00,0x85,0x69,0xca, + 0xe4,0x54,0xd0,0xe1,0xa0,0x27,0xa9,0x00, + 0x91,0x66,0x88,0x10,0xfb,0x20,0x76,0xfd, + 0x28,0xb0,0x02,0xa9,0x00,0x85,0x51,0xa9, + 0x00,0x38,0xfd,0xc1,0xe4,0x0a,0x39,0xb2, + 0x02,0x18,0x79,0xb2,0x02,0x6a,0x05,0x51, + 0x99,0xb2,0x02,0x88,0x10,0x03,0x6e,0xb3, + 0x02,0x88,0x10,0x03,0x6e,0xb4,0x02,0x60, + 0x48,0xa0,0x00,0xa5,0x5d,0x91,0x5e,0x68, + 0x60,0xad,0xbf,0x02,0xa6,0x57,0xd0,0x04, + 0x24,0x7b,0x30,0x06,0xbc,0x81,0xf2,0xb9, + 0x91,0xf2,0xa0,0x27,0xc4,0x53,0xb0,0x02, + 0x84,0x53,0x18,0xe5,0x54,0xb0,0x0e,0xa0, + 0x00,0x84,0x56,0x8a,0xd0,0x02,0xa4,0x52, + 0x84,0x55,0xa0,0x8d,0x60,0xbc,0x96,0xf2, + 0xa5,0x55,0xd9,0xa7,0xf2,0xa5,0x56,0xf9, + 0xac,0xf2,0xb0,0xe3,0xa0,0xff,0xa5,0x11, + 0xd0,0x04,0x84,0x11,0xa0,0x7f,0xc8,0x60, + 0xa0,0x17,0xcc,0xbf,0x02,0x48,0xa9,0x00, + 0x65,0x7b,0xf0,0x14,0xa2,0x0b,0xb5,0x54, + 0xbc,0x90,0x02,0x94,0x54,0x9d,0x90,0x02, + 0xca,0x10,0xf3,0x8a,0x45,0x7b,0x85,0x7b, + 0x68,0x60,0x20,0x82,0xf9,0x85,0x64,0x8a, + 0x18,0x65,0x64,0x90,0x02,0xe6,0x65,0x18, + 0x65,0x58,0xaa,0xa5,0x65,0x65,0x59,0x60, + 0xa2,0x00,0x20,0x62,0xf9,0x86,0x66,0x85, + 0x67,0x60,0xa9,0x00,0x85,0x65,0x84,0x64, + 0xa4,0x57,0xb9,0x96,0xf2,0x38,0xf9,0xb1, + 0xf2,0xa8,0xc8,0xa5,0x64,0x0a,0x26,0x65, + 0x0a,0x26,0x65,0x65,0x64,0x90,0x02,0xe6, + 0x65,0x0a,0x26,0x65,0x88,0x10,0xfa,0x60, + 0x20,0xb7,0xf9,0xa5,0x77,0xca,0x30,0x04, + 0x4a,0xca,0x10,0xfc,0x85,0x6e,0x60,0xa4, + 0x5a,0x20,0x78,0xf9,0xa5,0x5c,0xa6,0x5b, + 0x6a,0x86,0x6f,0xa9,0x00,0xa6,0x57,0xbc, + 0xb1,0xf2,0xf0,0x06,0x66,0x6f,0x6a,0x88, + 0xd0,0xfa,0x2a,0x2a,0x2a,0x2a,0xaa,0x60, + 0xe6,0x55,0xd0,0x02,0xe6,0x56,0xa6,0x57, + 0xbc,0x96,0xf2,0xbe,0xac,0xf2,0xe4,0x56, + 0xd0,0x0f,0xbe,0xa7,0xf2,0xe4,0x55,0xd0, + 0x08,0xa0,0x00,0x84,0x55,0x84,0x56,0xe6, + 0x54,0xa0,0x01,0x60,0x20,0xed,0xfd,0x8e, + 0xfe,0x02,0x8e,0xa2,0x02,0x4c,0xf2,0xf3, + 0xa5,0x6b,0xd0,0x06,0x20,0x28,0xfa,0x10, + 0x01,0x60,0x20,0x40,0xf9,0xc6,0x6b,0xd0, + 0x09,0xa9,0x9b,0x20,0x11,0xf6,0xa9,0x9b, + 0xd0,0x03,0x20,0xd1,0xf5,0x4c,0xa0,0xfd, + 0x20,0x40,0xf9,0xa5,0x55,0x85,0x6d,0xa5, + 0x54,0x85,0x6c,0x20,0xa0,0xfd,0xa5,0x2a, + 0x4a,0xb0,0x25,0x20,0x6b,0xfe,0x10,0x01, + 0x60,0xc9,0x9b,0xf0,0x1d,0x20,0xba,0xfa, + 0x30,0xf6,0xa5,0x55,0xc9,0x21,0xd0,0xeb, + 0x20,0x8c,0xfd,0x18,0x69,0x02,0xc5,0x54, + 0xd0,0xe1,0x20,0x6e,0xfb,0x4c,0x3b,0xfa, + 0xa9,0x9b,0x20,0xba,0xfa,0x30,0xd9,0x20, + 0x40,0xf9,0x20,0xf0,0xf8,0xa2,0x00,0x86, + 0x63,0xa4,0x6c,0x84,0x54,0x20,0x7a,0xf9, + 0xa4,0x6d,0xe6,0x63,0xb1,0x66,0xf0,0x04, + 0xa5,0x63,0x85,0x6b,0xc4,0x53,0xc8,0x90, + 0xf1,0x20,0xc7,0xfd,0xe6,0x54,0xa5,0x54, + 0xcd,0xbf,0x02,0xb0,0x0a,0x20,0x85,0xfd, + 0xd0,0x08,0xa4,0x52,0x4c,0x7a,0xfa,0x20, + 0xd3,0xfc,0xe6,0x6b,0xa5,0x54,0x20,0x78, + 0xfd,0x19,0xb2,0x02,0x99,0xb2,0x02,0xa6, + 0x6d,0x86,0x55,0xa4,0x6c,0x84,0x54,0x4c, + 0x9e,0xfd,0xa4,0x57,0xf0,0x0c,0xac,0xbf, + 0x02,0xc0,0x04,0xf0,0x05,0x48,0x20,0xee, + 0xf3,0x68,0x20,0x40,0xf9,0x20,0xf0,0xf8, + 0xa8,0x0e,0xa2,0x02,0xb0,0x1e,0x29,0x1f, + 0xc9,0x1b,0x90,0x18,0xa2,0x0e,0x98,0x20, + 0xbe,0xfc,0xd0,0x10,0xad,0xfe,0x02,0xd0, + 0x0b,0x20,0x69,0xfc,0x20,0xc7,0xfc,0x20, + 0x19,0xfe,0x10,0x06,0x8c,0xfb,0x02,0x20, + 0x29,0xf6,0xad,0xfb,0x02,0x4c,0xa0,0xfd, + 0x1b,0x1c,0x1d,0x1e,0x1f,0x7d,0x7e,0x7f, + 0x9c,0x9d,0x9e,0x9f,0xfd,0xfe,0xff,0x9b, + 0x1e,0x27,0x31,0xc7,0xd4,0x24,0x4c,0x8d, + 0xdd,0xe3,0x7a,0x72,0x6d,0xea,0xf6,0xa9, + 0x80,0x8d,0xa2,0x02,0x60,0x4c,0x49,0xf8, + 0xa6,0x54,0xd0,0x03,0xae,0xbf,0x02,0xca, + 0x10,0x0a,0xa6,0x54,0xe8,0xec,0xbf,0x02, + 0x90,0x02,0xa2,0x00,0x86,0x54,0x8a,0x20, + 0x8e,0xfd,0xc5,0x6c,0xf0,0x06,0x85,0x6c, + 0xa5,0x52,0x85,0x6d,0x60,0xa5,0x52,0xc5, + 0x55,0xb0,0x0b,0xc6,0x55,0x20,0xc7,0xfc, + 0xa0,0x00,0x98,0x91,0x5e,0x60,0xa5,0x54, + 0x20,0x85,0xfd,0xd0,0xf8,0xc6,0x54,0xa5, + 0x53,0x85,0x55,0x4c,0x55,0xfb,0xa0,0x00, + 0x4c,0xcc,0xe4,0x20,0x87,0xfb,0x1d,0xa3, + 0x02,0xd0,0x08,0x20,0x87,0xfb,0x49,0xff, + 0x3d,0xa3,0x02,0x9d,0xa3,0x02,0x60,0x20, + 0xa9,0xfd,0xa8,0x4c,0xb8,0xfd,0x20,0xa9, + 0xfd,0xa8,0x8a,0x38,0x65,0x54,0x85,0x54, + 0xc8,0xc0,0x78,0xb0,0x08,0x20,0xb8,0xfd, + 0x3d,0xa3,0x02,0xf0,0xf3,0x84,0x55,0xa5, + 0x55,0x38,0xe9,0x28,0x90,0x19,0x85,0x55, + 0xe6,0x54,0xa5,0x54,0xcd,0xbf,0x02,0xb0, + 0x07,0x20,0x85,0xfd,0xf0,0xe9,0x10,0x03, + 0x20,0xd3,0xfc,0xa6,0x52,0x86,0x55,0x60, + 0xa6,0x52,0xe4,0x55,0xb0,0x03,0xc6,0x55, + 0x60,0xa6,0x53,0xb0,0xf0,0xa6,0x55,0xe4, + 0x53,0xb0,0xe8,0xe6,0x55,0x60,0x20,0x8c, + 0xfd,0x4c,0xd5,0xfc,0x38,0x20,0x8d,0xf8, + 0x4c,0xc3,0xfb,0xa4,0x54,0x84,0x51,0x20, + 0x78,0xf9,0xa4,0x55,0x4c,0x82,0xfc,0x20, + 0x8c,0xfd,0x18,0x69,0x03,0x85,0x76,0xa4, + 0x54,0x84,0x51,0x20,0x78,0xf9,0xa4,0x55, + 0xa2,0x00,0xf0,0x04,0xa4,0x52,0xa6,0x50, + 0x84,0x65,0xa4,0x53,0xb1,0x66,0x85,0x50, + 0x88,0xb1,0x66,0xc8,0x91,0x66,0x88,0xc4, + 0x65,0xd0,0xf5,0x8a,0x91,0x66,0xe6,0x51, + 0x20,0xc7,0xfd,0xa5,0x51,0xcd,0xbf,0x02, + 0xb0,0x05,0x20,0x85,0xfd,0xf0,0xd5,0xa5, + 0x50,0xf0,0x2d,0xa5,0x54,0x48,0xa6,0x51, + 0xe4,0x76,0x08,0x86,0x54,0xa9,0x00,0x85, + 0x76,0xec,0xbf,0x02,0x90,0x03,0x20,0xd3, + 0xfc,0x28,0xb0,0x0e,0x20,0x8c,0xf8,0xa4, + 0x54,0x20,0x78,0xf9,0xa5,0x50,0xa4,0x52, + 0x91,0x66,0x68,0x38,0xe5,0x76,0x85,0x54, + 0x60,0xa9,0xfb,0x48,0xbd,0x10,0xfb,0x48, + 0x60,0xa4,0x52,0xb1,0x66,0xa4,0x53,0x91, + 0x68,0xa4,0x52,0xc8,0xb1,0x66,0x88,0x91, + 0x66,0xc8,0xc4,0x53,0xd0,0xf5,0x20,0xc7, + 0xfd,0xa6,0x51,0xe8,0xec,0xbf,0x02,0xb0, + 0x08,0x86,0x51,0x8a,0x20,0x85,0xfd,0xf0, + 0xd8,0xa4,0x53,0xa9,0x00,0x91,0x68,0xc4, + 0x52,0xf0,0x06,0x88,0xb1,0x68,0xf0,0xf7, + 0x60,0xc6,0x51,0xa5,0x51,0x20,0x85,0xfd, + 0xd0,0x0b,0xa5,0x55,0x48,0xa5,0x51,0x20, + 0xd5,0xfc,0x68,0x85,0x55,0x60,0xdd,0x00, + 0xfb,0xf0,0x03,0xca,0x10,0xf8,0x60,0xa6, + 0x55,0xa4,0x54,0x20,0x62,0xf9,0x86,0x5e, + 0x85,0x5f,0x60,0xa9,0x00,0x85,0x51,0xa2, + 0x00,0x86,0x76,0xa4,0x51,0x38,0xd0,0x21, + 0xae,0x6e,0x02,0xf0,0x1c,0xa2,0x00,0xa5, + 0x14,0xc5,0x14,0xf0,0xfc,0xe8,0x8e,0x05, + 0xd4,0xe0,0x07,0xd0,0xf2,0xa9,0x10,0xcd, + 0x0b,0xd4,0x90,0xfb,0xcd,0x0b,0xd4,0xb0, + 0xfb,0x08,0x20,0x78,0xf9,0xa6,0x51,0x10, + 0x0c,0x20,0xc7,0xfd,0xa0,0x27,0xb1,0x66, + 0x91,0x68,0x88,0x10,0xf9,0xe8,0xec,0xbf, + 0x02,0xd0,0xee,0xa0,0x27,0xa9,0x00,0x91, + 0x66,0x88,0x10,0xfb,0x28,0xb0,0x03,0x8d, + 0x05,0xd4,0x20,0x5f,0xfd,0xa5,0x51,0x20, + 0x78,0xfd,0xbe,0x5c,0xfd,0x38,0xf0,0x09, + 0x2e,0xb4,0x02,0xca,0xf0,0x03,0x2e,0xb3, + 0x02,0x85,0x64,0x49,0xff,0x39,0xb2,0x02, + 0x85,0x65,0xc6,0x64,0x25,0x64,0x65,0x65, + 0x99,0xb2,0x02,0xe6,0x76,0xe6,0x64,0x24, + 0x64,0xf0,0x80,0x60,0x02,0x01,0x00,0xa5, + 0x52,0xa2,0x6c,0x20,0x68,0xfd,0xa2,0x54, + 0xb4,0x00,0xc4,0x51,0x90,0x07,0xd0,0x03, + 0x95,0x01,0x60,0xd6,0x00,0x60,0xa5,0x54, + 0x48,0x4a,0x4a,0x4a,0xa8,0x68,0x29,0x07, + 0xaa,0xbd,0xc1,0xe4,0x60,0x20,0x78,0xfd, + 0x39,0xb2,0x02,0x60,0xa5,0x54,0x85,0x64, + 0xa5,0x64,0x20,0x85,0xfd,0xd0,0x04,0xc6, + 0x64,0xd0,0xf5,0xa5,0x64,0x60,0xa0,0x01, + 0x84,0x64,0x18,0x20,0x45,0xf9,0xa4,0x64, + 0x60,0xa5,0x54,0x20,0x8e,0xfd,0x18,0xe5, + 0x54,0xaa,0xbd,0xdd,0xfc,0x65,0x55,0x60, + 0x98,0x29,0x07,0xaa,0xbd,0xc1,0xe4,0x48, + 0x98,0x4a,0x4a,0x4a,0xaa,0x68,0x60,0xa5, + 0x66,0x85,0x68,0x18,0x69,0x28,0x85,0x66, + 0xa5,0x67,0x85,0x69,0x69,0x00,0x85,0x67, + 0x60,0x78,0x50,0x28,0x00,0x00,0x10,0x14, + 0x48,0xad,0xc6,0x02,0x45,0x4f,0x25,0x4e, + 0x8d,0x17,0xd0,0x68,0x40,0xa2,0xff,0x8e, + 0xb2,0x02,0x8e,0xb3,0x02,0x8e,0xb4,0x02, + 0xe8,0x86,0x6c,0xa5,0x52,0x85,0x6d,0x60, + 0xa2,0x02,0xb5,0x54,0x95,0x5a,0xca,0x10, + 0xf9,0x60,0xe6,0x55,0xa6,0x53,0xe4,0x55, + 0xb0,0x06,0xa6,0x52,0x86,0x55,0xe6,0x54, + 0x60,0xa0,0x00,0xb1,0x5e,0x85,0x5d,0xae, + 0xf0,0x02,0xd0,0x04,0x49,0x80,0x91,0x5e, + 0xc8,0x60,0x2c,0x6e,0x02,0x30,0x03,0xa0, + 0x01,0x60,0xa9,0x40,0x8d,0x0e,0xd4,0xa2, + 0x55,0xa9,0xc0,0x20,0x9f,0xf5,0x4c,0xee, + 0xf3,0xa2,0xff,0x8e,0xfc,0x02,0x8e,0xf2, + 0x02,0xe8,0x8e,0xf1,0x02,0x8e,0xb6,0x02, + 0xa9,0x40,0x8d,0xbe,0x02,0xa9,0x22,0x85, + 0x79,0xa9,0xff,0x85,0x7a,0x60,0xae,0xbe, + 0x02,0xd0,0x02,0xa0,0x40,0x98,0x29,0xc0, + 0x8d,0xbe,0x02,0xa2,0xff,0xa5,0x11,0xf0, + 0x5a,0xad,0xfc,0x02,0xc9,0xff,0xf0,0xf5, + 0x8e,0xfc,0x02,0xac,0xdb,0x02,0xd0,0x05, + 0xa0,0x0c,0x20,0xcc,0xe4,0xc9,0xc0,0xb0, + 0xe2,0xa8,0xb1,0x79,0x10,0x10,0xc9,0x81, + 0x90,0xd9,0xf0,0x2d,0xc9,0x83,0x90,0xc6, + 0xc9,0x85,0x90,0xc9,0xf0,0x32,0xc9,0x61, + 0x90,0x0f,0xc9,0x7b,0xb0,0x0b,0x2c,0xbe, + 0x02,0x70,0x04,0x10,0x04,0x29,0x1f,0x29, + 0xdf,0xa2,0x0f,0x20,0xbe,0xfc,0xf0,0x03, + 0x4d,0xb6,0x02,0x8d,0xfb,0x02,0xa0,0x01, + 0x60,0xad,0xb6,0x02,0x49,0x80,0x8d,0xb6, + 0x02,0xb0,0xa0,0x86,0x11,0xa0,0x80,0x60, + 0xa0,0x88,0x60,0xad,0xd9,0x02,0x8d,0x2b, + 0x02,0xad,0x09,0xd2,0x48,0x29,0x3f,0xc9, + 0x11,0xd0,0x06,0x68,0x8d,0xdc,0x02,0xd0, + 0x1c,0x68,0xcd,0xf2,0x02,0xd0,0x08,0xad, + 0xf1,0x02,0xd0,0x16,0xad,0xf2,0x02,0xc9, + 0x9f,0xf0,0x11,0x8d,0xfc,0x02,0x8d,0xf2, + 0x02,0xa9,0x00,0x85,0x4d,0xa9,0x03,0x8d, + 0xf1,0x02,0x68,0x40,0xad,0xff,0x02,0x49, + 0xff,0x8d,0xff,0x02,0xb0,0xef,0xa9,0x00, + 0x85,0x11,0x8d,0xff,0x02,0x8d,0xf0,0x02, + 0x68,0x40,0x6c,0x6a,0x3b,0x80,0x80,0x6b, + 0x2b,0x2a,0x6f,0x80,0x70,0x75,0x9b,0x69, + 0x2d,0x3d,0x76,0x80,0x63,0x80,0x80,0x62, + 0x78,0x7a,0x34,0x80,0x33,0x36,0x1b,0x35, + 0x32,0x31,0x2c,0x20,0x2e,0x6e,0x80,0x6d, + 0x2f,0x81,0x72,0x80,0x65,0x79,0x7f,0x74, + 0x77,0x71,0x39,0x80,0x30,0x37,0x7e,0x38, + 0x3c,0x3e,0x66,0x68,0x64,0x80,0x82,0x67, + 0x73,0x61,0x4c,0x4a,0x3a,0x80,0x80,0x4b, + 0x5c,0x5e,0x4f,0x80,0x50,0x55,0x9b,0x49, + 0x5f,0x7c,0x56,0x80,0x43,0x80,0x80,0x42, + 0x58,0x5a,0x24,0x80,0x23,0x26,0x1b,0x25, + 0x22,0x21,0x5b,0x20,0x5d,0x4e,0x80,0x4d, + 0x3f,0x80,0x52,0x80,0x45,0x59,0x9f,0x54, + 0x57,0x51,0x28,0x80,0x29,0x27,0x9c,0x40, + 0x7d,0x9d,0x46,0x48,0x44,0x80,0x83,0x47, + 0x53,0x41,0x0c,0x0a,0x7b,0x80,0x80,0x0b, + 0x1e,0x1f,0x0f,0x80,0x10,0x15,0x9b,0x09, + 0x1c,0x1d,0x16,0x80,0x03,0x80,0x80,0x02, + 0x18,0x1a,0x80,0x80,0x85,0x80,0x1b,0x80, + 0xfd,0x80,0x00,0x20,0x60,0x0e,0x80,0x0d, + 0x80,0x80,0x12,0x80,0x05,0x19,0x9e,0x14, + 0x17,0x11,0x80,0x80,0x80,0x80,0xfe,0x80, + 0x7d,0xff,0x06,0x08,0x04,0x80,0x84,0x07, + 0x13,0x01,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x01, + 0x13,0x02,0x43,0x58,0x00,0x00,0x00,0x00, + 0x00,0x00,0x8e,0xc1,0xb8,0xee,0xa2,0xc1 +}; diff --git a/atari800/src/roms/altirraos_xl.h b/atari800/src/roms/altirraos_xl.h new file mode 100644 index 0000000..9c5fba0 --- /dev/null +++ b/atari800/src/roms/altirraos_xl.h @@ -0,0 +1,8 @@ +#ifndef ROMS_ALTIRRAOS_XL_H_ +#define ROMS_ALTIRRAOS_XL_H_ + +#include "atari.h" + +extern UBYTE const ROM_altirraos_xl[0x4000]; + +#endif /* ROMS_ALTIRRAOS_XL_H_ */ diff --git a/atari800/src/sio.c b/atari800/src/sio.c index cefe3d6..ec87286 100644 --- a/atari800/src/sio.c +++ b/atari800/src/sio.c @@ -1259,6 +1259,7 @@ void SIO_Handler(void) else result = 'E'; break; + case 0x50: /* put (used by AltirraOS) */ case 0x57: /* write */ /* add pregap length */ CASSETTE_AddGap(gaps == 0 ? 3000 : 260); @@ -1678,6 +1679,48 @@ int SIO_RotateDisks(void) #ifndef BASIC +#if defined(__LIBRETRO__) +void Retro_SIO_StateSave(void) +{ + int i; + + for (i = 0; i < 8; i++) { + Retro_SaveINT((int*)&SIO_drive_status[i], 1); + Retro_SaveFNAME(SIO_filename[i]); + } +} + +void Retro_SIO_StateRead(void) +{ + int i; + + for (i = 0; i < 8; i++) { + int saved_drive_status; + char filename[FILENAME_MAX]; + + Retro_ReadINT(&saved_drive_status, 1); + SIO_drive_status[i] = (SIO_UnitStatus)saved_drive_status; + + Retro_ReadFNAME(filename); + if (filename[0] == 0) + continue; + + /* If the disk drive wasn't empty or off when saved, + mount the disk */ + switch (saved_drive_status) { + case SIO_READ_ONLY: + SIO_Mount(i + 1, filename, TRUE); + break; + case SIO_READ_WRITE: + SIO_Mount(i + 1, filename, FALSE); + break; + default: + break; + } + } +} +#endif /* __LIBRETRO__ */ + void SIO_StateSave(void) { int i; diff --git a/atari800/src/sio.h b/atari800/src/sio.h index be6c439..a4e03e1 100644 --- a/atari800/src/sio.h +++ b/atari800/src/sio.h @@ -59,4 +59,9 @@ int SIO_WriteSector(int unit, int sector, const UBYTE *buffer); void SIO_StateSave(void); void SIO_StateRead(void); +#if defined(__LIBRETRO__) +void Retro_SIO_StateSave(void); +void Retro_SIO_StateRead(void); +#endif + #endif /* SIO_H_ */ diff --git a/atari800/src/sound.c b/atari800/src/sound.c index 722a089..6196268 100644 --- a/atari800/src/sound.c +++ b/atari800/src/sound.c @@ -231,7 +231,9 @@ int Sound_Setup(void) return FALSE; } +#ifndef __LIBRETRO__ POKEYSND_stereo_enabled = Sound_out.channels == 2; +#endif /* __LIBRETRO__ */ #ifndef SOUND_CALLBACK free(process_buffer); process_buffer_size = Sound_out.buffer_frames * Sound_out.channels * Sound_out.sample_size; diff --git a/atari800/src/statesav.c b/atari800/src/statesav.c index a6603fd..76a6932 100644 --- a/atari800/src/statesav.c +++ b/atari800/src/statesav.c @@ -26,6 +26,14 @@ #include #include #include + +#if defined(__LIBRETRO__) +#include +#include + +int Retro_SaveState_Size = 0; +#endif + #ifdef HAVE_ERRNO_H #include #endif @@ -99,6 +107,12 @@ static size_t mem_write(const void *buf, size_t len, gzFile *stream); #define Z_OK 0 #endif + +#if defined(__LIBRETRO__) +static memstream_t* state_stream = NULL; +static bool state_stream_error = false; +#endif + static gzFile StateFile = NULL; static int nFileError = Z_OK; @@ -120,6 +134,119 @@ static void GetGZErrorText(void) Log_print("State file I/O failed."); } +#if defined(__LIBRETRO__) +/* Value is memory location of data, num is number of type to save */ +void Retro_SaveUBYTE(const UBYTE* data, int num) +{ + if (!state_stream || state_stream_error) + return; + + /* Assumption is that UBYTE = 8bits and the pointer passed in refers + * directly to the active bits in a padded location. If not (unlikely) + * you'll have to redefine this to save appropriately for cross-platform + * compatibility */ + if (memstream_write(state_stream, data, num) != num) + state_stream_error = true; + + Retro_SaveState_Size += num; +} + +void Retro_SaveINT(const int* data, int num) +{ + if (!state_stream || state_stream_error) + return; + + /* INTs are always saved as 32bits (4 bytes) in the file. They can be any size + * on the platform however. The sign bit is clobbered into the fourth byte saved + * for each int; on read it will be extended out to its proper position for the + * native INT size */ + while (num > 0) + { + UBYTE signbit = 0; + unsigned int temp; + UBYTE byte; + int temp0 = *data++; + if (temp0 < 0) + { + temp0 = -temp0; + signbit = 0x80; + } + temp = (unsigned int)temp0; + + byte = temp & 0xff; + if (memstream_write(state_stream, &byte, 1) != 1) + { + state_stream_error = true; + break; + } + + temp >>= 8; + byte = temp & 0xff; + if (memstream_write(state_stream, &byte, 1) != 1) + { + state_stream_error = true; + break; + } + + temp >>= 8; + byte = temp & 0xff; + if (memstream_write(state_stream, &byte, 1) != 1) + { + state_stream_error = true; + break; + } + + temp >>= 8; + byte = (temp & 0x7f) | signbit; + if (memstream_write(state_stream, &byte, 1) != 1) + { + state_stream_error = true; + break; + } + + num--; + Retro_SaveState_Size += 4; + } + +} + +/* Value is memory location of data, num is number of type to save */ +void Retro_SaveUWORD(const UWORD* data, int num) +{ + if (!state_stream || state_stream_error) + return; + + /* UWORDS are saved as 16bits, regardless of the size on this particular + * platform. Each byte of the UWORD will be pushed out individually in + * LSB order. The shifts here and in the read routines will work for both + * LSB and MSB architectures. */ + while (num > 0) + { + UWORD temp = *data++; + UBYTE byte = temp & 0xff; + + if (memstream_write(state_stream, &byte, 1) != 1) + { + state_stream_error = true; + break; + } + + temp >>= 8; + byte = temp & 0xff; + + if (memstream_write(state_stream, &byte, 1) != 1) + { + state_stream_error = true; + break; + } + + num--; + Retro_SaveState_Size += 2; + } + +} +#endif + /* Value is memory location of data, num is number of type to save */ void StateSav_SaveUBYTE(const UBYTE *data, int num) { @@ -328,10 +455,354 @@ void StateSav_ReadFNAME(char *filename) filename[namelen] = 0; } +#if defined(__LIBRETRO__) + +int Retro_SaveAtariState(uint8_t* data, size_t size, UBYTE SaveVerbose) +{ + UBYTE StateVersion = SAVE_VERSION_NUMBER; + Retro_SaveState_Size = 0; + + /* Clean up any existing memory stream */ + if (state_stream) + { + memstream_close(state_stream); + memstream_set_buffer(NULL, 0); + state_stream = NULL; + } + state_stream_error = false; + + if (!data || size < 1) + goto error; + + /* Open memory stream */ + memstream_set_buffer(data, size); + state_stream = memstream_open(1); + if (!state_stream) + goto error; + + if (memstream_write(state_stream, "ATARI800", 8) != 8) + goto error; + + Retro_SaveState_Size += 8; + + Retro_SaveUBYTE(&StateVersion, 1); + Retro_SaveUBYTE(&SaveVerbose, 1); + /* The order here is important. Atari800_StateSave must be first because it saves the machine type, and + decisions on what to save/not save are made based off that later in the process */ + Retro_Atari800_StateSave(); + Retro_CARTRIDGE_StateSave(); + Retro_SIO_StateSave(); + Retro_ANTIC_StateSave(); + Retro_CPU_StateSave(SaveVerbose); + Retro_GTIA_StateSave(); + Retro_PIA_StateSave(); + Retro_POKEY_StateSave(); +#ifdef XEP80_EMULATION + //XEP80_StateSave(); +#else + { + int local_xep80_enabled = FALSE; + Retro_SaveINT(&local_xep80_enabled, 1); + } +#endif /* XEP80_EMULATION */ + PBI_StateSave(); +#ifdef PBI_MIO + //PBI_MIO_StateSave(); +#else + { + int local_mio_enabled = FALSE; + Retro_SaveINT(&local_mio_enabled, 1); + } +#endif /* PBI_MIO */ +#ifdef PBI_BB + //PBI_BB_StateSave(); +#else + { + int local_bb_enabled = FALSE; + Retro_SaveINT(&local_bb_enabled, 1); + } +#endif /* PBI_BB */ +#ifdef PBI_XLD + //PBI_XLD_StateSave(); +#else + { + int local_xld_enabled = FALSE; + Retro_SaveINT(&local_xld_enabled, 1); + } +#endif /* PBI_XLD */ +#ifdef DREAMCAST + DCStateSave(); +#endif + + /* Close memory stream */ + memstream_close(state_stream); + memstream_set_buffer(NULL, 0); + state_stream = NULL; + + if (state_stream_error) + return FALSE; + + return Retro_SaveState_Size; + +error: + if (state_stream) + memstream_close(state_stream); + memstream_set_buffer(NULL, 0); + state_stream = NULL; + state_stream_error = true; + return FALSE; +} + +void Retro_SaveFNAME(const char* filename) +{ + UWORD namelen; +#ifdef HAVE_GETCWD + char dirname[FILENAME_MAX] = ""; + + /* Check to see if file is in application tree, if so, just save as + relative path....*/ + if (getcwd(dirname, FILENAME_MAX) != NULL) { + if (strncmp(filename, dirname, strlen(dirname)) == 0) + /* XXX: check if '/' or '\\' follows dirname in filename? */ + filename += strlen(dirname) + 1; + } +#endif + + namelen = strlen(filename); + /* Save the length of the filename, followed by the filename */ + Retro_SaveUWORD(&namelen, 1); + Retro_SaveUBYTE((const UBYTE*)filename, namelen); +} + +int Retro_ReadAtariState(const uint8_t* data, size_t size) +{ + char header_string[8]; + UBYTE StateVersion = 0; /* The version of the save file */ + UBYTE SaveVerbose = 0; /* Verbose mode means save basic, OS if patched */ + + Retro_SaveState_Size = 0; + + /* Clean up any existing memory stream */ + if (state_stream) + { + memstream_close(state_stream); + memstream_set_buffer(NULL, 0); + state_stream = NULL; + } + state_stream_error = false; + + /* Open memory stream */ + memstream_set_buffer((uint8_t*)data, size); + state_stream = memstream_open(0); + if (!state_stream) + goto error; + + if (memstream_read(state_stream, header_string, 8) != 8) + goto error; + + Retro_SaveState_Size += 8; + + if (memcmp(header_string, "ATARI800", 8) != 0) + goto error; + + if ((memstream_read(state_stream, &StateVersion, 1) != 1) || + (memstream_read(state_stream, &SaveVerbose, 1) != 1)) + goto error; + + Retro_SaveState_Size += 2; + + if (StateVersion > SAVE_VERSION_NUMBER || StateVersion < 3) + goto error; + + Retro_Atari800_StateRead(StateVersion); + if (StateVersion >= 4) { + Retro_CARTRIDGE_StateRead(StateVersion); + Retro_SIO_StateRead(); + } + Retro_ANTIC_StateRead(); + Retro_CPU_StateRead(SaveVerbose, StateVersion); + Retro_GTIA_StateRead(StateVersion); + Retro_PIA_StateRead(StateVersion); + Retro_POKEY_StateRead(); + if (StateVersion >= 6) { +#ifdef XEP80_EMULATION + //XEP80_StateRead(); +#else + int local_xep80_enabled; + Retro_ReadINT(&local_xep80_enabled, 1); + if (local_xep80_enabled) + goto error; +#endif /* XEP80_EMULATION */ + PBI_StateRead(); +#ifdef PBI_MIO + //PBI_MIO_StateRead(); +#else + { + int local_mio_enabled; + Retro_ReadINT(&local_mio_enabled, 1); + if (local_mio_enabled) + goto error; + } +#endif /* PBI_MIO */ +#ifdef PBI_BB + //PBI_BB_StateRead(); +#else + { + int local_bb_enabled; + Retro_ReadINT(&local_bb_enabled, 1); + if (local_bb_enabled) + goto error; + } +#endif /* PBI_BB */ +#ifdef PBI_XLD + //PBI_XLD_StateRead(); +#else + { + int local_xld_enabled; + Retro_ReadINT(&local_xld_enabled, 1); + if (local_xld_enabled) + goto error; + } +#endif /* PBI_XLD */ + } +#ifdef DREAMCAST + DCStateRead(); +#endif + + /* Close memory stream */ + memstream_close(state_stream); + memstream_set_buffer(NULL, 0); + state_stream = NULL; + + if (state_stream_error) + return FALSE; + + GTIA_consol_override = 0; + + return Retro_SaveState_Size; + +error: + if (state_stream) + memstream_close(state_stream); + memstream_set_buffer(NULL, 0); + state_stream = NULL; + state_stream_error = true; + return FALSE; +} + +/* Value is memory location of data, num is number of type to save */ +void Retro_ReadUBYTE(UBYTE* data, int num) +{ + if (!state_stream || state_stream_error) + return; + + if (memstream_read(state_stream, data, num) != num) + state_stream_error = true; + + Retro_SaveState_Size += num; +} + +/* Value is memory location of data, num is number of type to save */ +void Retro_ReadUWORD(UWORD* data, int num) +{ + if (!state_stream || state_stream_error) + return; + + while (num > 0) + { + UBYTE byte1; + UBYTE byte2; + + if (memstream_read(state_stream, &byte1, 1) != 1) + { + state_stream_error = true; + break; + } + + if (memstream_read(state_stream, &byte2, 1) != 1) + { + state_stream_error = true; + break; + } + + *data++ = (byte2 << 8) | byte1; + num--; + + Retro_SaveState_Size += 2; + } + +} + +void Retro_ReadINT(int* data, int num) +{ + if (!state_stream || state_stream_error) + return; + + while (num > 0) + { + UBYTE signbit = 0; + int temp; + UBYTE byte1; + UBYTE byte2; + UBYTE byte3; + UBYTE byte4; + + if (memstream_read(state_stream, &byte1, 1) != 1) + { + state_stream_error = true; + break; + } + + if (memstream_read(state_stream, &byte2, 1) != 1) + { + state_stream_error = true; + break; + } + + if (memstream_read(state_stream, &byte3, 1) != 1) + { + state_stream_error = true; + break; + } + + if (memstream_read(state_stream, &byte4, 1) != 1) + { + state_stream_error = true; + break; + } + + signbit = byte4 & 0x80; + byte4 &= 0x7f; + + temp = (byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1; + if (signbit) + temp = -temp; + *data++ = temp; + + num--; + + Retro_SaveState_Size += 4; + } +} + +void Retro_ReadFNAME(char* filename) +{ + UWORD namelen = 0; + + Retro_ReadUWORD(&namelen, 1); + if (namelen >= FILENAME_MAX) + return; + + Retro_ReadUBYTE((UBYTE*)filename, namelen); + filename[namelen] = 0; +} +#endif /* __RETROLIB__ */ + int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVerbose) { UBYTE StateVersion = SAVE_VERSION_NUMBER; + if (StateFile != NULL) { GZCLOSE(StateFile); StateFile = NULL; diff --git a/atari800/src/statesav.h b/atari800/src/statesav.h index 2c6b692..eb4240d 100644 --- a/atari800/src/statesav.h +++ b/atari800/src/statesav.h @@ -16,4 +16,19 @@ void StateSav_ReadUWORD(UWORD *data, int num); void StateSav_ReadINT(int *data, int num); void StateSav_ReadFNAME(char *filename); +#if defined(__LIBRETRO__) +int Retro_SaveAtariState(uint8_t* data, size_t size, UBYTE SaveVerbose); +int Retro_ReadAtariState(const uint8_t* data, size_t size); + +void Retro_SaveUBYTE(const UBYTE* data, int num); +void Retro_SaveUWORD(const UWORD* data, int num); +void Retro_SaveINT(const int* data, int num); +void Retro_SaveFNAME(const char* filename); + +void Retro_ReadUBYTE(UBYTE* data, int num); +void Retro_ReadUWORD(UWORD* data, int num); +void Retro_ReadINT(int* data, int num); +void Retro_ReadFNAME(char* filename); +#endif + #endif /* STATESAV_H_ */ diff --git a/atari800/src/sysrom.c b/atari800/src/sysrom.c index b3a01ee..4dd9f08 100644 --- a/atari800/src/sysrom.c +++ b/atari800/src/sysrom.c @@ -32,6 +32,10 @@ #include #include +#ifdef HAVE_SYS_STAT_H +#include +#endif + #include "sysrom.h" #include "cfg.h" @@ -40,6 +44,11 @@ #include "memory.h" #include "util.h" +# include "roms/altirra_5200_os.h" +# include "roms/altirraos_800.h" +# include "roms/altirraos_xl.h" +# include "roms/altirra_basic.h" + int SYSROM_os_versions[Atari800_MACHINE_SIZE] = { SYSROM_AUTO, SYSROM_AUTO, SYSROM_AUTO }; int SYSROM_basic_version = SYSROM_AUTO; int SYSROM_xegame_version = SYSROM_AUTO; @@ -75,35 +84,39 @@ static char xegame_custom_filename[FILENAME_MAX]; enum { CRC_NULL = 0 }; SYSROM_t SYSROM_roms[SYSROM_SIZE] = { - { osa_ntsc_filename, 0x2800, 0xc1b3bb02, TRUE }, /* SYSROM_A_NTSC */ - { osa_pal_filename, 0x2800, 0x72b3fed4, TRUE }, /* SYSROM_A_PAL */ - { osb_ntsc_filename, 0x2800, 0x0e86d61d, TRUE }, /* SYSROM_B_NTSC */ - { osaa00r10_filename, 0x4000, 0xc5c11546, TRUE }, /* SYSROM_AA00R10 */ - { osaa01r11_filename, 0x4000, 0x1a1d7b1b, TRUE }, /* SYSROM_AA01R11 */ - { osbb00r1_filename, 0x4000, 0x643bcc98, TRUE }, /* SYSROM_BB00R1 */ - { osbb01r2_filename, 0x4000, 0x1f9cd270, TRUE }, /* SYSROM_BB01R2 */ - { osbb02r3_filename, 0x4000, 0x0d477aa1, TRUE }, /* SYSROM_BB02R3 */ - { osbb02r3v4_filename, 0x4000, 0xd425a9cf, TRUE }, /* SYSROM_BB02R3V4 */ - { oscc01r4_filename, 0x4000, 0x0e000b99, TRUE }, /* SYSROM_CC01R4 */ - { osbb01r3_filename, 0x4000, 0x29f133f7, TRUE }, /* SYSROM_BB01R3 */ - { osbb01r4_filename, 0x4000, 0x1eaf4002, TRUE }, /* SYSROM_BB01R4_OS */ - { osbb01r59_filename, 0x4000, 0x45f47988, TRUE }, /* SYSROM_BB01R59 */ - { osbb01r59a_filename, 0x4000, 0xf0a236d3, TRUE }, /* SYSROM_BB01R59A */ - { os5200a_filename, 0x0800, 0x4248d3e3, TRUE }, /* SYSROM_5200 */ - { os5200b_filename, 0x0800, 0xc2ba2613, TRUE }, /* SYSROM_5200A */ - { basica_filename, 0x2000, 0x4bec4de2, TRUE }, /* SYSROM_BASIC_A */ - { basicb_filename, 0x2000, 0xf0202fb3, TRUE }, /* SYSROM_BASIC_B */ - { basicc_filename, 0x2000, 0x7d684184, TRUE }, /* SYSROM_BASIC_C */ - { xegame_filename, 0x2000, 0xbdca01fb, TRUE }, /* SYSROM_XEGAME */ - { os800_custom_filename, 0x2800, CRC_NULL, TRUE }, /* SYSROM_400800_CUSTOM */ - { osxl_custom_filename, 0x4000, CRC_NULL, TRUE }, /* SYSROM_XL_CUSTOM */ - { os5200_custom_filename, 0x0800, CRC_NULL, TRUE }, /* SYSROM_5200_CUSTOM */ - { basic_custom_filename, 0x2000, CRC_NULL, TRUE }, /* SYSROM_BASIC_CUSTOM */ - { xegame_custom_filename, 0x2000, CRC_NULL, TRUE }, /* SYSROM_XEGAME_CUSTOM */ + { osa_ntsc_filename, 0x2800, 0xc1b3bb02, NULL, TRUE }, /* SYSROM_A_NTSC */ + { osa_pal_filename, 0x2800, 0x72b3fed4, NULL, TRUE }, /* SYSROM_A_PAL */ + { osb_ntsc_filename, 0x2800, 0x0e86d61d, NULL, TRUE }, /* SYSROM_B_NTSC */ + { osaa00r10_filename, 0x4000, 0xc5c11546, NULL, TRUE }, /* SYSROM_AA00R10 */ + { osaa01r11_filename, 0x4000, 0x1a1d7b1b, NULL, TRUE }, /* SYSROM_AA01R11 */ + { osbb00r1_filename, 0x4000, 0x643bcc98, NULL, TRUE }, /* SYSROM_BB00R1 */ + { osbb01r2_filename, 0x4000, 0x1f9cd270, NULL, TRUE }, /* SYSROM_BB01R2 */ + { osbb02r3_filename, 0x4000, 0x0d477aa1, NULL, TRUE }, /* SYSROM_BB02R3 */ + { osbb02r3v4_filename, 0x4000, 0xd425a9cf, NULL, TRUE }, /* SYSROM_BB02R3V4 */ + { oscc01r4_filename, 0x4000, 0x0e000b99, NULL, TRUE }, /* SYSROM_CC01R4 */ + { osbb01r3_filename, 0x4000, 0x29f133f7, NULL, TRUE }, /* SYSROM_BB01R3 */ + { osbb01r4_filename, 0x4000, 0x1eaf4002, NULL, TRUE }, /* SYSROM_BB01R4_OS */ + { osbb01r59_filename, 0x4000, 0x45f47988, NULL, TRUE }, /* SYSROM_BB01R59 */ + { osbb01r59a_filename, 0x4000, 0xf0a236d3, NULL, TRUE }, /* SYSROM_BB01R59A */ + { os5200a_filename, 0x0800, 0x4248d3e3, NULL, TRUE }, /* SYSROM_5200 */ + { os5200b_filename, 0x0800, 0xc2ba2613, NULL, TRUE }, /* SYSROM_5200A */ + { basica_filename, 0x2000, 0x4bec4de2, NULL, TRUE }, /* SYSROM_BASIC_A */ + { basicb_filename, 0x2000, 0xf0202fb3, NULL, TRUE }, /* SYSROM_BASIC_B */ + { basicc_filename, 0x2000, 0x7d684184, NULL, TRUE }, /* SYSROM_BASIC_C */ + { xegame_filename, 0x2000, 0xbdca01fb, NULL, TRUE }, /* SYSROM_XEGAME */ + { os800_custom_filename, 0x2800, CRC_NULL, NULL, TRUE }, /* SYSROM_400800_CUSTOM */ + { osxl_custom_filename, 0x4000, CRC_NULL, NULL, TRUE }, /* SYSROM_XL_CUSTOM */ + { os5200_custom_filename, 0x0800, CRC_NULL, NULL, TRUE }, /* SYSROM_5200_CUSTOM */ + { basic_custom_filename, 0x2000, CRC_NULL, NULL, TRUE }, /* SYSROM_BASIC_CUSTOM */ + { xegame_custom_filename, 0x2000, CRC_NULL, NULL, TRUE }, /* SYSROM_XEGAME_CUSTOM */ + { NULL, 0x2800, CRC_NULL, ROM_altirraos_800, FALSE }, /* SYSROM_ALTIRRA_800 */ + { NULL, 0x4000, CRC_NULL, ROM_altirraos_xl, FALSE }, /* SYSROM_ALTIRRA_XL */ + { NULL, 0x0800, CRC_NULL, ROM_altirra_5200_os, FALSE }, /* SYSROM_ALTIRRA_5200 */ + { NULL, 0x2000, CRC_NULL, ROM_altirra_basic, FALSE }, /* SYSROM_ALTIRRA_BASIC */ }; /* Used in reading the config file to match option names. */ -static char const * const cfg_strings[SYSROM_SIZE] = { +static char const * const cfg_strings[SYSROM_LOADABLE_SIZE] = { "ROM_OS_A_NTSC", "ROM_OS_A_PAL", "ROM_OS_B_NTSC", @@ -158,11 +171,15 @@ static char const * const cfg_strings_rev[SYSROM_SIZE+1] = { "CUSTOM", /* SYSROM_5200_CUSTOM */ "CUSTOM", /* SYSROM_BASIC_CUSTOM */ "CUSTOM", /* SYSROM_XEGAME_CUSTOM */ + "ALTIRRA", /* SYSROM_ALTIRRA_800 */ + "ALTIRRA", /* SYSROM_ALTIRRA_XL */ + "ALTIRRA", /* SYSROM_ALTIRRA_5200 */ + "ALTIRRA", /* SYSROM_ALTIRRA_BASIC */ "AUTO" /* SYSROM_AUTO */ }; /* Number of ROM paths not set during initialisation. */ -static int num_unset_roms = SYSROM_SIZE; +static int num_unset_roms = SYSROM_LOADABLE_SIZE; /* Checks if LEN is a correct ROM length. */ static int IsLengthAllowed(int len) @@ -266,6 +283,9 @@ int SYSROM_FindInDir(char const *directory, int only_if_not_set) { DIR *dir; struct dirent *entry; +#ifdef HAVE_STAT + struct stat status; +#endif if (only_if_not_set && num_unset_roms == 0) /* No unset ROM paths left. */ @@ -281,7 +301,25 @@ int SYSROM_FindInDir(char const *directory, int only_if_not_set) int id; ULONG crc; int matched_crc = FALSE; + + if (entry->d_name[0] == '.') { + /* never match "." */ + if (entry->d_name[1] == '\0') + continue; + /* never match ".." */ + if (entry->d_name[1] == '.' && entry->d_name[2] == '\0') + continue; + } + Util_catpath(full_filename, directory, entry->d_name); + +#ifdef HAVE_STAT + if (stat(full_filename, &status) == 0) { + if (S_ISDIR(status.st_mode)) + continue ; + } +#endif + if ((file = fopen(full_filename, "rb")) == NULL) /* Ignore non-readable files (e.g. directories). */ continue; @@ -301,7 +339,7 @@ int SYSROM_FindInDir(char const *directory, int only_if_not_set) fclose(file); /* Match ROM image by CRC. */ - for (id = 0; id < SYSROM_SIZE; ++id) { + for (id = 0; id < SYSROM_LOADABLE_SIZE; ++id) { if ((!only_if_not_set || SYSROM_roms[id].unset) && SYSROM_roms[id].size == len && SYSROM_roms[id].crc32 != CRC_NULL && SYSROM_roms[id].crc32 == crc) { @@ -335,28 +373,29 @@ int SYSROM_FindInDir(char const *directory, int only_if_not_set) void SYSROM_SetDefaults(void) { int i; - for (i = 0; i < SYSROM_SIZE; ++i) + for (i = 0; i < SYSROM_LOADABLE_SIZE; ++i) SYSROM_roms[i].unset = FALSE; num_unset_roms = 0; } /* Ordered lists of ROM IDs to choose automatically when SYSROM_os_versions or SYSROM_basic_version are set to SYSROM_AUTO. */ -static int const autochoose_order_800_ntsc[] = { SYSROM_B_NTSC, SYSROM_A_NTSC, SYSROM_A_PAL, SYSROM_800_CUSTOM, -1 }; -static int const autochoose_order_800_pal[] = { SYSROM_A_PAL, SYSROM_B_NTSC, SYSROM_A_NTSC, SYSROM_800_CUSTOM, -1 }; -static int const autochoose_order_1200xl[] = { SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 }; -static int const autochoose_order_600xl[] = { SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 }; -static int const autochoose_order_800xl[] = { SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 }; -static int const autochoose_order_xe[] = { SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R2, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 }; -static int const autochoose_order_xegs[] = { SYSROM_BB01R4_OS, SYSROM_BB01R3, SYSROM_BB01R2, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, -1 }; -static int const autochoose_order_5200[] = { SYSROM_5200, SYSROM_5200A, SYSROM_5200_CUSTOM, -1 }; -static int const autochoose_order_basic[] = { SYSROM_BASIC_C, SYSROM_BASIC_B, SYSROM_BASIC_A, SYSROM_BASIC_CUSTOM, -1 }; +static int const autochoose_order_800_ntsc[] = { SYSROM_B_NTSC, SYSROM_A_NTSC, SYSROM_A_PAL, SYSROM_800_CUSTOM, SYSROM_ALTIRRA_800, -1 }; +static int const autochoose_order_800_pal[] = { SYSROM_A_PAL, SYSROM_B_NTSC, SYSROM_A_NTSC, SYSROM_800_CUSTOM, SYSROM_ALTIRRA_800, -1 }; +static int const autochoose_order_1200xl[] = { SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, SYSROM_ALTIRRA_XL, -1 }; +static int const autochoose_order_600xl[] = { SYSROM_BB00R1, SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, SYSROM_ALTIRRA_XL, -1 }; +static int const autochoose_order_800xl[] = { SYSROM_BB01R2, SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, SYSROM_ALTIRRA_XL, -1 }; +static int const autochoose_order_xe[] = { SYSROM_BB01R3, SYSROM_BB01R4_OS, SYSROM_BB01R2, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, SYSROM_ALTIRRA_XL, -1 }; +static int const autochoose_order_xegs[] = { SYSROM_BB01R4_OS, SYSROM_BB01R3, SYSROM_BB01R2, SYSROM_BB00R1, SYSROM_AA01R11, SYSROM_AA00R10, SYSROM_BB01R59, SYSROM_BB01R59A, SYSROM_BB02R3, SYSROM_BB02R3V4, SYSROM_CC01R4, SYSROM_XL_CUSTOM, SYSROM_ALTIRRA_XL, -1 }; +static int const autochoose_order_5200[] = { SYSROM_5200, SYSROM_5200A, SYSROM_5200_CUSTOM, SYSROM_ALTIRRA_5200, -1 }; +static int const autochoose_order_basic[] = { SYSROM_BASIC_C, SYSROM_BASIC_B, SYSROM_BASIC_A, SYSROM_BASIC_CUSTOM, SYSROM_ALTIRRA_BASIC, -1 }; static int const autochoose_order_xegame[] = { SYSROM_XEGAME, SYSROM_XEGAME_CUSTOM, -1 }; static int AutoChooseROM(int const *order) { do { - if (SYSROM_roms[*order].filename[0] != '\0') + if (SYSROM_roms[*order].data != NULL + || SYSROM_roms[*order].filename[0] != '\0') return *order; } while (*++order != -1); return -1; @@ -418,7 +457,9 @@ void SYSROM_ChooseROMs(int machine_type, int ram_size, int tv_system, int *os_ve else os_ver = SYSROM_os_versions[machine_type]; - if (os_ver != -1 && SYSROM_roms[os_ver].filename[0] == '\0') + if (os_ver != -1 + && SYSROM_roms[os_ver].data == NULL + && SYSROM_roms[os_ver].filename[0] == '\0') os_ver = -1; *os_version = os_ver; @@ -433,7 +474,9 @@ void SYSROM_ChooseROMs(int machine_type, int ram_size, int tv_system, int *os_ve basic_ver = SYSROM_AutoChooseBASIC(); else basic_ver = SYSROM_basic_version; - if (basic_ver != -1 && SYSROM_roms[basic_ver].filename[0] == '\0') + if (basic_ver != -1 + && SYSROM_roms[basic_ver].data == NULL + && SYSROM_roms[basic_ver].filename[0] == '\0') basic_ver = -1; *basic_version = basic_ver; @@ -442,12 +485,23 @@ void SYSROM_ChooseROMs(int machine_type, int ram_size, int tv_system, int *os_ve xegame_ver = SYSROM_AutoChooseXEGame(); else xegame_ver = SYSROM_xegame_version; - if (xegame_ver != -1 && SYSROM_roms[xegame_ver].filename[0] == '\0') + if (xegame_ver != -1 + && SYSROM_roms[xegame_ver].data == NULL + && SYSROM_roms[xegame_ver].filename[0] == '\0') xegame_ver = -1; *xegame_version = xegame_ver; } } +int SYSROM_LoadImage(int id, UBYTE *buffer) +{ + if (SYSROM_roms[id].data != NULL) { + memcpy(buffer, SYSROM_roms[id].data, SYSROM_roms[id].size); + return TRUE; + } + return Atari800_LoadImage(SYSROM_roms[id].filename, buffer, SYSROM_roms[id].size); +} + /* Matches values of OS_*_VERSION and BASIC_VERSION parameters in the config file. If matched, writes an appropriate value to *VERSION_PTR (which is a pointer to SYSROM_os_versions/SYSROM_basic_version) and returns TRUE; otherwise @@ -470,7 +524,7 @@ static int MatchROMVersionParameter(char const *string, int const *allowed_vals, int SYSROM_ReadConfig(char *string, char *ptr) { - int id = CFG_MatchTextParameter(string, cfg_strings, SYSROM_SIZE); + int id = CFG_MatchTextParameter(string, cfg_strings, SYSROM_LOADABLE_SIZE); if (id >= 0) { /* For faster start, don't check if CRC matches. */ Util_strlcpy(SYSROM_roms[id].filename, ptr, FILENAME_MAX); @@ -524,7 +578,7 @@ int SYSROM_ReadConfig(char *string, char *ptr) void SYSROM_WriteConfig(FILE *fp) { int id; - for (id = 0; id < SYSROM_SIZE; ++id) { + for (id = 0; id < SYSROM_LOADABLE_SIZE; ++id) { if (!SYSROM_roms[id].unset) fprintf(fp, "%s=%s\n", cfg_strings[id], SYSROM_roms[id].filename); } @@ -622,13 +676,13 @@ int SYSROM_Initialise(int *argc, char *argv[]) Log_print("\t-xlxe_rom Load XL/XE ROM from file"); Log_print("\t-5200_rom Load 5200 ROM from file"); Log_print("\t-basic_rom Load BASIC ROM from file"); - Log_print("\t-800-rev auto|a-ntsc|a-pal|b-ntsc|custom"); + Log_print("\t-800-rev auto|a-ntsc|a-pal|b-ntsc|custom|altirra"); Log_print("\t Select 400/800 OS revision"); - Log_print("\t-xl-rev auto|10|11|1|2|3a|3b|5|3|4|59|59a|custom"); + Log_print("\t-xl-rev auto|10|11|1|2|3a|3b|5|3|4|59|59a|custom|altirra"); Log_print("\t Select XL/XE OS revision"); - Log_print("\t-5200-rev auto|orig|a|custom"); + Log_print("\t-5200-rev auto|orig|a|custom|altirra"); Log_print("\t Select 5200 OS revision"); - Log_print("\t-basic-rev auto|a|b|c|custom"); + Log_print("\t-basic-rev auto|a|b|c|custom|altirra"); Log_print("\t Select BASIC revision"); Log_print("\t-xegame-rev auto|orig|custom"); Log_print("\t Select XEGS builtin game version"); diff --git a/atari800/src/sysrom.h b/atari800/src/sysrom.h index 92f9fd8..029bbdf 100644 --- a/atari800/src/sysrom.h +++ b/atari800/src/sysrom.h @@ -56,6 +56,12 @@ enum { SYSROM_5200_CUSTOM, /* Custom 5200 BIOS */ SYSROM_BASIC_CUSTOM,/* Custom BASIC */ SYSROM_XEGAME_CUSTOM, /* Custom XEGS game */ + SYSROM_LOADABLE_SIZE, /* Number of OS ROM loadable from file */ + /* --- Built-in free replacement OSes from Altirra --- */ + SYSROM_ALTIRRA_800 = SYSROM_LOADABLE_SIZE, /* AltirraOS 400/800 */ + SYSROM_ALTIRRA_XL, /* AltirraOS XL/XE/XEGS */ + SYSROM_ALTIRRA_5200, /* Altirra 5200 OS */ + SYSROM_ALTIRRA_BASIC, /* ATBASIC */ SYSROM_SIZE, /* Number of available OS ROMs */ SYSROM_AUTO = SYSROM_SIZE /* Use to indicate that OS revision should be chosen automatically */ }; @@ -63,6 +69,7 @@ typedef struct SYSROM_t { char *filename; /* Path to the ROM image file */ size_t size; /* Expected size of the ROM image */ ULONG crc32; /* Expected CRC32 of the ROM image */ + UBYTE const *data; /* Pointer to ROM data in case of built-in ROMs */ int unset; /* During initialisation indicates that no filename was given for this ROM image in config/command line */ } SYSROM_t; @@ -127,6 +134,10 @@ void SYSROM_SetDefaults(void); */ void SYSROM_ChooseROMs(int machine_type, int ram_size, int tv_system, int *os_version, int *basic_version, int *xegame_version); +/* Called from Atari800_InitialiseMachine(). Loads OS ROM identified by ID into + a memory buffer BUFFER. */ +int SYSROM_LoadImage(int id, UBYTE *buffer); + /* Read/write from/to configuration file. */ int SYSROM_ReadConfig(char *string, char *ptr); void SYSROM_WriteConfig(FILE *fp); diff --git a/atari800/src/ui.c b/atari800/src/ui.c index 3d46138..8652e61 100644 --- a/atari800/src/ui.c +++ b/atari800/src/ui.c @@ -99,6 +99,9 @@ #endif /* HAVE_OPENGL */ #endif /* GUI_SDL */ +#ifdef __LIBRETRO__ +extern int legacy_configuration_file; +#endif /* __LIBRETRO__ */ #ifdef DIRECTX /* Display Settings */ extern RENDERMODE rendermode; @@ -267,6 +270,7 @@ static void SystemSettings(void) UI_MENU_ACTION(SYSROM_A_PAL, "Rev. A PAL"), UI_MENU_ACTION(SYSROM_B_NTSC, "Rev. B NTSC"), UI_MENU_ACTION(SYSROM_800_CUSTOM, "Custom"), + UI_MENU_ACTION(SYSROM_ALTIRRA_800, "AltirraOS"), UI_MENU_END }; static UI_tMenuItem osxl_menu_array[] = { @@ -283,6 +287,7 @@ static void SystemSettings(void) UI_MENU_ACTION(SYSROM_BB01R59, "BB01 Rev. 59"), UI_MENU_ACTION(SYSROM_BB01R59A, "BB01 Rev. 59 alt."), UI_MENU_ACTION(SYSROM_XL_CUSTOM, "Custom"), + UI_MENU_ACTION(SYSROM_ALTIRRA_XL, "AltirraOS"), UI_MENU_END }; static UI_tMenuItem os5200_menu_array[] = { @@ -290,6 +295,7 @@ static void SystemSettings(void) UI_MENU_ACTION(SYSROM_5200, "Original"), UI_MENU_ACTION(SYSROM_5200A, "Rev. A"), UI_MENU_ACTION(SYSROM_5200_CUSTOM, "Custom"), + UI_MENU_ACTION(SYSROM_ALTIRRA_5200, "AltirraOS"), UI_MENU_END }; static UI_tMenuItem * const os_menu_arrays[Atari800_MACHINE_SIZE] = { @@ -303,6 +309,7 @@ static void SystemSettings(void) UI_MENU_ACTION(SYSROM_BASIC_B, "Rev. B"), UI_MENU_ACTION(SYSROM_BASIC_C, "Rev. C"), UI_MENU_ACTION(SYSROM_BASIC_CUSTOM, "Custom"), + UI_MENU_ACTION(SYSROM_ALTIRRA_BASIC, "Altirra BASIC"), UI_MENU_END }; static UI_tMenuItem xegame_menu_array[] = { @@ -366,7 +373,7 @@ static void SystemSettings(void) /* Size must be long enough to store " (auto)". */ char default_os_label[26]; /* Size must be long enough to store " (auto)". */ - char default_basic_label[14]; + char default_basic_label[21]; /* Size must be long enough to store " (auto)". */ char default_xegame_label[23]; char mosaic_label[7]; /* Fits "256 KB" */ @@ -409,7 +416,8 @@ static void SystemSettings(void) menu_array[1].suffix = default_os_label; } } - else if (SYSROM_roms[SYSROM_os_versions[Atari800_machine_type]].filename[0] == '\0') + else if (SYSROM_roms[SYSROM_os_versions[Atari800_machine_type]].data == NULL + && SYSROM_roms[SYSROM_os_versions[Atari800_machine_type]].filename[0] == '\0') menu_array[1].suffix = "ROM missing"; else menu_array[1].suffix = FindMenuItem(os_menu_arrays[Atari800_machine_type], SYSROM_os_versions[Atari800_machine_type])->item; @@ -432,7 +440,8 @@ static void SystemSettings(void) menu_array[3].suffix = default_basic_label; } } - else if (SYSROM_roms[SYSROM_basic_version].filename[0] == '\0') + else if (SYSROM_roms[SYSROM_basic_version].data == NULL + && SYSROM_roms[SYSROM_basic_version].filename[0] == '\0') menu_array[3].suffix = "ROM missing"; else { menu_array[3].suffix = FindMenuItem(basic_menu_array, SYSROM_basic_version)->item; @@ -452,7 +461,8 @@ static void SystemSettings(void) menu_array[4].suffix = default_xegame_label; } } - else if (SYSROM_roms[SYSROM_xegame_version].filename[0] == '\0') + else if (SYSROM_roms[SYSROM_xegame_version].data == NULL + && SYSROM_roms[SYSROM_xegame_version].filename[0] == '\0') menu_array[4].suffix = "ROM missing"; else menu_array[4].suffix = FindMenuItem(xegame_menu_array, SYSROM_xegame_version)->item; @@ -545,7 +555,8 @@ static void SystemSettings(void) as it can never be hidden. */ UI_tMenuItem *menu_ptr = os_menu_arrays[Atari800_machine_type] + 1; do { - if (SYSROM_roms[menu_ptr->retval].filename[0] != '\0') { + if (SYSROM_roms[menu_ptr->retval].data != NULL + || SYSROM_roms[menu_ptr->retval].filename[0] != '\0') { menu_ptr->flags = UI_ITEM_ACTION; rom_available = TRUE; } @@ -576,7 +587,8 @@ static void SystemSettings(void) as it can never be hidden. */ UI_tMenuItem *menu_ptr = basic_menu_array + 1; do { - if (SYSROM_roms[menu_ptr->retval].filename[0] != '\0') { + if (SYSROM_roms[menu_ptr->retval].data != NULL + || SYSROM_roms[menu_ptr->retval].filename[0] != '\0') { menu_ptr->flags = UI_ITEM_ACTION; rom_available = TRUE; } @@ -601,7 +613,8 @@ static void SystemSettings(void) as they can never be hidden. */ UI_tMenuItem *menu_ptr = xegame_menu_array + 2; do { - if (SYSROM_roms[menu_ptr->retval].filename[0] != '\0') { + if (SYSROM_roms[menu_ptr->retval].data != NULL + || SYSROM_roms[menu_ptr->retval].filename[0] != '\0') { menu_ptr->flags = UI_ITEM_ACTION; } else @@ -1048,6 +1061,15 @@ int UI_SelectCartType(int k) UI_MENU_ACTION(CARTRIDGE_THECART_32M, CARTRIDGE_THECART_32M_DESC), UI_MENU_ACTION(CARTRIDGE_THECART_64M, CARTRIDGE_THECART_64M_DESC), UI_MENU_ACTION(CARTRIDGE_XEGS_8F_64, CARTRIDGE_XEGS_8F_64_DESC), + UI_MENU_ACTION(CARTRIDGE_ATRAX_128_RAW, CARTRIDGE_ATRAX_128_RAW_DESC), + UI_MENU_ACTION(CARTRIDGE_ADAWLIAH_32, CARTRIDGE_ADAWLIAH_32_DESC), + UI_MENU_ACTION(CARTRIDGE_ADAWLIAH_64, CARTRIDGE_ADAWLIAH_64_DESC), + UI_MENU_ACTION(CARTRIDGE_5200_SUPER_64, CARTRIDGE_5200_SUPER_64_DESC), + UI_MENU_ACTION(CARTRIDGE_5200_SUPER_128, CARTRIDGE_5200_SUPER_128_DESC), + UI_MENU_ACTION(CARTRIDGE_5200_SUPER_256, CARTRIDGE_5200_SUPER_256_DESC), + UI_MENU_ACTION(CARTRIDGE_5200_SUPER_512, CARTRIDGE_5200_SUPER_512_DESC), + UI_MENU_ACTION(CARTRIDGE_ATMAX_NEW_1024, CARTRIDGE_ATMAX_NEW_1024_DESC), + UI_MENU_ACTION(CARTRIDGE_5200_40_ALT, CARTRIDGE_5200_40_ALT_DESC), UI_MENU_END }; @@ -1721,7 +1743,7 @@ static void ROMLocations(char const *title, UI_tMenuItem *menu_array) else { /* Use first non-empty ROM path as a starting filename for the dialog. */ int i; - for (i = 0; i < SYSROM_SIZE; ++i) { + for (i = 0; i < SYSROM_LOADABLE_SIZE; ++i) { if (SYSROM_roms[i].filename[0] != '\0') { strcpy(filename, SYSROM_roms[i].filename); break; @@ -1814,6 +1836,48 @@ static void ROMLocationsXEGame(void) ROMLocations("XEGS Builtin Game ROM Locations", menu_array); } +static SYSROM_t GetCurrentOS(void) +{ + SYSROM_t sysrom = { 0 }; + + int rom = SYSROM_os_versions[Atari800_machine_type]; + if (rom == SYSROM_AUTO) + rom = SYSROM_AutoChooseOS(Atari800_machine_type, MEMORY_ram_size, Atari800_tv_mode); + + if (rom != -1) + sysrom = SYSROM_roms[rom]; + + return sysrom; +} + +static SYSROM_t GetCurrentBASIC(void) +{ + SYSROM_t sysrom = { 0 }; + + int rom = SYSROM_basic_version; + if (rom == SYSROM_AUTO) + rom = SYSROM_AutoChooseBASIC(); + + if (rom != -1) + sysrom = SYSROM_roms[rom]; + + return sysrom; +} + +static SYSROM_t GetCurrentXEGame(void) +{ + SYSROM_t sysrom = { 0 }; + + int rom = SYSROM_xegame_version; + if (rom == SYSROM_AUTO) + rom = SYSROM_AutoChooseXEGame(); + + if (rom != -1) + sysrom = SYSROM_roms[rom]; + + return sysrom; +} + static void SystemROMSettings(void) { static UI_tMenuItem menu_array[] = { @@ -1827,6 +1891,8 @@ static void SystemROMSettings(void) }; int option = 0; + int need_initialise = FALSE; + SYSROM_t old_sysrom, new_sysrom; for (;;) { int seltype; @@ -1839,32 +1905,107 @@ static void SystemROMSettings(void) char rom_dir[FILENAME_MAX] = ""; int i; /* Use first non-empty ROM path as a starting filename for the dialog. */ - for (i = 0; i < SYSROM_SIZE; ++i) { + for (i = 0; i < SYSROM_LOADABLE_SIZE; ++i) { if (SYSROM_roms[i].filename[0] != '\0') { Util_splitpath(SYSROM_roms[i].filename, rom_dir, NULL); break; } } - if (UI_driver->fGetDirectoryPath(rom_dir)) - SYSROM_FindInDir(rom_dir, FALSE); + if (UI_driver->fGetDirectoryPath(rom_dir)) { + SYSROM_t old_basic, old_xegame; + + old_sysrom = GetCurrentOS(); + old_basic = GetCurrentBASIC(); + old_xegame = GetCurrentXEGame(); + + if (SYSROM_FindInDir(rom_dir, FALSE)) { + new_sysrom = GetCurrentOS(); + + if (old_sysrom.data != new_sysrom.data) { + need_initialise = TRUE; + break; + } + + if (Atari800_machine_type != Atari800_MACHINE_5200) { + new_sysrom = GetCurrentBASIC(); + + if (old_basic.data != new_sysrom.data) { + need_initialise = TRUE; + break; + } + } + + if (Atari800_machine_type == Atari800_MACHINE_XLXE && Atari800_builtin_game) { + new_sysrom = GetCurrentXEGame(); + + if (old_xegame.data != new_sysrom.data) { + need_initialise = TRUE; + break; + } + } + } + } } break; + case 1: - ROMLocations800(); - break; case 2: - ROMLocationsXL(); - break; case 3: - ROMLocations5200(); + old_sysrom = GetCurrentOS(); + + switch (option) { + case 1: + ROMLocations800(); + break; + case 2: + ROMLocationsXL(); + break; + case 3: + ROMLocations5200(); + break; + } + + new_sysrom = GetCurrentOS(); + + if (old_sysrom.data != new_sysrom.data) + need_initialise = TRUE; break; + case 4: - ROMLocationsBASIC(); + if (Atari800_machine_type != Atari800_MACHINE_5200) { + old_sysrom = GetCurrentBASIC(); + + ROMLocationsBASIC(); + + new_sysrom = GetCurrentBASIC(); + + if (old_sysrom.data != new_sysrom.data) + need_initialise = TRUE; + } else { + /* ignore BASIC changes on 5200 */ + ROMLocationsBASIC(); + } break; + case 5: - ROMLocationsXEGame(); + if (Atari800_machine_type == Atari800_MACHINE_XLXE && Atari800_builtin_game) { + old_sysrom = GetCurrentXEGame(); + + ROMLocationsXEGame(); + + new_sysrom = GetCurrentXEGame(); + + if (old_sysrom.data != new_sysrom.data) + need_initialise = TRUE; + } else { + /* ignore XEGame changes on non-XE */ + ROMLocationsXEGame(); + } break; + default: + if (need_initialise) + Atari800_InitialiseMachine(); return; } } @@ -1998,7 +2139,10 @@ static void AtariSettings(void) break; #ifndef DREAMCAST case 15: - UI_driver->fMessage(CFG_WriteConfig() ? "Configuration file updated" : "Error writing configuration file", 1); + if (legacy_configuration_file) + UI_driver->fMessage(CFG_WriteConfig() ? "Configuration file updated" : "Error writing configuration file", 1); + else + UI_driver->fMessage("Legacy configuration file is disabled", 1); break; case 16: CFG_save_on_exit = !CFG_save_on_exit; @@ -3956,7 +4100,7 @@ static void AboutEmulator(void) Atari800_TITLE "\0" "Copyright (c) 1995-1998 David Firth\0" "and\0" - "(c)1998-2015 Atari800 Development Team\0" + "(c)1998-2023 Atari800 Development Team\0" "See CREDITS file for details.\0" "http://atari800.atari.org/\0" "\0" @@ -4043,12 +4187,16 @@ void UI_Run(void) UI_MENU_FILESEL_ACCEL(UI_MENU_LOADSTATE, "Load State", "Alt+L"), #if !defined(CURSES_BASIC) && !defined(DREAMCAST) #ifdef HAVE_LIBPNG +#ifndef __LIBRETRO__ UI_MENU_FILESEL_ACCEL(UI_MENU_PCX, "Save Screenshot", "F10"), /* there isn't enough space for "PNG/PCX Interlaced Screenshot Shift+F10" */ UI_MENU_FILESEL_ACCEL(UI_MENU_PCXI, "Save Interlaced Screenshot", "Shift+F10"), +#endif // __LIBRETRO__ #else +#ifndef __LIBRETRO__ UI_MENU_FILESEL_ACCEL(UI_MENU_PCX, "PCX Screenshot", "F10"), UI_MENU_FILESEL_ACCEL(UI_MENU_PCXI, "PCX Interlaced Screenshot", "Shift+F10"), +#endif // __LIBRETRO__ #endif #endif UI_MENU_ACTION_ACCEL(UI_MENU_BACK, "Back to Emulated Atari", "Esc"), @@ -4061,10 +4209,14 @@ void UI_Run(void) #elif defined(DIRECTX) UI_MENU_ACTION_ACCEL(UI_MENU_MONITOR, monitor_label, "F8"), #else +#ifndef __LIBRETRO__ UI_MENU_ACTION_ACCEL(UI_MENU_MONITOR, "Enter Monitor", "F8"), +#endif // __LIBRETRO__ #endif UI_MENU_ACTION_ACCEL(UI_MENU_ABOUT, "About the Emulator", "Alt+A"), +#ifndef __LIBRETRO__ UI_MENU_ACTION_ACCEL(UI_MENU_EXIT, "Exit Emulator", "F9"), +#endif // __LIBRETRO__ UI_MENU_END }; diff --git a/atari800/src/ui_basic.c b/atari800/src/ui_basic.c index 708e648..a7eb390 100644 --- a/atari800/src/ui_basic.c +++ b/atari800/src/ui_basic.c @@ -44,6 +44,9 @@ #ifdef HAVE_WINDOWS_H #include #endif +#if defined(__PS3__) && !defined(__PSL1GHT__) +#include "devices.h" +#endif #include "antic.h" #include "atari.h" @@ -936,8 +939,8 @@ static void GetDirectory(const char *directory) FilenamesAdd(Util_strdup("[mc0:]")); #endif #ifdef WIIU -// FIXME: limited to sd: add usb: - FilenamesAdd(Util_strdup("[sd:]")); +// FIXME: limited to fs:/vol/external01 add usb: + FilenamesAdd(Util_strdup("[fs:/vol/external01]")); #endif #ifdef DOS_DRIVES @@ -1156,9 +1159,9 @@ static int FileSelector(char *path, int select_dir, char pDirectories[][FILENAME } #endif #ifdef WIIU -// FIXME for now only sd: ,please add usb: - else if (strcmp(selected_filename, "[sd:]") == 0) { - strcpy(new_dir, "sd:/"); +// FIXME for now only fs:/vol/external01 ,please add usb: + else if (strcmp(selected_filename, "[fs:/vol/external01]") == 0) { + strcpy(new_dir, "fs:/vol/external01/"); } #endif #ifdef DOS_DRIVES diff --git a/atari800/src/util.c b/atari800/src/util.c index 970cf32..0fbc6d8 100644 --- a/atari800/src/util.c +++ b/atari800/src/util.c @@ -57,6 +57,11 @@ #include #endif +#if defined(__PS3__) && !defined(__PSL1GHT__) +#include +#define usleep sys_timer_usleep +#endif + #include "atari.h" #include "platform.h" #include "util.h" diff --git a/atari800/src/votraxsnd.c b/atari800/src/votraxsnd.c index d70560a..6edf36e 100644 --- a/atari800/src/votraxsnd.c +++ b/atari800/src/votraxsnd.c @@ -267,8 +267,8 @@ void VOTRAXSND_Process(void *sndbuffer, int sndn) while (sndn > 0) { int amount = ((sndn > VTRX_BLOCK_SIZE) ? VTRX_BLOCK_SIZE : sndn); votrax_process(votrax_buffer, amount, temp_votrax_buffer); - if (bit16) mix((SWORD *)sndbuffer, votrax_buffer, amount, 128/4); - else mix8((UBYTE *)sndbuffer, votrax_buffer, amount, 128/4); + if (bit16) mix((SWORD *)sndbuffer, votrax_buffer, amount, POKEYSND_volume >> 3); + else mix8((UBYTE *)sndbuffer, votrax_buffer, amount, POKEYSND_volume >> 3); sndbuffer = (char *) sndbuffer + VTRX_BLOCK_SIZE*(bit16 ? 2 : 1)*((num_pokeys == 2) ? 2: 1); sndn -= VTRX_BLOCK_SIZE; } diff --git a/atari800_libretro.info b/atari800_libretro.info new file mode 100644 index 0000000..19a57cf --- /dev/null +++ b/atari800_libretro.info @@ -0,0 +1,59 @@ +# Software Information +display_name = "Atari - 5200 (Atari800)" +authors = "Petr Stehlik" +supported_extensions = "xfd|atr|dcm|cas|bin|a52|zip|atx|car|rom|com|xex|m3u" +corename = "Atari800" +categories = "Emulator" +license = "GPLv2" +permissions = "" + +# Hardware Information +manufacturer = "Atari" +systemname = "Atari 5200" +systemid = "atari_5200" +database = "Atari - 5200" +display_version = "3.1.0" + +# Libretro Features +supports_no_game = "true" +savestate = "true" +savestate_features = "null" +cheats = "false" +input_descriptors = "true" +memory_descriptors = "false" +libretro_saves = "false" +core_options = "true" +core_options_version = "1.0" +load_subsystem = "false" +hw_render = "false" +needs_fullpath = "true" +disk_control = "false" +is_experimental = "false" +needs_kbd_mouse_focus = "true" + +# BIOS/Firmware +firmware_count = 7 +firmware0_desc = "5200.rom (Atari 5200 BIOS)" +firmware0_path = "5200.rom" +firmware0_opt = "true" +firmware1_desc = "ATARIBAS.ROM (Atari BASIC)" +firmware1_path = "ATARIBAS.ROM" +firmware1_opt = "true" +firmware2_desc = "ATARIOSA.ROM (Atari 400/800 OS A)" +firmware2_path = "ATARIOSA.ROM" +firmware2_opt = "true" +firmware3_desc = "ATARIOSB.ROM (Atari 400/800 OS B)" +firmware3_path = "ATARIOSB.ROM" +firmware3_opt = "true" +firmware4_desc = "ATARIXL.ROM (Atari XL/XE OS)" +firmware4_path = "ATARIXL.ROM" +firmware4_opt = "true" +firmware5_desc = "BB01R4_OS.ROM (Atari XL/XE/XEGS OS v4)" +firmware5_path = "BB01R4_OS.ROM" +firmware5_opt = "true" +firmware6_desc = "XEGAME.ROM (Atari XEGS Missile Command)" +firmware6_path = "XEGAME.ROM" +firmware6_opt = "true" +notes = "(!) 5200.rom (md5): 281f20ea4320404ec820fb7ec0693b38|(!) ATARIBAS.ROM (md5): 0bac0c6a50104045d902df4503a4c30b|(!) ATARIOSA.ROM (md5): eb1f32f5d9f382db1bbfb8d7f9cb343a|(!) ATARIOSB.ROM (md5): a3e8d617c95d08031fe1b20d541434b2|(!) ATARIXL.ROM (md5): 06daac977823773a3eea3422fd26a703|(!) BB01R4_OS.ROM (md5): b7a2a04677d34f069eeb643d5238bf86|(!) XEGAME.ROM (md5): d7eb37aec6960cba36bc500e0e5d00bc" + +description = "A port of the free and portable Atari800 emulator to libretro. This core supports games and programs written for the Atari 8-bit computers (400, 800, 600 XL, 800XL, 130XE) and 5200 console. When loaded, the core should boot to the Atari Computer - Memo Pad screen and will generate a .atari800.cfg config file in the frontend's home directory and will add the required BIOS files it detects in the frontend's system directory to the config file. Once that is done, users may manually select which Atari system to emulate through the Atari System core option. These and other options can also be modified through the core's own menu, accessible through the retrokeyboard's F1 key." diff --git a/deps/zlib/adler32.c b/deps/zlib/adler32.c index a868f07..c8f732b 100644 --- a/deps/zlib/adler32.c +++ b/deps/zlib/adler32.c @@ -9,8 +9,6 @@ #define local static -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - #define BASE 65521 /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -21,45 +19,9 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif +#define MOD(a) a %= BASE +#define MOD28(a) a %= BASE +#define MOD63(a) a %= BASE /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) @@ -131,49 +93,3 @@ uLong ZEXPORT adler32(adler, buf, len) /* return recombined sums */ return adler | (sum2 << 16); } - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/deps/zlib/compress.c b/deps/zlib/compress.c deleted file mode 100644 index ea4dfbe..0000000 --- a/deps/zlib/compress.c +++ /dev/null @@ -1,80 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/deps/zlib/crc32.c b/deps/zlib/crc32.c index 979a719..0da509e 100644 --- a/deps/zlib/crc32.c +++ b/deps/zlib/crc32.c @@ -11,188 +11,22 @@ /* @(#) $Id$ */ -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - #include "zutil.h" /* for STDC and FAR definitions */ #define local static -/* Definitions for doing the crc four data bytes at a time. */ -#if !defined(NOBYFOUR) && defined(Z_U4) -# define BYFOUR -#endif -#ifdef BYFOUR - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local z_crc_t FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - z_crc_t c; - int n, k; - z_crc_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (z_crc_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (z_crc_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const z_crc_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const z_crc_t FAR *table; -{ - int n; +#define TBLS 1 - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= * This function can be used by asm versions of crc32() */ const z_crc_t FAR * ZEXPORT get_crc_table() { -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ return (const z_crc_t FAR *)crc_table; } @@ -208,22 +42,6 @@ unsigned long ZEXPORT crc32(crc, buf, len) { if (buf == Z_NULL) return 0UL; -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - z_crc_t endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; @@ -234,192 +52,3 @@ unsigned long ZEXPORT crc32(crc, buf, len) } while (--len); return crc ^ 0xffffffffUL; } - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(ZSWAP32(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/deps/zlib/infback.c b/deps/zlib/infback.c deleted file mode 100644 index 981aff1..0000000 --- a/deps/zlib/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/deps/zlib/trees.c b/deps/zlib/trees.c index 8c32b21..508a0b3 100644 --- a/deps/zlib/trees.c +++ b/deps/zlib/trees.c @@ -32,8 +32,6 @@ /* @(#) $Id$ */ -/* #define GEN_TREES_H */ - #include "deflate.h" #ifdef DEBUG @@ -80,39 +78,7 @@ local const uch bl_order[BL_CODES] #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ +#include "trees.h" struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ @@ -135,7 +101,6 @@ local static_tree_desc static_bl_desc = * Local (static) routines in this file. */ -local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); @@ -155,10 +120,6 @@ local void bi_flush OF((deflate_state *s)); local void copy_block OF((deflate_state *s, charf *buf, unsigned len, int header)); -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - #ifndef DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ @@ -226,163 +187,12 @@ local void send_bits(s, value, length) #endif /* DEBUG */ -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void ZLIB_INTERNAL _tr_init(s) deflate_state *s; { - tr_static_init(); - s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; diff --git a/deps/zlib/uncompr.c b/deps/zlib/uncompr.c deleted file mode 100644 index ad98be3..0000000 --- a/deps/zlib/uncompr.c +++ /dev/null @@ -1,59 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/deps/zlib/zconf.h.in b/deps/zlib/zconf.h.in deleted file mode 100644 index 8a46a58..0000000 --- a/deps/zlib/zconf.h.in +++ /dev/null @@ -1,506 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* ./configure may #define Z_U4 here */ - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# else -# if (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# else -# if (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -# endif -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#ifdef _WIN32 -# include /* for wchar_t */ -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/deps/zlib/zutil.c b/deps/zlib/zutil.c index 65e0d3b..429be5f 100644 --- a/deps/zlib/zutil.c +++ b/deps/zlib/zutil.c @@ -26,119 +26,6 @@ const char * const z_errmsg[10] = { "incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - #if defined(_WIN32_WCE) /* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. diff --git a/deps/zlib/zutil.h b/deps/zlib/zutil.h index 4e3dcc6..39ee13f 100644 --- a/deps/zlib/zutil.h +++ b/deps/zlib/zutil.h @@ -21,13 +21,9 @@ #include "zlib.h" -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif +#include +#include +#include #ifdef Z_SOLO typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ @@ -80,31 +76,12 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* target dependencies */ -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) @@ -179,11 +156,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 0x03 /* assume Unix */ #endif -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ +/* functions */ #if defined(pyr) || defined(Z_SOLO) # define NO_MEMCPY diff --git a/libretro/atari5200_hash.h b/libretro/atari5200_hash.h index 84a9037..2ca2aa9 100644 --- a/libretro/atari5200_hash.h +++ b/libretro/atari5200_hash.h @@ -1,6 +1,21 @@ -#define a5200 0 -#define a5200_40 1 -#define a5200_ee_16 2 +/* This file is no longer used. + It is only for differences between commits. + This file should be removed in the next commit. +*/ + +#define a5200 0 // 4, 8, NS16, 32 +#define a5200_40 1 // Bounty Bob CRC32: 57e7945e +#define a5200_ee_16 2 // 2 16k eeproms +#define a5200_64 3 // supercarts +#define a5200_128 4 +#define a5200_256 5 +#define a5200_512 6 +#define a5200_40_ALT 7 // Bounty Bob CRC32: 7873c6dd + +#define a5200_unsupported 100 +#define a5200_incomplete 101 +#define a5200_bad_dump 102 + typedef struct { int type; @@ -9,114 +24,475 @@ typedef struct { ULONG crc; } a5200_rom; -a5200_rom a5200_game[]={ +a5200_rom a5200_game[] = { { a5200,"5200menu.bin",8192,0x0de2db48}, - { a5200,"aep.bin",16384,0x35484751}, - { a5200,"decathln.bin",16384,0xf43e7cd0}, - { a5200,"asteroid.bin",8192,0x38480891}, - { a5200_ee_16,"astrchse.bin",16384,0x4019ecec}, - { a5200,"ballblze.bin",32768,0x94d97d14}, - { a5200_ee_16,"bzone.bin",16384,0xb3b8e314}, - { a5200,"beamrid.bin",16384,0x9bae58dc}, - { a5200,"berzerk.bin",16384,0xbe3cd348}, - { a5200,"blckbelt.bin",32768,0xed47b0d8}, - { a5200,"blaster.bin",16384,0xc8f9c094}, - { a5200,"blueprnt.bin",16384,0x0624e6e7}, - { a5200_40,"bbstrksb.bin",40960,0x7873c6dd}, - { a5200_ee_16,"buckrog.bin",16384,0x04807705}, - { a5200_ee_16,"centiped.bin",16384,0x536a70fe}, - { a5200,"choplift.bin",16384,0x9ad53bbc}, - { a5200_ee_16,"congo.bin",16384,0xf1f42bbd}, - { a5200_ee_16,"cntrmsre.bin",16384,0xfd541c80}, - { a5200,"pitfall2.bin",16384,0x4b910461}, - { a5200_ee_16,"defender.bin",16384,0xbd52623b}, - { a5200_ee_16,"digdug.bin",16384,0x6a687f9c}, - { a5200,"dredfctr.bin",8192,0x460def2d}, - { a5200,"finalleg.bin",16384,0xd3bd3221}, + { a5200,"A.E. (Proto)",16384,0x35484751}, + { a5200,"Activision Decathlon",16384,0xf43e7cd0}, + { a5200,"Asteroids (USA) (Proto)",8192,0x38480891}, + { a5200_ee_16,"Astro Chase",16384,0x4019ecec}, + { a5200,"Ballblazer",32768,0x94d97d14}, + { a5200,"Ballblazer", 8192, 0xDEF2A207 }, + { a5200_ee_16,"Battle Zone (Proto)",16384,0xb3b8e314}, + { a5200,"Beamrider",16384,0x9bae58dc}, + { a5200,"Berzerk",16384,0xbe3cd348}, + { a5200,"Blackbelt (Proto)",32768,0xed47b0d8}, + { a5200,"Blaster (USA) (Proto)",16384,0xc8f9c094}, + { a5200,"Blue Print",16384,0x0624e6e7}, + { a5200_40_ALT,"Bounty Bob Strikes Back",40960,0x7873c6dd}, // Alternative layout + { a5200_ee_16,"Buck Rogers - Planet of Zoom",16384,0x04807705}, + { a5200_ee_16,"Centipede",16384,0x536a70fe}, + { a5200,"Choplifter!",16384,0x9ad53bbc}, + { a5200_ee_16,"Congo Bongo",16384,0xf1f42bbd}, + { a5200_ee_16,"Counter Measure",16384,0xfd541c80}, + { a5200,"Dave Crane's Pitfall II - Lost Caverns",16384,0x4b910461}, + { a5200_ee_16,"Defender",16384,0xbd52623b}, + { a5200_ee_16,"Dig Dug",16384,0x6a687f9c}, + { a5200,"Dreadnaught Factor, The",8192,0x460def2d}, + { a5200,"Final Legacy (Proto)",16384,0xd3bd3221}, { a5200_ee_16,"friskyt.bin",16384,0x04b299a4}, - { a5200,"frogger.bin",8192,0xae7e3444}, - { a5200_ee_16,"frogger2.bin",16384,0x0af19345}, - { a5200,"galaxian.bin",8192,0x3ef4a23f}, + { a5200,"Frisky Tom (Mouse Speed Fix)",32768,0x04b299a4}, + { a5200,"Frogger",8192,0xae7e3444}, + { a5200_ee_16,"Frogger II - Threeedeep!",16384,0x0af19345}, + { a5200,"Galaxian",8192,0x3ef4a23f}, { a5200,"gorf.bin",8192,0xe955db74}, - { a5200,"gremlins.bin",32768,0x063ec2c4}, - { a5200_ee_16,"gyruss.bin",16384,0xcfd4a7f9}, - { a5200,"hero.bin",16384,0x18a73af3}, - { a5200_ee_16,"jamesbnd.bin",16384,0xd9ae4518}, - { a5200_ee_16,"joust.bin",16384,0xbfd30c01}, - { a5200_ee_16,"jrpacman.bin",16384,0x59983c40}, - { a5200_ee_16,"jungleh.bin",16384,0x2c676662}, - { a5200,"krazysht.bin",8192,0xee702214}, - { a5200,"kaboom.bin",4096,0x420f5d0b}, - { a5200_ee_16,"kangaroo.bin",16384,0xecfa624f}, - { a5200,"keystone.bin",8192,0x8fe3bb2c}, - { a5200,"laststar.bin",16384,0x83517703}, - { a5200_ee_16,"loontoon.bin",16384,0x84df4925}, - { a5200,"mario.bin",32768,0x873742f1}, - { a5200,"meebzork.bin",32768,0x9fb13411}, - { a5200,"megamnia.bin",8192,0x240a1e1a}, - { a5200,"meteorit.bin",16384,0xab8e035b}, + { a5200,"Gremlins",32768,0x063ec2c4}, + { a5200_ee_16,"Gyruss",16384,0xcfd4a7f9}, + { a5200,"H.E.R.O",16384,0x18a73af3}, + { a5200_ee_16,"James Bond 007",16384,0xd9ae4518}, + { a5200_ee_16,"Joust",16384,0xbfd30c01}, + { a5200_ee_16,"J.R. Pac-Man (Proto)",16384,0x59983c40}, + { a5200_ee_16,"Jungle Hunt",16384,0x2c676662}, + { a5200,"K-Razy Shoot-Out",8192,0xee702214}, + { a5200,"Kaboom!",4096,0x420f5d0b}, + { a5200_ee_16,"Kangaroo",16384,0xecfa624f}, + { a5200,"Keystone Kapers",8192,0x8fe3bb2c}, + { a5200,"Last Starfighter, The",16384,0x83517703}, + { a5200_ee_16,"Loony Tunes Hotel (Proto)",16384,0x84df4925}, + { a5200,"Mario Bros.",32768,0x873742f1}, + { a5200,"Meebzork",32768,0x9fb13411}, + { a5200,"MegaMania",8192,0x240a1e1a}, + { a5200,"Meteorites",16384,0xab8e035b}, { a5200_ee_16,"microgam.bin",16384,0x931a454a}, - { a5200,"milliped.bin",16384,0x969cfe1a}, - { a5200,"mine2049.bin",16384,0x7df1adfb}, - { a5200_ee_16,"minigolf.bin",16384,0xc597c087}, - { a5200,"missile.bin",8192,0x44d3ff6f}, - { a5200_ee_16,"montezum.bin",16384,0x2a640143}, - { a5200,"mpatrol.bin",16384,0xd0b2f285}, - { a5200,"mntnking.bin",8192,0x0f24243c}, - { a5200,"docastle.bin",8192,0xaa55f9be}, - { a5200_ee_16,"mspacman.bin",16384,0x752f5efd}, - { a5200_ee_16,"pacman.bin",16384,0x8873ef51}, - { a5200,"pengo.bin",32768,0xe4f8ba8c}, - { a5200,"pitfall.bin",8192,0xb2887833}, - { a5200_ee_16,"polepos.bin",16384,0xabc2d1e4}, - { a5200_ee_16,"popeye.bin",16384,0xa18a9a40}, + { a5200,"Microgammon (Proto)",32768,0x960ce5e2}, + { a5200,"Millipede (Proto).bin",16384,0x969cfe1a}, + { a5200,"Miner 2049er Starring Bounty Bob",16384,0x7df1adfb}, + { a5200_ee_16,"Miniature Golf (Proto)",16384,0xc597c087}, + { a5200,"Missile Command",8192,0x44d3ff6f}, + { a5200_ee_16,"Montezuma's Revenge featuring Panama Joe",16384,0x2a640143}, + { a5200,"Moon Patrol",16384,0xd0b2f285}, + { a5200,"Mountain King",8192,0x0f24243c}, + { a5200,"Mr. Do's Castle",8192,0xaa55f9be}, + { a5200_ee_16,"Ms. Pac-Man",16384,0x752f5efd}, + { a5200_ee_16,"Pac-man",16384,0x8873ef51}, + { a5200,"Pengo",32768,0xe4f8ba8c}, + { a5200,"Pitfall.bin",8192,0xb2887833}, + { a5200_ee_16,"Pole Position",16384,0xabc2d1e4}, + { a5200_ee_16,"Popeye",16384,0xa18a9a40}, { a5200,"qbert.bin",8192,0x3fe4a401}, - { a5200_ee_16,"qix.bin",16384,0xaea6d2c2}, - { a5200,"questroo.bin",16384,0xb5f3402b}, - { a5200,"rsbsebll.bin",32768,0x44166592}, - { a5200,"rsbktbll.bin",32768,0xdd217276}, - { a5200,"rsbktbll1.bin",32768,0xc90196fa}, - { a5200_ee_16,"rsbktbll2.bin",16384,0x0f996184}, - { a5200_ee_16,"rsftball.bin",16384,0x4336c2cc}, - { a5200_ee_16,"rssoccer.bin",16384,0xecbd1853}, - { a5200_ee_16,"rstennis.bin",16384,0x10f33c90}, - { a5200,"fractal.bin",32768,0x762c591b}, - { a5200,"riveraid.bin",8192,0x09fc7648}, - { a5200_ee_16,"roadrun.bin",16384,0xa97606ab}, - { a5200,"robotron.bin",16384,0x4252abd9}, - { a5200_ee_16,"spcedngn.bin",16384,0xb68d61e8}, - { a5200,"spaceinv.bin",8192,0xde5c354a}, - { a5200,"spceshut.bin",16384,0x387365dc}, - { a5200,"spitfire.bin",32768,0x3c311303}, - { a5200_ee_16,"sprtgoof.bin",16384,0x73b5b6fb}, - { a5200_ee_16,"starraid.bin",16384,0x7d819a9f}, - { a5200_ee_16,"startrek.bin",16384,0x69f23548}, - { a5200,"starwars.bin",8192,0x0675f0a5}, - { a5200_ee_16,"swa.bin",16384,0x75f566df}, - { a5200_ee_16,"stargate.bin",16384,0x1d1cee27}, - { a5200,"sprbreak.bin",4096,0xa0642110}, - { a5200,"scobra.bin",8192,0x97debcd2}, - { a5200,"spacman.bin",16384,0x0a4ddb1e}, - { a5200,"tempest.bin",16384,0x1187342f}, - { a5200,"trackfld.bin",16384,0x0ba22ece}, - { a5200,"vanguard.bin",32768,0xcaaea0a4}, - { a5200,"wow.bin",16384,0xd6f7ddfd}, - { a5200_ee_16,"xariarna.bin",16384,0xb8faaec3}, - { a5200,"xevious.bin",32768,0x382634dc}, - { a5200,"yllowsub.bin",4096,0xf47bc091}, - { a5200,"zaxxon.bin",32768,0x741746d1}, - { a5200,"zenji.bin",8192,0xda228530}, - { a5200,"znerangr.bin",16384,0x2959d827}, + { a5200_ee_16,"QIX",16384,0xaea6d2c2}, + { a5200,"Quest For Quintana Roo",16384,0xb5f3402b}, + { a5200,"Realsports Baseball",32768,0x44166592}, + { a5200,"Realsports Basketball",32768,0xdd217276}, + { a5200,"Realsports Basketball (Proto1)",32768,0xc90196fa}, + { a5200_ee_16,"Realsports Basketball (proto)",16384,0x0f996184}, + { a5200_ee_16,"Realsports Football",16384,0x4336c2cc}, + { a5200_ee_16,"Realsports Soccer",16384,0xecbd1853}, + { a5200_ee_16,"RealSports Tennis",16384,0x10f33c90}, + { a5200,"Rescue on Fractalus!",32768,0x762c591b}, + { a5200,"Carol Shaw's River Raid",8192,0x09fc7648}, + { a5200_ee_16,"Road Runner (Proto)",16384,0xa97606ab}, + { a5200,"Robotron 2084",16384,0x4252abd9}, + { a5200_ee_16,"Space Dungeon",16384,0xb68d61e8}, + { a5200,"Space Invaders",8192,0xde5c354a}, + { a5200,"Space Shuttle",16384,0x387365dc}, + { a5200,"Spitfire (Proto)",32768,0x3c311303}, + { a5200_ee_16,"Sport Goofy (Proto)",16384,0x73b5b6fb}, + { a5200_ee_16,"Star Raiders",16384,0x7d819a9f}, + { a5200_ee_16,"Star Trek - Strategic Operations Simulator",16384,0x69f23548}, + { a5200,"Star Wars - Death Star Battle",8192,0x0675f0a5}, + { a5200_ee_16,"Star Wars - The Arcade Game",16384,0x75f566df}, + { a5200_ee_16,"Stargate (Proto)",16384,0x1d1cee27}, + { a5200,"Super Breakout",4096,0xa0642110}, + { a5200,"Super Cobra",8192,0x97debcd2}, + { a5200,"Super Pac-Man (USA) (Proto)",16384,0x0a4ddb1e}, + { a5200,"Tempest (Proto)",16384,0x1187342f}, + { a5200,"Track And Field",16384,0x0ba22ece}, + { a5200,"Vanguard",32768,0xcaaea0a4}, + { a5200,"Wizard Of Wor",16384,0xd6f7ddfd}, + { a5200_ee_16,"Xari Arena (Proto)",16384,0xb8faaec3}, + { a5200_ee_16,"Xari Arena (9-20-83)",16384,0x29178296}, + { a5200,"Xevious",32768,0x382634dc}, + { a5200,"Yellow Submarine (Proto)",4096,0xf47bc091}, + { a5200,"Zaxxon",32768,0x741746d1}, + { a5200,"Zenji",8192,0xda228530}, + { a5200,"Zone Ranger",16384,0x2959d827}, { a5200,"petetest.bin",8192,0x28278cd6}, { a5200_ee_16,"pamdiag2.bin",16384,0xe8b130c4}, { a5200_ee_16,"pamdg23.bin",16384,0xce07d9ad}, { a5200,"finaltst.bin",8192,0x7ea86e87}, { a5200,"boogie.bin",4096,0x3bd5fdd6}, - { a5200,"cblast.bin",32768,0x7c988054}, - { a5200,"ccrisis.bin",32768,0xd50e4061}, - { a5200,"koffiyk.bin",32768,0x917be656}, - { a5200,"tempest (atariage).bin",32768,0xa6400e17}, + { a5200,"Boogie",16384,0x7a9d9f85}, + { a5200,"Castle Blast",32768,0x7c988054}, + { a5200,"Castle Crisis",32768,0xd50e4061}, + { a5200,"Koffi - Yellow Kopter",32768,0x917be656}, + { a5200,"Tempest (Atariage)",32768,0xa6400e17}, + { a5200,"Abracadabra",32768, 0x538a852e}, + { a5200,"3-D Tic-Tac-Toe", 32768, 0x38ec4bfe }, + { a5200,"Adventure 2 (Advanced - Special)", 32768, 0xaa600fac }, + { a5200,"Adventure 2 (Easy - Intermediate)", 32768, 0x69cc2cd6 }, + { a5200,"Alien Assault 2121 (A800)", 32768, 0x0dd8c1a0 }, + { a5200,"Analog Classics #1 (A800)", 32768, 0x3e382e45 }, + { a5200,"Ant Eater (A800)", 16384, 0x821f0d97 }, + { a5200,"Archon (A800)", 32767, 0x7bef7c2d }, + { a5200,"Asteroids (5200 Hack)", 8192, 0x28ec3d93 }, + { a5200,"Asteroids (A800)(Improved Defense-Slow Flip)", 16384, 0x0ce7a6e6 }, + { a5200,"Asteroids (A800)", 16384, 0x4e4bf0bd }, + { a5200,"Asteroids Vector Edition", 16384, 0xdd5ecbaa }, + { a5200,"Atlantis", 32768, 0xc99db95f }, + { a5200,"Attack of the Mutant Camels (A800)", 32768, 0x15cafede }, + { a5200,"Baby Berks", 32768, 0x8bc856cc }, + { a5200,"Bacterion (A800)", 8192, 0x4a2056d5 }, + { a5200,"Barnstorming", 16384, 0xf9addb80 }, + { a5200,"Basketball (A800)", 16384, 0x84acbf42 }, + { a5200,"Batty Builders (A800)", 32768, 0x67261f79 }, + { a5200,"BC's Quest For Tires (A800)", 32768, 0xa3a16596 }, + { a5200,"Beef Drop - Ultimate SD Digital Edition", 32768, 0x55545848 }, + { a5200,"Beef_Drop Demo (Fixed level 3)", 32768, 0x48a43bae }, + { a5200,"Blowsub", 16384, 0x3aa7bc0e }, + { a5200,"Boogie", 16384, 0x7a9d9f85 }, + { a5200,"BoulderDash (A800)", 32768, 0x00b9a3f4 }, + { a5200_40,"Bounty Bob Strikes Back", 40960, 0x57e7945e }, + { a5200,"Bowling", 16384, 0xd7237961 }, + { a5200,"Buried Bucks (A800)", 32768, 0x1d161671 }, + { a5200,"Captain Beeble (A800)", 32768, 0x2b760c6e }, + { a5200,"Capture The Flag (A800)", 16384, 0xd1d31e79 }, + { a5200,"Caverns Of Mars 2 (A800)", 16384, 0x2fdb70c1 }, + { a5200,"Caverns Of Mars (A800)", 32768, 0xd1b64581 }, + { a5200,"Caverns Of The Lost Miner (A800)", 32768, 0xff93b2db }, + { a5200,"Chess (Parker Brothers) (A800)", 32768, 0x0f6c1af4 }, + { a5200,"Chicken (A800)", 32768, 0xb2d018b1 }, + { a5200,"Chop Suey", 32768, 0x0244c402 }, // Autodetected as non-cart. Check afile.c for correct detection hack. + { a5200,"Christmas Cart", 16384, 0x38f4a6a4 }, + { a5200,"Claim Jumper (A800)", 16384, 0xb0553a77 }, + { a5200,"Cloud Burst (A800)", 16384, 0x58a0d074 }, + { a5200,"Clowns & Balloons (A800)", 32768, 0x0dafa507 }, + { a5200,"Crossfire (A800)", 32768, 0xd56be4bc }, + { a5200,"Crystal Castles (Clay) (A800)", 32768, 0xd3b10b5d }, + { a5200,"Crystal Castles (A800)", 32768, 0x596F61D1 }, + { a5200,"Curse Of The Lost Miner (A800)", 32768, 0x8cabcad2 }, + { a5200,"Curse Of The Lost Mines (A800)", 32768, 0xc15a1d9d }, + { a5200,"Deluxe Invaders (A800)", 16384, 0xaf796cfc }, + { a5200,"Demon Attack (A800)", 32768, 0x2174730e }, + { a5200,"Desmonds Dungeon (A800)", 32768, 0x1273a5d1 }, + { a5200,"Diamond Mine (A800)", 32768, 0x7882a1c0 }, + { a5200,"Dig Dug 10-9 (A800)", 32768, 0x89fde0da }, + { a5200,"Donkey Kong Arcade (Hack) (A800)", 32768, 0x8eee62a0 }, + { a5200,"Donkey Kong Jr Arcade (Hack) (A800)", 32768, 0x624cf75c }, + { a5200,"Donkey Kong Jr Enhanced (Hack) (A800)", 32768, 0x383a9157 }, + { a5200,"Donkey Kong Jr (A800)", 32768, 0xb136c3f5 }, + { a5200,"Donkey Kong (A800)", 32768, 0xe902c79e }, + { a5200,"Drelbs (A800)", 16384, 0xbce9e1c2 }, + { a5200,"Ducks Ahoy (A800)", 32768, 0x7a10c551 }, + { a5200,"Dust In The Wind", 32768, 0xf92da5f7 }, + { a5200,"Embargo (A800)", 16384, 0x803808cf }, + { a5200,"EMI Pool (A800)", 16384, 0x5b3ceac8 }, + { a5200,"Encounter (A800)", 32768, 0x6bd0efea }, + { a5200,"Enduro (5200)", 8192, 0x327633db }, + { a5200,"ET Phone Home! (A800)", 32768, 0x5e82a934 }, + { a5200,"Fast Eddie (A800)", 32768, 0xbc0d17bd }, + { a5200,"Fast Food (A800)", 16384, 0x246651b1 }, + { a5200,"Fishing Derby (A800)", 16384, 0xf8583e78 }, + { a5200,"Floyd The Droid (A800)", 8192, 0x89b2d7e5 }, + { a5200,"Forbidden Forest - Slinky (A800)", 32768, 0x219615d9 }, + { a5200,"Fort Apocalypse (A800)", 32768, 0x1b809acc }, + { a5200,"Freecell XE (A800)", 32768, 0x2d2a2807 }, + { a5200,"Freeway (A800)", 16384, 0xb506352f }, + { a5200,"Frisky Tom (Mouse speed fix) (Proto)", 32768, 0x37622411 }, + { a5200,"Frostbite 400 (A800)", 16384, 0x97e75867 }, + { a5200,"Galactic Chase (A800)", 8192, 0x4c5f1847 }, + { a5200,"Galaga (Proto) (A800)", 32768, 0xecda2354 }, + { a5200,"Gateway To Apshai (A800)", 32768, 0x59ec9114 }, + { a5200,"Gauntlet Demo", 32768, 0x3f7f9bd9 }, + { a5200,"Gebelli Compilation (A800)", 32768, 0xc05ff97c }, + { a5200,"Gorf (Digital)", 32768, 0x7f732dc9 }, + { a5200,"Gunpowder Charlie (A800)", 8192, 0x8deefa2f }, + { a5200,"Hyperblast! (A800)", 32768, 0x5ae93e04 }, + { a5200,"Intellidiscs", 32768, 0xe76a0fb6 }, + { a5200,"Ixion (A800)", 32768, 0xa84e68b9 }, + { a5200,"Jawbreaker (A800)", 32768, 0xb6150460 }, + { a5200,"Jet Boot Jack (A800)", 32768, 0xaf210f8e }, + { a5200,"Journey To The Planets (A800)", 32768, 0x31498fe6 }, + { a5200,"Jumpman Jr. (A800)", 32768, 0xfb35d43b }, + { a5200,"Juno First (A800)", 32768, 0x34928a3f }, + { a5200,"K-Star Patrol (A800)", 32768, 0xcb5355b9 }, + { a5200,"Kid Grid (A800)", 8192, 0x2ad24e49 }, + { a5200,"Kooky Diver 2021 (A800)", 32768, 0xe64eb7f1 }, + { a5200,"Kooky Klimber 2021 (A800)", 32768, 0xd0fe471b }, + { a5200,"Kooky's Quest 2021 (A800)", 32768, 0xd1425786 }, + { a5200,"Laser Gates (A800)", 32768, 0x73a3f5f4 }, + { a5200,"Magical Fairy Force (A800)", 32768, 0x2619c4f2 }, + { a5200,"Major Blink", 32768, 0xfe9abd19 }, + { a5200,"Mario Bros Arcade (A800)", 32768, 0x0d9ee13e }, + { a5200,"Missile Command Plus (A800)", 32768, 0xda25c34a }, + { a5200,"Mr. Cool (A800)", 32768, 0xb132a38d }, + { a5200,"Ms Pac-Man Encore (A800)", 32768, 0xdaeae9ad }, + { a5200,"Necromancer (A800)", 32768, 0x5b7303ed }, + { a5200,"O'Riley's Mine (A800)", 32768, 0x646bbe82 }, + { a5200,"Oil's Well (A800)", 32768, 0x0f77eb0d }, + { a5200,"Pac-man Fixed Munch", 32768, 0x21966b5c }, + { a5200,"Pac-man Plus (A800)", 32768, 0xd3363d1c }, + { a5200,"Pacman Arcade Demo V2 (A800)", 32768, 0xb3351c89 }, + { a5200,"Pacific Coast Highway (A800)", 32768, 0x4cc139d0 }, + { a5200,"Pastfinder (A800)", 32768, 0x366c9c2a }, + { a5200,"Phobos (A800)", 16384, 0x2fb8412a }, + { a5200,"Phoenix 2021 (A800)", 32768, 0x4ad9e737 }, + { a5200,"Pinhead", 16384, 0x2af2aa4b }, + { a5200,"Piracy 1621 (A800)", 32768, 0x762ec09c }, + { a5200,"Pitfall! (Classics Fix)", 32768, 0x78cd4061 }, + { a5200,"Pitstop (A800)", 32768, 0xc23d81f5 }, + { a5200,"Pooyan (A800)", 32768, 0x28210510 }, + { a5200,"Popeye Arcade (A800)", 32768, 0x87c94e0b }, + { a5200,"Preppie! II (A800)", 32768, 0x790a8be1 }, + { a5200,"Preppie! (A800)", 32768, 0x47dc1314 }, + { a5200,"Protector II (A800)", 32768, 0x2c1615d0 }, + { a5200,"Q-bert (No Button)", 8192, 0xaaf3d843 }, + { a5200,"Rainbow Walker (A800)", 16384, 0xcfe4aa0c }, + { a5200,"Rally Speedway (A800)", 32768, 0xd9e3fb4d }, + { a5200,"Rampage (A800)", 32768, 0xb3f352f2 }, + { a5200,"Ramses' Revenge 2021 BC (A800)", 32768, 0xc5aae92b }, + { a5200,"Raster Music Tracker", 32768, 0xc790a3a0 }, + { a5200,"Ratcatcher (A800)", 32768, 0x17c7708d }, + { a5200,"Realsports Curling", 32768, 0x0b5b6fbb }, + { a5200,"Rob n Banks (A800)", 32768, 0x9c34cc76 }, + { a5200,"Robot Dungeon 2121 (A800)", 32768, 0x971027bd }, + { a5200,"Rockball (A800)", 32768, 0xb975d952 }, + { a5200,"Rolltris (A800)", 32768, 0x39eb84a0 }, + { a5200,"Runner Bear (A800)", 32768, 0x9a4f1056 }, + { a5200,"Satan's Hollow (A800)", 32768, 0xfdf0f296 }, + { a5200,"Savage Pond (A800)", 16384, 0xc1f458e6 }, + { a5200,"Scramble (A800)", 32768, 0x41e48cff }, + { a5200,"Sea Chase (A800)", 16384, 0xa87c92e0 }, + { a5200,"Sea Dragon (A800)", 16384, 0x20b68254 }, + { a5200,"Shamus Case II (A800)", 32768, 0xa0e29983 }, + { a5200,"Shamus (A800)", 32768, 0x04eb6f41 }, + { a5200,"Sinistar (A800)", 32768, 0xfb1429b4 }, + { a5200,"Slime (A800)", 32768, 0x4b098ebc }, + { a5200,"Space Assailants 2121 (A800)", 32768, 0xb10338f5 }, + { a5200,"SpeedAce (A800)", 32768, 0x4e35e0fc }, + { a5200,"Spy Hunter (A800)", 32768, 0x4eff1e32 }, + { a5200,"Star Rider (A800)", 16384, 0xb9a9a96b }, + { a5200,"Tapper (A800)", 32768, 0xc18d30fa }, + { a5200,"Tempest (AtariAge)", 32768, 0x015e08b0 }, + { a5200,"Tennis (A800)", 16384, 0xd7e15040 }, + { a5200,"Thetris (A800)", 32768, 0x2f02d826 }, + { a5200,"TimeRunner (A800)", 32768, 0x6483d20c }, + { a5200,"TimeSlip (A800)", 32768, 0x97a9e3f7 }, + { a5200,"Train 1 (A800)", 32768, 0x6e32458b }, + { a5200,"Train 2 (A800)", 32768, 0x3f26a60c }, + { a5200,"Train 3 (A800)", 32768, 0x8716e7c8 }, + { a5200,"Turmoil (A800)", 32768, 0xe3ae4170 }, + { a5200,"Up'n Down (A800)", 32768, 0xb08ca999 }, + { a5200,"Yahtzee 2021 (A800)", 32768, 0x63a5dc8f }, + { a5200,"Worm War I (A800)", 32768, 0x271fdab5 }, + { a5200,"Yar's Strike (A800)", 8192, 0xd1c6f325 }, + { a5200,"Zaxxon 32k (A800)", 32768, 0xbddfd255 }, + { a5200_64,"Berks4", 65536, 0x56aca9c3 }, + { a5200_64,"Dropzone (A800)", 65536, 0x42214594 }, + { a5200_64,"ET Phone Home! (A800)", 65536, 0x0fd0ef86 }, + { a5200_64,"Laser Hawk (A800)", 65536, 0x2e2bee02 }, + { a5200_64,"Mr. Do (A800)", 65536, 0x4d66d5ab }, + { a5200_64,"M.U.L.E (A800)", 65536, 0x1f21446e }, + { a5200_64,"Oil's Well (Title) (A800)", 65536, 0x6a1ebc7d }, + { a5200_64,"Rampage 64K (A800)", 65536, 0xdf48d7d4 }, + { a5200_64,"Sea Dragon 64k (A800)", 65536, 0x66b4ea6b }, + { a5200_64,"Super Pac-man 64k (A800)", 65536, 0x93866191 }, + { a5200_512,"Bosconian (A800)", 524288, 0xbbc7d63c }, // Graphical glitches + /* TOSEC BIN */ + /* excluding .bin files that are actual .car files and files in previous lines */ + /* Filenames are truncated */ + /* TOSEC v2022-07-10 = 169 new*/ + { a5200,"Activision Decathlon, The (1983)",32768,0x1f9ed238}, // Marked as bad dump but it seems to work + { a5200,"Asteroids (1983)(Atari)(US)(prot",16384,0x8d2aaab5}, + { a5200,"Ballblazer (1986)(Atari - Lucasf",32768,0xdef2a207}, + { a5200,"Barroom Baseball (1983)(Atari)(U",32768,0x21d19c8f}, + { a5200,"Beamrider (1983)(Activision)(US)",32768,0x02d9b87a}, // Marked as bad dump but it seems to work + { a5200,"Beamrider (1983)(Activision)(US)",32768,0x71fa5a79}, + { a5200_bad_dump,"Berzerk (1983)(Atari)(US)[b][CX5",32767,0xcbf1a137}, // Marked as bad dump but it seems to work + { a5200,"Berzerk (1983)(Atari)(US)[o][CX5",32768,0xcc740e26}, + { a5200,"Blue Print (1983)(CBS Electronic",16384,0x13734e17}, + { a5200,"Blue Print (1983)[b2]",32768,0x40d08988}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Blue Print (1983)[b]",32767,0x74a59340}, + { a5200,"Blue Print (1983)(CBS Electronic",32768,0x69584e01}, + { a5200,"Blue Print (1983)(CBS Electronic",32768,0x746c3b89}, + { a5200,"Blue Print (1983)(CBS Electronic",32768,0x613b9379}, + { a5200,"Boogie (198x)(Atari)(US)(proto)[",8192,0x4e75738a}, + { a5200_incomplete,"Bounty Bob Strikes Back!...[a]",16384,0x74e6a611}, // No game: bank 0 of Bounty Bob. Get 0x57e7945e or 0x7873c6dd + { a5200_incomplete,"Bounty Bob Strikes Back!...[a2]",16384,0xefa4915d}, // No game: bank 1 of Bounty Bob. Get 0x57e7945e or 0x7873c6dd + { a5200_incomplete,"Bounty Bob Strikes Back!...[a3]",8192,0x02931055}, // No game: fixed memory module of Bounty Bob. Get 0x57e7945e or 0x7873c6dd + { a5200_ee_16,"Buck Rogers - Planet of Zoom...[a]",16384,0x20df4927}, + { a5200_bad_dump,"Buck Rogers - Planet of Zoom...[b2]",32768,0xa3f12cce}, + { a5200_bad_dump,"Buck Rogers - Planet of Zoom...[b]",32768,0xc8035788}, + { a5200,"Castle Blast (demo) (2002)(Habot",32768,0x2e0b4c50}, + { a5200,"Castle Blast v0.03 (demo) (2002)",32768,0xfa0648ef}, + { a5200,"Choplifter! (1984)(Atari)(US)[o]",32768,0x0851d277}, + { a5200_ee_16,"Congo Bongo (1983)(Sega)(US)[a][",16384,0x82b91800}, + { a5200_bad_dump,"Congo Bongo (1983)(Sega)(US)[b2]",32768,0x28ec8516}, + { a5200_bad_dump,"Congo Bongo (1983)(Sega)(US)[b][",32768,0x7bb360f5}, + { a5200,"Countermeasure (1982)(Atari)(US)",32768,0xa993c86e}, + { a5200,"Cross Bomber (2020-08-26)(Caruso",32768,0x83b5a291}, + { a5200,"Cross Bomber (2021-05-13)(Caruso",32768,0xe5c152d4}, + { a5200,"Cross Chase (2017-09-15)(Caruso,",16384,0x97a1898a}, + { a5200,"Cross Chase (2017-10-11)(Caruso,",16384,0x6ab5db54}, + { a5200,"Cross Chase (2017-10-30)(Caruso,",16384,0x8772e3e8}, + { a5200,"Cross Chase (2017-12-10)(Caruso,",16384,0x3ffeea23}, + { a5200,"Cross Chase (2018-02-03)(Caruso,",16384,0x93707c56}, + { a5200,"Cross Chase (2018-04-15)(Caruso,",16384,0xb00eaf87}, + { a5200,"Cross Chase (2018-05-19)(Caruso,",16384,0xd801446e}, + { a5200,"Cross Chase (2018-07-19)(Caruso,",16384,0x93067bf4}, + { a5200,"Cross Chase (2018-08-04)(Caruso,",16384,0x8f546594}, + { a5200,"Cross Chase (2018-10-29)(Caruso,",16384,0x4ccb6886}, + { a5200,"Cross Chase (2020-04-02)(Caruso,",16384,0x01ff6c85}, + { a5200,"Cross Chase (2021-05-13)(Caruso,",32768,0x057b0342}, + { a5200,"Cross Horde (2021-04-16)(Caruso,",32768,0xa3ba0993}, + { a5200,"Cross Horde (2021-04-25)(Caruso,",32768,0xec6aa2f7}, + { a5200,"Cross Horde v1.0 (2021-05-01)(Ca",32768,0xeb925e18}, + { a5200,"Cross Shoot (2020-07-03)(Caruso,",32768,0x719ba5cf}, + { a5200,"Cross Snake Preview (2020-12-05)",32768,0x0adfa450}, + { a5200,"Cross Snake v1.0 (2020-12-12)(Ca",32768,0xc49f3fa9}, + { a5200,"Cross Snake v2.0 (2020-12-31)(Ca",32768,0x8790deff}, + { a5200,"David Crane's Pitfall II - Lost ",32768,0x14db6854}, + { a5200,"Defender (1982)(Atari)(US)[b2][C",32768,0xebad58ba}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Defender (1982)(Atari)(US)[b][CX",28672,0x0d7454a1}, + { a5200,"Dig Dug (1983)(Atari)(US)[b][CX5",32768,0xd29bb9a9}, // Marked as bad dump but it seems to work + { a5200,"Dreadnaught Factor, The (1983)(A",16384,0x7226fee6}, + { a5200,"Frogger (1983)(Parker Brothers)(",8192,0x99dc4f40}, + { a5200_bad_dump,"Frogger (1983)(Parker Brothers)(",32768,0x8db0dde4}, + { a5200,"Frogger (1983)(Parker Brothers)[b]",16384,0x1062ef6a}, // Marked as bad dump but it seems to work + { a5200,"Frogger (1983)(Parker Brothers)(",32768,0x7936aa92}, + { a5200,"Frogger (1983)(Parker Brothers)(",16384,0x0b7e77fc}, + { a5200_ee_16,"Frogger II - Threeedeep! (1984)[a]",16384,0xdc1437d0}, + { a5200,"Frogger II - Threeedeep! (1984)[b]",32768,0x1418c44a}, + { a5200_ee_16,"Frogger II - Threeedeep! (1984)[o2][a]",16384,0x0fe438b3}, + { a5200,"Frogger II - Threeedeep! (1984)[o][a]",32768,0x110d6fbc}, + { a5200_bad_dump,"Galaxian (1982)(Atari)(US)[b][CX",32766,0x430f87d1}, + { a5200,"Galaxian (1982)(Atari)(US)[o2][C",16384,0xd4977e3b}, + { a5200,"Galaxian (1982)(Atari)(US)[o][CX",32768,0xa6dfa355}, + { a5200,"Gorf (1983)(CBS Electronics - Ba",16384,0x97b15243}, + { a5200,"Gremlins (1986)(Atari)(US)[b2][C",32768,0x15d0cfc2}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Gremlins (1986)(Atari)(US)[b][CX",32768,0xb1d4dc8e}, + { a5200,"H.E.R.O. (1984)(Activision)(US)[",32768,0x9af4db28}, // Marked as bad dump but it seems to work + { a5200,"H.E.R.O. (1984)(Activision)(US)[",32768,0xf145a21c}, + { a5200_bad_dump,"James Bond 007 (1983)(Parker Bro",32768,0x6e70b70b}, + { a5200_bad_dump,"James Bond 007 (1983)(Parker Bro",32768,0x4f1374b7}, + { a5200,"Joust (1983)(Atari)(US)[b][CX524",32768,0x6b9b16dc}, // Marked as bad dump but it seems to work + { a5200_ee_16,"Jr. Pac-Man (1984)(Atari)[a]",16384,0x7c30592c}, + { a5200_bad_dump,"Jr. Pac-Man (1984)(Atari)[b2]",16384,0x4da19779}, + { a5200_bad_dump,"Jr. Pac-Man (1984)(Atari)[b]",32768,0x3ecc921e}, + { a5200,"Jum's Pong (2000)(Jum)(PD).bin",32768,0xad95c112}, + { a5200,"Jungle Hunt (1983)(Atari)(US)[b]",32768,0xfdccde25}, // Marked as bad dump but it seems to work + { a5200,"K-Razy Shootout (1983)(CBS Elect",16384,0x02cdfc70}, + { a5200,"Kaboom! (1983)(Activision)(US)[o",16384,0x8591be3d}, + { a5200_ee_16,"Kangaroo (1983)(Atari)(US)[b2][C",16384,0x673c989f}, + { a5200,"Kangaroo (1983)(Atari)(US)[b][CX",32768,0xfecb2a41}, + { a5200,"Kangaroo (1983)(Atari)(US)[o][CX",32768,0xdb292060}, + { a5200_bad_dump,"Keystone Kapers (1984)(Activisio",32768,0x22163e26}, + { a5200,"Keystone Kapers (1984)(Activisio",32768,0xe905ed94}, + { a5200,"Koffi - Yellow Kopter (demo) (20",32768,0xd7047701}, + { a5200,"Last Starfighter, The (1984)[b]",32768,0x3761527f}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Looney Tunes Hotel (1983)(Atari)[b2]",32768,0x57761b66}, + { a5200,"Looney Tunes Hotel (1983)(Atari)[b3]",32768,0xb1cec23f}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Looney Tunes Hotel (1983)(Atari)[b]",8192,0xb9ea8f11}, + { a5200,"Mario Bros. (1983)(Atari)(US)[a]",32768,0x6b3f1179}, + { a5200_bad_dump,"Mario Bros. (1983)(Atari)(US)[b]",32768,0xd90f8119}, + { a5200,"Megamania (1983)(Activision)(US)",16384,0x74163d4b}, + { a5200,"Meteorites (1983)(Electra Concep",32768,0x6287fd9b}, + { a5200,"Millipede (1984)(Atari)(US)(prot",32768,0xfcb208a3}, + { a5200,"Miner 2049er (1983)(Big Five Sof",32768,0xf03d6b06}, + { a5200,"Miniature Golf (1983)(Atari)(US)",32768,0x621f8e89}, // Marked as bad dump but it seems to work + { a5200,"Missile Command (1982)(Atari)[b2]",32768,0x915d6952}, // Marked as bad dump but it seems to work + { a5200,"Missile Command (1982)(Atari)[b3]",32768,0xd3f15631}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Missile Command (1982)(Atari)[b]",32768,0x8de027d5}, + { a5200,"Montezuma's Revenge (1984)(Parke",32768,0xbcf677fb}, // Marked as bad dump but it seems to work + { a5200,"Moon Patrol (1983)(Atari)(US)[o]",32768,0xa8c7d41e}, + { a5200,"Mountain King (1983)(CBS Electro[o2]",16384,0xf6c6feaa}, + { a5200,"Mountain King (1983)(CBS Electro[o]",32768,0x4992f047}, + { a5200_bad_dump,"Mr. Do!'s Castle (1984)(Parker B[b2]",32768,0x0d367519}, + { a5200_bad_dump,"Mr. Do!'s Castle (1984)(Parker B[b]",16384,0x7f7ea877}, + { a5200,"Mr. Do!'s Castle (1984)(Parker B[o]",16384,0x457fb9b3}, + { a5200_bad_dump,"Ms. Pac-Man (1983)(Atari)(US)[b2",32768,0xaf6091c1}, + { a5200,"Ms. Pac-Man (1983)(Atari)(US)[b]",32768,0xe9e2c34b}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Pac-Man (1982)(Atari)(US)[b2][CX",16383,0x117368af}, + { a5200,"Pac-Man (1982)(Atari)(US)[b3][CX",32768,0xe7952627}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Pac-Man (1982)(Atari)(US)[b][CX5",32766,0x34b673ed}, + { a5200_bad_dump,"Pengo (1983)(Atari)(US)[b][CX523",32768,0x968d727d}, + { a5200,"Pitfall! (1984)(Activision)(US)[",16384,0x72066f45}, + { a5200_bad_dump,"Popeye (1984)(Parker Brothers)(U",32768,0x1cee2326}, + { a5200_bad_dump,"Q-bert (1983)(Parker Brothers)[b]",32768,0x2ffe9622}, + { a5200,"Q-bert (1983)(Parker Brothers)[o]",16384,0x3c33f26e}, + { a5200,"Qix (1982)(Atari)(US)[b2][CX5221",32768,0x85f750d4}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Qix (1982)(Atari)(US)[b][CX5221]",32768,0xb346d4ab}, + { a5200,"Quest for Quintana Roo (1984)(Su",32768,0x9dbf341f}, + { a5200,"RatCatcher (2016-06)(Witmer, Rya",32768,0x1af6982c}, + { a5200,"RealSports Baseball (1983)(Atari",32768,0xde0fa87c}, + { a5200,"RealSports Basketball (proto)[a]",32768,0xdb834f88}, + { a5200,"RealSports Football (1982)[b]",32768,0x7a182f89}, // Marked as bad dump but it seems to work + { a5200_ee_16,"RealSports Soccer (1983)(Atari)[a]",16384,0x3d75d4dc}, + { a5200,"RealSports Soccer (1983)(Atari)[b2]",32768,0x295435b6}, // Marked as bad dump but it seems to work + { a5200,"RealSports Soccer (1983)(Atari)[b]",32768,0x13c459d5}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"River Raid (1983)(Activision)[b2]",32768,0x51c5bc75}, + { a5200_bad_dump,"River Raid (1983)(Activision)[b]",32768,0x6615d5db}, + { a5200,"River Raid (1983)(Activision)[o]",16384,0x1f6730ba}, + { a5200,"Road Runner (1982)(Atari)(US)[b]",32768,0x1b38dac0}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Robotron - 2084 (1983)(Atari)[b]",32767,0x538f2354}, + { a5200,"Robotron - 2084 (1983)(Atari)[o2]",32768,0xec80b709}, + { a5200,"Robotron - 2084 (1983)(Atari)[o]",32768,0x301a76b7}, + { a5200,"Shooting Gallery (2012)(Mihai, S",32768,0x54238bca}, + { a5200_bad_dump,"Space Invaders (1982)(Atari)[b]",32768,0x91fae605}, + { a5200,"Space Invaders (1982)(Atari)[o2]",16384,0x53c6c68a}, + { a5200,"Space Invaders (1982)(Atari)[o]",32768,0x218e1be4}, + { a5200,"Space Shuttle - A Journey Into S[o]",32768,0x404aedac}, + { a5200,"Spitfire (1984)(Atari)(US)[a]",32768,0xdb982c2f}, + { a5200_bad_dump,"Sport Goofy (1983)(Atari)(US)[b2]",32768,0x7bb4a0ab}, + { a5200,"Sport Goofy (1983)(Atari)(US)[b3]",32768,0xede41a3f}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Sport Goofy (1983)(Atari)(US)[b]",8192,0x97486a66}, + { a5200,"Star Raiders (1982)(Atari)(US)[b2]",32768,0xbf574b31}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Star Raiders (1982)(Atari)(US)[b3]",32764,0x19aa7a20}, + { a5200_bad_dump,"Star Raiders (1982)(Atari)(US)[b]",16382,0x78d28196}, + { a5200,"Star Trek - Strategic Operations[b]",32768,0x519a9574}, // Marked as bad dump but it seems to work + { a5200,"Star Wars - Return of the Jedi [b]",32768,0x08c8ed8a}, // Marked as bad dump but it seems to work + { a5200,"Stargate (1984)(Atari)(US)(proto[b]",32768,0x3229c915}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Super Breakout (1982)(Atari)(US)[b]",32768,0x54ed2ead}, + { a5200,"Super Breakout (1982)(Atari)(US)[o2]",16384,0x1d02a598}, + { a5200,"Super Breakout (1982)(Atari)(US)[o]",32768,0x6f4a78f6}, + { a5200_bad_dump,"Super Cobra (1983)(Parker Brothe[b]",32768,0xd917c276}, + { a5200,"Super Cobra (1983)(Parker Brothe[o2]",16384,0x82e14ae9}, + { a5200,"Super Cobra (1983)(Parker Brothe[o]",32768,0xf0a99787}, + { a5200,"Track and Field (1984)(Atari)(US",32768,0x203d9cde}, + { a5200_bad_dump,"Vanguard (1983)(Atari)(US)[b][CX",32767,0x98b3123a}, + { a5200_bad_dump,"Wizard of Wor (1983)(CBS Electro[b]",32768,0x60cfe8d6}, + { a5200,"Wizard of Wor (1983)(CBS Electro[o]",32768,0xa4bf0093}, + { a5200,"Xari Arena (1983)(Atari)(US)[b2]",32768,0x78861424}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Xari Arena (1983)(Atari)(US)[b]",32768,0xc36cc9b2}, + { a5200_bad_dump,"Xevious (1984)(Atari)(US)(proto)",32767,0x135655a9}, + { a5200,"Yellow Submarine (1982)(Atari)[o2]",8192,0x3cd986c5}, + { a5200,"Yellow Submarine (1982)(Atari)[o]",16384,0x12cc298f}, + { a5200,"Zaxxon (1984)(Sega)(US)[b][008-0",32768,0x8304aefc}, // Marked as bad dump but it seems to work + { a5200,"Zenji (1984)(Activision)(US)[b][",32768,0x1ab5e425}, + { a5200,"Zenji (1984)(Activision)(US)[o][",16384,0xca1a962a}, + { a5200,"Zone Ranger (1984)(Activision)(U",32768,0x02c9abc6}, + /* End of TOSEC v2022-07-10*/ + /* No-Intro. Excluding .a52/.bin files that are actual .car files and files in previous lines*/ + /* No-Intro v2024-04-28 = 9 new */ + { a5200,"Astrogrover (USA) (Proto).a52",32768,0x18417ada}, + { a5200,"Battlezone (USA) (Proto) (Alt).a",32768,0x7d32a6ca}, + { a5200,"Behind Jaggi Lines! (USA) (Proto",32768,0x9dd7776a}, + { a5200,"Galaxian (USA) (Alt).a52",8192,0x3a6e6133}, + { a5200_ee_16,"Gyruss (USA) (Alt).a52",16384,0x4241582d}, + { a5200,"Pole Position (USA) (Proto).a52",32768,0x15b7b5ef}, + { a5200_ee_16,"Star Raiders (USA) (Alternate).a",16384,0x4bac5dd9}, + { a5200,"Star Trek - Strategic Operations (Alt)",16384,0x33b70206}, + { a5200_ee_16,"Super Pacman (USA) (Proto) (Alt)",16384,0xfd8f0cd4}, + /* End of No-Intro v2024-04-28 */ { -1,"",0,0}, } ; - diff --git a/libretro/atari800_hash.h b/libretro/atari800_hash.h new file mode 100644 index 0000000..361eca7 --- /dev/null +++ b/libretro/atari800_hash.h @@ -0,0 +1,421 @@ +/* This file is no longer used. + It is only for differences between commits. + This file should be removed in the next commit. +*/ + +#define a800 0 // STD_8, STD_16, XEGS_32 +#define a800_40 1 // Bounty Bob +#define a800_WILL_64 2 // 64 KB Williams cartridge +#define a800_XE_07_64 3 // XEGS 64 KB cartridge (banks 0-7) +#define a800_XE_128 4 // XEGS 128 KB cartridge +//#define a800_XE_256 4 // XEGS 256 KB cartridge. Not sure if any exist. +//#define a800_XE_512 5 // XEGS 512 KB cartridge. Not sure if any exist. +//#define a800_XE_1024 6 // XEGS 1 MB cartridge. Not sure if any exist. +#define a800_MAX_128 5 // Atarimax 128 KB Flash cartridge +#define a800_MAX_1024 6 // Atarimax 1 MB Flash cartridge (old) +#define a800_OSS_M091_16 15 // OSS one chip 16 KB cartridge +#define a800_TURBOSOFT_64 50 // Turbosoft 64 KB cartridge (Chile - Unlicensed) +#define a800_TURBOSOFT_128 51 // Turbosoft 128 KB cartridge (Chile - Unlicensed) +#define a800_TURBOSOFT_64_WILL 99 // Turbosoft 64 KB cartridge with Williams banking (Chile - Unlicensed) + +#define a800_unsupported 100 +#define a800_incomplete 101 +#define a800_bad_dump 102 + +typedef struct { + int type; + char name[50]; + int size; + ULONG crc; +} a800_rom; + +a800_rom a800_game[] = { + + { a800,"3-D Tic-Tac-Toe",8192,0x1cf50ebe}, + { a800,"Abracadabra!",16384,0xa35c775d}, + { a800_XE_128,"Ace Of Aces",131072,0xebad3ddb}, + { a800,"Activision Decathlon",16384,0x7cc0118b}, + { a800,"Adventure Creator",16384,0x8746d9da}, + { a800_XE_128,"Airball",131072,0xa0ccb3c1}, + { a800,"Alf In Color Caves",16384,0x79df7f9d}, + { a800,"Alien Ambush",8192,0xad7bc30b}, + { a800,"Alien Garden",8192,0x3e27ed0f}, + { a800,"Alpha Shield",8192,0xa7ade454}, + { a800_MAX_1024,"Alternate Reality- The City (MF) (Proto)",1048576,0x52cbd474}, + { a800_MAX_1024,"Alternate Reality- The Dungeon (MF)v9",1048576,0x9fd8d4d3}, + { a800,"Ant Eater",8192,0xc7290722}, + { a800,"Archon- The Light And The Dark",32768,0x2636829f}, + { a800_MAX_128,"Arkanoid I, II, III (MF)",131072,0x70f7bbe5}, + { a800,"Asteroids",8192,0xf9fff4a4}, + { a800,"Astro Chase (First Star Software)",16384,0x18752991}, + { a800,"Astro Chase",16384,0x11f1c7fa}, + { a800,"Atlantis",8192,0xbe0b390c}, + { a800,"Attack At EP-CYG-4",163834,0xdca02ca0}, + { a800,"Attack Of The Mutant Camels",163834,0xc933d741}, + { a800_XE_07_64,"Ballblazer",65536,0x820e5ce5}, + { a800,"Baseball",16384,0x065c3fd2}, + { a800,"Basketball",8192,0x79934851}, + { a800_XE_07_64,"Battlezone",65536,0x692515f2}, + { a800,"BC's Quest For Tires",16384,0xdddc6e36}, + { a800,"Beamrider",16384,0x2b05b8df}, + { a800_MAX_128,"Beyond Castle Wolfenstein (MF)",131926,0xf454689b}, + { a800,"Blue Max",32768,0x003f41ac}, + { a800,"Blaster",16384,0xce1126a2}, + { a800,"Boulderdash",16384,0xaf778329}, + { a800,"Boulders And Bombs",16384,0xab2ec21c}, + { a800_40,"Bounty Bob Strikes Back!",40960,0x0d00f072}, + { a800,"Bristles",16384,0x4263d64d}, + { a800_XE_07_64,"Bruce Lee (Repro)",65536,0x255dfc59}, + { a800,"Buck Rogers - Planet Of Zoom",16384,0x84dd597c}, + { a800,"Captain Beeble",16384,0xad8400b1}, + { a800,"Carnival Massacre (CS)",16384,0xea764851}, + { a800,"Carnival Massacre",16384,0x1baf0c97}, + { a800,"Castle Crisis",32768,0x47acda14}, + { a800,"Castle Hassle",16384,0x5a9e938a}, + { a800,"Castles And Keys",16384,0xbe14c091}, + { a800,"Caverns Of Mars",16384,0x8b9b2f5e}, + { a800,"Centipede",8192,0x44bb1842}, + { a800,"Chess",8192,0x72860db1}, + { a800,"Chicken",8192,0x1ab4d8d8}, + { a800,"Choplifter! (Broderbund)",16384,0x3ebc05ff}, + { a800_XE_07_64,"Choplifter!",65536,0xd426eccc}, + { a800,"Claim Jumper",16384,0x1a333c4a}, + { a800,"Cloudburts",8192,0x259aa18b}, + { a800_XE_128,"Commando",131072,0x28288df4}, // Autodetected as xex. Check afile.c for correct detection hack. + { a800,"Computer Chess",8192,0x5ce06e94}, + { a800,"Computer War",16384,0x4922aac6}, + { a800_MAX_1024,"Conan (MF)",1048576,0x25feb642}, + { a800,"Congo Bongo",16384,0x7a588045}, + { a800,"Cosmic Life",16384,0x919eaaa9}, + { a800,"Cosmic Tunnels",16384,0xad56c2bf}, + { a800,"Crossfire",8192,0x4d7e0503}, + { a800,"Crystal Castles",32768,0x998fa803}, + { a800,"Dance Fantasy",8192,0xfaec94e7}, + { a800_XE_07_64,"Dark Chambers",65536,0xfa2f132c}, + { a800_XE_07_64,"David's Midnight Magic",65536,0xb7ca61a2}, + { a800,"Defender",16384,0x782a81e4}, + { a800_XE_07_64,"Deflektor",65536,0xe4ed154e}, + { a800,"Deluxe Invaders",8192,0x15dc9b31}, + { a800,"Demo Cart",16384,0x9bedcdf3}, + { a800,"Demon Attack",8192,0x91328072}, + { a800_XE_07_64,"Desert Falcon",65536,0xa8f9324d}, + { a800,"Diamond Mine",16384,0xd8f9b867}, + { a800,"Dig Dug (1983)",16384,0xfdbc57ed}, + { a800,"Dig Dug",16384,0x6d68114e}, + { a800,"Donkey Kong Jr.",16384,0xa4eb70ef}, + { a800,"Donkey Kong",16384,0xf2b76a27}, + { a800,"Dreadnaught Factor",8192,0xc26fbb5b}, + { a800,"Droids",8192,0x5bb0c159}, + { a800,"Ducks Ahoy",16384,0x4cdfceb9}, + { a800_WILL_64,"DynaKillers",65536,0xad050724}, + { a800,"Eastern Front (1941)",16384,0xccff4a03}, + { a800,"Enduro",8192,0xa538a1bb}, + { a800_MAX_128,"Eidolon- The (MF)",131072,0x46f363f7}, + { a800,"Embargo",8192,0x07b1560c}, + { a800,"Espial",16384,0x64946757}, + { a800,"E.T. Phone Home",16384,0xbce4ef51}, + { a800,"Fantastic Voyage",8192,0x7bde2593}, + { a800,"Fast Eddie",8192,0x53ac386a}, + { a800,"Fast Food",8192,0x77223249}, + { a800_XE_128,"Fight Night",131072,0x4440d167}, + { a800,"Final Legacy",16384,0x6bd0d8e4}, + { a800,"Final Orbit",8192,0x177007e9}, + { a800,"Firebird",8192,0xe3c0b5f1}, + { a800,"Flapper",16384,0x18803c52}, + { a800_XE_128,"Flight Simulator II",131072,0x10cfc489}, + { a800,"Flip And Flop",16384,0x8ae057be}, + { a800_MAX_1024,"Flob 1.0.3b",1048576,0xff236e36}, + { a800,"Food Fight",32767,0x4236f0ea}, + { a800,"Fort Apocalypse",16384,0xf79b33f0}, + { a800,"Fortune Hutner",8192,0x03255972}, + { a800,"Frogger II - Threeedeep!",16384,0xed35f49c}, + { a800,"Frogger",8192,0x40e9476c}, + { a800,"Galaxian",8192,0xd60027be}, + { a800,"Gateway To Apshai",16384,0x3a0c6eb0}, + { a800_XE_128,"G.A.T.O.",131072,0xab06a3f5}, + { a800_MAX_128,"Gauntlet (MF)",131072,0x48cface0}, + { a800,"Gold Mine",8192,0x8459b11e}, + { a800,"Gorf",8192,0x90d0c7d7}, + { a800,"Gridrunner",8192,0x752dd5fe}, + { a800,"Gyruss",16384,0x1da47d01}, + { a800,"H.E.R.O.",16384,0x6062d3ce}, + { a800,"Halftime Battlin Bands",16384,0x8d14b5d3}, + { a800_XE_07_64,"Hardball",65536,0xbf0c6df2}, + { a800,"Hypnotic Land",16384,0x4fb75909}, + { a800,"Into The Eagles Nest",32768,0xf31321c2}, + { a800,"James Bond 007",16384,0x19b4e3a1}, + { a800,"Jawbreaker II",8192,0xe2a63a2d}, + { a800_MAX_1024,"Jim Slide XL",1048576,0x5f74de4a}, + { a800,"Journey To The Planets",16384,0xdce59b65}, + { a800,"Joust",16384,0xf6ec618c}, + { a800,"Jumbo Jet Pilot",16384,0xf046332b}, + { a800_MAX_128,"Jumpman",131072,0x4b7beb03}, + { a800,"Jumpman Jr.",16384,0x6c79bbad}, + { a800,"Jungle Hunt",16384,0x1847a7d4}, + { a800,"K-Razy Antiks",8192,0x84ab21b0}, + { a800,"K-razy Kritters (K-Byte)",8192,0x50354927}, + { a800,"K-razy Kritters",8192,0xf854a3b4}, + { a800,"K-razy Shoot-Out (CBS)",8192,0x636a01f5}, + { a800,"K-razy Shoot-Out (K-Byte)",8192,0x4300f6ff}, + { a800,"K-Star Patrol",8192,0x44c71fae}, + { a800,"Kangaroo",16384,0x1ef94906}, + { a800_XE_128,"Karateka",131072,0x97646f16}, + { a800,"Keystone Kapers",8192,0x465e1763}, + { a800,"Kickback",8192,0x2480ed0a}, + { a800_MAX_128,"Koronis Rift (MF)",131072,0xd385b89c}, + { a800_XE_128,"Lode Runner",131072,0x7790f474}, + { a800_MAX_1024,"Lords Of Conquest (MF)",1048576,0x3d6c01bb}, + { a800_MAX_1024,"M.U.L.E. (MF)",1048576,0x0b84f03e}, + { a800,"Major League Hockey",8192,0x4ffbc999}, + { a800_XE_07_64,"Mario Bros. XE",65536,0x7ba07c34}, + { a800,"M.A.S.H.",8192,0xfa041093}, + { a800,"Matterhorn",16384,0xdcc308cf}, + { a800,"Megamania",8192,0xb3c5130c}, + { a800_XE_128,"Mean 18 (Proto)",131072,0x0ee74a89}, + { a800_XE_128,"Midi Maze (Proto)",131072,0x193a53f6}, + { a800,"Millipede",16384,0xfb7e45da}, + { a800,"Miner 2049er",16384,0x6b1478bf}, + { a800,"Missile Command",8192,0xd2e36392}, + { a800,"Missile Command (XEGS built in)",8192,0xbdca01fb}, + { a800,"Mogul Maniac",16384,0x0c391600}, + { a800,"Monster Maze",16384,0x37049e57}, + { a800,"Montezuma's Revenge (prototype)",16384,0xbd4404d9}, + { a800,"Moon Patrol",16384,0xb845edb8}, + { a800,"Mountain King",8192,0x79748c93}, + { a800,"Mr. Cool",8192,0x1345d10c}, + { a800,"Mr. Do's Castle",8192,0xf1b9a24a}, + { a800,"Mr. TNT",8192,0x701dbdea}, + { a800,"Mrs. Pac-Man",16384,0xf91d18cf}, + { a800_MAX_128,"Mysterious Adventures (MF)",131072,0xadd506c5}, + { a800,"Necromancer",16384,0x39250ff2}, + { a800,"Nightstrike",8192,0x61245a75}, + { a800,"Oil's Well",16384,0x030ecad6}, + { a800,"One-On-One - Dr J. Vs Larry Bird",32768,0xab060567}, + { a800_MAX_1024,"onEscape (121422) (MF)",1048576,0x083fb021}, + { a800,"Orc Attack",16384,0xfbfaefcd}, + { a800,"Ozzy's Orchard",16384,0x1554b983}, + { a800,"Pac-Man",8192,0x61cf6167}, + { a800_MAX_128,"Pac-Man Arcade",131072,0x19bc1482}, + { a800,"Pastfinder",16384,0x12694c3f}, + { a800,"Peanut Butter Panic",8192,0xcdeb7759}, + { a800,"Pengo",16384,0xd8a9fe0a}, + { a800,"Picnic Paranoia",16384,0xe386a621}, + { a800,"Pitfall! II - The Lost Caverns",16384,0x1668cf3b}, + { a800,"Pitfall!",8192,0xb58bdf1c}, + { a800,"Pitstop",16384,0xd49ebf91}, + { a800,"Plattermania",8192,0x6cef6f94}, + { a800,"Pole Position",16384,0x581570C4}, + { a800,"Pool 400",8192,0xa6c2130f}, + { a800,"Popeye",16384,0x00fce79a}, + { a800,"Porky's",16384,0x1733d3fc}, + { a800,"Powerstar",16384,0xdc0dca6e}, + { a800,"Princes And The Frog",8192,0x7ce79281}, + { a800_MAX_1024,"Prince of Persia 211206 (MF)",1048576,0x52df819c}, + { a800,"Protector II",16384,0x374f311f}, + { a800,"Q-bert",8192,0xff3f0472}, + { a800,"Qix",8192,0x967b8051}, + { a800,"Rack'em Up",16384,0x5335d935}, + { a800,"Rally Speedway",16384,0x0a0f6ea2}, + { a800,"Realsports Football",16384,0x5e8951f4}, + { a800,"Realsports Tennis",16384,0x9a34cbdc}, + { a800_XE_07_64,"Rescue On Fractalus",65536,0x1ca549ad}, + { a800,"Risk (Proto)",8192,0x688b0a0c}, + { a800,"River Raid",8192,0x6e601d81}, + { a800,"River Rescue",16384,0xc018c8a0}, + { a800,"Robotron 2084",16384,0x528fc44a}, + { a800,"Satan's Hollow",16384,0x0f7c7934}, + { a800_MAX_128,"Scott Adams Adventures (MF)",131072,0x5446bcb1}, + { a800,"Sea Chase",8192,0x99b5a1dd}, + { a800,"Sea Fox",16384,0x932cc9a8}, + { a800,"Serpentine",8192,0x1b555b41}, + { a800,"Shamus",16384,0xbd3f06ee}, + { a800,"Silicon Warrior",16384,0x0736c8ae}, + { a800,"Slime",16384,0x1babcad6}, + { a800,"Soccer",8192,0x784c7060}, + { a800_MAX_1024,"Space Harrier",1048576,0xca98abfc}, + { a800,"Space Invaders",8192,0x6c811a10}, + { a800,"Space Shuttle",16384,0x66832f68}, + { a800,"Spark Bugs",8192,0xf56eced2}, + { a800,"Speedway Blast",8192,0xf895cc47}, + { a800,"Spider City",8192,0x8f8c3841}, + { a800,"Springer",16384,0x81466b55}, + { a800,"Spy Hunter",16384,0x34df8ffc}, + { a800,"Squish Em",8192,0xe01600b8}, + { a800,"Stargate (Proto)",16384,0xf527b721}, + { a800,"Star Raiders II",32768,0x737d4196}, + { a800,"Star Raiders",8192,0x5ec023ba}, + { a800,"Star Trek - Strategic Operations Simulator",16384,0x9df169d9}, + { a800,"Star Wars - Arcade Game - The",16384,0xaea795f7}, + { a800,"Star Wars - Death Star Battle",16384,0xd9f5cac7}, + { a800,"Starion",16384,0x23faf9b3}, + { a800,"Submarine Commander",16384,0x77198b2b}, + { a800_MAX_1024,"Summer Games (MF)",1048576,0x92325dc3}, + { a800_XE_128,"Summer Games",131072,0x95e6932d}, + { a800,"Super Cobra",8192,0x2af38d2f}, + { a800,"Super Pac-Man (Early Proto)",16384,0xb985be78}, + { a800,"Super Pac-Man (Proto)",16384,0xb518dda8}, + { a800,"Super Zaxxon",16384,0x9e64e13b}, + { a800,"Survival Of The Fittest",8192,0x7f48fbc5}, + { a800_XE_07_64,"Tapper (Cart)",65536,0xeff12440}, + { a800_XE_07_64,"Thunderfox",65536,0xb15ccef2}, + { a800,"Topper",16384,0x0286eea6}, + { a800_XE_07_64,"Tower Toppler (Proto)",65536,0x6b5333bd}, + { a800,"Track And Field",16384,0x9e2484c8}, + { a800,"Turmoil",8192,0xfe48aadf}, + { a800,"Typo Attack",16384,0x89da4ff7}, + { a800,"Typo",8192,0x70585854}, + { a800_MAX_1024,"Ultima II - Revenge of the Enchantress",1048576,0xd2a6db16}, + { a800_MAX_1024,"Ultima III (MF)",1048576,0xb132a1da}, + { a800_MAX_1024,"Ultima IV (MF)",1048576,0x62b1571f}, + { a800,"Up'n Down",16384,0x53ea3bf6}, + { a800,"Wizard Of Wor",16384,0x8017e56a}, + { a800_MAX_128,"World Karate Championship (MF)",131072,0x83c87b17}, + { a800,"Worm War I",8291,0x79934b01}, + { a800_XE_128,"Xenophobe",131072,0x68466666}, + { a800,"Zaxxon",16384,0x21579706}, + { a800,"Zenji",16384,0xebc6ec2e}, + { a800,"Zone Ranger",16384,0x8f1e72e7}, + /* Turbosoft Chile Unlicensed multicarts - Retrogames.cl ROM dumps = 16 new */ + /* Some games on the multicarts do not work, even with Atari800 5.2.0 or Altirra 4.21 emulators */ + { a800_TURBOSOFT_64_WILL,"Turbosoft C1 (Retrogames.cl dump)",65536,0xb2b45500}, + { a800_TURBOSOFT_64,"Turbosoft C2 (Retrogames.cl dump)",65536,0xade93e66}, + { a800_TURBOSOFT_64_WILL,"Turbosoft C3 (Retrogames.cl dump)",65536,0xbedf99fe}, + { a800_TURBOSOFT_64_WILL,"Turbosoft C4 (Retrogames.cl dump)",65536,0x97a8c904}, // Autodetected as non-cart. Check afile.c for correct detection hack. + { a800_TURBOSOFT_64_WILL,"Turbosoft C5 (Retrogames.cl dump)",65536,0x78dbb563}, + { a800_TURBOSOFT_64_WILL,"Turbosoft C6 (Retrogames.cl dump)",65536,0x49e18f6e}, + { a800_TURBOSOFT_128,"Turbosoft D1 (Retrogames.cl dump)",131072,0x4d1dd418}, + { a800_TURBOSOFT_128,"Turbosoft D2 (Retrogames.cl dump)",131072,0x025ab67a}, + { a800_TURBOSOFT_128,"Turbosoft D3 (Retrogames.cl dump)",131072,0xbca7d11b}, + { a800_TURBOSOFT_128,"Turbosoft D4 (Retrogames.cl dump)",131072,0x72df4a5e}, + { a800_MAX_128,"Turbosoft D5 (Retrogames.cl dump)",131072,0xa5aee6fd}, // Autodetected as non-cart. Check afile.c for correct detection hack. + { a800_TURBOSOFT_128,"Turbosoft D6 (Retrogames.cl dump)",131072,0x5498c7dc}, + { a800_TURBOSOFT_128,"Turbosoft D7 (Retrogames.cl dump)",131072,0x3fb92d9e}, + { a800_TURBOSOFT_64,"Turbosoft D8 (Retrogames.cl dump)",131072,0x3d68152e}, + { a800_MAX_128,"Turbosoft E1 (Retrogames.cl dump)",131072,0xfa100cbf}, + { a800_TURBOSOFT_128,"Turbosoft E2 (Retrogames.cl dump)",131072,0xbede95cd}, + /* End of Turbosoft multicarts*/ + /* TOSEC BIN - excluding .bin files that are actual .car files and files in previous lines */ + /* TOSEC v2006-03-29 = 3 new*/ + { a800_OSS_M091_16,"Action!",16384,0x0bcd70c6}, + { a800,"Asteroids",8192,0x7ed3e6a3}, + { a800,"Defender",16384,0x161cbe09}, + /* End of TOSEC v2006-03-29*/ + /* TOSEC v2022-07-10 = 115 new*/ + { a800,"3-D Tic-Tac-Toe (1979)(Atari)[!]",8192,0x4660c404}, + { a800,"Alpha Shield (1983)(Sirius Softw",8192,0x484e8443}, + { a800,"Animated Puzzle (1984)(Atari)(US",16384,0x1a4c75a7}, + { a800,"Animated Puzzle (1984)(Atari)(US",16384,0x90f37afe}, + { a800,"Ant Eater (1982)(Romox)(US)[a].b",8192,0x18702a0f}, + { a800,"Ant Eater (1982)(Romox)[earlier ",8192,0x73a3a64c}, + { a800,"Arex (1983)(Adventure Internatio",16384,0x2a080e7d}, + { a800,"Atlantis (1983)(Imagic)(US)[!][7",8192,0xf929f40f}, + { a800,"Baseball (1983)(Inhome Software)",16384,0x43c9d2a0}, + { a800,"Basketball (1979)(Atari)(US)[!][",8192,0x1ba8d718}, + { a800,"Beef Drop (demo) (2004-08-11)(Si",32768,0xd209e797}, + { a800,"Berzerk (1983)(Atari)(proto).bin",16384,0xb1dedb79}, + { a800_unsupported,"Bomb Jake (2009)(GR8 Software)(P",532480,0x8e89ca50}, // Corina 512K + 512K SRAM + 8K EEPROM cartridge not supported yet + { a800,"Boulders and Bombs (1982)(CBS So",8192,0xd6d51d3e}, + { a800_40,"Bounty Bob Strikes Back! (1984)(",40960,0xcc7912ed}, + { a800,"Carnival Massacre (1983)(Thorn E",16384,0x0c8e8d5b}, + { a800,"Centipede (1981)(Atari)(US)(prot",8192,0xd54f0200}, + { a800,"Chiffres et des Lettres, Des (19",16384,0xc7705c53}, + { a800,"Chiffres et des Lettres, Des (19",16384,0x3d8f5c25}, + { a800,"Claim Jumper (1982)(Synapse Soft",16384,0x374d14d9}, + { a800,"Cloudburst (1982)(DANA)(US)[!].b",8192,0x32e5629e}, + { a800,"Computer Chess (1979)(Atari)(US)",8192,0xc9614423}, + { a800,"Congo Bongo (1983)(Sega)(US).bin",16384,0x7a588045}, + { a800,"Conquest of the Crown (1994)(Lin",16384,0x94f56b90}, + { a800,"Cosmic Life (1983)(Spinnaker Sof",8192,0xec65758b}, + { a800,"Crystal Castles (1984)(Atari)(US",16384,0xe3ec1080}, + { a800,"Crystal Castles (1984)(Atari)(US",16384,0x89bb9431}, + { a800,"Crystal Castles (1984)(Atari)(US",16384,0x6c64892c}, + { a800,"Crystal Raiders (2001)(Video 61 ",16384,0xf15b2306}, + { a800,"Da' Fuzz (1983)(Roklan)(US).bin",16384,0xb94f66ea}, + { a800,"Da' Fuzz (1983)(Roklan)(US)[a].b",8192,0xbcda6dba}, + { a800,"Danger Ranger (1984)(Microdeal)[",8192,0xf5497ef3}, + { a800,"Decathlon (1984)(Activision)(US)",16384,0x76845603}, + { a800,"Decathlon (1984)(Activision)(US)",16384,0xaffbe54b}, + { a800,"Defender (1982)(Atari)(US)[!][CX",16384,0x782a81e4}, + { a800,"Defender Rev. 2 (1982)(Atari)(US",16384,0xfcb4b36f}, + { a800,"Delta Drawing v3.23 (1983)(Spinn",8192,0x20cbad07}, + { a800,"Demon Attack (1982)(Imagic)[!][O",8192,0x1cb8b52d}, + { a800,"Destiny - The Cruiser (198x)(Adv",16384,0x0c847bb3}, + { a800,"Dig Dug (1982)(Atari)(US).bin",16384,0x29b44ff6}, + { a800,"Donkey Kong (1983)(Atari)(US)[!]",16384,0x8a406275}, + { a800,"Donkey Kong Junior (1983)(Atari)",16384,0xa3e2d833}, + { a800,"Droids (1983)(TG Software)(US).b",8192,0x440082e6}, + { a800_WILL_64,"Dropzone (20xx)(Video 61).bin",65536,0x4870ed52}, + { a800,"Espial (1984)(Tigervision)(US).b",16384,0xdcde7482}, + { a800,"Excelsor (1986)(Players)[p].bin",8192,0xa854cc63}, + { a800,"Explorer (1984)(Activision)(prot",16384,0x98a4e5b7}, + { a800,"Fantastic Voyage (1982)(Sirius S",16384,0xea2c9b8f}, + { a800,"Fantastic Voyage (1982)(Sirius S",8192,0xcd428e17}, + { a800,"Fast Eddie (1982)(Sirius Softwar",8192,0x0939f2d0}, + { a800,"Final Legacy (1984)(Atari)(US)[G",16384,0x506e4ed0}, + { a800,"Final Orbit (1983)(Sirius Softwa",8192,0x4de5cd53}, + { a800,"Firebird (1981)(Gebelli Software",8192,0xab4f2d14}, + { a800,"Firebird (1981)(Gebelli Software",8192,0xb9557f4b}, + { a800,"Fortune Hunter (1982)(Romox)(US)",8192,0xc0fea1f7}, + { a800,"Fortune Hunter (1982)(Romox)(US)",8192,0x5cee3180}, + { a800,"Frogger II - Threeedeep! (1984)(",16384,0x7a5b4f65}, + { a800,"Frogger II - Threeedeep! (1984)(",8192,0xe924f2bc}, + { a800,"Gateway to Apshai (1983)(Epyx)[6",16384,0x4ccdbef0}, + { a800,"Gridrunner (1983)(HesWare)(US)[a",8192,0x02f44555}, + { a800,"Gyruss (1984)(Parker Brothers)(C",8192,0x0d78e8a9}, + { a800,"Gyruss (1984)(Parker Brothers)(P",8192,0xba14b37b}, + { a800,"Hard Hat Willy (1983)(Inhome Sof",16384,0x214be698}, + { a800_WILL_64,"Jinks (20xx)(Video 61 - Williams",65536,0x39fe57ee}, + { a800,"Jr. Pac-Man (1997)(Video 61 - At",16384,0xebc1db55}, + { a800,"K-Razy Antiks (1982)(CBS Softwar",8192,0xab7bdb79}, + { a800,"K-Star Patrol (1982)(CBS Softwar",8192,0x89c82cc2}, + { a800,"Kaboom! (1983)(Activision)(US)[!",8192,0xc2e2e645}, + { a800,"Laser Gates (1984)(Imagic)[p].bi",16384,0xea2a103e}, + { a800,"Last Starfighter, The (1984)(Ata",16384,0x3267eba7}, + { a800,"Last Starfighter, The (1984)(Ata",16384,0xb4c640f1}, + { a800,"Legacy, The rev7.1 (1984)(Atari)",16384,0xa445af7d}, + { a800,"Lifespan (1983)(Roklan)(US)(prot",16384,0xe4d62c12}, + { a800,"McDonald's Pac-Mac (1983)(Parker",8192,0x209d2e17}, + { a800,"McDonald's Pac-Mac (1983)(Parker",8192,0xca961d16}, + { a800,"Meteor (198x)(Germ-Soft)[p].bin",8192,0xc27ff7df}, + { a800,"Millipede (1983)(Atari)(proto).b",16384,0x82457872}, + { a800,"Miner 2049er (1982)(Big Five Sof",16384,0xeb770df4}, + { a800,"Missile Command+ (2006)(Lee, Pau",16384,0x2acfd240}, + { a800,"Moogles (1983)(Sirius)[p].bin",16384,0x0585fb5a}, + { a800,"Mr Do!'s Castle (1984)(Parker Br",8192,0xabed3b88}, + { a800,"Ms. Pac-Man (1983)(Atari)[!][red",16384,0x4ad748b2}, + { a800,"Orc Attack (1983)(Thorn EMI)(GB)",16384,0x5e9849b1}, + { a800,"Ozzy's Orchard (1983)(TG Softwar",16384,0x1554b983}, + { a800,"Pastfinder (1984)(Activision)[!]",16384,0x14fddfb8}, + { a800,"Popeye (1983)(Parker Brothers)(E",16384,0xa35d5e6a}, + { a800,"Preppie (2001)(Video 61 - Advent",16384,0x52ae50e3}, + { a800,"River Rescue (1983)(Thorn EMI)(G",16384,0xa7d2e0e8}, + { a800,"Silicon Warrior (1983)(Epyx)[!][",16384,0xa7ecc8f7}, + { a800,"Space Invaders (1980)(Atari)[!][",8192,0x3614d0aa}, + { a800,"Space Journey (1983)(Roklan)[09-",16384,0x161657f0}, + { a800,"Speedway Blast (1982)(IDSI)[!][O",8192,0x8e67192b}, + { a800,"Spider City (1983)(Sirius)[!].bi",8192,0xd519f2fb}, + { a800,"Squish 'Em! (1983)(Sirius)[!].bi",8192,0xf0553d6c}, + { a800,"Star Maze (1984)(Roklan)[!][11-0",16384,0x6fd9daff}, + { a800,"Star Trux (1982)(Atari)(proto).b",8192,0x8212c4b7}, + { a800,"Star Wars - Return of the Jedi -",8192,0xa40e15e5}, + { a800,"Submarine Commander (1982)(Thorn",16384,0xce9562eb}, + { a800,"Super Breakout (1979)(Atari)(US)",8192,0xc9066f06}, + { a800,"Super Breakout (1979)(Atari)(US)",8192,0x4da14cf9}, + { a800,"Super Pac-Man (1984)(Atari)(prot",16384,0x4b9b00f5}, + { a800,"Superman III (1983)(Atari)(proto",16384,0x639846d6}, + { a800,"Thera-Med Zahnschutz-Spiel, Das ",8192,0x10df011f}, + { a800,"Timebound (1984)(CBS Software)(U",16384,0xd3e98044}, + { a800,"Trion (1983)(Romox - London Soft",16384,0x2c42362f}, + { a800,"Up Up and Away (1983)(Ringblack ",16384,0xa8261044}, + { a800,"Video Easel (1979)(Atari)(US).bi",8192,0xfb45dae5}, + { a800,"Video Easel (1979)(Atari)(US)[!]",8192,0x276d7acc}, + { a800,"Video Poker Card Game (1998)(Vid",16384,0xdc492963}, + { a800,"Webster - The Word Game (1983)(C",8192,0x6fffb4a9}, + { a800,"Weltraumkolonie (1984)(Spinnaker",8192,0x06fd2cdb}, + { a800,"Worm War 1 (1982)(Sirius)[!].bin",8192,0xd9b120f4}, + { a800_unsupported,"Yie Another Kung-Fu (2011)(GR8 S",1056768,0x8ed7da2d}, // Corina 1M + 8K EEPROM cartridge not supported yet + { a800,"Zone Ranger (1984)(Activision)[!",16384,0x1b6c7b78}, + { a800_WILL_64,"Zybex (1991)(Video 61 - Williams",65536,0xc1da182c}, + /* End of TOSEC v2022-07-10*/ + { -1,"",0,0}, +} ; diff --git a/libretro/carts_hash.c b/libretro/carts_hash.c new file mode 100644 index 0000000..9a3f802 --- /dev/null +++ b/libretro/carts_hash.c @@ -0,0 +1,888 @@ +#include "carts_hash.h" + +const a5200_rom a5200_game[] = { + { a5200,"5200menu.bin",8192,0x0de2db48}, + { a5200,"A.E. (Proto)",16384,0x35484751}, + { a5200,"Activision Decathlon",16384,0xf43e7cd0}, + { a5200,"Asteroids (USA) (Proto)",8192,0x38480891}, + { a5200_ee_16,"Astro Chase",16384,0x4019ecec}, + { a5200,"Ballblazer",32768,0x94d97d14}, + { a5200,"Ballblazer", 8192, 0xDEF2A207 }, + { a5200_ee_16,"Battle Zone (Proto)",16384,0xb3b8e314}, + { a5200,"Beamrider",16384,0x9bae58dc}, + { a5200,"Berzerk",16384,0xbe3cd348}, + { a5200,"Blackbelt (Proto)",32768,0xed47b0d8}, + { a5200,"Blaster (USA) (Proto)",16384,0xc8f9c094}, + { a5200,"Blue Print",16384,0x0624e6e7}, + { a5200_40_ALT,"Bounty Bob Strikes Back",40960,0x7873c6dd}, // Alternative layout + { a5200_ee_16,"Buck Rogers - Planet of Zoom",16384,0x04807705}, + { a5200_ee_16,"Centipede",16384,0x536a70fe}, + { a5200,"Choplifter!",16384,0x9ad53bbc}, + { a5200_ee_16,"Congo Bongo",16384,0xf1f42bbd}, + { a5200_ee_16,"Counter Measure",16384,0xfd541c80}, + { a5200,"Dave Crane's Pitfall II - Lost Caverns",16384,0x4b910461}, + { a5200_ee_16,"Defender",16384,0xbd52623b}, + { a5200_ee_16,"Dig Dug",16384,0x6a687f9c}, + { a5200,"Dreadnaught Factor, The",8192,0x460def2d}, + { a5200,"Final Legacy (Proto)",16384,0xd3bd3221}, + { a5200_ee_16,"friskyt.bin",16384,0x04b299a4}, + { a5200,"Frisky Tom (Mouse Speed Fix)",32768,0x04b299a4}, + { a5200,"Frogger",8192,0xae7e3444}, + { a5200_ee_16,"Frogger II - Threeedeep!",16384,0x0af19345}, + { a5200,"Galaxian",8192,0x3ef4a23f}, + { a5200,"gorf.bin",8192,0xe955db74}, + { a5200,"Gremlins",32768,0x063ec2c4}, + { a5200_ee_16,"Gyruss",16384,0xcfd4a7f9}, + { a5200,"H.E.R.O",16384,0x18a73af3}, + { a5200_ee_16,"James Bond 007",16384,0xd9ae4518}, + { a5200_ee_16,"Joust",16384,0xbfd30c01}, + { a5200_ee_16,"J.R. Pac-Man (Proto)",16384,0x59983c40}, + { a5200_ee_16,"Jungle Hunt",16384,0x2c676662}, + { a5200,"K-Razy Shoot-Out",8192,0xee702214}, + { a5200,"Kaboom!",4096,0x420f5d0b}, + { a5200_ee_16,"Kangaroo",16384,0xecfa624f}, + { a5200,"Keystone Kapers",8192,0x8fe3bb2c}, + { a5200,"Last Starfighter, The",16384,0x83517703}, + { a5200_ee_16,"Loony Tunes Hotel (Proto)",16384,0x84df4925}, + { a5200,"Mario Bros.",32768,0x873742f1}, + { a5200,"Meebzork",32768,0x9fb13411}, + { a5200,"MegaMania",8192,0x240a1e1a}, + { a5200,"Meteorites",16384,0xab8e035b}, + { a5200_ee_16,"microgam.bin",16384,0x931a454a}, + { a5200,"Microgammon (Proto)",32768,0x960ce5e2}, + { a5200,"Millipede (Proto).bin",16384,0x969cfe1a}, + { a5200,"Miner 2049er Starring Bounty Bob",16384,0x7df1adfb}, + { a5200_ee_16,"Miniature Golf (Proto)",16384,0xc597c087}, + { a5200,"Missile Command",8192,0x44d3ff6f}, + { a5200_ee_16,"Montezuma's Revenge featuring Panama Joe",16384,0x2a640143}, + { a5200,"Moon Patrol",16384,0xd0b2f285}, + { a5200,"Mountain King",8192,0x0f24243c}, + { a5200,"Mr. Do's Castle",8192,0xaa55f9be}, + { a5200_ee_16,"Ms. Pac-Man",16384,0x752f5efd}, + { a5200_ee_16,"Pac-man",16384,0x8873ef51}, + { a5200,"Pengo",32768,0xe4f8ba8c}, + { a5200,"Pitfall.bin",8192,0xb2887833}, + { a5200_ee_16,"Pole Position",16384,0xabc2d1e4}, + { a5200_ee_16,"Popeye",16384,0xa18a9a40}, + { a5200,"qbert.bin",8192,0x3fe4a401}, + { a5200_ee_16,"QIX",16384,0xaea6d2c2}, + { a5200,"Quest For Quintana Roo",16384,0xb5f3402b}, + { a5200,"Realsports Baseball",32768,0x44166592}, + { a5200,"Realsports Basketball",32768,0xdd217276}, + { a5200,"Realsports Basketball (Proto1)",32768,0xc90196fa}, + { a5200_ee_16,"Realsports Basketball (proto)",16384,0x0f996184}, + { a5200_ee_16,"Realsports Football",16384,0x4336c2cc}, + { a5200_ee_16,"Realsports Soccer",16384,0xecbd1853}, + { a5200_ee_16,"RealSports Tennis",16384,0x10f33c90}, + { a5200,"Rescue on Fractalus!",32768,0x762c591b}, + { a5200,"Carol Shaw's River Raid",8192,0x09fc7648}, + { a5200_ee_16,"Road Runner (Proto)",16384,0xa97606ab}, + { a5200,"Robotron 2084",16384,0x4252abd9}, + { a5200_ee_16,"Space Dungeon",16384,0xb68d61e8}, + { a5200,"Space Invaders",8192,0xde5c354a}, + { a5200,"Space Shuttle",16384,0x387365dc}, + { a5200,"Spitfire (Proto)",32768,0x3c311303}, + { a5200_ee_16,"Sport Goofy (Proto)",16384,0x73b5b6fb}, + { a5200_ee_16,"Star Raiders",16384,0x7d819a9f}, + { a5200_ee_16,"Star Trek - Strategic Operations Simulator",16384,0x69f23548}, + { a5200,"Star Wars - Death Star Battle",8192,0x0675f0a5}, + { a5200_ee_16,"Star Wars - The Arcade Game",16384,0x75f566df}, + { a5200_ee_16,"Stargate (Proto)",16384,0x1d1cee27}, + { a5200,"Super Breakout",4096,0xa0642110}, + { a5200,"Super Cobra",8192,0x97debcd2}, + { a5200,"Super Pac-Man (USA) (Proto)",16384,0x0a4ddb1e}, + { a5200,"Tempest (Proto)",16384,0x1187342f}, + { a5200,"Track And Field",16384,0x0ba22ece}, + { a5200,"Vanguard",32768,0xcaaea0a4}, + { a5200,"Wizard Of Wor",16384,0xd6f7ddfd}, + { a5200_ee_16,"Xari Arena (Proto)",16384,0xb8faaec3}, + { a5200_ee_16,"Xari Arena (9-20-83)",16384,0x29178296}, + { a5200,"Xevious",32768,0x382634dc}, + { a5200,"Yellow Submarine (Proto)",4096,0xf47bc091}, + { a5200,"Zaxxon",32768,0x741746d1}, + { a5200,"Zenji",8192,0xda228530}, + { a5200,"Zone Ranger",16384,0x2959d827}, + { a5200,"petetest.bin",8192,0x28278cd6}, + { a5200_ee_16,"pamdiag2.bin",16384,0xe8b130c4}, + { a5200_ee_16,"pamdg23.bin",16384,0xce07d9ad}, + { a5200,"finaltst.bin",8192,0x7ea86e87}, + { a5200,"boogie.bin",4096,0x3bd5fdd6}, + { a5200,"Boogie",16384,0x7a9d9f85}, + { a5200,"Castle Blast",32768,0x7c988054}, + { a5200,"Castle Crisis",32768,0xd50e4061}, + { a5200,"Koffi - Yellow Kopter",32768,0x917be656}, + { a5200,"Tempest (Atariage)",32768,0xa6400e17}, + { a5200,"Abracadabra",32768, 0x538a852e}, + { a5200,"3-D Tic-Tac-Toe", 32768, 0x38ec4bfe }, + { a5200,"Adventure 2 (Advanced - Special)", 32768, 0xaa600fac }, + { a5200,"Adventure 2 (Easy - Intermediate)", 32768, 0x69cc2cd6 }, + { a5200,"Alien Assault 2121 (A800)", 32768, 0x0dd8c1a0 }, + { a5200,"Analog Classics #1 (A800)", 32768, 0x3e382e45 }, + { a5200,"Ant Eater (A800)", 16384, 0x821f0d97 }, + { a5200,"Archon (A800)", 32767, 0x7bef7c2d }, + { a5200,"Asteroids (5200 Hack)", 8192, 0x28ec3d93 }, + { a5200,"Asteroids (A800)(Improved Defense-Slow Flip)", 16384, 0x0ce7a6e6 }, + { a5200,"Asteroids (A800)", 16384, 0x4e4bf0bd }, + { a5200,"Asteroids Vector Edition", 16384, 0xdd5ecbaa }, + { a5200,"Atlantis", 32768, 0xc99db95f }, + { a5200,"Attack of the Mutant Camels (A800)", 32768, 0x15cafede }, + { a5200,"Baby Berks", 32768, 0x8bc856cc }, + { a5200,"Bacterion (A800)", 8192, 0x4a2056d5 }, + { a5200,"Barnstorming", 16384, 0xf9addb80 }, + { a5200,"Basketball (A800)", 16384, 0x84acbf42 }, + { a5200,"Batty Builders (A800)", 32768, 0x67261f79 }, + { a5200,"BC's Quest For Tires (A800)", 32768, 0xa3a16596 }, + { a5200,"Beef Drop - Ultimate SD Digital Edition", 32768, 0x55545848 }, + { a5200,"Beef_Drop Demo (Fixed level 3)", 32768, 0x48a43bae }, + { a5200,"Blowsub", 16384, 0x3aa7bc0e }, + { a5200,"Boogie", 16384, 0x7a9d9f85 }, + { a5200,"BoulderDash (A800)", 32768, 0x00b9a3f4 }, + { a5200_40,"Bounty Bob Strikes Back", 40960, 0x57e7945e }, + { a5200,"Bowling", 16384, 0xd7237961 }, + { a5200,"Buried Bucks (A800)", 32768, 0x1d161671 }, + { a5200,"Captain Beeble (A800)", 32768, 0x2b760c6e }, + { a5200,"Capture The Flag (A800)", 16384, 0xd1d31e79 }, + { a5200,"Caverns Of Mars 2 (A800)", 16384, 0x2fdb70c1 }, + { a5200,"Caverns Of Mars (A800)", 32768, 0xd1b64581 }, + { a5200,"Caverns Of The Lost Miner (A800)", 32768, 0xff93b2db }, + { a5200,"Chess (Parker Brothers) (A800)", 32768, 0x0f6c1af4 }, + { a5200,"Chicken (A800)", 32768, 0xb2d018b1 }, + { a5200,"Chop Suey", 32768, 0x0244c402 }, // Autodetected as non-cart. Check afile.c for correct detection hack. + { a5200,"Christmas Cart", 16384, 0x38f4a6a4 }, + { a5200,"Claim Jumper (A800)", 16384, 0xb0553a77 }, + { a5200,"Cloud Burst (A800)", 16384, 0x58a0d074 }, + { a5200,"Clowns & Balloons (A800)", 32768, 0x0dafa507 }, + { a5200,"Crossfire (A800)", 32768, 0xd56be4bc }, + { a5200,"Crystal Castles (Clay) (A800)", 32768, 0xd3b10b5d }, + { a5200,"Crystal Castles (A800)", 32768, 0x596F61D1 }, + { a5200,"Curse Of The Lost Miner (A800)", 32768, 0x8cabcad2 }, + { a5200,"Curse Of The Lost Mines (A800)", 32768, 0xc15a1d9d }, + { a5200,"Deluxe Invaders (A800)", 16384, 0xaf796cfc }, + { a5200,"Demon Attack (A800)", 32768, 0x2174730e }, + { a5200,"Desmonds Dungeon (A800)", 32768, 0x1273a5d1 }, + { a5200,"Diamond Mine (A800)", 32768, 0x7882a1c0 }, + { a5200,"Dig Dug 10-9 (A800)", 32768, 0x89fde0da }, + { a5200,"Donkey Kong Arcade (Hack) (A800)", 32768, 0x8eee62a0 }, + { a5200,"Donkey Kong Jr Arcade (Hack) (A800)", 32768, 0x624cf75c }, + { a5200,"Donkey Kong Jr Enhanced (Hack) (A800)", 32768, 0x383a9157 }, + { a5200,"Donkey Kong Jr (A800)", 32768, 0xb136c3f5 }, + { a5200,"Donkey Kong (A800)", 32768, 0xe902c79e }, + { a5200,"Drelbs (A800)", 16384, 0xbce9e1c2 }, + { a5200,"Ducks Ahoy (A800)", 32768, 0x7a10c551 }, + { a5200,"Dust In The Wind", 32768, 0xf92da5f7 }, + { a5200,"Embargo (A800)", 16384, 0x803808cf }, + { a5200,"EMI Pool (A800)", 16384, 0x5b3ceac8 }, + { a5200,"Encounter (A800)", 32768, 0x6bd0efea }, + { a5200,"Enduro (5200)", 8192, 0x327633db }, + { a5200,"ET Phone Home! (A800)", 32768, 0x5e82a934 }, + { a5200,"Fast Eddie (A800)", 32768, 0xbc0d17bd }, + { a5200,"Fast Food (A800)", 16384, 0x246651b1 }, + { a5200,"Fishing Derby (A800)", 16384, 0xf8583e78 }, + { a5200,"Floyd The Droid (A800)", 8192, 0x89b2d7e5 }, + { a5200,"Forbidden Forest - Slinky (A800)", 32768, 0x219615d9 }, + { a5200,"Fort Apocalypse (A800)", 32768, 0x1b809acc }, + { a5200,"Freecell XE (A800)", 32768, 0x2d2a2807 }, + { a5200,"Freeway (A800)", 16384, 0xb506352f }, + { a5200,"Frisky Tom (Mouse speed fix) (Proto)", 32768, 0x37622411 }, + { a5200,"Frostbite 400 (A800)", 16384, 0x97e75867 }, + { a5200,"Galactic Chase (A800)", 8192, 0x4c5f1847 }, + { a5200,"Galaga (Proto) (A800)", 32768, 0xecda2354 }, + { a5200,"Gateway To Apshai (A800)", 32768, 0x59ec9114 }, + { a5200,"Gauntlet Demo", 32768, 0x3f7f9bd9 }, + { a5200,"Gebelli Compilation (A800)", 32768, 0xc05ff97c }, + { a5200,"Gorf (Digital)", 32768, 0x7f732dc9 }, + { a5200,"Gunpowder Charlie (A800)", 8192, 0x8deefa2f }, + { a5200,"Hyperblast! (A800)", 32768, 0x5ae93e04 }, + { a5200,"Intellidiscs", 32768, 0xe76a0fb6 }, + { a5200,"Ixion (A800)", 32768, 0xa84e68b9 }, + { a5200,"Jawbreaker (A800)", 32768, 0xb6150460 }, + { a5200,"Jet Boot Jack (A800)", 32768, 0xaf210f8e }, + { a5200,"Journey To The Planets (A800)", 32768, 0x31498fe6 }, + { a5200,"Jumpman Jr. (A800)", 32768, 0xfb35d43b }, + { a5200,"Juno First (A800)", 32768, 0x34928a3f }, + { a5200,"K-Star Patrol (A800)", 32768, 0xcb5355b9 }, + { a5200,"Kid Grid (A800)", 8192, 0x2ad24e49 }, + { a5200,"Kooky Diver 2021 (A800)", 32768, 0xe64eb7f1 }, + { a5200,"Kooky Klimber 2021 (A800)", 32768, 0xd0fe471b }, + { a5200,"Kooky's Quest 2021 (A800)", 32768, 0xd1425786 }, + { a5200,"Laser Gates (A800)", 32768, 0x73a3f5f4 }, + { a5200,"Magical Fairy Force (A800)", 32768, 0x2619c4f2 }, + { a5200,"Major Blink", 32768, 0xfe9abd19 }, + { a5200,"Mario Bros Arcade (A800)", 32768, 0x0d9ee13e }, + { a5200,"Missile Command Plus (A800)", 32768, 0xda25c34a }, + { a5200,"Mr. Cool (A800)", 32768, 0xb132a38d }, + { a5200,"Ms Pac-Man Encore (A800)", 32768, 0xdaeae9ad }, + { a5200,"Necromancer (A800)", 32768, 0x5b7303ed }, + { a5200,"O'Riley's Mine (A800)", 32768, 0x646bbe82 }, + { a5200,"Oil's Well (A800)", 32768, 0x0f77eb0d }, + { a5200,"Pac-man Fixed Munch", 32768, 0x21966b5c }, + { a5200,"Pac-man Plus (A800)", 32768, 0xd3363d1c }, + { a5200,"Pacman Arcade Demo V2 (A800)", 32768, 0xb3351c89 }, + { a5200,"Pacific Coast Highway (A800)", 32768, 0x4cc139d0 }, + { a5200,"Pastfinder (A800)", 32768, 0x366c9c2a }, + { a5200,"Phobos (A800)", 16384, 0x2fb8412a }, + { a5200,"Phoenix 2021 (A800)", 32768, 0x4ad9e737 }, + { a5200,"Pinhead", 16384, 0x2af2aa4b }, + { a5200,"Piracy 1621 (A800)", 32768, 0x762ec09c }, + { a5200,"Pitfall! (Classics Fix)", 32768, 0x78cd4061 }, + { a5200,"Pitstop (A800)", 32768, 0xc23d81f5 }, + { a5200,"Pooyan (A800)", 32768, 0x28210510 }, + { a5200,"Popeye Arcade (A800)", 32768, 0x87c94e0b }, + { a5200,"Preppie! II (A800)", 32768, 0x790a8be1 }, + { a5200,"Preppie! (A800)", 32768, 0x47dc1314 }, + { a5200,"Protector II (A800)", 32768, 0x2c1615d0 }, + { a5200,"Q-bert (No Button)", 8192, 0xaaf3d843 }, + { a5200,"Rainbow Walker (A800)", 16384, 0xcfe4aa0c }, + { a5200,"Rally Speedway (A800)", 32768, 0xd9e3fb4d }, + { a5200,"Rampage (A800)", 32768, 0xb3f352f2 }, + { a5200,"Ramses' Revenge 2021 BC (A800)", 32768, 0xc5aae92b }, + { a5200,"Raster Music Tracker", 32768, 0xc790a3a0 }, + { a5200,"Ratcatcher (A800)", 32768, 0x17c7708d }, + { a5200,"Realsports Curling", 32768, 0x0b5b6fbb }, + { a5200,"Rob n Banks (A800)", 32768, 0x9c34cc76 }, + { a5200,"Robot Dungeon 2121 (A800)", 32768, 0x971027bd }, + { a5200,"Rockball (A800)", 32768, 0xb975d952 }, + { a5200,"Rolltris (A800)", 32768, 0x39eb84a0 }, + { a5200,"Runner Bear (A800)", 32768, 0x9a4f1056 }, + { a5200,"Satan's Hollow (A800)", 32768, 0xfdf0f296 }, + { a5200,"Savage Pond (A800)", 16384, 0xc1f458e6 }, + { a5200,"Scramble (A800)", 32768, 0x41e48cff }, + { a5200,"Sea Chase (A800)", 16384, 0xa87c92e0 }, + { a5200,"Sea Dragon (A800)", 16384, 0x20b68254 }, + { a5200,"Shamus Case II (A800)", 32768, 0xa0e29983 }, + { a5200,"Shamus (A800)", 32768, 0x04eb6f41 }, + { a5200,"Sinistar (A800)", 32768, 0xfb1429b4 }, + { a5200,"Slime (A800)", 32768, 0x4b098ebc }, + { a5200,"Space Assailants 2121 (A800)", 32768, 0xb10338f5 }, + { a5200,"SpeedAce (A800)", 32768, 0x4e35e0fc }, + { a5200,"Spy Hunter (A800)", 32768, 0x4eff1e32 }, + { a5200,"Star Rider (A800)", 16384, 0xb9a9a96b }, + { a5200,"Tapper (A800)", 32768, 0xc18d30fa }, + { a5200,"Tempest (AtariAge)", 32768, 0x015e08b0 }, + { a5200,"Tennis (A800)", 16384, 0xd7e15040 }, + { a5200,"Thetris (A800)", 32768, 0x2f02d826 }, + { a5200,"TimeRunner (A800)", 32768, 0x6483d20c }, + { a5200,"TimeSlip (A800)", 32768, 0x97a9e3f7 }, + { a5200,"Train 1 (A800)", 32768, 0x6e32458b }, + { a5200,"Train 2 (A800)", 32768, 0x3f26a60c }, + { a5200,"Train 3 (A800)", 32768, 0x8716e7c8 }, + { a5200,"Turmoil (A800)", 32768, 0xe3ae4170 }, + { a5200,"Up'n Down (A800)", 32768, 0xb08ca999 }, + { a5200,"Yahtzee 2021 (A800)", 32768, 0x63a5dc8f }, + { a5200,"Worm War I (A800)", 32768, 0x271fdab5 }, + { a5200,"Yar's Strike (A800)", 8192, 0xd1c6f325 }, + { a5200,"Zaxxon 32k (A800)", 32768, 0xbddfd255 }, + { a5200_64,"Berks4", 65536, 0x56aca9c3 }, + { a5200_64,"Dropzone (A800)", 65536, 0x42214594 }, + { a5200_64,"ET Phone Home! (A800)", 65536, 0x0fd0ef86 }, + { a5200_64,"Laser Hawk (A800)", 65536, 0x2e2bee02 }, + { a5200_64,"Mr. Do (A800)", 65536, 0x4d66d5ab }, + { a5200_64,"M.U.L.E (A800)", 65536, 0x1f21446e }, + { a5200_64,"Oil's Well (Title) (A800)", 65536, 0x6a1ebc7d }, + { a5200_64,"Rampage 64K (A800)", 65536, 0xdf48d7d4 }, + { a5200_64,"Sea Dragon 64k (A800)", 65536, 0x66b4ea6b }, + { a5200_64,"Super Pac-man 64k (A800)", 65536, 0x93866191 }, + { a5200_512,"Bosconian (A800)", 524288, 0xbbc7d63c }, // Graphical glitches + /* TOSEC BIN */ + /* excluding .bin files that are actual .car files and files in previous lines */ + /* Filenames are truncated */ + /* TOSEC v2022-07-10 = 169 new */ + { a5200,"Activision Decathlon, The (1983)",32768,0x1f9ed238}, // Marked as bad dump but it seems to work + { a5200,"Asteroids (1983)(Atari)(US)(prot",16384,0x8d2aaab5}, + { a5200,"Ballblazer (1986)(Atari - Lucasf",32768,0xdef2a207}, + { a5200,"Barroom Baseball (1983)(Atari)(U",32768,0x21d19c8f}, + { a5200,"Beamrider (1983)(Activision)(US)",32768,0x02d9b87a}, // Marked as bad dump but it seems to work + { a5200,"Beamrider (1983)(Activision)(US)",32768,0x71fa5a79}, + { a5200_bad_dump,"Berzerk (1983)(Atari)(US)[b][CX5",32767,0xcbf1a137}, // Marked as bad dump but it seems to work + { a5200,"Berzerk (1983)(Atari)(US)[o][CX5",32768,0xcc740e26}, + { a5200,"Blue Print (1983)(CBS Electronic",16384,0x13734e17}, + { a5200,"Blue Print (1983)[b2]",32768,0x40d08988}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Blue Print (1983)[b]",32767,0x74a59340}, + { a5200,"Blue Print (1983)(CBS Electronic",32768,0x69584e01}, + { a5200,"Blue Print (1983)(CBS Electronic",32768,0x746c3b89}, + { a5200,"Blue Print (1983)(CBS Electronic",32768,0x613b9379}, + { a5200,"Boogie (198x)(Atari)(US)(proto)[",8192,0x4e75738a}, + { a5200_incomplete,"Bounty Bob Strikes Back!...[a]",16384,0x74e6a611}, // No game: bank 0 of Bounty Bob. Get 0x57e7945e or 0x7873c6dd + { a5200_incomplete,"Bounty Bob Strikes Back!...[a2]",16384,0xefa4915d}, // No game: bank 1 of Bounty Bob. Get 0x57e7945e or 0x7873c6dd + { a5200_incomplete,"Bounty Bob Strikes Back!...[a3]",8192,0x02931055}, // No game: fixed memory module of Bounty Bob. Get 0x57e7945e or 0x7873c6dd + { a5200_ee_16,"Buck Rogers - Planet of Zoom...[a]",16384,0x20df4927}, + { a5200_bad_dump,"Buck Rogers - Planet of Zoom...[b2]",32768,0xa3f12cce}, + { a5200_bad_dump,"Buck Rogers - Planet of Zoom...[b]",32768,0xc8035788}, + { a5200,"Castle Blast (demo) (2002)(Habot",32768,0x2e0b4c50}, + { a5200,"Castle Blast v0.03 (demo) (2002)",32768,0xfa0648ef}, + { a5200,"Choplifter! (1984)(Atari)(US)[o]",32768,0x0851d277}, + { a5200_ee_16,"Congo Bongo (1983)(Sega)(US)[a][",16384,0x82b91800}, + { a5200_bad_dump,"Congo Bongo (1983)(Sega)(US)[b2]",32768,0x28ec8516}, + { a5200_bad_dump,"Congo Bongo (1983)(Sega)(US)[b][",32768,0x7bb360f5}, + { a5200,"Countermeasure (1982)(Atari)(US)",32768,0xa993c86e}, + { a5200,"Cross Bomber (2020-08-26)(Caruso",32768,0x83b5a291}, + { a5200,"Cross Bomber (2021-05-13)(Caruso",32768,0xe5c152d4}, + { a5200,"Cross Chase (2017-09-15)(Caruso,",16384,0x97a1898a}, + { a5200,"Cross Chase (2017-10-11)(Caruso,",16384,0x6ab5db54}, + { a5200,"Cross Chase (2017-10-30)(Caruso,",16384,0x8772e3e8}, + { a5200,"Cross Chase (2017-12-10)(Caruso,",16384,0x3ffeea23}, + { a5200,"Cross Chase (2018-02-03)(Caruso,",16384,0x93707c56}, + { a5200,"Cross Chase (2018-04-15)(Caruso,",16384,0xb00eaf87}, + { a5200,"Cross Chase (2018-05-19)(Caruso,",16384,0xd801446e}, + { a5200,"Cross Chase (2018-07-19)(Caruso,",16384,0x93067bf4}, + { a5200,"Cross Chase (2018-08-04)(Caruso,",16384,0x8f546594}, + { a5200,"Cross Chase (2018-10-29)(Caruso,",16384,0x4ccb6886}, + { a5200,"Cross Chase (2020-04-02)(Caruso,",16384,0x01ff6c85}, + { a5200,"Cross Chase (2021-05-13)(Caruso,",32768,0x057b0342}, + { a5200,"Cross Horde (2021-04-16)(Caruso,",32768,0xa3ba0993}, + { a5200,"Cross Horde (2021-04-25)(Caruso,",32768,0xec6aa2f7}, + { a5200,"Cross Horde v1.0 (2021-05-01)(Ca",32768,0xeb925e18}, + { a5200,"Cross Shoot (2020-07-03)(Caruso,",32768,0x719ba5cf}, + { a5200,"Cross Snake Preview (2020-12-05)",32768,0x0adfa450}, + { a5200,"Cross Snake v1.0 (2020-12-12)(Ca",32768,0xc49f3fa9}, + { a5200,"Cross Snake v2.0 (2020-12-31)(Ca",32768,0x8790deff}, + { a5200,"David Crane's Pitfall II - Lost ",32768,0x14db6854}, + { a5200,"Defender (1982)(Atari)(US)[b2][C",32768,0xebad58ba}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Defender (1982)(Atari)(US)[b][CX",28672,0x0d7454a1}, + { a5200,"Dig Dug (1983)(Atari)(US)[b][CX5",32768,0xd29bb9a9}, // Marked as bad dump but it seems to work + { a5200,"Dreadnaught Factor, The (1983)(A",16384,0x7226fee6}, + { a5200,"Frogger (1983)(Parker Brothers)(",8192,0x99dc4f40}, + { a5200_bad_dump,"Frogger (1983)(Parker Brothers)(",32768,0x8db0dde4}, + { a5200,"Frogger (1983)(Parker Brothers)[b]",16384,0x1062ef6a}, // Marked as bad dump but it seems to work + { a5200,"Frogger (1983)(Parker Brothers)(",32768,0x7936aa92}, + { a5200,"Frogger (1983)(Parker Brothers)(",16384,0x0b7e77fc}, + { a5200_ee_16,"Frogger II - Threeedeep! (1984)[a]",16384,0xdc1437d0}, + { a5200,"Frogger II - Threeedeep! (1984)[b]",32768,0x1418c44a}, + { a5200_ee_16,"Frogger II - Threeedeep! (1984)[o2][a]",16384,0x0fe438b3}, + { a5200,"Frogger II - Threeedeep! (1984)[o][a]",32768,0x110d6fbc}, + { a5200_bad_dump,"Galaxian (1982)(Atari)(US)[b][CX",32766,0x430f87d1}, + { a5200,"Galaxian (1982)(Atari)(US)[o2][C",16384,0xd4977e3b}, + { a5200,"Galaxian (1982)(Atari)(US)[o][CX",32768,0xa6dfa355}, + { a5200,"Gorf (1983)(CBS Electronics - Ba",16384,0x97b15243}, + { a5200,"Gremlins (1986)(Atari)(US)[b2][C",32768,0x15d0cfc2}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Gremlins (1986)(Atari)(US)[b][CX",32768,0xb1d4dc8e}, + { a5200,"H.E.R.O. (1984)(Activision)(US)[",32768,0x9af4db28}, // Marked as bad dump but it seems to work + { a5200,"H.E.R.O. (1984)(Activision)(US)[",32768,0xf145a21c}, + { a5200_bad_dump,"James Bond 007 (1983)(Parker Bro",32768,0x6e70b70b}, + { a5200_bad_dump,"James Bond 007 (1983)(Parker Bro",32768,0x4f1374b7}, + { a5200,"Joust (1983)(Atari)(US)[b][CX524",32768,0x6b9b16dc}, // Marked as bad dump but it seems to work + { a5200_ee_16,"Jr. Pac-Man (1984)(Atari)[a]",16384,0x7c30592c}, + { a5200_bad_dump,"Jr. Pac-Man (1984)(Atari)[b2]",16384,0x4da19779}, + { a5200_bad_dump,"Jr. Pac-Man (1984)(Atari)[b]",32768,0x3ecc921e}, + { a5200,"Jum's Pong (2000)(Jum)(PD).bin",32768,0xad95c112}, + { a5200,"Jungle Hunt (1983)(Atari)(US)[b]",32768,0xfdccde25}, // Marked as bad dump but it seems to work + { a5200,"K-Razy Shootout (1983)(CBS Elect",16384,0x02cdfc70}, + { a5200,"Kaboom! (1983)(Activision)(US)[o",16384,0x8591be3d}, + { a5200_ee_16,"Kangaroo (1983)(Atari)(US)[b2][C",16384,0x673c989f}, + { a5200,"Kangaroo (1983)(Atari)(US)[b][CX",32768,0xfecb2a41}, + { a5200,"Kangaroo (1983)(Atari)(US)[o][CX",32768,0xdb292060}, + { a5200_bad_dump,"Keystone Kapers (1984)(Activisio",32768,0x22163e26}, + { a5200,"Keystone Kapers (1984)(Activisio",32768,0xe905ed94}, + { a5200,"Koffi - Yellow Kopter (demo) (20",32768,0xd7047701}, + { a5200,"Last Starfighter, The (1984)[b]",32768,0x3761527f}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Looney Tunes Hotel (1983)(Atari)[b2]",32768,0x57761b66}, + { a5200,"Looney Tunes Hotel (1983)(Atari)[b3]",32768,0xb1cec23f}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Looney Tunes Hotel (1983)(Atari)[b]",8192,0xb9ea8f11}, + { a5200,"Mario Bros. (1983)(Atari)(US)[a]",32768,0x6b3f1179}, + { a5200_bad_dump,"Mario Bros. (1983)(Atari)(US)[b]",32768,0xd90f8119}, + { a5200,"Megamania (1983)(Activision)(US)",16384,0x74163d4b}, + { a5200,"Meteorites (1983)(Electra Concep",32768,0x6287fd9b}, + { a5200,"Millipede (1984)(Atari)(US)(prot",32768,0xfcb208a3}, + { a5200,"Miner 2049er (1983)(Big Five Sof",32768,0xf03d6b06}, + { a5200,"Miniature Golf (1983)(Atari)(US)",32768,0x621f8e89}, // Marked as bad dump but it seems to work + { a5200,"Missile Command (1982)(Atari)[b2]",32768,0x915d6952}, // Marked as bad dump but it seems to work + { a5200,"Missile Command (1982)(Atari)[b3]",32768,0xd3f15631}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Missile Command (1982)(Atari)[b]",32768,0x8de027d5}, + { a5200,"Montezuma's Revenge (1984)(Parke",32768,0xbcf677fb}, // Marked as bad dump but it seems to work + { a5200,"Moon Patrol (1983)(Atari)(US)[o]",32768,0xa8c7d41e}, + { a5200,"Mountain King (1983)(CBS Electro[o2]",16384,0xf6c6feaa}, + { a5200,"Mountain King (1983)(CBS Electro[o]",32768,0x4992f047}, + { a5200_bad_dump,"Mr. Do!'s Castle (1984)(Parker B[b2]",32768,0x0d367519}, + { a5200_bad_dump,"Mr. Do!'s Castle (1984)(Parker B[b]",16384,0x7f7ea877}, + { a5200,"Mr. Do!'s Castle (1984)(Parker B[o]",16384,0x457fb9b3}, + { a5200_bad_dump,"Ms. Pac-Man (1983)(Atari)(US)[b2",32768,0xaf6091c1}, + { a5200,"Ms. Pac-Man (1983)(Atari)(US)[b]",32768,0xe9e2c34b}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Pac-Man (1982)(Atari)(US)[b2][CX",16383,0x117368af}, + { a5200,"Pac-Man (1982)(Atari)(US)[b3][CX",32768,0xe7952627}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Pac-Man (1982)(Atari)(US)[b][CX5",32766,0x34b673ed}, + { a5200_bad_dump,"Pengo (1983)(Atari)(US)[b][CX523",32768,0x968d727d}, + { a5200,"Pitfall! (1984)(Activision)(US)[",16384,0x72066f45}, + { a5200_bad_dump,"Popeye (1984)(Parker Brothers)(U",32768,0x1cee2326}, + { a5200_bad_dump,"Q-bert (1983)(Parker Brothers)[b]",32768,0x2ffe9622}, + { a5200,"Q-bert (1983)(Parker Brothers)[o]",16384,0x3c33f26e}, + { a5200,"Qix (1982)(Atari)(US)[b2][CX5221",32768,0x85f750d4}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Qix (1982)(Atari)(US)[b][CX5221]",32768,0xb346d4ab}, + { a5200,"Quest for Quintana Roo (1984)(Su",32768,0x9dbf341f}, + { a5200,"RatCatcher (2016-06)(Witmer, Rya",32768,0x1af6982c}, + { a5200,"RealSports Baseball (1983)(Atari",32768,0xde0fa87c}, + { a5200,"RealSports Basketball (proto)[a]",32768,0xdb834f88}, + { a5200,"RealSports Football (1982)[b]",32768,0x7a182f89}, // Marked as bad dump but it seems to work + { a5200_ee_16,"RealSports Soccer (1983)(Atari)[a]",16384,0x3d75d4dc}, + { a5200,"RealSports Soccer (1983)(Atari)[b2]",32768,0x295435b6}, // Marked as bad dump but it seems to work + { a5200,"RealSports Soccer (1983)(Atari)[b]",32768,0x13c459d5}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"River Raid (1983)(Activision)[b2]",32768,0x51c5bc75}, + { a5200_bad_dump,"River Raid (1983)(Activision)[b]",32768,0x6615d5db}, + { a5200,"River Raid (1983)(Activision)[o]",16384,0x1f6730ba}, + { a5200,"Road Runner (1982)(Atari)(US)[b]",32768,0x1b38dac0}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Robotron - 2084 (1983)(Atari)[b]",32767,0x538f2354}, + { a5200,"Robotron - 2084 (1983)(Atari)[o2]",32768,0xec80b709}, + { a5200,"Robotron - 2084 (1983)(Atari)[o]",32768,0x301a76b7}, + { a5200,"Shooting Gallery (2012)(Mihai, S",32768,0x54238bca}, + { a5200_bad_dump,"Space Invaders (1982)(Atari)[b]",32768,0x91fae605}, + { a5200,"Space Invaders (1982)(Atari)[o2]",16384,0x53c6c68a}, + { a5200,"Space Invaders (1982)(Atari)[o]",32768,0x218e1be4}, + { a5200,"Space Shuttle - A Journey Into S[o]",32768,0x404aedac}, + { a5200,"Spitfire (1984)(Atari)(US)[a]",32768,0xdb982c2f}, + { a5200_bad_dump,"Sport Goofy (1983)(Atari)(US)[b2]",32768,0x7bb4a0ab}, + { a5200,"Sport Goofy (1983)(Atari)(US)[b3]",32768,0xede41a3f}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Sport Goofy (1983)(Atari)(US)[b]",8192,0x97486a66}, + { a5200,"Star Raiders (1982)(Atari)(US)[b2]",32768,0xbf574b31}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Star Raiders (1982)(Atari)(US)[b3]",32764,0x19aa7a20}, + { a5200_bad_dump,"Star Raiders (1982)(Atari)(US)[b]",16382,0x78d28196}, + { a5200,"Star Trek - Strategic Operations[b]",32768,0x519a9574}, // Marked as bad dump but it seems to work + { a5200,"Star Wars - Return of the Jedi [b]",32768,0x08c8ed8a}, // Marked as bad dump but it seems to work + { a5200,"Stargate (1984)(Atari)(US)(proto[b]",32768,0x3229c915}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Super Breakout (1982)(Atari)(US)[b]",32768,0x54ed2ead}, + { a5200,"Super Breakout (1982)(Atari)(US)[o2]",16384,0x1d02a598}, + { a5200,"Super Breakout (1982)(Atari)(US)[o]",32768,0x6f4a78f6}, + { a5200_bad_dump,"Super Cobra (1983)(Parker Brothe[b]",32768,0xd917c276}, + { a5200,"Super Cobra (1983)(Parker Brothe[o2]",16384,0x82e14ae9}, + { a5200,"Super Cobra (1983)(Parker Brothe[o]",32768,0xf0a99787}, + { a5200,"Track and Field (1984)(Atari)(US",32768,0x203d9cde}, + { a5200_bad_dump,"Vanguard (1983)(Atari)(US)[b][CX",32767,0x98b3123a}, + { a5200_bad_dump,"Wizard of Wor (1983)(CBS Electro[b]",32768,0x60cfe8d6}, + { a5200,"Wizard of Wor (1983)(CBS Electro[o]",32768,0xa4bf0093}, + { a5200,"Xari Arena (1983)(Atari)(US)[b2]",32768,0x78861424}, // Marked as bad dump but it seems to work + { a5200_bad_dump,"Xari Arena (1983)(Atari)(US)[b]",32768,0xc36cc9b2}, + { a5200_bad_dump,"Xevious (1984)(Atari)(US)(proto)",32767,0x135655a9}, + { a5200,"Yellow Submarine (1982)(Atari)[o2]",8192,0x3cd986c5}, + { a5200,"Yellow Submarine (1982)(Atari)[o]",16384,0x12cc298f}, + { a5200,"Zaxxon (1984)(Sega)(US)[b][008-0",32768,0x8304aefc}, // Marked as bad dump but it seems to work + { a5200,"Zenji (1984)(Activision)(US)[b][",32768,0x1ab5e425}, + { a5200,"Zenji (1984)(Activision)(US)[o][",16384,0xca1a962a}, + { a5200,"Zone Ranger (1984)(Activision)(U",32768,0x02c9abc6}, + /* End of TOSEC v2022-07-10*/ + /* No-Intro. Excluding .a52/.bin files that are actual .car files and files in previous lines*/ + /* No-Intro v2024-04-28 = 9 new */ + { a5200,"Astrogrover (USA) (Proto).a52",32768,0x18417ada}, + { a5200,"Battlezone (USA) (Proto) (Alt).a",32768,0x7d32a6ca}, + { a5200,"Behind Jaggi Lines! (USA) (Proto",32768,0x9dd7776a}, + { a5200,"Galaxian (USA) (Alt).a52",8192,0x3a6e6133}, + { a5200_ee_16,"Gyruss (USA) (Alt).a52",16384,0x4241582d}, + { a5200,"Pole Position (USA) (Proto).a52",32768,0x15b7b5ef}, + { a5200_ee_16,"Star Raiders (USA) (Alternate).a",16384,0x4bac5dd9}, + { a5200,"Star Trek - Strategic Operations (Alt)",16384,0x33b70206}, + { a5200_ee_16,"Super Pacman (USA) (Proto) (Alt)",16384,0xfd8f0cd4}, + /* End of No-Intro v2024-04-28 */ + { -1,"",0,0}, +} ; + + +const a800_rom a800_game[] = { + { a800,"3-D Tic-Tac-Toe",8192,0x1cf50ebe}, + { a800,"Abracadabra!",16384,0xa35c775d}, + { a800_XE_128,"Ace Of Aces",131072,0xebad3ddb}, + { a800,"Activision Decathlon",16384,0x7cc0118b}, + { a800,"Adventure Creator",16384,0x8746d9da}, + { a800_XE_128,"Airball",131072,0xa0ccb3c1}, + { a800,"Alf In Color Caves",16384,0x79df7f9d}, + { a800,"Alien Ambush",8192,0xad7bc30b}, + { a800,"Alien Garden",8192,0x3e27ed0f}, + { a800,"Alpha Shield",8192,0xa7ade454}, + { a800_MAX_1024,"Alternate Reality- The City (MF) (Proto)",1048576,0x52cbd474}, + { a800_MAX_1024,"Alternate Reality- The Dungeon (MF)v9",1048576,0x9fd8d4d3}, + { a800,"Ant Eater",8192,0xc7290722}, + { a800,"Archon- The Light And The Dark",32768,0x2636829f}, + { a800_MAX_128,"Arkanoid I, II, III (MF)",131072,0x70f7bbe5}, + { a800,"Asteroids",8192,0xf9fff4a4}, + { a800,"Astro Chase (First Star Software)",16384,0x18752991}, + { a800,"Astro Chase",16384,0x11f1c7fa}, + { a800,"Atlantis",8192,0xbe0b390c}, + { a800,"Attack At EP-CYG-4",163834,0xdca02ca0}, + { a800,"Attack Of The Mutant Camels",163834,0xc933d741}, + { a800_XE_07_64,"Ballblazer",65536,0x820e5ce5}, + { a800,"Baseball",16384,0x065c3fd2}, + { a800,"Basketball",8192,0x79934851}, + { a800_XE_07_64,"Battlezone",65536,0x692515f2}, + { a800,"BC's Quest For Tires",16384,0xdddc6e36}, + { a800,"Beamrider",16384,0x2b05b8df}, + { a800_MAX_128,"Beyond Castle Wolfenstein (MF)",131926,0xf454689b}, + { a800,"Blue Max",32768,0x003f41ac}, + { a800,"Blaster",16384,0xce1126a2}, + { a800,"Boulderdash",16384,0xaf778329}, + { a800,"Boulders And Bombs",16384,0xab2ec21c}, + { a800_40,"Bounty Bob Strikes Back!",40960,0x0d00f072}, + { a800,"Bristles",16384,0x4263d64d}, + { a800_XE_07_64,"Bruce Lee (Repro)",65536,0x255dfc59}, + { a800,"Buck Rogers - Planet Of Zoom",16384,0x84dd597c}, + { a800,"Captain Beeble",16384,0xad8400b1}, + { a800,"Carnival Massacre (CS)",16384,0xea764851}, + { a800,"Carnival Massacre",16384,0x1baf0c97}, + { a800,"Castle Crisis",32768,0x47acda14}, + { a800,"Castle Hassle",16384,0x5a9e938a}, + { a800,"Castles And Keys",16384,0xbe14c091}, + { a800,"Caverns Of Mars",16384,0x8b9b2f5e}, + { a800,"Centipede",8192,0x44bb1842}, + { a800,"Chess",8192,0x72860db1}, + { a800,"Chicken",8192,0x1ab4d8d8}, + { a800,"Choplifter! (Broderbund)",16384,0x3ebc05ff}, + { a800_XE_07_64,"Choplifter!",65536,0xd426eccc}, + { a800,"Claim Jumper",16384,0x1a333c4a}, + { a800,"Cloudburts",8192,0x259aa18b}, + { a800_XE_128,"Commando",131072,0x28288df4}, // Autodetected as xex. Check afile.c for correct detection hack. + { a800,"Computer Chess",8192,0x5ce06e94}, + { a800,"Computer War",16384,0x4922aac6}, + { a800_MAX_1024,"Conan (MF)",1048576,0x25feb642}, + { a800,"Congo Bongo",16384,0x7a588045}, + { a800,"Cosmic Life",16384,0x919eaaa9}, + { a800,"Cosmic Tunnels",16384,0xad56c2bf}, + { a800,"Crossfire",8192,0x4d7e0503}, + { a800,"Crystal Castles",32768,0x998fa803}, + { a800,"Dance Fantasy",8192,0xfaec94e7}, + { a800_XE_07_64,"Dark Chambers",65536,0xfa2f132c}, + { a800_XE_07_64,"David's Midnight Magic",65536,0xb7ca61a2}, + { a800,"Defender",16384,0x782a81e4}, + { a800_XE_07_64,"Deflektor",65536,0xe4ed154e}, + { a800,"Deluxe Invaders",8192,0x15dc9b31}, + { a800,"Demo Cart",16384,0x9bedcdf3}, + { a800,"Demon Attack",8192,0x91328072}, + { a800_XE_07_64,"Desert Falcon",65536,0xa8f9324d}, + { a800,"Diamond Mine",16384,0xd8f9b867}, + { a800,"Dig Dug (1983)",16384,0xfdbc57ed}, + { a800,"Dig Dug",16384,0x6d68114e}, + { a800,"Donkey Kong Jr.",16384,0xa4eb70ef}, + { a800,"Donkey Kong",16384,0xf2b76a27}, + { a800,"Dreadnaught Factor",8192,0xc26fbb5b}, + { a800,"Droids",8192,0x5bb0c159}, + { a800,"Ducks Ahoy",16384,0x4cdfceb9}, + { a800_WILL_64,"DynaKillers",65536,0xad050724}, + { a800,"Eastern Front (1941)",16384,0xccff4a03}, + { a800,"Enduro",8192,0xa538a1bb}, + { a800_MAX_128,"Eidolon- The (MF)",131072,0x46f363f7}, + { a800,"Embargo",8192,0x07b1560c}, + { a800,"Espial",16384,0x64946757}, + { a800,"E.T. Phone Home",16384,0xbce4ef51}, + { a800,"Fantastic Voyage",8192,0x7bde2593}, + { a800,"Fast Eddie",8192,0x53ac386a}, + { a800,"Fast Food",8192,0x77223249}, + { a800_XE_128,"Fight Night",131072,0x4440d167}, + { a800,"Final Legacy",16384,0x6bd0d8e4}, + { a800,"Final Orbit",8192,0x177007e9}, + { a800,"Firebird",8192,0xe3c0b5f1}, + { a800,"Flapper",16384,0x18803c52}, + { a800_XE_128,"Flight Simulator II",131072,0x10cfc489}, + { a800,"Flip And Flop",16384,0x8ae057be}, + { a800_MAX_1024,"Flob 1.0.3b",1048576,0xff236e36}, + { a800,"Food Fight",32767,0x4236f0ea}, + { a800,"Fort Apocalypse",16384,0xf79b33f0}, + { a800,"Fortune Hutner",8192,0x03255972}, + { a800,"Frogger II - Threeedeep!",16384,0xed35f49c}, + { a800,"Frogger",8192,0x40e9476c}, + { a800,"Galaxian",8192,0xd60027be}, + { a800,"Gateway To Apshai",16384,0x3a0c6eb0}, + { a800_XE_128,"G.A.T.O.",131072,0xab06a3f5}, + { a800_MAX_128,"Gauntlet (MF)",131072,0x48cface0}, + { a800,"Gold Mine",8192,0x8459b11e}, + { a800,"Gorf",8192,0x90d0c7d7}, + { a800,"Gridrunner",8192,0x752dd5fe}, + { a800,"Gyruss",16384,0x1da47d01}, + { a800,"H.E.R.O.",16384,0x6062d3ce}, + { a800,"Halftime Battlin Bands",16384,0x8d14b5d3}, + { a800_XE_07_64,"Hardball",65536,0xbf0c6df2}, + { a800,"Hypnotic Land",16384,0x4fb75909}, + { a800,"Into The Eagles Nest",32768,0xf31321c2}, + { a800,"James Bond 007",16384,0x19b4e3a1}, + { a800,"Jawbreaker II",8192,0xe2a63a2d}, + { a800_MAX_1024,"Jim Slide XL",1048576,0x5f74de4a}, + { a800,"Journey To The Planets",16384,0xdce59b65}, + { a800,"Joust",16384,0xf6ec618c}, + { a800,"Jumbo Jet Pilot",16384,0xf046332b}, + { a800_MAX_128,"Jumpman",131072,0x4b7beb03}, + { a800,"Jumpman Jr.",16384,0x6c79bbad}, + { a800,"Jungle Hunt",16384,0x1847a7d4}, + { a800,"K-Razy Antiks",8192,0x84ab21b0}, + { a800,"K-razy Kritters (K-Byte)",8192,0x50354927}, + { a800,"K-razy Kritters",8192,0xf854a3b4}, + { a800,"K-razy Shoot-Out (CBS)",8192,0x636a01f5}, + { a800,"K-razy Shoot-Out (K-Byte)",8192,0x4300f6ff}, + { a800,"K-Star Patrol",8192,0x44c71fae}, + { a800,"Kangaroo",16384,0x1ef94906}, + { a800_XE_128,"Karateka",131072,0x97646f16}, + { a800,"Keystone Kapers",8192,0x465e1763}, + { a800,"Kickback",8192,0x2480ed0a}, + { a800_MAX_128,"Koronis Rift (MF)",131072,0xd385b89c}, + { a800_XE_128,"Lode Runner",131072,0x7790f474}, + { a800_MAX_1024,"Lords Of Conquest (MF)",1048576,0x3d6c01bb}, + { a800_MAX_1024,"M.U.L.E. (MF)",1048576,0x0b84f03e}, + { a800,"Major League Hockey",8192,0x4ffbc999}, + { a800_XE_07_64,"Mario Bros. XE",65536,0x7ba07c34}, + { a800,"M.A.S.H.",8192,0xfa041093}, + { a800,"Matterhorn",16384,0xdcc308cf}, + { a800,"Megamania",8192,0xb3c5130c}, + { a800_XE_128,"Mean 18 (Proto)",131072,0x0ee74a89}, + { a800_XE_128,"Midi Maze (Proto)",131072,0x193a53f6}, + { a800,"Millipede",16384,0xfb7e45da}, + { a800,"Miner 2049er",16384,0x6b1478bf}, + { a800,"Missile Command",8192,0xd2e36392}, + { a800,"Missile Command (XEGS built in)",8192,0xbdca01fb}, + { a800,"Mogul Maniac",16384,0x0c391600}, + { a800,"Monster Maze",16384,0x37049e57}, + { a800,"Montezuma's Revenge (prototype)",16384,0xbd4404d9}, + { a800,"Moon Patrol",16384,0xb845edb8}, + { a800,"Mountain King",8192,0x79748c93}, + { a800,"Mr. Cool",8192,0x1345d10c}, + { a800,"Mr. Do's Castle",8192,0xf1b9a24a}, + { a800,"Mr. TNT",8192,0x701dbdea}, + { a800,"Mrs. Pac-Man",16384,0xf91d18cf}, + { a800_MAX_128,"Mysterious Adventures (MF)",131072,0xadd506c5}, + { a800,"Necromancer",16384,0x39250ff2}, + { a800,"Nightstrike",8192,0x61245a75}, + { a800,"Oil's Well",16384,0x030ecad6}, + { a800,"One-On-One - Dr J. Vs Larry Bird",32768,0xab060567}, + { a800_MAX_1024,"onEscape (121422) (MF)",1048576,0x083fb021}, + { a800,"Orc Attack",16384,0xfbfaefcd}, + { a800,"Ozzy's Orchard",16384,0x1554b983}, + { a800,"Pac-Man",8192,0x61cf6167}, + { a800_MAX_128,"Pac-Man Arcade",131072,0x19bc1482}, + { a800,"Pastfinder",16384,0x12694c3f}, + { a800,"Peanut Butter Panic",8192,0xcdeb7759}, + { a800,"Pengo",16384,0xd8a9fe0a}, + { a800,"Picnic Paranoia",16384,0xe386a621}, + { a800,"Pitfall! II - The Lost Caverns",16384,0x1668cf3b}, + { a800,"Pitfall!",8192,0xb58bdf1c}, + { a800,"Pitstop",16384,0xd49ebf91}, + { a800,"Plattermania",8192,0x6cef6f94}, + { a800,"Pole Position",16384,0x581570C4}, + { a800,"Pool 400",8192,0xa6c2130f}, + { a800,"Popeye",16384,0x00fce79a}, + { a800,"Porky's",16384,0x1733d3fc}, + { a800,"Powerstar",16384,0xdc0dca6e}, + { a800,"Princes And The Frog",8192,0x7ce79281}, + { a800_MAX_1024,"Prince of Persia 211206 (MF)",1048576,0x52df819c}, + { a800,"Protector II",16384,0x374f311f}, + { a800,"Q-bert",8192,0xff3f0472}, + { a800,"Qix",8192,0x967b8051}, + { a800,"Rack'em Up",16384,0x5335d935}, + { a800,"Rally Speedway",16384,0x0a0f6ea2}, + { a800,"Realsports Football",16384,0x5e8951f4}, + { a800,"Realsports Tennis",16384,0x9a34cbdc}, + { a800_XE_07_64,"Rescue On Fractalus",65536,0x1ca549ad}, + { a800,"Risk (Proto)",8192,0x688b0a0c}, + { a800,"River Raid",8192,0x6e601d81}, + { a800,"River Rescue",16384,0xc018c8a0}, + { a800,"Robotron 2084",16384,0x528fc44a}, + { a800,"Satan's Hollow",16384,0x0f7c7934}, + { a800_MAX_128,"Scott Adams Adventures (MF)",131072,0x5446bcb1}, + { a800,"Sea Chase",8192,0x99b5a1dd}, + { a800,"Sea Fox",16384,0x932cc9a8}, + { a800,"Serpentine",8192,0x1b555b41}, + { a800,"Shamus",16384,0xbd3f06ee}, + { a800,"Silicon Warrior",16384,0x0736c8ae}, + { a800,"Slime",16384,0x1babcad6}, + { a800,"Soccer",8192,0x784c7060}, + { a800_MAX_1024,"Space Harrier",1048576,0xca98abfc}, + { a800,"Space Invaders",8192,0x6c811a10}, + { a800,"Space Shuttle",16384,0x66832f68}, + { a800,"Spark Bugs",8192,0xf56eced2}, + { a800,"Speedway Blast",8192,0xf895cc47}, + { a800,"Spider City",8192,0x8f8c3841}, + { a800,"Springer",16384,0x81466b55}, + { a800,"Spy Hunter",16384,0x34df8ffc}, + { a800,"Squish Em",8192,0xe01600b8}, + { a800,"Stargate (Proto)",16384,0xf527b721}, + { a800,"Star Raiders II",32768,0x737d4196}, + { a800,"Star Raiders",8192,0x5ec023ba}, + { a800,"Star Trek - Strategic Operations Simulator",16384,0x9df169d9}, + { a800,"Star Wars - Arcade Game - The",16384,0xaea795f7}, + { a800,"Star Wars - Death Star Battle",16384,0xd9f5cac7}, + { a800,"Starion",16384,0x23faf9b3}, + { a800,"Submarine Commander",16384,0x77198b2b}, + { a800_MAX_1024,"Summer Games (MF)",1048576,0x92325dc3}, + { a800_XE_128,"Summer Games",131072,0x95e6932d}, + { a800,"Super Cobra",8192,0x2af38d2f}, + { a800,"Super Pac-Man (Early Proto)",16384,0xb985be78}, + { a800,"Super Pac-Man (Proto)",16384,0xb518dda8}, + { a800,"Super Zaxxon",16384,0x9e64e13b}, + { a800,"Survival Of The Fittest",8192,0x7f48fbc5}, + { a800_XE_07_64,"Tapper (Cart)",65536,0xeff12440}, + { a800_XE_07_64,"Thunderfox",65536,0xb15ccef2}, + { a800,"Topper",16384,0x0286eea6}, + { a800_XE_07_64,"Tower Toppler (Proto)",65536,0x6b5333bd}, + { a800,"Track And Field",16384,0x9e2484c8}, + { a800,"Turmoil",8192,0xfe48aadf}, + { a800,"Typo Attack",16384,0x89da4ff7}, + { a800,"Typo",8192,0x70585854}, + { a800_MAX_1024,"Ultima II - Revenge of the Enchantress",1048576,0xd2a6db16}, + { a800_MAX_1024,"Ultima III (MF)",1048576,0xb132a1da}, + { a800_MAX_1024,"Ultima IV (MF)",1048576,0x62b1571f}, + { a800,"Up'n Down",16384,0x53ea3bf6}, + { a800,"Wizard Of Wor",16384,0x8017e56a}, + { a800_MAX_128,"World Karate Championship (MF)",131072,0x83c87b17}, + { a800,"Worm War I",8291,0x79934b01}, + { a800_XE_128,"Xenophobe",131072,0x68466666}, + { a800,"Zaxxon",16384,0x21579706}, + { a800,"Zenji",16384,0xebc6ec2e}, + { a800,"Zone Ranger",16384,0x8f1e72e7}, + /* Turbosoft Chile Unlicensed multicarts - Retrogames.cl ROM dumps = 16 new */ + /* Some games on the multicarts do not work, even with Atari800 5.2.0 or Altirra 4.21 emulators */ + { a800_TURBOSOFT_64_WILL,"Turbosoft C1 (Retrogames.cl dump)",65536,0xb2b45500}, + { a800_TURBOSOFT_64,"Turbosoft C2 (Retrogames.cl dump)",65536,0xade93e66}, + { a800_TURBOSOFT_64_WILL,"Turbosoft C3 (Retrogames.cl dump)",65536,0xbedf99fe}, + { a800_TURBOSOFT_64_WILL,"Turbosoft C4 (Retrogames.cl dump)",65536,0x97a8c904}, // Autodetected as non-cart. Check afile.c for correct detection hack. + { a800_TURBOSOFT_64_WILL,"Turbosoft C5 (Retrogames.cl dump)",65536,0x78dbb563}, + { a800_TURBOSOFT_64_WILL,"Turbosoft C6 (Retrogames.cl dump)",65536,0x49e18f6e}, + { a800_TURBOSOFT_128,"Turbosoft D1 (Retrogames.cl dump)",131072,0x4d1dd418}, + { a800_TURBOSOFT_128,"Turbosoft D2 (Retrogames.cl dump)",131072,0x025ab67a}, + { a800_TURBOSOFT_128,"Turbosoft D3 (Retrogames.cl dump)",131072,0xbca7d11b}, + { a800_TURBOSOFT_128,"Turbosoft D4 (Retrogames.cl dump)",131072,0x72df4a5e}, + { a800_MAX_128,"Turbosoft D5 (Retrogames.cl dump)",131072,0xa5aee6fd}, // Autodetected as non-cart. Check afile.c for correct detection hack. + { a800_TURBOSOFT_128,"Turbosoft D6 (Retrogames.cl dump)",131072,0x5498c7dc}, + { a800_TURBOSOFT_128,"Turbosoft D7 (Retrogames.cl dump)",131072,0x3fb92d9e}, + { a800_TURBOSOFT_64,"Turbosoft D8 (Retrogames.cl dump)",131072,0x3d68152e}, + { a800_MAX_128,"Turbosoft E1 (Retrogames.cl dump)",131072,0xfa100cbf}, + { a800_TURBOSOFT_128,"Turbosoft E2 (Retrogames.cl dump)",131072,0xbede95cd}, + /* End of Turbosoft multicarts*/ + /* TOSEC BIN - excluding .bin files that are actual .car files and files in previous lines */ + /* TOSEC v2006-03-29 = 3 new*/ + { a800_OSS_M091_16,"Action!",16384,0x0bcd70c6}, + { a800,"Asteroids",8192,0x7ed3e6a3}, + { a800,"Defender",16384,0x161cbe09}, + /* End of TOSEC v2006-03-29*/ + /* TOSEC v2022-07-10 = 115 new*/ + { a800,"3-D Tic-Tac-Toe (1979)(Atari)[!]",8192,0x4660c404}, + { a800,"Alpha Shield (1983)(Sirius Softw",8192,0x484e8443}, + { a800,"Animated Puzzle (1984)(Atari)(US",16384,0x1a4c75a7}, + { a800,"Animated Puzzle (1984)(Atari)(US",16384,0x90f37afe}, + { a800,"Ant Eater (1982)(Romox)(US)[a].b",8192,0x18702a0f}, + { a800,"Ant Eater (1982)(Romox)[earlier ",8192,0x73a3a64c}, + { a800,"Arex (1983)(Adventure Internatio",16384,0x2a080e7d}, + { a800,"Atlantis (1983)(Imagic)(US)[!][7",8192,0xf929f40f}, + { a800,"Baseball (1983)(Inhome Software)",16384,0x43c9d2a0}, + { a800,"Basketball (1979)(Atari)(US)[!][",8192,0x1ba8d718}, + { a800,"Beef Drop (demo) (2004-08-11)(Si",32768,0xd209e797}, + { a800,"Berzerk (1983)(Atari)(proto).bin",16384,0xb1dedb79}, + { a800_unsupported,"Bomb Jake (2009)(GR8 Software)(P",532480,0x8e89ca50}, // Corina 512K + 512K SRAM + 8K EEPROM cartridge not supported yet + { a800,"Boulders and Bombs (1982)(CBS So",8192,0xd6d51d3e}, + { a800_40,"Bounty Bob Strikes Back! (1984)(",40960,0xcc7912ed}, + { a800,"Carnival Massacre (1983)(Thorn E",16384,0x0c8e8d5b}, + { a800,"Centipede (1981)(Atari)(US)(prot",8192,0xd54f0200}, + { a800,"Chiffres et des Lettres, Des (19",16384,0xc7705c53}, + { a800,"Chiffres et des Lettres, Des (19",16384,0x3d8f5c25}, + { a800,"Claim Jumper (1982)(Synapse Soft",16384,0x374d14d9}, + { a800,"Cloudburst (1982)(DANA)(US)[!].b",8192,0x32e5629e}, + { a800,"Computer Chess (1979)(Atari)(US)",8192,0xc9614423}, + { a800,"Congo Bongo (1983)(Sega)(US).bin",16384,0x7a588045}, + { a800,"Conquest of the Crown (1994)(Lin",16384,0x94f56b90}, + { a800,"Cosmic Life (1983)(Spinnaker Sof",8192,0xec65758b}, + { a800,"Crystal Castles (1984)(Atari)(US",16384,0xe3ec1080}, + { a800,"Crystal Castles (1984)(Atari)(US",16384,0x89bb9431}, + { a800,"Crystal Castles (1984)(Atari)(US",16384,0x6c64892c}, + { a800,"Crystal Raiders (2001)(Video 61 ",16384,0xf15b2306}, + { a800,"Da' Fuzz (1983)(Roklan)(US).bin",16384,0xb94f66ea}, + { a800,"Da' Fuzz (1983)(Roklan)(US)[a].b",8192,0xbcda6dba}, + { a800,"Danger Ranger (1984)(Microdeal)[",8192,0xf5497ef3}, + { a800,"Decathlon (1984)(Activision)(US)",16384,0x76845603}, + { a800,"Decathlon (1984)(Activision)(US)",16384,0xaffbe54b}, + { a800,"Defender (1982)(Atari)(US)[!][CX",16384,0x782a81e4}, + { a800,"Defender Rev. 2 (1982)(Atari)(US",16384,0xfcb4b36f}, + { a800,"Delta Drawing v3.23 (1983)(Spinn",8192,0x20cbad07}, + { a800,"Demon Attack (1982)(Imagic)[!][O",8192,0x1cb8b52d}, + { a800,"Destiny - The Cruiser (198x)(Adv",16384,0x0c847bb3}, + { a800,"Dig Dug (1982)(Atari)(US).bin",16384,0x29b44ff6}, + { a800,"Donkey Kong (1983)(Atari)(US)[!]",16384,0x8a406275}, + { a800,"Donkey Kong Junior (1983)(Atari)",16384,0xa3e2d833}, + { a800,"Droids (1983)(TG Software)(US).b",8192,0x440082e6}, + { a800_WILL_64,"Dropzone (20xx)(Video 61).bin",65536,0x4870ed52}, + { a800,"Espial (1984)(Tigervision)(US).b",16384,0xdcde7482}, + { a800,"Excelsor (1986)(Players)[p].bin",8192,0xa854cc63}, + { a800,"Explorer (1984)(Activision)(prot",16384,0x98a4e5b7}, + { a800,"Fantastic Voyage (1982)(Sirius S",16384,0xea2c9b8f}, + { a800,"Fantastic Voyage (1982)(Sirius S",8192,0xcd428e17}, + { a800,"Fast Eddie (1982)(Sirius Softwar",8192,0x0939f2d0}, + { a800,"Final Legacy (1984)(Atari)(US)[G",16384,0x506e4ed0}, + { a800,"Final Orbit (1983)(Sirius Softwa",8192,0x4de5cd53}, + { a800,"Firebird (1981)(Gebelli Software",8192,0xab4f2d14}, + { a800,"Firebird (1981)(Gebelli Software",8192,0xb9557f4b}, + { a800,"Fortune Hunter (1982)(Romox)(US)",8192,0xc0fea1f7}, + { a800,"Fortune Hunter (1982)(Romox)(US)",8192,0x5cee3180}, + { a800,"Frogger II - Threeedeep! (1984)(",16384,0x7a5b4f65}, + { a800,"Frogger II - Threeedeep! (1984)(",8192,0xe924f2bc}, + { a800,"Gateway to Apshai (1983)(Epyx)[6",16384,0x4ccdbef0}, + { a800,"Gridrunner (1983)(HesWare)(US)[a",8192,0x02f44555}, + { a800,"Gyruss (1984)(Parker Brothers)(C",8192,0x0d78e8a9}, + { a800,"Gyruss (1984)(Parker Brothers)(P",8192,0xba14b37b}, + { a800,"Hard Hat Willy (1983)(Inhome Sof",16384,0x214be698}, + { a800_WILL_64,"Jinks (20xx)(Video 61 - Williams",65536,0x39fe57ee}, + { a800,"Jr. Pac-Man (1997)(Video 61 - At",16384,0xebc1db55}, + { a800,"K-Razy Antiks (1982)(CBS Softwar",8192,0xab7bdb79}, + { a800,"K-Star Patrol (1982)(CBS Softwar",8192,0x89c82cc2}, + { a800,"Kaboom! (1983)(Activision)(US)[!",8192,0xc2e2e645}, + { a800,"Laser Gates (1984)(Imagic)[p].bi",16384,0xea2a103e}, + { a800,"Last Starfighter, The (1984)(Ata",16384,0x3267eba7}, + { a800,"Last Starfighter, The (1984)(Ata",16384,0xb4c640f1}, + { a800,"Legacy, The rev7.1 (1984)(Atari)",16384,0xa445af7d}, + { a800,"Lifespan (1983)(Roklan)(US)(prot",16384,0xe4d62c12}, + { a800,"McDonald's Pac-Mac (1983)(Parker",8192,0x209d2e17}, + { a800,"McDonald's Pac-Mac (1983)(Parker",8192,0xca961d16}, + { a800,"Meteor (198x)(Germ-Soft)[p].bin",8192,0xc27ff7df}, + { a800,"Millipede (1983)(Atari)(proto).b",16384,0x82457872}, + { a800,"Miner 2049er (1982)(Big Five Sof",16384,0xeb770df4}, + { a800,"Missile Command+ (2006)(Lee, Pau",16384,0x2acfd240}, + { a800,"Moogles (1983)(Sirius)[p].bin",16384,0x0585fb5a}, + { a800,"Mr Do!'s Castle (1984)(Parker Br",8192,0xabed3b88}, + { a800,"Ms. Pac-Man (1983)(Atari)[!][red",16384,0x4ad748b2}, + { a800,"Orc Attack (1983)(Thorn EMI)(GB)",16384,0x5e9849b1}, + { a800,"Ozzy's Orchard (1983)(TG Softwar",16384,0x1554b983}, + { a800,"Pastfinder (1984)(Activision)[!]",16384,0x14fddfb8}, + { a800,"Popeye (1983)(Parker Brothers)(E",16384,0xa35d5e6a}, + { a800,"Preppie (2001)(Video 61 - Advent",16384,0x52ae50e3}, + { a800,"River Rescue (1983)(Thorn EMI)(G",16384,0xa7d2e0e8}, + { a800,"Silicon Warrior (1983)(Epyx)[!][",16384,0xa7ecc8f7}, + { a800,"Space Invaders (1980)(Atari)[!][",8192,0x3614d0aa}, + { a800,"Space Journey (1983)(Roklan)[09-",16384,0x161657f0}, + { a800,"Speedway Blast (1982)(IDSI)[!][O",8192,0x8e67192b}, + { a800,"Spider City (1983)(Sirius)[!].bi",8192,0xd519f2fb}, + { a800,"Squish 'Em! (1983)(Sirius)[!].bi",8192,0xf0553d6c}, + { a800,"Star Maze (1984)(Roklan)[!][11-0",16384,0x6fd9daff}, + { a800,"Star Trux (1982)(Atari)(proto).b",8192,0x8212c4b7}, + { a800,"Star Wars - Return of the Jedi -",8192,0xa40e15e5}, + { a800,"Submarine Commander (1982)(Thorn",16384,0xce9562eb}, + { a800,"Super Breakout (1979)(Atari)(US)",8192,0xc9066f06}, + { a800,"Super Breakout (1979)(Atari)(US)",8192,0x4da14cf9}, + { a800,"Super Pac-Man (1984)(Atari)(prot",16384,0x4b9b00f5}, + { a800,"Superman III (1983)(Atari)(proto",16384,0x639846d6}, + { a800,"Thera-Med Zahnschutz-Spiel, Das ",8192,0x10df011f}, + { a800,"Timebound (1984)(CBS Software)(U",16384,0xd3e98044}, + { a800,"Trion (1983)(Romox - London Soft",16384,0x2c42362f}, + { a800,"Up Up and Away (1983)(Ringblack ",16384,0xa8261044}, + { a800,"Video Easel (1979)(Atari)(US).bi",8192,0xfb45dae5}, + { a800,"Video Easel (1979)(Atari)(US)[!]",8192,0x276d7acc}, + { a800,"Video Poker Card Game (1998)(Vid",16384,0xdc492963}, + { a800,"Webster - The Word Game (1983)(C",8192,0x6fffb4a9}, + { a800,"Weltraumkolonie (1984)(Spinnaker",8192,0x06fd2cdb}, + { a800,"Worm War 1 (1982)(Sirius)[!].bin",8192,0xd9b120f4}, + { a800_unsupported,"Yie Another Kung-Fu (2011)(GR8 S",1056768,0x8ed7da2d}, // Corina 1M + 8K EEPROM cartridge not supported yet + { a800,"Zone Ranger (1984)(Activision)[!",16384,0x1b6c7b78}, + { a800_WILL_64,"Zybex (1991)(Video 61 - Williams",65536,0xc1da182c}, + /* End of TOSEC v2022-07-10*/ + { -1,"",0,0}, +} ; + +int is_5200_cart(ULONG crc) { + int idx = 0; + while (a5200_game[idx].type != -1) { + if (crc == a5200_game[idx].crc) + return TRUE; + idx++; + } + return FALSE; +} + +int is_800_cart(ULONG crc) { + int idx = 0; + while (a800_game[idx].type != -1) { + if (crc == a800_game[idx].crc) + return TRUE; + idx++; + } + return FALSE; +} + +int is_cart(ULONG crc) { + return (is_5200_cart(crc) || is_800_cart(crc)); +} diff --git a/libretro/carts_hash.h b/libretro/carts_hash.h new file mode 100644 index 0000000..7d9dcfd --- /dev/null +++ b/libretro/carts_hash.h @@ -0,0 +1,64 @@ +#include "atari.h" + +#define NO_CART 0 +#define A5200_CART 1 +#define A800_CART 2 + + + +// Atari 5200 carts +#define a5200 0 // 4, 8, NS16, 32 +#define a5200_40 1 // Bounty Bob CRC32: 57e7945e +#define a5200_ee_16 2 // 2 16k eeproms +#define a5200_64 3 // supercarts +#define a5200_128 4 +#define a5200_256 5 +#define a5200_512 6 +#define a5200_40_ALT 7 // Bounty Bob CRC32: 7873c6dd + +#define a5200_unsupported 100 +#define a5200_incomplete 101 +#define a5200_bad_dump 102 + + +typedef struct { + int type; + char name[50]; + int size; + ULONG crc; +} a5200_rom; + + +// Atari 800 carts +#define a800 0 // STD_8, STD_16, XEGS_32 +#define a800_40 1 // Bounty Bob +#define a800_WILL_64 2 // 64 KB Williams cartridge +#define a800_XE_07_64 3 // XEGS 64 KB cartridge (banks 0-7) +#define a800_XE_128 4 // XEGS 128 KB cartridge +//#define a800_XE_256 4 // XEGS 256 KB cartridge. Not sure if any exist. +//#define a800_XE_512 5 // XEGS 512 KB cartridge. Not sure if any exist. +//#define a800_XE_1024 6 // XEGS 1 MB cartridge. Not sure if any exist. +#define a800_MAX_128 5 // Atarimax 128 KB Flash cartridge +#define a800_MAX_1024 6 // Atarimax 1 MB Flash cartridge (old) +#define a800_OSS_M091_16 15 // OSS one chip 16 KB cartridge +#define a800_TURBOSOFT_64 50 // Turbosoft 64 KB cartridge (Chile - Unlicensed) +#define a800_TURBOSOFT_128 51 // Turbosoft 128 KB cartridge (Chile - Unlicensed) +#define a800_TURBOSOFT_64_WILL 99 // Turbosoft 64 KB cartridge with Williams banking (Chile - Unlicensed) + +#define a800_unsupported 100 +#define a800_incomplete 101 +#define a800_bad_dump 102 + +typedef struct { + int type; + char name[50]; + int size; + ULONG crc; +} a800_rom; + +extern const a5200_rom a5200_game[]; +extern const a800_rom a800_game[]; + +int is_5200_cart(ULONG crc); +int is_800_cart(ULONG crc); +int is_cart(ULONG crc); diff --git a/libretro/cmdline.c b/libretro/cmdline.c index c4a97e4..8ec0dbf 100644 --- a/libretro/cmdline.c +++ b/libretro/cmdline.c @@ -22,7 +22,7 @@ void Add_Option(const char* option) first++; } - sprintf(XARGV[PARAMCOUNT++],"%s\0",option); + sprintf(XARGV[PARAMCOUNT++],"%s", option); } int pre_main(const char *argv) diff --git a/libretro/config.h b/libretro/config.h index 7571c23..b5be5e3 100644 --- a/libretro/config.h +++ b/libretro/config.h @@ -568,6 +568,10 @@ code using `volatile' can become incorrect without. Disable with care. */ /* #undef volatile */ +#if defined(PS2) +#undef HAVE_CHMOD +#endif + #if defined(VITA) || defined(PSP) #undef HAVE_CHMOD @@ -579,3 +583,33 @@ #undef HAVE_NANOSLEEP #endif + +#if defined(__PS3__) && !defined(__PSL1GHT__) +#undef HAVE_FSEEKO +#undef HAVE_GETCWD +#undef HAVE_NANOSLEEP +#undef HAVE_MKSTEMP +#undef HAVE_MKTEMP +#undef HAVE_SIGNAL +#undef HAVE_SIGNAL_H +#undef HAVE_SYSTEM +#undef HAVE_TMPFILE +#undef HAVE_TMPNAM +#undef HAVE_STRINGS_H +#include +#define O_RDONLY CELL_FS_O_RDONLY +#define O_WRONLY CELL_FS_O_WRONLY +#define O_CREAT CELL_FS_O_CREAT +#define O_TRUNC CELL_FS_O_TRUNC +#define O_RDWR CELL_FS_O_RDWR +#define sysFsStat cellFsStat +#define sysFSStat CellFsStat +#define sysFSDirent CellFsDirent +#define sysFsOpendir cellFsOpendir +#define sysFsReaddir cellFsReaddir +#define sysFSDirent CellFsDirent +#define sysFsClosedir cellFsClosedir +#define WORDS_BIGENDIAN 1 +#define FS_SUCCEEDED 0 +#define FS_TYPE_DIR 1 +#endif diff --git a/libretro/core-mapper.c b/libretro/core-mapper.c index 3098fd0..aca6fbb 100644 --- a/libretro/core-mapper.c +++ b/libretro/core-mapper.c @@ -3,22 +3,17 @@ #include "retroscreen.h" #include "platform.h" #include "vkbd.h" +#include "input.h" +#include "pokey.h" + //CORE VAR #ifdef _WIN32 char slash = '\\'; #else char slash = '/'; #endif -extern const char *retro_save_directory; -extern const char *retro_system_directory; -extern const char *retro_content_directory; -char RETRO_DIR[512]; - -char DISKA_NAME[512]="\0"; -char DISKB_NAME[512]="\0"; -char TAPE_NAME[512]="\0"; -extern void Screen_SetFullUpdate(int scr); +//extern void retro_message(const char* text, unsigned int frames, int alt); long frame=0; unsigned long Ktime=0 , LastFPSTime=0; @@ -31,51 +26,68 @@ unsigned long Ktime=0 , LastFPSTime=0; #endif //SOUND -short signed int SNDBUF[1024*2]; +UBYTE SNDBUF[1024*2*2]; int snd_sampler_pal = 44100 / 50; int snd_sampler_ntsc = 44100 / 60; -//PATH -char RPATH[512]; - //EMU FLAGS -int NPAGE=-1, KCOL=1, BKGCOLOR=0; -int SHOWKEY=-1; +int NPAGE = -1, KCOL = 1, BKGCOLOR = 0; +int SHOWKEY = -1, SHOWKEYDELAY = 0; +int VKBD_OPACITY = -1; #if defined(ANDROID) || defined(__ANDROID__) -int MOUSE_EMULATED=1; +int MOUSE_EMULATED = 1; #else -int MOUSE_EMULATED=-1; +int MOUSE_EMULATED = -1; #endif + int SHIFTON=-1,MOUSEMODE=-1,PAS=4; int SND=1; //SOUND ON/OFF int pauseg=0; //enter_gui int touch=-1; // gui mouse btn + //JOY int al[2][2];//left analog1 int ar[2][2];//right analog1 unsigned char MXjoy[4]; // joy int16_t joypad_bits[4]; +extern UBYTE consol_mask; #define JOYRANGE_UP_VALUE -16384 /* Joystick ranges in XY */ #define JOYRANGE_DOWN_VALUE 16383 #define JOYRANGE_LEFT_VALUE -16384 #define JOYRANGE_RIGHT_VALUE 16383 -extern int a5200_joyhack; - +// retro core option variables +extern int atari_joyhack; extern int keyboard_type; - -//MOUSE +extern int pot_analog_deadzone; +extern int paddle_mode; +extern int paddle_speed; + +extern int INPUT_joy_5200_center; +extern int INPUT_joy_5200_min; +extern int INPUT_joy_5200_max; +extern int INPUT_digital_5200_min; +extern int INPUT_digital_5200_center; +extern int INPUT_digital_5200_max; + +//MOUSE Is this even tied to anything? extern int pushi; // gui mouse btn int gmx,gmy; //gui mouse int mouse_wu=0,mouse_wd=0; + +//Atari800 EMU mouse +extern UBYTE POKEY_POT_input[8]; +extern int INPUT_mouse_pot_min; +extern int INPUT_mouse_pot_max; + //KEYBOARD -char Key_Sate[512]; -char Key_Sate2[512]; -static char old_Key_Sate[512]; +char Key_State[512]; +static char old_Key_State[512]; -int mbt[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +int mbt[4][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } + , { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }; //STATS GUI int BOXDEC= 32+2; @@ -83,7 +95,6 @@ int STAT_BASEY; /*static*/ retro_input_state_t input_state_cb; static retro_input_poll_t input_poll_cb; -extern void retro_audio_cb( short l, short r); extern bool libretro_supports_bitmasks; @@ -113,13 +124,14 @@ int slowdown=0; #define RETRO_DEVICE_ATARI_KEYBOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_KEYBOARD, 0) #define RETRO_DEVICE_ATARI_JOYSTICK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1) +#define RETRO_DEVICE_ATARI_5200_JOYSTICK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) void texture_uninit(void) { } void texture_init(void) { memset(Retro_Screen, 0, sizeof(Retro_Screen)); - memset(old_Key_Sate ,0, sizeof(old_Key_Sate)); + memset(old_Key_State ,0, sizeof(old_Key_State)); gmx=(retrow/2)-1; gmy=(retroh/2)-1; @@ -143,14 +155,22 @@ void retro_sound_update(void) if (! UI_is_active) { - Sound_Callback(SNDBUF, 1024*2*2); - for(x=0;x 1) + memset(Retro_Screen, 0, sizeof(Retro_Screen)); +} void vkbd_key(int key,int pressed) { @@ -158,14 +178,14 @@ void vkbd_key(int key,int pressed) { if(SHIFTON==1) ; - Key_Sate[key]=1; + Key_State[key]=1; // key is being held down } else { if(SHIFTON==1) ; - Key_Sate[key]=0; + Key_State[key]=0; // key is being RELEASE } } @@ -228,7 +248,7 @@ void retro_virtualkb(void) virtual_kdb(( char *)Retro_Screen,vkx,vky); - i=8; + i=0; // swapped Button 1 and 2 definitions ( used to be 8 ) if( (joypad_bits[0] & (1 << i)) && vkflag[4]==0 ) vkflag[4]=1; else if( !(joypad_bits[0] & (1 << i)) && vkflag[4]==1 ) @@ -257,7 +277,11 @@ void retro_virtualkb(void) SHOWKEY=-SHOWKEY; } else if(i==-5) - oldi=-1; + { + //VKbd opacitu on/off + VKBD_OPACITY=-VKBD_OPACITY; + oldi=-1; + } else if(i==-6) oldi=-1; else if(i==-7) @@ -305,12 +329,6 @@ void retro_virtualkb(void) } } -void Screen_SetFullUpdate(int scr) -{ - if(scr==0 ||scr>1) - memset(Retro_Screen, 0, sizeof(Retro_Screen)); -} - void Process_key(void) { int i; @@ -319,13 +337,13 @@ void Process_key(void) return; for(i=0;i<320;i++) - Key_Sate[i]=input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0,i) ? 0x80: 0; + Key_State[i]=input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0,i) ? 0x80: 0; - if(memcmp( Key_Sate,old_Key_Sate , sizeof(Key_Sate) ) ) + if(memcmp( Key_State,old_Key_State , sizeof(Key_State) ) ) { - for(i=0;i<320;i++) + for(i=0;i<320;i++) { - if(Key_Sate[i] && Key_Sate[i]!=old_Key_Sate[i] ) + if(Key_State[i] && Key_State[i]!=old_Key_State[i] ) { if(i==RETROK_RCTRL) { @@ -347,7 +365,7 @@ void Process_key(void) //retro_key_down(i); } - else if ( !Key_Sate[i] && Key_Sate[i]!=old_Key_Sate[i] ) + else if ( !Key_State[i] && Key_State[i]!=old_Key_State[i] ) { if(i==RETROK_RCTRL) { @@ -373,7 +391,52 @@ void Process_key(void) } } - memcpy(old_Key_Sate,Key_Sate , sizeof(Key_Sate) ); + memcpy(old_Key_State,Key_State , sizeof(Key_State) ); +} + +int Atari_POT(int input) +{ + int which = input / 2; + int xval, yval, pval, result; + + //if (consol_mask == 0x0f) + // return 228; + + /* account for Joystick swap enabled */ + if (atari_joyhack == 2) + which = (which + 1) % 2; + + xval = input_state_cb(which, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X); + yval = input_state_cb(which, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y); + + pval = (input & 1) ? yval : xval; + + if ((pval > -pot_analog_deadzone) && (pval < pot_analog_deadzone)) + return INPUT_joy_5200_center; + + /* Convert to amplitude */ + float amplitude = (float)((pval > pot_analog_deadzone) ? + (pval - pot_analog_deadzone) : + (pval + pot_analog_deadzone)) / + (float)(LIBRETRO_ANALOG_RANGE - pot_analog_deadzone); + + /* Map to Atari 5200 values */ + if (amplitude >= 0.0f) + result = (JOY_5200_CENTER + (unsigned int)(((float)(INPUT_joy_5200_max - JOY_5200_CENTER) * amplitude) + 0.5f)); + else + result = (JOY_5200_CENTER - (unsigned int)(((float)(JOY_5200_CENTER - INPUT_joy_5200_min) * -amplitude) + 0.5f)); + + /* for debug purposes */ + //if (input == 1) + //{ + // char msg[256]; + + // //sprintf(msg, "X=%f, Y=%f, Deadzone=%f. Result- %i\n", xval / (float)LIBRETRO_ANALOG_RANGE, yval / (float)LIBRETRO_ANALOG_RANGE, (float)pot_analog_deadzone, result); + // sprintf(msg, "Joy Min=%i, Joy Max=%i. Result- %i\n", INPUT_joy_5200_max, INPUT_joy_5200_min, result); + // retro_message(msg, 60, 0); + //} + + return result; } int Retro_PollEvent() @@ -381,13 +444,12 @@ int Retro_PollEvent() // RETRO B Y SLT STA UP DWN LEFT RGT A X L R L2 R2 L3 R3 // INDEX 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - int SAVPAS=PAS; int i,j; static int vbt[4][16]={ - {0x0,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x80,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, - {0x0,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x80,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, - {0x0,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x80,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, - {0x0,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x80,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, + {0x80,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x10,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, + {0x80,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x10,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, + {0x80,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x10,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, + {0x80,0x0,0x0,0x0,0x01,0x02,0x04,0x08,0x10,0x40,0x0,0x0,0x0,0x0,0x0,0x0}, }; input_poll_cb(); @@ -409,12 +471,13 @@ int Retro_PollEvent() int16_t mouse_x,mouse_y; mouse_x=mouse_y=0; - if(SHOWKEY==-1 && pauseg==0)Process_key(); + if (SHOWKEY==-1 && pauseg==0) + Process_key(); //Joy mode for(j=0;j<4;j++) { - for(i=4;i<10;i++) + for(i=0;i<16;i++) { if(joypad_bits[j] & (1 << i)) MXjoy[j] |= vbt[j][i]; // Joy press @@ -423,21 +486,12 @@ int Retro_PollEvent() } } - if(a5200_joyhack) //hack for robotron right analog act as Joy1 + if (atari_joyhack == 1 && !paddle_mode) //hack for robotron right analog act as Joy1 { -#if 0 - int x,y; -#endif - //emulate Joy1 with joy analog right ar[0][0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X)); ar[0][1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y)); -#if 0 - x=ar[0][0]; - y=ar[0][1]; -#endif - /* Directions */ if (ar[0][1] <= JOYRANGE_UP_VALUE) @@ -450,40 +504,152 @@ int Retro_PollEvent() else if (ar[0][0] >= JOYRANGE_RIGHT_VALUE) MXjoy[1] |= 0x08; } + else if (atari_joyhack == 2 && !paddle_mode) //hack for Joy 1 / 2 swap. + { + //emulate Joy1 with joy analog right + al[0][0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X)); + al[0][1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y)); + + if (libretro_supports_bitmasks) + joypad_bits[1] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK); + else + { + joypad_bits[1] = 0; + joypad_bits[1] |= input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK) ? 1 : 0; + } + + for (i = 0 ; i < 16; i++) + { + if (joypad_bits[1] & (1 << i)) + MXjoy[1] |= vbt[0][i]; // Joy press + else if (MXjoy[1] & vbt[0][i]) + MXjoy[1] &= ~vbt[0][i]; // Joy press + } + + /* Directions */ + + if (al[0][1] <= JOYRANGE_UP_VALUE) + MXjoy[1] |= 0x01; + else if (al[0][1] >= JOYRANGE_DOWN_VALUE) + MXjoy[1] |= 0x02; + + if (al[0][0] <= JOYRANGE_LEFT_VALUE) + MXjoy[1] |= 0x04; + else if (al[0][0] >= JOYRANGE_RIGHT_VALUE) + MXjoy[1] |= 0x08; + } + else if (atari_joyhack == 3 && !paddle_mode) //hack for supporting Joy 2B+ games + { + //use paddles' potentiometers for fire 2 and fire 3 + POKEY_POT_input[0] = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_A)) ? INPUT_mouse_pot_max : INPUT_mouse_pot_min; + POKEY_POT_input[1] = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) ? INPUT_mouse_pot_max : INPUT_mouse_pot_min; + POKEY_POT_input[2] = (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_A)) ? INPUT_mouse_pot_max : INPUT_mouse_pot_min; + POKEY_POT_input[3] = (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) ? INPUT_mouse_pot_max : INPUT_mouse_pot_min; + //prevent propagation of RETRO_DEVICE_ID_JOYPAD_Y that is interpreted as space key + joypad_bits[0] &= ~(1 << RETRO_DEVICE_ID_JOYPAD_Y); + joypad_bits[1] &= ~(1 << RETRO_DEVICE_ID_JOYPAD_Y); + } - - if(atari_devices[0]==RETRO_DEVICE_ATARI_JOYSTICK) + if ( atari_devices[0] != RETRO_DEVICE_ATARI_KEYBOARD) { //shortcut for joy mode only //Button B Y SLT STA // 0 1 2 3 - for(i=0;i<4;i++) - { - if ( (joypad_bits[0] & (1 << i)) && mbt[i]==0 ) - mbt[i]=1; - else if (mbt[i]==1 && !(joypad_bits[0] & (1 << i)) ) - { - mbt[i]=0; - if(i==2) - MOUSE_EMULATED = -MOUSE_EMULATED; - } - } - //Button L R L2 R2 L3 R3 - // 10 11 12 13 14 15 - for(i=10;i<16;i++) - { - if ( (joypad_bits[0] & (1 << i)) && mbt[i]==0 ) - mbt[i]=1; - else if ( mbt[i]==1 && !(joypad_bits[0] & (1 << i)) ) - { - mbt[i]=0; - if(i==14) - SHOWKEY = -SHOWKEY; - } - } - }//if atari_devices=joy + for (i = 0; i < 16; i++) + { + for (int j = 0; j < 4; j++) + { + if ((joypad_bits[j] & (1 << i)) && mbt[j][i] == 0) + mbt[j][i] = 1; + else if (mbt[j][i] == 1 && !(joypad_bits[j] & (1 << i))) + { + mbt[j][i] = 0; +#if defined(ANDROID) || defined(__ANDROID__) + /* apparently this is used by the ANDROID port? Keep in for now. Android only*/ + if(i==2) + MOUSE_EMULATED = -MOUSE_EMULATED; +#endif + } + } + } + + /* Huh? */ + //for(i=0;i<4;i++) + //{ + // if ( (joypad_bits[0] & (1 << i)) && mbt[i]==0 ) + // mbt[i]=1; + // else if (mbt[i]==1 && !(joypad_bits[0] & (1 << i)) ) + // { + // mbt[i]=0; + // //if(i==2) /* hard coded? android only? */ + // // MOUSE_EMULATED = -MOUSE_EMULATED; + // } + //} + ////Button L R L2 R2 L3 R3 + //// 10 11 12 13 14 15 + //for(i=10;i<16;i++) + //{ + // if ( (joypad_bits[0] & (1 << i)) && mbt[i]==0 ) + // mbt[i]=1; + // else if ( mbt[i]==1 && !(joypad_bits[0] & (1 << i)) ) + // { + // mbt[i]=0; + // //if(i==14) /* removed can be defined in controller settings screen? */ + // //SHOWKEY = -SHOWKEY; + // } + //} + } + else //Emulate joystick controls with keyboard/retro_keyboard only Joy 1 atm... experimental + { + // these are the same for both computer and 5200 + if (Key_State[RETROK_KP8]) // up + MXjoy[0] |= 0x01; + else if (Key_State[RETROK_KP2]) // down + MXjoy[0] |= 0x02; + if (Key_State[RETROK_KP4]) // left + MXjoy[0] |= 0x04; + else if (Key_State[RETROK_KP6]) // right + MXjoy[0] |= 0x08; + + if (Key_State[RETROK_RALT]) // fire 1 + MXjoy[0] |= 0x80; + + // 5200 fire button 2 + if (Atari800_machine_type == Atari800_MACHINE_5200 && !UI_is_active) + if ( Key_State[RETROK_RCTRL]) + INPUT_key_shift = 1; + } + + if (paddle_mode) + { + for (int i = 0; i < 4; i++) + { + int pval = input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X); + + if ((pval < -pot_analog_deadzone) || (pval > pot_analog_deadzone)) + { + if (pval > 0) + POKEY_POT_input[i] -= paddle_speed; + else + POKEY_POT_input[i] += paddle_speed; + } + else + { + if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) + POKEY_POT_input[i] -= paddle_speed; + if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) + POKEY_POT_input[i] += paddle_speed; + } + + if (POKEY_POT_input[i] < INPUT_mouse_pot_min) + POKEY_POT_input[i] = INPUT_mouse_pot_min; + + if (POKEY_POT_input[i] > INPUT_mouse_pot_max) + POKEY_POT_input[i] = INPUT_mouse_pot_max; + } + } if(MOUSE_EMULATED==1) { @@ -498,10 +664,8 @@ int Retro_PollEvent() mouse_y += PAS; if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) mouse_y -= PAS; - mouse_l = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_A)) ? 1 : 0; - mouse_r = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_B)) ? 1 : 0; - - PAS=SAVPAS; + mouse_l = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_B)) ? 1 : 0; + mouse_r = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_A)) ? 1 : 0; slowdown=1; } diff --git a/libretro/font2.i b/libretro/font2.i index d1868a7..a815c8f 100644 --- a/libretro/font2.i +++ b/libretro/font2.i @@ -1,270 +1,266 @@ -/****************************************************************/ -/* Apple IIgs emulator */ -/* */ -/* Apple 2GS Original fonts. */ -/* All the characters are coded in their original set. */ -/* Only the USA keyboard is recognized with ROM 01. */ -/* */ -/****************************************************************/ +/**************************************/ +/* Atari 800 emulator */ +/* */ +/* Atari 8bit Original fonts. */ +/* */ +/**************************************/ unsigned char font_array[256*8] = { -0xc7, 0xbb, 0xab, 0xa3, 0xa7, 0xbf, 0xc3, 0xff, -0xef, 0xd7, 0xbb, 0xbb, 0x83, 0xbb, 0xbb, 0xff, -0x87, 0xbb, 0xbb, 0x87, 0xbb, 0xbb, 0x87, 0xff, -0xc7, 0xbb, 0xbf, 0xbf, 0xbf, 0xbb, 0xc7, 0xff, -0x87, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x87, 0xff, -0x83, 0xbf, 0xbf, 0x87, 0xbf, 0xbf, 0x83, 0xff, -0x83, 0xbf, 0xbf, 0x87, 0xbf, 0xbf, 0xbf, 0xff, -0xc3, 0xbf, 0xbf, 0xbf, 0xb3, 0xbb, 0xc3, 0xff, -0xbb, 0xbb, 0xbb, 0x83, 0xbb, 0xbb, 0xbb, 0xff, -0xc7, 0xef, 0xef, 0xef, 0xef, 0xef, 0xc7, 0xff, -0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xbb, 0xc7, 0xff, -0xbb, 0xb7, 0xaf, 0x9f, 0xaf, 0xb7, 0xbb, 0xff, -0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x83, 0xff, -0xbb, 0x93, 0xab, 0xab, 0xbb, 0xbb, 0xbb, 0xff, -0xbb, 0xbb, 0x9b, 0xab, 0xb3, 0xbb, 0xbb, 0xff, -0xc7, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xc7, 0xff, -0x87, 0xbb, 0xbb, 0x87, 0xbf, 0xbf, 0xbf, 0xff, -0xc7, 0xbb, 0xbb, 0xbb, 0xab, 0xb7, 0xcb, 0xff, -0x87, 0xbb, 0xbb, 0x87, 0xaf, 0xb7, 0xbb, 0xff, -0xc7, 0xbb, 0xbf, 0xc7, 0xfb, 0xbb, 0xc7, 0xff, -0x83, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xff, -0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xc7, 0xff, -0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xd7, 0xef, 0xff, -0xbb, 0xbb, 0xbb, 0xab, 0xab, 0x93, 0xbb, 0xff, -0xbb, 0xbb, 0xd7, 0xef, 0xd7, 0xbb, 0xbb, 0xff, -0xbb, 0xbb, 0xd7, 0xef, 0xef, 0xef, 0xef, 0xff, -0x83, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x83, 0xff, -0x83, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x83, 0xff, -0xff, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xff, 0xff, -0x83, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0x83, 0xff, -0xff, 0xff, 0xef, 0xd7, 0xbb, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xef, 0xef, 0xef, 0xef, 0xef, 0xff, 0xef, 0xff, -0xd7, 0xd7, 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, -0xd7, 0xd7, 0x83, 0xd7, 0x83, 0xd7, 0xd7, 0xff, -0xef, 0xc3, 0xaf, 0xc7, 0xeb, 0x87, 0xef, 0xff, -0x9f, 0x9b, 0xf7, 0xef, 0xdf, 0xb3, 0xf3, 0xff, -0xdf, 0xaf, 0xaf, 0xdf, 0xab, 0xb7, 0xcb, 0xff, -0xef, 0xef, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, -0xef, 0xdf, 0xbf, 0xbf, 0xbf, 0xdf, 0xef, 0xff, -0xef, 0xf7, 0xfb, 0xfb, 0xfb, 0xf7, 0xef, 0xff, -0xef, 0xab, 0xc7, 0xef, 0xc7, 0xab, 0xef, 0xff, -0xff, 0xef, 0xef, 0x83, 0xef, 0xef, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xef, 0xef, 0xdf, 0xff, -0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, -0xff, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0xff, 0xff, -0xc7, 0xbb, 0xb3, 0xab, 0x9b, 0xbb, 0xc7, 0xff, -0xef, 0xcf, 0xef, 0xef, 0xef, 0xef, 0xc7, 0xff, -0xc7, 0xbb, 0xfb, 0xe7, 0xdf, 0xbf, 0x83, 0xff, -0x83, 0xfb, 0xf7, 0xe7, 0xfb, 0xbb, 0xc7, 0xff, -0xf7, 0xe7, 0xd7, 0xb7, 0x83, 0xf7, 0xf7, 0xff, -0x83, 0xbf, 0x87, 0xfb, 0xfb, 0xbb, 0xc7, 0xff, -0xe3, 0xdf, 0xbf, 0x87, 0xbb, 0xbb, 0xc7, 0xff, -0x83, 0xfb, 0xf7, 0xef, 0xdf, 0xdf, 0xdf, 0xff, -0xc7, 0xbb, 0xbb, 0xc7, 0xbb, 0xbb, 0xc7, 0xff, -0xc7, 0xbb, 0xbb, 0xc3, 0xfb, 0xf7, 0x8f, 0xff, -0xff, 0xff, 0xef, 0xff, 0xef, 0xff, 0xff, 0xff, -0xff, 0xff, 0xef, 0xff, 0xef, 0xef, 0xdf, 0xff, -0xf7, 0xef, 0xdf, 0xbf, 0xdf, 0xef, 0xf7, 0xff, -0xff, 0xff, 0x83, 0xff, 0x83, 0xff, 0xff, 0xff, -0xdf, 0xef, 0xf7, 0xfb, 0xf7, 0xef, 0xdf, 0xff, -0xc7, 0xbb, 0xf7, 0xef, 0xef, 0xff, 0xef, 0xff, -0x08, 0x10, 0x6c, 0xfe, 0xfc, 0xfc, 0x7e, 0x6c, -0x08, 0x10, 0x6c, 0x82, 0x84, 0x84, 0x52, 0x6c, -0x00, 0x00, 0x40, 0x60, 0x70, 0x78, 0x6c, 0x42, -0xfe, 0x44, 0x28, 0x10, 0x10, 0x28, 0x54, 0xfe, -0x00, 0x02, 0x04, 0x88, 0x50, 0x20, 0x20, 0x00, -0xfe, 0xfc, 0xfa, 0x36, 0xae, 0xde, 0xde, 0xfe, -0xfc, 0xfc, 0xfc, 0xdc, 0x9c, 0x00, 0x9e, 0xde, -0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, -0x10, 0x20, 0x40, 0xfe, 0x40, 0x20, 0x10, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, -0x10, 0x10, 0x10, 0x10, 0x92, 0x54, 0x38, 0x10, -0x10, 0x38, 0x54, 0x92, 0x10, 0x10, 0x10, 0x10, -0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x02, 0x02, 0x22, 0x62, 0xfe, 0x60, 0x20, -0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, -0xc8, 0x18, 0x38, 0x7e, 0x38, 0x18, 0x08, 0xf6, -0x26, 0x30, 0x38, 0xfc, 0x38, 0x30, 0x20, 0xde, -0x02, 0x12, 0x10, 0xfe, 0x7c, 0x38, 0x12, 0x02, -0x02, 0x12, 0x38, 0x7c, 0xfe, 0x10, 0x12, 0x02, -0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xfe, -0x10, 0x08, 0x04, 0xfe, 0x04, 0x08, 0x10, 0x00, -0x54, 0xaa, 0x54, 0xaa, 0x54, 0xaa, 0x54, 0xaa, -0xaa, 0x54, 0xaa, 0x54, 0xaa, 0x54, 0xaa, 0x54, -0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0xfe, 0x00, -0x00, 0x00, 0xfc, 0x02, 0x02, 0x02, 0xfe, 0x00, -0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, -0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, -0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, -0x28, 0x28, 0xee, 0x00, 0xee, 0x28, 0x28, 0x00, -0xfe, 0x02, 0x02, 0x32, 0x32, 0x02, 0x02, 0xfe, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0xdf, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0xc7, 0xfb, 0xc3, 0xbb, 0xc3, 0xff, -0xbf, 0xbf, 0x87, 0xbb, 0xbb, 0xbb, 0x87, 0xff, -0xff, 0xff, 0xc3, 0xbf, 0xbf, 0xbf, 0xc3, 0xff, -0xfb, 0xfb, 0xc3, 0xbb, 0xbb, 0xbb, 0xc3, 0xff, -0xff, 0xff, 0xc7, 0xbb, 0x83, 0xbf, 0xc3, 0xff, -0xe7, 0xdb, 0xdf, 0x87, 0xdf, 0xdf, 0xdf, 0xff, -0xff, 0xff, 0xc7, 0xbb, 0xbb, 0xc3, 0xfb, 0xc7, -0xbf, 0xbf, 0x87, 0xbb, 0xbb, 0xbb, 0xbb, 0xff, -0xef, 0xff, 0xcf, 0xef, 0xef, 0xef, 0xc7, 0xff, -0xf7, 0xff, 0xe7, 0xf7, 0xf7, 0xf7, 0xb7, 0xcf, -0xbf, 0xbf, 0xbb, 0xb7, 0x8f, 0xb7, 0xbb, 0xff, -0xcf, 0xef, 0xef, 0xef, 0xef, 0xef, 0xc7, 0xff, -0xff, 0xff, 0x93, 0xab, 0xab, 0xab, 0xbb, 0xff, -0xff, 0xff, 0x87, 0xbb, 0xbb, 0xbb, 0xbb, 0xff, -0xff, 0xff, 0xc7, 0xbb, 0xbb, 0xbb, 0xc7, 0xff, -0xff, 0xff, 0x87, 0xbb, 0xbb, 0x87, 0xbf, 0xbf, -0xff, 0xff, 0xc3, 0xbb, 0xbb, 0xc3, 0xfb, 0xfb, -0xff, 0xff, 0xa3, 0x9f, 0xbf, 0xbf, 0xbf, 0xff, -0xff, 0xff, 0xc3, 0xbf, 0xc7, 0xfb, 0x87, 0xff, -0xdf, 0xdf, 0x87, 0xdf, 0xdf, 0xdb, 0xe7, 0xff, -0xff, 0xff, 0xbb, 0xbb, 0xbb, 0xb3, 0xcb, 0xff, -0xff, 0xff, 0xbb, 0xbb, 0xbb, 0xd7, 0xef, 0xff, -0xff, 0xff, 0xbb, 0xbb, 0xab, 0xab, 0x93, 0xff, -0xff, 0xff, 0xbb, 0xd7, 0xef, 0xd7, 0xbb, 0xff, -0xff, 0xff, 0xbb, 0xbb, 0xbb, 0xc3, 0xfb, 0xc7, -0xff, 0xff, 0x83, 0xf7, 0xef, 0xdf, 0x83, 0xff, -0xe3, 0xcf, 0xcf, 0x9f, 0xcf, 0xcf, 0xe3, 0xff, -0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, -0x8f, 0xe7, 0xe7, 0xf3, 0xe7, 0xe7, 0x8f, 0xff, -0xcb, 0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -0xff, 0xab, 0xd7, 0xab, 0xd7, 0xab, 0xff, 0xff, -0x38, 0x44, 0x54, 0x5c, 0x58, 0x40, 0x3c, 0x00, -0x10, 0x28, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x00, -0x78, 0x44, 0x44, 0x78, 0x44, 0x44, 0x78, 0x00, -0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, -0x78, 0x44, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00, -0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00, -0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x00, -0x3c, 0x40, 0x40, 0x40, 0x4c, 0x44, 0x3c, 0x00, -0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x00, -0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, -0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, 0x00, -0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00, -0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x00, -0x44, 0x6c, 0x54, 0x54, 0x44, 0x44, 0x44, 0x00, -0x44, 0x44, 0x64, 0x54, 0x4c, 0x44, 0x44, 0x00, -0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, -0x78, 0x44, 0x44, 0x78, 0x40, 0x40, 0x40, 0x00, -0x38, 0x44, 0x44, 0x44, 0x54, 0x48, 0x34, 0x00, -0x78, 0x44, 0x44, 0x78, 0x50, 0x48, 0x44, 0x00, -0x38, 0x44, 0x40, 0x38, 0x04, 0x44, 0x38, 0x00, -0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, -0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, -0x44, 0x44, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, -0x44, 0x44, 0x44, 0x54, 0x54, 0x6c, 0x44, 0x00, -0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x00, -0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00, -0x7c, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7c, 0x00, -0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x00, -0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, -0x7c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, -0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, +0x00, 0x36, 0x7F, 0x7F, 0x3E, 0x1C, 0x08, 0x00, +0x18, 0x18, 0x18, 0x1F, 0x1F, 0x18, 0x18, 0x18, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x18, 0x18, 0x18, 0xF8, 0xF8, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0xF8, 0xF8, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18, +0x03, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xC0, +0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, +0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, +0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, +0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, +0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, +0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, +0x00, 0x1C, 0x1C, 0x77, 0x77, 0x08, 0x1C, 0x00, +0x00, 0x00, 0x00, 0x1F, 0x1F, 0x18, 0x18, 0x18, +0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, +0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, +0x00, 0x00, 0x3C, 0x7E, 0x7E, 0x7E, 0x3C, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, +0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, +0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, +0x18, 0x18, 0x18, 0x1F, 0x1F, 0x00, 0x00, 0x00, +0x78, 0x60, 0x78, 0x60, 0x7E, 0x18, 0x1E, 0x00, +0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x00, +0x00, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, +0x00, 0x18, 0x30, 0x7E, 0x30, 0x18, 0x00, 0x00, +0x00, 0x18, 0x0C, 0x7E, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, -0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, -0x28, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x28, 0x00, -0x10, 0x3c, 0x50, 0x38, 0x14, 0x78, 0x10, 0x00, -0x60, 0x64, 0x08, 0x10, 0x20, 0x4c, 0x0c, 0x00, -0x20, 0x50, 0x50, 0x20, 0x54, 0x48, 0x34, 0x00, -0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10, 0x00, -0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00, -0x10, 0x54, 0x38, 0x10, 0x38, 0x54, 0x10, 0x00, -0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, -0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, -0x38, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x38, 0x00, -0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, -0x38, 0x44, 0x04, 0x18, 0x20, 0x40, 0x7c, 0x00, -0x7c, 0x04, 0x08, 0x18, 0x04, 0x44, 0x38, 0x00, -0x08, 0x18, 0x28, 0x48, 0x7c, 0x08, 0x08, 0x00, -0x7c, 0x40, 0x78, 0x04, 0x04, 0x44, 0x38, 0x00, -0x1c, 0x20, 0x40, 0x78, 0x44, 0x44, 0x38, 0x00, -0x7c, 0x04, 0x08, 0x10, 0x20, 0x20, 0x20, 0x00, -0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00, -0x38, 0x44, 0x44, 0x3c, 0x04, 0x08, 0x70, 0x00, -0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x20, 0x00, -0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x00, -0x00, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00, -0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, -0x38, 0x44, 0x08, 0x10, 0x10, 0x00, 0x10, 0x00, -0x38, 0x44, 0x54, 0x5c, 0x58, 0x40, 0x3c, 0x00, -0x10, 0x28, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x00, -0x78, 0x44, 0x44, 0x78, 0x44, 0x44, 0x78, 0x00, -0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, -0x78, 0x44, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00, -0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00, -0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x00, -0x3c, 0x40, 0x40, 0x40, 0x4c, 0x44, 0x3c, 0x00, -0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x00, -0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, -0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, 0x00, -0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00, -0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x00, -0x44, 0x6c, 0x54, 0x54, 0x44, 0x44, 0x44, 0x00, -0x44, 0x44, 0x64, 0x54, 0x4c, 0x44, 0x44, 0x00, -0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, -0x78, 0x44, 0x44, 0x78, 0x40, 0x40, 0x40, 0x00, -0x38, 0x44, 0x44, 0x44, 0x54, 0x48, 0x34, 0x00, -0x78, 0x44, 0x44, 0x78, 0x50, 0x48, 0x44, 0x00, -0x38, 0x44, 0x40, 0x38, 0x04, 0x44, 0x38, 0x00, -0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, -0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, -0x44, 0x44, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, -0x44, 0x44, 0x44, 0x54, 0x54, 0x6c, 0x44, 0x00, -0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x00, -0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00, -0x7c, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7c, 0x00, -0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x00, -0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, -0x7c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, -0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, -0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, -0x40, 0x40, 0x78, 0x44, 0x44, 0x44, 0x78, 0x00, -0x00, 0x00, 0x3c, 0x40, 0x40, 0x40, 0x3c, 0x00, -0x04, 0x04, 0x3c, 0x44, 0x44, 0x44, 0x3c, 0x00, -0x00, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x3c, 0x00, -0x18, 0x24, 0x20, 0x78, 0x20, 0x20, 0x20, 0x00, -0x00, 0x00, 0x38, 0x44, 0x44, 0x3c, 0x04, 0x38, -0x40, 0x40, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, -0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x38, 0x00, -0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x48, 0x30, -0x40, 0x40, 0x44, 0x48, 0x70, 0x48, 0x44, 0x00, -0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, -0x00, 0x00, 0x6c, 0x54, 0x54, 0x54, 0x44, 0x00, -0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, -0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, -0x00, 0x00, 0x78, 0x44, 0x44, 0x78, 0x40, 0x40, -0x00, 0x00, 0x3c, 0x44, 0x44, 0x3c, 0x04, 0x04, -0x00, 0x00, 0x5c, 0x60, 0x40, 0x40, 0x40, 0x00, -0x00, 0x00, 0x3c, 0x40, 0x38, 0x04, 0x78, 0x00, -0x20, 0x20, 0x78, 0x20, 0x20, 0x24, 0x18, 0x00, -0x00, 0x00, 0x44, 0x44, 0x44, 0x4c, 0x34, 0x00, -0x00, 0x00, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, -0x00, 0x00, 0x44, 0x44, 0x54, 0x54, 0x6c, 0x00, -0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, -0x00, 0x00, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x38, -0x00, 0x00, 0x7c, 0x08, 0x10, 0x20, 0x7c, 0x00, -0x1c, 0x30, 0x30, 0x60, 0x30, 0x30, 0x1c, 0x00, -0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, -0x70, 0x18, 0x18, 0x0c, 0x18, 0x18, 0x70, 0x00, -0x34, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x54, 0x28, 0x54, 0x28, 0x54, 0x00, 0x00, +0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, +0x00, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, +0x00, 0x66, 0xFF, 0x66, 0x66, 0xFF, 0x66, 0x00, +0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0x00, +0x00, 0x66, 0x6C, 0x18, 0x30, 0x66, 0x46, 0x00, +0x1C, 0x36, 0x1C, 0x38, 0x6F, 0x66, 0x3B, 0x00, +0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0E, 0x1C, 0x18, 0x18, 0x1C, 0x0E, 0x00, +0x00, 0x70, 0x38, 0x18, 0x18, 0x38, 0x70, 0x00, +0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, +0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, +0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, +0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, +0x00, 0x3C, 0x66, 0x6E, 0x76, 0x66, 0x3C, 0x00, +0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7E, 0x00, +0x00, 0x3C, 0x66, 0x0C, 0x18, 0x30, 0x7E, 0x00, +0x00, 0x7E, 0x0C, 0x18, 0x0C, 0x66, 0x3C, 0x00, +0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x00, +0x00, 0x7E, 0x60, 0x7C, 0x06, 0x66, 0x3C, 0x00, +0x00, 0x3C, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, +0x00, 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x00, +0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, +0x00, 0x3C, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, +0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, +0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00, +0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, +0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, +0x00, 0x3C, 0x66, 0x0C, 0x18, 0x00, 0x18, 0x00, +0x00, 0x3C, 0x66, 0x6E, 0x6E, 0x60, 0x3E, 0x00, +0x00, 0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x00, +0x00, 0x7C, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, +0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x00, +0x00, 0x78, 0x6C, 0x66, 0x66, 0x6C, 0x78, 0x00, +0x00, 0x7E, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, +0x00, 0x7E, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, +0x00, 0x3E, 0x60, 0x60, 0x6E, 0x66, 0x3E, 0x00, +0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, +0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, +0x00, 0x06, 0x06, 0x06, 0x06, 0x66, 0x3C, 0x00, +0x00, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x00, +0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, +0x00, 0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x00, +0x00, 0x66, 0x76, 0x7E, 0x7E, 0x6E, 0x66, 0x00, +0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, +0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x00, +0x00, 0x3C, 0x66, 0x66, 0x66, 0x6C, 0x36, 0x00, +0x00, 0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x00, +0x00, 0x3C, 0x60, 0x3C, 0x06, 0x06, 0x3C, 0x00, +0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, +0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7E, 0x00, +0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, +0x00, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00, +0x00, 0x66, 0x66, 0x3C, 0x3C, 0x66, 0x66, 0x00, +0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, +0x00, 0x7E, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, +0x00, 0x1E, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00, +0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, +0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, +0x00, 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, +0x00, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x00, +0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, +0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, +0x00, 0x00, 0x3C, 0x60, 0x60, 0x60, 0x3C, 0x00, +0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, +0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, +0x00, 0x0E, 0x18, 0x3E, 0x18, 0x18, 0x18, 0x00, +0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x7C, +0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x00, +0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00, +0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3C, +0x00, 0x60, 0x60, 0x6C, 0x78, 0x6C, 0x66, 0x00, +0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, +0x00, 0x00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0x00, +0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, +0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, +0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, +0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06, +0x00, 0x00, 0x7C, 0x66, 0x60, 0x60, 0x60, 0x00, +0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, +0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x0E, 0x00, +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, +0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, +0x00, 0x00, 0x63, 0x6B, 0x7F, 0x3E, 0x36, 0x00, +0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, +0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x0C, 0x78, +0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, +0x00, 0x18, 0x3C, 0x7E, 0x7E, 0x18, 0x3C, 0x00, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x00, 0x7E, 0x78, 0x7C, 0x6E, 0x66, 0x06, 0x00, +0x08, 0x18, 0x38, 0x78, 0x38, 0x18, 0x08, 0x00, +0x10, 0x18, 0x1C, 0x1E, 0x1C, 0x18, 0x10, 0x00, +0xFF, 0xC9, 0x80, 0x80, 0xC1, 0xE3, 0xF7, 0xFF, +0xE7, 0xE7, 0xE7, 0xE0, 0xE0, 0xE7, 0xE7, 0xE7, +0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, +0xE7, 0xE7, 0xE7, 0x07, 0x07, 0xFF, 0xFF, 0xFF, +0xE7, 0xE7, 0xE7, 0x07, 0x07, 0xE7, 0xE7, 0xE7, +0xFF, 0xFF, 0xFF, 0x07, 0x07, 0xE7, 0xE7, 0xE7, +0xFC, 0xF8, 0xF1, 0xE3, 0xC7, 0x8F, 0x1F, 0x3F, +0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, +0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, +0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, +0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, +0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, +0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, +0xFF, 0xE3, 0xE3, 0x88, 0x88, 0xF7, 0xE3, 0xFF, +0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xE7, 0xE7, 0xE7, +0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, +0xE7, 0xE7, 0xE7, 0x00, 0x00, 0xE7, 0xE7, 0xE7, +0xFF, 0xFF, 0xC3, 0x81, 0x81, 0x81, 0xC3, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, +0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, +0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xE7, 0xE7, 0xE7, +0xE7, 0xE7, 0xE7, 0x00, 0x00, 0xFF, 0xFF, 0xFF, +0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, +0xE7, 0xE7, 0xE7, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, +0x87, 0x9F, 0x87, 0x9F, 0x81, 0xE7, 0xE1, 0xFF, +0xFF, 0xE7, 0xC3, 0x81, 0xE7, 0xE7, 0xE7, 0xFF, +0xFF, 0xE7, 0xE7, 0xE7, 0x81, 0xC3, 0xE7, 0xFF, +0xFF, 0xE7, 0xCF, 0x81, 0xCF, 0xE7, 0xFF, 0xFF, +0xFF, 0xE7, 0xF3, 0x81, 0xF3, 0xE7, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xE7, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0xFF, +0xFF, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0x99, 0x00, 0x99, 0x99, 0x00, 0x99, 0xFF, +0xE7, 0xC1, 0x9F, 0xC3, 0xF9, 0x83, 0xE7, 0xFF, +0xFF, 0x99, 0x93, 0xE7, 0xCF, 0x99, 0xB9, 0xFF, +0xE3, 0xC9, 0xE3, 0xC7, 0x90, 0x99, 0xC4, 0xFF, +0xFF, 0xE7, 0xE7, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xF1, 0xE3, 0xE7, 0xE7, 0xE3, 0xF1, 0xFF, +0xFF, 0x8F, 0xC7, 0xE7, 0xE7, 0xC7, 0x8F, 0xFF, +0xFF, 0x99, 0xC3, 0x00, 0xC3, 0x99, 0xFF, 0xFF, +0xFF, 0xE7, 0xE7, 0x81, 0xE7, 0xE7, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xE7, 0xCF, +0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xE7, 0xFF, +0xFF, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0xBF, 0xFF, +0xFF, 0xC3, 0x99, 0x91, 0x89, 0x99, 0xC3, 0xFF, +0xFF, 0xE7, 0xC7, 0xE7, 0xE7, 0xE7, 0x81, 0xFF, +0xFF, 0xC3, 0x99, 0xF3, 0xE7, 0xCF, 0x81, 0xFF, +0xFF, 0x81, 0xF3, 0xE7, 0xF3, 0x99, 0xC3, 0xFF, +0xFF, 0xF3, 0xE3, 0xC3, 0x93, 0x81, 0xF3, 0xFF, +0xFF, 0x81, 0x9F, 0x83, 0xF9, 0x99, 0xC3, 0xFF, +0xFF, 0xC3, 0x9F, 0x83, 0x99, 0x99, 0xC3, 0xFF, +0xFF, 0x81, 0xF9, 0xF3, 0xE7, 0xCF, 0xCF, 0xFF, +0xFF, 0xC3, 0x99, 0xC3, 0x99, 0x99, 0xC3, 0xFF, +0xFF, 0xC3, 0x99, 0xC1, 0xF9, 0xF3, 0xC7, 0xFF, +0xFF, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, +0xFF, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xCF, +0xF9, 0xF3, 0xE7, 0xCF, 0xE7, 0xF3, 0xF9, 0xFF, +0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, +0x9F, 0xCF, 0xE7, 0xF3, 0xE7, 0xCF, 0x9F, 0xFF, +0xFF, 0xC3, 0x99, 0xF3, 0xE7, 0xFF, 0xE7, 0xFF, +0xFF, 0xC3, 0x99, 0x91, 0x91, 0x9F, 0xC1, 0xFF, +0xFF, 0xE7, 0xC3, 0x99, 0x99, 0x81, 0x99, 0xFF, +0xFF, 0x83, 0x99, 0x83, 0x99, 0x99, 0x83, 0xFF, +0xFF, 0xC3, 0x99, 0x9F, 0x9F, 0x99, 0xC3, 0xFF, +0xFF, 0x87, 0x93, 0x99, 0x99, 0x93, 0x87, 0xFF, +0xFF, 0x81, 0x9F, 0x83, 0x9F, 0x9F, 0x81, 0xFF, +0xFF, 0x81, 0x9F, 0x83, 0x9F, 0x9F, 0x9F, 0xFF, +0xFF, 0xC1, 0x9F, 0x9F, 0x91, 0x99, 0xC1, 0xFF, +0xFF, 0x99, 0x99, 0x81, 0x99, 0x99, 0x99, 0xFF, +0xFF, 0x81, 0xE7, 0xE7, 0xE7, 0xE7, 0x81, 0xFF, +0xFF, 0xF9, 0xF9, 0xF9, 0xF9, 0x99, 0xC3, 0xFF, +0xFF, 0x99, 0x93, 0x87, 0x87, 0x93, 0x99, 0xFF, +0xFF, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x81, 0xFF, +0xFF, 0x9C, 0x88, 0x80, 0x94, 0x9C, 0x9C, 0xFF, +0xFF, 0x99, 0x89, 0x81, 0x81, 0x91, 0x99, 0xFF, +0xFF, 0xC3, 0x99, 0x99, 0x99, 0x99, 0xC3, 0xFF, +0xFF, 0x83, 0x99, 0x99, 0x83, 0x9F, 0x9F, 0xFF, +0xFF, 0xC3, 0x99, 0x99, 0x99, 0x93, 0xC9, 0xFF, +0xFF, 0x83, 0x99, 0x99, 0x83, 0x93, 0x99, 0xFF, +0xFF, 0xC3, 0x9F, 0xC3, 0xF9, 0xF9, 0xC3, 0xFF, +0xFF, 0x81, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xFF, +0xFF, 0x99, 0x99, 0x99, 0x99, 0x99, 0x81, 0xFF, +0xFF, 0x99, 0x99, 0x99, 0x99, 0xC3, 0xE7, 0xFF, +0xFF, 0x9C, 0x9C, 0x94, 0x80, 0x88, 0x9C, 0xFF, +0xFF, 0x99, 0x99, 0xC3, 0xC3, 0x99, 0x99, 0xFF, +0xFF, 0x99, 0x99, 0xC3, 0xE7, 0xE7, 0xE7, 0xFF, +0xFF, 0x81, 0xF3, 0xE7, 0xCF, 0x9F, 0x81, 0xFF, +0xFF, 0xE1, 0xE7, 0xE7, 0xE7, 0xE7, 0xE1, 0xFF, +0xFF, 0xBF, 0x9F, 0xCF, 0xE7, 0xF3, 0xF9, 0xFF, +0xFF, 0x87, 0xE7, 0xE7, 0xE7, 0xE7, 0x87, 0xFF, +0xFF, 0xF7, 0xE3, 0xC9, 0x9C, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, +0xFF, 0xE7, 0xC3, 0x81, 0x81, 0xC3, 0xE7, 0xFF, +0xFF, 0xFF, 0xC3, 0xF9, 0xC1, 0x99, 0xC1, 0xFF, +0xFF, 0x9F, 0x9F, 0x83, 0x99, 0x99, 0x83, 0xFF, +0xFF, 0xFF, 0xC3, 0x9F, 0x9F, 0x9F, 0xC3, 0xFF, +0xFF, 0xF9, 0xF9, 0xC1, 0x99, 0x99, 0xC1, 0xFF, +0xFF, 0xFF, 0xC3, 0x99, 0x81, 0x9F, 0xC3, 0xFF, +0xFF, 0xF1, 0xE7, 0xC1, 0xE7, 0xE7, 0xE7, 0xFF, +0xFF, 0xFF, 0xC1, 0x99, 0x99, 0xC1, 0xF9, 0x83, +0xFF, 0x9F, 0x9F, 0x83, 0x99, 0x99, 0x99, 0xFF, +0xFF, 0xE7, 0xFF, 0xC7, 0xE7, 0xE7, 0xC3, 0xFF, +0xFF, 0xF9, 0xFF, 0xF9, 0xF9, 0xF9, 0xF9, 0xC3, +0xFF, 0x9F, 0x9F, 0x93, 0x87, 0x93, 0x99, 0xFF, +0xFF, 0xC7, 0xE7, 0xE7, 0xE7, 0xE7, 0xC3, 0xFF, +0xFF, 0xFF, 0x99, 0x80, 0x80, 0x94, 0x9C, 0xFF, +0xFF, 0xFF, 0x83, 0x99, 0x99, 0x99, 0x99, 0xFF, +0xFF, 0xFF, 0xC3, 0x99, 0x99, 0x99, 0xC3, 0xFF, +0xFF, 0xFF, 0x83, 0x99, 0x99, 0x83, 0x9F, 0x9F, +0xFF, 0xFF, 0xC1, 0x99, 0x99, 0xC1, 0xF9, 0xF9, +0xFF, 0xFF, 0x83, 0x99, 0x9F, 0x9F, 0x9F, 0xFF, +0xFF, 0xFF, 0xC1, 0x9F, 0xC3, 0xF9, 0x83, 0xFF, +0xFF, 0xE7, 0x81, 0xE7, 0xE7, 0xE7, 0xF1, 0xFF, +0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0xC1, 0xFF, +0xFF, 0xFF, 0x99, 0x99, 0x99, 0xC3, 0xE7, 0xFF, +0xFF, 0xFF, 0x9C, 0x94, 0x80, 0xC1, 0xC9, 0xFF, +0xFF, 0xFF, 0x99, 0xC3, 0xE7, 0xC3, 0x99, 0xFF, +0xFF, 0xFF, 0x99, 0x99, 0x99, 0xC1, 0xF3, 0x87, +0xFF, 0xFF, 0x81, 0xF3, 0xE7, 0xCF, 0x81, 0xFF, +0xFF, 0xE7, 0xC3, 0x81, 0x81, 0xE7, 0xC3, 0xFF, +0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, +0xFF, 0x81, 0x87, 0x83, 0x91, 0x99, 0xF9, 0xFF, +0xF7, 0xE7, 0xC7, 0x87, 0xC7, 0xE7, 0xF7, 0xFF, +0xEF, 0xE7, 0xE3, 0xE1, 0xE3, 0xE7, 0xEF, 0xFF, }; - -/* Well, this is finally done ! */ diff --git a/libretro/graph.c b/libretro/graph.c index 55e1fef..5142871 100755 --- a/libretro/graph.c +++ b/libretro/graph.c @@ -8,6 +8,24 @@ #include "libretro-core.h" extern int VIRTUAL_WIDTH; +extern int VKBD_OPACITY; + +unsigned Opacity(unsigned color1, unsigned color2){ + + unsigned r,g,b; + + if (VKBD_OPACITY==1){ + r=(R_RGB565(color1)/2)+(R_RGB565(color2)/2); + g=(G_RGB565(color1)/2)+(G_RGB565(color2)/2); + b=(B_RGB565(color1)/2)+(B_RGB565(color2)/2); + return RGB565(r,g,b); + } + else + { + return color2; + } + +} void DrawFBoxBmp(char *buffer,int x,int y,int dx,int dy,unsigned color){ @@ -24,7 +42,7 @@ unsigned short *mbuffer=(unsigned short *)buffer; for(j=y;j= 0) ? 1 : -1; - sy = (dy >= 0) ? 1 : -1; + int dx = x2 - x1; + int dy = y2 - y1; + int sx = (dx >= 0) ? 1 : -1; + int sy = (dy >= 0) ? 1 : -1; if (dx==0) { if (dy>0) { @@ -135,7 +146,7 @@ unsigned short *mbuffer=(unsigned short *)buffer; } else { idx=x1+y1*VIRTUAL_WIDTH; - mbuffer[idx]=color; + mbuffer[idx]=Opacity(mbuffer[idx],color); return ; } } @@ -150,8 +161,8 @@ unsigned short *mbuffer=(unsigned short *)buffer; } } - dx = sx * dx + 1; - dy = sy * dy + 1; + dx = sx * dx + 1; + dy = sy * dy + 1; pixx = 1; pixy = VIRTUAL_WIDTH; @@ -174,7 +185,7 @@ unsigned short *mbuffer=(unsigned short *)buffer; idx=x1+y1*VIRTUAL_WIDTH; for (; x < dx; x++, idx +=pixx) { - mbuffer[idx]=color; + mbuffer[idx]=Opacity(mbuffer[idx],color); y += dy; if (y >= dx) { y -= dx; @@ -183,55 +194,28 @@ unsigned short *mbuffer=(unsigned short *)buffer; } } -/* -void DrawBox(char *buffer,box b,char t[],unsigned color){ - - - DrawBoxBmp(mbuffer,b.x,b.y,b.dx,b.dy,color); - textCpixel(mbuffer,b.x, 3*b.x + b.dx ,b.y+2,color,1,1,4,"%s",t); - -} - -void DrawBoxF(char *buffer,box b,char t[],unsigned color,unsigned border){ - - int ydec=b.y+(b.dy/2)-4; - - - if(ydecmaxstrlen) strlen = maxstrlen; int surfw=strlen * 7 * xscale; int surfh=8 * yscale; @@ -342,7 +327,7 @@ unsigned char *mbuffer=(unsigned char *)surf; for(yrepeat = y; yrepeat < y+ surfh; yrepeat++) for(xrepeat = x; xrepeat< x+surfw; xrepeat++,yptr++) - if(*yptr!=0)mbuffer[xrepeat+yrepeat*VIRTUAL_WIDTH] = *yptr; + if(*yptr!=0)mbuffer[xrepeat+yrepeat*VIRTUAL_WIDTH] = Opacity(mbuffer[xrepeat+yrepeat*VIRTUAL_WIDTH],*yptr); free(linesurf); diff --git a/libretro/libretro-common/include/libretro.h b/libretro/libretro-common/include/libretro.h index 5790173..3d6df6f 100644 --- a/libretro/libretro-common/include/libretro.h +++ b/libretro/libretro-common/include/libretro.h @@ -282,6 +282,15 @@ enum retro_language RETRO_LANGUAGE_PERSIAN = 20, RETRO_LANGUAGE_HEBREW = 21, RETRO_LANGUAGE_ASTURIAN = 22, + RETRO_LANGUAGE_FINNISH = 23, + RETRO_LANGUAGE_INDONESIAN = 24, + RETRO_LANGUAGE_SWEDISH = 25, + RETRO_LANGUAGE_UKRAINIAN = 26, + RETRO_LANGUAGE_CZECH = 27, + RETRO_LANGUAGE_CATALAN_VALENCIA = 28, + RETRO_LANGUAGE_CATALAN = 29, + RETRO_LANGUAGE_BRITISH_ENGLISH = 30, + RETRO_LANGUAGE_HUNGARIAN = 31, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -712,6 +721,9 @@ enum retro_mod * state of rumble motors in controllers. * A strong and weak motor is supported, and they can be * controlled indepedently. + * Should be called from either retro_init() or retro_load_game(). + * Should not be called from retro_set_environment(). + * Returns false if rumble functionality is unavailable. */ #define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24 /* uint64_t * -- @@ -1127,6 +1139,13 @@ enum retro_mod * retro_core_option_definition structs to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL. * This allows the core to additionally set option sublabel information * and/or provide localisation support. + * + * If version is >= 2, core options may instead be set by passing + * a retro_core_options_v2 struct to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + * or an array of retro_core_options_v2 structs to + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL. This allows the core + * to additionally set optional core option category information + * for frontends with core option category support. */ #define RETRO_ENVIRONMENT_SET_CORE_OPTIONS 53 @@ -1168,7 +1187,7 @@ enum retro_mod * default value is NULL, the first entry in the * retro_core_option_definition::values array is treated as the default. * - * The number of possible options should be very limited, + * The number of possible option values should be very limited, * and must be less than RETRO_NUM_CORE_OPTION_VALUES_MAX. * i.e. it should be feasible to cycle through options * without a keyboard. @@ -1201,6 +1220,7 @@ enum retro_mod * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION * returns an API version of >= 1. * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS. * This should be called the first time as early as * possible (ideally in retro_set_environment). * Afterwards it may be called again for the core to communicate @@ -1335,6 +1355,445 @@ enum retro_mod * should be considered active. */ +#define RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK 62 + /* const struct retro_audio_buffer_status_callback * -- + * Lets the core know the occupancy level of the frontend + * audio buffer. Can be used by a core to attempt frame + * skipping in order to avoid buffer under-runs. + * A core may pass NULL to disable buffer status reporting + * in the frontend. + */ + +#define RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY 63 + /* const unsigned * -- + * Sets minimum frontend audio latency in milliseconds. + * Resultant audio latency may be larger than set value, + * or smaller if a hardware limit is encountered. A frontend + * is expected to honour requests up to 512 ms. + * + * - If value is less than current frontend + * audio latency, callback has no effect + * - If value is zero, default frontend audio + * latency is set + * + * May be used by a core to increase audio latency and + * therefore decrease the probability of buffer under-runs + * (crackling) when performing 'intensive' operations. + * A core utilising RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK + * to implement audio-buffer-based frame skipping may achieve + * optimal results by setting the audio latency to a 'high' + * (typically 6x or 8x) integer multiple of the expected + * frame time. + * + * WARNING: This can only be called from within retro_run(). + * Calling this can require a full reinitialization of audio + * drivers in the frontend, so it is important to call it very + * sparingly, and usually only with the users explicit consent. + * An eventual driver reinitialize will happen so that audio + * callbacks happening after this call within the same retro_run() + * call will target the newly initialized driver. + */ + +#define RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE 64 + /* const struct retro_fastforwarding_override * -- + * Used by a libretro core to override the current + * fastforwarding mode of the frontend. + * If NULL is passed to this function, the frontend + * will return true if fastforwarding override + * functionality is supported (no change in + * fastforwarding state will occur in this case). + */ + +#define RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE 65 + /* const struct retro_system_content_info_override * -- + * Allows an implementation to override 'global' content + * info parameters reported by retro_get_system_info(). + * Overrides also affect subsystem content info parameters + * set via RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO. + * This function must be called inside retro_set_environment(). + * If callback returns false, content info overrides + * are unsupported by the frontend, and will be ignored. + * If callback returns true, extended game info may be + * retrieved by calling RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * in retro_load_game() or retro_load_game_special(). + * + * 'data' points to an array of retro_system_content_info_override + * structs terminated by a { NULL, false, false } element. + * If 'data' is NULL, no changes will be made to the frontend; + * a core may therefore pass NULL in order to test whether + * the RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE and + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT callbacks are supported + * by the frontend. + * + * For struct member descriptions, see the definition of + * struct retro_system_content_info_override. + * + * Example: + * + * - struct retro_system_info: + * { + * "My Core", // library_name + * "v1.0", // library_version + * "m3u|md|cue|iso|chd|sms|gg|sg", // valid_extensions + * true, // need_fullpath + * false // block_extract + * } + * + * - Array of struct retro_system_content_info_override: + * { + * { + * "md|sms|gg", // extensions + * false, // need_fullpath + * true // persistent_data + * }, + * { + * "sg", // extensions + * false, // need_fullpath + * false // persistent_data + * }, + * { NULL, false, false } + * } + * + * Result: + * - Files of type m3u, cue, iso, chd will not be + * loaded by the frontend. Frontend will pass a + * valid path to the core, and core will handle + * loading internally + * - Files of type md, sms, gg will be loaded by + * the frontend. A valid memory buffer will be + * passed to the core. This memory buffer will + * remain valid until retro_deinit() returns + * - Files of type sg will be loaded by the frontend. + * A valid memory buffer will be passed to the core. + * This memory buffer will remain valid until + * retro_load_game() (or retro_load_game_special()) + * returns + * + * NOTE: If an extension is listed multiple times in + * an array of retro_system_content_info_override + * structs, only the first instance will be registered + */ + +#define RETRO_ENVIRONMENT_GET_GAME_INFO_EXT 66 + /* const struct retro_game_info_ext ** -- + * Allows an implementation to fetch extended game + * information, providing additional content path + * and memory buffer status details. + * This function may only be called inside + * retro_load_game() or retro_load_game_special(). + * If callback returns false, extended game information + * is unsupported by the frontend. In this case, only + * regular retro_game_info will be available. + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT is guaranteed + * to return true if RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE + * returns true. + * + * 'data' points to an array of retro_game_info_ext structs. + * + * For struct member descriptions, see the definition of + * struct retro_game_info_ext. + * + * - If function is called inside retro_load_game(), + * the retro_game_info_ext array is guaranteed to + * have a size of 1 - i.e. the returned pointer may + * be used to access directly the members of the + * first retro_game_info_ext struct, for example: + * + * struct retro_game_info_ext *game_info_ext; + * if (environ_cb(RETRO_ENVIRONMENT_GET_GAME_INFO_EXT, &game_info_ext)) + * printf("Content Directory: %s\n", game_info_ext->dir); + * + * - If the function is called inside retro_load_game_special(), + * the retro_game_info_ext array is guaranteed to have a + * size equal to the num_info argument passed to + * retro_load_game_special() + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 67 + /* const struct retro_core_options_v2 * -- + * Allows an implementation to signal the environment + * which variables it might want to check for later using + * GET_VARIABLE. + * This allows the frontend to present these variables to + * a user dynamically. + * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of >= 2. + * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS. + * This should be called the first time as early as + * possible (ideally in retro_set_environment). + * Afterwards it may be called again for the core to communicate + * updated options to the frontend, but the number of core + * options must not change from the number in the initial call. + * If RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION returns an API + * version of >= 2, this callback is guaranteed to succeed + * (i.e. callback return value does not indicate success) + * If callback returns true, frontend has core option category + * support. + * If callback returns false, frontend does not have core option + * category support. + * + * 'data' points to a retro_core_options_v2 struct, containing + * of two pointers: + * - retro_core_options_v2::categories is an array of + * retro_core_option_v2_category structs terminated by a + * { NULL, NULL, NULL } element. If retro_core_options_v2::categories + * is NULL, all core options will have no category and will be shown + * at the top level of the frontend core option interface. If frontend + * does not have core option category support, categories array will + * be ignored. + * - retro_core_options_v2::definitions is an array of + * retro_core_option_v2_definition structs terminated by a + * { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL } + * element. + * + * >> retro_core_option_v2_category notes: + * + * - retro_core_option_v2_category::key should contain string + * that uniquely identifies the core option category. Valid + * key characters are [a-z, A-Z, 0-9, _, -] + * Namespace collisions with other implementations' category + * keys are permitted. + * - retro_core_option_v2_category::desc should contain a human + * readable description of the category key. + * - retro_core_option_v2_category::info should contain any + * additional human readable information text that a typical + * user may need to understand the nature of the core option + * category. + * + * Example entry: + * { + * "advanced_settings", + * "Advanced", + * "Options affecting low-level emulation performance and accuracy." + * } + * + * >> retro_core_option_v2_definition notes: + * + * - retro_core_option_v2_definition::key should be namespaced to not + * collide with other implementations' keys. e.g. A core called + * 'foo' should use keys named as 'foo_option'. Valid key characters + * are [a-z, A-Z, 0-9, _, -]. + * - retro_core_option_v2_definition::desc should contain a human readable + * description of the key. Will be used when the frontend does not + * have core option category support. Examples: "Aspect Ratio" or + * "Video > Aspect Ratio". + * - retro_core_option_v2_definition::desc_categorized should contain a + * human readable description of the key, which will be used when + * frontend has core option category support. Example: "Aspect Ratio", + * where associated retro_core_option_v2_category::desc is "Video". + * If empty or NULL, the string specified by + * retro_core_option_v2_definition::desc will be used instead. + * retro_core_option_v2_definition::desc_categorized will be ignored + * if retro_core_option_v2_definition::category_key is empty or NULL. + * - retro_core_option_v2_definition::info should contain any additional + * human readable information text that a typical user may need to + * understand the functionality of the option. + * - retro_core_option_v2_definition::info_categorized should contain + * any additional human readable information text that a typical user + * may need to understand the functionality of the option, and will be + * used when frontend has core option category support. This is provided + * to accommodate the case where info text references an option by + * name/desc, and the desc/desc_categorized text for that option differ. + * If empty or NULL, the string specified by + * retro_core_option_v2_definition::info will be used instead. + * retro_core_option_v2_definition::info_categorized will be ignored + * if retro_core_option_v2_definition::category_key is empty or NULL. + * - retro_core_option_v2_definition::category_key should contain a + * category identifier (e.g. "video" or "audio") that will be + * assigned to the core option if frontend has core option category + * support. A categorized option will be shown in a subsection/ + * submenu of the frontend core option interface. If key is empty + * or NULL, or if key does not match one of the + * retro_core_option_v2_category::key values in the associated + * retro_core_option_v2_category array, option will have no category + * and will be shown at the top level of the frontend core option + * interface. + * - retro_core_option_v2_definition::values is an array of + * retro_core_option_value structs terminated by a { NULL, NULL } + * element. + * --> retro_core_option_v2_definition::values[index].value is an + * expected option value. + * --> retro_core_option_v2_definition::values[index].label is a + * human readable label used when displaying the value on screen. + * If NULL, the value itself is used. + * - retro_core_option_v2_definition::default_value is the default + * core option setting. It must match one of the expected option + * values in the retro_core_option_v2_definition::values array. If + * it does not, or the default value is NULL, the first entry in the + * retro_core_option_v2_definition::values array is treated as the + * default. + * + * The number of possible option values should be very limited, + * and must be less than RETRO_NUM_CORE_OPTION_VALUES_MAX. + * i.e. it should be feasible to cycle through options + * without a keyboard. + * + * Example entries: + * + * - Uncategorized: + * + * { + * "foo_option", + * "Speed hack coprocessor X", + * NULL, + * "Provides increased performance at the expense of reduced accuracy.", + * NULL, + * NULL, + * { + * { "false", NULL }, + * { "true", NULL }, + * { "unstable", "Turbo (Unstable)" }, + * { NULL, NULL }, + * }, + * "false" + * } + * + * - Categorized: + * + * { + * "foo_option", + * "Advanced > Speed hack coprocessor X", + * "Speed hack coprocessor X", + * "Setting 'Advanced > Speed hack coprocessor X' to 'true' or 'Turbo' provides increased performance at the expense of reduced accuracy", + * "Setting 'Speed hack coprocessor X' to 'true' or 'Turbo' provides increased performance at the expense of reduced accuracy", + * "advanced_settings", + * { + * { "false", NULL }, + * { "true", NULL }, + * { "unstable", "Turbo (Unstable)" }, + * { NULL, NULL }, + * }, + * "false" + * } + * + * Only strings are operated on. The possible values will + * generally be displayed and stored as-is by the frontend. + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL 68 + /* const struct retro_core_options_v2_intl * -- + * Allows an implementation to signal the environment + * which variables it might want to check for later using + * GET_VARIABLE. + * This allows the frontend to present these variables to + * a user dynamically. + * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of >= 2. + * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2. + * This should be called the first time as early as + * possible (ideally in retro_set_environment). + * Afterwards it may be called again for the core to communicate + * updated options to the frontend, but the number of core + * options must not change from the number in the initial call. + * If RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION returns an API + * version of >= 2, this callback is guaranteed to succeed + * (i.e. callback return value does not indicate success) + * If callback returns true, frontend has core option category + * support. + * If callback returns false, frontend does not have core option + * category support. + * + * This is fundamentally the same as RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + * with the addition of localisation support. The description of the + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 callback should be consulted + * for further details. + * + * 'data' points to a retro_core_options_v2_intl struct. + * + * - retro_core_options_v2_intl::us is a pointer to a + * retro_core_options_v2 struct defining the US English + * core options implementation. It must point to a valid struct. + * + * - retro_core_options_v2_intl::local is a pointer to a + * retro_core_options_v2 struct defining core options for + * the current frontend language. It may be NULL (in which case + * retro_core_options_v2_intl::us is used by the frontend). Any items + * missing from this struct will be read from + * retro_core_options_v2_intl::us instead. + * + * NOTE: Default core option values are always taken from the + * retro_core_options_v2_intl::us struct. Any default values in + * the retro_core_options_v2_intl::local struct will be ignored. + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK 69 + /* const struct retro_core_options_update_display_callback * -- + * Allows a frontend to signal that a core must update + * the visibility of any dynamically hidden core options, + * and enables the frontend to detect visibility changes. + * Used by the frontend to update the menu display status + * of core options without requiring a call of retro_run(). + * Must be called in retro_set_environment(). + */ + +#define RETRO_ENVIRONMENT_SET_VARIABLE 70 + /* const struct retro_variable * -- + * Allows an implementation to notify the frontend + * that a core option value has changed. + * + * retro_variable::key and retro_variable::value + * must match strings that have been set previously + * via one of the following: + * + * - RETRO_ENVIRONMENT_SET_VARIABLES + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + * + * After changing a core option value via this + * callback, RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE + * will return true. + * + * If data is NULL, no changes will be registered + * and the callback will return true; an + * implementation may therefore pass NULL in order + * to test whether the callback is supported. + */ + +#define RETRO_ENVIRONMENT_GET_THROTTLE_STATE (71 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_throttle_state * -- + * Allows an implementation to get details on the actual rate + * the frontend is attempting to call retro_run(). + */ + +#define RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT (72 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* int * -- + * Tells the core about the context the frontend is asking for savestate. + * (see enum retro_savestate_context) + */ + +#define RETRO_ENVIRONMENT_GET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_SUPPORT (73 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_hw_render_context_negotiation_interface * -- + * Before calling SET_HW_RNEDER_CONTEXT_NEGOTIATION_INTERFACE, a core can query + * which version of the interface is supported. + * + * Frontend looks at interface_type and returns the maximum supported + * context negotiation interface version. + * If the interface_type is not supported or recognized by the frontend, a version of 0 + * must be returned in interface_version and true is returned by frontend. + * + * If this environment call returns true with interface_version greater than 0, + * a core can always use a negotiation interface version larger than what the frontend returns, but only + * earlier versions of the interface will be used by the frontend. + * A frontend must not reject a negotiation interface version that is larger than + * what the frontend supports. Instead, the frontend will use the older entry points that it recognizes. + * If this is incompatible with a particular core's requirements, it can error out early. + * + * Backwards compatibility note: + * This environment call was introduced after Vulkan v1 context negotiation. + * If this environment call is not supported by frontend - i.e. the environment call returns false - + * only Vulkan v1 context negotiation is supported (if Vulkan HW rendering is supported at all). + * If a core uses Vulkan negotiation interface with version > 1, negotiation may fail unexpectedly. + * All future updates to the context negotiation interface implies that frontend must support + * this environment call to query support. + */ + + /* VFS functionality */ /* File paths: @@ -2224,6 +2683,30 @@ struct retro_frame_time_callback retro_usec_t reference; }; +/* Notifies a libretro core of the current occupancy + * level of the frontend audio buffer. + * + * - active: 'true' if audio buffer is currently + * in use. Will be 'false' if audio is + * disabled in the frontend + * + * - occupancy: Given as a value in the range [0,100], + * corresponding to the occupancy percentage + * of the audio buffer + * + * - underrun_likely: 'true' if the frontend expects an + * audio buffer underrun during the + * next frame (indicates that a core + * should attempt frame skipping) + * + * It will be called right before retro_run() every frame. */ +typedef void (RETRO_CALLCONV *retro_audio_buffer_status_callback_t)( + bool active, unsigned occupancy, bool underrun_likely); +struct retro_audio_buffer_status_callback +{ + retro_audio_buffer_status_callback_t callback; +}; + /* Pass this to retro_video_refresh_t if rendering to hardware. * Passing NULL to retro_video_refresh_t is still a frame dupe as normal. * */ @@ -2548,6 +3031,35 @@ enum retro_pixel_format RETRO_PIXEL_FORMAT_UNKNOWN = INT_MAX }; +enum retro_savestate_context +{ + /* Standard savestate written to disk. */ + RETRO_SAVESTATE_CONTEXT_NORMAL = 0, + + /* Savestate where you are guaranteed that the same instance will load the save state. + * You can store internal pointers to code or data. + * It's still a full serialization and deserialization, and could be loaded or saved at any time. + * It won't be written to disk or sent over the network. + */ + RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_INSTANCE = 1, + + /* Savestate where you are guaranteed that the same emulator binary will load that savestate. + * You can skip anything that would slow down saving or loading state but you can not store internal pointers. + * It won't be written to disk or sent over the network. + * Example: "Second Instance" runahead + */ + RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_BINARY = 2, + + /* Savestate used within a rollback netplay feature. + * You should skip anything that would unnecessarily increase bandwidth usage. + * It won't be written to disk but it will be sent over the network. + */ + RETRO_SAVESTATE_CONTEXT_ROLLBACK_NETPLAY = 3, + + /* Ensure sizeof() == sizeof(int). */ + RETRO_SAVESTATE_CONTEXT_UNKNOWN = INT_MAX +}; + struct retro_message { const char *msg; /* Message to be displayed. */ @@ -2714,6 +3226,213 @@ struct retro_system_info bool block_extract; }; +/* Defines overrides which modify frontend handling of + * specific content file types. + * An array of retro_system_content_info_override is + * passed to RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE + * NOTE: In the following descriptions, references to + * retro_load_game() may be replaced with + * retro_load_game_special() */ +struct retro_system_content_info_override +{ + /* A list of file extensions for which the override + * should apply, delimited by a 'pipe' character + * (e.g. "md|sms|gg") + * Permitted file extensions are limited to those + * included in retro_system_info::valid_extensions + * and/or retro_subsystem_rom_info::valid_extensions */ + const char *extensions; + + /* Overrides the need_fullpath value set in + * retro_system_info and/or retro_subsystem_rom_info. + * To reiterate: + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info::path is guaranteed to contain a valid + * path to an existent file + * - retro_game_info::data and retro_game_info::size are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - retro_game_info::path may be NULL + * - retro_game_info::data and retro_game_info::size are guaranteed + * to be valid + * + * In addition: + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info_ext::full_path is guaranteed to contain a valid + * path to an existent file + * - retro_game_info_ext::archive_path may be NULL + * - retro_game_info_ext::archive_file may be NULL + * - retro_game_info_ext::dir is guaranteed to contain a valid path + * to the directory in which the content file exists + * - retro_game_info_ext::name is guaranteed to contain the + * basename of the content file, without extension + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file in lower case format + * - retro_game_info_ext::data and retro_game_info_ext::size + * are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - If retro_game_info_ext::file_in_archive is false: + * - retro_game_info_ext::full_path is guaranteed to contain + * a valid path to an existent file + * - retro_game_info_ext::archive_path may be NULL + * - retro_game_info_ext::archive_file may be NULL + * - retro_game_info_ext::dir is guaranteed to contain a + * valid path to the directory in which the content file exists + * - retro_game_info_ext::name is guaranteed to contain the + * basename of the content file, without extension + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file in lower case format + * - If retro_game_info_ext::file_in_archive is true: + * - retro_game_info_ext::full_path may be NULL + * - retro_game_info_ext::archive_path is guaranteed to + * contain a valid path to an existent compressed file + * inside which the content file is located + * - retro_game_info_ext::archive_file is guaranteed to + * contain a valid path to an existent content file + * inside the compressed file referred to by + * retro_game_info_ext::archive_path + * e.g. for a compressed file '/path/to/foo.zip' + * containing 'bar.sfc' + * > retro_game_info_ext::archive_path will be '/path/to/foo.zip' + * > retro_game_info_ext::archive_file will be 'bar.sfc' + * - retro_game_info_ext::dir is guaranteed to contain a + * valid path to the directory in which the compressed file + * (containing the content file) exists + * - retro_game_info_ext::name is guaranteed to contain + * EITHER + * 1) the basename of the compressed file (containing + * the content file), without extension + * OR + * 2) the basename of the content file inside the + * compressed file, without extension + * In either case, a core should consider 'name' to + * be the canonical name/ID of the the content file + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file inside the compressed file, + * in lower case format + * - retro_game_info_ext::data and retro_game_info_ext::size are + * guaranteed to be valid */ + bool need_fullpath; + + /* If need_fullpath is false, specifies whether the content + * data buffer available in retro_load_game() is 'persistent' + * + * If persistent_data is false and retro_load_game() is called: + * - retro_game_info::data and retro_game_info::size + * are valid only until retro_load_game() returns + * - retro_game_info_ext::data and retro_game_info_ext::size + * are valid only until retro_load_game() returns + * + * If persistent_data is true and retro_load_game() is called: + * - retro_game_info::data and retro_game_info::size + * are valid until retro_deinit() returns + * - retro_game_info_ext::data and retro_game_info_ext::size + * are valid until retro_deinit() returns */ + bool persistent_data; +}; + +/* Similar to retro_game_info, but provides extended + * information about the source content file and + * game memory buffer status. + * And array of retro_game_info_ext is returned by + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * NOTE: In the following descriptions, references to + * retro_load_game() may be replaced with + * retro_load_game_special() */ +struct retro_game_info_ext +{ + /* - If file_in_archive is false, contains a valid + * path to an existent content file (UTF-8 encoded) + * - If file_in_archive is true, may be NULL */ + const char *full_path; + + /* - If file_in_archive is false, may be NULL + * - If file_in_archive is true, contains a valid path + * to an existent compressed file inside which the + * content file is located (UTF-8 encoded) */ + const char *archive_path; + + /* - If file_in_archive is false, may be NULL + * - If file_in_archive is true, contain a valid path + * to an existent content file inside the compressed + * file referred to by archive_path (UTF-8 encoded) + * e.g. for a compressed file '/path/to/foo.zip' + * containing 'bar.sfc' + * > archive_path will be '/path/to/foo.zip' + * > archive_file will be 'bar.sfc' */ + const char *archive_file; + + /* - If file_in_archive is false, contains a valid path + * to the directory in which the content file exists + * (UTF-8 encoded) + * - If file_in_archive is true, contains a valid path + * to the directory in which the compressed file + * (containing the content file) exists (UTF-8 encoded) */ + const char *dir; + + /* Contains the canonical name/ID of the content file + * (UTF-8 encoded). Intended for use when identifying + * 'complementary' content named after the loaded file - + * i.e. companion data of a different format (a CD image + * required by a ROM), texture packs, internally handled + * save files, etc. + * - If file_in_archive is false, contains the basename + * of the content file, without extension + * - If file_in_archive is true, then string is + * implementation specific. A frontend may choose to + * set a name value of: + * EITHER + * 1) the basename of the compressed file (containing + * the content file), without extension + * OR + * 2) the basename of the content file inside the + * compressed file, without extension + * RetroArch sets the 'name' value according to (1). + * A frontend that supports routine loading of + * content from archives containing multiple unrelated + * content files may set the 'name' value according + * to (2). */ + const char *name; + + /* - If file_in_archive is false, contains the extension + * of the content file in lower case format + * - If file_in_archive is true, contains the extension + * of the content file inside the compressed file, + * in lower case format */ + const char *ext; + + /* String of implementation specific meta-data. */ + const char *meta; + + /* Memory buffer of loaded game content. Will be NULL: + * IF + * - retro_system_info::need_fullpath is true and + * retro_system_content_info_override::need_fullpath + * is unset + * OR + * - retro_system_content_info_override::need_fullpath + * is true */ + const void *data; + + /* Size of game content memory buffer, in bytes */ + size_t size; + + /* True if loaded content file is inside a compressed + * archive */ + bool file_in_archive; + + /* - If data is NULL, value is unset/ignored + * - If data is non-NULL: + * - If persistent_data is false, data and size are + * valid only until retro_load_game() returns + * - If persistent_data is true, data and size are + * are valid until retro_deinit() returns */ + bool persistent_data; +}; + struct retro_game_geometry { unsigned base_width; /* Nominal video width of game. */ @@ -2812,6 +3531,10 @@ struct retro_core_option_definition const char *default_value; }; +#ifdef __PS3__ +#undef local +#endif + struct retro_core_options_intl { /* Pointer to an array of retro_core_option_definition structs @@ -2825,6 +3548,143 @@ struct retro_core_options_intl struct retro_core_option_definition *local; }; +struct retro_core_option_v2_category +{ + /* Variable uniquely identifying the + * option category. Valid key characters + * are [a-z, A-Z, 0-9, _, -] */ + const char *key; + + /* Human-readable category description + * > Used as category menu label when + * frontend has core option category + * support */ + const char *desc; + + /* Human-readable category information + * > Used as category menu sublabel when + * frontend has core option category + * support + * > Optional (may be NULL or an empty + * string) */ + const char *info; +}; + +struct retro_core_option_v2_definition +{ + /* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. + * Valid key characters are [a-z, A-Z, 0-9, _, -] */ + const char *key; + + /* Human-readable core option description + * > Used as menu label when frontend does + * not have core option category support + * e.g. "Video > Aspect Ratio" */ + const char *desc; + + /* Human-readable core option description + * > Used as menu label when frontend has + * core option category support + * e.g. "Aspect Ratio", where associated + * retro_core_option_v2_category::desc + * is "Video" + * > If empty or NULL, the string specified by + * desc will be used as the menu label + * > Will be ignored (and may be set to NULL) + * if category_key is empty or NULL */ + const char *desc_categorized; + + /* Human-readable core option information + * > Used as menu sublabel */ + const char *info; + + /* Human-readable core option information + * > Used as menu sublabel when frontend + * has core option category support + * (e.g. may be required when info text + * references an option by name/desc, + * and the desc/desc_categorized text + * for that option differ) + * > If empty or NULL, the string specified by + * info will be used as the menu sublabel + * > Will be ignored (and may be set to NULL) + * if category_key is empty or NULL */ + const char *info_categorized; + + /* Variable specifying category (e.g. "video", + * "audio") that will be assigned to the option + * if frontend has core option category support. + * > Categorized options will be displayed in a + * subsection/submenu of the frontend core + * option interface + * > Specified string must match one of the + * retro_core_option_v2_category::key values + * in the associated retro_core_option_v2_category + * array; If no match is not found, specified + * string will be considered as NULL + * > If specified string is empty or NULL, option will + * have no category and will be shown at the top + * level of the frontend core option interface */ + const char *category_key; + + /* Array of retro_core_option_value structs, terminated by NULL */ + struct retro_core_option_value values[RETRO_NUM_CORE_OPTION_VALUES_MAX]; + + /* Default core option value. Must match one of the values + * in the retro_core_option_value array, otherwise will be + * ignored */ + const char *default_value; +}; + +struct retro_core_options_v2 +{ + /* Array of retro_core_option_v2_category structs, + * terminated by NULL + * > If NULL, all entries in definitions array + * will have no category and will be shown at + * the top level of the frontend core option + * interface + * > Will be ignored if frontend does not have + * core option category support */ + struct retro_core_option_v2_category *categories; + + /* Array of retro_core_option_v2_definition structs, + * terminated by NULL */ + struct retro_core_option_v2_definition *definitions; +}; + +struct retro_core_options_v2_intl +{ + /* Pointer to a retro_core_options_v2 struct + * > US English implementation + * > Must point to a valid struct */ + struct retro_core_options_v2 *us; + + /* Pointer to a retro_core_options_v2 struct + * - Implementation for current frontend language + * - May be NULL */ + struct retro_core_options_v2 *local; +}; + +/* Used by the frontend to monitor changes in core option + * visibility. May be called each time any core option + * value is set via the frontend. + * - On each invocation, the core must update the visibility + * of any dynamically hidden options using the + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY environment + * callback. + * - On the first invocation, returns 'true' if the visibility + * of any core option has changed since the last call of + * retro_load_game() or retro_load_game_special(). + * - On each subsequent invocation, returns 'true' if the + * visibility of any core option has changed since the last + * time the function was called. */ +typedef bool (RETRO_CALLCONV *retro_core_options_update_display_callback_t)(void); +struct retro_core_options_update_display_callback +{ + retro_core_options_update_display_callback_t callback; +}; + struct retro_game_info { const char *path; /* Path to game, UTF-8 encoded. @@ -2871,6 +3731,84 @@ struct retro_framebuffer Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */ }; +/* Used by a libretro core to override the current + * fastforwarding mode of the frontend */ +struct retro_fastforwarding_override +{ + /* Specifies the runtime speed multiplier that + * will be applied when 'fastforward' is true. + * For example, a value of 5.0 when running 60 FPS + * content will cap the fast-forward rate at 300 FPS. + * Note that the target multiplier may not be achieved + * if the host hardware has insufficient processing + * power. + * Setting a value of 0.0 (or greater than 0.0 but + * less than 1.0) will result in an uncapped + * fast-forward rate (limited only by hardware + * capacity). + * If the value is negative, it will be ignored + * (i.e. the frontend will use a runtime speed + * multiplier of its own choosing) */ + float ratio; + + /* If true, fastforwarding mode will be enabled. + * If false, fastforwarding mode will be disabled. */ + bool fastforward; + + /* If true, and if supported by the frontend, an + * on-screen notification will be displayed while + * 'fastforward' is true. + * If false, and if supported by the frontend, any + * on-screen fast-forward notifications will be + * suppressed */ + bool notification; + + /* If true, the core will have sole control over + * when fastforwarding mode is enabled/disabled; + * the frontend will not be able to change the + * state set by 'fastforward' until either + * 'inhibit_toggle' is set to false, or the core + * is unloaded */ + bool inhibit_toggle; +}; + +/* During normal operation. Rate will be equal to the core's internal FPS. */ +#define RETRO_THROTTLE_NONE 0 + +/* While paused or stepping single frames. Rate will be 0. */ +#define RETRO_THROTTLE_FRAME_STEPPING 1 + +/* During fast forwarding. + * Rate will be 0 if not specifically limited to a maximum speed. */ +#define RETRO_THROTTLE_FAST_FORWARD 2 + +/* During slow motion. Rate will be less than the core's internal FPS. */ +#define RETRO_THROTTLE_SLOW_MOTION 3 + +/* While rewinding recorded save states. Rate can vary depending on the rewind + * speed or be 0 if the frontend is not aiming for a specific rate. */ +#define RETRO_THROTTLE_REWINDING 4 + +/* While vsync is active in the video driver and the target refresh rate is + * lower than the core's internal FPS. Rate is the target refresh rate. */ +#define RETRO_THROTTLE_VSYNC 5 + +/* When the frontend does not throttle in any way. Rate will be 0. + * An example could be if no vsync or audio output is active. */ +#define RETRO_THROTTLE_UNBLOCKED 6 + +struct retro_throttle_state +{ + /* The current throttling mode. Should be one of the values above. */ + unsigned mode; + + /* How many times per second the frontend aims to call retro_run. + * Depending on the mode, it can be 0 if there is no known fixed rate. + * This won't be accurate if the total processing time of the core and + * the frontend is longer than what is available for one frame. */ + float rate; +}; + /* Callbacks */ /* Environment callback. Gives implementations a way of performing diff --git a/libretro/libretro-common/include/memmap.h b/libretro/libretro-common/include/memmap.h index ebbc307..8897877 100644 --- a/libretro/libretro-common/include/memmap.h +++ b/libretro/libretro-common/include/memmap.h @@ -26,7 +26,7 @@ #include #include -#if defined(PSP) || defined(PS2) || defined(GEKKO) || defined(VITA) || defined(_XBOX) || defined(_3DS) || defined(WIIU) || defined(SWITCH) || defined(HAVE_LIBNX) +#if defined(PSP) || defined(PS2) || defined(GEKKO) || defined(VITA) || defined(_XBOX) || defined(_3DS) || defined(WIIU) || defined(SWITCH) || defined(HAVE_LIBNX) || defined(__PS3__) || defined(__PSL1GHT__) /* No mman available */ #elif defined(_WIN32) && !defined(_XBOX) #include diff --git a/libretro/libretro-common/include/streams/memory_stream.h b/libretro/libretro-common/include/streams/memory_stream.h new file mode 100644 index 0000000..2c6f3fc --- /dev/null +++ b/libretro/libretro-common/include/streams/memory_stream.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (memory_stream.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _LIBRETRO_SDK_FILE_MEMORY_STREAM_H +#define _LIBRETRO_SDK_FILE_MEMORY_STREAM_H + +#include +#include + +#include + +RETRO_BEGIN_DECLS + +typedef struct memstream memstream_t; + +memstream_t *memstream_open(unsigned writing); + +void memstream_close(memstream_t *stream); + +uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes); + +uint64_t memstream_write(memstream_t *stream, const void *data, uint64_t bytes); + +int memstream_getc(memstream_t *stream); + +void memstream_putc(memstream_t *stream, int c); + +char *memstream_gets(memstream_t *stream, char *buffer, size_t len); + +uint64_t memstream_pos(memstream_t *stream); + +void memstream_rewind(memstream_t *stream); + +int64_t memstream_seek(memstream_t *stream, int64_t offset, int whence); + +void memstream_set_buffer(uint8_t *buffer, uint64_t size); + +uint64_t memstream_get_last_size(void); + +uint64_t memstream_get_ptr(memstream_t *stream); + +RETRO_END_DECLS + +#endif diff --git a/libretro/libretro-common/libco/aarch64.c b/libretro/libretro-common/libco/aarch64.c index b9781e3..eef31a3 100644 --- a/libretro/libretro-common/libco/aarch64.c +++ b/libretro/libretro-common/libco/aarch64.c @@ -11,7 +11,7 @@ #include #include -#ifndef IOS +#ifndef __APPLE__ #include #endif diff --git a/libretro/libretro-common/libco/emscripten_fiber.c b/libretro/libretro-common/libco/emscripten_fiber.c new file mode 100644 index 0000000..2170ad1 --- /dev/null +++ b/libretro/libretro-common/libco/emscripten_fiber.c @@ -0,0 +1,85 @@ +#define LIBCO_C +#include "libco.h" + +#define _BSD_SOURCE +#define _XOPEN_SOURCE 500 +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*thread_cb)(); + +// Todo: dynamic stack size +typedef struct { + emscripten_fiber_t context; + char *asyncify_stack; + char *c_stack; +} Fiber; + +static inline void thread_entry(void *entrypoint) { + ((thread_cb)entrypoint)(); +} + +static Fiber main_fiber; +static Fiber* running_fiber = 0; + +void init_main_fiber() { + main_fiber.asyncify_stack = (char*)malloc(16385 * sizeof(char)); + emscripten_fiber_init_from_current_context(&main_fiber.context, main_fiber.asyncify_stack, 16385); + running_fiber = &main_fiber; +} + +cothread_t co_active() { + if(!running_fiber) init_main_fiber(); + + return (cothread_t)running_fiber; +} + +cothread_t co_derive(void* memory, unsigned int heapsize, void (*coentry)(void)) { + if(!running_fiber) init_main_fiber(); + + Fiber* fiber = malloc(sizeof(Fiber)); + fiber->c_stack = (char*) memory; + fiber->asyncify_stack = (char*) malloc(heapsize * sizeof(char)); + + emscripten_fiber_init(&fiber->context, thread_entry, coentry, fiber->c_stack, heapsize, fiber->asyncify_stack, heapsize); + + return (cothread_t)fiber; +} + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { + if(!running_fiber) init_main_fiber(); + + Fiber* fiber = malloc(sizeof(Fiber)); + fiber->c_stack = (char*)malloc(heapsize * sizeof(char)); + fiber->asyncify_stack = (char*)malloc(heapsize * sizeof(char)); + + emscripten_fiber_init(&fiber->context, thread_entry, coentry, fiber->c_stack, heapsize, fiber->asyncify_stack, heapsize); + + return (cothread_t)fiber; +} + +void co_delete(cothread_t cothread) { + if(cothread) { + free(cothread); + } +} + +void co_switch(cothread_t cothread) { + Fiber* old_fiber = running_fiber; + running_fiber = (Fiber*)cothread; + + emscripten_fiber_swap(&old_fiber->context, &running_fiber->context); +} + +int co_serializable() { + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/libretro/libretro-common/libco/libco.c b/libretro/libretro-common/libco/libco.c index 36cd7da..c781977 100644 --- a/libretro/libretro-common/libco/libco.c +++ b/libretro/libretro-common/libco/libco.c @@ -9,7 +9,9 @@ void *genode_alloc_secondary_stack(unsigned long stack_size); void genode_free_secondary_stack(void *stack); #endif -#if defined _MSC_VER +#if defined(EMSCRIPTEN) + #include "emscripten_fiber.c" +#elif defined _MSC_VER #include #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) #include "fiber.c" @@ -29,6 +31,8 @@ void genode_free_secondary_stack(void *stack); #include "ppc.c" #elif defined(__aarch64__) #include "aarch64.c" + #elif defined(PS2) + #include "ps2.c" #elif defined(PSP) #include "psp1.c" #elif defined VITA diff --git a/libretro/libretro-common/libco/ppc.c b/libretro/libretro-common/libco/ppc.c index 391f721..b6f8d18 100644 --- a/libretro/libretro-common/libco/ppc.c +++ b/libretro/libretro-common/libco/ppc.c @@ -16,8 +16,8 @@ floating-point and AltiVec save/restore */ #define LIBCO_MPROTECT (__unix__ && !LIBCO_PPC_ASM) #if LIBCO_MPROTECT - #include - #include +#include +#include #endif /* State format (offsets in 32-bit words) @@ -51,6 +51,14 @@ or are directly to function */ #endif #endif +/* Whether the code should be inline asm stored in .text, or the original +array buffer */ +#ifndef LIBCO_STATIC_TEXT + #if defined(WIIU) + #define LIBCO_STATIC_TEXT 1 + #endif +#endif + #ifdef LIBCO_PPC_ASM #ifdef __cplusplus @@ -58,8 +66,227 @@ or are directly to function */ #endif /* Swap code is in ppc.S */ - void co_swap_asm( cothread_t, cothread_t ); - #define CO_SWAP_ASM( x, y ) co_swap_asm( x, y ) + void co_swap_asm(cothread_t, cothread_t); + #define CO_SWAP_ASM(x, y) co_swap_asm(x, y) + +#elif LIBCO_STATIC_TEXT + +asm( + ".globl libco_ppc_code\n" + "libco_ppc_code:\n" +#if LIBCO_PPC64 + "mfcr %r8\n" + "std %r1,40(%r4)\n" + "mflr %r9\n" + "std %r14,72(%r4)\n" + "std %r15,80(%r4)\n" + "std %r16,88(%r4)\n" + "std %r17,96(%r4)\n" + "std %r18,104(%r4)\n" + "std %r19,112(%r4)\n" + "std %r20,120(%r4)\n" + "std %r21,128(%r4)\n" + "std %r22,136(%r4)\n" + "std %r23,144(%r4)\n" + "std %r24,152(%r4)\n" + "std %r25,160(%r4)\n" + "std %r26,168(%r4)\n" + "std %r27,176(%r4)\n" + "std %r28,184(%r4)\n" + "std %r29,192(%r4)\n" + "std %r30,200(%r4)\n" + "std %r31,208(%r4)\n" + "std %r9,32(%r4)\n" + "ld %r7,32(%r3)\n" + "ld %r1,40(%r3)\n" + "bl 1f\n" + "trap\n" + "1:stw %r8,48(%r4)\n" + "lwz %r6,48(%r3)\n" + "mtctr %r7\n" + "ld %r14,72(%r3)\n" + "ld %r15,80(%r3)\n" + "ld %r16,88(%r3)\n" + "ld %r17,96(%r3)\n" + "ld %r18,104(%r3)\n" + "ld %r19,112(%r3)\n" + "ld %r20,120(%r3)\n" + "ld %r21,128(%r3)\n" + "ld %r22,136(%r3)\n" + "ld %r23,144(%r3)\n" + "ld %r24,152(%r3)\n" + "ld %r25,160(%r3)\n" + "ld %r26,168(%r3)\n" + "ld %r27,176(%r3)\n" + "ld %r28,184(%r3)\n" + "ld %r29,192(%r3)\n" + "ld %r30,200(%r3)\n" + "ld %r31,208(%r3)\n" + "mtcr %r6\n" +#else + "mfcr %r8\n" + "stw %r1,40(%r4)\n" + "mflr %r9\n" + "stw %r13,60(%r4)\n" + "stw %r14,64(%r4)\n" + "stw %r15,68(%r4)\n" + "stw %r16,72(%r4)\n" + "stw %r17,76(%r4)\n" + "stw %r18,80(%r4)\n" + "stw %r19,84(%r4)\n" + "stw %r20,88(%r4)\n" + "stw %r21,92(%r4)\n" + "stw %r22,96(%r4)\n" + "stw %r23,100(%r4)\n" + "stw %r24,104(%r4)\n" + "stw %r25,108(%r4)\n" + "stw %r26,112(%r4)\n" + "stw %r27,116(%r4)\n" + "stw %r28,120(%r4)\n" + "stw %r29,124(%r4)\n" + "stw %r30,128(%r4)\n" + "stw %r31,132(%r4)\n" + "stw %r9,32(%r4)\n" + "lwz %r7,32(%r3)\n" + "lwz %r1,40(%r3)\n" + "bl 1f\n" + "trap\n" + "1:stw %r8,48(%r4)\n" + "lwz %r6,48(%r3)\n" + "mtctr %r7\n" + "lwz %r13,60(%r3)\n" + "lwz %r14,64(%r3)\n" + "lwz %r15,68(%r3)\n" + "lwz %r16,72(%r3)\n" + "lwz %r17,76(%r3)\n" + "lwz %r18,80(%r3)\n" + "lwz %r19,84(%r3)\n" + "lwz %r20,88(%r3)\n" + "lwz %r21,92(%r3)\n" + "lwz %r22,96(%r3)\n" + "lwz %r23,100(%r3)\n" + "lwz %r24,104(%r3)\n" + "lwz %r25,108(%r3)\n" + "lwz %r26,112(%r3)\n" + "lwz %r27,116(%r3)\n" + "lwz %r28,120(%r3)\n" + "lwz %r29,124(%r3)\n" + "lwz %r30,128(%r3)\n" + "lwz %r31,132(%r3)\n" + "mtcr %r6\n" +#endif + +#ifndef LIBCO_PPC_NOFP + "stfd %f14,224(%r4)\n" + "stfd %f15,232(%r4)\n" + "stfd %f16,240(%r4)\n" + "stfd %f17,248(%r4)\n" + "stfd %f18,256(%r4)\n" + "stfd %f19,264(%r4)\n" + "stfd %f20,272(%r4)\n" + "stfd %f21,280(%r4)\n" + "stfd %f22,288(%r4)\n" + "stfd %f23,296(%r4)\n" + "stfd %f24,304(%r4)\n" + "stfd %f25,312(%r4)\n" + "stfd %f26,320(%r4)\n" + "stfd %f27,328(%r4)\n" + "stfd %f28,336(%r4)\n" + "stfd %f29,344(%r4)\n" + "stfd %f30,352(%r4)\n" + "stfd %f31,360(%r4)\n" + "lfd %f14,224(%r3)\n" + "lfd %f15,232(%r3)\n" + "lfd %f16,240(%r3)\n" + "lfd %f17,248(%r3)\n" + "lfd %f18,256(%r3)\n" + "lfd %f19,264(%r3)\n" + "lfd %f20,272(%r3)\n" + "lfd %f21,280(%r3)\n" + "lfd %f22,288(%r3)\n" + "lfd %f23,296(%r3)\n" + "lfd %f24,304(%r3)\n" + "lfd %f25,312(%r3)\n" + "lfd %f26,320(%r3)\n" + "lfd %f27,328(%r3)\n" + "lfd %f28,336(%r3)\n" + "lfd %f29,344(%r3)\n" + "lfd %f30,352(%r3)\n" + "lfd %f31,360(%r3)\n" +#endif + +#ifdef __ALTIVEC__ + "mfvrsave %r5\n" + "addi %r8,%r4,384\n" + "addi %r9,%r4,400\n" + "andi. %r0,%r5,4095\n" + "stw %r5,52(%r4)\n" + "beq- 2\n" + "stvx %v20,%r0,%r8\n" + "addi %r8,%r8,32\n" + "stvx %v21,%r0,%r9\n" + "addi %r9,%r9,32\n" + "stvx %v22,%r0,%r8\n" + "addi %r8,%r8,32\n" + "stvx %v23,%r0,%r9\n" + "addi %r9,%r9,32\n" + "stvx %v24,%r0,%r8\n" + "addi %r8,%r8,32\n" + "stvx %v25,%r0,%r9\n" + "addi %r9,%r9,32\n" + "stvx %v26,%r0,%r8\n" + "addi %r8,%r8,32\n" + "stvx %v27,%r0,%r9\n" + "addi %r9,%r9,32\n" + "stvx %v28,%r0,%r8\n" + "addi %r8,%r8,32\n" + "stvx %v29,%r0,%r9\n" + "addi %r9,%r9,32\n" + "stvx %v30,%r0,%r8\n" + "stvx %v31,%r0,%r9\n" + "2:lwz %r5,52(%r3)\n" + "addi %r8,%r3,384\n" + "addi %r9,%r3,400\n" + "andi. %r0,%r5,4095\n" + "mtvrsave %r5\n" + "beqctr \n" + "lvx %v20,%r0,%r8\n" + "addi %r8,%r8,32\n" + "lvx %v21,%r0,%r9\n" + "addi %r9,%r9,32\n" + "lvx %v22,%r0,%r8\n" + "addi %r8,%r8,32\n" + "lvx %v23,%r0,%r9\n" + "addi %r9,%r9,32\n" + "lvx %v24,%r0,%r8\n" + "addi %r8,%r8,32\n" + "lvx %v25,%r0,%r9\n" + "addi %r9,%r9,32\n" + "lvx %v26,%r0,%r8\n" + "addi %r8,%r8,32\n" + "lvx %v27,%r0,%r9\n" + "addi %r9,%r9,32\n" + "lvx %v28,%r0,%r8\n" + "addi %r8,%r8,32\n" + "lvx %v29,%r0,%r9\n" + "addi %r9,%r9,32\n" + "lvx %v30,%r0,%r8\n" + "lvx %v31,%r0,%r9\n" +#endif + "bctr" +); + +extern void libco_ppc_code(cothread_t, cothread_t); + +#if LIBCO_PPCDESC +/* Function call goes through indirect descriptor */ +#define CO_SWAP_ASM(x, y) \ + ((void (*)(cothread_t, cothread_t)) (uintptr_t) x)(x, y) +#else +/* Function call goes directly to code */ +#define CO_SWAP_ASM(x, y) \ + libco_ppc_code(x, y) +#endif #else @@ -272,122 +499,118 @@ static const uint32_t libco_ppc_code [] = { #if LIBCO_PPCDESC /* Function call goes through indirect descriptor */ - #define CO_SWAP_ASM( x, y ) \ - ((void (*)( cothread_t, cothread_t )) (uintptr_t) x)( x, y ) + #define CO_SWAP_ASM(x, y) \ + ((void (*)(cothread_t, cothread_t)) (uintptr_t) x)(x, y) #else /* Function call goes directly to code */ - #define CO_SWAP_ASM( x, y ) \ - ((void (*)( cothread_t, cothread_t )) (uintptr_t) libco_ppc_code)( x, y ) + #define CO_SWAP_ASM(x, y) \ + ((void (*)(cothread_t, cothread_t)) (uintptr_t) libco_ppc_code)(x, y) #endif #endif -static uint32_t* co_create_( unsigned size, uintptr_t entry ) +static uint32_t* co_create_( unsigned size, uintptr_t entry) { - uint32_t* t = (uint32_t*) malloc( size ); + uint32_t *t = (uint32_t*)malloc(size); - (void) entry; +#if LIBCO_PPCDESC + if (t) + { + /* Copy entry's descriptor */ + memcpy(t, (void*)entry, sizeof(void*) * 3); - #if LIBCO_PPCDESC - if ( t ) - { - /* Copy entry's descriptor */ - memcpy( t, (void*) entry, sizeof (void*) * 3 ); - - /* Set function pointer to swap routine */ - #ifdef LIBCO_PPC_ASM - *(const void**) t = *(void**) &co_swap_asm; - #else - *(const void**) t = libco_ppc_code; - #endif - } + /* Set function pointer to swap routine */ +#ifdef LIBCO_PPC_ASM + *(const void**) t = *(void**) &co_swap_asm; +#else + *(const void**) t = libco_ppc_code; +#endif + } #endif return t; } -cothread_t co_create( unsigned int size, void (*entry_)( void ) ) +cothread_t co_create(unsigned int size, void (*entry_)(void)) { uintptr_t entry = (uintptr_t) entry_; - uint32_t* t = NULL; + uint32_t *t = NULL; /* Be sure main thread was successfully allocated */ - if ( co_active() ) + if (co_active()) { size += state_size + above_stack + stack_align; - t = co_create_( size, entry ); + t = co_create_(size, entry); } - if ( t ) - { - uintptr_t sp; - int shift; - - /* Save current registers into new thread, so that any special ones will - have proper values when thread is begun */ - CO_SWAP_ASM( t, t ); - - #if LIBCO_PPCDESC - /* Get real address */ - entry = (uintptr_t) *(void**) entry; - #endif - - /* Put stack near end of block, and align */ - sp = (uintptr_t) t + size - above_stack; - sp -= sp % stack_align; - - /* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we - save and restore them as 64 bits, regardless of the size the ABI - uses. So, we manually write pointers at the proper size. We always - save and restore at the same address, and since PPC is big-endian, - we must put the low byte first on PPC32. */ - - /* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts - and don't have to care how many bits uintptr_t is. */ - #if LIBCO_PPC64 - shift = 16; - #else - shift = 0; - #endif - - /* Set up so entry will be called on next swap */ - t [8] = (uint32_t) (entry >> shift >> shift); - t [9] = (uint32_t) entry; - - t [10] = (uint32_t) (sp >> shift >> shift); - t [11] = (uint32_t) sp; - } + if (t) + { + uintptr_t sp; +#if LIBCO_PPC64 + int shift = 16; +#else + int shift = 0; +#endif + /* Save current registers into new thread, so that any special ones will + have proper values when thread is begun */ + CO_SWAP_ASM(t, t); + +#if LIBCO_PPCDESC + /* Get real address */ + entry = (uintptr_t) *(void**)entry; +#endif + + /* Put stack near end of block, and align */ + sp = (uintptr_t) t + size - above_stack; + sp -= sp % stack_align; + + /* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we + save and restore them as 64 bits, regardless of the size the ABI + uses. So, we manually write pointers at the proper size. We always + save and restore at the same address, and since PPC is big-endian, + we must put the low byte first on PPC32. */ + + /* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts + and don't have to care how many bits uintptr_t is. */ + + /* Set up so entry will be called on next swap */ + t [8] = (uint32_t) (entry >> shift >> shift); + t [9] = (uint32_t) entry; + + t [10] = (uint32_t) (sp >> shift >> shift); + t [11] = (uint32_t) sp; + } return t; } -void co_delete( cothread_t t ) +void co_delete(cothread_t t) { free(t); } -static void co_init_( void ) +static void co_init_(void) { -#if LIBCO_MPROTECT +#if LIBCO_MPROTECT && !LIBCO_STATIC_TEXT /* TODO: pre- and post-pad PPC code so that this doesn't make other data executable and writable */ - long page_size = sysconf( _SC_PAGESIZE ); - if ( page_size > 0 ) + long page_size = sysconf(_SC_PAGESIZE); + if (page_size > 0) { uintptr_t align = page_size; uintptr_t begin = (uintptr_t) libco_ppc_code; uintptr_t end = begin + sizeof libco_ppc_code; /* Align beginning and end */ - end += align - 1; - end -= end % align; - begin -= begin % align; + end += align - 1; + end -= end % align; + begin -= begin % align; - mprotect( (void*) begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC ); + mprotect((void*)begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC); } #endif - co_active_handle = co_create_( state_size, (uintptr_t) &co_switch ); + co_active_handle = co_create_(state_size, (uintptr_t) &co_switch); } cothread_t co_active(void) @@ -400,8 +623,7 @@ cothread_t co_active(void) void co_switch(cothread_t t) { - cothread_t old = co_active_handle; + cothread_t old = co_active_handle; co_active_handle = t; - - CO_SWAP_ASM( t, old ); + CO_SWAP_ASM(t, old); } diff --git a/libretro/libretro-common/libco/ps2.c b/libretro/libretro-common/libco/ps2.c new file mode 100644 index 0000000..03409cb --- /dev/null +++ b/libretro/libretro-common/libco/ps2.c @@ -0,0 +1,58 @@ +#define LIBCO_C +#include "libco.h" + +#include +#include +#include + +/* Since cothread_t is a void pointer it must contain an address. We can't return a reference to a local variable + * because it would go out of scope, so we create a static variable instead so we can return a reference to it. + */ +static int32_t active_thread_id = -1; +extern void *_gp; + +cothread_t co_active(void) +{ + active_thread_id = GetThreadId(); + return &active_thread_id; +} + +cothread_t co_create(unsigned int size, void (*entrypoint)(void)) +{ + /* Similar scenario as with active_thread_id except there will only be one active_thread_id while there could be many + * new threads each with their own handle, so we create them on the heap instead and delete them manually when they're + * no longer needed in co_delete(). + */ + ee_thread_t thread; + cothread_t handle = malloc(sizeof(cothread_t)); + void *threadStack = (void *)malloc(size); + if (!threadStack) + return NULL; + + thread.stack_size = size; + thread.gp_reg = &_gp; + thread.func = (void *)entrypoint; + thread.stack = threadStack; + thread.option = 0; + thread.initial_priority = 1; + + int32_t new_thread_id = CreateThread(&thread); + + StartThread(new_thread_id, NULL); + *(uint32_t *)handle = new_thread_id; + return handle; +} + +void co_delete(cothread_t handle) +{ + TerminateThread(*(uint32_t *)handle); + DeleteThread(*(uint32_t *)handle); + free(handle); +} + +void co_switch(cothread_t handle) +{ + WakeupThread(*(uint32_t *)handle); + /* Sleep the currently active thread so the new thread can start */ + SleepThread(); +} diff --git a/libretro/libretro-common/streams/memory_stream.c b/libretro/libretro-common/streams/memory_stream.c new file mode 100644 index 0000000..2aa1c80 --- /dev/null +++ b/libretro/libretro-common/streams/memory_stream.c @@ -0,0 +1,191 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (memory_stream.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include + +/* TODO/FIXME - static globals */ +static uint8_t* g_buffer = NULL; +static uint64_t g_size = 0; +static uint64_t last_file_size = 0; + +struct memstream +{ + uint64_t size; + uint64_t ptr; + uint64_t max_ptr; + uint8_t *buf; + unsigned writing; +}; + +void memstream_set_buffer(uint8_t *buffer, uint64_t size) +{ + g_buffer = buffer; + g_size = size; +} + +uint64_t memstream_get_last_size(void) +{ + return last_file_size; +} + +memstream_t *memstream_open(unsigned writing) +{ + memstream_t *stream; + if (!g_buffer || !g_size) + return NULL; + + stream = (memstream_t*)malloc(sizeof(*stream)); + + if (!stream) + return NULL; + + stream->buf = g_buffer; + stream->size = g_size; + stream->ptr = 0; + stream->max_ptr = 0; + stream->writing = writing; + + g_buffer = NULL; + g_size = 0; + + return stream; +} + +void memstream_close(memstream_t *stream) +{ + if (!stream) + return; + + last_file_size = stream->writing ? stream->max_ptr : stream->size; + free(stream); +} + +uint64_t memstream_get_ptr(memstream_t *stream) +{ + return stream->ptr; +} + +uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes) +{ + uint64_t avail = 0; + + if (!stream) + return 0; + + avail = stream->size - stream->ptr; + if (bytes > avail) + bytes = avail; + + memcpy(data, stream->buf + stream->ptr, (size_t)bytes); + stream->ptr += bytes; + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; + return bytes; +} + +uint64_t memstream_write(memstream_t *stream, + const void *data, uint64_t bytes) +{ + uint64_t avail = 0; + + if (!stream) + return 0; + + avail = stream->size - stream->ptr; + if (bytes > avail) + bytes = avail; + + memcpy(stream->buf + stream->ptr, data, (size_t)bytes); + stream->ptr += bytes; + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; + return bytes; +} + +int64_t memstream_seek(memstream_t *stream, int64_t offset, int whence) +{ + uint64_t ptr; + + switch (whence) + { + case SEEK_SET: + ptr = offset; + break; + case SEEK_CUR: + ptr = stream->ptr + offset; + break; + case SEEK_END: + ptr = (stream->writing ? stream->max_ptr : stream->size) + offset; + break; + default: + return -1; + } + + if (ptr <= stream->size) + { + stream->ptr = ptr; + return 0; + } + + return -1; +} + +void memstream_rewind(memstream_t *stream) +{ + memstream_seek(stream, 0L, SEEK_SET); +} + +uint64_t memstream_pos(memstream_t *stream) +{ + return stream->ptr; +} + +char *memstream_gets(memstream_t *stream, char *buffer, size_t len) +{ + return NULL; +} + +int memstream_getc(memstream_t *stream) +{ + int ret = 0; + if (stream->ptr >= stream->size) + return EOF; + ret = stream->buf[stream->ptr++]; + + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; + + return ret; +} + +void memstream_putc(memstream_t *stream, int c) +{ + if (stream->ptr < stream->size) + stream->buf[stream->ptr++] = c; + + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; +} diff --git a/libretro/libretro-common/vfs/vfs_implementation.c b/libretro/libretro-common/vfs/vfs_implementation.c index 034d8f3..46259e6 100644 --- a/libretro/libretro-common/vfs/vfs_implementation.c +++ b/libretro/libretro-common/vfs/vfs_implementation.c @@ -909,6 +909,19 @@ int retro_vfs_stat_impl(const char *path, int32_t *size) orbisDclose(dir_ret); is_character_special = S_ISCHR(buf.st_mode); +#elif defined(__PSL1GHT__) || defined(__PS3__) + /* Lowlevel Lv2 */ + sysFSStat buf; + + if (!path || !*path) + return 0; + if (sysFsStat(path, &buf) < 0) + return 0; + + if (size) + *size = (int32_t)buf.st_size; + + is_dir = ((buf.st_mode & S_IFMT) == S_IFDIR); #elif defined(_WIN32) /* Windows */ DWORD file_info; @@ -1081,6 +1094,10 @@ struct libretro_vfs_implementation_dir #elif defined(VITA) || defined(PSP) SceUID directory; SceIoDirent entry; +#elif defined(__PSL1GHT__) || defined(__PS3__) + int error; + int directory; + sysFSDirent entry; #elif defined(ORBIS) int directory; struct dirent entry; @@ -1096,6 +1113,8 @@ static bool dirent_check_error(libretro_vfs_implementation_dir *rdir) return (rdir->directory == INVALID_HANDLE_VALUE); #elif defined(VITA) || defined(PSP) || defined(ORBIS) return (rdir->directory < 0); +#elif defined(__PSL1GHT__) || defined(__PS3__) + return (rdir->error != FS_SUCCEEDED); #else return !(rdir->directory); #endif @@ -1159,6 +1178,8 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl( #elif defined(_3DS) rdir->directory = !string_is_empty(name) ? opendir(name) : NULL; rdir->entry = NULL; +#elif defined(__PSL1GHT__) || defined(__PS3__) + rdir->error = sysFsOpendir(name, &rdir->directory); #elif defined(ORBIS) rdir->directory = orbisDopen(name); #else @@ -1194,6 +1215,10 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) return (rdir->directory != INVALID_HANDLE_VALUE); #elif defined(VITA) || defined(PSP) return (sceIoDread(rdir->directory, &rdir->entry) > 0); +#elif defined(__PSL1GHT__) || defined(__PS3__) + uint64_t nread; + rdir->error = sysFsReaddir(rdir->directory, &rdir->entry, &nread); + return (nread != 0); #elif defined(ORBIS) return (orbisDread(rdir->directory, &rdir->entry) > 0); #else @@ -1214,7 +1239,7 @@ const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *rdir if (name) free(name); return (char*)rdir->entry.cFileName; -#elif defined(VITA) || defined(PSP) || defined(ORBIS) +#elif defined(VITA) || defined(PSP) || defined(ORBIS) || defined(__PSL1GHT__) || defined(__PS3__) return rdir->entry.d_name; #else if (!rdir || !rdir->entry) @@ -1235,6 +1260,9 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir) #elif defined(VITA) return SCE_S_ISDIR(entry->d_stat.st_mode); #endif +#elif defined(__PSL1GHT__) || defined(__PS3__) + sysFSDirent* entry = (sysFSDirent*)&rdir->entry; + return (entry->d_type == FS_TYPE_DIR); #elif defined(ORBIS) const struct dirent *entry = &rdir->entry; if (entry->d_type == DT_DIR) @@ -1271,6 +1299,8 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) FindClose(rdir->directory); #elif defined(VITA) || defined(PSP) sceIoDclose(rdir->directory); +#elif defined(__PSL1GHT__) || defined(__PS3__) + rdir->error = sysFsClosedir(rdir->directory); #elif defined(ORBIS) orbisDclose(rdir->directory); #else diff --git a/libretro/libretro-core.c b/libretro/libretro-core.c index 2f55a3f..9a5c75c 100644 --- a/libretro/libretro-core.c +++ b/libretro/libretro-core.c @@ -1,51 +1,170 @@ #include +#include #include "libretro.h" +#include "libretro_core_options.h" #include "libretro-core.h" +#include "retro_strings.h" + +// DISK CONTROL +#include "retro_disk_control.h" +static dc_storage* dc; + +#include "antic.h" #include "atari.h" +#include "afile.h" #include "devices.h" #include "esc.h" #include "memory.h" #include "cassette.h" #include "artifact.h" +#include "statesav.h" + +#include "carts_hash.h" +#include "crc32.h" +#include "colours.h" cothread_t mainThread; cothread_t emuThread; -static void fallback_log(enum retro_log_level level, const char *fmt, ...); - +static void fallback_log(enum retro_log_level level, const char* fmt, ...); retro_log_printf_t log_cb = fallback_log; int CROP_WIDTH; int CROP_HEIGHT; int VIRTUAL_WIDTH; -int retrow=400; -int retroh=300; +int retrow = 400; +int retroh = 300; + +#define ATARI_JOYPAD_BUTTONS 16 +#define ATARI_NUMBER_JOYSTICKS 4 #define RETRO_DEVICE_ATARI_KEYBOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_KEYBOARD, 0) #define RETRO_DEVICE_ATARI_JOYSTICK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1) - -unsigned atari_devices[ 4 ]; - -int keyboard_type=0; -int autorun5200=0; -int a5200_joyhack=0; - -int RETROJOY=0,RETROPT0=0,RETROSTATUS=0,RETRODRVTYPE=0; -int retrojoy_init=0,retro_ui_finalized=0; -int retro_sound_finalized=0; - -float retro_fps=49.8607597; +#define RETRO_DEVICE_ATARI_5200_JOYSTICK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) + +/* Atari 800 Joysticks 1 thru 4 */ +#define RETRO_DESCRIPTOR_BLOCK(_user) \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Fire 1" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Fire 2" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Space/Fire 3" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Return" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Option" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Atari800 Menu" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Esc" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Help" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Virtual Keyboard" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" } + +static struct retro_input_descriptor inputDescriptors_a800[] = +{ + RETRO_DESCRIPTOR_BLOCK(0), + RETRO_DESCRIPTOR_BLOCK(1), + RETRO_DESCRIPTOR_BLOCK(2), + RETRO_DESCRIPTOR_BLOCK(3), + {0}, +}; +#undef RETRO_DESCRIPTOR_BLOCK + +/* Atari 5200 Joysticks 1 thru 4 */ +#define RETRO_DESCRIPTOR_BLOCK(_user) \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Joystick Up (Digital)" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Joystick Down (Digital)" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Joystick Left (Digital)" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Joystick Right (Digital)" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Fire 1" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Fire 2" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Numpad #" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Numpad *" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Pause" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "Numpad 0" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "Numpad 1" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "Numpad 2" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "Numpad 3" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Numpad 7" }, \ + { _user, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Virtual Keyboard" } + +static struct retro_input_descriptor inputDescriptors_a5200[] = +{ + RETRO_DESCRIPTOR_BLOCK(0), + RETRO_DESCRIPTOR_BLOCK(1), + RETRO_DESCRIPTOR_BLOCK(2), + RETRO_DESCRIPTOR_BLOCK(3), + {0}, +}; +#undef RETRO_DESCRIPTOR_BLOCK + +/* Dynamic inputdescripter */ +static struct retro_input_descriptor inputDescriptors_dyna[(ATARI_JOYPAD_BUTTONS * ATARI_NUMBER_JOYSTICKS) + 1]; + +unsigned atari_devices[4]; + +#define A800_SAVE_STATE_SIZE 1300000 + +// libretro-Atari800 core options variables +int keyboard_type = 0; +int autorunCartridge = NO_CART; +int atari_joyhack = 0; +int paddle_mode = 0; +int paddle_speed = 3; +int atarixegs_keyboard_detached = 0; +int atari800_f10 = 0; + +int color_first_time = TRUE; +double color_hue = 0.0; +double color_saturation = 0.0; +double color_contrast = 0.0; +double color_brightness = 0.0; +double color_gamma = 2.35; +double color_delay = 0.0; +#define COLOR_VARIABLE(name) \ + var.key = "color_" #name; \ + var.value = NULL; \ + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { \ + float var_value; \ + var_value = atof(var.value); \ + if (var_value != color_##name) { \ + colors_changed = TRUE; \ + color_##name = var_value; \ + } \ + } /* END OF COLOR_VARIABLE */ + +extern int INPUT_joy_5200_center; +extern int INPUT_joy_5200_min; +extern int INPUT_joy_5200_max; +extern int INPUT_digital_5200_min; +extern int INPUT_digital_5200_center; +extern int INPUT_digital_5200_max; + +int pot_analog_deadzone = (int)(0.15f * (float)LIBRETRO_ANALOG_RANGE); + +int RETROJOY = 0, RETROPT0 = 0, RETROSTATUS = 0, RETRODRVTYPE = 0; +int retrojoy_init = 0, retro_ui_finalized = 0; +int retro_sound_finalized = 0; + +int libretro_runloop_active = 0; + +char old_Atari800_machine_type[100]; + +float retro_fps = 49.8607597; long long retro_frame_counter; extern int ToggleTV; extern int CURRENT_TV; -extern int SHIFTON,pauseg,SND ,snd_sampler_pal; -extern short signed int SNDBUF[1024*2]; -extern char RPATH[512]; -extern char RETRO_DIR[512]; -int cap32_statusbar=0; +extern int SHIFTON, pauseg, SND; +extern UBYTE SNDBUF[]; + +char RPATH[512]; +char RETRO_DIR[512]; +int cap32_statusbar = 0; #include "cmdline.c" @@ -56,10 +175,11 @@ extern void Emu_init(); extern void Emu_uninit(); extern void input_gui(void); -const char *retro_save_directory; -const char *retro_system_directory; -const char *retro_content_directory; -char retro_system_data_directory[512];; +const char* retro_save_directory; +const char* retro_system_directory; +const char* retro_content_directory; +char retro_system_data_directory[512]; +int legacy_configuration_file; static retro_video_refresh_t video_cb; static retro_audio_sample_t audio_cb; @@ -68,732 +188,1331 @@ static retro_environment_t environ_cb; bool libretro_supports_bitmasks = false; +static void fallback_log(enum retro_log_level level, const char* fmt, ...) +{ + va_list va; + + (void)level; + + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); +} + +int HandleExtension(char* path, char* ext) +{ + int len = strlen(path); + + if (len >= 4 && + path[len - 4] == '.' && + path[len - 3] == ext[0] && + path[len - 2] == ext[1] && + path[len - 1] == ext[2]) + { + return 1; + } + + return 0; +} + +//***************************************************************************** +//***************************************************************************** +// Disk control + +extern void SIO_Dismount(int diskno); +extern int SIO_Mount(int diskno, const char* filename, int b_open_readonly); +extern void CART_Remove(void); +extern int CASSETTE_Insert(const char* filename); +extern void CASSETTE_Remove(void); +extern void CASSETTE_Seek(unsigned int position); + +//extern int SIO_RotateDisks(void); + +void retro_message(const char* text, unsigned int frames, int alt) { + struct retro_message msg; + struct retro_message_ext msg_ext; + + char msg_local[256]; + unsigned int message_interface_version; + + snprintf(msg_local, sizeof(msg_local), "Atari800: %s", text); + msg.msg = msg_local; + msg.frames = frames; + + msg_ext.msg = msg_local; + msg_ext.duration = frames; + msg_ext.priority = 3; + msg_ext.level = RETRO_LOG_INFO; + msg_ext.target = RETRO_MESSAGE_TYPE_NOTIFICATION_ALT; + msg_ext.type = -1 ; + + if (environ_cb(RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION, &message_interface_version) && (message_interface_version >= 1)) + { + if (alt) + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, (void*)&msg_ext); + else + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, (void*)&msg); + } + else + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg); +} + +static int get_image_unit() +{ + int unit = dc->unit; + if (dc->index < dc->count) + { + if (dc_get_image_type(dc->files[dc->index]) == DC_IMAGE_TYPE_TAPE) + dc->unit = DC_IMAGE_TYPE_TAPE; + else if (dc_get_image_type(dc->files[dc->index]) == DC_IMAGE_TYPE_FLOPPY) + dc->unit = DC_IMAGE_TYPE_FLOPPY; + else + dc->unit = DC_IMAGE_TYPE_FLOPPY; + } + else + unit = DC_IMAGE_TYPE_FLOPPY; + + return unit; +} + +static void retro_insert_image() +{ + if (dc->unit == DC_IMAGE_TYPE_TAPE) + { + int error = CASSETTE_Insert(dc->files[dc->index]); + if (!error) + { + CASSETTE_Seek(0); + log_cb(RETRO_LOG_INFO,"[retro_insert_image] Tape (%d) inserted: %s\n", dc->index + 1, dc->names[dc->index]); + } + else + { + log_cb(RETRO_LOG_INFO,"[retro_insert_image] Tape Error (%d): %s\n", error, dc->files[dc->index]); + } + } + else if (dc->unit == DC_IMAGE_TYPE_FLOPPY) + { + int error = SIO_Mount(1, dc->files[dc->index], 0); + if (error) + { + log_cb(RETRO_LOG_INFO,"[retro_insert_image] Disk (%d) Error : %s\n", dc->index + 1, dc->files[dc->index]); + return; + } + log_cb(RETRO_LOG_INFO,"[retro_insert_image] Disk (%d) inserted into drive 1 : %s\n", dc->index + 1, dc->files[dc->index]); + } + else + { + log_cb(RETRO_LOG_INFO,"[retro_insert_image] unsupported image-type : %u\n", dc->unit); + } +} + +static bool retro_set_eject_state(bool ejected) +{ + if (dc) + { + int unit = get_image_unit(); + + if (dc->eject_state == ejected) + return true; + + if (ejected && dc->index <= dc->count && dc->files[dc->index] != NULL) + { + if (unit == DC_IMAGE_TYPE_TAPE) + { + CASSETTE_Remove(); + log_cb(RETRO_LOG_INFO,"[retro_set_eject_state] Tape (%d/%d) ejected %s\n", dc->index + 1, dc->count, dc->names[dc->index]); + } + else + { + SIO_Dismount(1); + log_cb(RETRO_LOG_INFO,"[retro_set_eject_state] Disk (%d/%d) ejected: %s\n", dc->index + 1, dc->count, dc->names[dc->index]); + } + } + else if (!ejected && dc->index < dc->count && dc->files[dc->index] != NULL) + { + retro_insert_image(); + } + + dc->eject_state = ejected; + return true; + } + + return false; +} + +/* Gets current eject state. The initial state is 'not ejected'. */ +static bool retro_get_eject_state(void) +{ + if (dc) + return dc->eject_state; + + return true; +} + +static unsigned retro_get_image_index(void) +{ + if (dc) + return dc->index; + + return 0; +} + +/* Sets image index. Can only be called when disk is ejected. + * The implementation supports setting "no disk" by using an + * index >= get_num_images(). + */ +static bool retro_set_image_index(unsigned index) +{ + // Insert image + if (dc) + { + if (index == dc->index) + return true; + + if (dc->replace) + { + dc->replace = false; + index = 0; + } + + if (index < dc->count && dc->files[index]) + { + dc->index = index; + int unit = get_image_unit(); + log_cb(RETRO_LOG_INFO,"[retro_set_image_index] Unit (%d) image (%d/%d) inserted: %s\n", dc->index + 1, unit, dc->count, dc->files[dc->index]); + return true; + } + } + + return false; +} + +static unsigned retro_get_num_images(void) +{ + if (dc) + return dc->count; + + return 0; +} + +/* Adds a new valid index (get_num_images()) to the internal disk list. + * This will increment subsequent return values from get_num_images() by 1. + * This image index cannot be used until a disk image has been set + * with replace_image_index. */ +static bool retro_add_image_index(void) +{ + if (dc) + { + if (dc->count <= DC_MAX_SIZE) + { + dc->files[dc->count] = NULL; + dc->names[dc->count] = NULL; + dc->types[dc->count] = DC_IMAGE_TYPE_NONE; + dc->count++; + return true; + } + } + + return false; +} -static void fallback_log(enum retro_log_level level, const char *fmt, ...) +static bool retro_replace_image_index(unsigned index, const struct retro_game_info* info) { - va_list va; + if (dc) + { + if (info != NULL) + { + int error = dc_replace_file(dc, index, info->path); + + if ( error == 2) + retro_message("Duplicate Disk selected. Use Index", 6000, 1); + } + else + { + dc_remove_file(dc, index); + } + + return true; + } + + return false; +} - (void)level; +static bool retro_get_image_path(unsigned index, char* path, size_t len) +{ + if (len < 1) + return false; + + if (dc) + { + if (index < dc->count) + { + if (!string_is_empty(dc->files[index])) + { + strncpy(path, dc->files[index], len); + return true; + } + } + } + + return false; +} - va_start(va, fmt); - vfprintf(stderr, fmt, va); - va_end(va); +static bool retro_get_image_label(unsigned index, char* label, size_t len) +{ + if (len < 1) + return false; + + if (dc) + { + if (index < dc->count) + { + if (!string_is_empty(dc->names[index])) + { + strncpy(label, dc->names[index], len); + return true; + } + } + } + + return false; } +static struct retro_disk_control_callback disk_interface = { + retro_set_eject_state, + retro_get_eject_state, + retro_get_image_index, + retro_set_image_index, + retro_get_num_images, + retro_replace_image_index, + retro_add_image_index, +}; + +static struct retro_disk_control_ext_callback disk_interface_ext = { + retro_set_eject_state, + retro_get_eject_state, + retro_get_image_index, + retro_set_image_index, + retro_get_num_images, + retro_replace_image_index, + retro_add_image_index, + NULL, /* disk_set_initial_image, not even sure if I want to use this */ + retro_get_image_path, + retro_get_image_label, +}; + void retro_set_environment(retro_environment_t cb) { - environ_cb = cb; - - static const struct retro_controller_description p1_controllers[] = { - { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, - { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, - }; - static const struct retro_controller_description p2_controllers[] = { - { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, - { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, - }; - static const struct retro_controller_description p3_controllers[] = { - { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, - { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, - }; - static const struct retro_controller_description p4_controllers[] = { - { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, - { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, - }; - - static const struct retro_controller_info ports[] = { - { p1_controllers, 2 }, // port 1 - { p2_controllers, 2 }, // port 2 - { p3_controllers, 2 }, // port 3 - { p4_controllers, 2 }, // port 4 - { NULL, 0 } - }; - - cb( RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports ); - - struct retro_variable variables[] = { - { - "atari800_system", - "Atari System; 400/800 (OS B)|800XL (64K)|130XE (128K)|5200", - }, - { - "atari800_ntscpal", - "Video Standard; NTSC|PAL", - }, - { - "atari800_internalbasic", - "Internal BASIC (hold OPTION on boot); disabled|enabled", - }, - { - "atari800_sioaccel", - "SIO Acceleration; disabled|enabled", - }, - { - "atari800_cassboot", - "Boot from Cassette; disabled|enabled", - }, - { - "atari800_artifacting", - "Hi-Res Artifacting; disabled|enabled", - }, - { - "atari800_opt1", - "Autodetect A5200 CartType; disabled|enabled" , - }, - { - "atari800_opt2", - "Joy hack A5200 for robotron; disabled|enabled" , - }, - { - "atari800_resolution", - "Internal resolution; 336x240|320x240|384x240|384x272|384x288|400x300", - }, - { - "atari800_keyboard", - "Retroarch Keyboard type; poll|callback", - }, - - { NULL, NULL }, - }; - - cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables); + bool option_cats_supported; + + environ_cb = cb; + + static const struct retro_controller_description p1_controllers[] = { + { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, + { "ATARI 5200 Joystick", RETRO_DEVICE_ATARI_5200_JOYSTICK }, + { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, + }; + static const struct retro_controller_description p2_controllers[] = { + { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, + { "ATARI 5200 Joystick", RETRO_DEVICE_ATARI_5200_JOYSTICK }, + { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, + }; + static const struct retro_controller_description p3_controllers[] = { + { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, + { "ATARI 5200 Joystick", RETRO_DEVICE_ATARI_5200_JOYSTICK }, + { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, + }; + static const struct retro_controller_description p4_controllers[] = { + { "ATARI Joystick", RETRO_DEVICE_ATARI_JOYSTICK }, + { "ATARI 5200 Joystick", RETRO_DEVICE_ATARI_5200_JOYSTICK }, + { "ATARI Keyboard", RETRO_DEVICE_ATARI_KEYBOARD }, + }; + + static const struct retro_controller_info ports[] = { + { p1_controllers, 3 }, // port 1 + { p2_controllers, 3 }, // port 2 + { p3_controllers, 3 }, // port 3 + { p4_controllers, 3 }, // port 4 + { NULL, 0 } + }; + + /* Initialise core options */ + libretro_set_core_options(environ_cb, &option_cats_supported); + + cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports); + + bool no_content = true; + cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content); } static void update_variables(void) { - - struct retro_variable var; - - var.key = "atari800_opt1"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - autorun5200 = 1; - } - - var.key = "atari800_opt2"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - a5200_joyhack = 1; - } - - var.key = "atari800_resolution"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - char *pch; - char str[100]; - snprintf(str, sizeof(str), "%s", var.value); - - pch = strtok(str, "x"); - if (pch) - retrow = strtoul(pch, NULL, 0); - pch = strtok(NULL, "x"); - if (pch) - retroh = strtoul(pch, NULL, 0); - - fprintf(stderr, "[libretro-atari800]: Got size: %u x %u.\n", retrow, retroh); - - CROP_WIDTH =retrow; - CROP_HEIGHT= (retroh-80); - VIRTUAL_WIDTH = retrow; - texture_init(); - //reset_screen(); - } - - var.key = "atari800_system"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "400/800 (OS B)") == 0) - { - Atari800_machine_type = Atari800_MACHINE_800; - MEMORY_ram_size = 48; - Atari800_builtin_basic = FALSE; - Atari800_keyboard_leds = FALSE; - Atari800_f_keys = FALSE; - Atari800_jumper = FALSE; - Atari800_builtin_game = FALSE; - Atari800_keyboard_detached = FALSE; - Atari800_InitialiseMachine(); - } - else if (strcmp(var.value, "800XL (64K)") == 0) - { - Atari800_machine_type = Atari800_MACHINE_XLXE; - MEMORY_ram_size = 64; - Atari800_builtin_basic = TRUE; - Atari800_keyboard_leds = FALSE; - Atari800_f_keys = FALSE; - Atari800_jumper = FALSE; - Atari800_builtin_game = FALSE; - Atari800_keyboard_detached = FALSE; - Atari800_InitialiseMachine(); - } - else if (strcmp(var.value, "130XE (128K)") == 0) - { - Atari800_machine_type = Atari800_MACHINE_XLXE; - MEMORY_ram_size = 128; - Atari800_builtin_basic = TRUE; - Atari800_keyboard_leds = FALSE; - Atari800_f_keys = FALSE; - Atari800_jumper = FALSE; - Atari800_builtin_game = FALSE; - Atari800_keyboard_detached = FALSE; - Atari800_InitialiseMachine(); - } - else if (strcmp(var.value, "5200") == 0) - { - Atari800_machine_type = Atari800_MACHINE_5200; - MEMORY_ram_size = 16; - Atari800_builtin_basic = FALSE; - Atari800_keyboard_leds = FALSE; - Atari800_f_keys = FALSE; - Atari800_jumper = FALSE; - Atari800_builtin_game = FALSE; - Atari800_keyboard_detached = FALSE; - Atari800_InitialiseMachine(); - } - } - - var.key = "atari800_ntscpal"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "NTSC") == 0) - { - Atari800_tv_mode = Atari800_TV_NTSC; - } - else if (strcmp(var.value, "PAL") == 0) - { - Atari800_tv_mode = Atari800_TV_PAL; - } - } - - var.key = "atari800_internalbasic"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - { - Atari800_disable_basic = FALSE; - Atari800_InitialiseMachine(); - } - else if (strcmp(var.value, "disabled") == 0) - { - Atari800_disable_basic = TRUE; - Atari800_InitialiseMachine(); - } - } - - var.key = "atari800_sioaccel"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - { - ESC_enable_sio_patch = Devices_enable_h_patch = Devices_enable_p_patch = Devices_enable_r_patch = TRUE; - Atari800_InitialiseMachine(); - } - else if (strcmp(var.value, "disabled") == 0) - { - ESC_enable_sio_patch = Devices_enable_h_patch = Devices_enable_p_patch = Devices_enable_r_patch = FALSE; - Atari800_InitialiseMachine(); - } - } - - var.key = "atari800_cassboot"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - { - CASSETTE_hold_start=1; - Atari800_InitialiseMachine(); - } - else if (strcmp(var.value, "disabled") == 0) - { - CASSETTE_hold_start=0; - Atari800_InitialiseMachine(); - } - } - - var.key = "atari800_artifacting"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - { - if (Atari800_tv_mode == Atari800_TV_NTSC) - { - ARTIFACT_Set(ARTIFACT_NTSC_OLD); - ARTIFACT_SetTVMode(Atari800_TV_NTSC); - } - else if (Atari800_tv_mode == Atari800_TV_PAL) - { - ARTIFACT_Set(ARTIFACT_NONE); // PAL Blending has been flipped off in config for now. - ARTIFACT_SetTVMode(Atari800_TV_PAL); - } - } - else if (strcmp(var.value, "disabled") == 0) - { - if (Atari800_tv_mode == Atari800_TV_NTSC) - { - ARTIFACT_Set(ARTIFACT_NONE); - ARTIFACT_SetTVMode(Atari800_TV_NTSC); - } - else if (Atari800_tv_mode == Atari800_TV_PAL) - { - ARTIFACT_Set(ARTIFACT_NONE); - ARTIFACT_SetTVMode(Atari800_TV_PAL); - } - } - } - - var.key = "atari800_keyboard"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "poll") == 0) - { - keyboard_type=0; - } - else if (strcmp(var.value, "callback") == 0) - { - keyboard_type=1; - } - } + struct retro_variable var; + + /* Moved here for better consistency and when system options that require EMU reset to occur */ + if (strcmp(RPATH, "") == 0) // Start core with no content + autorunCartridge = NO_CART; + /* Most complex case - .bin (common) and .rom (rare) can be used for both Atari 5200 console and Atari 8bit computers */ + else if (HandleExtension((char*)RPATH, "bin") || HandleExtension((char*)RPATH, "BIN") + || HandleExtension((char*)RPATH, "rom") || HandleExtension((char*)RPATH, "ROM")) { + autorunCartridge = A800_CART; // default Atari 8bit, as most/all Atari 5200 games should be in atari5200_hash.h + ULONG crc; + FILE *fp; + fp = fopen((char*)RPATH, "rb"); + if (fp != NULL) { + CRC32_FromFile(fp, &crc); + fclose(fp); + if (is_5200_cart(crc)) { + autorunCartridge = A5200_CART; + log_cb(RETRO_LOG_INFO,"[update_variables] Found Atari 5200 bin file in DB for: %s\n", (char*)RPATH); + } else + log_cb(RETRO_LOG_INFO,"[update_variables] Assumming Atari 8bit bin file: %s\n", (char*)RPATH); + } else { + log_cb(RETRO_LOG_INFO,"[update_variables] Error opening bin file: %s\n", (char*)RPATH ); + } + } /* bin, rom files */ + else if (HandleExtension((char*)RPATH, "a52") || HandleExtension((char*)RPATH, "A52")) + autorunCartridge = A5200_CART; + else if (HandleExtension((char*)RPATH, "car") || HandleExtension((char*)RPATH, "CAR")) + autorunCartridge = A800_CART; + /* Non cartridges extensions*/ + else if (HandleExtension((char*)RPATH, "xex") || HandleExtension((char*)RPATH, "XEX") + || HandleExtension((char*)RPATH, "com") || HandleExtension((char*)RPATH, "COM") + || HandleExtension((char*)RPATH, "m3u") || HandleExtension((char*)RPATH, "M3U") + || HandleExtension((char*)RPATH, "atx") || HandleExtension((char*)RPATH, "ATX") + || HandleExtension((char*)RPATH, "cas") || HandleExtension((char*)RPATH, "CAS") + || HandleExtension((char*)RPATH, "dcm") || HandleExtension((char*)RPATH, "DCM") + || HandleExtension((char*)RPATH, "atr") || HandleExtension((char*)RPATH, "ATR")) + autorunCartridge = NO_CART; + /* Other unknown extensions - priority is Atari 8bit computer*/ + else + autorunCartridge = A800_CART; + + /* Controller Hack for Dual Stick, Swap Ports or Joy 2B+*/ + var.key = "atari800_opt2"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if ( (strcmp(var.value, "Dual Stick") == 0) || + (strcmp(var.value, "enabled") == 0)) // to accomodate for old value + atari_joyhack = 1; + else if ( strcmp(var.value,"Swap Ports") == 0) + atari_joyhack = 2; + else if ( strcmp(var.value,"Joy 2B+") == 0) + atari_joyhack = 3; + else + atari_joyhack = 0; + } + + /* Sets the Atari 800 internal emulated resolution */ + var.key = "atari800_resolution"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + char* pch; + char str[100]; + snprintf(str, sizeof(str), "%s", var.value); + + pch = strtok(str, "x"); + if (pch) + retrow = strtoul(pch, NULL, 0); + pch = strtok(NULL, "x"); + if (pch) + retroh = strtoul(pch, NULL, 0); + + fprintf(stderr, "[libretro-atari800]: Got size: %u x %u.\n", retrow, retroh); + + CROP_WIDTH = retrow; + CROP_HEIGHT = (retroh - 80); + VIRTUAL_WIDTH = retrow; + texture_init(); + //reset_screen(); + } + + /* Set the Atari system emulated */ + var.key = "atari800_system"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + /* I moved "5200" comparison up to top because I'm lazy. :P Leave it here! */ + if (autorunCartridge == A5200_CART || (strcmp(var.value, "5200") == 0)) + { + Atari800_machine_type = Atari800_MACHINE_5200; + MEMORY_ram_size = 16; + Atari800_builtin_basic = FALSE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + /* Force Atari 5200 joystick layout for Atari 5200 machine emulation */ + retro_set_controller_port_device(0, RETRO_DEVICE_ATARI_5200_JOYSTICK); + retro_set_controller_port_device(1, RETRO_DEVICE_ATARI_5200_JOYSTICK); + } + else if (strcmp(var.value, "400/800 (OS B)") == 0) + { + Atari800_machine_type = Atari800_MACHINE_800; + MEMORY_ram_size = 48; + Atari800_builtin_basic = FALSE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + } + else if (strcmp(var.value, "800XL (64K)") == 0) + { + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 64; + Atari800_builtin_basic = TRUE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + } + else if (strcmp(var.value, "130XE (128K)") == 0) + { + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 128; + Atari800_builtin_basic = TRUE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + } + else if (strcmp(var.value, "Modern XL/XE(320K CS)") == 0) + { + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = MEMORY_RAM_320_COMPY_SHOP; + Atari800_builtin_basic = TRUE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + } + else if (strcmp(var.value, "Modern XL/XE(576K)") == 0) + { + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 576; + Atari800_builtin_basic = TRUE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + } + else if (strcmp(var.value, "Modern XL/XE(1088K)") == 0) + { + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 1088; + Atari800_builtin_basic = TRUE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = FALSE; + Atari800_keyboard_detached = FALSE; + } + else if (strcmp(var.value, "XEGS") == 0) + { + Atari800_machine_type = Atari800_MACHINE_XLXE; + MEMORY_ram_size = 64; + Atari800_builtin_basic = TRUE; + Atari800_keyboard_leds = FALSE; + Atari800_f_keys = FALSE; + Atari800_jumper = FALSE; + Atari800_builtin_game = TRUE; + Atari800_keyboard_detached = atarixegs_keyboard_detached; + } + + if (!libretro_runloop_active || (strcmp(var.value, old_Atari800_machine_type) != 0 )) + { + Atari800_InitialiseMachine(); + strcpy(old_Atari800_machine_type, var.value); + } + } + + /* Are we running in NTSC (60hz) or Pal Mode (50hz) */ + var.key = "atari800_ntscpal"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "NTSC") == 0) + { + Atari800_tv_mode = Atari800_TV_NTSC; + } + else if (strcmp(var.value, "PAL") == 0) + { + Atari800_tv_mode = Atari800_TV_PAL; + } + } + + /* Set colors */ + + int colors_changed = FALSE; + + /* COLOR_VARIABLE macro is defined on L128 */ + COLOR_VARIABLE(hue) + COLOR_VARIABLE(saturation) + COLOR_VARIABLE(contrast) + COLOR_VARIABLE(brightness) + COLOR_VARIABLE(gamma) + + if ((color_first_time || colors_changed) && Colours_setup != NULL) { + Colours_setup->hue = color_hue; + Colours_setup->saturation = color_saturation; + Colours_setup->contrast = color_contrast; + Colours_setup->brightness = color_brightness; + Colours_setup->gamma = color_gamma; + Colours_Update(); + log_cb(RETRO_LOG_INFO, "[Atari800 CORE] Colours_setup changed\n"); + color_first_time = FALSE; + } + + + + + /* Activate or deactivate built in internal BASIC*/ + var.key = "atari800_internalbasic"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + { + Atari800_disable_basic = FALSE; + } + else if (strcmp(var.value, "disabled") == 0) + { + Atari800_disable_basic = TRUE; + } + + if (!libretro_runloop_active) + Atari800_InitialiseMachine(); + } + + /* Set whether SIO acceleration is activated. Currently an ALL or nothing setup. */ + var.key = "atari800_sioaccel"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + { + ESC_enable_sio_patch = Devices_enable_h_patch = Devices_enable_p_patch = Devices_enable_r_patch = TRUE; + } + else if (strcmp(var.value, "disabled") == 0) + { + ESC_enable_sio_patch = Devices_enable_h_patch = Devices_enable_p_patch = Devices_enable_r_patch = FALSE; + } + + if (!libretro_runloop_active) + Atari800_InitialiseMachine(); + else + ESC_UpdatePatches(); /* We need to do this for it to take while the emulator is running */ + } + + /* Set whether a cassette image will autoboot ( Hold start on boot ). */ + var.key = "atari800_cassboot"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + { + CASSETTE_hold_start = 1; + } + else if (strcmp(var.value, "disabled") == 0) + { + CASSETTE_hold_start = 0; + } + + if (!libretro_runloop_active) + Atari800_InitialiseMachine(); + } + + /* Set whether a new legacy configuration file will be loaded or created if not found. */ + var.key = "atari800_cfg"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + { + legacy_configuration_file = TRUE; + } + else if (strcmp(var.value, "disabled") == 0) + { + legacy_configuration_file = FALSE; + } + + } + + /* Set artifacting type. */ + var.key = "atari800_artifacting_mode"; + var.value = NULL; + + if ( environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + int old_artif_mode = ANTIC_artif_mode; + + if (strcmp(var.value, "none") == 0) + { + ANTIC_artif_mode = 0; + } + if (strcmp(var.value, "blue/brown 1") == 0) + { + ANTIC_artif_mode = 1; + } + else if (strcmp(var.value, "blue/brown 2") == 0) + { + ANTIC_artif_mode = 2; + } + else if (strcmp(var.value, "GTIA") == 0) + { + ANTIC_artif_mode = 3; + } + else if (strcmp(var.value, "CTIA") == 0) + { + ANTIC_artif_mode = 4; + } + + /* only do this if changed from off to on */ + if (ANTIC_artif_mode && !old_artif_mode) + { + if (Atari800_tv_mode == Atari800_TV_NTSC) + { + ARTIFACT_Set(ARTIFACT_NTSC_OLD); + ARTIFACT_SetTVMode(Atari800_TV_NTSC); + } + else if (Atari800_tv_mode == Atari800_TV_PAL) + { + ARTIFACT_Set(ARTIFACT_NONE); // PAL Blending has been flipped off in config for now. + ARTIFACT_SetTVMode(Atari800_TV_PAL); + } + } + /* only do this if changed from on to off*/ + else if (!ANTIC_artif_mode && old_artif_mode) + { + if (Atari800_tv_mode == Atari800_TV_NTSC) + { + ARTIFACT_Set(ARTIFACT_NONE); + ARTIFACT_SetTVMode(Atari800_TV_NTSC); + } + else if (Atari800_tv_mode == Atari800_TV_PAL) + { + ARTIFACT_Set(ARTIFACT_NONE); + ARTIFACT_SetTVMode(Atari800_TV_PAL); + } + } + + ANTIC_UpdateArtifacting(); + } + + /* Set whether paddle mode is active. */ + var.key = "paddle_active"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + paddle_mode = 1; + else + paddle_mode = 0; + } + + /* Set paddle movement speed. */ + var.key = "paddle_movement_speed"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + paddle_speed = (int)string_to_unsigned(var.value); + } + + var.key = "atari800_keyboard"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "poll") == 0) + { + keyboard_type = 0; + } + else if (strcmp(var.value, "callback") == 0) + { + keyboard_type = 1; + } + } + + var.key = "atarixegs_keyboard_detached"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "attached") == 0) + { + atarixegs_keyboard_detached = 0; + } + else if (strcmp(var.value, "detached") == 0) + { + atarixegs_keyboard_detached = 1; + } + } + + var.key = "atari800_f10"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "F1") == 0) + { + atari800_f10 = 0; + } + else if (strcmp(var.value, "F10") == 0) + { + atari800_f10 = 1; + } + } + + /* Digital Joystick/Paddle Sensitivity */ + var.key = "pot_digital_sensitivity"; + var.value = NULL; + INPUT_digital_5200_min = JOY_5200_MIN; + INPUT_digital_5200_max = JOY_5200_MAX; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value ) + { + float range; + + if (string_is_equal(var.value, "100")) + range = 1; + else + range = (float)string_to_unsigned(var.value) / 100.0f; + + INPUT_digital_5200_min = JOY_5200_CENTER - + (unsigned int)(((float)(JOY_5200_CENTER - JOY_5200_MIN) * + range) + 0.5f); + INPUT_digital_5200_max = JOY_5200_CENTER + + (unsigned int)(((float)(JOY_5200_MAX - JOY_5200_CENTER) * + range) + 0.5f); + } + + /* Analog Joystick Sensitivity */ + var.key = "pot_analog_sensitivity"; + var.value = NULL; + INPUT_joy_5200_min = JOY_5200_MIN; + INPUT_joy_5200_max = JOY_5200_MAX; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value ) + { + float range; + + if (string_is_equal(var.value, "100")) + range = 1; + else + range = (float)string_to_unsigned(var.value) / 100.0f; + + INPUT_joy_5200_min = JOY_5200_CENTER - + (unsigned int)(((float)(JOY_5200_CENTER - JOY_5200_MIN) * + range) + 0.5f); + INPUT_joy_5200_max = JOY_5200_CENTER + + (unsigned int)(((float)(JOY_5200_MAX - JOY_5200_CENTER) * + range) + 0.5f); + } + + /* Analog Joystick Deadzone */ + var.key = "pot_analog_deadzone"; + var.value = NULL; + pot_analog_deadzone = (int)(0.15f * (float)LIBRETRO_ANALOG_RANGE); + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value ) + { + unsigned deadzone = string_to_unsigned(var.value); + pot_analog_deadzone = (int)((float)deadzone * 0.01f * (float)LIBRETRO_ANALOG_RANGE); + } } static void retro_wrap_emulator() -{ - log_cb(RETRO_LOG_INFO, "WRAP EMU THD\n"); - pre_main(RPATH); +{ + log_cb(RETRO_LOG_INFO, "WRAP EMU THD\n"); + pre_main(RPATH); - log_cb(RETRO_LOG_INFO, "EXIT EMU THD\n"); - pauseg=-1; + log_cb(RETRO_LOG_INFO, "EXIT EMU THD\n"); + pauseg = -1; - //environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, 0); + //environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, 0); - // Were done here - co_switch(mainThread); + // Were done here + co_switch(mainThread); - // Dead emulator, but libco says not to return - while(true) - { - log_cb(RETRO_LOG_INFO, "Running a dead emulator."); - co_switch(mainThread); - } + // Dead emulator, but libco says not to return + while (true) + { + log_cb(RETRO_LOG_INFO, "Running a dead emulator."); + co_switch(mainThread); + } } -void Emu_init(){ +void Emu_init() { #ifdef RETRO_AND - MOUSEMODE=1; + MOUSEMODE = 1; #endif - // update_variables(); + // update_variables(); + + memset(Key_State, 0, 512); - memset(Key_Sate,0,512); - memset(Key_Sate2,0,512); + if (!emuThread && !mainThread) + { + mainThread = co_active(); + emuThread = co_create(65536 * sizeof(void*), retro_wrap_emulator); + } - if(!emuThread && !mainThread) - { - mainThread = co_active(); - emuThread = co_create(65536*sizeof(void*), retro_wrap_emulator); - } + old_Atari800_machine_type[0] = 0; - update_variables(); + update_variables(); } -void Emu_uninit(){ +void Emu_uninit() { - texture_uninit(); + texture_uninit(); } void retro_shutdown_core(void) { - log_cb(RETRO_LOG_INFO, "SHUTDOWN\n"); + log_cb(RETRO_LOG_INFO, "SHUTDOWN\n"); - texture_uninit(); - environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL); + texture_uninit(); + environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL); } -void retro_reset(void){ +void retro_reset(void) { + if (dc) + { + retro_set_eject_state(TRUE); + retro_set_image_index(0); + } + + AFILE_OpenFile(RPATH, 1, 1, 0); } -void retro_get_system_av_info(struct retro_system_av_info *info) +void retro_get_system_av_info(struct retro_system_av_info* info) { - update_variables(); + update_variables(); - info->geometry.base_width = retrow; - info->geometry.base_height = retroh; + info->geometry.base_width = retrow; + info->geometry.base_height = retroh; - if (log_cb) - log_cb(RETRO_LOG_INFO, "AV_INFO: width=%d height=%d\n",info->geometry.base_width,info->geometry.base_height); + if (log_cb) + log_cb(RETRO_LOG_INFO, "AV_INFO: width=%d height=%d\n", info->geometry.base_width, info->geometry.base_height); - info->geometry.max_width = 400; - info->geometry.max_height = 300; + info->geometry.max_width = 400; + info->geometry.max_height = 300; - if (log_cb) - log_cb(RETRO_LOG_INFO, "AV_INFO: max_width=%d max_height=%d\n",info->geometry.max_width,info->geometry.max_height); + if (log_cb) + log_cb(RETRO_LOG_INFO, "AV_INFO: max_width=%d max_height=%d\n", info->geometry.max_width, info->geometry.max_height); - info->geometry.aspect_ratio = 4.0 / 3.0; + info->geometry.aspect_ratio = 4.0 / 3.0; - if (log_cb) - log_cb(RETRO_LOG_INFO, "AV_INFO: aspect_ratio = %f\n",info->geometry.aspect_ratio); + if (log_cb) + log_cb(RETRO_LOG_INFO, "AV_INFO: aspect_ratio = %f\n", info->geometry.aspect_ratio); - info->timing.fps = retro_fps; - info->timing.sample_rate = 44100.0; + info->timing.fps = retro_fps; + info->timing.sample_rate = 44100.0; - if (log_cb) - log_cb(RETRO_LOG_INFO, "AV_INFO: fps = %f sample_rate = %f\n",info->timing.fps,info->timing.sample_rate); + if (log_cb) + log_cb(RETRO_LOG_INFO, "AV_INFO: fps = %f sample_rate = %f\n", info->timing.fps, info->timing.sample_rate); } void retro_init(void) { - struct retro_log_callback log; + unsigned dci_version = 0; + struct retro_log_callback log; + dc = dc_create(); + + libretro_runloop_active = 0; + + if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) + log_cb = log.log; - if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) - log_cb = log.log; - - const char *system_dir = NULL; + const char* system_dir = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir) && system_dir) - { - // if defined, use the system directory - retro_system_directory=system_dir; - } + if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir) && system_dir) + { + // if defined, use the system directory + retro_system_directory = system_dir; + } - const char *content_dir = NULL; + const char* content_dir = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY, &content_dir) && content_dir) - { - // if defined, use the system directory - retro_content_directory=content_dir; - } + if (environ_cb(RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY, &content_dir) && content_dir) + { + // if defined, use the system directory + retro_content_directory = content_dir; + } - const char *save_dir = NULL; + const char* save_dir = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save_dir) && save_dir) - { - // If save directory is defined use it, otherwise use system directory - retro_save_directory = *save_dir ? save_dir : retro_system_directory; - } - else - { - // make retro_save_directory the same in case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY is not implemented by the frontend - retro_save_directory=retro_system_directory; - } + if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save_dir) && save_dir) + { + // If save directory is defined use it, otherwise use system directory + retro_save_directory = *save_dir ? save_dir : retro_system_directory; + } + else + { + // make retro_save_directory the same in case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY is not implemented by the frontend + retro_save_directory = retro_system_directory; + } - if(retro_system_directory==NULL)sprintf(RETRO_DIR, "%s\0","."); - else sprintf(RETRO_DIR, "%s\0", retro_system_directory); + if (retro_system_directory == NULL) + sprintf(RETRO_DIR, "%s", "." ); + else + sprintf(RETRO_DIR, "%s%c", retro_system_directory, '0'); - sprintf(retro_system_data_directory, "%s/data\0",RETRO_DIR); + sprintf(retro_system_data_directory, "%s/data", RETRO_DIR); - log_cb(RETRO_LOG_INFO, "Retro SYSTEM_DIRECTORY %s\n",retro_system_directory); - log_cb(RETRO_LOG_INFO, "Retro SAVE_DIRECTORY %s\n",retro_save_directory); - log_cb(RETRO_LOG_INFO, "Retro CONTENT_DIRECTORY %s\n",retro_content_directory); + log_cb(RETRO_LOG_INFO, "Retro SYSTEM_DIRECTORY %s\n", retro_system_directory); + log_cb(RETRO_LOG_INFO, "Retro SAVE_DIRECTORY %s\n", retro_save_directory); + log_cb(RETRO_LOG_INFO, "Retro CONTENT_DIRECTORY %s\n", retro_content_directory); #ifndef RENDER16B - enum retro_pixel_format fmt =RETRO_PIXEL_FORMAT_XRGB8888; + enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888; #else - enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; + enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; #endif - - if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) - { - fprintf(stderr, "PIXEL FORMAT is not supported.\n"); -log_cb(RETRO_LOG_INFO, "PIXEL FORMAT is not supported.\n"); - exit(0); - } - - struct retro_input_descriptor inputDescriptors[] = { - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, - { 0 } - }; - environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, &inputDescriptors); - - Emu_init(); - - texture_init(); - - if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL)) - libretro_supports_bitmasks = true; + + if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) + { + fprintf(stderr, "PIXEL FORMAT is not supported.\n"); + log_cb(RETRO_LOG_INFO, "PIXEL FORMAT is not supported.\n"); + exit(0); + } + + /* set these up early retro_set_controller_port_device() will adjust later */ + for (int i = 0; i < 4; i++) + { + memcpy(inputDescriptors_dyna + ATARI_JOYPAD_BUTTONS * i, inputDescriptors_a800 + ATARI_JOYPAD_BUTTONS * i, (ATARI_JOYPAD_BUTTONS + 1) * sizeof(struct retro_input_descriptor)); + atari_devices[i] = RETRO_DEVICE_ATARI_JOYSTICK; + } + + environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, &inputDescriptors_dyna); + + // Disk control interface + if (environ_cb(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci_version) && (dci_version >= 1)) + environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &disk_interface_ext); + else + environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_interface); + + Emu_init(); + texture_init(); + + if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL)) + libretro_supports_bitmasks = true; } extern void main_exit(); void retro_deinit(void) -{ - Emu_uninit(); - - - co_switch(emuThread); -log_cb(RETRO_LOG_INFO, "exit emu\n"); - // main_exit(); - co_switch(mainThread); -log_cb(RETRO_LOG_INFO, "exit main\n"); - if(emuThread) - { - co_delete(emuThread); - emuThread = 0; - } - - log_cb(RETRO_LOG_INFO, "Retro DeInit\n"); - - libretro_supports_bitmasks = false; +{ + Emu_uninit(); + + co_switch(emuThread); + log_cb(RETRO_LOG_INFO, "exit emu\n"); + // main_exit(); + co_switch(mainThread); + log_cb(RETRO_LOG_INFO, "exit main\n"); + if (emuThread) + { + co_delete(emuThread); + emuThread = 0; + } + + // Clean the m3u storage + if (dc) + { + dc_free(dc); + dc = 0; + } + + log_cb(RETRO_LOG_INFO, "Retro DeInit\n"); + + libretro_supports_bitmasks = false; } unsigned retro_api_version(void) { - return RETRO_API_VERSION; + return RETRO_API_VERSION; } -void retro_set_controller_port_device( unsigned port, unsigned device ) +void retro_set_controller_port_device(unsigned port, unsigned device) { - if ( port < 4 ) - { - atari_devices[ port ] = device; + if (port < 4) + { + atari_devices[port] = device; -printf(" port(%d)=%d \n",port,device); - } -} + printf(" port(%d)=%d \n", port, device); -void retro_get_system_info(struct retro_system_info *info) -{ - memset(info, 0, sizeof(*info)); - info->library_name = "Atari800"; - info->library_version = "3.1.0" GIT_VERSION; - info->valid_extensions = "xfd|atr|cdm|cas|bin|a52|zip|atx|car|com|xex"; - info->need_fullpath = true; - info->block_extract = false; + if (device == RETRO_DEVICE_ATARI_JOYSTICK) + memcpy(inputDescriptors_dyna + ATARI_JOYPAD_BUTTONS * port, inputDescriptors_a800 + ATARI_JOYPAD_BUTTONS * port, (ATARI_JOYPAD_BUTTONS + 1) * sizeof(struct retro_input_descriptor)); + else if (device == RETRO_DEVICE_ATARI_5200_JOYSTICK) + memcpy(inputDescriptors_dyna + ATARI_JOYPAD_BUTTONS * port, inputDescriptors_a5200 + ATARI_JOYPAD_BUTTONS * port, (ATARI_JOYPAD_BUTTONS + 1) * sizeof(struct retro_input_descriptor)); + environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, &inputDescriptors_dyna); + } } -/* -void retro_get_system_av_info(struct retro_system_av_info *info) -{ - struct retro_game_geometry geom = { retrow, retroh, 400, 300,4.0 / 3.0 }; - struct retro_system_timing timing = { retro_fps, 44100.0 }; - info->geometry = geom; - info->timing = timing; +void retro_get_system_info(struct retro_system_info* info) +{ + memset(info, 0, sizeof(*info)); + info->library_name = "Atari800"; +#ifdef GIT_VERSION + info->library_version = "3.1.0" GIT_VERSION; +#else + info->library_version = "3.1.0"; +#endif + info->valid_extensions = "xfd|atr|dcm|cas|bin|a52|zip|atx|car|rom|com|xex|m3u"; + info->need_fullpath = true; + info->block_extract = false; } -*/ + void retro_set_audio_sample(retro_audio_sample_t cb) { - audio_cb = cb; + audio_cb = cb; } void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { - audio_batch_cb = cb; + audio_batch_cb = cb; } void retro_set_video_refresh(retro_video_refresh_t cb) { - video_cb = cb; + video_cb = cb; } -void retro_audio_cb( short l, short r) +void retro_audio_cb(int16_t l, int16_t r) { - audio_cb(l,r); + audio_cb(l, r); } /* Forward declarations */ void retro_sound_update(void); -void Retro_PollEvent(void); +int Retro_PollEvent(void); void retro_run(void) { - int x; - - bool updated = false; + bool updated = false; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) - update_variables(); + libretro_runloop_active = 1; - retro_frame_counter++; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) + update_variables(); - if(pauseg==0){ + retro_frame_counter++; - if (ToggleTV == 1) - { - struct retro_system_av_info ninfo; + if (pauseg == 0) { - retro_fps=CURRENT_TV==312?49.8607597:59.9227434; + if (ToggleTV == 1) + { + struct retro_system_av_info ninfo; - retro_get_system_av_info(&ninfo); + retro_fps = CURRENT_TV == 312 ? 49.8607597 : 59.9227434; - environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &ninfo); + retro_get_system_av_info(&ninfo); - if (log_cb) - log_cb(RETRO_LOG_INFO, "ChangeAV: w:%d h:%d ra:%f.\n", - ninfo.geometry.base_width, ninfo.geometry.base_height, ninfo.geometry.aspect_ratio); + environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &ninfo); - ToggleTV=0; - } + if (log_cb) + log_cb(RETRO_LOG_INFO, "ChangeAV: w:%d h:%d ra:%f.\n", + ninfo.geometry.base_width, ninfo.geometry.base_height, ninfo.geometry.aspect_ratio); - if(retro_sound_finalized) - retro_sound_update(); + ToggleTV = 0; + } - Retro_PollEvent(); - } + if (retro_sound_finalized) + retro_sound_update(); - video_cb(Retro_Screen,retrow,retroh,retrow<= 4 && - path[len-4] == '.' && - path[len-3] == ext[0] && - path[len-2] == ext[1] && - path[len-1] == ext[2]) - { - return 1; - } - - return 0; + /* + printf( "Down: %s, Code: %d, Char: %u, Mod: %u.\n", + down ? "yes" : "no", keycode, character, mod); + */ } -bool retro_load_game(const struct retro_game_info *info) +bool retro_load_game(const struct retro_game_info* info) { - const char *full_path; - - (void)info; - - - struct retro_keyboard_callback cb = { keyboard_cb }; - environ_cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &cb); - - full_path = info->path; - - strcpy(RPATH,full_path); - - update_variables(); - - if( HandleExtension((char*)RPATH,"a52") || HandleExtension((char*)RPATH,"A52")) - autorun5200=1; + struct retro_keyboard_callback cb = { keyboard_cb }; + environ_cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &cb); + + if (info!=NULL) { + const char* full_path; + bool media_is_disk_tape = TRUE; + + (void)info; + + full_path = info->path; + + // If it's a m3u file + if (strendswith(full_path, "M3U")) + { + // Parse the m3u file + dc_parse_m3u(dc, full_path); + + // Some debugging + //log_cb(RETRO_LOG_INFO, "m3u file parsed, %d file(s) found\n", dc->count); + //for (unsigned i = 0; i < dc->count; i++) + //{ + // fprintf(fp, "file %d: %s\n", i + 1, dc->files[i]); + // log_cb(RETRO_LOG_INFO, "file %d: %s\n", i + 1, dc->files[i]); + //} + } + else if (strendswith(full_path, "XFD") || + strendswith(full_path, "ATR") || + strendswith(full_path, "DCM") || + strendswith(full_path, "ATX") || + strendswith(full_path, "CAS")) + { + // Add the file to disk control context + // Maybe, in a later version of retroarch, we could add disk on the fly (didn't find how to do this) + dc_add_file(dc, full_path); + } + else + media_is_disk_tape = FALSE; + + if (media_is_disk_tape) + { + // Init first disk + dc->index = 0; + dc->eject_state = false; + log_cb(RETRO_LOG_INFO, "Disk/Cassette (%d) inserted into drive 1 : %s\n", dc->index + 1, dc->files[dc->index]); + strcpy(RPATH, dc->files[0]); + } + else + strcpy(RPATH, full_path); + } + + update_variables(); + + // Moved elsewhere + //if (HandleExtension((char*)RPATH, "a52") || HandleExtension((char*)RPATH, "A52")) + // autorunCartridge = 1; #ifdef RENDER16B - memset(Retro_Screen,0,400*300*2); + memset(Retro_Screen, 0, 400 * 300 * 2); #else - memset(Retro_Screen,0,400*300*2*2); + memset(Retro_Screen, 0, 400 * 300 * 2 * 2); #endif - memset(SNDBUF,0,1024*2*2); + memset(SNDBUF, 0, 1024 * 2 * 2); + + /* trouble shooting */ + //int fileType = 0; + //char msg[256]; + //fileType = AFILE_DetectFileType(RPATH); + //sprintf(msg, "File type detected=%i\n", fileType); + //retro_message(msg, 10000, 0); - co_switch(emuThread); + co_switch(emuThread); - return true; + return true; } -void retro_unload_game(void){ +void retro_unload_game(void) { - pauseg=-1; + pauseg = -1; } unsigned retro_get_region(void) { - return RETRO_REGION_NTSC; + return RETRO_REGION_NTSC; } -bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num) +bool retro_load_game_special(unsigned type, const struct retro_game_info* info, size_t num) { - (void)type; - (void)info; - (void)num; - return false; + (void)type; + (void)info; + (void)num; + return false; } size_t retro_serialize_size(void) { - return 0; + uint8_t* data_; + int size; + + data_ = calloc(A800_SAVE_STATE_SIZE, 1); + size = Retro_SaveAtariState(data_, A800_SAVE_STATE_SIZE, 1); + free(data_); + + return size; } -bool retro_serialize(void *data_, size_t size) +bool retro_serialize(void* data_, size_t size) { - return false; + int returned_size; + + returned_size = Retro_SaveAtariState(data_, size, 1); + + return returned_size; } -bool retro_unserialize(const void *data_, size_t size) +bool retro_unserialize(const void* data_, size_t size) { - return false; + int returned_size; + + returned_size = Retro_ReadAtariState(data_, size); + + return returned_size; } -void *retro_get_memory_data(unsigned id) +void* retro_get_memory_data(unsigned id) { - if ( id == RETRO_MEMORY_SYSTEM_RAM ) - return MEMORY_mem; - return NULL; + if (id == RETRO_MEMORY_SYSTEM_RAM) + return MEMORY_mem; + + return NULL; } size_t retro_get_memory_size(unsigned id) { - if ( id == RETRO_MEMORY_SYSTEM_RAM ) - return 65536; - return 0; + if (id == RETRO_MEMORY_SYSTEM_RAM) + return 65536; + + return 0; } void retro_cheat_reset(void) {} -void retro_cheat_set(unsigned index, bool enabled, const char *code) +void retro_cheat_set(unsigned index, bool enabled, const char* code) { - (void)index; - (void)enabled; - (void)code; + (void)index; + (void)enabled; + (void)code; } diff --git a/libretro/libretro-core.h b/libretro/libretro-core.h index 558fff2..d2968ec 100644 --- a/libretro/libretro-core.h +++ b/libretro/libretro-core.h @@ -36,13 +36,12 @@ extern cothread_t mainThread; extern cothread_t emuThread; -extern char Key_Sate[512]; -extern char Key_Sate2[512]; +extern char Key_State[512]; extern int pauseg; #define NPLGN 12 -#define NLIGN 5 +#define NLIGN 6 #define NLETT 5 #define XSIDE (CROP_WIDTH/NPLGN -1) @@ -58,9 +57,31 @@ extern int pauseg; #ifndef RENDER16B #define RGB565(r, g, b) (((r) << (5+16)) | ((g) << (5+8)) | (b<<5)) +#define R_RGB565(rgb) (((rgb) >> (5+16)) & 255) +#define G_RGB565(rgb) (((rgb) >> (5+8)) & 255) +#define B_RGB565(rgb) ((rgb>>5) & 255) +#else +#if defined(ABGR1555) +#define RGB565(r, g, b) (((b) << (10)) | ((g) << 5) | (r)) +#define B_RGB565(rgb) (((rgb) >> (10)) & 31) +#define G_RGB565(rgb) (((rgb) >> 5) & 31) +#define R_RGB565(rgb) (rgb & 31) #else #define RGB565(r, g, b) (((r) << (5+6)) | ((g) << 6) | (b)) +#define R_RGB565(rgb) (((rgb) >> (5+6)) & 31) +#define G_RGB565(rgb) (((rgb) >> 6) & 31) +#define B_RGB565(rgb) (rgb & 31) +#endif #endif #define uint32 unsigned int #define uint8 unsigned char + +//Paddle & 5200 POT +#define LIBRETRO_ANALOG_RANGE 0x8000 +#define JOY_5200_MIN 6 +#define JOY_5200_MAX 220 +#define JOY_5200_CENTER 114 + +void retro_message(const char* text, unsigned int frames, int alt); +void retro_audio_cb(int16_t l, int16_t r); #endif diff --git a/libretro/libretro_core_options.h b/libretro/libretro_core_options.h new file mode 100644 index 0000000..bf129c9 --- /dev/null +++ b/libretro/libretro_core_options.h @@ -0,0 +1,1177 @@ +#ifndef LIBRETRO_CORE_OPTIONS_H__ +#define LIBRETRO_CORE_OPTIONS_H__ + +#include +#include + +#include +#include + +#ifndef HAVE_NO_LANGEXTRA +#include "libretro_core_options_intl.h" +#endif + +/* + ******************************** + * VERSION: 1.0 + ******************************** + * + * - 1.0: First commit. Support for cor options v2 interfaec. + * - libretro_core_options_intl.h includes BOM and utf-8 + * fix for MSVC 2010-2013 + * - Contains HAVE_NO_LANGEXTRA flag to disable translations + * on platforms/compilers without BOM support + * - Uses core options v1 interface when + * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 + * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) + * - Support for generation of core options v0 retro_core_option_value + * arrays containing options with a single value + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ******************************** + * Core Option Definitions + ******************************** +*/ + +/* RETRO_LANGUAGE_ENGLISH */ + +/* Default language: + * - All other languages must include the same keys and values + * - Will be used as a fallback in the event that frontend language + * is not available + * - Will be used as a fallback for any missing entries in + * frontend language definition */ + +//struct retro_core_option_v2_category option_cats_us[] = { +// { NULL, NULL, NULL }, +//}; + +#define RANGE_1 \ + { \ + {"-1.00", NULL}, \ + {"-0.98", NULL}, \ + {"-0.96", NULL}, \ + {"-0.94", NULL}, \ + {"-0.92", NULL}, \ + {"-0.90", NULL}, \ + {"-0.88", NULL}, \ + {"-0.86", NULL}, \ + {"-0.84", NULL}, \ + {"-0.82", NULL}, \ + {"-0.80", NULL}, \ + {"-0.78", NULL}, \ + {"-0.76", NULL}, \ + {"-0.74", NULL}, \ + {"-0.72", NULL}, \ + {"-0.70", NULL}, \ + {"-0.68", NULL}, \ + {"-0.66", NULL}, \ + {"-0.64", NULL}, \ + {"-0.62", NULL}, \ + {"-0.60", NULL}, \ + {"-0.58", NULL}, \ + {"-0.56", NULL}, \ + {"-0.54", NULL}, \ + {"-0.52", NULL}, \ + {"-0.50", NULL}, \ + {"-0.48", NULL}, \ + {"-0.46", NULL}, \ + {"-0.44", NULL}, \ + {"-0.42", NULL}, \ + {"-0.40", NULL}, \ + {"-0.38", NULL}, \ + {"-0.36", NULL}, \ + {"-0.34", NULL}, \ + {"-0.32", NULL}, \ + {"-0.30", NULL}, \ + {"-0.28", NULL}, \ + {"-0.26", NULL}, \ + {"-0.24", NULL}, \ + {"-0.22", NULL}, \ + {"-0.20", NULL}, \ + {"-0.18", NULL}, \ + {"-0.16", NULL}, \ + {"-0.14", NULL}, \ + {"-0.12", NULL}, \ + {"-0.10", NULL}, \ + {"-0.08", NULL}, \ + {"-0.06", NULL}, \ + {"-0.04", NULL}, \ + {"-0.02", NULL}, \ + {"0.00", "0.00 (Default)"}, \ + {"0.02", NULL}, \ + {"0.04", NULL}, \ + {"0.06", NULL}, \ + {"0.08", NULL}, \ + {"0.10", NULL}, \ + {"0.12", NULL}, \ + {"0.14", NULL}, \ + {"0.16", NULL}, \ + {"0.18", NULL}, \ + {"0.20", NULL}, \ + {"0.22", NULL}, \ + {"0.24", NULL}, \ + {"0.26", NULL}, \ + {"0.28", NULL}, \ + {"0.30", NULL}, \ + {"0.32", NULL}, \ + {"0.34", NULL}, \ + {"0.36", NULL}, \ + {"0.38", NULL}, \ + {"0.40", NULL}, \ + {"0.42", NULL}, \ + {"0.44", NULL}, \ + {"0.46", NULL}, \ + {"0.48", NULL}, \ + {"0.50", NULL}, \ + {"0.52", NULL}, \ + {"0.54", NULL}, \ + {"0.56", NULL}, \ + {"0.58", NULL}, \ + {"0.60", NULL}, \ + {"0.62", NULL}, \ + {"0.64", NULL}, \ + {"0.66", NULL}, \ + {"0.68", NULL}, \ + {"0.70", NULL}, \ + {"0.72", NULL}, \ + {"0.74", NULL}, \ + {"0.76", NULL}, \ + {"0.78", NULL}, \ + {"0.80", NULL}, \ + {"0.82", NULL}, \ + {"0.84", NULL}, \ + {"0.86", NULL}, \ + {"0.88", NULL}, \ + {"0.90", NULL}, \ + {"0.92", NULL}, \ + {"0.94", NULL}, \ + {"0.96", NULL}, \ + {"0.98", NULL}, \ + {"1.00", NULL}, \ + { NULL, NULL }, \ + } + + +#define RANGE_2 \ + { \ + {"-2.00", NULL}, \ + {"-1.96", NULL}, \ + {"-1.92", NULL}, \ + {"-1.88", NULL}, \ + {"-1.84", NULL}, \ + {"-1.80", NULL}, \ + {"-1.76", NULL}, \ + {"-1.72", NULL}, \ + {"-1.68", NULL}, \ + {"-1.64", NULL}, \ + {"-1.60", NULL}, \ + {"-1.56", NULL}, \ + {"-1.52", NULL}, \ + {"-1.48", NULL}, \ + {"-1.44", NULL}, \ + {"-1.40", NULL}, \ + {"-1.36", NULL}, \ + {"-1.32", NULL}, \ + {"-1.28", NULL}, \ + {"-1.24", NULL}, \ + {"-1.20", NULL}, \ + {"-1.16", NULL}, \ + {"-1.12", NULL}, \ + {"-1.08", NULL}, \ + {"-1.04", NULL}, \ + {"-1.00", NULL}, \ + {"-0.96", NULL}, \ + {"-0.92", NULL}, \ + {"-0.88", NULL}, \ + {"-0.84", NULL}, \ + {"-0.80", NULL}, \ + {"-0.76", NULL}, \ + {"-0.72", NULL}, \ + {"-0.68", NULL}, \ + {"-0.64", NULL}, \ + {"-0.60", NULL}, \ + {"-0.56", NULL}, \ + {"-0.52", NULL}, \ + {"-0.48", NULL}, \ + {"-0.44", NULL}, \ + {"-0.40", NULL}, \ + {"-0.36", NULL}, \ + {"-0.32", NULL}, \ + {"-0.28", NULL}, \ + {"-0.24", NULL}, \ + {"-0.20", NULL}, \ + {"-0.16", NULL}, \ + {"-0.12", NULL}, \ + {"-0.08", NULL}, \ + {"-0.04", NULL}, \ + {"0.00", "0.00 (Default)"}, \ + {"0.04", NULL}, \ + {"0.08", NULL}, \ + {"0.12", NULL}, \ + {"0.16", NULL}, \ + {"0.20", NULL}, \ + {"0.24", NULL}, \ + {"0.28", NULL}, \ + {"0.32", NULL}, \ + {"0.36", NULL}, \ + {"0.40", NULL}, \ + {"0.44", NULL}, \ + {"0.48", NULL}, \ + {"0.52", NULL}, \ + {"0.56", NULL}, \ + {"0.60", NULL}, \ + {"0.64", NULL}, \ + {"0.68", NULL}, \ + {"0.72", NULL}, \ + {"0.76", NULL}, \ + {"0.80", NULL}, \ + {"0.84", NULL}, \ + {"0.88", NULL}, \ + {"0.92", NULL}, \ + {"0.96", NULL}, \ + {"1.00", NULL}, \ + {"1.04", NULL}, \ + {"1.08", NULL}, \ + {"1.12", NULL}, \ + {"1.16", NULL}, \ + {"1.20", NULL}, \ + {"1.24", NULL}, \ + {"1.28", NULL}, \ + {"1.32", NULL}, \ + {"1.36", NULL}, \ + {"1.40", NULL}, \ + {"1.44", NULL}, \ + {"1.48", NULL}, \ + {"1.52", NULL}, \ + {"1.56", NULL}, \ + {"1.60", NULL}, \ + {"1.64", NULL}, \ + {"1.68", NULL}, \ + {"1.72", NULL}, \ + {"1.76", NULL}, \ + {"1.80", NULL}, \ + {"1.84", NULL}, \ + {"1.88", NULL}, \ + {"1.92", NULL}, \ + {"1.96", NULL}, \ + {"2.00", NULL}, \ + { NULL, NULL }, \ + } + +#define RANGE_GAMMA \ + { \ + {"1.00", NULL}, \ + {"1.02", NULL}, \ + {"1.04", NULL}, \ + {"1.06", NULL}, \ + {"1.08", NULL}, \ + {"1.10", NULL}, \ + {"1.12", NULL}, \ + {"1.14", NULL}, \ + {"1.16", NULL}, \ + {"1.18", NULL}, \ + {"1.20", NULL}, \ + {"1.22", NULL}, \ + {"1.24", NULL}, \ + {"1.26", NULL}, \ + {"1.28", NULL}, \ + {"1.30", NULL}, \ + {"1.32", NULL}, \ + {"1.34", NULL}, \ + {"1.36", NULL}, \ + {"1.38", NULL}, \ + {"1.40", NULL}, \ + {"1.42", NULL}, \ + {"1.44", NULL}, \ + {"1.46", NULL}, \ + {"1.48", NULL}, \ + {"1.50", NULL}, \ + {"1.52", NULL}, \ + {"1.54", NULL}, \ + {"1.56", NULL}, \ + {"1.58", NULL}, \ + {"1.60", NULL}, \ + {"1.62", NULL}, \ + {"1.64", NULL}, \ + {"1.66", NULL}, \ + {"1.68", NULL}, \ + {"1.70", NULL}, \ + {"1.72", NULL}, \ + {"1.74", NULL}, \ + {"1.76", NULL}, \ + {"1.78", NULL}, \ + {"1.80", NULL}, \ + {"1.82", NULL}, \ + {"1.84", NULL}, \ + {"1.86", NULL}, \ + {"1.88", NULL}, \ + {"1.90", NULL}, \ + {"1.92", NULL}, \ + {"1.94", NULL}, \ + {"1.96", NULL}, \ + {"1.98", NULL}, \ + {"2.00", NULL}, \ + {"2.02", NULL}, \ + {"2.04", NULL}, \ + {"2.06", NULL}, \ + {"2.08", NULL}, \ + {"2.10", NULL}, \ + {"2.12", NULL}, \ + {"2.14", NULL}, \ + {"2.16", NULL}, \ + {"2.18", NULL}, \ + {"2.20", NULL}, \ + {"2.22", NULL}, \ + {"2.24", NULL}, \ + {"2.26", NULL}, \ + {"2.28", NULL}, \ + {"2.30", NULL}, \ + {"2.32", NULL}, \ + {"2.34", NULL}, \ + {"2.35", "2.35 (Default)"}, \ + {"2.36", NULL}, \ + {"2.38", NULL}, \ + {"2.40", NULL}, \ + {"2.42", NULL}, \ + {"2.44", NULL}, \ + {"2.46", NULL}, \ + {"2.48", NULL}, \ + {"2.50", NULL}, \ + {"2.52", NULL}, \ + {"2.54", NULL}, \ + {"2.56", NULL}, \ + {"2.58", NULL}, \ + {"2.60", NULL}, \ + {"2.62", NULL}, \ + {"2.64", NULL}, \ + {"2.66", NULL}, \ + {"2.68", NULL}, \ + {"2.70", NULL}, \ + {"2.72", NULL}, \ + {"2.74", NULL}, \ + {"2.76", NULL}, \ + {"2.78", NULL}, \ + {"2.80", NULL}, \ + {"2.82", NULL}, \ + {"2.84", NULL}, \ + {"2.86", NULL}, \ + {"2.88", NULL}, \ + {"2.90", NULL}, \ + {"2.92", NULL}, \ + {"2.94", NULL}, \ + {"2.96", NULL}, \ + {"2.98", NULL}, \ + {"3.00", NULL}, \ + {"3.02", NULL}, \ + {"3.04", NULL}, \ + {"3.06", NULL}, \ + {"3.08", NULL}, \ + {"3.10", NULL}, \ + {"3.12", NULL}, \ + {"3.14", NULL}, \ + {"3.16", NULL}, \ + {"3.18", NULL}, \ + {"3.20", NULL}, \ + {"3.22", NULL}, \ + {"3.24", NULL}, \ + {"3.26", NULL}, \ + {"3.28", NULL}, \ + {"3.30", NULL}, \ + {"3.32", NULL}, \ + {"3.34", NULL}, \ + {"3.36", NULL}, \ + {"3.38", NULL}, \ + {"3.40", NULL}, \ + {"3.42", NULL}, \ + {"3.44", NULL}, \ + {"3.46", NULL}, \ + {"3.48", NULL}, \ + {"3.50", NULL}, \ + { NULL, NULL }, \ + } + +struct retro_core_option_v2_category option_cats_us[] = { + { + "video", + "Video", + "Configure video standard (NTSC/PAL). Enable Hi-res artifacting and set artifacting mode. Set internal resolution" + }, + { + "input", + "Input", + "Configure 5200 Digital and Analog Joystick sensitivity and Analog deadzone. Activate Swap, Dual Joysticks or Joy 2B+. Activate Paddle mode and set Paddle speed. Set retroarch keyboard type." + }, + { NULL, NULL, NULL }, +}; + +struct retro_core_option_v2_definition option_defs_us[] = { + { + "atari800_ntscpal", + "Video Standard", + NULL, + "Select whether emulated system is NTSC (60hz) or PAL (50hz)", + NULL, + "video", + { + { "NTSC", NULL }, + { "PAL", NULL }, + { NULL, NULL }, + }, + "disabled" + }, + { + "atari800_artifacting_mode", + "Hi-Res Artifacting Mode", + NULL, + "Set Hi-Res Artifacting mode used. Typically dependant on the actual emulated system. Pick the color combination that pleases you.", + NULL, + "video", + { + { "none", "None "}, + { "blue/brown 1", NULL }, + { "blue/brown 2", NULL }, + { "GTIA", NULL }, + { "CTIA", NULL }, + { NULL, NULL }, + }, + "none" + }, + { + "atari800_resolution", + "Internal resolution", + NULL, + "Set emulated systems internal resolution.", + NULL, + "video", + { + { "336x240", NULL }, + { "320x240", NULL }, + { "384x240", NULL }, + { "384x272", NULL }, + { "384x288", NULL }, + { "400x300", NULL }, + { NULL, NULL }, + }, + "336x240" + }, + { + "color_hue", + "Color tint/hue", + NULL, + "Set emulated color tint between -1.0 and 1.0", + NULL, + "video", + RANGE_1, + "0.00" + }, + { + "color_saturation", + "Color saturation", + NULL, + "Set emulated color saturation between -1.0 and 1.0.", + NULL, + "video", + RANGE_1, + "0.00" + }, + { + "color_contrast", + "Color contrast", + NULL, + "Set emulated color contrast between -2.0 and 2.0.", + NULL, + "video", + RANGE_2, + "0.00" + }, + { + "color_brightness", + "Color brightness", + NULL, + "Set emulated color brightness between -2.0 and 2.0.", + NULL, + "video", + RANGE_2, + "0.00" + }, + { + "color_gamma", + "Color gamma", + NULL, + "Set emulated color gamma between 1.0 and 3.5.", + NULL, + "video", + RANGE_GAMMA, + "2.35" + }, + { + "atari800_opt2", + "Controller Hacks", + NULL, + "Apply gamepad input hacks required for specific games. 'Dual Stick' maps Player 2's joystick to the right analog stick of Player 1's RetroPad, enabling dual stick control in 'Robotron 2084' and 'Space Dungeon'. 'Swap Ports' maps Player 1 to port 2 and Player 2 to port 1 of the emulated console, correcting the swapped inputs of 'Wizard of Wor', 'Apple Panic' and a few other games. 'Joy 2B+' enables multibutton joysticks support.", + NULL, + "input", + { + { "none", NULL }, + { "enabled", "Dual Stick" }, + { "Swap Ports", "Swap Ports" }, + { "Joy 2B+", "Joy 2B+" }, + { NULL, NULL }, + }, + "none" + }, + { + "paddle_active", + "Activate Paddle Mode", + NULL, + "Use analog stick and digital pad to control paddle games. Dual Stick and Swap Ports will be de-activated if this is enabled", + NULL, + "input", + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled" + }, + { + "paddle_movement_speed", + "Paddle Movement Speed", + NULL, + "Determines how fast the paddle will move.", + NULL, + "input", + { + { "1", NULL }, + { "2", NULL }, + { "3", NULL }, + { "4", NULL }, + { "5", NULL }, + { "6", NULL }, + { "7", NULL }, + { "8", NULL }, + { "9", NULL }, + { NULL, NULL }, + }, + "3" + }, + { + "pot_digital_sensitivity", + "Digital Joystick Sensitivity", + NULL, + "Set the effective range of the emulated analog joystick when using the gamepad's digital D-Pad for movement. Lower values equate to slower speeds. Also can be used to make games like Centipede, Kaboom, Missile Command, Pengo, Realsports Tennis, Pole Position, Xari Arena and Super Breakout more playable.", + NULL, + "input", + { + { "5", "5%" }, + { "10", "10%" }, + { "15", "15%" }, + { "20", "20%" }, + { "25", "25%" }, + { "30", "30%" }, + { "35", "35%" }, + { "40", "40%" }, + { "45", "45%" }, + { "50", "50%" }, + { "55", "55%" }, + { "60", "60%" }, + { "65", "65%" }, + { "70", "70%" }, + { "75", "75%" }, + { "80", "80%" }, + { "85", "85%" }, + { "90", "90%" }, + { "95", "95%" }, + { "100", "100%" }, + { NULL, NULL }, + }, + "100" + }, + { + "pot_analog_sensitivity", + "Analog Joystick Sensitivity", + NULL, + "Set the effective range of the emulated analog joystick when using the gamepad's left analog stick for movement. Lower values equate to slower speeds. Also can be used to make games like Centipede, Kaboom, Missile Command, Pengo, Realsports Tennis, Pole Position, Xari Arena and Super Breakout more playable.", + NULL, + "input", + { + { "5", "5%" }, + { "10", "10%" }, + { "15", "15%" }, + { "20", "20%" }, + { "25", "25%" }, + { "30", "30%" }, + { "35", "35%" }, + { "40", "40%" }, + { "45", "45%" }, + { "50", "50%" }, + { "55", "55%" }, + { "60", "60%" }, + { "65", "65%" }, + { "70", "70%" }, + { "75", "75%" }, + { "80", "80%" }, + { "85", "85%" }, + { "90", "90%" }, + { "95", "95%" }, + { "100", "100%" }, + { NULL, NULL }, + }, + "100" + }, + { + "pot_analog_deadzone", + "Analog Joystick Deadzone", + NULL, + "Set the deadzone of the gamepad's analog sticks. Use this to eliminate controller drift.", + NULL, + "input", + { + { "0", "0%" }, + { "3", "3%" }, + { "5", "5%" }, + { "7", "7%" }, + { "10", "10%" }, + { "13", "13%" }, + { "15", "15%" }, + { "17", "17%" }, + { "20", "20%" }, + { "23", "23%" }, + { "25", "25%" }, + { "27", "27%" }, + { "30", "30%" }, + { NULL, NULL }, + }, + "15" + }, + { + "atari800_keyboard", + "Retroarch Keyboard type", + NULL, + "Set whether keyboard is polled or used callback.", + NULL, + "input", + { + { "poll", NULL }, + { "callback", NULL }, + { NULL, NULL }, + }, + "poll" + }, + { + "atarixegs_keyboard_detached", + "Atari XEGS keyboard", + NULL, + "Set whether the Atari XEGS keyboard is attached or detached. If 'Internal BASIC' is enabled and the keyboard is attached, it will boot to BASIC. If 'Internal BASIC' is enabled and the keyboard is detached it will boot to the in-built game (Missile Command). If 'Internal BASIC' is disabled, it will boot to the Self Test screen.", + NULL, + "input", + { + { "attached", NULL }, + { "detached", NULL }, + { NULL, NULL }, + }, + "attached" + }, + /* This legacy menu should be eliminated, as soon as all options are included in RetroArch Core Options */ + { + "atari800_f10", + "Legacy menu key", + NULL, + "Set whether the Atari800 emulator's legacy menu is invoked by pressing F1 (default) or F10 (to avoid interference with RetroArch's own menu).", + NULL, + "input", + { + { "F1", NULL }, + { "F10", NULL }, + { NULL, NULL }, + }, + "F1" + }, + { + "keyboard_defines", + "Atari Keyboard Defines", + NULL, + "Joystick and Console Key mappings for\n\"Atari Keyboard\".\n \n Joystick \"Keyboard Numpad 8, 2, 4 & 6\".\n \n5200 analog joystick. Left analog stick or \"Keyboard Numpad 8, 2, 4 & 6\".\n \nFire 1 \"Right CTRL\". Fire 2 \"Right ALT\".\n \n5200 * \"Keyboard Numpad * \". # \"Keyboard =\"\n \n5200 Keypad 0-9 \"Keyboard 0-9\".\nPause \"P\", Reset \"R\".\n \n'Console' keys Option \"F2\", Select \"F3\",\nStart \"F4\".\n \nController 1 only.", + NULL, + "input", + { + { "informational", NULL }, + { NULL, NULL }, + }, + "informational" + }, + { + "atari800_system", + "Atari System", + NULL, + "Select system emulated. Atari 5200 for Atari 5200 console games. 400/800 (OS B) for <48K games or ones that require OS/B. 800XL (64K) works for most content. 130XE (128K), Modern XL/XE(320K Compy Shop), Modern XL/XE(576K), Modern XL/XE(1088K) for content that needs more than 64K. Atari XE Game System for the Atari XE Game System or XEGS console games.", + NULL, + NULL, + { + { "400/800 (OS B)", "Atari 400/800 (OS B)" }, + { "800XL (64K)", "Atari 800XL (64K)" }, + { "130XE (128K)", "Atari 130XE (128K)" }, + { "Modern XL/XE(320K CS)", "Modern Atari XL/XE(320K Compy Shop)" }, + { "Modern XL/XE(576K)", "Modern Atari XL/XE(576K)" }, + { "Modern XL/XE(1088K)", "Modern Atari XL/XE(1088K)" }, + { "XEGS", "Atari XE Game System"}, + { "5200", "Atari 5200 Super System" }, + { NULL, NULL }, + }, + "800XL (64K)" // The Atari 800XL should be the default because most games will work on it, rather than the Atari 400/800. + }, + { + "atari800_internalbasic", + "Internal BASIC (hold OPTION on boot) (Restart)", + NULL, + "Enable for content that needs Atari BASIC in order to run. A proper ROM file (ATARIBAS.ROM) is needed.", + NULL, + NULL, + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled" + }, + { + "atari800_sioaccel", + "SIO Acceleration", + NULL, + "This enables ALL SIO acceleration. Enabled improves loading speed for Disk and Cassette images. Disable only for protected disk (.ATX) and protected cassette images. Reboot required if change made while loading a cassette image.", + NULL, + NULL, + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "enabled" + }, + { + "atari800_cassboot", + "Boot from Cassette (Reboot)", + NULL, + "Forces emulated system to boot from autoboot cassette images by holding down the \"START\" key on boot.", + NULL, + NULL, + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled" + }, + { + "atari800_cfg", + "Uses the Atari800 legacy configuration file", + NULL, + "If the Atari800 legacy configuration file, .atari800.cfg, is found, it will be loaded, and if not found, a new will be created.", + NULL, + NULL, + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled" + }, + /* Detection should be enabled always because now all file extensions are covered in update_variables + { + "atari800_opt1", + "Autodetect Atari Cartridge Type (Restart)", + NULL, + "Emulator will auto detect Atari cartridge based on checksum. (requires good ROM dumps).", + NULL, + NULL, + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled" + },*/ + /* Not sure if I want to implement this. Only helps a small handful of games ( Kaboom, Super Breakout and Star Wars The Arcade Game + { + "pot_analog_center", + "Analog Joystick/Paddle Center", + NULL, + "Set the value for emulated analog joystick or paddle center. Use this to properly center player for some games like Kaboom, Starwars or Super Breakout. Default is 114", + NULL, + "5200", + { + { "80", NULL }, + { "82", NULL }, + { "84", NULL }, + { "86", NULL }, + { "88", NULL }, + { "90", NULL }, + { "92", NULL }, + { "94", NULL }, + { "96", NULL }, + { "98", NULL }, + { "100", NULL }, + { "102", NULL }, + { "104", NULL }, + { "106", NULL }, + { "108", NULL }, + { "110", NULL }, + { "112", NULL }, + { "114", NULL }, + { "116", NULL }, + { "118", NULL }, + { "120", NULL }, + { "122", NULL }, + { "124", NULL }, + { "126", NULL }, + { "128", NULL }, + { "130", NULL }, + { "132", NULL }, + { "134", NULL }, + { "136", NULL }, + { "130", NULL }, + { "140", NULL }, + { "142", NULL }, + { "144", NULL }, + { "146", NULL }, + { "148", NULL }, + { "150", NULL }, + { NULL, NULL }, + }, + "114" + }, */ + { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL }, +}; + +struct retro_core_options_v2 options_us = { + option_cats_us, + option_defs_us +}; + +/* + ******************************** + * Language Mapping + ******************************** +*/ + +#ifndef HAVE_NO_LANGEXTRA +struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = { + &options_us, /* RETRO_LANGUAGE_ENGLISH */ + NULL, /* RETRO_LANGUAGE_JAPANESE */ + NULL, /* RETRO_LANGUAGE_FRENCH */ + NULL, /* RETRO_LANGUAGE_SPANISH */ + NULL, /* RETRO_LANGUAGE_GERMAN */ + NULL, /* RETRO_LANGUAGE_ITALIAN */ + NULL, /* RETRO_LANGUAGE_DUTCH */ + NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ + NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ + NULL, /* RETRO_LANGUAGE_RUSSIAN */ + NULL, /* RETRO_LANGUAGE_KOREAN */ + NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ + NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ + NULL, /* RETRO_LANGUAGE_ESPERANTO */ + NULL, /* RETRO_LANGUAGE_POLISH */ + NULL, /* RETRO_LANGUAGE_VIETNAMESE */ + NULL, /* RETRO_LANGUAGE_ARABIC */ + NULL, /* RETRO_LANGUAGE_GREEK */ + NULL, /* RETRO_LANGUAGE_TURKISH */ + NULL, /* RETRO_LANGUAGE_SLOVAK */ + NULL, /* RETRO_LANGUAGE_PERSIAN */ + NULL, /* RETRO_LANGUAGE_HEBREW */ + NULL, /* RETRO_LANGUAGE_ASTURIAN */ + NULL, /* RETRO_LANGUAGE_FINNISH */ +}; +#endif + +/* + ******************************** + * Functions + ******************************** +*/ + +/* Handles configuration/setting of core options. + * Should be called as early as possible - ideally inside + * retro_set_environment(), and no later than retro_load_game() + * > We place the function body in the header to avoid the + * necessity of adding more .c files (i.e. want this to + * be as painless as possible for core devs) + */ + +static INLINE void libretro_set_core_options(retro_environment_t environ_cb, + bool *categories_supported) +{ + unsigned version = 0; +#ifndef HAVE_NO_LANGEXTRA + unsigned language = 0; +#endif + + if (!environ_cb || !categories_supported) + return; + + *categories_supported = false; + + if (!environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version)) + version = 0; + + if (version >= 2) + { +#ifndef HAVE_NO_LANGEXTRA + struct retro_core_options_v2_intl core_options_intl; + + core_options_intl.us = &options_us; + core_options_intl.local = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) && + (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH)) + core_options_intl.local = options_intl[language]; + + *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL, + &core_options_intl); +#else + *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + &options_us); +#endif + } + else + { + size_t i, j; + size_t option_index = 0; + size_t num_options = 0; + struct retro_core_option_definition + *option_v1_defs_us = NULL; +#ifndef HAVE_NO_LANGEXTRA + size_t num_options_intl = 0; + struct retro_core_option_v2_definition + *option_defs_intl = NULL; + struct retro_core_option_definition + *option_v1_defs_intl = NULL; + struct retro_core_options_intl + core_options_v1_intl; +#endif + struct retro_variable *variables = NULL; + char **values_buf = NULL; + + /* Determine total number of options */ + while (true) + { + if (option_defs_us[num_options].key) + num_options++; + else + break; + } + + if (version >= 1) + { + /* Allocate US array */ + option_v1_defs_us = (struct retro_core_option_definition *) + calloc(num_options + 1, sizeof(struct retro_core_option_definition)); + + /* Copy parameters from option_defs_us array */ + for (i = 0; i < num_options; i++) + { + struct retro_core_option_v2_definition *option_def_us = &option_defs_us[i]; + struct retro_core_option_value *option_values = option_def_us->values; + struct retro_core_option_definition *option_v1_def_us = &option_v1_defs_us[i]; + struct retro_core_option_value *option_v1_values = option_v1_def_us->values; + + option_v1_def_us->key = option_def_us->key; + option_v1_def_us->desc = option_def_us->desc; + option_v1_def_us->info = option_def_us->info; + option_v1_def_us->default_value = option_def_us->default_value; + + /* Values must be copied individually... */ + while (option_values->value) + { + option_v1_values->value = option_values->value; + option_v1_values->label = option_values->label; + + option_values++; + option_v1_values++; + } + } + +#ifndef HAVE_NO_LANGEXTRA + if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) && + (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH) && + options_intl[language]) + option_defs_intl = options_intl[language]->definitions; + + if (option_defs_intl) + { + /* Determine number of intl options */ + while (true) + { + if (option_defs_intl[num_options_intl].key) + num_options_intl++; + else + break; + } + + /* Allocate intl array */ + option_v1_defs_intl = (struct retro_core_option_definition *) + calloc(num_options_intl + 1, sizeof(struct retro_core_option_definition)); + + /* Copy parameters from option_defs_intl array */ + for (i = 0; i < num_options_intl; i++) + { + struct retro_core_option_v2_definition *option_def_intl = &option_defs_intl[i]; + struct retro_core_option_value *option_values = option_def_intl->values; + struct retro_core_option_definition *option_v1_def_intl = &option_v1_defs_intl[i]; + struct retro_core_option_value *option_v1_values = option_v1_def_intl->values; + + option_v1_def_intl->key = option_def_intl->key; + option_v1_def_intl->desc = option_def_intl->desc; + option_v1_def_intl->info = option_def_intl->info; + option_v1_def_intl->default_value = option_def_intl->default_value; + + /* Values must be copied individually... */ + while (option_values->value) + { + option_v1_values->value = option_values->value; + option_v1_values->label = option_values->label; + + option_values++; + option_v1_values++; + } + } + } + + core_options_v1_intl.us = option_v1_defs_us; + core_options_v1_intl.local = option_v1_defs_intl; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_v1_intl); +#else + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, option_v1_defs_us); +#endif + } + else + { + /* Allocate arrays */ + variables = (struct retro_variable *)calloc(num_options + 1, + sizeof(struct retro_variable)); + values_buf = (char **)calloc(num_options, sizeof(char *)); + + if (!variables || !values_buf) + goto error; + + /* Copy parameters from option_defs_us array */ + for (i = 0; i < num_options; i++) + { + const char *key = option_defs_us[i].key; + const char *desc = option_defs_us[i].desc; + const char *default_value = option_defs_us[i].default_value; + struct retro_core_option_value *values = option_defs_us[i].values; + size_t buf_len = 3; + size_t default_index = 0; + + values_buf[i] = NULL; + + if (desc) + { + size_t num_values = 0; + + /* Determine number of values */ + while (true) + { + if (values[num_values].value) + { + /* Check if this is the default value */ + if (default_value) + if (strcmp(values[num_values].value, default_value) == 0) + default_index = num_values; + + buf_len += strlen(values[num_values].value); + num_values++; + } + else + break; + } + + /* Build values string */ + if (num_values > 0) + { + buf_len += num_values - 1; + buf_len += strlen(desc); + + values_buf[i] = (char *)calloc(buf_len, sizeof(char)); + if (!values_buf[i]) + goto error; + + strcpy(values_buf[i], desc); + strcat(values_buf[i], "; "); + + /* Default value goes first */ + strcat(values_buf[i], values[default_index].value); + + /* Add remaining values */ + for (j = 0; j < num_values; j++) + { + if (j != default_index) + { + strcat(values_buf[i], "|"); + strcat(values_buf[i], values[j].value); + } + } + } + } + + variables[option_index].key = key; + variables[option_index].value = values_buf[i]; + option_index++; + } + + /* Set variables */ + environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables); + } + +error: + /* Clean up */ + + if (option_v1_defs_us) + { + free(option_v1_defs_us); + option_v1_defs_us = NULL; + } + +#ifndef HAVE_NO_LANGEXTRA + if (option_v1_defs_intl) + { + free(option_v1_defs_intl); + option_v1_defs_intl = NULL; + } +#endif + + if (values_buf) + { + for (i = 0; i < num_options; i++) + { + if (values_buf[i]) + { + free(values_buf[i]); + values_buf[i] = NULL; + } + } + + free(values_buf); + values_buf = NULL; + } + + if (variables) + { + free(variables); + variables = NULL; + } + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libretro/libretro_core_options_intl.h b/libretro/libretro_core_options_intl.h new file mode 100644 index 0000000..038553a --- /dev/null +++ b/libretro/libretro_core_options_intl.h @@ -0,0 +1,91 @@ +#ifndef LIBRETRO_CORE_OPTIONS_INTL_H__ +#define LIBRETRO_CORE_OPTIONS_INTL_H__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900) +/* https://support.microsoft.com/en-us/kb/980263 */ +#pragma execution_character_set("utf-8") +#pragma warning(disable:4566) +#endif + +#include + +/* + ******************************** + * VERSION: 2.0 + ******************************** + * + * - 2.0: Add support for core options v2 interface + * - 1.3: Move translations to libretro_core_options_intl.h + * - libretro_core_options_intl.h includes BOM and utf-8 + * fix for MSVC 2010-2013 + * - Added HAVE_NO_LANGEXTRA flag to disable translations + * on platforms/compilers without BOM support + * - 1.2: Use core options v1 interface when + * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 + * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) + * - 1.1: Support generation of core options v0 retro_core_option_value + * arrays containing options with a single value + * - 1.0: First commit +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ******************************** + * Core Option Definitions + ******************************** +*/ + +/* RETRO_LANGUAGE_JAPANESE */ + +/* RETRO_LANGUAGE_FRENCH */ + +/* RETRO_LANGUAGE_SPANISH */ + +/* RETRO_LANGUAGE_GERMAN */ + +/* RETRO_LANGUAGE_ITALIAN */ + +/* RETRO_LANGUAGE_DUTCH */ + +/* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ + +/* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ + +/* RETRO_LANGUAGE_RUSSIAN */ + +/* RETRO_LANGUAGE_KOREAN */ + +/* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ + +/* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ + +/* RETRO_LANGUAGE_ESPERANTO */ + +/* RETRO_LANGUAGE_POLISH */ + +/* RETRO_LANGUAGE_VIETNAMESE */ + +/* RETRO_LANGUAGE_ARABIC */ + +/* RETRO_LANGUAGE_GREEK */ + +/* RETRO_LANGUAGE_TURKISH */ + +/* RETRO_LANGUAGE_SLOVAK */ + +/* RETRO_LANGUAGE_PERSIAN */ + +/* RETRO_LANGUAGE_HEBREW */ + +/* RETRO_LANGUAGE_ASTURIAN */ + +/* RETRO_LANGUAGE_FINNISH */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libretro/platform.c b/libretro/platform.c index 060760b..2b3f479 100644 --- a/libretro/platform.c +++ b/libretro/platform.c @@ -37,22 +37,32 @@ #include "screen.h" #include "colours.h" #include "ui.h" - -extern char Key_Sate[512]; - #include "libretro-core.h" #include "libretro.h" #include "retroscreen.h" +#define RETRO_DEVICE_ATARI_KEYBOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_KEYBOARD, 0) +#define RETRO_DEVICE_ATARI_JOYSTICK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1) +#define RETRO_DEVICE_ATARI_5200_JOYSTICK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) + +extern char Key_State[512]; +extern int SHIFTON; +extern int CTRLON; extern int UI_is_active; +extern int SHOWKEY, SHOWKEYDELAY; +extern int atari800_f10; static int swap_joysticks = FALSE; int PLATFORM_kbd_joy_0_enabled = TRUE; /* enabled by default, doesn't hurt */ int PLATFORM_kbd_joy_1_enabled = TRUE;//FALSE; /* disabled, would steal normal keys */ int PLATFORM_kbd_joy_2_enabled = TRUE;//FALSE; /* disabled, would steal normal keys */ int PLATFORM_kbd_joy_3_enabled = TRUE;//FALSE; /* disabled, would steal normal keys */ + extern unsigned char MXjoy[4]; // joy -extern int mbt[16]; +extern int mbt[4][16]; +extern unsigned atari_devices[4]; +extern int paddle_mode; + extern int retro_sound_finalized; int CURRENT_TV=Atari800_TV_PAL; @@ -162,44 +172,47 @@ static int key_control = 0; int PLATFORM_Keyboard(void) { int shiftctrl = 0; + int whichButton = 0; UI_alt_function = -1; - if (Key_Sate[RETROK_LALT]){ + if (Key_State[RETROK_LALT]){ - if (Key_Sate[RETROK_r]) + if (Key_State[RETROK_r]) UI_alt_function = UI_MENU_RUN; - else if (Key_Sate[RETROK_y]) + else if (Key_State[RETROK_y]) UI_alt_function = UI_MENU_SYSTEM; - else if (Key_Sate[RETROK_o]) + else if (Key_State[RETROK_o]) UI_alt_function = UI_MENU_SOUND; - else if (Key_Sate[RETROK_w]) + else if (Key_State[RETROK_w]) UI_alt_function = UI_MENU_SOUND_RECORDING; - else if (Key_Sate[RETROK_a]) + else if (Key_State[RETROK_a]) UI_alt_function = UI_MENU_ABOUT; - else if (Key_Sate[RETROK_s]) + else if (Key_State[RETROK_s]) UI_alt_function = UI_MENU_SAVESTATE; - else if (Key_Sate[RETROK_d]) + else if (Key_State[RETROK_d]) UI_alt_function = UI_MENU_DISK; - else if (Key_Sate[RETROK_l]) + else if (Key_State[RETROK_l]) UI_alt_function = UI_MENU_LOADSTATE; - else if (Key_Sate[RETROK_c]) + else if (Key_State[RETROK_c]) UI_alt_function = UI_MENU_CARTRIDGE; - else if (Key_Sate[RETROK_t]) + else if (Key_State[RETROK_t]) UI_alt_function = UI_MENU_CASSETTE; - else if (Key_Sate[RETROK_BACKSLASH]) + else if (Key_State[RETROK_BACKSLASH]) return AKEY_PBI_BB_MENU; } /* SHIFT STATE */ - if ((Key_Sate[RETROK_LSHIFT]) || (Key_Sate[RETROK_RSHIFT])) + //if ((Key_State[RETROK_LSHIFT]) || (Key_State[RETROK_RSHIFT])) + if (SHIFTON == 1) INPUT_key_shift = 1; else INPUT_key_shift = 0; /* CONTROL STATE */ - if ((Key_Sate[RETROK_LCTRL]) || (Key_Sate[RETROK_RCTRL])) + //if ((Key_State[RETROK_LCTRL]) || (Key_State[RETROK_RCTRL])) + if (CTRLON == 1) key_control = 1; else key_control = 0; @@ -208,28 +221,22 @@ int PLATFORM_Keyboard(void) /* OPTION / SELECT / START keys */ INPUT_key_consol = INPUT_CONSOL_NONE; - if (Key_Sate[RETROK_F2]) + if (Key_State[RETROK_F2]) INPUT_key_consol &= (~INPUT_CONSOL_OPTION); - if (Key_Sate[RETROK_F3]) + if (Key_State[RETROK_F3]) INPUT_key_consol &= (~INPUT_CONSOL_SELECT); - if (Key_Sate[RETROK_F4]) + if (Key_State[RETROK_F4]) INPUT_key_consol &= (~INPUT_CONSOL_START); /* Handle movement and special keys. */ - if (Key_Sate[RETROK_F1])return AKEY_UI; + if ((!atari800_f10 && Key_State[RETROK_F1]) || (atari800_f10 && Key_State[RETROK_F10])) + return AKEY_UI; - if (Key_Sate[RETROK_F5]) + if (Key_State[RETROK_F5] && (Atari800_machine_type != Atari800_MACHINE_5200)) return INPUT_key_shift ? AKEY_COLDSTART : AKEY_WARMSTART; - if (Key_Sate[RETROK_F8]){ - UI_alt_function = UI_MENU_MONITOR; - } - - if (Key_Sate[RETROK_F9])return AKEY_EXIT; - - if (Key_Sate[RETROK_F10])return INPUT_key_shift ? AKEY_SCREENSHOT_INTERLACE : AKEY_SCREENSHOT; - if (Key_Sate[RETROK_F12])return AKEY_TURBO; + if (Key_State[RETROK_F12]) return AKEY_TURBO; if (UI_alt_function != -1) { return AKEY_UI; @@ -238,69 +245,131 @@ int PLATFORM_Keyboard(void) if (INPUT_key_shift) shiftctrl ^= AKEY_SHFT; - if (Atari800_machine_type == Atari800_MACHINE_5200 && !UI_is_active) { + // Atari 5200 specific. Don't accept joypad input when UI is active. or virtual keyboard is active. + if (Atari800_machine_type == Atari800_MACHINE_5200 && !UI_is_active) + { + INPUT_key_shift = 0; - if (MXjoy[0]&0x40) { /* 2nd action button */ - INPUT_key_shift = 1; + if (SHOWKEYDELAY) + SHOWKEYDELAY--; + + /* Don't accept joypad input when virtual keyboard is active */ + for (int i = 0; i < 4; i++) + { + if (SHOWKEY == -1) + { + //if (MXjoy[0]&0x40) { + /* 2nd action button */ + if (atari_devices[i] == RETRO_DEVICE_ATARI_JOYSTICK) + whichButton = RETRO_DEVICE_ID_JOYPAD_X; + else if (atari_devices[i] == RETRO_DEVICE_ATARI_5200_JOYSTICK) + whichButton = RETRO_DEVICE_ID_JOYPAD_A; + else if (atari_devices[i] == RETRO_DEVICE_ATARI_KEYBOARD && (Key_State[RETROK_RCTRL])) + INPUT_key_shift = 1; + + if (mbt[i][whichButton]) { + INPUT_key_shift = 1; + break; + } + + /* shared between ATARI_JOYSTICK and ATARI_5200*/ + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_START]) + return AKEY_5200_START ^ shiftctrl; + + /* only Hash # and Asterick * */ + if (atari_devices[i] == RETRO_DEVICE_ATARI_JOYSTICK) + { + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_SELECT]) return AKEY_5200_HASH ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L]) return AKEY_5200_ASTERISK ^ shiftctrl; + } + /* We map most all keys. Only number keys done are 0-4. This might change */ + /* Not a big fan of this method. Likely creates issues on 2 or more player games. */ + /* But testing seems to show otherwise. Maybe OR the values and then return the result */ + else if (atari_devices[i] == RETRO_DEVICE_ATARI_5200_JOYSTICK) + { + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_Y]) return AKEY_5200_HASH ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_X]) return AKEY_5200_ASTERISK ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_SELECT]) return AKEY_5200_PAUSE ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L]) return AKEY_5200_0 ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_R]) return AKEY_5200_1 ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L2]) return AKEY_5200_2 ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_R2]) return AKEY_5200_3 ^ shiftctrl; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L3]) return AKEY_5200_7 ^ shiftctrl; + } + } + + if (atari_devices[i] == RETRO_DEVICE_ATARI_JOYSTICK) + whichButton = RETRO_DEVICE_ID_JOYPAD_L3; + else if (atari_devices[i] == RETRO_DEVICE_ATARI_5200_JOYSTICK) + whichButton = RETRO_DEVICE_ID_JOYPAD_R3; + + if (mbt[i][whichButton]) + if (!SHOWKEYDELAY) + { + SHOWKEY = -SHOWKEY; + SHOWKEYDELAY = 20; + } } - else { - INPUT_key_shift = 0; - } - - if (mbt[RETRO_DEVICE_ID_JOYPAD_START]) - return AKEY_5200_START ^ shiftctrl; - - if (Key_Sate[RETROK_F4]) - return AKEY_5200_START ^ shiftctrl; - - if(Key_Sate[RETROK_p])return AKEY_5200_PAUSE ^ shiftctrl; - if(Key_Sate[RETROK_r])return AKEY_5200_RESET ^ shiftctrl; - if(Key_Sate[RETROK_0])return AKEY_5200_0 ^ shiftctrl; - if(Key_Sate[RETROK_1])return AKEY_5200_1 ^ shiftctrl; - if(Key_Sate[RETROK_2])return AKEY_5200_2 ^ shiftctrl; - if(Key_Sate[RETROK_3])return AKEY_5200_3 ^ shiftctrl; - if(Key_Sate[RETROK_4])return AKEY_5200_4 ^ shiftctrl; - if(Key_Sate[RETROK_5])return AKEY_5200_5 ^ shiftctrl; - if(Key_Sate[RETROK_6])return AKEY_5200_6 ^ shiftctrl; - if(Key_Sate[RETROK_7])return AKEY_5200_7 ^ shiftctrl; - if(Key_Sate[RETROK_8])return AKEY_5200_8 ^ shiftctrl; - if(Key_Sate[RETROK_9])return AKEY_5200_9 ^ shiftctrl; - if(Key_Sate[RETROK_HASH])return AKEY_5200_HASH ^ shiftctrl; - if(Key_Sate[RETROK_EQUALS])return AKEY_5200_HASH ^ shiftctrl; - if(Key_Sate[RETROK_ASTERISK])return AKEY_5200_ASTERISK ^ shiftctrl; - if(Key_Sate[RETROK_KP_MULTIPLY])return AKEY_5200_ASTERISK ^ shiftctrl; + /* keyboard mapped to 5200 controls*/ + if (Key_State[RETROK_F4]) return AKEY_5200_START ^ shiftctrl; + if (Key_State[RETROK_p]) return AKEY_5200_PAUSE ^ shiftctrl; + if (Key_State[RETROK_r]) return AKEY_5200_RESET ^ shiftctrl; + if (Key_State[RETROK_0]) return AKEY_5200_0 ^ shiftctrl; + if (Key_State[RETROK_1]) return AKEY_5200_1 ^ shiftctrl; + if (Key_State[RETROK_2]) return AKEY_5200_2 ^ shiftctrl; + if (Key_State[RETROK_3]) return AKEY_5200_3 ^ shiftctrl; + if (Key_State[RETROK_4]) return AKEY_5200_4 ^ shiftctrl; + if (Key_State[RETROK_5]) return AKEY_5200_5 ^ shiftctrl; + if (Key_State[RETROK_6]) return AKEY_5200_6 ^ shiftctrl; + if (Key_State[RETROK_7]) return AKEY_5200_7 ^ shiftctrl; + if (Key_State[RETROK_8]) return AKEY_5200_8 ^ shiftctrl; + if (Key_State[RETROK_9]) return AKEY_5200_9 ^ shiftctrl; + if (Key_State[RETROK_HASH]) return AKEY_5200_HASH ^ shiftctrl; + if (Key_State[RETROK_EQUALS]) return AKEY_5200_HASH ^ shiftctrl; + if (Key_State[RETROK_ASTERISK]) return AKEY_5200_ASTERISK ^ shiftctrl; + if (Key_State[RETROK_KP_MULTIPLY]) return AKEY_5200_ASTERISK ^ shiftctrl; + + /* virtual keyboard mapped to 5200 controls */ + if (Key_State[RETROK_F5]) + return AKEY_5200_RESET ^ shiftctrl; + + if (Key_State[RETROK_F7]) + { + SHOWKEY = -1; + SHOWKEYDELAY = 20; + return AKEY_UI; + } return AKEY_NONE; } //else if (Atari800_machine_type != Atari800_MACHINE_5200 && !UI_is_active) -{ if (key_control) shiftctrl ^= AKEY_CTRL; - if (Key_Sate[RETROK_BACKQUOTE] || Key_Sate[RETROK_LSUPER] ) + if (Key_State[RETROK_BACKQUOTE] || Key_State[RETROK_LSUPER] ) return AKEY_ATARI ^ shiftctrl; - if (Key_Sate[RETROK_RSUPER] ){ + if (Key_State[RETROK_RSUPER] ){ if (INPUT_key_shift) return AKEY_CAPSLOCK; else return AKEY_CAPSTOGGLE; } - if (Key_Sate[RETROK_END] || Key_Sate[RETROK_F6] ) + if (Key_State[RETROK_END] || Key_State[RETROK_F6] ) return AKEY_HELP ^ shiftctrl; - if (Key_Sate[RETROK_PAGEDOWN]) + if (Key_State[RETROK_PAGEDOWN]) return AKEY_F2 | AKEY_SHFT; - if (Key_Sate[RETROK_PAGEUP]) + if (Key_State[RETROK_PAGEUP]) return AKEY_F1 | AKEY_SHFT; - if (Key_Sate[RETROK_HOME]) + if (Key_State[RETROK_HOME]) return key_control ? AKEY_LESS|shiftctrl : AKEY_CLEAR; - if (Key_Sate[RETROK_PAUSE] || Key_Sate[RETROK_F7] ) + if (Key_State[RETROK_PAUSE]) { if (BINLOAD_wait_active) { BINLOAD_pause_loading = TRUE; @@ -309,45 +378,51 @@ int PLATFORM_Keyboard(void) else return AKEY_BREAK; } - if (Key_Sate[RETROK_CAPSLOCK]){ + if (Key_State[RETROK_CAPSLOCK]){ if (INPUT_key_shift) return AKEY_CAPSLOCK|shiftctrl; else return AKEY_CAPSTOGGLE|shiftctrl; } - if (Key_Sate[RETROK_SPACE]) + if (Key_State[RETROK_SPACE]) return AKEY_SPACE ^ shiftctrl; - if (Key_Sate[RETROK_BACKSPACE]) - return AKEY_BACKSPACE|shiftctrl; + if (Key_State[RETROK_BACKSPACE]){ + if (INPUT_key_shift) + return AKEY_DELETE_CHAR; + else if (key_control) + return AKEY_DELETE_LINE; + else + return AKEY_BACKSPACE; + } - if (Key_Sate[RETROK_RETURN]) + if (Key_State[RETROK_RETURN]) return AKEY_RETURN ^ shiftctrl; - if (Key_Sate[RETROK_LEFT]) + if (Key_State[RETROK_LEFT]) return (!UI_is_active && Atari800_f_keys ? AKEY_F3 : (INPUT_key_shift ? AKEY_PLUS : AKEY_LEFT)) ^ shiftctrl; - if (Key_Sate[RETROK_RIGHT]) + if (Key_State[RETROK_RIGHT]) return (!UI_is_active && Atari800_f_keys ? AKEY_F4 : (INPUT_key_shift ? AKEY_ASTERISK : AKEY_RIGHT)) ^ shiftctrl; - if (Key_Sate[RETROK_UP]) + if (Key_State[RETROK_UP]) return (!UI_is_active && Atari800_f_keys ? AKEY_F1 : (INPUT_key_shift ? AKEY_MINUS : AKEY_UP)) ^ shiftctrl; - if (Key_Sate[RETROK_DOWN]) + if (Key_State[RETROK_DOWN]) return (!UI_is_active && Atari800_f_keys ? AKEY_F2 : (INPUT_key_shift ? AKEY_EQUAL : AKEY_DOWN)) ^ shiftctrl; - if (Key_Sate[RETROK_ESCAPE]) + if (Key_State[RETROK_ESCAPE]) return AKEY_ESCAPE ^ shiftctrl; - if (Key_Sate[RETROK_TAB]) + if (Key_State[RETROK_TAB]) return AKEY_TAB ^ shiftctrl; - if (Key_Sate[RETROK_DELETE]){ + if (Key_State[RETROK_DELETE]){ if (INPUT_key_shift) return AKEY_DELETE_LINE|shiftctrl; else return AKEY_DELETE_CHAR; } - if (Key_Sate[RETROK_INSERT]){ + if (Key_State[RETROK_INSERT]){ if (INPUT_key_shift) return AKEY_INSERT_LINE|shiftctrl; else @@ -355,263 +430,315 @@ int PLATFORM_Keyboard(void) } if (INPUT_cx85){ - - if (Key_Sate[RETROK_KP1]) - return AKEY_CX85_1; - else if (Key_Sate[RETROK_KP2]) - return AKEY_CX85_2; - else if (Key_Sate[RETROK_KP2]) - return AKEY_CX85_3; - else if (Key_Sate[RETROK_KP3]) - return AKEY_CX85_4; - else if (Key_Sate[RETROK_KP4]) - return AKEY_CX85_5; - else if (Key_Sate[RETROK_KP5]) - return AKEY_CX85_6; - else if (Key_Sate[RETROK_KP6]) - return AKEY_CX85_7; - else if (Key_Sate[RETROK_KP7]) - return AKEY_CX85_8; - else if (Key_Sate[RETROK_KP8]) - return AKEY_CX85_9; - else if (Key_Sate[RETROK_KP9]) - return AKEY_CX85_0; - else if (Key_Sate[RETROK_KP0]) - return AKEY_CX85_2; - else if (Key_Sate[RETROK_KP_PERIOD]) - return AKEY_CX85_PERIOD; - else if (Key_Sate[RETROK_KP_MINUS]) - return AKEY_CX85_MINUS; - else if (Key_Sate[RETROK_KP_ENTER]) - return AKEY_CX85_PLUS_ENTER; - else if (Key_Sate[RETROK_KP_DIVIDE]) - return (key_control ? AKEY_CX85_ESCAPE : AKEY_CX85_NO); - else if (Key_Sate[RETROK_KP_MULTIPLY]) - return AKEY_CX85_DELETE; - else if (Key_Sate[RETROK_KP_PLUS]) - return AKEY_CX85_YES; + if (Key_State[RETROK_KP1]) return AKEY_CX85_1; + else if (Key_State[RETROK_KP2]) return AKEY_CX85_2; + else if (Key_State[RETROK_KP2]) return AKEY_CX85_3; + else if (Key_State[RETROK_KP3]) return AKEY_CX85_4; + else if (Key_State[RETROK_KP4]) return AKEY_CX85_5; + else if (Key_State[RETROK_KP5]) return AKEY_CX85_6; + else if (Key_State[RETROK_KP6]) return AKEY_CX85_7; + else if (Key_State[RETROK_KP7]) return AKEY_CX85_8; + else if (Key_State[RETROK_KP8]) return AKEY_CX85_9; + else if (Key_State[RETROK_KP9]) return AKEY_CX85_0; + else if (Key_State[RETROK_KP0]) return AKEY_CX85_2; + else if (Key_State[RETROK_KP_PERIOD]) return AKEY_CX85_PERIOD; + else if (Key_State[RETROK_KP_MINUS]) return AKEY_CX85_MINUS; + else if (Key_State[RETROK_KP_ENTER]) return AKEY_CX85_PLUS_ENTER; + else if (Key_State[RETROK_KP_DIVIDE]) return (key_control ? AKEY_CX85_ESCAPE : AKEY_CX85_NO); + else if (Key_State[RETROK_KP_MULTIPLY]) return AKEY_CX85_DELETE; + else if (Key_State[RETROK_KP_PLUS]) return AKEY_CX85_YES; } /* Handle CTRL-0 to CTRL-9 and other control characters */ if (key_control) { - if (Key_Sate[RETROK_PERIOD]) - return AKEY_FULLSTOP|shiftctrl; - if (Key_Sate[RETROK_COMMA]) - return AKEY_COMMA|shiftctrl; - if (Key_Sate[RETROK_SEMICOLON]) - return AKEY_SEMICOLON|shiftctrl; - if (Key_Sate[RETROK_SLASH]) - return AKEY_SLASH|shiftctrl; - if (Key_Sate[RETROK_BACKSLASH]) - return AKEY_ESCAPE|shiftctrl; - if (Key_Sate[RETROK_0]) - return AKEY_CTRL_0|shiftctrl; - if (Key_Sate[RETROK_1]) - return AKEY_CTRL_1|shiftctrl; - if (Key_Sate[RETROK_2]) - return AKEY_CTRL_2|shiftctrl; - if (Key_Sate[RETROK_3]) - return AKEY_CTRL_3|shiftctrl; - if (Key_Sate[RETROK_4]) - return AKEY_CTRL_4|shiftctrl; - if (Key_Sate[RETROK_5]) - return AKEY_CTRL_5|shiftctrl; - if (Key_Sate[RETROK_6]) - return AKEY_CTRL_6|shiftctrl; - if (Key_Sate[RETROK_7]) - return AKEY_CTRL_7|shiftctrl; - if (Key_Sate[RETROK_8]) - return AKEY_CTRL_8|shiftctrl; - if (Key_Sate[RETROK_9]) - return AKEY_CTRL_9|shiftctrl; - - if (Key_Sate[RETROK_a])return AKEY_CTRL_a; - if (Key_Sate[RETROK_b])return AKEY_CTRL_b; - if (Key_Sate[RETROK_c])return AKEY_CTRL_c; - if (Key_Sate[RETROK_d])return AKEY_CTRL_d; - if (Key_Sate[RETROK_e])return AKEY_CTRL_e; - if (Key_Sate[RETROK_f])return AKEY_CTRL_f; - if (Key_Sate[RETROK_g])return AKEY_CTRL_g; - if (Key_Sate[RETROK_h])return AKEY_CTRL_h; - if (Key_Sate[RETROK_i])return AKEY_CTRL_i; - if (Key_Sate[RETROK_j])return AKEY_CTRL_j; - if (Key_Sate[RETROK_k])return AKEY_CTRL_k; - if (Key_Sate[RETROK_l])return AKEY_CTRL_l; - if (Key_Sate[RETROK_m])return AKEY_CTRL_m; - if (Key_Sate[RETROK_n])return AKEY_CTRL_n; - if (Key_Sate[RETROK_o])return AKEY_CTRL_o; - if (Key_Sate[RETROK_p])return AKEY_CTRL_p; - if (Key_Sate[RETROK_q])return AKEY_CTRL_q; - if (Key_Sate[RETROK_r])return AKEY_CTRL_r; - if (Key_Sate[RETROK_s])return AKEY_CTRL_s; - if (Key_Sate[RETROK_t])return AKEY_CTRL_t; - if (Key_Sate[RETROK_u])return AKEY_CTRL_u; - if (Key_Sate[RETROK_v])return AKEY_CTRL_v; - if (Key_Sate[RETROK_w])return AKEY_CTRL_w; - if (Key_Sate[RETROK_x])return AKEY_CTRL_x; - if (Key_Sate[RETROK_y])return AKEY_CTRL_y; - if (Key_Sate[RETROK_z])return AKEY_CTRL_z; + if (Key_State[RETROK_PERIOD]) return AKEY_FULLSTOP|shiftctrl; + if (Key_State[RETROK_COMMA]) return AKEY_COMMA|shiftctrl; + if (Key_State[RETROK_SEMICOLON]) return AKEY_SEMICOLON|shiftctrl; + if (Key_State[RETROK_SLASH]) return AKEY_SLASH|shiftctrl; + if (Key_State[RETROK_BACKSLASH]) return AKEY_ESCAPE|shiftctrl; + if (Key_State[RETROK_0]) return AKEY_CTRL_0|shiftctrl; + if (Key_State[RETROK_1]) return AKEY_CTRL_1|shiftctrl; + if (Key_State[RETROK_2]) return AKEY_CTRL_2|shiftctrl; + if (Key_State[RETROK_3]) return AKEY_CTRL_3|shiftctrl; + if (Key_State[RETROK_4]) return AKEY_CTRL_4|shiftctrl; + if (Key_State[RETROK_5]) return AKEY_CTRL_5|shiftctrl; + if (Key_State[RETROK_6]) return AKEY_CTRL_6|shiftctrl; + if (Key_State[RETROK_7]) return AKEY_CTRL_7|shiftctrl; + if (Key_State[RETROK_8]) return AKEY_CTRL_8|shiftctrl; + if (Key_State[RETROK_9]) return AKEY_CTRL_9|shiftctrl; + + if (Key_State[RETROK_a]) return AKEY_CTRL_a; + if (Key_State[RETROK_b]) return AKEY_CTRL_b; + if (Key_State[RETROK_c]) return AKEY_CTRL_c; + if (Key_State[RETROK_d]) return AKEY_CTRL_d; + if (Key_State[RETROK_e]) return AKEY_CTRL_e; + if (Key_State[RETROK_f]) return AKEY_CTRL_f; + if (Key_State[RETROK_g]) return AKEY_CTRL_g; + if (Key_State[RETROK_h]) return AKEY_CTRL_h; + if (Key_State[RETROK_i]) return AKEY_CTRL_i; + if (Key_State[RETROK_j]) return AKEY_CTRL_j; + if (Key_State[RETROK_k]) return AKEY_CTRL_k; + if (Key_State[RETROK_l]) return AKEY_CTRL_l; + if (Key_State[RETROK_m]) return AKEY_CTRL_m; + if (Key_State[RETROK_n]) return AKEY_CTRL_n; + if (Key_State[RETROK_o]) return AKEY_CTRL_o; + if (Key_State[RETROK_p]) return AKEY_CTRL_p; + if (Key_State[RETROK_q]) return AKEY_CTRL_q; + if (Key_State[RETROK_r]) return AKEY_CTRL_r; + if (Key_State[RETROK_s]) return AKEY_CTRL_s; + if (Key_State[RETROK_t]) return AKEY_CTRL_t; + if (Key_State[RETROK_u]) return AKEY_CTRL_u; + if (Key_State[RETROK_v]) return AKEY_CTRL_v; + if (Key_State[RETROK_w]) return AKEY_CTRL_w; + if (Key_State[RETROK_x]) return AKEY_CTRL_x; + if (Key_State[RETROK_y]) return AKEY_CTRL_y; + if (Key_State[RETROK_z]) return AKEY_CTRL_z; /* these three keys also type control-graphics characters, but there don't seem to be AKEY_ values for them! */ - if (Key_Sate[RETROK_COMMA])return (AKEY_CTRL | AKEY_COMMA); - if (Key_Sate[RETROK_PERIOD])return (AKEY_CTRL | AKEY_FULLSTOP); - if (Key_Sate[RETROK_SEMICOLON])return (AKEY_CTRL | AKEY_SEMICOLON); - + if (Key_State[RETROK_COMMA]) return (AKEY_CTRL | AKEY_COMMA); + if (Key_State[RETROK_PERIOD]) return (AKEY_CTRL | AKEY_FULLSTOP); + if (Key_State[RETROK_SEMICOLON]) return (AKEY_CTRL | AKEY_SEMICOLON); + + if (Key_State[RETROK_F7]) return (AKEY_CTRL | AKEY_F1); + if (Key_State[RETROK_F8]) return (AKEY_CTRL | AKEY_F2); + if (Key_State[RETROK_F9]) return (AKEY_CTRL | AKEY_F3); + if (Key_State[RETROK_F10]) return (AKEY_CTRL | AKEY_F4); + + // cursor keys + if (Key_State[RETROK_PLUS]) return AKEY_LEFT; + if (Key_State[RETROK_ASTERISK]) return AKEY_RIGHT; + if (Key_State[RETROK_EQUALS]) return AKEY_DOWN; + if (Key_State[RETROK_UNDERSCORE]) return AKEY_UP; } /* handle all keys */ if (INPUT_key_shift) { - if (Key_Sate[RETROK_a])return AKEY_A; - if (Key_Sate[RETROK_b])return AKEY_B; - if (Key_Sate[RETROK_c])return AKEY_C; - if (Key_Sate[RETROK_d])return AKEY_D; - if (Key_Sate[RETROK_e])return AKEY_E; - if (Key_Sate[RETROK_f])return AKEY_F; - if (Key_Sate[RETROK_g])return AKEY_G; - if (Key_Sate[RETROK_h])return AKEY_H; - if (Key_Sate[RETROK_i])return AKEY_I; - if (Key_Sate[RETROK_j])return AKEY_J; - if (Key_Sate[RETROK_k])return AKEY_K; - if (Key_Sate[RETROK_l])return AKEY_L; - if (Key_Sate[RETROK_m])return AKEY_M; - if (Key_Sate[RETROK_n])return AKEY_N; - if (Key_Sate[RETROK_o])return AKEY_O; - if (Key_Sate[RETROK_p])return AKEY_P; - if (Key_Sate[RETROK_q])return AKEY_Q; - if (Key_Sate[RETROK_r])return AKEY_R; - if (Key_Sate[RETROK_s])return AKEY_S; - if (Key_Sate[RETROK_t])return AKEY_T; - if (Key_Sate[RETROK_u])return AKEY_U; - if (Key_Sate[RETROK_v])return AKEY_V; - if (Key_Sate[RETROK_w])return AKEY_W; - if (Key_Sate[RETROK_x])return AKEY_X; - if (Key_Sate[RETROK_y])return AKEY_Y; - if (Key_Sate[RETROK_z])return AKEY_Z; - - if (Key_Sate[RETROK_1])return AKEY_EXCLAMATION; - if (Key_Sate[RETROK_2])return AKEY_AT; - if (Key_Sate[RETROK_3])return AKEY_HASH; - if (Key_Sate[RETROK_4])return AKEY_DOLLAR; - if (Key_Sate[RETROK_5])return AKEY_PERCENT; - if (Key_Sate[RETROK_6])return AKEY_CARET; - if (Key_Sate[RETROK_7])return AKEY_AMPERSAND; - if (Key_Sate[RETROK_8])return AKEY_ASTERISK; - if (Key_Sate[RETROK_9])return AKEY_PARENLEFT; - if (Key_Sate[RETROK_0])return AKEY_PARENRIGHT; - - if (Key_Sate[RETROK_BACKSLASH])return AKEY_BAR; - if (Key_Sate[RETROK_COMMA])return AKEY_LESS; - if (Key_Sate[RETROK_PERIOD])return AKEY_GREATER; - if (Key_Sate[RETROK_MINUS])return AKEY_UNDERSCORE; - if (Key_Sate[RETROK_EQUALS])return AKEY_PLUS; - if (Key_Sate[RETROK_LEFTBRACKET])return AKEY_BRACKETLEFT; // no curly braces on Atari - if (Key_Sate[RETROK_RIGHTBRACKET])return AKEY_BRACKETRIGHT; // no curly braces on Atari - if (Key_Sate[RETROK_SEMICOLON])return AKEY_COLON; - if (Key_Sate[RETROK_QUOTE])return AKEY_DBLQUOTE; - if (Key_Sate[RETROK_SLASH])return AKEY_QUESTION; + if (Key_State[RETROK_a]) return AKEY_A; + if (Key_State[RETROK_b]) return AKEY_B; + if (Key_State[RETROK_c]) return AKEY_C; + if (Key_State[RETROK_d]) return AKEY_D; + if (Key_State[RETROK_e]) return AKEY_E; + if (Key_State[RETROK_f]) return AKEY_F; + if (Key_State[RETROK_g]) return AKEY_G; + if (Key_State[RETROK_h]) return AKEY_H; + if (Key_State[RETROK_i]) return AKEY_I; + if (Key_State[RETROK_j]) return AKEY_J; + if (Key_State[RETROK_k]) return AKEY_K; + if (Key_State[RETROK_l]) return AKEY_L; + if (Key_State[RETROK_m]) return AKEY_M; + if (Key_State[RETROK_n]) return AKEY_N; + if (Key_State[RETROK_o]) return AKEY_O; + if (Key_State[RETROK_p]) return AKEY_P; + if (Key_State[RETROK_q]) return AKEY_Q; + if (Key_State[RETROK_r]) return AKEY_R; + if (Key_State[RETROK_s]) return AKEY_S; + if (Key_State[RETROK_t]) return AKEY_T; + if (Key_State[RETROK_u]) return AKEY_U; + if (Key_State[RETROK_v]) return AKEY_V; + if (Key_State[RETROK_w]) return AKEY_W; + if (Key_State[RETROK_x]) return AKEY_X; + if (Key_State[RETROK_y]) return AKEY_Y; + if (Key_State[RETROK_z]) return AKEY_Z; + + if (Key_State[RETROK_1]) return AKEY_EXCLAMATION; + if (Key_State[RETROK_2]) return AKEY_DBLQUOTE; + if (Key_State[RETROK_3]) return AKEY_HASH; + if (Key_State[RETROK_4]) return AKEY_DOLLAR; + if (Key_State[RETROK_5]) return AKEY_PERCENT; + if (Key_State[RETROK_6]) return AKEY_AMPERSAND; + if (Key_State[RETROK_7]) return AKEY_QUOTE; + if (Key_State[RETROK_8]) return AKEY_AT; + if (Key_State[RETROK_9]) return AKEY_PARENLEFT; + if (Key_State[RETROK_0]) return AKEY_PARENRIGHT; + + if (Key_State[RETROK_BACKSLASH]) return AKEY_BAR; + if (Key_State[RETROK_COMMA]) return AKEY_BRACKETLEFT; + if (Key_State[RETROK_PERIOD]) return AKEY_BRACKETRIGHT; + if (Key_State[RETROK_UNDERSCORE]) return AKEY_MINUS; + if (Key_State[RETROK_PLUS]) return AKEY_BACKSLASH; + if (Key_State[RETROK_EQUALS]) return AKEY_BAR; + if (Key_State[RETROK_LEFTBRACKET]) return AKEY_BRACKETLEFT; // no curly braces on Atari + if (Key_State[RETROK_RIGHTBRACKET]) return AKEY_BRACKETRIGHT; // no curly braces on Atari + if (Key_State[RETROK_SEMICOLON]) return AKEY_COLON; + if (Key_State[RETROK_QUOTE]) return AKEY_DBLQUOTE; + if (Key_State[RETROK_SLASH]) return AKEY_QUESTION; + if (Key_State[RETROK_ASTERISK]) return AKEY_CIRCUMFLEX; + if (Key_State[RETROK_LESS]) return AKEY_LESS; + if (Key_State[RETROK_GREATER]) return AKEY_GREATER; + + if (Key_State[RETROK_F7]) return (AKEY_SHFT | AKEY_F1); + if (Key_State[RETROK_F8]) return (AKEY_SHFT | AKEY_F2); + if (Key_State[RETROK_F9]) return (AKEY_SHFT | AKEY_F3); + if (Key_State[RETROK_F10]) return (AKEY_SHFT | AKEY_F4); } else { - if (Key_Sate[RETROK_a])return AKEY_a; - if (Key_Sate[RETROK_b])return AKEY_b; - if (Key_Sate[RETROK_c])return AKEY_c; - if (Key_Sate[RETROK_d])return AKEY_d; - if (Key_Sate[RETROK_e])return AKEY_e; - if (Key_Sate[RETROK_f])return AKEY_f; - if (Key_Sate[RETROK_g])return AKEY_g; - if (Key_Sate[RETROK_h])return AKEY_h; - if (Key_Sate[RETROK_i])return AKEY_i; - if (Key_Sate[RETROK_j])return AKEY_j; - if (Key_Sate[RETROK_k])return AKEY_k; - if (Key_Sate[RETROK_l])return AKEY_l; - if (Key_Sate[RETROK_m])return AKEY_m; - if (Key_Sate[RETROK_n])return AKEY_n; - if (Key_Sate[RETROK_o])return AKEY_o; - if (Key_Sate[RETROK_p])return AKEY_p; - if (Key_Sate[RETROK_q])return AKEY_q; - if (Key_Sate[RETROK_r])return AKEY_r; - if (Key_Sate[RETROK_s])return AKEY_s; - if (Key_Sate[RETROK_t])return AKEY_t; - if (Key_Sate[RETROK_u])return AKEY_u; - if (Key_Sate[RETROK_v])return AKEY_v; - if (Key_Sate[RETROK_w])return AKEY_w; - if (Key_Sate[RETROK_x])return AKEY_x; - if (Key_Sate[RETROK_y])return AKEY_y; - if (Key_Sate[RETROK_z])return AKEY_z; - - if (Key_Sate[RETROK_0])return AKEY_0; - if (Key_Sate[RETROK_1])return AKEY_1; - if (Key_Sate[RETROK_2])return AKEY_2; - if (Key_Sate[RETROK_3])return AKEY_3; - if (Key_Sate[RETROK_4])return AKEY_4; - if (Key_Sate[RETROK_5])return AKEY_5; - if (Key_Sate[RETROK_6])return AKEY_6; - if (Key_Sate[RETROK_7])return AKEY_7; - if (Key_Sate[RETROK_8])return AKEY_8; - if (Key_Sate[RETROK_9])return AKEY_9; - - if (Key_Sate[RETROK_BACKSLASH])return AKEY_BACKSLASH; - if (Key_Sate[RETROK_COMMA])return AKEY_COMMA; - if (Key_Sate[RETROK_PERIOD])return AKEY_FULLSTOP; - if (Key_Sate[RETROK_MINUS])return AKEY_MINUS; - if (Key_Sate[RETROK_EQUALS])return AKEY_EQUAL; - if (Key_Sate[RETROK_LEFTBRACKET])return AKEY_BRACKETLEFT; - if (Key_Sate[RETROK_RIGHTBRACKET])return AKEY_BRACKETRIGHT; - if (Key_Sate[RETROK_SEMICOLON])return AKEY_SEMICOLON; - if (Key_Sate[RETROK_QUOTE])return AKEY_QUOTE; - if (Key_Sate[RETROK_SLASH])return AKEY_SLASH; - + if (Key_State[RETROK_a]) return AKEY_a; + if (Key_State[RETROK_b]) return AKEY_b; + if (Key_State[RETROK_c]) return AKEY_c; + if (Key_State[RETROK_d]) return AKEY_d; + if (Key_State[RETROK_e]) return AKEY_e; + if (Key_State[RETROK_f]) return AKEY_f; + if (Key_State[RETROK_g]) return AKEY_g; + if (Key_State[RETROK_h]) return AKEY_h; + if (Key_State[RETROK_i]) return AKEY_i; + if (Key_State[RETROK_j]) return AKEY_j; + if (Key_State[RETROK_k]) return AKEY_k; + if (Key_State[RETROK_l]) return AKEY_l; + if (Key_State[RETROK_m]) return AKEY_m; + if (Key_State[RETROK_n]) return AKEY_n; + if (Key_State[RETROK_o]) return AKEY_o; + if (Key_State[RETROK_p]) return AKEY_p; + if (Key_State[RETROK_q]) return AKEY_q; + if (Key_State[RETROK_r]) return AKEY_r; + if (Key_State[RETROK_s]) return AKEY_s; + if (Key_State[RETROK_t]) return AKEY_t; + if (Key_State[RETROK_u]) return AKEY_u; + if (Key_State[RETROK_v]) return AKEY_v; + if (Key_State[RETROK_w]) return AKEY_w; + if (Key_State[RETROK_x]) return AKEY_x; + if (Key_State[RETROK_y]) return AKEY_y; + if (Key_State[RETROK_z]) return AKEY_z; + + if (Key_State[RETROK_0]) return AKEY_0; + if (Key_State[RETROK_1]) return AKEY_1; + if (Key_State[RETROK_2]) return AKEY_2; + if (Key_State[RETROK_3]) return AKEY_3; + if (Key_State[RETROK_4]) return AKEY_4; + if (Key_State[RETROK_5]) return AKEY_5; + if (Key_State[RETROK_6]) return AKEY_6; + if (Key_State[RETROK_7]) return AKEY_7; + if (Key_State[RETROK_8]) return AKEY_8; + if (Key_State[RETROK_9]) return AKEY_9; + + if (Key_State[RETROK_BACKSLASH]) return AKEY_BACKSLASH; + if (Key_State[RETROK_COMMA]) return AKEY_COMMA; + if (Key_State[RETROK_PERIOD]) return AKEY_FULLSTOP; + if (Key_State[RETROK_MINUS]) return AKEY_MINUS; + if (Key_State[RETROK_PLUS]) return AKEY_PLUS; + if (Key_State[RETROK_EQUALS]) return AKEY_EQUAL; + if (Key_State[RETROK_LEFTBRACKET]) return AKEY_BRACKETLEFT; + if (Key_State[RETROK_RIGHTBRACKET]) return AKEY_BRACKETRIGHT; + if (Key_State[RETROK_SEMICOLON]) return AKEY_SEMICOLON; + if (Key_State[RETROK_QUOTE]) return AKEY_QUOTE; + if (Key_State[RETROK_SLASH]) return AKEY_SLASH; + if (Key_State[RETROK_ASTERISK]) return AKEY_ASTERISK; + if (Key_State[RETROK_LESS]) return AKEY_LESS; + if (Key_State[RETROK_GREATER]) return AKEY_GREATER; + if (Key_State[RETROK_UNDERSCORE]) return AKEY_UNDERSCORE; + + if (Key_State[RETROK_F7]) return AKEY_F1; + if (Key_State[RETROK_F8]) return AKEY_F2; + if (Key_State[RETROK_F9]) return AKEY_F3; + if (Key_State[RETROK_F10]) return AKEY_F4; } /* FIXME joy bind */ + if (!UI_is_active) + { + if (SHOWKEYDELAY) + SHOWKEYDELAY--; + + for (int i = 0; i < 4; i++) + { + if (SHOWKEY == -1) + { + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_SELECT]) + INPUT_key_consol &= (~INPUT_CONSOL_SELECT); + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_START]) + INPUT_key_consol &= (~INPUT_CONSOL_START); + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L]) + INPUT_key_consol &= (~INPUT_CONSOL_OPTION); + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_R]) + return AKEY_UI; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_Y]) + return AKEY_SPACE; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L2]) + return AKEY_ESCAPE; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_X]) + return AKEY_RETURN; + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_R2]) + return AKEY_HELP; + } + + if (mbt[i][RETRO_DEVICE_ID_JOYPAD_L3]) + if (!SHOWKEYDELAY) + { + SHOWKEY = -SHOWKEY; + SHOWKEYDELAY = 20; + } + } - if (mbt[RETRO_DEVICE_ID_JOYPAD_SELECT]) - INPUT_key_consol &= (~INPUT_CONSOL_SELECT); - if (mbt[RETRO_DEVICE_ID_JOYPAD_START]) - INPUT_key_consol &= (~INPUT_CONSOL_START); - if (mbt[RETRO_DEVICE_ID_JOYPAD_L]) - INPUT_key_consol &= (~INPUT_CONSOL_OPTION); - if (mbt[RETRO_DEVICE_ID_JOYPAD_R]) - return AKEY_UI; - if (mbt[RETRO_DEVICE_ID_JOYPAD_L2]) - return AKEY_SPACE; - if (mbt[RETRO_DEVICE_ID_JOYPAD_R2]) - return AKEY_ESCAPE; - if (mbt[RETRO_DEVICE_ID_JOYPAD_B]) - return AKEY_RETURN; -} + /* not quite working when controller Device Type is ATARI Keyboard.. FIXME!*/ + //if (atari_devices[0] == RETRO_DEVICE_ATARI_KEYBOARD && (Key_State[RETROK_F11])) + // if (!SHOWKEYDELAY) + // { + // SHOWKEY = -SHOWKEY; + // SHOWKEYDELAY = 20; + // Key_State[RETROK_F11] = 0; + // } + } + /* not a big fan of hard coding input.. but it helps in a pinch of one accidently unmaps the controls + and this code is only used when the UI is active */ if (UI_is_active){ - // whitout kbd in GUI - if (MXjoy[0]&0x04) + // whithout kbd in GUI + if (MXjoy[0] & 0x04) return AKEY_LEFT; - if (MXjoy[0]&0x08) + if (MXjoy[0] & 0x08) return AKEY_RIGHT; - if (MXjoy[0]&0x01) + if (MXjoy[0] & 0x01) return AKEY_UP; - if (MXjoy[0]&0x02) + if (MXjoy[0] & 0x02) return AKEY_DOWN; - if (MXjoy[0]&0x80) + if (MXjoy[0] & 0x10) return AKEY_RETURN; - if (MXjoy[0]&0x40) + if (MXjoy[0] & 0x80) return AKEY_ESCAPE; } + /* This is my alternate internal UI controls... mapped based on players controller mapping. I can't decide which is the best to use + Maybe give the player the option? */ + //if (UI_is_active) { + // for (int i = 0; i < 4; i++) + // { + // if (mbt[i][RETRO_DEVICE_ID_JOYPAD_LEFT]) + // return AKEY_LEFT; + // if (mbt[i][RETRO_DEVICE_ID_JOYPAD_RIGHT]) + // return AKEY_RIGHT; + // if (mbt[i][RETRO_DEVICE_ID_JOYPAD_UP]) + // return AKEY_UP; + // if (mbt[i][RETRO_DEVICE_ID_JOYPAD_DOWN]) + // return AKEY_DOWN; + + // if (atari_devices[i] == RETRO_DEVICE_ATARI_JOYSTICK) + // whichButton = RETRO_DEVICE_ID_JOYPAD_A; + // else if (atari_devices[i] == RETRO_DEVICE_ATARI_5200_JOYSTICK) + // whichButton = RETRO_DEVICE_ID_JOYPAD_B; + // if (mbt[i][whichButton]) + // return AKEY_RETURN; + + // if (atari_devices[i] == RETRO_DEVICE_ATARI_JOYSTICK) + // whichButton = RETRO_DEVICE_ID_JOYPAD_R2; + // else if (atari_devices[i] == RETRO_DEVICE_ATARI_5200_JOYSTICK) + // whichButton = RETRO_DEVICE_ID_JOYPAD_A; + // if (mbt[i][whichButton]) + // return AKEY_ESCAPE; + // } + //} + return AKEY_NONE; - } /* int PLATFORM_GetRawKey(void) { - input_poll_cb(); for(i=0;i<320;i++) - Key_Sate[i]=input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0,i) ? 0x80: 0; - + Key_State[i]=input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0,i) ? 0x80: 0; } */ @@ -665,45 +792,77 @@ static void get_platform_PORT(unsigned char *s0, unsigned char *s1, unsigned cha int stick0, stick1, stick2, stick3; stick0 = stick1 = stick2 = stick3 = INPUT_STICK_CENTRE; + /* only send trigger (joyleft) if paddle mode is active and trigger button pressed*/ + if (!UI_is_active && paddle_mode) + { + if (PLATFORM_kbd_joy_0_enabled) { + if ((MXjoy[0] & 0x80)) + stick0 &= INPUT_STICK_LEFT; + } + + if (PLATFORM_kbd_joy_1_enabled) { + if ((MXjoy[1] & 0x80)) + stick1 &= INPUT_STICK_LEFT; + } + + if (PLATFORM_kbd_joy_2_enabled) { + if ((MXjoy[2] & 0x80)) + stick2 &= INPUT_STICK_LEFT; + } + + if (PLATFORM_kbd_joy_3_enabled) { + if ((MXjoy[3] & 0x80)) + stick3 &= INPUT_STICK_LEFT; + } + + *s0 = stick0; + *s1 = stick1; + *s2 = stick2; + *s3 = stick3; + + /* trig is all we care about */ + return; + } + if (PLATFORM_kbd_joy_0_enabled) { - if (MXjoy[0]&0x04) + if (MXjoy[0] & 0x04) stick0 &= INPUT_STICK_LEFT; - if (MXjoy[0]&0x08) + if (MXjoy[0] & 0x08) stick0 &= INPUT_STICK_RIGHT; - if (MXjoy[0]&0x01) + if (MXjoy[0] & 0x01) stick0 &= INPUT_STICK_FORWARD; - if (MXjoy[0]&0x02) + if (MXjoy[0] & 0x02) stick0 &= INPUT_STICK_BACK; } if (PLATFORM_kbd_joy_1_enabled) { - if (MXjoy[1]&0x04) + if (MXjoy[1] & 0x04) stick1 &= INPUT_STICK_LEFT; - if (MXjoy[1]&0x08) + if (MXjoy[1] & 0x08) stick1 &= INPUT_STICK_RIGHT; - if (MXjoy[1]&0x01) + if (MXjoy[1] & 0x01) stick1 &= INPUT_STICK_FORWARD; - if (MXjoy[1]&0x02) + if (MXjoy[1] & 0x02) stick1 &= INPUT_STICK_BACK; } if (PLATFORM_kbd_joy_2_enabled) { - if (MXjoy[2]&0x04) + if (MXjoy[2] & 0x04) stick2 &= INPUT_STICK_LEFT; - if (MXjoy[2]&0x08) + if (MXjoy[2] & 0x08) stick2 &= INPUT_STICK_RIGHT; - if (MXjoy[2]&0x01) + if (MXjoy[2] & 0x01) stick2 &= INPUT_STICK_FORWARD; - if (MXjoy[2]&0x02) + if (MXjoy[2] & 0x02) stick2 &= INPUT_STICK_BACK; } if (PLATFORM_kbd_joy_3_enabled) { - if (MXjoy[3]&0x04) + if (MXjoy[3] & 0x04) stick3 &= INPUT_STICK_LEFT; - if (MXjoy[3]&0x08) + if (MXjoy[3] & 0x08) stick3 &= INPUT_STICK_RIGHT; - if (MXjoy[3]&0x01) + if (MXjoy[3] & 0x01) stick3 &= INPUT_STICK_FORWARD; - if (MXjoy[3]&0x02) + if (MXjoy[3] & 0x02) stick3 &= INPUT_STICK_BACK; } @@ -728,19 +887,19 @@ static void get_platform_TRIG(unsigned char *t0, unsigned char *t1, unsigned cha trig0 = trig1 = trig2 = trig3 = 1; if (PLATFORM_kbd_joy_0_enabled) { - trig0 = MXjoy[0]&0x80?0:1; + trig0 = MXjoy[0] & 0x80 ? 0:1; } if (PLATFORM_kbd_joy_1_enabled) { - trig1 = MXjoy[1]&0x80?0:1; + trig1 = MXjoy[1] & 0x80 ? 0:1; } if (PLATFORM_kbd_joy_2_enabled) { - trig2 = MXjoy[2]&0x80?0:1; + trig2 = MXjoy[2] & 0x80 ? 0:1; } if (PLATFORM_kbd_joy_3_enabled) { - trig3 = MXjoy[3]&0x80?0:1; + trig3 = MXjoy[3] & 0x80 ? 0:1; } if (swap_joysticks) { @@ -760,6 +919,9 @@ static void get_platform_TRIG(unsigned char *t0, unsigned char *t1, unsigned cha int PLATFORM_PORT(int num) { + if (SHOWKEY == 1 ) + return 0xff; + if (num == 0) { UBYTE a, b, c, d; get_platform_PORT(&a, &b, &c, &d); @@ -779,6 +941,10 @@ int PLATFORM_PORT(int num) int PLATFORM_TRIG(int num) { UBYTE a, b, c, d; + + if (SHOWKEY == 1) + return 0x01; + get_platform_TRIG(&a, &b, &c, &d); switch (num) { diff --git a/libretro/retro_disk_control.c b/libretro/retro_disk_control.c new file mode 100644 index 0000000..31b6d45 --- /dev/null +++ b/libretro/retro_disk_control.c @@ -0,0 +1,428 @@ +/* Copyright (C) 2018 + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "libretro.h" +#include "retro_disk_control.h" +#include "retro_strings.h" +#include "retro_utils.h" +#include "file/file_path.h" + +#include +#include +#include +#include + +/*#include +#include +#include +#include +#include +#include */ + +static void fallback_log(enum retro_log_level level, const char* fmt, ...); +static retro_log_printf_t log_cb = fallback_log; + +static void fallback_log(enum retro_log_level level, const char* fmt, ...) +{ + va_list va; + + (void)level; + + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); +} + +#define COMMENT "#" +#define M3U_SPECIAL_COMMAND "#COMMAND:" + +// Return the directory name of filename 'filename'. +static char* dirname_int(const char* filename) +{ + if (filename == NULL) + return NULL; + + // Find last separator + char* right = find_last_slash(filename); + if (right) + return strleft(filename, right - filename); + + // Not found + return NULL; +} + +static char* m3u_search_file(const char* basedir, const char* dskName) +{ + // If basedir was provided + if (basedir != NULL && !path_is_absolute(dskName)) + { + // Join basedir and dskName + char* dskPath = path_join_dup(basedir, dskName); + + // Verify if this item is a relative filename (append it to the m3u path) + if (file_exists(dskPath)) + { + // Return + return dskPath; + } + free(dskPath); + } + + // Verify if this item is an absolute pathname (or the file is in working dir) + if (file_exists(dskName)) + { + // Copy and return + return strdup(dskName); + } + + // File not found + return NULL; +} + +void dc_reset(dc_storage* dc) +{ + unsigned i; + + // Verify + if (dc == NULL) + return; + + // Clean the command + if (dc->command) + { + free(dc->command); + dc->command = NULL; + } + + // Clean the struct + for (i = 0; i < dc->count; i++) + { + free(dc->files[i]); + dc->files[i] = NULL; + free(dc->names[i]); + dc->names[i] = NULL; + + dc->types[i] = DC_IMAGE_TYPE_NONE; + } + + dc->unit = DC_IMAGE_TYPE_NONE; + dc->count = 0; + dc->index = 0; + dc->index_prev = 0; + dc->eject_state = true; + dc->replace = false; +} + +dc_storage* dc_create(void) +{ + int i; + + // Initialize the struct + dc_storage* dc = NULL; + + if ((dc = (dc_storage*)malloc(sizeof(dc_storage))) != NULL) + { + dc->unit = DC_IMAGE_TYPE_NONE; + dc->count = 0; + dc->index = 0; + dc->eject_state = true; + dc->replace = false; + dc->command = NULL; + for (i = 0; i < DC_MAX_SIZE; i++) + { + dc->files[i] = NULL; + dc->names[i] = NULL; + dc->types[i] = DC_IMAGE_TYPE_NONE; + } + } + + return dc; +} + +bool dc_add_file_int(dc_storage* dc, char* filename, char* name) +{ + /* Verify */ + if (dc == NULL) + return false; + + if (!filename || (*filename == '\0')) + return false; + + /* If max size is not exceeded */ + if (dc->count < DC_MAX_SIZE) + { + /* Add the file */ + dc->count++; + dc->files[dc->count - 1] = strdup(filename); + dc->names[dc->count - 1] = !string_is_empty(name) ? strdup(name) : NULL; + dc->types[dc->count - 1] = dc_get_image_type(filename); + + log_cb(RETRO_LOG_INFO, ">>> dc added int %s - [%s]\n", filename, name); + return true; + } + + return false; +} + +bool dc_add_file(dc_storage* dc, const char* filename) +{ + unsigned index = 0; + + /* Verify */ + if (dc == NULL || !filename || (*filename == '\0')) + return false; + + /* Dupecheck */ + for (index = 0; index < dc->count; index++) + { + if (!strcmp(dc->files[index], filename)) + { + log_cb(RETRO_LOG_INFO,"File '%s' ignored as duplicate!\n", filename); + return true; + } + } + + // Get 'name' - just the filename without extension + char name[512]; + name[0] = '\0'; + fill_pathname(name, path_basename(filename), "", sizeof(name)); + + if (!dc_add_file_int(dc, strdup(filename), strdup(name))) + return false; + + // if dc unit-type is none, get type from first image + if (dc->unit == DC_IMAGE_TYPE_NONE) + { + if (dc_get_image_type(dc->files[0]) == DC_IMAGE_TYPE_TAPE) + dc->unit = DC_IMAGE_TYPE_TAPE; + else if (dc_get_image_type(dc->files[0]) == DC_IMAGE_TYPE_FLOPPY) + dc->unit = DC_IMAGE_TYPE_FLOPPY; + else if (dc_get_image_type(dc->files[0]) == DC_IMAGE_TYPE_MEM) + dc->unit = DC_IMAGE_TYPE_MEM; + else + dc->unit = DC_IMAGE_TYPE_FLOPPY; + } + + log_cb(RETRO_LOG_INFO,">>> dc added %s - [%s] [unit %i]\n", filename, name, dc->unit); + return true; +} + +bool dc_remove_file(dc_storage* dc, int index) +{ + if (dc == NULL) + return false; + + if (index < 0 || index >= dc->count) + return false; + + // "If ptr is a null pointer, no action occurs" + free(dc->files[index]); + dc->files[index] = NULL; + free(dc->names[index]); + dc->names[index] = NULL; + dc->types[index] = DC_IMAGE_TYPE_NONE; + + // Shift all entries after index one slot up + if (index != dc->count - 1) + { + memmove(dc->files + index, dc->files + index + 1, (dc->count - 1 - index) * sizeof(dc->files[0])); + memmove(dc->names + index, dc->names + index + 1, (dc->count - 1 - index) * sizeof(dc->names[0])); + } + dc->count--; + + // Reset fliplist unit after removing last entry + if (dc->count == 0) + { + dc->unit = DC_IMAGE_TYPE_NONE; + } + + return true; +} + +int dc_replace_file(dc_storage* dc, int index, const char* filename) +{ + if (dc == NULL) + return false; + + if (index < 0 || index >= dc->count) + return false; + + // "If ptr is a null pointer, no action occurs" + free(dc->files[index]); + dc->files[index] = NULL; + free(dc->names[index]); + dc->names[index] = NULL; + dc->types[index] = DC_IMAGE_TYPE_NONE; + + if (filename == NULL) + { + dc_remove_file(dc, index); + } + else + { + dc->replace = false; + + char full_path_replace[RETRO_PATH_MAX] = { 0 }; + strncpy(full_path_replace, (char*)filename, sizeof(full_path_replace)); + + /* ZIP/M3U not implemented internally */ + if ( + strendswith(full_path_replace, "m3u") || + strendswith(full_path_replace, "zip") || + strendswith(full_path_replace, "7z") + ) + { + log_cb(RETRO_LOG_INFO,">>> dc replace %s unsupported type.\n", filename); + return false; + } + /* Single append */ + else + { + // Get 'name' - just the filename without extension + char name[512]; + name[0] = '\0'; + fill_pathname(name, path_basename(filename), "", sizeof(name)); + + /* Dupecheck */ + for (unsigned i = 0; i < dc->count - 1; i++) + { + if (!strcmp(dc->files[i], full_path_replace)) + { + dc_remove_file(dc, index); + return 2; // 2 = duplicate found + } + } + + dc->files[index] = strdup(filename); + dc->names[index] = !string_is_empty(name) ? strdup(name) : NULL; + dc->types[index] = dc_get_image_type(filename); + + log_cb(RETRO_LOG_INFO,">>> dc replace %s - %s [%u].\n", filename, name , dc->types[index] ); + } + } + + return true; +} + + +void dc_parse_m3u(dc_storage* dc, const char* m3u_file) +{ + // Verify + if (dc == NULL) + return; + + if (m3u_file == NULL) + return; + + FILE* fp = NULL; + + // Try to open the file + if ((fp = fopen(m3u_file, "r")) == NULL) + return; + + // Reset + dc_reset(dc); + + // Get the m3u base dir for resolving relative path + char* basedir = dirname_int(m3u_file); + + // Disk control interface 'name' for the following file + char* image_name = NULL; + + // Read the lines while there is line to read and we have enough space + char buffer[2048]; + while ((dc->count <= DC_MAX_SIZE) && (fgets(buffer, sizeof(buffer), fp) != NULL)) + { + char* string = trimwhitespace(buffer); + + // If it's a m3u special key or a file + if (strstartswith(string, M3U_SPECIAL_COMMAND)) + { + dc->command = strright(string, strlen(string) - strlen(M3U_SPECIAL_COMMAND)); + } + else if (!strstartswith(string, COMMENT)) + { + // Search the file (absolute, relative to m3u) + char* filename; + if ((filename = m3u_search_file(basedir, string)) != NULL) + { + + char tmp[512]; + tmp[0] = '\0'; + + fill_pathname(tmp, path_basename(filename), "", sizeof(tmp)); + image_name = strdup(tmp); + + // Add the file to the struct + dc_add_file_int(dc, filename, image_name); + image_name = NULL; + } + + } + } + + // If basedir was provided + if (basedir != NULL) + free(basedir); + + // Close the file + fclose(fp); + + if (dc->count != 0) + { + if (dc_get_image_type(dc->files[0]) == DC_IMAGE_TYPE_TAPE) + dc->unit = DC_IMAGE_TYPE_TAPE; + else if (dc_get_image_type(dc->files[0]) == DC_IMAGE_TYPE_FLOPPY) + dc->unit = DC_IMAGE_TYPE_FLOPPY; + else + dc->unit = DC_IMAGE_TYPE_FLOPPY; + + log_cb(RETRO_LOG_INFO,">>> dc (m3u) unit type: %i\n", dc->unit); + } +} + +void dc_free(dc_storage* dc) +{ + // Clean the struct + dc_reset(dc); + free(dc); + dc = NULL; + return; +} + +enum dc_image_type dc_get_image_type(const char* filename) +{ + // Missing file + if (!filename || (*filename == '\0')) + return DC_IMAGE_TYPE_NONE; + + // Floppy image + if (strendswith(filename, "atr") || + strendswith(filename, "atx") || + strendswith(filename, "xfd") || + strendswith(filename, "dcm")) + return DC_IMAGE_TYPE_FLOPPY; + + // Tape image. Removed "cdt" since it is not an Atari800 file type + if (strendswith(filename, "cas")) + return DC_IMAGE_TYPE_TAPE; + + // Fallback + return DC_IMAGE_TYPE_UNKNOWN; +} diff --git a/libretro/retro_disk_control.h b/libretro/retro_disk_control.h new file mode 100644 index 0000000..4033ca0 --- /dev/null +++ b/libretro/retro_disk_control.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * Caprice32 libretro port + * + * Copyright not6 - r-type (2015-2018) + * Copyright David Colmenero - D_Skywalk (2019-2021) + * Copyright Daniel De Matteis (2012-2021) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef RETRO_DISK_CONTROL_H__ +#define RETRO_DISK_CONTROL_H__ + +#include + +//***************************************************************************** +// Disk control structure and functions +#define DC_MAX_SIZE 20 + +//static INLINE bool string_is_empty(const char* data) +//{ +// return !data || (*data == '\0'); +//} + +enum dc_image_type { + DC_IMAGE_TYPE_NONE = 0, + DC_IMAGE_TYPE_FLOPPY, + DC_IMAGE_TYPE_TAPE, + DC_IMAGE_TYPE_MEM, + DC_IMAGE_TYPE_UNKNOWN +}; + +struct dc_storage{ + char* command; + char* files[DC_MAX_SIZE]; + char* names[DC_MAX_SIZE]; + enum dc_image_type types[DC_MAX_SIZE]; + unsigned unit; + unsigned count; + int index; + bool eject_state; + bool replace; + unsigned index_prev; +}; + +typedef struct dc_storage dc_storage; +dc_storage* dc_create(void); + +void dc_parse_m3u(dc_storage* dc, const char* m3u_file); +bool dc_add_file(dc_storage* dc, const char* filename); +void dc_free(dc_storage* dc); +void dc_reset(dc_storage* dc); +int dc_replace_file(dc_storage* dc, int index, const char* filename); +bool dc_remove_file(dc_storage* dc, int index); +enum dc_image_type dc_get_image_type(const char* filename); + +#endif diff --git a/libretro/retro_files.c b/libretro/retro_files.c new file mode 100644 index 0000000..6a94bee --- /dev/null +++ b/libretro/retro_files.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2018 + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "retro_files.h" + +#include +#include +#include + +void path_join(char* out, const char* basedir, const char* filename) +{ + snprintf(out, RETRO_PATH_MAX, "%s%s%s", basedir, RETRO_PATH_SEPARATOR, filename); +} diff --git a/libretro/retro_files.h b/libretro/retro_files.h new file mode 100644 index 0000000..4a39f94 --- /dev/null +++ b/libretro/retro_files.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2018 + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef RETRO_FILES_H__ +#define RETRO_FILES_H__ + +#include + +//***************************************************************************** +// File helpers functions +#define RETRO_PATH_MAX 512 + +#ifdef _WIN32 +#define RETRO_PATH_SEPARATOR "\\" +// Windows also support the unix path separator +#define RETRO_PATH_SEPARATOR_ALT "/" +#else +#define RETRO_PATH_SEPARATOR "/" +#endif + +void path_join(char* out, const char* basedir, const char* filename); + +#endif diff --git a/libretro/retro_strings.c b/libretro/retro_strings.c new file mode 100644 index 0000000..5d8e5f0 --- /dev/null +++ b/libretro/retro_strings.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2018 + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "retro_strings.h" + +#include +#include +#include +#include + +// Note: This function returns a pointer to a substring_left of the original string. +// If the given string was allocated dynamically, the caller must not overwrite +// that pointer with the returned value, since the original pointer must be +// deallocated using the same allocator with which it was allocated. The return +// value must NOT be deallocated using free() etc. +char* trimwhitespace(char *str) +{ + char *end; + + // Trim leading space + while(isspace((unsigned char)*str)) str++; + + if(*str == 0) // All spaces? + return str; + + // Trim trailing space + end = str + strlen(str) - 1; + while(end > str && isspace((unsigned char)*end)) end--; + + // Write new null terminator character + end[1] = '\0'; + + return str; +} + +// Returns a substring of 'str' that contains the 'len' leftmost characters of 'str'. +char* strleft(const char* str, int len) +{ + char* result = calloc(len + 1, sizeof(char)); + strncpy(result, str, len); + return result; +} + +// Returns a substring of 'str' that contains the 'len' rightmost characters of 'str'. +char* strright(const char* str, int len) +{ + int pos = strlen(str) - len; + char* result = calloc(len + 1, sizeof(char)); + strncpy(result, str + pos, len); + return result; +} + +// Returns true if 'str' starts with 'start' +bool strstartswith(const char* str, const char* start) +{ + if (strlen(str) >= strlen(start)) + if(!strncasecmp(str, start, strlen(start))) + return true; + + return false; +} + +// Returns true if 'str' ends with 'end' +bool strendswith(const char* str, const char* end) +{ + if (strlen(str) >= strlen(end)) + if(!strcasecmp((char*)&str[strlen(str)-strlen(end)], end)) + return true; + + return false; +} diff --git a/libretro/retro_strings.h b/libretro/retro_strings.h new file mode 100644 index 0000000..d4594fc --- /dev/null +++ b/libretro/retro_strings.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2018 + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef RETRO_STRINGS_H__ +#define RETRO_STRINGS_H__ + +#include + +//***************************************************************************** +// String helpers functions +char* trimwhitespace(char *str); +char* strleft(const char* str, int len); +char* strright(const char* str, int len); +bool strstartswith(const char* str, const char* start); +bool strendswith(const char* str, const char* end); + +#endif diff --git a/libretro/retro_utils.c b/libretro/retro_utils.c new file mode 100644 index 0000000..1348acf --- /dev/null +++ b/libretro/retro_utils.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * Caprice32 libretro port + * + * Copyright not6 - r-type (2015-2018) + * Copyright David Colmenero - D_Skywalk (2019-2021) + * Copyright Daniel De Matteis (2012-2021) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + + +#include +#include +#include +#include + +#include "retro_utils.h" +#ifdef VITA + #include "file/file_path.h" +#endif + +extern uint8_t* pbGPBuffer; + +// Verify file extension +bool file_check_extension(const char *filename, const size_t filename_size, const char *ext, const size_t ext_size) +{ +#ifndef __PS3__ + size_t file_len = strnlen(filename, filename_size); + size_t ext_len = strnlen(ext, ext_size); +#else + size_t file_len = strlen(filename) > filename_size ? filename_size : strlen(filename); + size_t ext_len = strlen(ext) > ext_size ? ext_size : strlen(ext); +#endif + + if( ext_len > file_len || file_len >= filename_size - 1) + return false; + + const char * file_ext = &filename[file_len - ext_len]; + + return (strncasecmp(file_ext, ext, filename_size) == 0); +} + +bool file_check_flag(const char *filename, const size_t filename_size, const char *flag, const size_t flag_size) +{ +#ifndef __PS3__ + size_t file_len = strnlen(filename, filename_size); + size_t flag_len = strnlen(flag, flag_size); +#else + size_t file_len = strlen(filename) > filename_size ? filename_size : strlen(filename); + size_t flag_len = strlen(flag) > flag_size ? flag_size : strlen(flag); +#endif + + for (int i = 0; i < file_len; i++) { + if (i + flag_len > file_len) + return false; + + if (strncasecmp(&filename[i], flag, flag_len) == 0) + return true; + } + return false; +} + +// Verify if file exists +bool file_exists(const char *filename) +{ +#ifdef VITA + if (path_is_valid(filename) && !path_is_directory(filename)) +#else + struct stat buf; + if (stat(filename, &buf) == 0 && + (buf.st_mode & (S_IRUSR|S_IWUSR)) && !(buf.st_mode & S_IFDIR)) +#endif + { + /* file points to user readable regular file */ + return true; + } + return false; +} + +int file_size (int file_num) +{ + struct stat s; + + if (!fstat(file_num, &s)) { + return s.st_size; + } else { + return 0; + } +} + +void path_join(char* out, const char* basedir, const char* filename) +{ + snprintf(out, RETRO_PATH_MAX, "%s%s%s", basedir, RETRO_PATH_SEPARATOR, filename); +} + +char* path_join_dup(const char* basedir, const char* filename) +{ + size_t dirlen = strlen(basedir); + size_t seplen = strlen(RETRO_PATH_SEPARATOR); + size_t filelen = strlen(filename); + char* result = (char*)malloc(dirlen + seplen + filelen + 1); + strcpy(result, basedir); + strcpy(result + dirlen, RETRO_PATH_SEPARATOR); + strcpy(result + dirlen + seplen, filename); + return result; +} + +/** + * D_Skywalk: Imported from my 3DS pituka implementation + * http://david.dantoine.org/proyecto/26/ + */ + +#ifdef _3DS +void* linearMemAlign(size_t size, size_t alignment); +void linearFree(void* mem); +#endif + +void *retro_malloc(size_t size) { + #ifdef _3DS + return linearMemAlign(size, 0x80); + #else + return malloc(size); + #endif +} + +void retro_free(void * mem) { + #ifdef _3DS + linearFree(mem); + #else + free(mem); + #endif +} + +// ----------------------------- crc32b -------------------------------- + +/* This is the basic CRC-32 calculation with some optimization but no +table lookup. The the byte reversal is avoided by shifting the crc reg +right instead of left and by using a reversed 32-bit word to represent +the polynomial. */ + +uint32_t crc32_calculate(uint8_t * data, uint32_t size) { + uint32_t byte, crc, mask; + + crc = 0xFFFFFFFF; + + for (int i = 0; i < size; i++) { + byte = data[i]; + crc = crc ^ byte; + for (int j = 7; j >= 0; j--) { + mask = -(crc & 1); + crc = (crc >> 1) ^ (0xedb88320 & mask); + } + } + return ~crc; +} + diff --git a/libretro/retro_utils.h b/libretro/retro_utils.h new file mode 100644 index 0000000..dd1f5d1 --- /dev/null +++ b/libretro/retro_utils.h @@ -0,0 +1,72 @@ +/**************************************************************************** + * Caprice32 libretro port + * + * Copyright not6 - r-type (2015-2018) + * Copyright David Colmenero - D_Skywalk (2019-2021) + * Copyright Daniel De Matteis (2012-2021) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + + +#ifndef RETRO_UTILS_H__ +#define RETRO_UTILS_H__ + +#include +#include +#include + +//***************************************************************************** +// File helpers functions +#define RETRO_PATH_MAX 512 + +#ifdef _WIN32 +#define RETRO_PATH_SEPARATOR "\\" +// Windows also support the unix path separator +#define RETRO_PATH_SEPARATOR_ALT "/" +#else +#define RETRO_PATH_SEPARATOR "/" +#endif + +bool file_check_extension(const char *filename, const size_t filename_size, const char *ext, const size_t ext_size); +bool file_check_flag(const char *filename, const size_t filename_size, const char *flag, const size_t flag_size); +void path_join(char* out, const char* basedir, const char* filename); +char* path_join_dup(const char* basedir, const char* filename); + +bool file_exists(const char *filename); +int file_size (int file_num); +uint32_t get_hash(const char *filename); + +void *retro_malloc(size_t size); +void retro_free(void * mem); + +#endif diff --git a/libretro/vkbd.c b/libretro/vkbd.c index 3e0fbe5..752fa6a 100644 --- a/libretro/vkbd.c +++ b/libretro/vkbd.c @@ -10,6 +10,7 @@ extern int NPAGE; extern int KCOL; extern int BKGCOLOR; extern int SHIFTON; +extern int CTRLON; void virtual_kdb(char *buffer,int vx,int vy) { @@ -23,7 +24,7 @@ unsigned *pix=(unsigned*)buffer; unsigned short *pix=(unsigned short *)buffer; #endif - page = (NPAGE == -1) ? 0 : 5*NPLGN; + page = (NPAGE == -1) ? 0 : NLIGN*NPLGN; coul = RGB565(28, 28, 31); BKGCOLOR = (KCOL>0?0xFF808080:0); @@ -33,15 +34,55 @@ unsigned short *pix=(unsigned short *)buffer; for(y=0;y" ,RETROK_PERIOD}, - { " /" ," ?" ,RETROK_SLASH}, - { " \\"," \\" ,RETROK_BACKSLASH}, - { "SHFT" ,"SHFT" ,0x25}, - - { "PG2","PG2" ,-2}, //40+8 - { "TAB","TAB" ,0x54}, - { "CPSL" ,"CPSL" ,0x86}, - { "RET" ,"RET" ,0x22}, - { "DEL" ,"DEL" ,0x97}, - { "CTRL" ,"CTRL" ,0x27}, - { "CLR" ,"CLR" , 0x20}, - { "Spc" ,"Spc",0x57}, - { "= " ,"= " ,RETROK_EQUALS}, - { " *" ," *", RETROK_ASTERISK}, - { "# " ,"# " ,RETROK_HASH}, - { "Ent" ,"Ent",0x06}, - - - { "ESC" ,"ESC" ,RETROK_ESCAPE },//50+1° - { " 1" ," !" , RETROK_1 },//0 - { " 2" ," \"" ,RETROK_2 }, - { " 3" ," #" ,RETROK_3 }, - { " 4" ," $" ,RETROK_4 }, - { " 5" ," %" ,RETROK_5 }, - { " 6" ," &" ,RETROK_6 }, - { " 7" ," \'" ,RETROK_7 }, - { " 8" ," (" ,RETROK_8 }, - { " 9" ," )" ,RETROK_9 }, - { " 0" ," _" ,RETROK_0 }, - { " ^" ,"Pnd" ,0x30 }, - - { " F7" ," F7" ,RETROK_F7}, //60+12 - { " F8" ," F8" ,RETROK_F8}, - { " F9" ," F9" ,RETROK_F9}, - { " F0" ," F0" ,RETROK_F10}, - { " t" ," T" ,0x63}, - { " /\\" ," /\\" ,0x00}, - { " u" ," U" ,0x52}, - { " i" ," I" ,0x43}, - { " o" ," O" ,0x42}, - { " p" ," P" ,0x33}, - { " @" ," |" ,0x32}, - { " [" ," [" ,0x21}, - - { " F4" ," F4" ,RETROK_F4}, //70+14 - { " F5" ," F5" ,RETROK_F5}, - { " F6" ," F6" ,RETROK_F6}, - { " ." ," ." ,0x07}, - { " <-" ," <-" ,0x10}, - { "COPY" ,"COPY" ,0x11}, - { " ->" ," ->" ,0x01}, - { " r" ," R" ,RETROK_r}, - { " p" ," P" ,RETROK_p}, - { "= " ,"= " ,RETROK_EQUALS}, - { " *" ," *", RETROK_ASTERISK}, - { "# " ,"# " ,RETROK_HASH}, - - { " F1" ," F1" ,RETROK_F1},//80+16 - { " F2" ," F2" ,RETROK_F2}, - { " F3" ," F3" ,RETROK_F3}, - { "Ent" ,"Ent" ,0x06}, - { " b" ," B" ,0x66}, - { " \\/" ," \\/" ,0x02}, - { " m"," M" ,0x46}, - { " ,"," <" ,0x47}, - { " ."," >" ,0x37}, - { "TAPE" ,"TAPE" ,-8}, - { "EXIT","EXIT" ,-6}, - { "SNA" ,"SNA" ,-7}, - - - { "PG1","PG1" ,-2},//90+18 - { "DSK","DSK" ,-5}, - { "GUI","GUI" ,-13}, - { "COL" ,"COL",-3}, - { "CTRL" ,"CTRL" ,0x27}, - { "SPC" ,"SPC" ,0x57}, - { "SHFT" ,"SHFT" ,0x25}, - { "ESC","ESC",0x82}, - { "CLR" ,"CLR",0x20}, - { "DEL" ,"DEL",0x97}, - { "Ent" ,"Ent",0x22}, - { "KBD" ,"KBD",-4}, + { "HLP", "HLP", "HLP", RETROK_F6}, // page 1, line 1 + { "STA", "STA", "STA", RETROK_F4}, + { "SEL", "SEL", "SEL", RETROK_F3}, + { "OPT", "OPT", "OPT", RETROK_F2}, + { "RES", "RES", "RES", RETROK_F5}, + { " F1", " F1", " F1", RETROK_F7}, + { " F2", " F2", " F2", RETROK_F8}, + { " F3", " F3", " F3", RETROK_F9}, + { " F4", " F4", " F4", RETROK_F10}, + { "Clr", "Clr", "Clr", RETROK_HOME}, + { "Ins", "Ins", "Ins", RETROK_INSERT}, + { "Bsp", "Del", "Del", RETROK_BACKSPACE}, + + { "Esc", "Esc", "Esc", RETROK_ESCAPE}, // page 1, line 2 + { " 1 ", " ! ", " \xb1 " , RETROK_1}, + { " 2 ", " \" ", " \xb2 ", RETROK_2}, + { " 3 ", " # ", " \xb3 ", RETROK_3}, + { " 4 ", " $ ", " \xb4 ", RETROK_4}, + { " 5 ", " %% ", " \xb5 ", RETROK_5}, + { " 6 ", " & ", " \xb6 ", RETROK_6}, + { " 7 ", " \' ", " \xb7 ", RETROK_7}, + { " 8 ", " @ ", " \xb8 ", RETROK_8}, + { " 9 ", " ( ", " \xb9 ", RETROK_9}, + { " 0 ", " ) ", " \xb0 ", RETROK_0}, + { "Brk", "Brk", "Brk", RETROK_PAUSE}, + + { "Tab", "Tab", "Tab", RETROK_TAB}, // page 1, line 3 + { " q ", " Q ", "Q \x11", RETROK_q}, + { " w ", " W ", "W \x17", RETROK_w}, + { " e ", " E ", "E \x05", RETROK_e}, + { " r ", " R ", "R \x12", RETROK_r}, + { " t ", " T ", "T \x14", RETROK_t}, + { " y ", " Y ", "Y \x19", RETROK_y}, + { " u ", " U ", "U \x15", RETROK_u}, + { " i ", " I ", "I \x09", RETROK_i}, + { " o ", " O ", "O \x0f", RETROK_o}, + { " p ", " P ", "P \x10", RETROK_p}, + { "Ret", "Ret", "Ret", RETROK_RETURN}, + + { "Ctl", "Ctl", "Ctl", RETROK_LCTRL}, // page 1, line 4 + { " a ", " A ", "A \x01", RETROK_a}, + { " s ", " S ", "S \x13", RETROK_s}, + { " d ", " D ", "D \x04", RETROK_d}, + { " f ", " F ", "F \x06", RETROK_f}, + { " g ", " G ", "G \x07", RETROK_g}, + { " h ", " H ", "H \x08", RETROK_h}, + { " j ", " J ", "J \x0a", RETROK_j}, + { " k ", " K ", "K \x0b", RETROK_k}, + { " l ", " L ", "L \x0c", RETROK_l}, + { " ; ", " : ", "; \x7b", RETROK_SEMICOLON}, + { "Cap", "Cap", "Cap", RETROK_CAPSLOCK}, + + { "Shf", "Shf", "Shf", RETROK_LSHIFT}, // page 1, line 5 + { " z ", " Z ", "Z \x1a", RETROK_z}, + { " x ", " X ", "X \x18", RETROK_x}, + { " c ", " C ", "C \x03", RETROK_c}, + { " v ", " V ", "V \x16", RETROK_v}, + { " b ", " B ", "B \x02", RETROK_b}, + { " n ", " N ", "N \x0e", RETROK_n}, + { " m ", " M ", "M \x0d", RETROK_m}, + { " , ", " [ ", ", \x00", RETROK_COMMA}, + { " . ", " ] ", ". \x60", RETROK_PERIOD}, + { " \x9c ", " \x9c ", " \x9c ", RETROK_UP}, + { "Inv", "Inv", "Inv", RETROK_LSUPER}, + + { "OPC", "OPC", "OPC", -5}, // page 1, line 6 + { "Spc", "Spc", "Spc", RETROK_SPACE}, + { " + ", " \\ ", " \x1e ", RETROK_PLUS}, + { " _ ", " - ", " \x1c ", RETROK_UNDERSCORE}, + { " = ", " | ", " \x1d ", RETROK_EQUALS}, + { " * ", " ^ ", " \x1f ", RETROK_ASTERISK}, + { " / ", " ? ", " / ", RETROK_SLASH}, + { " < ", " < ", " < ", RETROK_LESS}, + { " > ", " > ", " > ", RETROK_GREATER}, + { " \x9e ", " \x9e ", " \x9e ", RETROK_LEFT}, + { " \x9d ", " \x9d ", " \x9d ", RETROK_DOWN}, + { " \x9f ", " \x9f ", " \x9f ", RETROK_RIGHT}, + + + { "Esc", "Esc", "Esc", RETROK_ESCAPE}, // page 2, line 1 + { "HLP", "HLP", "HLP", RETROK_F6}, + { "STA", "STA", "STA", RETROK_F4}, + { "SEL", "SEL", "SEL", RETROK_F3}, + { "OPT", "OPT", "OPT", RETROK_F2}, + { "RES", "RES", "RES", RETROK_F5}, + { " F1", " F1", " F1", RETROK_F7}, + { " F2", " F2", " F2", RETROK_F8}, + { " F3", " F3", " F3", RETROK_F9}, + { " F4", " F4", " F4", RETROK_F10}, + { "GUI", "GUI", "GUI", RETROK_F1}, + { "Brk", "Brk", "Brk", RETROK_PAUSE}, + + { "Esc", "Esc", "Esc", RETROK_ESCAPE}, // page 2, line 2 + { "HLP", "HLP", "HLP", RETROK_F6}, + { "STA", "STA", "STA", RETROK_F4}, + { "SEL", "SEL", "SEL", RETROK_F3}, + { "OPT", "OPT", "OPT", RETROK_F2}, + { "RES", "RES", "RES", RETROK_F5}, + { " F1", " F1", " F1", RETROK_F7}, + { " F2", " F2", " F2", RETROK_F8}, + { " F3", " F3", " F3", RETROK_F9}, + { " F4", " F4", " F4", RETROK_F10}, + { "GUI", "GUI", "GUI", RETROK_F1}, + { "Brk", "Brk", "Brk", RETROK_PAUSE}, + + { "Tab", "Tab", "Tab", RETROK_TAB}, // page 2, line 3 + { " q ", " Q ", "Q \x11", RETROK_q}, + { " w ", " W ", "W \x17", RETROK_w}, + { " e ", " E ", "E \x05", RETROK_e}, + { " r ", " R ", "R \x12", RETROK_r}, + { " \x9c ", " \x9c ", " \x9c ", RETROK_UP}, + { " y ", " Y ", "Y \x19", RETROK_y}, + { " u ", " U ", "U \x15", RETROK_u}, + { " i ", " I ", "I \x09", RETROK_i}, + { " o ", " O ", "O \x0f", RETROK_o}, + { " p ", " P ", "P \x10", RETROK_p}, + { "Ret", "Ret", "Ret", RETROK_RETURN}, + + { "Ctl", "Ctl", "Ctl", RETROK_LCTRL}, // page 2, line 4 + { " a ", " A ", "A \x01", RETROK_a}, + { " s ", " S ", "S \x13", RETROK_s}, + { " d ", " D ", "D \x04", RETROK_d}, + { " \x9e ", " \x9e ", " \x9e ", RETROK_LEFT}, + { "Ret", "Ret", "Ret", RETROK_RETURN}, + { " \x9f ", " \x9f ", " \x9f ", RETROK_RIGHT}, + { " j ", " J ", "J \x0a", RETROK_j}, + { " k ", " K ", "K \x0b", RETROK_k}, + { " l ", " L ", "L \x0c", RETROK_l}, + { " ; ", " : ", "; \x7b", RETROK_SEMICOLON}, + { "Cap", "Cap", "Cap", RETROK_CAPSLOCK}, + + { "Shf", "Shf", "Shf", RETROK_LSHIFT}, // page 2, line 5 + { " z ", " Z ", "Z \x1a", RETROK_z}, + { " x ", " X ", "X \x18", RETROK_x}, + { " c ", " C ", "C \x03", RETROK_c}, + { " v ", " V ", "V \x16", RETROK_v}, + { " \x9d ", " \x9d ", " \x9d ", RETROK_DOWN}, + { " n ", " N ", "N \x0e", RETROK_n}, + { " m ", " M ", "M \x0d", RETROK_m}, + { " , ", " [ ", ", \x00", RETROK_COMMA}, + { " . ", " ] ", ". \x60", RETROK_PERIOD}, + { " / ", " ? ", " / ", RETROK_SLASH}, + { "Inv", "Inv", "Inv", RETROK_LSUPER}, + + { "PG1", "PG1", "PG1", -2}, // page 2, line 6 + { "Spc", "Spc", "Spc", RETROK_SPACE}, + { "Del", "Del", "Del", RETROK_DELETE}, + { "Clr", "Clr", "Clr", RETROK_HOME}, + { "Ins", "Ins", "Ins", RETROK_INSERT}, + { " + ", " \\ ", " \x1e ", RETROK_PLUS}, + { " _ ", " - ", " \x1c ", RETROK_UNDERSCORE}, + { " = ", " | ", " \x1d ", RETROK_EQUALS}, + { " * ", " ^ ", " \x1f ", RETROK_ASTERISK}, + { " < ", " < ", " < ", RETROK_LESS}, + { " > ", " > ", " > ", RETROK_GREATER}, + { "PG1", "PG1", "PG1", -2}, } ;